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
This commit is contained in:
parent
15a4717dd1
commit
baf53602ca
11 changed files with 422 additions and 32 deletions
110
history/2026-09-21-gate-house-a16-a17-response.md
Normal file
110
history/2026-09-21-gate-house-a16-a17-response.md
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
# 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 16–17, 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 16–17, 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue