harden(caller): repo-wide validate_caller meta-guard (closes #81)#82
Merged
Conversation
Import-introspection over every `*_CALLER` constant in the swarph_cli package + validate_caller each, so the #80 hyphenated-caller bug class can't be re-introduced in ANY module without a per-caller test. Converged design (lab+droplet): introspect named constants, not AST literal-walk — `caller=SHORTHAND_CALLER` is an ast.Name, not a literal, so a literal-walk would miss exactly the callers #80 hardened. Negative-control verified (a planted hyphenated *_CALLER is discovered + caught). Test-only; no production change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…oplet review) Folds in droplet's two non-blocking polish items pre-merge: 1. COMMIT the catch-property (don't manually-verify-once) — test_guard_catches_a_planted_bad_caller plants a hyphenated *_CALLER on a discovered module + asserts the guard discovers AND rejects it. This is #80's own lesson applied to the meta-guard: pin it, don't remember it. 2. test_no_modules_skipped_by_the_walk asserts the introspection walk skips ZERO modules, so a bad caller in a module importable-in-prod-but-not-CI can't ship silently uncaught. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
darw007d
added a commit
that referenced
this pull request
Jun 20, 2026
…) (#84) The repl-default caller rolled its own slug that — unlike caller._sanitize_username which default_caller uses — didn't guarantee a leading letter / collapse underscores / fall back on empty. So a leading-digit OS username produced a non-conforming 'cli.repl.3bob' that crashes SwarphCall at runtime (the #80 crash-class on the dynamic path). Fix is DRY: reuse the one robust sanitizer, eliminating the divergence (USER=3bob -> cli.repl.u_3bob; !!! -> cli.repl.unknown). + a parametrized adversarial- username regression test (leading-digit/all-special/empty/etc). No production behavior change for normal usernames; 53 chat/caller tests green, #80+#82 unaffected. Co-authored-by: lab-ovh <lab@brainsurfing.tech> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
darw007d
added a commit
that referenced
this pull request
Jun 21, 2026
…, repl-caller #83/#84) Ships the dotted caller-convention fixes that were merged to main but unreleased: - #80: compress shorthand + verify-expand model paths were DEAD at runtime (hyphenated callers rejected by swarph_shared's dotted convention) — now dotted constants. - #82: repo-wide validate_caller meta-guard so the bug class can't be re-introduced. - #83/#84: _default_repl_caller convention-safe slug (reuses _sanitize_username). Anyone on 0.13.2 running `swarph compress` hit the dead path; this releases the fix. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #81. Generalizes #80's per-caller regression test into a repo-wide meta-guard: discovers every static
*_CALLERconstant across theswarph_clipackage by import-introspection and runsvalidate_calleron each — so the hyphenated-caller bug class (swarph-compress, silently dead at runtime) can't be re-introduced in ANY module without someone remembering to add a per-caller test.Design (converged lab + droplet on #81)
Import-introspection, not AST literal-walk. The callers live in named
*_CALLERconstants —caller=SHORTHAND_CALLERis anast.Name, not a literal, so a naive 'walk forcaller="..."literals' would miss exactly the callers #80 hardened. Introspection (pkgutil.walk_packages→ import →dir()for*_CALLERstr attrs) resolves the value for free, auto-covers any future module's caller constant, and nudges the light convention that caller tags live in discoverable*_CALLERconstants.Coverage
test_all_caller_constants_conform— every*_CALLERconstant in the package (currently compress'sSHORTHAND_CALLER/VERIFY_EXPAND_CALLER; auto-extends). Has a sanity assert that the known compress callers are discovered (catches a stale-install / wrong-tree resolution).test_default_caller_producers_conform_happy_path— the default-caller producers emit a conforming tag for an injected normal username (deterministic, not dependent on the CI runner's real user).*_CALLERon a discovered module is both discovered by the introspection and caught (guard fails loud, names the offending constant). A guard that can't fail is useless — this one fails on the right thing.Test-only; no production code change.
Building this surfaced a real latent bug in the dynamic default-caller producers (out of scope for a static meta-guard):
_default_repl_caller(chat.py) anddefault_caller's_sanitize_username(main.py) don't guarantee an[a-z]-leading slug. A leading-digit / all-special / empty OS username → e.g.USER=3bob→cli.repl.3bob→ fails the convention → would crash SwarphCall at runtime (the same crash-class as #80, but via the dynamic path). Confirmed:_default_repl_caller()withUSER=3bobreturns'cli.repl.3bob'whichvalidate_callerrejects. Recommend a follow-up: prefix/guard the slug to ensure an[a-z]lead (or fail-loud) + an adversarial-username regression test. Filing separately rather than bundling.🤖 Generated with Claude Code