instar 1.3.760 → 1.3.762

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,29 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ Doorway/Model Knowledge Registry — rollout increment 5, the FINAL increment (the companion-gated enforcement activation, per `docs/specs/DOORWAY-MODEL-KNOWLEDGE-REGISTRY-SPEC.md` §Rollout step 5 + §3). Increments 1–3 (enriched manifest + derived-frontier lint in report mode; deterministic prober + scan-state + dark job + §2.7 guard; `GET /doorways` + CLAUDE.md awareness + config knob) are already merged. This increment turns the freshness ratchet's teeth ON and ratifies the constitutional standard WITH those teeth — it adds no runtime behavior, no probing, no spend; the scan job stays DARK.
9
+
10
+ - **Freshness lint flipped `report` → `strict`** (`scripts/model-registry-freshness.manifest.json`, spec §Rollout step 5 + §3 ratification precondition). The shipped manifest's `enforcement` field is now `"strict"`, so the freshness lint (`scripts/lint-model-registry-freshness.mjs`) — which runs in the `npm run lint` chain — now EXITS 1 (fails CI) on any finding: a routing pin drifting off its door's derived frontier set, a `flaggedStale` row, or `lastReviewedAt` aging past `stalenessWindowDays`. This is the anti-rot ratchet the standard names, going live.
11
+ - **`flaggedStale` reconciliation verified clean.** The strict flip is gated on the registry being genuinely fresh. The prior flagged pins were already operator-confirmed + reconciled into `topModels` (increment 1: `gemini-2.5-pro` → `gemini-3.1-pro-preview`; codex `capable` stays `gpt-5.5`), so `flaggedStale` is empty and both teeth (staleness + derived-frontier drift) pass clean under strict — the flip does not break the build. The `$enforcementNote` documents the flip, the reason it's safe now, and the one-line rollback (set the field back to `"report"`).
12
+ - **Constitutional standard added: "Keep the Doorway/Model Map Current"** (`docs/STANDARDS-REGISTRY.md`, Building family, spec §3) — a stale doorway/model map is a defect kept current by a standing process (the scan job) and gated by a ratchet (the now-strict freshness lint), never by anyone remembering to re-check. The standard is ratified WITH live teeth (per the spec's explicit ratification precondition), naming its structural guards in `**Applied through.**`: the doorway-scan job + prober, the strict freshness lint, the enriched registry manifest, and the routing narrative. The enforcement-coverage auditor classifies it as an enforced `gate` (verified guards on disk, zero dangling refs).
13
+
14
+ This completes the DOORWAY-MODEL-KNOWLEDGE-REGISTRY spec's rollout. Operator step 4 (enabling the dark scan job on the maintainer agent for a free-probes soak, then optionally opting into metered scopes) remains the operator's deliberate, reversible choice — unchanged by this increment.
15
+
16
+ ## What to Tell Your User
17
+
18
+ Nothing you do changes today, and nothing turns on. Under the hood, the guard that keeps my "which models can I reach, and what's the top model behind each door" map from silently going stale now has teeth: if a model pin drifts off the current frontier, or the map goes un-reviewed past its window, the build fails loudly instead of letting the map rot invisibly (which is exactly how my cross-model reviewer ended up quietly running on a year-old model). I also wrote this down as a formal standard — "keep the doorway/model map current" — so it's a rule enforced by machinery, not by me remembering to look. The weekly scan that refreshes the map stays switched off until you deliberately enable it.
19
+
20
+ ## Summary of New Capabilities
21
+
22
+ - **The model-registry freshness ratchet is now GATING** — a stale or drifted per-provider model pin fails CI (`npm run lint`) instead of merely printing a report line, so the doorway/model map can no longer rot silently between manual reviews.
23
+ - **A new constitutional standard, "Keep the Doorway/Model Map Current"** — ratified with live teeth, naming the doorway-scan job + the strict freshness lint + the registry as the structure that keeps the map true (Structure beats Willpower).
24
+
25
+ ## Evidence
26
+
27
+ - `tests/unit/model-registry-freshness.test.ts` (20) — includes the strengthened "shipped manifest" test asserting the real manifest is now `enforcement:"strict"` (`r.strict === true`) AND clean under strict (zero gating findings), so the enforcement flip is proven safe and a silent revert to `report` would fail the test. Both teeth are still exercised on both sides of their decision boundary.
28
+ - `node scripts/lint-model-registry-freshness.mjs` — now prints `enforcement=strict` and exits 0 (PASS: staleness OK, all four pins in their derived frontier set, `flaggedStale` empty). The `npm run lint` chain stays green.
29
+ - `tests/unit/standards-enforcement-auditor.test.ts` (11) + `tests/unit/standards-registry-applied-through.test.ts` (4) + `tests/unit/standard-enforcement-extractor.test.ts` (8) — the standards parser + enforcement-coverage auditor stay green over the real registry with the new article present; the coverage audit classifies "Keep the Doorway/Model Map Current" as an enforced `gate` with zero dangling refs (every named guard resolves on disk), and the real-registry canary (danglingCount === 0, sane enforced ratio) holds.
@@ -0,0 +1,82 @@
1
+ # Side-Effects Review — Doorway/Model Knowledge Registry, increment 3 (GET /doorways route + CLAUDE.md awareness + maintenance.doorwayScan config-knob migration)
2
+
3
+ **Version / slug:** `doorway-model-registry-inc3`
4
+ **Date:** `2026-07-04`
5
+ **Author:** `echo`
6
+ **Spec:** `docs/specs/DOORWAY-MODEL-KNOWLEDGE-REGISTRY-SPEC.md` (approved:true, review-convergence tagged) — §Rollout step 3, §D5, §D6, §Agent Awareness, §Migration Parity.
7
+ **Second-pass reviewer:** `not-required` — this increment adds NO block/allow authority. The one new HTTP surface (`GET /doorways`) is READ-ONLY (it never gates a message, dispatch, session, or action); the other two pieces are a data-model seed (`migrateConfig`) and a documentation append (`generateClaudeMd`/`migrateClaudeMd`). Nothing here touches messaging/dispatch block-allow, session lifecycle, compaction/respawn, coherence/idempotency/trust, or anything named sentinel/guard/gate/watchdog. See §4.
8
+
9
+ ## Summary of the change
10
+
11
+ Third rollout increment of `DOORWAY-MODEL-KNOWLEDGE-REGISTRY-SPEC.md` (§Rollout step 3). Increments 1 (enriched manifest + lint, #1364) and 2 (deterministic prober + scan-state + dark job + §2.7 guard, #1373) are merged. This increment ships the READ + AWARENESS layer:
12
+
13
+ 1. **`GET /doorways` route** (`src/server/routes.ts` + new `src/core/DoorwayRegistryReader.ts`) — a read-only, Bearer-authed (global middleware), always-mounted route returning the merged doorway→model view: canonical `topModels` (git-tracked, authoritative — §1.1) overlaid with this machine's read-validated live reachability. Honors the **D5 two-state contract**: `200` with `scanState:"never-run"` when the canonical manifest is present but no scan has run (each door `reachable:null`/`probeStatus:"never-scanned"`/`lastScannedAt:null`), `200` merged once a scan-state exists, and `503` with a stable machine-readable `code` (`registry-unavailable-no-instar-source` when the manifest is absent — a non-instar-source install; `registry-corrupt` when present-but-unparseable). It never fabricates an empty map.
14
+ 2. **CLAUDE.md awareness block** — a new shared section function `DOORWAY_REGISTRY_CLAUDEMD_SECTION(port)` in `PostUpdateMigrator.ts`, interpolated into `generateClaudeMd()` (`src/scaffold/templates.ts`, new agents via init) AND appended by a content-sniffed `migrateClaudeMd()` block (existing agents via update — Migration Parity). Pointer-style (not an inlined door/model table) per §Agent Awareness.
15
+ 3. **`maintenance.doorwayScan` config-knob migration** — seeded via the canonical `SHARED_DEFAULTS`/`applyDefaults` path in `ConfigDefaults.ts` (runs inside `migrateConfig()` on both init AND migration), with the D6 fail-closed defaults `scope:"free-probes"`, `cadence:"0 4 * * 1"`, `digestTopicId:null`, `budgetCapUsd:0` — and seeding **every field EXCEPT `enabled`** (the round-2/round-5 deny-wins bug: a seeded `false` would make `config.enabled !== false` false and permanently block the scan). Typed on `InstarConfig` (`src/core/types.ts`). Plus classification wiring: the `/doorways` prefix added to `CAPABILITY_INDEX` (discoverability lint) and the CLAUDE.md section added to `feature-delivery-completeness`'s tracked `legacyMigratorSections`.
16
+
17
+ The scan job itself remains DARK (inc2's `enabled:false` job manifest); this increment adds no cadence, no probing, no spend. Increment 5 (reconcile `flaggedStale` → flip lint to strict → ratify the standard) is companion-gated and explicitly NOT in this PR.
18
+
19
+ ## Decision-point inventory
20
+
21
+ - **`GET /doorways` (NEW read route)** — `add` — read-only observability. Returns 200/503 by an OBJECTIVE, decidable file-presence/parse check (manifest present+parseable? scan-state present+scanned?). No behavioural gate, no message/dispatch/session decision. Bearer-auth is applied globally by `authMiddleware` (like every other `/`-mounted route); an un-authed request 401s (proven in the Tier-3 e2e).
22
+ - **`maintenance.doorwayScan` config seed** — `add` — a pure additive data-model default (add-missing-only; never clobbers an operator value; seeds `0`/`null` correctly). NOT a decision point.
23
+ - **CLAUDE.md awareness block** — `add` — documentation. NOT a decision point.
24
+ - No message/dispatch/tone-gate/session-lifecycle/coherence/trust decision point is touched.
25
+
26
+ ---
27
+
28
+ ## 1. Over-block
29
+
30
+ Not applicable in the blocking sense — this increment adds no block authority. The nearest analogue is the route's 503 branch: it "withholds" a payload only when there is genuinely no registry to serve (manifest absent or unparseable). That is the honest D5 answer, not an over-block — the `code` field distinguishes "this feature isn't present on this install" (`registry-unavailable-no-instar-source`) from "the manifest is corrupt" (`registry-corrupt`) so a client never mistakes either for a transient server failure. A present-but-empty `doors{}` still returns 200 with an empty `doorways[]` (honest), not 503.
31
+
32
+ ## 2. Under-block
33
+
34
+ Also not applicable. Two correctness risks were considered and closed:
35
+ - **Trusting poisoned machine-local scan-state.** The scan-state file is plaintext + machine-local; a local writer can plant well-formed poison after a clamped write (§1.3). The reader re-validates EVERY scan-state field it uses on read: door ids are charset/length-clamped AND cross-checked against the manifest's known-candidate set (unknown/metachar ids dropped), `probeStatus` is coerced to the fixed enum (out-of-enum → `malformed-response`), timestamps are ISO-or-null, and `reachable` is DERIVED from the clamped `probeStatus` (never the stored boolean — so a poisoned `reachable:"yes"` is never trusted, and P20 unknown≠down holds). Nothing raw-passes into the response. Honest scope: containment, not tamper-proofing a plaintext file (the accepted at-rest posture of every machine-local registry).
36
+ - **A crash on a corrupt scan-state.** The reader degrades a corrupt/unparseable scan-state to never-run and never throws — a bad machine-local file can only make the live half honest-empty, never break the read.
37
+
38
+ ## 3. Level-of-abstraction fit
39
+
40
+ Correct layers. The merged-view composition lives in a dedicated `src/core/DoorwayRegistryReader.ts` (a pure reader — no I/O beyond two small file reads, no runtime authority), the route is a thin handler that maps the reader's discriminated result to the D5 status codes, the config default lives in the single-source-of-truth `ConfigDefaults.SHARED_DEFAULTS` (so init AND migration seed it identically), and the awareness text lives in the shared `*_CLAUDEMD_SECTION` function used by BOTH `generateClaudeMd` and `migrateClaudeMd` (so new-install and update text can never drift). The route reads the canonical manifest via `ctx.config.projectDir` (the source-tree idiom already used for `STANDARDS-REGISTRY.md`), matching the prober's dark posture (§2.9): a non-instar-source install honestly 503s.
41
+
42
+ ## 4. Signal vs authority compliance
43
+
44
+ **Required reference:** `docs/signal-vs-authority.md`
45
+
46
+ Fully compliant — this increment adds **only SIGNAL / read surfaces**, no authority:
47
+ - `GET /doorways` is a read. It surfaces the merged map; it never blocks, gates, delays, or rewrites anything. Routing continues to read the canonical layer only (§1.1) — the route is observability over the same data, never a routing input.
48
+ - The config seed and CLAUDE.md block are data/documentation, not decisions.
49
+ - No brittle logic carries blocking authority (there is no blocking authority here at all). The only binary in the change — the 200-vs-503 branch — rests on an objective, decidable check (file present + parseable), the same shape as the sibling read routes (`/cartographer/health`, `/codex/usage`, `/guards`).
50
+
51
+ ## 5. Interactions
52
+
53
+ - **Shadowing:** none. `GET /doorways` is a brand-new top-level prefix (no collision — verified by the discoverability lint, which now classifies `/doorways` in `CAPABILITY_INDEX`). The `migrateClaudeMd` block is content-sniffed on a unique heading substring (`Doorway/Model Knowledge Registry`) → idempotent, never double-appends, never shadows another section's sniff. The `SHARED_DEFAULTS` seed is add-missing-only → never overwrites another feature's config or an operator value.
54
+ - **Double-fire / races:** none. The route is a pure read (two `readFileSync` of small files per request, no shared mutable state). It reads the same machine-local scan-state the inc2 prober writes atomically (temp+rename) — a concurrent write can never produce a torn read that crashes the route (corrupt-parse → degrades to never-run).
55
+ - **Feedback loops:** none. Reading `/doorways` has no side effect on the scan-state or manifest.
56
+
57
+ ## 6. External surfaces
58
+
59
+ - **Other agents / users:** the CLAUDE.md awareness block teaches every agent (new via init, existing via update) that `GET /doorways` exists and when to use it — the intended Agent-Awareness surface. The route is new but read-only + Bearer-gated; a pure end-user install (no manifest) gets an honest 503 rather than a fabricated payload.
60
+ - **Install base:** the config seed reaches existing agents via `migrateConfig`→`applyDefaults` on update (Migration Parity), new agents via `init`; the CLAUDE.md block via `migrateClaudeMd`/`generateClaudeMd`; the route via the compiled `dist` (always-mounted). No new job, no new hook — the scan job + guard already shipped in inc2.
61
+ - **External systems (Telegram/Slack/GitHub/Cloudflare):** none. This increment performs no network I/O and no messaging.
62
+ - **Persistent state:** none written. The route only READS the (inc2) machine-local scan-state + the git-tracked manifest.
63
+ - **Timing / runtime conditions:** none — the route's answer is a pure function of two files on disk at request time.
64
+
65
+ ## 6b. Operator-surface quality
66
+
67
+ `GET /doorways` is an agent/API read surface, not an operator-tap surface (Mobile-Complete Operator Actions is N/A — there is no operator DECISION or credential collection here). The read is exposed to the agent (via the CLAUDE.md awareness block + `CAPABILITY_INDEX`) so the agent answers "what models can I reach?" conversationally, without the operator running a CLI. No config edit is asked of the operator in this increment.
68
+
69
+ ## 7. Multi-machine posture (Cross-Machine Coherence)
70
+
71
+ - **`GET /doorways` is machine-local-by-design on its live half, and that is the correct posture.** The canonical `topModels` half is git-tracked source → byte-identical on every machine. The live `reachable`/`probeStatus`/`lastScannedAt` half is read from THIS machine's scan-state (`.instar/state/doorway-scan.json`) — machine-local because a door's reachability is a physical fact of that machine's disk (installed CLIs, per-disk logins), the same justification inc2 recorded (`machine-local-justification: physical-credential-locality`). A machine correctly answers `/doorways` about ITS OWN reachability. A pool-scope read (merge each machine's live half, tagged by machine) is the DECLINED/tracked follow-up the spec already names (§Multi-machine) — deliberately not built here (more conservative than adding a half-baked merge).
72
+ - **`maintenance.doorwayScan` config** is a normal config field; it is not a replicated store and carries no cross-machine coherence hazard (each machine reads its own config, as with every other `maintenance.*`/`monitoring.*` knob).
73
+ - **CLAUDE.md awareness** is per-agent local documentation. No cross-machine action.
74
+ - No feature here silently assumes a single machine; the one live surface is machine-local on purpose with the reason stated, and the pool-scope merge is explicitly deferred, not assumed-away.
75
+
76
+ ## 8. Rollback cost
77
+
78
+ Low and clean. The route is read-only and additive — reverting the PR removes the `/doorways` route, the reader module, the config seed, the type, the CLAUDE.md block, and the two classification entries with no data migration and no state repair (nothing durable was written). An operator's already-seeded `maintenance.doorwayScan` block would remain in their config as inert (unread) keys — harmless, and re-added identically on the next update. No hot-fix urgency: the scan job stays dark regardless, so a route bug can only affect a read response, never behaviour, spend, or routing.
79
+
80
+ ## Second-pass review
81
+
82
+ Not required (see the header rationale): no block/allow authority on messaging/inbound/dispatch, no session-lifecycle/compaction/respawn change, no coherence/idempotency/trust gate, and nothing named sentinel/guard/gate/watchdog is touched. The change is a read-only route + a data-model seed + a documentation block. The signal-vs-authority answer (§4) is unambiguous: signal only.
@@ -0,0 +1,118 @@
1
+ # Side-Effects Review — Doorway/Model Knowledge Registry, increment 5 (flip freshness lint to strict + ratify the "Keep the Doorway/Model Map Current" standard)
2
+
3
+ **Version / slug:** `doorway-model-registry-inc5`
4
+ **Date:** `2026-07-04`
5
+ **Author:** `echo`
6
+ **Spec:** `docs/specs/DOORWAY-MODEL-KNOWLEDGE-REGISTRY-SPEC.md` (approved:true, review-convergence tagged) — §Rollout step 5 (companion-gated), §3 (the standard + its ratification precondition), §1.4 (derived-frontier lint).
7
+ **Second-pass reviewer:** `not-required` — this increment adds NO runtime block/allow authority. The only "gating" it activates is a **build-time CI lint** (`scripts/lint-model-registry-freshness.mjs`) that fails `npm run lint` on a stale/drifted model pin — a build-time ratchet over git-tracked source, not a runtime gate over messaging, dispatch, sessions, coherence, or trust. Nothing here touches the message path, session lifecycle, compaction/respawn, or any runtime sentinel/guard/gate/watchdog. See §4. (The driving spec already went through 7 spec-converge rounds including dedicated security + adversarial reviewers.)
8
+
9
+ ## Summary of the change
10
+
11
+ Fifth and FINAL rollout increment of `DOORWAY-MODEL-KNOWLEDGE-REGISTRY-SPEC.md` (§Rollout step 5, the companion-gated enforcement activation). It does three things, all documentation/config-value scope — no `src/*.ts` runtime change, no new route, no new job, no probing, no spend:
12
+
13
+ 1. **Flip the freshness lint from `report` to `strict`** — `scripts/model-registry-freshness.manifest.json`: `"enforcement": "report"` → `"strict"`, plus a rewritten `$enforcementNote` documenting the flip, why it's safe now, and the one-line rollback (set it back to `"report"`). The lint (`scripts/lint-model-registry-freshness.mjs`) reads this field; strict makes it exit 1 (fail CI) on any finding. It runs in the `npm run lint` chain.
14
+ 2. **Reconcile-verify `flaggedStale`** — the spec's ratification precondition requires the registry be genuinely fresh before the strict flip. The prior flagged pins were already operator-confirmed + reconciled into `topModels` in increment 1 (`flaggedStale` is `[]`, documented in `$flaggedStaleNote`). Verified: under strict, staleness (reviewed 2026-07-03, 45d window) + all four pins' derived-frontier drift pass clean → the flip does not break the build. No new reconciliation edit was needed; the verification is the reconciliation for this step.
15
+ 3. **Add the constitutional standard "Keep the Doorway/Model Map Current"** — `docs/STANDARDS-REGISTRY.md`, Building family, using the spec §3 proposed entry text and matching the existing entry format (Rule / In practice / Earned from / Traces to the goal / Applied through). The `**Applied through.**` line names the structural guards (the doorway-scan job + prober, the strict freshness lint, the enriched manifest, the routing narrative), all resolving on disk.
16
+
17
+ Also updated: `tests/unit/model-registry-freshness.test.ts` — the "shipped manifest" test now asserts the manifest is `enforcement:"strict"` (`r.strict === true`) AND clean under strict, regression-guarding both the flip and a silent revert.
18
+
19
+ ## Decision-point inventory
20
+
21
+ - **`scripts/model-registry-freshness.manifest.json` `enforcement` field** — `modify` (`report` → `strict`) — turns an existing CI lint from non-gating to gating. Build-time only; no runtime decision surface.
22
+ - **`docs/STANDARDS-REGISTRY.md` new article** — `add` — documentation (a constitutional standard). Parsed by the read-only, non-gating enforcement-coverage auditor. NOT a decision point.
23
+ - **`tests/unit/model-registry-freshness.test.ts`** — `modify` — a test assertion strengthened. NOT a decision point.
24
+ - No message/dispatch/tone-gate/session-lifecycle/coherence/trust runtime decision point is touched.
25
+
26
+ ---
27
+
28
+ ## 1. Over-block
29
+
30
+ **What legitimate inputs does this change reject that it shouldn't?**
31
+
32
+ No runtime block/allow surface — over-block is not applicable at runtime. The nearest analogue is the CI lint now failing the build: it "rejects" a commit/build only when a model pin genuinely drifts off its door's derived frontier set, a `flaggedStale` row is present, or `lastReviewedAt` has aged past the 45-day window. That is exactly the intended anti-rot signal, not an over-block — the manifest is currently clean under strict (verified), so it does not reject the present state. A false-positive would require a legitimate pin that is genuinely off the reviewed frontier set, which by definition is the drift the guard exists to catch (reconcile the manifest to clear it — that IS the review). The window is 45 days, giving ample lead time before a staleness age-out.
33
+
34
+ ## 2. Under-block
35
+
36
+ **What failure modes does this still miss?**
37
+
38
+ The lint is model-id-AGNOSTIC by construction — it asserts internal consistency (pins ⊆ derived frontier set) and review freshness; it does NOT verify that the operator-confirmed frontier ids are objectively the true current frontier. A registry that is internally consistent but collectively behind the real world (every pin + every `topModels` entry stale in lockstep, re-reviewed within the window) passes. This is the accepted, documented gap the recurring doorway-scan job (still dark, operator step 4) exists to close by live-re-probing the doors and surfacing "a new frontier model exists that no pin references." The standard's own text names this: scan-liveness monitoring is a tracked follow-up whose anti-rot backstop is this lint. So the strict lint is the tripwire; the scan is the engine — this increment activates the tripwire, and the engine remains a deliberate operator enablement.
39
+
40
+ ## 3. Level-of-abstraction fit
41
+
42
+ **Is this at the right layer?**
43
+
44
+ Yes. The `enforcement` value lives in the single human-edit manifest that the lint already reads — the one source of truth; flipping it there (not in code) keeps the toggle reversible and data-driven, exactly as the lint was designed (spec §1.4, PR #1359). The standard lives in `docs/STANDARDS-REGISTRY.md` alongside every other constitutional standard, parsed by the same auditor. The test change lives in the existing lint test. No new abstraction is introduced; nothing is re-implemented. This is precisely the "flip a manifest field + ratify a doc standard" shape the spec's rollout step 5 prescribes.
45
+
46
+ ## 4. Signal vs authority compliance
47
+
48
+ **Required reference:** [docs/signal-vs-authority.md](../../docs/signal-vs-authority.md)
49
+
50
+ - [x] No — this change has no runtime block/allow surface. The only authority it activates is a **build-time CI ratchet** over git-tracked source (a lint that fails `npm run lint` on stale/drifted model pins). That is the sanctioned shape for a freshness ratchet (a deterministic, model-id-agnostic consistency check — not an LLM judgment, not a message/dispatch gate). The added standard is documentation; the enforcement-coverage auditor that reads it is explicitly observe-only / non-gating ("a gap is a signal to build a guard").
51
+
52
+ No brittle logic gains runtime blocking authority — there is none here. The lint's decision (pass/fail) rests on objective, decidable checks: a regex match against a source file, set membership in a derived list, and a date comparison. It is fed by the manifest (the operator-reviewed source of truth), never by inference.
53
+
54
+ ## 5. Interactions
55
+
56
+ **Does this interact with existing checks, recovery paths, or infrastructure?**
57
+
58
+ - **Shadowing:** none. The lint is the last entry in the `npm run lint` chain and independent of the others; flipping its enforcement changes only its own exit code on its own findings. The new standard article is appended at the end of the Building family (a unique `### Keep the Doorway/Model Map Current` heading) — it is picked up by the parser as one more article and does not shadow or collide with any existing article's heading or enforcement-ref extraction.
59
+ - **Double-fire:** none. The lint runs once per `npm run lint`; there is no second consumer of `manifest.enforcement` (verified: the only reader is `scripts/lint-model-registry-freshness.mjs`; unrelated `.enforcement`/`enforcementKind` references in `StandardsEnforcementAuditor`/routes are a different field on a different object). The three route/e2e fixture manifests that set `enforcement:"report"` write their OWN fixtures and are unaffected by the shipped manifest's value.
60
+ - **Races:** none — a config value and a doc addition; no shared mutable runtime state.
61
+ - **Feedback loops:** none. The lint reads the manifest and source pins; it writes nothing. The auditor reads the registry; it writes nothing.
62
+
63
+ ## 6. External surfaces
64
+
65
+ **Does this change anything visible outside the immediate code path?**
66
+
67
+ - **Other agents / users:** the standards registry gains one article (visible to any agent reading the constitution, and to the enforcement-coverage audit `GET /conformance/coverage` as one more enforced `gate` row). The manifest flip is invisible to end users (a CI/dev-time behavior). No runtime behavior changes for any running agent.
68
+ - **External systems:** none (no Telegram/Slack/GitHub/Cloudflare surface touched).
69
+ - **Persistent state:** none — no ledger, DB, or memory-file writes. Both changed files are git-tracked source.
70
+ - **CI:** the flip makes the model-freshness lint gating. The shipped manifest is clean under strict, so CI stays green today; a future stale/drifted pin will (by design) fail CI until reconciled — this is the intended ratchet, not a regression.
71
+ - **Operator surface (Mobile-Complete Operator Actions):** no operator-facing action is added or touched. There is no dashboard form, approval page, or grant/revoke/secret surface in this change. Not applicable.
72
+
73
+ ---
74
+
75
+ ## 6b. Operator-surface quality (Operator-Surface Quality standard)
76
+
77
+ No operator surface — not applicable. This change touches no dashboard renderer/markup, approval page, or grant/revoke/secret-drop form (only a JSON config value, a markdown standards entry, and a unit test).
78
+
79
+ ---
80
+
81
+ ## 7. Multi-machine posture (Cross-Machine Coherence)
82
+
83
+ **replicated (via git-tracked source).** All three artifacts — `scripts/model-registry-freshness.manifest.json`, `docs/STANDARDS-REGISTRY.md`, and the test — are committed instar source, identical on every machine the moment they ship (the same distribution path as every lint and standard). The lint runs in CI (one canonical run) and locally per checkout; the `enforcement` value is the same everywhere by construction. There is no machine-local state, no per-machine scan-state touched here (the live scan-state remains dark/unwritten in this increment). It emits NO user-facing notices (no one-voice-gating concern), holds NO durable runtime state (nothing to strand on topic transfer), and generates NO URLs. The canonical/reviewed manifest layer is deliberately identical across machines (spec §1.1); only the LIVE scan-state layer is machine-local by design, and this increment does not touch it.
84
+
85
+ ## 8. Rollback cost
86
+
87
+ **If this turns out wrong in production, what's the back-out?**
88
+
89
+ - **Hot-fix release:** trivial. Set `scripts/model-registry-freshness.manifest.json` `"enforcement"` back to `"report"` (documented in the `$enforcementNote`) and ship as the next patch — the lint reverts to non-gating (prints findings, exits 0). The standard can be left in place (documentation) or removed in the same revert; the enforcement-coverage auditor treats its absence as one fewer article (non-gating).
90
+ - **Data migration:** none — no persistent state.
91
+ - **Agent state repair:** none — existing agents need no notification or reset; nothing runtime changed.
92
+ - **User visibility:** none — no user-visible runtime regression during a rollback window (the change is CI/dev-time + documentation only).
93
+
94
+ ---
95
+
96
+ ## Conclusion
97
+
98
+ This review confirms the increment is a documentation + config-value activation with no runtime block/allow surface. The single meaningful side effect is intended: the model-registry freshness lint becomes gating, and it is verified clean under strict before the flip (staleness fresh, all pins in their derived frontier sets, `flaggedStale` empty), so CI stays green today and only a genuine future drift/age-out fails the build — the anti-rot ratchet the standard names, ratified WITH its teeth per the spec's explicit precondition. Rollback is a one-line manifest edit. No design change was required by the review. Clear to ship — this completes the DOORWAY-MODEL-KNOWLEDGE-REGISTRY spec rollout.
99
+
100
+ ---
101
+
102
+ ## Second-pass review (if required)
103
+
104
+ Not required — see the header rationale (no runtime block/allow authority; the only gating is a build-time model-id-agnostic CI lint over git-tracked source).
105
+
106
+ ---
107
+
108
+ ## Evidence pointers
109
+
110
+ - `node scripts/lint-model-registry-freshness.mjs` → `enforcement=strict`, exit 0, PASS (staleness OK reviewed 2026-07-03 1d ago window 45d; all four pins in their derived frontier set; `flaggedStale` empty).
111
+ - `npx vitest run tests/unit/model-registry-freshness.test.ts` → 20 passed (incl. the strengthened shipped-manifest strict-and-clean assertion).
112
+ - `npx vitest run tests/unit/standards-enforcement-auditor.test.ts tests/unit/standards-registry-applied-through.test.ts tests/unit/standard-enforcement-extractor.test.ts` → 23 passed; the real-registry coverage audit classifies "Keep the Doorway/Model Map Current" as an enforced `gate`, danglingCount 0, total standards 70.
113
+
114
+ ---
115
+
116
+ ## Class-Closure Declaration (display-only mirror)
117
+
118
+ No agent-authored-artifact defect fixed, and no self-triggered controller (loop/monitor/sentinel/reaper/scheduler/recovery path) added or modified — not applicable. This increment flips an existing CI lint's enforcement value and adds a constitutional-standard doc entry; it introduces no new control loop and fixes no defect in an LLM prompt/hook/config/skill/standards-text artifact.