v4.0.0-rc.3
Pre-releaseTL;DR: The rc.3 release candidate consolidates the complete post-rc.2 hardening line: one central hidden/reserved-vault boundary, patched dependency and consumer evidence, exact CI/artifact/npm/GitHub/Registry transactions, and a controlled refresh of the release-mutation identity projection. Gate B now narrows publication to an owner-created immutable
v*tag and a tag-push-only workflow: there is no manual-dispatch publication path, and transient recovery reruns the original tag-push run instead of creating a new release invocation. The product surface remains 46 tools, 19 prompts, and 1807 source tests; this candidate does not claim stable promotion, stable MCP Registry synchronization, desktop signing, or broader distribution acceptance.Method note: this candidate was prepared from exact clean
main1db2c0d5eca534911e2164d7f107c8a1c246581d, with live ruleset readback on 2026-08-10. Under D-45, no local install, build, lint, test, coverage, smoke, OIA, package/client runtime, benchmark, or evaluation workload ran on the maintainer MacBook; executable proof remains delegated to disposable GitHub-hosted runners on the exact candidate SHA. Preparation performed no tag, npm, GitHub Release, or MCP Registry write. Publication remains conditional on this unified Gate-B/version candidate landing onmainand every exact release-required check passing on its squash-merge SHA.
Included post-v4.0.0-rc.2 hardening
Gate B — owner-created immutable release tags and tag-push-only execution
- Live rulesets establish the minimum protected-tag control. Active tag ruleset
20654714(v-release-tags-immutable) coversrefs/tags/v*, forbids update and deletion, has no bypass actor, and reports that the current user can never bypass it. Active tag ruleset20654735(v-release-tags-owner-create) covers the same namespace, gates creation, and grants the repository owner the sole always-on creation bypass. The trusted owner credential can still create a release tag; after creation, neither that credential nor another actor can move or delete it through the ruleset bypass surface. - The release workflow has one exact start condition. Its only trigger is
push.tags: ["v*"];workflow_dispatch,workflow_call, branch, pull-request, and schedule triggers are absent. In this sole event context, the retained legacy fallback expressions resolve to the pushed${{ github.ref_name }}tag and exact${{ github.ref }}ref. They remain inert temporarily so frozen mutation m367 stays byte-identical; the structural trigger invariant has positive and mutation-negative controls that prevent the removed manual-input path from returning. - Recovery preserves the original release event. A transient failure is resumed by rerunning the original GitHub Actions run created by the protected tag push. Operators do not dispatch a fresh workflow, replay publication from a mutable branch, or manufacture a second release identity.
- The release-mutation identity refresh is controlled, not silent. The canonical generator runs remotely against the immutable historical matrix oracle while reading the candidate's current external sources. Git history preserves the prior fixture bytes; the refreshed fixture changes exactly six source records and 272 mechanically dependent mutation records, including three dependency-source descendants, then receives new independent byte pins. Mutation IDs, order, roles, expressions—including m367—cases and topology remain fixed at 30 sources, 560 mutations, 536 roots plus cases, 24 dependencies, 541 checks, and 546 leaves. The structural diff proves that unrelated source identities and every case remain unchanged.
- Residual trust is stated, not hidden. Gate B is not a default-branch trusted controller and does not claim least-privilege isolation between repository code execution and later npm, GitHub, or OIDC-capable steps.
NPM_TOKENremains repository-scoped without a release environment; other already-authorized credential holders remain trusted; branch protection still enforces seven contexts with administrators unenforced and zero required approvals, while release publication independently requires the complete exact context set and manual process gates. Stable MCP Registry publication remains out of scope for this RC.
Built-in hidden/reserved vault boundary (mcpvault transfer audit)
TL;DR: A primary-source comparison with
bitbonsai/mcpvaultfound one security pattern that enquire-mcp should adopt immediately: hidden and reserved path names must be a central public-visibility rule, not merely a walker convention. Before this patch, recursive Markdown/file walks skipped dot entries and a short case-sensitive directory list, whileVault.isExcluded()represented only operator-supplied globs. A client that already knew a path could therefore read or stat.secret.mddirectly; arbitrary hidden paths and case variants such as nestedNode_Modulescould also reach watcher/index flows. One pure segment classifier now composes ahead of user filters across lists, direct reads, writes, watcher admission, persistent cache, stale index keys and MCP resources. It rejects dot-prefixed segments and reserved Obsidian/Git/trash/dependency/OS metadata at every depth, case-insensitively and with Windows trailing-dot/space normalization, while preserving ordinary dotted note/folder names. Direct and mutation paths check both lexical and canonical physical identities. Persisted FTS, embedding and hybrid candidates plus chunk resources re-admit the bounded live source before returning stored excerpts or bytes. The source-test declaration count remains 1807.Method note: the transfer audit pinned mcpvault main at
6c3e1d9dfd311eee52f5c5ab277e9c821cff2aecand compared its path filter, frontmatter, range-read, wikilink, skill, website, release and search implementations against exact enquire-mcp main. The urgent patch borrows only the proven path-policy pattern, not mcpvault's O(N) per-query scanner, default-write posture or release process. Existing test callbacks were extended with positive and negative controls for default/no-filter lists, direct text/binary/stat access, missing hidden paths, create/append/rename byte preservation, case/mixed-separator/Windows-equivalent names, both in-vault symlink directions, crafted parse-cache entries, stale FTS/Embed/chunk rows, watcher add/change versus unlink, startup/alias admission and the trusted Periodic Notes exception. The first remote CodeQL pass rejected a trailing-dot/space regular expression as polynomial on client-controlled paths; the existing shared non-backtracking trailing-run helper now preserves the Windows normalization semantics in linear time, including a long-suffix positive/negative control and a structural regression guard. The required same-class sweep also found and replaced the identical trailing-slash shape in the user-controlledwiki_folderprompt path, and added both files to the permanent sink inventory. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client runtime, benchmark or evaluation workload ran on the maintainer MacBook; executable proof belongs exclusively to disposable GitHub-hosted CI on the exact candidate SHA.
- The policy is intrinsic, not an implicit default glob.
restrictedVaultPathReason()is independent of CLI configuration, andVault.exclusionReason()composes it before--read-paths/--exclude-glob, producing an accurate stable refusal reason. Walkers and watcher no longer own divergentSKIP_DIRSlists. - Admission is two-identity and non-oracular. The lexical vault-relative spelling is rejected before
realpathor an ENOENT fallback; an existing canonical target is checked again afterward. Writes, appends and renames repeat physical admission before their content-bearing write or move step, while Periodic Notes retains exactly two trusted config reads that still obey explicit user filters. If those explicit filters hide the config, alias resolution uses the public default and authorizes that derived target without revealing the configured folder. - Derived state fails closed without blocking erasure. Parse-cache load/save drops restricted bodies. Persisted FTS/Embed/hybrid rows and chunk URIs perform bounded live
Vault.stat()admission before returning indexed excerpts or bytes, closing a visible-key-to-hidden-symlink stale-row bypass. Watcher activation and physical-alias inspection check both lexical and canonical identities; exact unlink handling remains admitted to purge stale rows. - Compatibility counters stay explicit. Existing diagnostic
total_chunks/total_filesfields still describe physical index health and may include stale filtered rows until rebuild. They reveal no path or content; privacy-scoped aggregate counting remains risk-triggered because doing an O(vault) physical admission pass on every query would be a disproportionate latency regression. - Upgrade cleanup remains operator-controlled. Stale hidden/reserved rows are no longer returned, but an upgrade does not claim retroactive deletion from FTS5, EmbedDb, HNSW, or old parse-cache files. Operators who require at-rest removal must clear and rebuild those derived stores under the new policy.
- The boundary is honest about local concurrency. It rejects client-chosen spellings and stable aliases, but does not claim an
openat-style transaction against a same-account process swapping path components between filesystem syscalls; such a process is already inside the vault filesystem trust boundary.
Declarative npm-workflow provenance binding mutation m116
TL;DR: The release-mutation identity graph moves
release.m116from the shared legacy loop into the existing unarynpm.workflowplanner path without changing the frozen mutation, detector, expectation, fixture or historical execution order. The case continues to reject replacing the exact tag commit bindingPROVENANCE_SHA: ${{ github.sha }}with the workflow-file commit${{ github.workflow_sha }}. The hybrid partition advances from 45 to 46 declarative mutations (43 first + 3 all) and from 515 to 514 legacy mutations (495 first + 19 all), with exactly 45 declarative cases, expectations and roots plus one declarative dependency; the frozen global graph remains 30 sources, 560 mutations, 536 roots/cases, 24 dependencies, 541 checks and 546 matcher leaves.Method note:
release.m116reuses the unarynpmWorkflowProblemsadapter introduced by m114; no planner API or fifth adapter is added. Its declarative identity remains bound tofixture.release-workflow, the exact token witness,npm.workflow, the top-levelnpmProvenanceWorkflowProblemsdetector and the exact npm-provenance problem identity. The historical root remains pinned at SHA-25654be2d32d9f71d6781fa5b76a93b19373e8387f0c99452104b3676ab8060c27c, while the shared matcher remains physical once for the 33 remaining m117+ legacy roots at SHA-2563df3ee2ebc3147bc3f2669b03a7d54b7dd8f5d4f2bf7a125e749d5a9fbb9c240. The immutable fixture remains byte-identical at SHA-256fb431715ec32253b4474c4993a46acbc0c20749b9f3162b31985c3f8668513e9. The first remote test pass correctly rejected the copied legacy template-literal AST form: declarative string slots now use canonical double-quotedStringLiteralnodes, and one negative control mutates needle, replacement and witness anchor back to backticks and requires all three passive-value diagnostics. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client runtime, benchmark or evaluation workload runs on the maintainer MacBook; executable validation is required from GitHub-hosted CI on the exact candidate and squash-main SHAs.
- The existing unary contract gains one exact root. The clean release-workflow baseline, m116 mutant, witness and problem identity remain explicit, while the adapter surface stays unchanged.
- Historical order remains explicit. The m002–m037 prefix stays at 36 cases,
executeRemaining()finishes at 45 cases/expectations, and the shared legacy npm-workflow loop now begins at m117. - Release and product state remain out of scope. No workflow, runtime/product code, package or lockfile, version, tag, publication state, dist-tag, fixture regeneration or cleanup action is changed by this boundary.
Declarative npm-workflow reserve mutation m115
TL;DR: The release-mutation identity graph moves
release.m115from the shared legacy loop into the existing unarynpm.workflowplanner path without changing the frozen mutation, detector, expectation, fixture or historical execution order. The case continues to reject weakening the token-free npm-provenance verification reserve from 2,700 to 1,200 seconds. The hybrid partition advances from 44 to 45 declarative mutations (42 first + 3 all) and from 516 to 515 legacy mutations (496 first + 19 all), with exactly 44 declarative cases, expectations and roots plus one declarative dependency; the frozen global graph remains 30 sources, 560 mutations, 536 roots/cases, 24 dependencies, 541 checks and 546 matcher leaves.Method note:
release.m115reuses the unarynpmWorkflowProblemsadapter introduced by m114; no planner API or fifth adapter is added. Its declarative identity remains bound tofixture.release-workflow, the exact token witness,npm.workflow, the top-levelnpmProvenanceWorkflowProblemsdetector and the exact npm-provenance problem identity. The historical root remains pinned at SHA-25632f57ce2ec034103af6ada47d96577ac16df4c63e90c2ea31994b106f4955576, while the shared matcher remains physical once for the 34 remaining m116+ legacy roots at SHA-2563df3ee2ebc3147bc3f2669b03a7d54b7dd8f5d4f2bf7a125e749d5a9fbb9c240. The immutable fixture remains byte-identical at SHA-256fb431715ec32253b4474c4993a46acbc0c20749b9f3162b31985c3f8668513e9. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client runtime, benchmark or evaluation workload runs on the maintainer MacBook; executable validation is required from GitHub-hosted CI on the exact candidate and squash-main SHAs.
- The existing unary contract gains one exact root. The clean release-workflow baseline, m115 mutant, witness and problem identity remain explicit, while the adapter surface stays unchanged.
- Historical order remains explicit. The m002–m037 prefix stays at 36 cases,
executeRemaining()finishes at 44 cases/expectations, and the shared legacy npm-workflow loop now begins at m116. - Release and product state remain out of scope. No workflow, runtime/product code, package or lockfile, version, tag, publication state, dist-tag, fixture regeneration or cleanup action is changed by this boundary.
Declarative npm-workflow canary m114
TL;DR: The release-mutation identity graph moves
release.m114into the closed declarative planner as the first unarynpm.workflowcanary without changing its mutation, detector, expectation, fixture or historical execution position. The case still proves that the npm publish phase cannot weaken its exact 4,500-second reserve to 2,100 seconds. The hybrid partition advances from 43 to 44 declarative mutations (41 first + 3 all) and from 517 to 516 legacy mutations (497 first + 19 all), with exactly 43 declarative cases, expectations and roots plus one declarative dependency; the frozen global graph remains exactly 30 sources, 560 mutations, 536 roots/cases, 24 dependencies, 541 checks and 546 matcher leaves.Method note: the planner gains one deliberately unary adapter capsule,
npmWorkflowProblems, whose baseline and mutant calls are both frozen before the exact npm-provenance problem identity is evaluated. The independent AST auditors bindrelease.m114tofixture.release-workflow,npm.workflow, the literal reserve mutation and the exact top-levelnpmProvenanceWorkflowProblemsfunction; they also reject missing, transplanted, aliased, shadowed or reassigned fourth-adapter bindings and resurrection of the historical root SHA-25633eafb51e59c895771d9b0523834365e423477bdee438022ebba3866ac293581. The shared npm-workflow matcher remains physical once for the remaining m115+ legacy cases at SHA-2563df3ee2ebc3147bc3f2669b03a7d54b7dd8f5d4f2bf7a125e749d5a9fbb9c240, while the existing 65 full matrix audits and telemetry budget stay unchanged. The immutable fixture remains byte-identical at SHA-256fb431715ec32253b4474c4993a46acbc0c20749b9f3162b31985c3f8668513e9. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client runtime, benchmark or evaluation workload runs on the maintainer MacBook; executable proof belongs exclusively to GitHub-hosted CI on the exact candidate and squash-main SHAs.
- The unary canary is closed end to end. The descriptor, source, witness, invocation, adapter property, top-level binding and exact problem identity must agree; a clean baseline must remain problem-free and the mutant must be detected exactly once.
- Staged execution preserves historical order. The m002–m037 prefix stays at 36 cases, the existing legacy loop and declarative m107–m113 suffix remain unchanged,
executeRemaining()now finishes at 43 cases/expectations, and the legacy npm-workflow loop begins at m115. - Release and product state are untouched. No workflow, runtime/product code, package or lockfile, version, tag, npm/GitHub Release/MCP Registry state, dist-tag, cleanup action or fixture regeneration is part of this boundary.
Declarative Registry dependency pair m108→m107
TL;DR: The release-mutation identity graph moves the nested Registry replay dependency
release.m108and its owning workflow rootrelease.m107into one atomic declarative chain without changing either mutation, detector, expectation, fixture or execution position. m108 still opens the exact bounded replay loop around the MCP Registry publication transaction, while m107 still closes that loop only after the exact publication-confirmation line. The hybrid partition advances from 41 to 43 declarative mutations (40 first + 3 all) and from 519 to 517 legacy mutations (498 first + 19 all), with exactly 42 declarative cases/expectations/roots and one declarative dependency; the frozen global graph remains exactly 30 sources, 560 mutations, 536 roots/cases, 24 dependencies, 541 checks and 546 matcher leaves.Method note: the dependency is registered before its owner in frozen topological order: m108 derives from the immutable Registry publish-step source, m107 derives from m108, and only m107 owns a
registry.step.runcase whose clean baseline remains the raw publish step. The shared Registry-loop matcher stays physical once for the remaining m038–m106 legacy roots; staged execution still completes the m002–m037 prefix first, then the legacy loop, then declarative cases m107→m109→m110→m111→m112→m113 before legacy m114. Existing bounded candidates now reject flattening the m107 source edge, reversing m108/m107 registration, assigning a case to dependency-only m108, and resurrecting the exact historical nested nodes with SHA-256067bacefc171385fbf496ba6d7e25ad9403569d2a8daeba29e483e8c486507b8/b67c164531f5a0702f1ceb3ec750cf4df6f655ac68d12fbb31bf04db35ca5325, without increasing the existing 65 full matrix audits. The immutable fixture remains byte-identical at SHA-256fb431715ec32253b4474c4993a46acbc0c20749b9f3162b31985c3f8668513e9. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client runtime, benchmark or evaluation workload runs on the maintainer MacBook; executable proof belongs exclusively to GitHub-hosted CI on the exact candidate and squash-main SHAs.
- The dependency pair migrates atomically. m108 remains dependency-only, m107 remains its sole owner/root, the source edge is exact, and the root's clean detector baseline never inherits the replay mutation.
- Staged order and shared ownership remain closed. The m037 prefix boundary stays 36/36, the suffix finishes at 42/42, and the one Registry-loop matcher retains exactly 69 legacy owners after m107 moves declarative.
- Release and product state are untouched. No workflow, runtime/product code, package or lockfile, version, tag, npm/GitHub Release/MCP Registry state, dist-tag, cleanup action or fixture regeneration is part of this boundary.
Declarative npm-provenance contract mutations m112–m113
TL;DR: The release-mutation identity graph moves the two mirrored npm-provenance composition cases
release.m112andrelease.m113into one closed declarative contract without changing either mutation, detector, expectation, fixture or execution position. m112 still proves that the release workflow cannot bypass the exact tag-push provenance-context binding; m113 still proves that the integrity evaluator cannot acceptworkflow_dispatchin place of the requiredpushevent. The hybrid partition advances from 39 to 41 declarative mutations (38 first + 3 all) and from 521 to 519 legacy mutations (500 first + 19 all), while the frozen global graph remains exactly 30 sources, 560 mutations, 536 roots/cases, 24 dependencies, 541 checks and 546 matcher leaves.Method note: the closed planner gains two deliberately directional invocations over one immutable binary adapter capsule:
npm.contract.releaseevaluates the mutant release workflow with the clean integrity source, whilenpm.contract.integrityevaluates the clean release workflow with the mutant integrity source. A bounded planner control proves the four ordered adapter tuples, missing-adapter preflight and dirty-clean-baseline failure. The independent auditor binds the newfixture.release-workflowsource, both companion directions, the exact npm-provenance problem identity and all three execution adapters before any detector runs. Existing bounded candidates reject source/adapter drift, reversed companions, cross-case transplants, declaration-order drift, resurrection of historical root SHA-256 values2472b8e6ac2bbd1d245fe3c4a80a0e02feb000823d261169c21161a276c54b0d/ebe9c3077c0627c8d7ac444bbfaf9fedf4e51e6c152ca81593c40bf6dc831742and resurrection of unique matcher SHA-256 values70d1140baaad93fc1a0491e5da0b6d8d3c4474a6989db7642db4f0602ab0715a/1b65bfa3daf8f47b905b8593e9e7abb7f6aa1a93724a7f9609e43421e93d9e94, without increasing the existing 65 full matrix audits. The immutable fixture remains byte-identical at SHA-256fb431715ec32253b4474c4993a46acbc0c20749b9f3162b31985c3f8668513e9. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client runtime, benchmark or evaluation workload runs on the maintainer MacBook; executable proof belongs exclusively to GitHub-hosted CI on the exact candidate and squash-main SHAs.
- The binary contract is directional, not an unordered pair. Each invocation freezes the mutated slot, the exact clean companion handle and adapter argument order; reversing or aliasing either side fails before execution.
- Staged execution preserves historical order. The m002–m037 prefix and m038–m108 legacy loop remain unchanged,
executeRemaining()consumes m109→m110→m111→m112→m113 exactly once, and the next legacy matcher starts at m114; the final declarative census is 41 cases and 41 expectations. - Release and product state are untouched. No workflow, runtime/product code, package or lockfile, version, tag, npm/GitHub Release/MCP Registry state, dist-tag, cleanup action or fixture regeneration is part of this boundary.
Declarative Registry-step integrity mutation m111
TL;DR: The release-mutation identity graph moves
release.m111into the closed declarative planner without changing its mutation, detector, expectation, fixture or execution order. The case still proves that MCP Registry publication rejects an integrity evaluator whose convergence predicate was weakened from the exact retryable-status guard to any convergence phase. The hybrid partition advances from 38 to 39 declarative mutations (36 first + 3 all) and from 522 to 521 legacy mutations (502 first + 19 all), while the frozen global graph remains exactly 30 sources, 560 mutations, 536 roots/cases, 24 dependencies, 541 checks and 546 matcher leaves.Method note:
release.m111deliberately stays in its own Registry-step-integrity family. It has the same raw mutation tuple and materialized mutant as declarative evaluator caserelease.m035, but a different frozen oracle: m035 evaluates the integrity source alone, while m111 evaluates that mutant as the integrity companion to the exact Registry publish step. The independent auditor therefore binds m111 toregistry.step.integrity,releaseIntegritySourceandregistryPublishStepSourceby exact frozen ID, invocation direction and problem identity rather than tuple ordinal. Existing bounded candidates now reject an m035-oracle transplant, wrong m111 companion, registration-order drift, resurrection of the historical root SHA-25677aaafb7f62f9bb1addab5347cb5e704ece40a7354569378d17d1881bb3e1479and resurrection of its unique matcher SHA-256f77d156123db5a20c3cb2984980ad88548547a95d673ff9315d1be394ba86c5d, without adding another full matrix audit beyond the existing 65. The immutable fixture remains byte-identical at SHA-256fb431715ec32253b4474c4993a46acbc0c20749b9f3162b31985c3f8668513e9. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client runtime, benchmark or evaluation workload runs on the maintainer MacBook; executable proof belongs exclusively to GitHub-hosted CI on the exact candidate and squash-main SHAs.
- The duplicate tuple cannot collapse two distinct cases. m035 remains a
registry.evaluatorcase and m111 remains aregistry.step.integritycase with the clean Registry run in theruncompanion slot; swapping either oracle family or companion identity fails closed. - Staged execution preserves historical order. The m002–m037 prefix remains 36 cases, the unchanged m038–m108 legacy loop runs next,
executeRemaining()consumes m109→m110→m111 exactly once, and legacy m112 follows; the final declarative census is 39 cases and 39 expectations. - Release and product state are untouched. No workflow, runtime/product code, package or lockfile, version, tag, npm/GitHub Release/MCP Registry state, dist-tag, cleanup action or fixture regeneration is part of this boundary.
Declarative Registry-step mutations m109–m110
TL;DR: The release-mutation identity graph now moves its first two Registry workflow cases into the closed declarative planner without changing a mutation, detector, expectation, fixture or execution order.
release.m109still proves that a forged early confirmation is rejected andrelease.m110still proves that the final attempted/confirmed guard cannot weaken from OR to AND. The hybrid partition advances from 36 to 38 declarative mutations while the frozen global graph remains exactly 30 sources, 560 mutations, 536 roots/cases, 24 dependencies, 541 checks and 546 matcher leaves.Method note: the planner registers the exact derived Registry run as a second immutable source only after a clean raw-run baseline, seals after the literal m109/m110 descriptors and freezes both evaluator and Registry-step adapters before executing the m002–m037 prefix. The existing m038–m108 legacy loop then runs unchanged,
executeRemaining()consumes m109/m110, and legacy m111 follows, preserving the complete frozen primary-oracle order. The independent AST auditor derives both source families and invocation companions from the unchanged SHA-256-pinned identity fixture, accepts m109's replacement-derived0→1witness without weakening positive occurrence counts, pins the underlying step detector and workflow problem statement, and rejects source, adapter, witness, XOR, registration, seal and suffix-order drift. The fixture remains byte-identical at SHA-256fb431715ec32253b4474c4993a46acbc0c20749b9f3162b31985c3f8668513e9; only the current hybrid source/slice digests move with the reviewed representation. The first executable replay exposed a false negative in the XOR self-control: it reinserted differently indented calls before the legacy body, shifting unrelated identities instead of reproducing the pinned nodes. The class fix SHA-pins both historical call-node byte spans, appends them after the closed legacy tail and rejects any order/root/matcher spillover. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client runtime, benchmark or evaluation workload runs on the maintainer MacBook; executable proof belongs exclusively to GitHub-hosted CI on the exact candidate and squash-main SHAs.
- The migration is one-for-one, not a census-only rewrite. Exact frozen IDs, source bytes, mutation modes, strings, occurrence counts, witnesses, invocation inputs, companions, problem identities and matcher ownership must agree for both migrated cases, while resurrecting either legacy form produces an explicit
1/1XOR failure. - Staged execution preserves historical order. The only admitted boundary is m037 with both exact adapters; the suffix is zero-argument, executes once after the remaining Registry loop and before m111, and finishes at 38 cases and 38 expectations.
- Release and product state are untouched. No workflow, runtime/product code, package or lockfile, version, tag, npm/GitHub Release/MCP Registry state, dist-tag, cleanup action or fixture regeneration is part of this boundary.
Coverage rerun isolation
TL;DR: The two exhaustive repository-integrity oracles still run in full on both blocking Node 22.13 and Node 24 legs, but are no longer repeated under V8 coverage instrumentation after those prerequisites pass. The coverage command omits exactly
tests/meta-invariant-coverage.test.tsandtests/release-integrity.test.ts; the existingsrc/**/*.tsinclude glob and reviewed registration-only exclusions, four global floors, per-file floor gate, all 1807 ordinary-suite registrations, the 480/330-second scoped oracle ceilings and the 10-minute coverage breaker remain in force. No product code, workflow, Vitest configuration, package version, tag or publication state changes.Method note: the still-executed
no-internal-importsinvariant pins the exact two-path coverage command, forbids npm pre/post hooks around either test command, and binds the complete reviewed step identities of the unfiltered fail-capable Node 22.13/24 matrix and prerequisite-bound coverage job. The manualprepublishOnlypath retains its complete reviewed gate sequence and must run one exactnpm teststage before the isolated coverage stage. It also pins the canonical static Vitest include/exclude set, Node environment, 15-second default, setup bootstrap, reporters and four global floors plus execution of the per-file floor gate; the reachable direct suite registrations and their 480/330-second bounds; and the reviewed nine-file transitive closure for direct module-loader forms. Type-only edges and files read solely as source text remain valid because they do not execute production modules. Existing positive and negative callbacks reject missing, additional, wildcard, reordered or fail-open prerequisites; hidden configuration filters; raised or unreachable timeout registrations; and unresolved, self-package, direct/transitivesrc/dist, Vitest-loader andcreateRequireedges without increasing the 1807 source-test declarations. Becausepackage.jsonis a frozen release-mutation source, a temporary branch-only GitHub-hosted Node 22 runner restored the pinned legacy source only while regenerating the fixture; the accepted artifact changed exactly five leaves acrossmanifest.package-jsonandrelease.m466, both fixture-digest pins now bind SHA-256fb431715ec32253b4474c4993a46acbc0c20749b9f3162b31985c3f8668513e9, and the capture workflow was removed before final CI. The first full remote replay exposed two self-test blind spots rather than product failures: the AST guard rejected the current parser's non-truedefault-export marker, and the inserted-step negative control spliced a validated copy instead of the parsed workflow's backing array. The class fix now rejects only an explicit export-equals assignment, preserves the validated backing step array for structural mutations and adds an exact export-equals control. The next replay exposed redundant self-audit work: every sibling mutation re-ran the full nine-file aggregate until the ordinary 15-second test ceiling expired. Reducing those traversals from 46 to 7 was still too slow under V8 instrumentation. One combined representative now mutates every aggregate input carrier, both scoped registrations and a transitive helper edge and must return the complete exact diagnostic vector; sibling controls call the same shared pure leaf detectors over minimal synthetic sources. That reduces full aggregate evaluations from 46 to 2 without dropping a failure direction or raising any timeout. The combined Vitest mutation changes both the config source and config-file census, so neither carrier can be silently disconnected. A final static adversarial review also closed three neighboring fail-open paths before merge: npm lifecycle hooks, unpinned Vitest execution values and mutable/unreviewed intermediate CI steps. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client runtime, benchmark or evaluation workload runs on the maintainer MacBook; executable proof belongs exclusively to GitHub-hosted CI on the exact candidate and squash-main SHAs.
- Coverage remains a production-code gate, not a filtered ordinary suite. The standalone coverage rerun changes only after both exact full-test matrix legs succeed;
vitest.config.tsretains thesrc/**/*.tsinclude glob, reviewed registration-only exclusions, reporters and four global thresholds, and CI still executes the per-file floor gate. - The omission cannot silently grow. The package command is an exact two-path literal contract, and the invariant rejects wildcards, duplicates, reordering, alternate config files, test-level excludes and every third or missing path.
- Reviewed import isolation is transitive and fail closed. The reviewed nine-file runtime closure contains no production module; a new local edge must be resolved and reviewed, while any reviewed direct module-loader edge into
src,distor the package's own public entrypoint blocks the change. - Release state is untouched. This is post-rc.2 CI hardening only: no version, lockfile dependency graph, release workflow, tag, dist-tag, npm/GitHub Release/MCP Registry write or publication occurs.
YAML and Canvas runtime patch refresh
TL;DR: The YAML/frontmatter parser and optional PDF-to-bitmap backend advance to their current compatible patch releases without changing Enquire's public contract.
js-yamlmoves from5.2.2to5.2.3, bringing own-key/null-prototype tag lookup and parser edge-case corrections; optional@napi-rs/canvasmoves from1.0.2to1.0.3, carrying upstream shadow, filter, gradient and native-renderer maintenance used only by the lazy OCR rasterization path. Canvas remains optional in both package manifests, and no runtime surface, Node floor, version, tag or publication state changes.Method note: the stale Dependabot PR was audited rather than merged: its package ranges and registry integrity values were re-derived from official upstream/npm metadata on exact current
main, while its redundant root-lock classification of Canvas as both ordinary and optional was rejected. Because the immutable release-mutation fixture intentionally retains the pre-migration legacy matrix, a disposable GitHub-hosted Node 22 runner temporarily supplies that exact frozen source only while regenerating candidate-dependent source bytes; the capture workflow is removed before final review and the resulting fixture is pinned at SHA-2561a57caa0ce49d1873e272cc4b65b1134284ad2a78072b5fb099b037d9c7e5fea. The admissible fixture delta is limited to themanifest.package-jsonandmanifest.package-locksource hashes plus the derivedrelease.m466witness/fingerprint, while all 30 sources, 560 mutations, 536 roots, 24 dependencies, 541 logical checks, 546 matcher leaves and every case identity remain unchanged. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client runtime, benchmark or evaluation workload runs on the maintainer MacBook; executable and compatibility proof belongs exclusively to GitHub-hosted CI on the exact candidate and squash-main SHAs.
- YAML lookup fails inside the parser contract. Upstream now resolves tags and mapping entries through own properties on null-prototype tables, avoiding prototype fallback and raw lookup errors for user-controlled YAML while preserving ordinary frontmatter and Bases parsing.
- Canvas stays a bounded optional backend. The native package and its 11 platform binaries move together to
1.0.3; Enquire still loads Canvas lazily only for PDF/OCR rasterization and retains the missing-backend path. - The lock mirrors the manifest exactly.
@napi-rs/canvasremains solely underoptionalDependencies; no new JavaScript package, override, advisory exception or audit allowlist is introduced. - Release state is untouched. This housekeeping patch does not change workflows in its final form, package version, tags, npm/GitHub Release/MCP Registry state, dist-tags or publication behavior.
TL;DR: The release audit's own test oracles now fail closed. Curated structural-test coverage must name every required file, negative-control callbacks must contain a recognized assertion call reachable inside their own bounded syntax, and release-control source mutations must match an exact nonzero occurrence count and actually change the fixture before an expected failure can count as evidence. Missing, stale, duplicate, vacuous, assertion-shaped-text, borrowed-assertion and no-op controls exercise those failure directions. Runtime, workflow behavior, version and the existing 1807 source-test declarations are unchanged.
Method note: this is repository hardening landed after the immutable
v4.0.0-rc.2tag and npm publication; it is not part of those published bytes. The patch was prepared by static inspection on exactmainunder D-45, with no local install, build, lint, test, coverage, smoke, OIA, package/client, benchmark or evaluation workload on the maintainer MacBook. Existing test callbacks carry the new self-controls without adding declarations; executable proof is delegated to GitHub-hosted CI on the exact PR SHA and then the squash-merge SHA. The first remote replay exposed two blind spots left by repeated static review: stale RUN/JOB pagination counts and a union-typed mutation helper that made literal needles appear regex-shaped to CodeQL. A second replay proved the narrowing remained analyzer-sensitive, so the class fix removed native regex mutation sinks entirely and converted the five live regex mutations to exact literal blocks before acceptance.
Current security correction (2026-08-03): later
GHSA-rgw5-rvv9-x895supersedes rc.9's then-current conclusion thatbrace-expansion@5.0.8was fully patched. The root override and sole lockfile node now select5.0.9; the historical rc.9 entry remains release context, not current security guidance. This is a dev-only TypeDoc → minimatch resolution, with no runtime dependency or audit-allowlist change.
Current security correction (2026-08-04): a later live-advisory refresh disclosed
GHSA-8j4g-w8fx-2239in the reachable Hono graph plusGHSA-7p8r-x3mc-p8w7and threeip-addressadvisories in two orphaned lockfile subgraphs. The reachable floor is now patchedhono@4.12.34; the staleajv-formats → ajv → fast-uriandexpress-rate-limit → ip-addresssubgraphs are removed instead of allowlisted or carried forward, while the defensivefast-urioverride floor advances to first-patched^3.1.5. The source allowlist remains empty.
PDF.js and nanoid advisory refresh
TL;DR: Two newly disclosed high-severity advisories are fixed at their first patched lines instead of being allowlisted. The direct optional PDF parser advances from
pdfjs-dist@6.1.200to6.2.108, closingGHSA-hq66-cqwq-w95j; the development-only PostCSS path resolvesnanoid@3.3.17, closingGHSA-2v37-7h3g-55p8. The source audit allowlist remains empty, and the PDF/OCR missing-dependency guidance now names the exact supported PDF.js floor.Method note: the advisories appeared in the live GitHub/npm data after the prior dependency candidate had completed CI, so their first failure on an unrelated release-oracle PR was temporal database drift rather than a regression from that PR. The exact dependency paths, patched versions and registry integrity values were re-derived from official advisory and package metadata. The dependency source change deliberately invalidates the frozen release-mutation fixture, so a disposable GitHub-hosted runner regenerated it from the exact candidate; the final candidate removes that temporary capture workflow and pins the new raw digest. Static differential review proves the inventory remains 30 sources, 560 mutations, 536 roots, 24 dependencies, 541 logical checks and 546 matcher leaves, with no changed case identity. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client, benchmark or evaluation workload ran on the maintainer MacBook; executable and compatibility proof belongs exclusively to GitHub-hosted CI on the exact candidate and squash-main SHAs.
- The PDF boundary is patched, not waived. Enquire does not construct PDF.js's browser viewer, annotation-layer or scripting-manager surface, but PDFs are untrusted input and a compatible upstream fix exists, so the optional runtime dependency moves to the first patched
6.2.108release without an audit exception. - The development graph remains strict.
vitest → vite → postcssalready permits nanoid's patched3.3.17within its existing semver range; only the exact lock resolution changes. Enquire does not import nanoid and the vulnerable custom zero-size generator path is absent from production, but a fixable high advisory still fails the source-tree gate. - The immutable identity graph is refreshed, not rebaselined. Only
manifest.package-json,manifest.package-lockand the derived witness/fingerprint forrelease.m466change; all 536 case records, every mutation expression/span and the complete topology remain byte-identical. - No policy gate is weakened. There is no new override or allowlist entry, no Node-floor, version, workflow, tag or publication change, and no public dependency write occurs in PR CI.
GitHub workflow schema rescue
TL;DR: The release workflow is valid under GitHub's own schema again, without weakening its one-shot publication transaction. Case-only proxy and npm configuration aliases no longer coexist in YAML
envmaps; lowercase variants are instead cleared or pinned by Bash builtins before the first external command. The roughly 45.7k-character Basic asset transaction no longer exceeds GitHub's 21,000-characterrunlimit: its exact body is loaded once, matched to a workflow-pinned SHA-256, and the same verified in-memory snapshot is executed through absolute protected Bash. Every repository workflow now has a structural case-folded-env and inline-command-length guard with negative controls. Versions, tags, npm, GitHub Releases and MCP Registry state are unchanged.Method note: GitHub rejected the exact squash-main
release.ymlbefore allocating a job and reported case-insensitive duplicateenvnames; a complete static census found 27 aliases, while the first error list exposed only a prefix. A second platform audit then compared every inline command with GitHub's documented 21,000-character ceiling and found one independent roughly 45.7k-character violation. The rescue preserves the former transaction byte-for-byte except for explicit repository/channel variables and the inherited lowercase-proxy cleanup. The wrapper reads the script from the exact workflow commit, not the selected source-tag checkout, so manual recovery of a compatible older immutable tag remains possible. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client, benchmark or evaluation workload ran on the maintainer MacBook; only YAML parsing, shell syntax, exact-diff and static census checks ran locally. Executable proof belongs exclusively to GitHub-hosted CI on the rescue PR and squash-main SHAs.
- The audit oracle now models GitHub rather than generic YAML alone. Every workflow
envmap rejects case-insensitive key collisions, everyrunscalar is bounded at 21,000 characters, and exact-boundary plus duplicate-key mutations prove both failure directions without increasing the 1807 source-test declarations. - Lowercase npm configuration remains pinned. The canonical uppercase YAML values are mirrored and exported under all nine lowercase spellings before
npm pack; the existing mixed-case purge and explicit publish envelope remain in force at the irreversible npm boundary. - Extraction preserves compatible historical-tag recovery without a mutable-path execution gap. The token-bearing wrapper reads the script blob from GitHub's exact workflow commit in an empty child environment with lazy fetch and replacement objects disabled, plus no inherited Git environment or system/global configuration; it snapshots the bytes once, compares one literal digest, and pipes those same bytes to protected Bash rather than executing the selected source-tag workspace pathname.
Repository mutation-oracle residual
TL;DR: The same fail-closed mutation contract now covers the remaining bounded repository oracles. A fresh AST census corrected the stale planning claim:
abs-path-leak-invariant,docs-consistencyandwrite-lifecycle-invariantcontained exactly 45 negative source mutations plus one ordinary whitespace normalization, not 45 plus nine. All 45 negatives now prove an exact nonzero live-source count and a changed result before their detector can pass; digit-bounded documentation counts retain whole-number semantics without regex mutation sinks. A fail-closed AST inventory permits only the one exact reviewed normalization and rejects new dot, bracket, extracted, destructured or prototypereplace/replaceAllaccess across the three files. Product code, workflows, versions, tags, publications and the 1807 source-test declarations are unchanged.Method note: the exact-main census and migration were performed by static inspection under D-45. The pre-change runtime inventory was 46 raw accesses: 45 mutation oracles (41 literal-string needles and four regex needles) plus one ordinary transform; a comment-only historical mention was excluded by the TypeScript AST. The regex cases were converted to exact literals or a manual ASCII-digit-boundary helper. Missing, duplicate, empty, invalid-count, no-op, first-versus-all, digit-lookalike, bracket, extraction, destructuring, prototype and helper-name-bypass self-controls were added inside an existing test callback. No local project workload ran; executable proof belongs to GitHub-hosted CI on the exact PR and squash-main SHAs.
Read-only Actions artifact/API temporal contract
TL;DR: Ordinary PR and main CI now prove that the exact MCPB archive exported by
upload-artifactis readable through the Actions REST API under its emitted artifact ID and has the emitted SHA-256 digest before any platform consumer can rely on it. The producer alone receivesactions: read, validates the official action's raw numeric-ID and 64-lowercase-hex digest outputs, retries failed read attempts under a fixed attempt/call budget, and fails closed on a missing identity, wrong media type, digest mismatch, or exhausted wait. Linux, Windows, and macOS still consume one canonical artifact through the pinned download action withdigest-mismatch: error. Both Docker smoke probes retain their wall-clock limits, add a TERM-to-KILL grace, preserve the bounded probe command status, and reject every nonzero exit before inspecting response markers.Method note: this is post-rc.2 repository/CI hardening and is not part of the immutable
v4.0.0-rc.2tag or npm bytes. The contract was re-derived from exact currentmain, GitHub's official Actions artifact REST documentation, and the exact pinnedactions/upload-artifactREADME:artifact-idis a positive decimal REST identity andartifact-digestis raw SHA-256 hex without asha256:prefix. The existing release-integrity declaration now checks producer-only least privilege, immediate upload-to-canary ordering, exact output bindings, explicit Bash execution with a non-inheritable startup hook, one exact ordered canary body, unchanged three-OS consumption, and exactly two Docker smoke bodies with fail-capable metadata and preserved exit status. Mutations cover missing/wrong ID, digest and media bindings; prefixed-digest acceptance; removed timeouts or kill grace; increased retry count; unreachable, prematurely successful, neutralized-digest and fail-open paths; shell/environment bypass; status swallowing; duplicate, borrowed or additional Docker commands; global permission expansion; and step reordering. Remote replays proved the canary, three-OS fan-out and Docker paths, then correctly rejected a stale upload-action mutation anchor, an incorrectly indented nested-digest mutation anchor, and formatter/lint drift; all were repaired without weakening a gate. Under D-45 no local project workload ran; executable proof belongs exclusively to GitHub-hosted CI on the exact candidate and squash-main SHAs.
- The readback is bounded twice. Each REST call has a 30-second TERM deadline plus a 5-second KILL grace; at most 12 calls run with five-second inter-attempt waits. The producer job budget increases from 30 to 40 minutes to add headroom for the bounded readback.
- The digest is compared without normalization. A
sha256:-prefixed or otherwise malformed upload output is rejected instead of stripped into an accepted value. The downloaded ZIP is hashed directly and compared byte-for-byte with the action output before the log records the exact artifact ID and digest. - No release-side mutation changes.
release.yml, version surfaces, tags, npm channels, GitHub Releases, MCP Registry state, and cleanup workflows are untouched. The source-test declaration count remains 1807.
Exact CI admission and strict external read models
TL;DR: Release admission now binds all 12 required jobs to one exact
CImain-push workflow run for the checked-out SHA instead of trusting repository-wide check-run names or GitHub's default latest-only job projection. The gate reads every execution withfilter=all, validates strict paginated workflow/job/artifact/release/asset shapes, positive safe IDs, exact run/SHA/workflow/attempt identity and envelope totals, then selects one unique maximum attempt per required job. Reordered rerun history cannot hide the newest failure, and duplicate maximum-attempt executions fail closed.[[]]is an authoritative empty array collection; an outer[], malformed pages/elements, unsafe identities and invalid digest types are not. GitHub Release absence requires six separately successful strict zero observations. A 230-minute internal clock beneath the 240-minute runner ceiling establishes the reserve boundary for later one-shot transaction lanes. npm publication, GitHub draft creation/asset upload/publication, MCP Registry publication, versions, tags and public state are unchanged; the source-test declaration count remains 1807.Method note: this is post-rc.2 repository/release-workflow hardening and is not part of the immutable
v4.0.0-rc.2tag or npm bytes. The contract was reconstructed from exactmain, GitHub's official workflow-run, all-execution Jobs and Release-asset response models, plus pinned read-only live Jobs-field evidence. Existing release-integrity declarations now exercise both response orders for old-success/new-failure and old-failure/new-success, duplicate maxima, foreign workflow/run/SHA/attempt identities, malformed200pages and elements, unsafe numeric identities, wrong digest types and the six-zero observation order without adding a top-level test. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client, benchmark or evaluation workload ran; executable proof belongs to GitHub-hosted CI on the exact candidate and squash-main SHAs.
- Reruns are evaluated by attempt, not response order. Untouched successful jobs may remain on an older attempt, while the unique greatest execution for each exact required name is authoritative; a greatest-attempt failure fails and a greatest-attempt pending job waits.
- Malformed reads cannot become absence or readiness. Every slurped collection has at least one page, Actions envelopes have coherent safe
total_countvalues, and every element is decoded before a count or classifier can authorize progress. Failed Release reads consume the bounded attempt budget but never increment the absence evidence. - Read deadlines cannot capture release writes. Every post-gate GitHub read consumes the internal clock through a helper that rejects mutation-capable REST/GraphQL arguments. The existing npm/create/upload/PATCH/Registry commands remain outside that helper and unchanged; transaction-specific reserves and one-shot reconciliation land separately in 5f.3–5f.5.
Exact npm tarball transaction
TL;DR: npm publication is now bound to one canonical tarball and its exact SHA-512 SRI instead of a mutable checkout directory or mandatory registry
gitHead. The release job packs once with lifecycle scripts disabled, verifies the sole internalpackage/package.json, independently hashes those exact bytes, reserves the complete post-write recovery budget, re-proves the remote annotated tag, re-reads one coherent full npm packument, re-hashes immediately before the write, and invokesnpm publishfor that exact file at most once with npm transport retries and lifecycle scripts disabled. A bounded fresh-packument loop then requires the exact SRI and channel before one final tag proof; a timeout or ambiguous nonzero publish exit can never authorize a second publish. Missing or nullgitHeadis accepted as optional metadata, while any present empty, malformed, non-string or divergent value fails closed. Versions, tags and public registry state are unchanged by this repository patch, and the source-test declaration count remains 1807.Method note: this is post-rc.2
mainhardening and is not part of the immutablev4.0.0-rc.2tag or npm bytes. The transaction was reconstructed from exact currentmain, D-54, npm's official full package-metadata model and the exact tarball-input publication path. One HTTP-200 full packument supplies version, SRI, optional source metadata and channel from the same bounded no-cache snapshot; package-level 404, transport failure, an oversized body, malformed JSON or a wrong document identity never becomes evidence that the exact version is absent. Existing declarations now cover the evaluator matrix, byte identity, reserve arithmetic, write ordering and no-replay mutations. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client, benchmark or evaluation workload ran on the maintainer MacBook; PR CI performs no public npm write, and executable proof belongs to GitHub-hosted CI on the exact candidate and squash-main SHAs.
- The immutable consumer bytes are primary. Pack metadata and an independent SHA-512 digest must agree before the registry is consulted, and the same file is hashed again immediately before its only publish invocation. Existing or eventually visible versions must expose that exact
dist.integrity; matching source metadata cannot compensate for a missing or different SRI. - Absence is a property of one valid package snapshot. Only a bounded HTTPS 200 full packument with the exact package name, object-shaped
versions/dist-tags, and no own key for the candidate version can select the publish path. An absent channel is represented separately from any present value, so a present sentinel or malformed SemVer cannot masquerade as absence. The abbreviated install document is deliberately rejected because it does not promisegitHead; separatenpm viewcalls and text-matched E404 output no longer decide publication. - Ambiguous writes reconcile instead of replaying. A 4,500-second reserve covers the immediate tag proof, fresh pre-write snapshot, 600-second publish deadline plus kill grace, all 12 readback attempts and waits, final tag proof, the bounded token-free provenance verifier and processing margin. The publish exit is recorded, not trusted as sole truth: exact registry convergence may prove success, while incomplete or divergent state fails for manual recovery without
dist-tag, unpublish or a second publish command.
One-shot GitHub Release transaction
TL;DR: GitHub Release creation, Basic-asset upload and draft publication now use one bounded write per irreversible boundary followed by authoritative reconciliation, never blind replay. A run may create one draft, issue at most one retry-free upload POST for each repeatedly confirmed missing asset, and issue at most one publish PATCH. Lost, timed-out or malformed responses are resolved through the exact release ID, canonical title/CHANGELOG body and asset identity; duplicate releases or assets,
starterstate, unexpected names, divergent metadata or bytes, and incomplete published state fail closed for manual recovery. The sorted six-asset projection freezes IDs, names, states, media types, positive sizes and SHA-256 digests across publication, with no delete, overwrite or clobber path.Method note: this is post-rc.2 repository/release-workflow hardening and is not part of the immutable
v4.0.0-rc.2tag, GitHub Release or npm bytes. The implementation was reconstructed from exact currentmainunder D-45; no local install, build, lint, test, coverage, smoke, OIA, package/client, benchmark or evaluation workload ran on the maintainer MacBook. Structural mutations pin write cardinality, transport retries, reserve/tag ordering, exact-ID convergence, full asset projection and the absence of destructive recovery commands. Executable proof belongs exclusively to GitHub-hosted CI on the exact candidate and squash-main SHAs; this patch itself performs no release, tag, npm or Registry mutation.
- Each write has a reserve and an exact-repository source proof. Draft creation, each missing-asset upload and draft publication reserve their bounded recovery windows and prove the GitHub repository's annotated-tag object before the sole write. Ambiguous non-contradictory results reconcile through fresh strict reads without replay; an explicitly contradictory response stops immediately for manual recovery. Successful or recovered paths end with the corresponding state postconditions and a final tag proof.
- Existing assets are proven before new ones are written. The workflow freezes local size/digest metadata, validates and downloads every already visible asset, then performs a final exact-ID draft/name-absence refresh followed by the local re-hash immediately before POST. The upload disables curlrc, transport retries, redirects and proxy use, and downloads the exact returned or recovered asset ID for byte comparison. Sensitive GitHub/npm transaction steps use privileged no-profile Bash, fresh configuration paths, exact registry/TLS/retry arguments, and explicitly clear the enumerated shell, loader, archive, debug, proxy, CA and Node injection variables covered by structural mutations.
- Public release metadata is part of identity. Every preflight, create recovery, upload reconciliation and published-reuse path requires
name == tagandbodybyte-equal to the canonical local CHANGELOG slice. A same-tag draft with stale, misleading or injected release notes is rejected before assets or publication can make it public. - This narrows inherited-state risk; it is not clean-runner isolation. Checkout credentials are not persisted, the captured deadline cannot be replaced through later job environment writes, and sensitive downloads/writes use fresh scratch paths where this patch establishes them. The release-time test suite no longer receives the contents-write token—the exact SHA's mandatory CI already ran the live metadata invariant. The job still installs and executes project dependencies before publication on the same runner with job-wide write/OIDC permissions; complete PATH, workspace, detached-process and token-lifecycle isolation requires a separate least-privilege clean publisher job and is deliberately not claimed here.
- Publication narrows, but does not claim CAS over, the Latest boundary. After reserve and tag proof, a fresh exact-ID release/asset snapshot must still match the frozen six-field projection; only then does stable publication re-read Latest and validate monotonic version advance immediately before PATCH. Both Latest reads separate CLI stdout from human-readable stderr, require one strict HTTP envelope and exactly one JSON document, and authorize absence only for GitHub's exact 404 status, media type and three-field body. Exact-ID, list, asset and stable-Latest reads must converge afterward. GitHub's Release API offers no value-CAS against an independent external publisher, so that separate publisher-exclusivity gate remains outside this patch.
Exact npm provenance source identity
TL;DR: A new npm version can be written only by the exact tag-push context that its provenance will describe, and every converged publication must expose the exact two cryptographically verified npm attestations for those bytes and that source. Immediately before the sole possible
npm publish, the release workflow compares independent GitHub-expression aliases with the runtimeGITHUB_*values and requires the canonical repository and owner IDs, GitHub-hosted runner,pushevent, tag ref, source SHA, workflow ref/SHA and positive invocation identity. At this intermediate pre-Gate-B boundary, a manual dispatch frommaincould still recover an already-valid publication, but it could not publish a checked-out tag while npm signed the unrelated controller ref; the rc.3 Gate B above now removes dispatch and retains only original tag-run reruns. After registry convergence, a separate token-free step uses an exact URL/SRI-pinned npm verifier in a clean scripts-disabled consumer and requires one exact package target plus exactly one npm publish v0.1 and one SLSA v1 DSSE statement. The verified Fulcio leaf certificate must contain exactly the expected tagged release-workflow SAN and the GitHub Actions OIDC issuer rather than merely trusting the statement to name its own signer. PURL, tarball SHA-512, repository, workflow, tag, event, source and invocation all fail closed on absence, duplication, malformed input or divergence.Method note: this is post-rc.2 repository/release-workflow hardening and is not part of the immutable
v4.0.0-rc.2tag or npm bytes. The gap was established from npm's official provenance generator and a public differential: rc.1's tag-push attestation names its tarball source, while rc.2'smain-based manual dispatch truthfully names the controller SHA/ref instead of the older checked-out tag. The patch does not rewrite provenance environment variables or infer success fromnpm audit signaturesalone: the pre-write gate rejects a mismatched OIDC context, and the post-write semantic evaluator inspects the exact bundles already verified by pinned npm. The full remote coverage replay also exposed that the growing mutation oracle reparsed the same roughly 152 KB workflow fixture for every evaluator-source mutation and crossed the shared 15-second test ceiling; workflow and evaluator-source validation are now separate, preserving every negative control while removing 38 redundant YAML parses. The optimized oracle then measured 14,996 ms under exact-head V8 coverage, so this one deliberately heavyweight case receives a 30-second ceiling while the repository-wide limit remains 15 seconds. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client, benchmark or evaluation workload ran on the maintainer MacBook; PR CI performs no npm write, and all executable proof belongs to GitHub-hosted runners on the exact candidate and squash-main SHAs.
- Fresh publication is tag-push-only; recovery remains resumable. The provenance context gate runs after the final tarball re-hash and only on the actual publish branch, before the attempt flag and write. At this intermediate boundary, dispatch could reuse a previously published exact version only when its signed source/tag/workflow evidence was canonical; rc.3 supersedes that route with a rerun of the original tag-push attempt. A fresh publication must additionally bind the signed invocation to the current run and attempt.
- Cryptographic success is necessary but not sufficient. The verifier requires empty
invalid/missingsets, one exact installed package, the canonical attestation endpoint and exactly two unique supported predicate types. Both statements must contain one identical PURL/SHA-512 subject; the SLSA statement additionally freezes the GitHub Actions build type, GitHub-hosted builder, exact tag dependency and invocation URL. Its already-verified X.509 leaf must parse from canonical DER, expose exactly the taggedoomkapwn/enquire-mcp/.github/workflows/release.ymlURI as its sole SAN, and carry an exact legacy and/or v2 Fulcio issuer extension forhttps://token.actions.githubusercontent.com. This blocks a different trusted OIDC provider from self-asserting our repository inside a signed payload. Reordered arrays and JSON object keys remain valid; unknown, missing or duplicate evidence does not. - The verifier has no publication credentials. Its pinned npm archive is independently SHA-512-checked before safe extraction, the isolated install disables scripts/audit/funding/optional dependencies and transport retries, and both installation and signature verification are wall-clock bounded. Signature retries force online metadata revalidation across a 70-second convergence window so one fresh but not-yet-attested cached packument cannot decide every attempt. npm, GitHub, OIDC, shell-loader, proxy, CA and Node injection variables are removed from the child environment; the step sits after npm convergence and before any GitHub Release mutation.
- The trust-root residual stays explicit. This closes the observed event/source mismatch inside the current release workflow; it does not make tag-loaded workflow code immutable, prevent another credential holder from publishing, or provide a repository-wide CAS. Immutable release tags, a trusted default-branch controller, clean least-privilege publisher-job isolation and trusted publishing remain separate owner-gated hardening decisions.
Exact MCP Registry reconciliation
TL;DR: Stable MCP Registry publication is now a bounded reconciliation transaction, not an unconditional command. Exact-version and Latest reads include deleted records and feed one pure fail-closed evaluator: only a schema-bound reviewed
server.jsoninactive+isLateststate may be reused, while only the Registry's exact production 404 shape can authorize a first publish. A deleted, deprecated, non-latest, semantically divergent, malformed or unreadable version never becomes absence. The exact-pinned publisher validates one byte-bound reviewed manifest snapshot, logs in through GitHub OIDC, and may invokepublishonce; a timeout or ambiguous exit is resolved only by bounded exact+Latest readback, never by replay. This repository patch changes no version, tag, npm channel, GitHub Release or public Registry state, and the source-test declaration count remains 1807.Method note: the transaction was re-derived from the official live Registry OpenAPI, the pinned
mcp-publisher v1.7.9source and read-only production probes of the existing3.11.6record plus the deliberately absent4.0.0-rc.2record. Those probes confirmed both the strict200 application/jsonand three-field404 application/problem+jsonenvelopes, while intermittent near-timeout responses proved that a single request is not a safe release oracle. The audit also rediscovered a prior regression class: promotional copy had expandedserver.json#descriptionfrom a previously valid value to 135 characters, beyond the current 100-character schema ceiling, because the earlier fix had no persistent schema-bound invariant. The description is now an exact 100-character TOP-1 line and the pure manifest contract makes the same drift fail closed. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client, benchmark or evaluation workload ran on the maintainer MacBook; the Registry fixtures and leaf mutation controls reuse the existing test declaration, and executable proof belongs exclusively to GitHub-hosted CI.
- Absence is exact and tombstone-aware. Reads use URL-encoded name/version detail endpoints with
include_deleted=true; fuzzy search, list pagination and text-matched errors are outside the write-decision boundary. A production-shaped exact 404 may selectpublish, while every HTTP 200 must carry one exact server document plus required official status, timestamps and boolean Latest metadata. Object-key order is irrelevant, array order and every manifest field remain semantic identity. - The reviewed manifest is the write input. npm publication outputs, package name/version,
mcpName, repository identity, schema URL, description bound, package version and stdio transport must agree. The workflow no longer rewritesserver.jsonat runtime: it snapshots the tracked bytes in isolated scratch space, validates and hashes that snapshot, and re-hashes it immediately before the sole possible publish command. - Every irreversible edge has a clock and source proof. The whole Registry lane consumes the release job's global deadline. Publisher download, archive identity, validation, OIDC login, the sole publish and all readbacks have explicit wall-clock bounds; the remote annotated tag is proven before the first read, on every reuse path, directly before the write and after convergence. Network/429/5xx/visibility lag may retry only during post-write reconciliation; identity or lifecycle divergence is terminal.
- This closes Registry state reconciliation, not the publisher trust root. PR CI exercises pure fixtures and mutation oracles but performs no Registry login or write. The job still inherits repository code execution plus job-wide GitHub/OIDC permissions, so trusted default-branch control, immutable tags, publisher exclusivity and clean least-privilege publisher jobs remain the separate owner-gated Gate B.
Aggregate release-mutation planner foundation
TL;DR: The monolithic release oracle now has a fail-closed declarative planner ready for its complete migration. Canonical named sources, validated mutation and detector identities, exact first/all replacement cardinality, changed-output and bounded positive-witness checks, dependency/DAG validation, reachability, stable aggregate diagnostics and a hard preflight seal are defined in one pure test-support state machine. A dirty preflight executes zero detector closures: every locally applicable descriptor is visited once, a malformed witness cannot suppress cardinality validation, and every dependency-blocked descriptor is reported explicitly. Only an entirely clean sealed graph may execute deferred detectors with complete root use and a declared count of immediate void-returning check callbacks. The initial regional AST census pinned 556 direct call sites, but the follow-up execution-multiplicity sweep proved that one all-mode site ran across five tag-proof tuples. Those tuples are now explicit, so the runtime inventory is exactly 560 project cases—538 first-occurrence and 22 all-occurrence operations—plus 20 bounded helper self-controls. This preparatory work deliberately does not claim that the 560 cases are already migrated or that 5f.5a is closed.
Method note: the planner boundary follows a fresh exact-main AST census after PR #429's remote cascade proved that the first stale literal hid every later target defect. A follow-up runtime-multiplicity sweep then checked every helper call against its execution context and found the one class the syntax-node count could not see: one
replaceAllExactlyinside a five-row tuple loop represented five different semantic cases. The loop is expanded and helpers in execution-multiplying loop bodies/bindings, maps, nested functions/classes, destructuring defaults, optional chains or conditional paths are now rejected conservatively as non-straight-line cases. A fail-closed module-load audit runs before Vitest can enter the matrix callback, bindsdescribe/itto their exact unaliased Vitest imports and pins one ordinary top-level suite plus one direct zero-argument matrix registration, so binding shadows, callback returns,describe.skip, context skipping or conditional registration cannot silently turn the semantic inventory into zero executions. The corrected census still distinguishes rawrelease.yml, the raw GitHub transaction script and their combined fixture rather than collapsing their tag-proof counts:8/4/4/4/4plus2/1/1/1/1equals the combined10/5/5/5/5; a mutation-free sibling proves that one extra raw proof-shaped occurrence changes only the expected raw count. Synthetic siblings inject missing, duplicate-count, no-op, prefix-preserving boundary, invalid-witness, identity, dependency, cycle, blocked-descendant and orphan defects and require stable reports without executing a detector. Clean, directly-returned-async, swallowed-outer-violation and retained-reference siblings prove JavaScript replacement-token parity—including literal$1/$01/$<name>/$0and mutation-output replacements—plus detector scoping, immediate-return guards and the immutable seal/execute boundary. The first disposable replay then exposed two concrete test-contract defects: expression-bodied Vitest matcher calls return a value rather thanundefined, and a later wrapped or detector-level synchronous fault could mask an earlier caught sticky scope fault. Accepted checks now use explicit statement bodies, and synchronous wrapped-assertion plus detector-throw paths rethrow the first recorded violation; explicit later assertion/detector faults prove that neither guard was weakened. The first PR coverage replay also crossed the former scoped 30-second ceiling only after the new full-source reachability and binding controls were added; the matrix keeps a bounded 60-second ceiling while the repository-wide default stays at 15 seconds. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client, benchmark or evaluation workload ran on the maintainer MacBook. The existing release-integrity declaration carries the controls without increasing the 1807 source-test count; executable proof belongs exclusively to GitHub-hosted CI.
- Registration cannot become execution by accident. Sources, descriptors, inventory and detector metadata are snapshotted at registration; retained caller references cannot rewrite the sealed graph. Execution requires a clean seal, complete declared-root consumption and the declared number of wrapped callbacks whose immediate return is
undefined. Directly returned async callbacks/checks, caught outer scope/check failures and unexpected sealing failures leave a terminal failed state. - The inventory lock now counts semantic cases rather than syntax nodes. The five tag-proof tuples are five explicit all-mode calls, so the reviewed project split is
538 first + 22 all = 560; the separate 20 helper self-controls remain bounded. The module-load invariant pins exact Vitest bindings plus direct unskipped suite/test registration and rejects count/mode/boundary drift, helper or test-binding aliases/shadows, parenthesized bypasses, suite or matrix early returns, context/conditional skipping and non-straight-line helper cases that could be skipped or multiplied. Negative loop-body/binding, callback-map, optional-call, logical-assignment, destructuring-default and repeated-class controls close neighboring syntax; positive iterable-array and nested-straight-line controls keep explicit once-only composition valid. - The next migration remains mandatory. Only the follow-up that gives all 560 project cases unique literal IDs, canonical source references, opaque dependency handles and closed queued detector expectations can close 5f.5a and unblock dist-tag reconciliation. Callback identity is snapshotted, but this runtime foundation does not inspect callback bodies: mutable captured state, a vacuous check body, an internally swallowed matcher error or detached fire-and-forget work remain possible. The full migration must keep detector inputs inside the named graph and replace arbitrary per-case callbacks with a closed declarative assertion primitive before claiming semantic/non-deferred detector coverage. This foundation changes no workflow, product behavior, version, tag, npm/GitHub Release/MCP Registry state or publication path.
Closed release-mutation data DSL
TL;DR: The release-mutation planner no longer accepts arbitrary detector callbacks. Plan-owned opaque source and mutation handles feed a closed data-only invocation union; every semantic case names one explicit mutation root, one clean source-lineage baseline and a non-empty inventory of exact-problem, equality, inequality or allowlisted named-regex expectations. One aggregate seal snapshots and validates the complete graph, materializes both baseline and mutant, rejects equal outputs, invalid roots, foreign or forged handles, unreachable mutations and incompatible expectations, and only then permits one exhaustive dispatcher to execute cases in registration order. The hybrid source invariant keeps
legacy + declarative = 560separately at538 first + 22 all; when legacy reaches zero it additionally requires exactly 560 unique descriptors, 536 cases and roots, 541 expectations and 24 dependency-only nodes. This boundary deliberately migrates none of the 560 production cases yet, does not close 5f.5a and does not unlock 5f.6.Method note: the closed grammar was derived from D-58 and adversarially reviewed against vacuous callbacks, swallowed failures, detached work, replacement-only baselines, equal baseline/mutant outputs, invalid-case reachability and registration-time re-entrancy. The review found a concrete
Proxytrap path that could enterseal()while a registration snapshot was still active; registration now has an explicit non-reentrant phase guard, snapshot inspection is depth/size-bounded, and accessors, functions, thenables, cycles, sparse/custom arrays and non-plain objects are rejected as data. Proxy traps may run during JavaScript reflection, but they cannot re-enter the plan lifecycle. Static controls require direct top-level handle bindings, literal IDs and modes, exact case/invocation/expectation shapes, one global clean seal assertion and one subsequent execution. Self-hosted negative controls resolve each edit inside the exact injected prelude and pin one scoped occurrence, so an earlier copy of the same token in the test source cannot make a supposed mutation a no-op. The first full remote coverage replay exposed scaling rather than a semantic failure: 19 new adversarial fixtures each reparsed and walked the complete source, while the visitor also computed source offsets for every unrelated AST node. Candidate-first dispatch now performs that work only for the five closed declarative method names or the exact plan binding, identical positive-control scans are reused, and wrong-receiver/computed/aliased controls prove the optimization did not narrow the fail-closed surface. A subsequent optimized replay still completed every other test but reached the exact 60-second per-test ceiling under V8 coverage, so only this exhaustive matrix now has a bounded 120-second ceiling; the repository default remains unchanged. A subsequent independent audit then found that identifier-computed or destructured plan methods could evade that named-method census while adding a runtime case; all non-direct uses of the exact plan binding are now rejected, and the runtime inventory independently pins cases, expectations, unique roots and dependency-only mutations. A final prototype audit found that replacingReleaseMutationPlan.prototype.sealandexecutecould preserve the required syntax while suppressing the runtime oracle. The constructor and prototype are now frozen, each instance is sealed, constructor value-use is restricted to direct construction or type positions, exact Vitest/planner import declarations exclude aliases, namespaces and hoisted mocks, andexpectis pinned to direct or allowlisted static calls without optional chains. Direct dynamic-code constructors are rejected; captured seal/freeze/push/regex/reflection primitives plus a descriptor-level ambient-intrinsic fingerprint cover accessors, species and iterator prototypes, preventing collection or matcher monkey-patching and proxy-triggered reflection TOCTOU from hollowing out validation. The canonical lifecycle must end with exact executed phase, case count and expectation count, with indexed execution proving every closed expectation began. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client, benchmark or evaluation workload ran on the maintainer MacBook; executable proof belongs exclusively to GitHub-hosted CI on the exact PR and squash-main SHAs.
- Baseline evidence is negative as well as positive. Equality requires the baseline not to equal the expected mutant value; inequality requires the baseline to equal the forbidden value; a named regex must miss the baseline and match the mutant. Dedicated counterexamples fail when both sides already satisfy inequality or both sides already match the named regex, so mutant-only weakening cannot pass unnoticed. The throw fixture evaluates the clean input without an exception and emits one exact problem identity only when the mutant crosses its reviewed trigger; incompatible expectations produce one exact type diagnostic rather than duplicate noise.
- Handles carry authority, not caller-readable data. Frozen empty tokens are resolved through private plan ownership metadata. A case root must be one unique registered mutation; its baseline may follow only the root's source lineage, while replacement dependencies remain dependency-only unless independently rooted. Full plans pin mutation modes and the complete case/expectation/root/dependency topology at runtime, so a syntactically hidden extra case cannot preserve the declared graph by count.
- The migration bridge pins topology, not semantic identity by count alone. Declarative registrations cannot hide in loops, callbacks, aliases, computed properties, evaluated descriptor fields or conditional paths. Every intermediate boundary preserves the exact first/all total, while the complete root/expectation/dependency inventory activates only at
legacy = 0; the runtime seal independently rejects orphaned or invalid graphs throughout the migration. The bounded migration PRs must still add an independently reviewed legacy-to-descriptor identity manifest before the final zero-legacy boundary—correct cardinalities alone cannot prove one-for-one semantic substitution. - Release state is unchanged.
release.yml, product/runtime code, package version, tags, npm channels, GitHub Releases, MCP Registry records and the existing 1807 source-test declarations are untouched.
Exact GitHub Release mutation problem identities
TL;DR: Every GitHub Release transaction mutation now names the exact problem it must expose instead of accepting any non-empty diagnostic array. The 46 upload/publication/snapshot roots that already had specialized exact assertions no longer pass through a redundant generic loop. The remaining 76 roots are literal
{ mutant, expectedProblem }records whose ordered subject-specific identities cover environment sealing, the hash-pinned script, strict Latest reads, metadata, draft creation, upload, six-asset identity, publication and recovery. Their one fixed 76-position numeric execution loop requires.toContain(expectedProblem)without trusting mutable iterator intrinsics. The complete release inventory remains 560 mutations (538 first + 22 all), 536 roots, 541 expectations and 24 dependency-only nodes; none is migrated to the declarative planner by this prerequisite.Method note: an independent identity-manifest audit found that the former
.not.toEqual([])loop let 76 roots borrow any neighboring detector, including multi-trigger mutations that legitimately emit more than one problem. The class fix keeps detector strings independent and adds a TypeScript-AST invariant over the exact 76-position literal profile, direct mutation calls, fixed numeric assertion loop, exact matrix callback and one top-level non-shadowed, non-reassigned detector binding. Negative controls replace the matcher with a generic non-empty assertion, borrow the script-snapshot problem for the environment-plus-scriptGH_CONFIG_DIRmutation, makeexpectedProblemcomputed, shadow or reassign the detector, and regress the loop to mutableArray.prototype.entries; all must fail without adding a new source-test declaration. A raw-expression-preserving static census also confirms that the 560 mutation calls retain their exact source, needle, replacement, mode and occurrence semantics after the record conversion. The patch was prepared by static inspection on exactmainunder D-45. No local install, build, lint, test, coverage, smoke, OIA, package/client, benchmark or evaluation workload ran on the maintainer MacBook; executable proof belongs exclusively to GitHub-hosted CI on the exact candidate and squash-main SHAs.
- Exact identity is stronger than an allowlist. The invariant pins the selected problem at every ordinal, so a mutation that trips both a broad hash-canary and its subject-specific upload/publication/recovery detector cannot satisfy the case with the wrong valid message.
- The matrix loses only redundant assertions. Twenty upload, 22 publication and four snapshot-shape roots retain their existing specialized exact loops; removing their three spreads changes 122 generic plus 46 exact checks into exactly 76 exact plus 46 exact checks without changing a mutation call, replacement mode, dependency or detector.
- Release and product state are unchanged.
release.yml, runtime code, versions, tags, npm/GitHub Release/MCP Registry state, cleanup workflows and the 1807 source-test declarations are untouched.
Atomic release-mutation check pairs
TL;DR: A closed release-mutation check now binds exactly one invocation to exactly one expectation. Cases carry an ordered
checksinventory instead of one invocation plus a freely associated expectation array, so a future production case cannot collapse distinct probes onto one observation or borrow a valid expectation from a different invocation. Aggregate preflight validates every pair, the sealed plan replays every invocation in order, and execution counters prove that every registered logical check began. The 560 production mutations remain entirely legacy at this boundary; this prerequisite does not claim a semantic migration, a finished identity manifest or closure of 5f.5a.Method note: an independent exact-main audit of the quarantined identity-manifest prototype found that the former case shape could not represent the real detector graph. The target still contains 536 primary cases and 541 logical check records, but the registry-composition checks each preserve several leaf matcher conditions behind one future allowlisted composite observation. This patch fixes that data-model ambiguity before manifest generation: runtime fixtures execute distinct text/throw probes in one case, permit the same expectation semantic only when the invocation identity differs, and reject missing, collapsed, reordered or duplicate exact pairings. The 560 legacy project cases and all of their current matcher evaluations are unchanged. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client, benchmark or evaluation workload ran on the maintainer MacBook; executable proof belongs exclusively to GitHub-hosted CI on the exact candidate and squash-main SHAs.
- Pair identity is the unit of duplication and execution. Two checks may legitimately expect the same exact problem from different closed invocations; the same invocation plus the same semantic expectation is redundant and fails preflight even when its ID differs.
- The AST invariant matches the runtime grammar. Declarative cases require literal
checks, every element has onlyinvokeandexpectation, and structural controls reject the old array shape, missing pairs, cross-probe expectation swaps and attempts to place several expectations behind one invocation. - Release and product state are unchanged. No workflow, product/runtime code, version, tag, npm/GitHub Release/MCP Registry state, cleanup job or source-test declaration changes in this boundary.
Frozen release-mutation semantic identity
TL;DR: The complete legacy release-mutation matrix now has one deterministic, reviewable semantic identity manifest before any migration begins. It freezes 30 materialized sources, all 560 mutations (
538 first + 22 all), 536 roots, 24 dependency-only nodes, 541 logical checks and 546 raw matcher leaves, including exact source/replacement edges, invocation inputs, expectation identities, assertion spans, witnesses and the 76-record GitHub Release transaction profile. This boundary still migrates 0 of 560 production mutations; it prevents a later cardinality-preserving swap, omission or detector reassignment from masquerading as a faithful declarative conversion.Method note: a dependency-free, read-only generator accepts no arguments, pins both the complete
release-integrity.test.tsSHA-256 and the exact matrix-slice SHA-256, and emits canonical JSON to stdout with one source, mutation or case per reviewable line. A separate TypeScript-AST auditor does not import that generator or share its normalizer: it independently materializes the closed 30-source catalogue, resolves raw expressions, applies JavaScript replacement semantics, validates content/mutant hashes and positive witnesses, re-censuses the graph and binds every root to its exact detector class and expectation. The existing meta-invariant runs the generator twice, requires byte-identical output and an externally pinned fixture digest, proves the generator did not write the fixture, then exercises duplicate-key, source-drift, raw/resolved, graph, invocation and named-regex negative controls. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client, benchmark or evaluation workload ran on the maintainer MacBook; executable proof belongs exclusively to GitHub-hosted CI on the exact candidate and squash-main SHAs.
- Identity is wider than mutation text. Every source has an independent content digest and semantic fingerprint; every mutation binds its legacy ordinal, mode, occurrence, raw and resolved expressions, source lineage, replacement dependency, owner root, source span and before/after witness; every case binds its ordered checks, closed invocation signature and exact matcher leaves.
- The two oracles fail independently. The generator cannot stamp reviewed provenance over changed source bytes, while the auditor reads only its hardcoded repository-relative source catalogue, rejects duplicate JSON keys and unknown schema fields, and recomputes fingerprints from the independently reconstructed graph. A valid count with unrelated identities is therefore insufficient.
- The fixture remains a migration prerequisite, not a migration claim.
release.yml, runtime/product code, package version, tags, npm/GitHub Release/MCP Registry state and the existing 1807 source-test declarations are unchanged. The next bounded PRs may replace legacy calls only while preserving this exact identity graph.
First migration-aware release-mutation family
TL;DR: The first 36 frozen release-mutation identities now move from one shared legacy loop into the closed declarative planner without changing, rebaselining or regenerating the reviewed fixture. The migration-aware auditor requires every one of the 560 frozen IDs to exist on exactly one side of a disjoint legacy/declarative partition.
release.m002…release.m037preserve their exact Registry-evaluator source, first/all mode, literal replacement, cardinality, positive witness, root, invocation and problem identity; the remaining legacy inventory is exactly 524 mutations (505 first + 19 all), while the combined inventory remains 560 (538 first + 22 all) with the same 536 roots, 24 dependency-only nodes, 541 logical checks and 546 matcher leaves.Method note: this is one atomic migration boundary and does not itself refresh the fixture. It consumes the advisory-updated, externally pinned 1,138-line fixture from PR #440 at digest
b1bef74ea285f53f8acf3c78d942db4880f06648c50b051351e0e004c73253d3; that prior refresh changed only the package-manifest source identities and the derivedrelease.m466witness/fingerprint while preserving every case and the complete graph. The fixture's internal provenance, source catalogue, materialized bytes, fingerprints and witnesses remain independently validated. Shifted current-source offsets are not treated as identity: remaining legacy calls and matcher leaves are matched by their frozen ordered AST-text hashes, while the 36 declarative descriptors/cases are parsed from literal straight-line registrations and compared field-for-field with the frozen rows. Separate exact digests pin both the complete currentrelease-integrity.test.tssource and its mixed matrix slice; each must be deliberately reviewed and advanced with a migration batch. This closes detector-body, source-carrier, value-flow, reachability and wrapper substitutions while the legacy half remains. Byte drift, missing/overlapping or unknown migrated IDs, semantic swaps, descriptor drift, source/root/invocation transplants, cross-boundary dependency splits, execute-adapter drift, frozen-source-object overrides, ambient intrinsic replacement and detector/problem-prelude/helper alias, write or body drift are negative controls. Remote replays additionally exposed formatter drift, a raw-tuple ordinal incorrectly reused inside an AST-hash bucket forrelease.m111,release.m258andrelease.m433, and a duplicate-key control that ignored the mandatory fixture-digest alarm. The class repair maps legacy rows by authoritative filtered order, audits hash multiplicity separately, exercises unique-second/shared-hash cases, and requires every fixture-tamper control to retain the digest alarm. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client, benchmark or evaluation workload runs on the maintainer MacBook; executable proof belongs exclusively to GitHub-hosted CI on the exact candidate and squash-main SHAs.
- Production detector access stays one closed seam. Cases contain only
registry.evaluator, one clean baseline handle, one exact mutant root and the reviewed Registry problem identity. The planner owns materialization and the differential: it invokes the one structurally pinned detector for both sides, requires a clean baseline, validates a dense exact problem inventory and rejects arbitrary per-case callbacks, hard-coded observations, getters, thenables, extra fields, unknown identities and duplicate problems. - The immutable fixture remains the authority across mixed representation. The historical generator is no longer rerun against the intentionally changed matrix source. The current auditor instead proves the frozen graph itself, pins the real Registry detector/problem/prelude nodes, and requires the explicit cumulative migrated-ID allowlist plus exact remaining-legacy order.
- The hybrid source is locked between reviewed migrations. Intentionally moving full-source and matrix-slice digests pin every detector/helper body and every byte from the matrix's first source read through its final assertion. The source map is one frozen 14-property object with no spread, computed or duplicate override;
String.prototype.includes, the exact Registry detector and the mutation counter retain their reviewed implementations and bindings. This supplements rather than replaces the immutable historical fixture. - Release and product state are unchanged. This migration changes test support and release-oracle declarations only: no workflow, runtime/product behavior, package version, tag, npm/GitHub Release/MCP Registry state, publication path, cleanup job or source-test declaration changes.
Exact-tree coverage runner variance
TL;DR: The two exhaustive release-mutation invariants retain bounded hang detection without treating ordinary GitHub-hosted runner variance as a logic failure. The immutable-identity meta hook moves from a scoped 90-second ceiling to 180 seconds, and the unchanged 560-case release matrix moves from 120 to 240 seconds. Global Vitest limits, the coverage job's 10-minute hard ceiling, every existing mutation identity and semantic check, and all production and release behavior remain unchanged; one new structural negative control pins the larger matrix budget.
Method note: PR #439's exact head and its squash-main commit have the same Git tree
b16ce94a71ec94179653c36d27fc1057b2a66b7e. The PR runner completed the two heavy paths in 63.9 and 79.6 seconds, while two distinct main runners completed the same synchronous work in 125.2/126.7 and 168.3/169.9 seconds before Vitest reported the former 90/120-second timeouts. A second rerun therefore reproduced infrastructure sensitivity rather than adding evidence for a code regression. The repair changes only those two literal per-hook/per-test ceilings, structurally pins the 240-second matrix budget, and adds a negative control that lowers it back to 120 seconds and must fail inventory admission. Under D-45 no local project workload ran; all executable proof remains on GitHub-hosted CI.
- This is containment, not an assurance reduction. Both ceilings remain below the job's independent hard limit, no assertion is skipped or sharded, and the same complete graph still executes before coverage can pass.
- The scalability follow-up remains explicit. The meta hook performs 22 complete parses/audits of the full matrix and immutable fixture at this boundary; the separately reviewable prepared-auditor class fix below removes that repetition without coupling it to restoration of green
main. - No release state changes. The patch does not touch
release.yml, product/runtime code, package manifests, versions, tags, npm, GitHub Releases, MCP Registry state, dist-tags or publication workflows.
Prepared release-mutation audit reuse
TL;DR: The exhaustive meta-oracle now prepares its immutable 1.45 MB identity fixture once for all 48 matrix audits routed through the prepared auditor, while preserving a fresh TypeScript AST and every matrix-dependent and cross-axis validation for each call. Each fresh AST builds its constant-declaration index once and resolves root-to-assertion flow through one reverse adjacency graph instead of rescanning the complete tree and every binding flow for every consumer. It materializes the 560-node mutation graph once, reuses it for 45 calls only when all 30 independently reconstructed source strings compare byte-for-byte with the captured clean projection, and deliberately bypasses that cache for two source-catalogue drifts. The four altered-fixture controls retain the canonical one-shot path, global and scoped timeouts remain unchanged, and no assertion, mutation identity or detector is removed.
Method note: static phase mapping found that the former 22 calls repeated duplicate-key JSON parsing, frozen provenance, inventory, mutation/case topology, semantic fingerprints and materialized mutation witnesses even though 19 calls used one byte-identical fixture and 17 retained one exact source projection. It also found five identical whole-AST constant-declaration walks per valid candidate and a complete variable-flow rescan for every legacy matcher. The class fix deep-freezes the parsed plain-JSON graph, buffers each manifest-only diagnostic slice so the canonical wrapper preserves its prior fail-closed order, builds one candidate-local declaration index and one fresh symbol adjacency graph, and exposes only
auditMatrixplus immutable telemetry—never the fixture, AST or internal phases. State-isolation, fresh-diagnostic-array, prepared-versus-one-shot equivalence, duplicate-key, exact reuse-count, source-catalogue-bypass and all-30-slot projection-comparator controls keep the optimization non-vacuous. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client, benchmark or evaluation workload ran on the maintainer MacBook; executable proof and any timing claim belong exclusively to GitHub-hosted CI on the exact candidate and squash-main SHAs.
- Reuse is exact and local, not a global memo. Each auditor instance owns at most one clean source projection. A source-catalogue drift bypasses the graph cache; any independently materialized source problem or byte difference forces a fresh graph evaluation and cannot replace the captured projection.
- Candidate-sensitive work remains complete. Full-source and matrix-slice digests, AST parsing, raw-expression shape, source catalogue, cardinality constants, declarative scan, hybrid XOR partition, remaining legacy matchers and Registry evaluator/run pins run for every matrix candidate.
- The public diagnostic contract remains stable.
releaseMutationIdentityAuditProblemsis still the canonical one-shot entrypoint, now composed from a fresh prepared auditor. Every call returns a new mutable diagnostics array, while the prepared fixture and cached projection remain recursively immutable and inaccessible. - Release and product state remain unchanged. No production source, workflow, package manifest, version, tag, npm/GitHub Release/MCP Registry state, publication path, fixture bytes, release matrix or timeout changes in this checkpoint.
Staged release-mutation execution prerequisites
TL;DR: The closed release-mutation planner and its independent identity auditor now support one fully sealed graph whose cases can execute in two exact source-ordered stages. The planner adds closed
registry.step.runandregistry.step.integrityinvocations, validates and pins the complete adapter set required by both prefix and suffix before the first detector runs, executes through one plan-owned case root, and resumes the remaining cases without accepting another adapter. The identity auditor separately reconstructs the exact global(case, root)execution trace across declarative stages and legacy matcher sites. Physical matcher multiplicity is counted by distinct remaining frozen spans, so one shared loop can straddle a migration boundary without hiding duplication of those frozen spans or falsely requiring their removal. This checkpoint migrates no additional release mutations: the declarative partition remains 36 of 560.Method note: the prerequisite was designed from the frozen 560-mutation identity graph and reviewed against the next bounded Registry-step family before that family was moved. Focused controls cover both argument orders, a full execution, and an inclusive
releaseMutationM018prefix plus its pinned suffix; the alternate staged source is accepted with only the two intentionally moving source digests. Negative controls additionally cover wrong prefix phase or derived census, a missing, replayed or adapter-reinjected suffix, a missing prefix adapter, nested or computed lifecycle calls, dependency-only and foreign boundaries, terminal-prefix cleanup, malformed and cross-family results, invalid companion handles, ambient-intrinsic poisoning during result inspection, runtimeReflect.setattempts against the active cursor, adapter capsule, lifecycle and prepared-case inventory both inside the prefix detector and between stages, migrated-matcher resurrection, residual-matcher removal or duplication, aliased, copied, reversed, wrapped and conditionally skipped shared iterables, a callback-level early return, exact ownerless-prefix tampering, discarded direct/carrier root values, tuple/object binding swaps, reversed Registry-step companion arguments, a shortened indexed loop and a staged suffix moved behind a shared legacy matcher. The first remote candidate exposed formatter drift, one intentionally reviewedReleaseMutationPlanheritage use omitted from its closed reference census, and an accidental extraction of frozen legacy caserelease.m111; the class repair admits exactly that one heritage site, rejects any alternate subclass and restores the original nested mutation/matcher identity while testing the raw-run adapter separately. The second remote candidate exposed a second frozen-range violation plus one stale negative-control expectation: a redundant raw-run assertion had been inserted between the two matcher leaves of composite caserelease.m038, while the control still named the obsolete full-only lifecycle. The class repair removes that interleaved duplicate in favour of the dedicated raw-run positive/negative controls, uses a comment-only source drift that cannot perturb matcher topology and reuses the exact full-or-staged lifecycle problem. The third remote candidate then corrected the discarded-root control's observed shared-array cardinality from 36 to 35 and moved the canonical baseline assertion ahead of mutant-diagnostic comparison, so a stale negative expectation can no longer mask a real baseline regression. The fourth remote candidate exposed one self-referential mutation needle: the bare transaction-loop header matched both a pre-matrix identity-control string and the real execution loop. A complete static census of all 51 matrix-derived exact replacements found no second count mismatch; the shortened-loop control now uses the unique two-line loop-and-binding prefix, so it can mutate only the intended runtime topology. The fifth remote candidate passed the complete Node 22, Node 24 and macOS suites, then proved that coverage was doing sustained work rather than hanging: the meta hook grew from 24 to 53 candidate-audit invocations (23 to 52 full matrix scans) and completed synchronously in 323.7 seconds, while the expanded release oracle completed in 217.8 seconds. Their scoped hang bounds move to 480 and 330 seconds respectively, preserving every audit and the unchanged 10-minute job circuit breaker. No further full matrix audit may be added before the follow-up sharding/coverage-rerun optimization. Under D-45 no local install, build, lint, test, coverage, smoke, OIA, package/client, benchmark or evaluation workload ran on the maintainer MacBook; executable proof belongs exclusively to GitHub-hosted CI on the exact candidate and squash-main SHAs.
- One seal still covers the complete future graph.
executeThrough(root, adapters)accepts only an exact plan-owned case root, preflights the adapter requirements of every prepared case, freezes the required function references and advances the cursor only after a complete case succeeds. All planner data, lifecycle counters and internal mutation helpers live in native#privateslots rather than writable or directly callable TypeScript-private members; a frozen staged capsule binds the adapter snapshot, next cursor and complete prepared-case count across the gap.executeRemaining()accepts no adapter and is legal exactly once after a non-terminal prefix. Invalid boundaries, capsule drift and detector failures fail closed; reflective writes or helper calls, out-of-phase calls, re-entry and replay cannot reopen, skip or re-execute the plan. - Registry workflow mutations remain data-only. A run mutation carries one canonical integrity-source companion; an integrity mutation carries one canonical run-source companion. The identity-side invocation parser retains that direction-specific companion slot and handle, then compares both against the frozen ordered inputs and their exact declarative source bindings without widening the current evaluator-only partition. The sole execution adapter receives exact
(run, integrity)strings, and its result must be a dense, duplicate-free inventory containing only the workflow problem identity. Its wrapper AST and runtime binding census are pinned independently; the closed adapter-reference grammar admits exact evaluator-only, step-only or combined evaluator/step objects in either full or prefix execution and rejects swapped, missing or misplaced bindings. Fixture-level and helper-level controls exercise both companion directions and both sides of that adapter grammar. - Execution order is now an independently checked identity dimension. Declarative execution events must terminate through a fail-closed cursor; legacy cases anchor to the first matcher of their frozen primary check. Both the current full execution and the alternate
releaseMutationM018prefix/suffix lifecycle have exact source grammar, phase and derived-census controls. A physical matcher shared by multiple cases is admitted only through one closed dense array iteration shape with an exact root-bearing projection, immutable named binding, unconditional matcher body and complete literal index bound; the Registry loop separately pins its four reviewed ownerless prefix controls. The resulting exact case/root sequence must equal the historical frozen primary-matcher order, including groups whose runtime order differs from numeric mutation IDs. - Release and product state remain unchanged. No production source, workflow, package manifest, version, tag, npm/GitHub Release/MCP Registry state, publication path, immutable fixture bytes or declarative-partition changes occur here. The canonical test-only hybrid matrix slice changes to prepare the exact raw-run adapter and execution-order controls; a separate alternate-source control exercises the staged lifecycle against that reviewed graph. The canonical slice and complete current source retain independent pinned digests.
Tests (1807)
1807 → 1807 source tests. Gate B trigger controls extend existing structural test declarations; the release-mutation graph remains 560 cases and no new source it() declaration is added. Final executable evidence remains remote-only.
Stats
46 tools · 19 prompts · 1807 source tests · 12 directly enumerated release-required contexts · 8 synchronized version surfaces. MCPB Basic remains a separately bounded 13-tool, zero-prompt profile.