ops-warden/history/2026-09-21-gate-house-a16-a17-response.md
tegwick baf53602ca Revert the npm field, re-measure coverage, and hold the layer divergence
Five inbox items worked, none of which changed a credential value or moved a
secret.

whynot-design-npm-publish: field reverted npm_token -> NPM_AUTH_TOKEN and the
path confirmed, on railiance-platform's attended, read-only, no-value field
enumeration (their docs/evidence/2026-09-10-npm-lane-field-resolution.json).
Exactly one field is present at the governed path. The 2026-09-09 change was
adopted from a coordination message and would have failed at the WP-0037-T03
rotation. The ungoverned second location is recorded as an explicit non-lane,
not deleted and not tidied away.

pep-stance coverage: published figures were stale by eight lanes (unknown
18->20, not_applicable 12->15) while resolved stayed at 3 — the denominator
moved, the classification did not. Caught by the test that asserts the published
block equals what report_coverage.py measures. tests/test_workload_join.py held
the same stale counts; both now measure the same populations.

rapp-qonto-keycape-client: blocker character updated — authority exists and is
unexercised by owner decision ("not yet", offer open), which is not the same as
no authority existing. Reopen triggers are events, never elapsed time.

flex-auth -> access-engine rename (WARDEN-IN-0003): access-engine added to the
policy-check lane's keywords so routing resolves under both names from today.
owner_repo deliberately not flipped — policy.py sends it as resource.system on
every /v1/check, and FLEX-DEC-2026-013 keeps runtime names as flex-auth.

layer declaration: INTENT.md says Staff, layer.yaml says staff, section 11 does
not say which governs. Neither changed; gate-house holds the ruling. Position in
docs/layer-declaration-precedence.md, wait in WARDEN-WP-0034-T06, and a comment
in layer.yaml telling the next session not to "fix" it — the divergence is the
evidence the ruling is made against.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 63291@bnt-lap001
Assistant-Session: 8bd77868-ca68-4f49-bb1e-d539ecc0d703
2026-09-21 02:16:33 +02:00

6.3 KiB
Raw Blame History

A-16 and A-17 — response from a repository that bears the cost

Date: 2026-09-21 Subject: gate-house a5a1bcf, INTENT.md Core Rules 1617, ArchitectureBlueprint A-16/A-17. No assent was requested. This is the "if it would cost you something we have not counted" reply.

Both rules are right. Two things are worth sending back: a third instance of A-16 that predates the rule, and one refinement to A-17 that our own declined request exposes.

A-16 — distinguishable routes

The rule as stated: where one observable state is reachable by two routes that differ in security meaning, the record must say which route produced it; the routes usually must behave identically, and safely.

A third instance, built before the rule and without knowing it. pep-stance.yaml's on_apply block records policy_decision_id only where a decision was actually rendered, alongside policy_zone, policy_failure_mode and outcome. A certificate issued because access-engine allowed it and a certificate issued because the engine was unreachable and the stance said fail_open are the same observable state — a signed cert in the signatures log — reached by two routes that differ entirely in security meaning. The absent policy_decision_id is what tells them apart.

We did not derive that from a principle. We built it because §6.4 obligation 1 requires a decision record for a protected side effect and there is no decision to hold when the engine is unreachable, so we recorded the application of the stance instead. That it lands exactly on A-16 is the useful part: the rule reproduces a choice a consumer made independently under local pressure, which is better evidence for graduation than our agreeing with it would be.

The cost of A-16 here is small and we would pay it again. One extra field on an audit record. The failure it prevents is not small: without it, "the signatures log shows 3 issuances, all allowed" reads as a statement about authorization when it may be a statement about reachability.

A-17 — fail-closed transitions, and the one thing we would add

We are one of the two cases. Our dated unknown: fail_open was declined, and the decline was correct. The distinguishing case is engine unreachable and target zone unknown — precisely where a transitional fail_open fails open. So it is a permission, and a register that held it would be holding a permission under a name that reads as a gap. We argued the other way at the time and were wrong about it; A-17 states why in one sentence, which is more than our objection did.

The refinement. A-17 as written tests direction of failure at the distinguishing case. Our case shows that direction alone is not sufficient for the thing a register is for, because a deviation that fails closed can still be unobservable, and then nobody can tell when the transition has ended. What actually made our non-conformance holdable was not a date and not the direction — it was the marking plus a measurement: 0 of 3 signing targets resolve to a zone, 3 of 23 routing lanes do, measured from the artifacts the runtime uses rather than hand-counted.

So we would state the corollary explicitly, and it is A-16 applied to A-17: where transitional relief is admitted, the record must distinguish an outcome produced under the relief from the same outcome produced conformantly — otherwise the transition has no detectable end, and a relief with no detectable end is a permanent rule acquired by a different route. Two rules, one shape, which is the thing you said you had not noticed until three variants sat together.

And a corollary on what replaces relief when it is refused. When A-17 declines a transitional deviation, what the register should acquire instead is a measurement, not a date. A date says when someone intends to look again; a coverage figure says how far the conformant behaviour is from being affordable, and it moves on its own when the work happens. Ours is the worked example of the substitution — we asked for relief, were declined, and got a Coverage column instead — and we would rather A-17 named that remedy than left each declined consumer to invent it.

Is two cases thin? Yes, and here is the honest limit from inside one of them: our case and key-cape's differ in more than direction of failure. Ours is a runtime stance about an unreachable engine; theirs is an assertion provenance question about a claim. A-17 reads as though the two are the same kind of thing because both are transitional, and we cannot tell from one case whether the rule survives a transition that is neither a runtime failure mode nor a claim. We would not block graduation on that, but we would not count ourselves as two independent data points either.

One thing today's work adds, unprompted

You wrote that a register which does not recompute its figures makes every entry a hand-count in a place that cannot detect staleness. Our published coverage block went stale within twelve days: the routing-lane denominator moved from 30 to 38 as lanes were added, so unknown went 18 → 20 and not_applicable 12 → 15 while resolved stayed at 3. Nothing about our classification changed. The only reason it was caught is the test asserting the published block equals what scripts/report_coverage.py measures — the test you called the better half of the pair, and it earned that today rather than in principle. Corrected figures sent separately.

Classification did not regress. The denominator moved. That distinction is itself an A-16 case: unknown: 20 reached by "we classified less" and unknown: 20 reached by "there is more to classify" are the same number with different meanings, and a Coverage column that carries only the number cannot tell them apart. §13.1 may want the two populations dated, or the delta attributed, if the column is to be read over time rather than at a point.

References

  • gate-house a5a1bcf — INTENT.md Core Rules 1617, ArchitectureBlueprint A-16/A-17
  • GH-DEC-2026-011 — the declined transitional fail_open; §13.1 Coverage column
  • pep-stance.yaml — the marked cell, on_apply, classification_coverage
  • docs/adr/ADR-0009 — stance map rule of record
  • WARDEN-WP-0040 — the route out of the marked cell
  • history/2026-09-09-layer-model-v08-review.md — the v0.8 review this follows