instar 1.3.957 → 1.3.959

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,167 @@
1
+ # Side-effects review — census-tracker-ref-kinds
2
+
3
+ **Change:** pending census tracker refs are typed by KIND; the 49 enrolment-backlog
4
+ entries move from a machine-local evolution-action id (`ACT-1193`) to a
5
+ fleet-stable key resolved against a shipped source constant
6
+ (`backlog:decision-quality-enrolment` → `BACKLOG_TRACKERS`).
7
+
8
+ **Spec:** `docs/specs/census-tracker-ref-kinds.md` (converged, 2 rounds)
9
+
10
+ ---
11
+
12
+ ## 1. Over-block — what legitimate inputs does this reject that it shouldn't?
13
+
14
+ **One, deliberately, at build time.** The format ratchet accepts exactly two ref
15
+ kinds and additionally resolves every `backlog:` key against the registry. A
16
+ census entry pointing at an unregistered key now fails CI rather than shipping.
17
+
18
+ That is the intent — a dangling ref is the whole defect — but it is a real new
19
+ way to redden a build, and the failure message names the entry and the missing
20
+ key so the fix is mechanical.
21
+
22
+ **Nothing at runtime.** The adjudicator's `ACT-<n>` path is behaviourally
23
+ identical, with one exception that strictly *widens* what is accepted: a null
24
+ (unreadable/absent) queue now yields `unverifiable` instead of the callsite
25
+ skipping adjudication silently. No input that previously produced a verdict
26
+ produces a different one.
27
+
28
+ ## 2. Under-block — what failure modes does this still miss?
29
+
30
+ - **A registered key whose work is abandoned.** The check proves the tracker
31
+ *resolves*, never that anyone is doing the work. Round-2 review named this;
32
+ it is mitigated (a required `closureCondition`, and CI forbidding orphaned
33
+ keys) but not solved — a human still has to read the registry and notice a key
34
+ that should have been retired. Honest framing: this makes the debt *legible*,
35
+ not *worked*.
36
+ - **The 49 are still not enrolled.** This change makes the counter meaningful; it
37
+ enrols nothing. The backlog is unchanged at 49 by design, and the graduation
38
+ criterion asserts that explicitly so "progress" cannot be faked by shrinking it.
39
+ - **A second backlog added carelessly.** CI pins the current distribution to one
40
+ key, so a second key is a deliberate, reviewed act — but nothing judges whether
41
+ the second backlog is a *good* division of the work.
42
+
43
+ ## 3. Level-of-abstraction fit
44
+
45
+ Right layer, and it moved *down* during review. The first design put resolution
46
+ in the route (an injected `specExists` predicate over the filesystem); the final
47
+ one puts it in a pure function over a constant imported directly. Fewer seams,
48
+ no I/O, and `unverifiable` becomes unreachable for the new kind by construction
49
+ rather than by care.
50
+
51
+ The one deliberate cross-layer touch: `liveActs` became nullable so the *route*
52
+ no longer decides whether adjudication is possible. That decision belongs with
53
+ the kinds, which live in the adjudicator.
54
+
55
+ ## 4. Signal vs authority compliance
56
+
57
+ `docs/signal-vs-authority.md`. Both decision points are `invariant`, argued in
58
+ the spec:
59
+
60
+ - **The adjudicator** holds no authority over agent behaviour. It computes a
61
+ verdict for a read-only observability counter — it gates nothing, blocks
62
+ nothing, and no code path branches on its output.
63
+ - **The format ratchet** is a closed-world format check over a two-member enum
64
+ at a dev-process chokepoint — the documented exemption class ("the cost of a
65
+ false pass is catastrophic and the cost of a false block is merely 'try again
66
+ with the right arguments'"). Here even that overstates it: a false block is a
67
+ named CI failure with the offending entry printed.
68
+
69
+ No brittle matcher gains blocking authority over a runtime path.
70
+
71
+ ## 5. Interactions
72
+
73
+ - **The 2026-07-23 high-water fix** — preserved exactly, and the spec argues why
74
+ it must be (this change is its second half, not its replacement). The ACT path
75
+ keeps `unverifiable`-not-`dead` for a peer-minted id, and the new null-queue
76
+ case extends the same principle rather than contradicting it.
77
+ - **The pending shrink-only ratchet** — identity-pinned, so repointing all 49
78
+ changes 49 baseline lines. That is the designed "reviewed baseline change"
79
+ behaviour, not a bypass: the diff is large and legible on purpose.
80
+ - **`GET /decision-quality?scope=pool`** — unaffected. `censusDebt` is built at a
81
+ single local callsite and is not among the pool-merged fields (verified in
82
+ source while adjudicating the mixed-version finding), so no peer's raw ref
83
+ reaches another machine's adjudicator.
84
+ - **No shadowing or double-fire.** One adjudicator, one callsite, one loop.
85
+
86
+ ## 6. External surfaces
87
+
88
+ - `GET /decision-quality` → `censusDebt` — **field shapes unchanged**; the
89
+ `pendingRefUnverifiable` array simply becomes empty where it was 49 entries.
90
+ No consumer sees a new or renamed field.
91
+ - No new route, config key, flag, env var, or CLI surface.
92
+ - No user-visible behaviour on any agent. This is instrumentation.
93
+ - **Timing/state dependence:** removed, not added. The new kind's verdict depends
94
+ on nothing outside the shipped artifact — no clock, no queue, no filesystem,
95
+ no network.
96
+
97
+ ## 7. Multi-machine posture (Cross-Machine Coherence)
98
+
99
+ **Unified**, and that is the entire point of the change.
100
+
101
+ - `BACKLOG_TRACKERS` — unified by construction: a source constant in `src/data/`
102
+ (published in `package.json` `files[]`, compiled into `dist/`). There is no
103
+ per-machine copy that can diverge.
104
+ - `adjudicatePendingTracker` — unified. Reads machine-local state *only* for the
105
+ `ACT-<n>` kind, which is machine-local by design and already guarded.
106
+ - The evolution action queue stays **machine-local BY DESIGN**
107
+ (`machine-local-justification: operator-ratified-exception`, citing the
108
+ 2026-07-23 high-water adjudication already in `src/server/routes.ts`).
109
+ Inherited, not introduced — this change stops *depending* on that locality for
110
+ a fleet-wide tracker rather than attempting to change it.
111
+ - No notices, no durable state, no generated URLs — nothing to strand on a topic
112
+ transfer or to break across a machine boundary.
113
+
114
+ ## 8. Rollback cost
115
+
116
+ **Revert the commit.** No flag, because there is no weakened state to return to;
117
+ no migration, because no durable state is written; no agent-state repair.
118
+
119
+ Stated plainly because the spec's first draft got it wrong: *before* a revert, a
120
+ `backlog:` ref pointing at an unregistered key reports **`dead`**, not
121
+ `unverifiable` — a loud false deletion rather than a quiet unknown. Two things
122
+ bound that: CI resolves every `backlog:` ref against the registry, so a dangling
123
+ key cannot reach a release; and reverting restores today's `unverifiable`.
124
+
125
+ ## Second-pass review
126
+
127
+ **Not required** by the Phase-5 trigger list: no block/allow decision on
128
+ messaging or dispatch, no session lifecycle, no compaction path, no coherence
129
+ gate, trust level, or idempotency check, and nothing named sentinel/guard/gate/
130
+ watchdog. The change is a read-only observability counter plus a CI ratchet.
131
+
132
+ Substituting for it, and arguably stronger: the spec went through **two rounds of
133
+ external cross-model review**, the first of which returned SERIOUS ISSUES and
134
+ inverted the design (see the convergence report). The reviewer proved the
135
+ original anchor would have produced 49 fleet-wide false deletions — a defect no
136
+ internal pass caught.
137
+
138
+ ---
139
+
140
+ ## Addendum — an unrelated flake this change's own full-suite run surfaced
141
+
142
+ Running the full unit suite against this branch produced one failure:
143
+ `tests/unit/builtin-manifest.test.ts > is up-to-date with current source`. It
144
+ passed in isolation, so it is not caused by this change — but the Zero-Failure
145
+ Standard makes it mine on sight, so it is fixed in the same PR rather than
146
+ re-run away.
147
+
148
+ **The defect.** That test verified the committed manifest was current by
149
+ *regenerating over it* and diffing the file before/after — a verifier that
150
+ mutates the artifact it verifies. `tests/unit/package-completeness.test.ts` runs
151
+ a full `npx tsc` build which (per its own comment) regenerates the same
152
+ `src/data/builtin-manifest.json`. Under the parallel suite the two race, so a
153
+ perfectly good tree goes red at random.
154
+
155
+ **The fix.** `scripts/generate-builtin-manifest.cjs` honours an optional
156
+ `INSTAR_BUILTIN_MANIFEST_OUT` override (default path unchanged); the test
157
+ generates to a temp dir and diffs against the committed file, touching nothing
158
+ shared. The check is now read-only and order-independent, and its failure
159
+ message says how to fix a genuinely stale manifest.
160
+
161
+ **Side effects of the fix:** none beyond the test. The override is opt-in and
162
+ unset everywhere except this test, so the build and `prepublishOnly` paths are
163
+ byte-identical. No runtime code, no shipped surface.
164
+
165
+ This is the ninth instance in this run of the same shape — a check reporting a
166
+ result it did not actually establish. Here it reported failure it hadn't earned,
167
+ which is the less dangerous direction but the same root cause.