Plan 3c (adapter registry + framework coverage). Registry infrastructure (registry.massu.ai) is live and signed; six new first-party AST adapters bring supported framework count from 4 to 10 (rails, phoenix, aspnet, spring, flask, go-chi added on top of the 1.4.0 baseline of fastapi, django, nextjs-trpc, swiftui). A structural drift-guard test now makes "AST adapter silently degrades to regex fallback" impossible to merge — closing the gap that masked a web-tree-sitter/tree-sitter-wasms ABI mismatch through three Phase 7 commits.
Added
- Adapter registry trust model (Plan 3c Phase 5) — three-class adapter loading: CORE-BUNDLED (shipped in
@massu/coreitself, no verification needed), REGISTRY-VERIFIED (npm packages cross-checked against the signed manifest atregistry.massu.ai/adapters/manifest.json), LOCAL-EXPLICIT (operator-configured paths inmassu.config.yaml > adapters.local). Per-class verification scopes, kill-switch (adapters.enabled: falseshort-circuits REGISTRY-VERIFIED + LOCAL-EXPLICIT entirely), and persistent-stderr warnings on degraded modes. Seepackages/core/security/AUDIT-2026-05-XX.md(Phase 3.5 audit) anddocs/SECURITY.md. - Adapter registry infrastructure —
registry.massu.ailive on Vercel with Let's Encrypt (CN=registry.massu.ai), serving the signed manifest envelope (manifest_b64+ Ed25519 detached signature) at/adapters/manifest.json. Public signing key fingerprint3b6226d036c472e533110d11a7d0cd2773ce1d7d4f1003517d5bd69c5418ed4cshipped atpackages/core/security/registry-pubkey.{b64,pem,env}. Private key in macOS Keychain (security add-generic-passwordentrymassu/registry/signing/private). HTTPS verified (HSTSmax-age=63072000; includeSubDomains; preload). - Adapter SDK subpath export —
@massu/core/adaptersubpath providesdefineAdapter()factory +CodebaseAdaptertypes for third-party adapter authors. Adapters never import from@massu/coreinternals — only from this stable SDK. Seedocs/AUTHORING-ADAPTERS.md. npx massu adaptersCLI — three subcommands:list(show which adapters are loaded + their trust class),refresh(re-fetch + re-verify the registry manifest),search <query>(search the manifest for adapters by id/keywords).- Six new first-party AST adapters (Plan 3c Phase 7) — bringing supported framework count to 10:
GRAMMAR_MANIFESTexpansion — six new Tree-sitter grammar entries (go,ruby,csharp,java,kotlin,elixir) with hardcoded sha256 hashes for atomic-write cache verification. Each grammar wasm is downloaded once into~/.massu/wasm-cache/<lang>-<sha>.wasmwith LRU eviction at 16 entries (~50 MB cap).- Detection signal expansion —
DetectionSignalsnow includesmixExs?,csproj?,pomXml?,gradleBuild?(preferringbuild.gradle.ktsoverbuild.gradleper Gradle 7+ defaults). Mirrors the existinggemfile/goMod/cargoToml/pyprojectTomlmanifest-reader pattern. - STRUCTURAL grammar drift-guard (CR-46) — new test
adapter-grammar-strict.test.tsasserts every shipped adapter returns NON-'none'confidence on a clear-cut fixture. Closes the lenient-test-pattern hole (expect(['none', 'medium', 'high']).toContain(...)) that previously allowed grammar-load failures to silently degrade adapters to regex-fallback. Future ABI breaks, query typos, or wasm-cache corruption flip this gate red. Thecore-bundled-ids-drift.test.ts(added in Phase 5) now also covers the 5 new Phase 7 adapter ids. - Telemetry writer —
~/.massu/telemetry/adapter-discovery-*.jsonlfiles capture per-discovery-run statistics (count by trust class, refusal reasons) for offline analysis. Replay command surfaces aggregates without re-running discovery. massu adapters add-local/remove-local/resync-local-fingerprint— three CLI commands that maintain the~/.massu/adapters-local-fingerprint.jsonsentinel (gap-32 postinstall-poisoning defense). Drift between the recorded fingerprint and the currentadapters.localcontent forces operator re-acknowledgment before LOCAL-EXPLICIT adapters load.
Fixed
- Phase 7 grammar loadability (commit
d31b4d8) — pinnedweb-tree-sitterfrom^0.26.8to~0.25.10. Root cause (cited):web-tree-sitter@0.26.xatweb-tree-sitter.js:1944requires WebAssembly custom-section namedylink.0; the wasms shipped bytree-sitter-wasms@0.1.13(compiled withtree-sitter-cli@^0.20.8) emit the olderdylinksection name (verified viaxxd ~/.massu/wasm-cache/elixir-*.wasm). Empirical sweep across 0.20.8 → 0.26.8 confirmed 0.25.10 is the maximum-compatible version. Pre-fix, every Phase 7 AST adapter (python-flask,go-chi,rails) was silently degrading to'none'confidence (regex fallback). The newadapter-grammar-strict.test.tsis the structural drift-prevention that makes this class of bug impossible to merge again. - Rails adapter query (commit
d31b4d8) — removed(method_call ...)patterns fromrails.tsqueries. Thetree-sitter-rubyv0.20.1 grammar (pinned bytree-sitter-wasms@0.1.13) emits routes.rb DSL invocations as(call method: (identifier) arguments: (argument_list ...))— there is nomethod_callnode. Verified via AST probe (R-011 evidence cited inline inrails.ts). Even after the grammar-load fix, themethod_callpatterns would have thrownQueryError: Bad node name 'method_call'attree-sitter.js:1477. - Pattern-scanner FAILs (commit
c943aa3) — directive-aware scanner + drift-guard close two stale FAILs. The scanner now respects// massu-pattern-scanner: skipdirectives in source files (intentional regex deviations) and runs a sibling drift-guard test that fails the build ifmassu-pattern-scanner.shreports any new FAIL category not previously cleared. - Phase 3.5 security audit (commits
51ad804,259d7d8,4ab141e,9c5a80b,4d8f60a,2c21853) — closed all 17 findings across 6 audit iterations. Notable:HIGH-NEW-1(manifest cache TOCTOU), 5MEDfindings on schema validation tightness,LOW-NEW3-1(InstallEntrySchema.version regex),LOW-NEW4-2(printable-ASCII guard against ANSI log injection),LOW-NEW5-1(FingerprintSentinelSchema using PrintableAsciiStringSchema). Final iteration shipped a STRUCTURAL drift-guard test for the manifest-cachefetched_atfield — making the class of bug "manifest cache silently serves stale data because freshness is unenforced" impossible. - Phase 5
gap-37install-time + load-time sha256 — adapter packages now record theirinstalled_sha256atnpm installtime in~/.massu/adapter-manifest-installed.json; load-time discovery re-computes the hash and refuses to load on drift. Cross-check against the signed registry manifest'ssha256field detects post-install sidecar tampering (auditM4fix). scope MyAppWeb do(alias-only Phoenix scope) — correctly excluded fromscope_prefix_basecapture per the string-literal-anchor in the SCOPE_PATH_QUERY (verified negative case via AST probe).
Security
- All Phase 3.5 audit findings closed (0 unfixed) per
packages/core/security/AUDIT-2026-05-XX.md. - Symlink attack defense across
discover.ts:walkNodeModules(lstatSyncnotstatSync) — same fix that landed ininstall-tracking.ts(auditH1) was missed indiscover.tsuntil iter 2. - Hidden-directory load-time refusal in
discover.ts(MED-NEW-2) — packages shipping.git/payload.jsetc. are refused at load time, closing thesha256OfDir-excludes-hidden-dirs gap. - Adapter-loading kill-switch (
adapters.enabled: false) defaults tofalseat the config schema layer (gap-1 /C1) — operators MUST opt-in to third-party adapter loading.
Infrastructure
web-tree-sitterpinned to~0.25.10(was^0.26.8). Hard upper bound documented inline; loosen this only aftertree-sitter-wasmsships a release withdylink.0-format wasms.- 5 workspace placeholder packages remain at
0.0.0-prework(@massu/adapter-{rails,phoenix,aspnet,spring,go-chi}) — these adapters ship CORE-BUNDLED in@massu/coreitself for 1.5.0; separate REGISTRY-VERIFIED package publish is a follow-on.