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
81
docs/layer-declaration-precedence.md
Normal file
81
docs/layer-declaration-precedence.md
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
# Which of ops-warden's two layer declarations governs — unruled, and not ours to rule
|
||||||
|
|
||||||
|
**Status: open, waiting on gate-house. ops-warden will not change either file
|
||||||
|
until the ruling lands.** Route: `WARDEN-WP-0034-T06`.
|
||||||
|
|
||||||
|
## The fact
|
||||||
|
|
||||||
|
ops-warden carries both forms §11 of `security-layer-model` permits, and they
|
||||||
|
state different values:
|
||||||
|
|
||||||
|
| File | Value |
|
||||||
|
| --- | --- |
|
||||||
|
| `INTENT.md` frontmatter | `layer: Staff` |
|
||||||
|
| `layer.yaml` | `layer: staff` |
|
||||||
|
|
||||||
|
§11 accepts either form and does not say which governs when both exist and
|
||||||
|
disagree. A conformance run reading `INTENT.md` and a run reading `layer.yaml`
|
||||||
|
reach different answers for this repository, and **both are following the
|
||||||
|
standard**. That is the finding.
|
||||||
|
|
||||||
|
## What this is not
|
||||||
|
|
||||||
|
It is not a disagreement with anybody else. flex-auth's first published B1
|
||||||
|
(2026-09-20) reported that the estate spells `layer:` three ways *across*
|
||||||
|
repositories and that ops-warden was among the repositories that would fail a
|
||||||
|
validator on casing. flex-auth withdrew that on 2026-09-21: it came from a shell
|
||||||
|
pipeline that took the first `^layer:` match per repository across two files
|
||||||
|
without recording which file it came from, so it reported one value where there
|
||||||
|
were two. They rebuilt it as `tools/survey_layer_declarations.go` with a receipt
|
||||||
|
(`flex-auth docs/evidence/2026-09-21-layer-declaration-survey.json`), and running
|
||||||
|
it falsified the finding it was built to reproduce.
|
||||||
|
|
||||||
|
Nine of nine repositories carrying both forms do exactly what ops-warden does.
|
||||||
|
The split is *within* each repository and universal, not careless.
|
||||||
|
|
||||||
|
It is also not a typo. Either spelling is defensible: the custodian's
|
||||||
|
estate-wide sweep records that §3's own table capitalises, which makes the nine
|
||||||
|
lower-casing `layer.yaml` files the divergent ones against the standard's
|
||||||
|
spelling — and separately that §3 and §4 disagree inside the standard itself
|
||||||
|
(`Engines` in §3's table, `Engine` in §4's catalog rows). Neither of those is
|
||||||
|
settled either.
|
||||||
|
|
||||||
|
## ops-warden's position
|
||||||
|
|
||||||
|
1. **We are not aligning the two files on our own initiative.** Two questions
|
||||||
|
are open at gate-house — which form governs, and whether the §3 vocabulary is
|
||||||
|
case-sensitive — and they have different answers. Aligning now means picking
|
||||||
|
one, and picking one before the ruling is ops-warden authoring a ruling it
|
||||||
|
does not own, in the same move §11 forbids when it says a layer stated *about*
|
||||||
|
a repository by another repository is not a declaration.
|
||||||
|
|
||||||
|
2. **A unilateral fix would also destroy the evidence.** The finding is
|
||||||
|
*observable* precisely because nine repositories exhibit it. A repository
|
||||||
|
that quietly normalises its own files makes the estate look more conformant
|
||||||
|
than it is and shrinks the population the ruling is being made against.
|
||||||
|
|
||||||
|
3. **Neither value is in doubt.** ops-warden is Staff, declared in its own voice
|
||||||
|
in `ADR-0010`, and no reading of either file makes it anything else. What is
|
||||||
|
in doubt is only which file a mechanical check should read. No behaviour of
|
||||||
|
this repository depends on the answer.
|
||||||
|
|
||||||
|
4. **When the ruling lands**, whichever form it names, ops-warden changes the
|
||||||
|
other file to match in one commit, together with a regression test asserting
|
||||||
|
the two agree — so the next divergence is caught rather than surveyed.
|
||||||
|
|
||||||
|
## Why this page exists rather than an inbox thread
|
||||||
|
|
||||||
|
gate-house's own observation, recorded against ops-warden in another lane: a
|
||||||
|
correction that only matters months from now is badly housed in a message
|
||||||
|
thread, because a correction we merely read is one we can only get right by
|
||||||
|
remembering. A later session asking "why do these two files disagree, shall I
|
||||||
|
just fix it?" needs to find this page, not reconstruct the reasoning.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- `net-kingdom/canon/standards/security-layer-model_v0.8.md` §3, §11 (proposed)
|
||||||
|
- `the-custodian/docs/assessments/2026-09-21-layer-declaration-boundaries.md`
|
||||||
|
— estate-wide view; questions 1, 2 and 3 are the ones that reach this page
|
||||||
|
- flex-auth message `719b3e9e` (correction), `docs/conformance/boundaries-review.md`
|
||||||
|
- `docs/adr/ADR-0010-ops-warden-is-staff.md` — the declaration itself
|
||||||
|
- `WARDEN-WP-0034-T06` — the live record of the wait
|
||||||
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
|
||||||
|
|
@ -91,3 +91,60 @@ created: '2026-08-28T20:40:24.957468Z'
|
||||||
updated: '2026-08-28T20:40:24.957468Z'
|
updated: '2026-08-28T20:40:24.957468Z'
|
||||||
state_hub_intake_id: "01a04d97-94cd-7b49-8019-a91c7fce8adb"
|
state_hub_intake_id: "01a04d97-94cd-7b49-8019-a91c7fce8adb"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## WARDEN-IN-0003 — FLEX-WP-0020 handoff: flex-auth → access-engine repository rename, credential-route surface
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
id: WARDEN-IN-0003
|
||||||
|
kind: intake
|
||||||
|
title: 'FLEX-WP-0020 handoff: flex-auth to access-engine repository rename, credential-route
|
||||||
|
surface'
|
||||||
|
status: open
|
||||||
|
origin: cross-repo
|
||||||
|
origin_ref: flex-auth FLEX-WP-0020 (message 0a1956c5)
|
||||||
|
priority: medium
|
||||||
|
owner: ops-warden
|
||||||
|
requested_by: flex-auth
|
||||||
|
surface: credential-route
|
||||||
|
description: 'flex-auth is preparing the repository-coordinate rename flex-auth ->
|
||||||
|
access-engine. The repository UUID fda8ad85-a7d7-4055-8f21-902a533e59df and Forge
|
||||||
|
ID 42 are unchanged; RUNTIME names stay flex-auth per FLEX-DEC-2026-013. The ask:
|
||||||
|
review registry/routing/catalog.yaml''s owner repository field so routing still
|
||||||
|
resolves after the rename, create a live record on this side, and reply with its
|
||||||
|
id. No secret requested, none returned. The message is explicitly not completion
|
||||||
|
evidence.'
|
||||||
|
notes: 'REVIEWED 2026-09-21; one change made, one deliberately not made.
|
||||||
|
|
||||||
|
SCOPE. Exactly one catalog lane names flex-auth as owner_repo: flex-auth-policy-check
|
||||||
|
(authorization decision — may this actor perform this action), warden_executes false,
|
||||||
|
route-only, no credential flows. Two other lanes mention flex-auth without owning
|
||||||
|
anything by it: flex-auth-decision-envelope-signing-key is owned by railiance-platform,
|
||||||
|
and ten lanes carry a policy_ref string of the form "flex-auth check secret.read:<domain>".
|
||||||
|
|
||||||
|
CHANGED. access-engine added to flex-auth-policy-check''s need_keywords, so the lane
|
||||||
|
resolves under both names from today rather than from the rename. That is the
|
||||||
|
deprecation window ops-warden asked for in WARDEN-IN-0001 and is the only change
|
||||||
|
routing needs: warden route find matches on keywords and lane id, neither of which is
|
||||||
|
a repository coordinate.
|
||||||
|
|
||||||
|
NOT CHANGED, and this is the finding worth having. owner_repo is NOT purely a
|
||||||
|
repository coordinate in this catalog. src/warden/policy.py sends it verbatim as
|
||||||
|
resource.system, and again as context.owner_repo, on every flex-auth /v1/check.
|
||||||
|
FLEX-DEC-2026-013 keeps runtime names as flex-auth, so flipping owner_repo at rename
|
||||||
|
time would rename a policy resource the PDP matches on, under cover of a repository
|
||||||
|
rename — a runtime change wearing a coordinate change''s clothes, and one that would
|
||||||
|
fail at the check rather than at the edit. It flips when the runtime name flips, not
|
||||||
|
when the repository does. If access-engine intends resource.system to follow the
|
||||||
|
repository rather than the runtime, that is a policy question for flex-auth to answer
|
||||||
|
before the rename lands, not an inference for ops-warden to make from its own catalog.
|
||||||
|
|
||||||
|
The lane id flex-auth-policy-check, the subsystem string, and the policy_ref strings
|
||||||
|
are runtime-facing for the same reason and are unchanged.
|
||||||
|
|
||||||
|
Related and unresolved: WARDEN-WP-0039-T03 already waits on the credential proxy''s
|
||||||
|
admitted policy binding, which is the same resource.system field seen from the
|
||||||
|
delegated-read side. The rename must not be allowed to answer that question by
|
||||||
|
accident.'
|
||||||
|
created: '2026-09-21T00:00:00Z'
|
||||||
|
updated: '2026-09-21T00:00:00Z'
|
||||||
|
```
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,12 @@ schema_version: "0.1"
|
||||||
framework: netkingdom-security-layer-model
|
framework: netkingdom-security-layer-model
|
||||||
standard_version: "0.7"
|
standard_version: "0.7"
|
||||||
repository: ops-warden
|
repository: ops-warden
|
||||||
|
# UNRULED, 2026-09-21: INTENT.md frontmatter declares `Staff` and this file
|
||||||
|
# declares `staff`. §11 permits both forms and does not say which governs when
|
||||||
|
# both exist and disagree; gate-house holds that ruling and the case-sensitivity
|
||||||
|
# one. NEITHER VALUE IS BEING CHANGED until it rules — see
|
||||||
|
# docs/layer-declaration-precedence.md and WARDEN-WP-0034-T06. Do not "fix" this
|
||||||
|
# line to match INTENT.md, or the reverse: the divergence is the evidence.
|
||||||
layer: staff
|
layer: staff
|
||||||
declared_by: docs/adr/ADR-0010
|
declared_by: docs/adr/ADR-0010
|
||||||
declared_at: "2026-08-29"
|
declared_at: "2026-08-29"
|
||||||
|
|
|
||||||
|
|
@ -87,8 +87,14 @@ on_apply:
|
||||||
# Coverage is DISCLOSURE, never a transitional licence: it does not soften this
|
# Coverage is DISCLOSURE, never a transitional licence: it does not soften this
|
||||||
# map's stance, does not gate it, and never makes the marked cell conformant.
|
# map's stance, does not gate it, and never makes the marked cell conformant.
|
||||||
# Self-measured; regenerate with `python scripts/report_coverage.py`.
|
# Self-measured; regenerate with `python scripts/report_coverage.py`.
|
||||||
|
# 2026-09-21 re-measure: routing lanes grew from 30 to 38 catalogued entries
|
||||||
|
# since 2026-09-09, so unknown rose 18 -> 20 and not-applicable 12 -> 15 while
|
||||||
|
# RESOLVED STAYED AT 3. Classification did not regress; the denominator moved.
|
||||||
|
# Signing targets are unchanged. Reported to gate-house per §13.1 — a figure in
|
||||||
|
# a register that cannot detect its own staleness is only as good as the last
|
||||||
|
# re-measure, and this one was stale by eight lanes before the test caught it.
|
||||||
classification_coverage:
|
classification_coverage:
|
||||||
measured: "2026-09-09"
|
measured: "2026-09-21"
|
||||||
attribution: self-measured
|
attribution: self-measured
|
||||||
signing_targets:
|
signing_targets:
|
||||||
resolved: 0
|
resolved: 0
|
||||||
|
|
@ -96,8 +102,8 @@ classification_coverage:
|
||||||
not_applicable: 1
|
not_applicable: 1
|
||||||
routing_lanes:
|
routing_lanes:
|
||||||
resolved: 3
|
resolved: 3
|
||||||
unknown: 18
|
unknown: 20
|
||||||
not_applicable: 12
|
not_applicable: 15
|
||||||
|
|
||||||
verdict_caching: none
|
verdict_caching: none
|
||||||
input_claim_caching: "registry/flex-auth/production_registry_snapshot.json, rebuilt by scripts/build_flex_auth_registry.py"
|
input_claim_caching: "registry/flex-auth/production_registry_snapshot.json, rebuilt by scripts/build_flex_auth_registry.py"
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@
|
||||||
# declares it, and is null where the field set has not been established --
|
# declares it, and is null where the field set has not been established --
|
||||||
# null means unknown, never 'one field'.
|
# null means unknown, never 'one field'.
|
||||||
|
|
||||||
generated_at: "2026-09-15T18:38:11Z"
|
generated_at: "2026-09-21T00:11:00Z"
|
||||||
source: ops-warden/registry/routing/catalog.yaml
|
source: ops-warden/registry/routing/catalog.yaml
|
||||||
catalog_revision: "8a40dcb11b729115773630e449fd880c0700372e"
|
catalog_revision: "308409bff1fecb588e4667f7e3db335fde9cbbe6"
|
||||||
catalog_revision_date: "2026-09-14T09:59:11+02:00"
|
catalog_revision_date: "2026-09-15T20:38:47+02:00"
|
||||||
catalog_dirty: true
|
catalog_dirty: true
|
||||||
high_risk_lane_count: 29
|
high_risk_lane_count: 29
|
||||||
concrete_path_count: 15
|
concrete_path_count: 15
|
||||||
|
|
|
||||||
|
|
@ -313,15 +313,29 @@ entries:
|
||||||
# form is superseded; do not reintroduce it.
|
# form is superseded; do not reintroduce it.
|
||||||
auth_method: "bao login -method=oidc -path=netkingdom role=whynot-design-workload-kv-read"
|
auth_method: "bao login -method=oidc -path=netkingdom role=whynot-design-workload-kv-read"
|
||||||
path_template: "platform/workloads/coulomb/whynot-design/npm-publish"
|
path_template: "platform/workloads/coulomb/whynot-design/npm-publish"
|
||||||
# Field corrected 2026-09-09 on the owner's statement (secrets-engine msg
|
# Field REVERTED to NPM_AUTH_TOKEN on 2026-09-10, and the path CONFIRMED, by the
|
||||||
# 15f0c0ca): `npm_token` is the KV FIELD; `NPM_AUTH_TOKEN` is the environment
|
# custodian of the path (railiance-platform msgs c6841bdb, 79f3e047). An attended,
|
||||||
# variable the publication-scope policy injects, and ops-warden had copied the
|
# read-only, no-value founder session enumerated the field names actually present
|
||||||
# env var in as the field name. That is ADR-0001's failure mode exactly — a
|
# at this path: exactly one, NPM_AUTH_TOKEN. Receipt: railiance-platform
|
||||||
# pointer layer restating an owner's procedure and getting it wrong — so it is
|
# docs/evidence/2026-09-10-npm-lane-field-resolution.json (commit 9d24086); prior
|
||||||
# corrected from the owner's doc (secrets-engine docs/whynot-design-real-publish-closeout.md),
|
# basis CCR-2026-0001's two dated receipts (2026-06-28) naming the same field.
|
||||||
# never re-derived here. The path is a separate question, open with
|
#
|
||||||
# railiance-platform; do not change it on this correction.
|
# The 2026-09-09 change to `npm_token` was adopted from secrets-engine's statement
|
||||||
fetch_command: "bao kv get -field=npm_token platform/workloads/coulomb/whynot-design/npm-publish"
|
# (msg 15f0c0ca) and is wrong FOR THIS PATH. That is ADR-0001's failure mode in its
|
||||||
|
# proper form: a correction taken from a coordination message is still an unverified
|
||||||
|
# mutation, and this one would have named a field that does not exist — failing at
|
||||||
|
# the rotation (WARDEN-WP-0037-T03) rather than on a cheap day. Reverting is a
|
||||||
|
# correction back to the evidenced value, not a new lane change.
|
||||||
|
#
|
||||||
|
# OPEN, and not ops-warden's to settle: a legacy location
|
||||||
|
# secret/coulomb/whynot-design/npm/publish exists (metadata only, v1 created
|
||||||
|
# 2026-07-03, outside this lane's exact-path policy and outside any CCR).
|
||||||
|
# railiance-platform's hypothesis is that secrets-engine's lowercase field belongs
|
||||||
|
# to THAT path and that the native exec front door below may be reading the
|
||||||
|
# ungoverned duplicate. Tracked as railiance-platform RPF-WP-0035-T07; ops-warden
|
||||||
|
# has asked secrets-engine which location `secrets-engine exec` reads. Until that
|
||||||
|
# is answered, this catalog names the governed path and the field evidenced at it.
|
||||||
|
fetch_command: "bao kv get -field=NPM_AUTH_TOKEN platform/workloads/coulomb/whynot-design/npm-publish"
|
||||||
policy_ref: "flex-auth check secret.read:whynot-design"
|
policy_ref: "flex-auth check secret.read:whynot-design"
|
||||||
exec_capable: true
|
exec_capable: true
|
||||||
lane: secret
|
lane: secret
|
||||||
|
|
@ -337,7 +351,7 @@ entries:
|
||||||
automatable: false
|
automatable: false
|
||||||
steps:
|
steps:
|
||||||
- "In the coulomb Forgejo registry, revoke the current @whynot/design publish token and generate a new one (scope: package read/write) for the whynot-design publish identity."
|
- "In the coulomb Forgejo registry, revoke the current @whynot/design publish token and generate a new one (scope: package read/write) for the whynot-design publish identity."
|
||||||
- "Write it back: `bao kv put platform/workloads/coulomb/whynot-design/npm-publish npm_token=@file` (value from a mode-0600 file). The field is `npm_token`; `NPM_AUTH_TOKEN` is the injected env var, not a KV key."
|
- "Write it back: `bao kv put platform/workloads/coulomb/whynot-design/npm-publish NPM_AUTH_TOKEN=@file` (value from a mode-0600 file). NPM_AUTH_TOKEN is the KV field name at this path, evidenced by an attended enumeration on 2026-09-10; it is also the env var the publication-scope policy injects, which is what made the two readings easy to confuse."
|
||||||
- "Verify capabilities-safe, then publish a fresh version and confirm it with Forgejo-supported `npm view <package>@<version>` through the governed execution lane (value used, not printed)."
|
- "Verify capabilities-safe, then publish a fresh version and confirm it with Forgejo-supported `npm view <package>@<version>` through the governed execution lane (value used, not printed)."
|
||||||
|
|
||||||
- id: policy-nexus-forgejo-source-read
|
- id: policy-nexus-forgejo-source-read
|
||||||
|
|
@ -383,7 +397,19 @@ entries:
|
||||||
workload_ref:
|
workload_ref:
|
||||||
applicability: not-applicable
|
applicability: not-applicable
|
||||||
reason: "Generic authorization action; the governed resource supplies workload identity."
|
reason: "Generic authorization action; the governed resource supplies workload identity."
|
||||||
need_keywords: [authorization, policy, permission, allow, deny, may, flex-auth, topaz, pdp, decision]
|
need_keywords: [authorization, policy, permission, allow, deny, may, flex-auth, access-engine, topaz, pdp, decision]
|
||||||
|
# FLEX-WP-0020 rename review, 2026-09-21 (flex-auth msg 0a1956c5; WARDEN-IN-0003).
|
||||||
|
# `access-engine` added to the keywords so this lane resolves under BOTH names from
|
||||||
|
# today — the deprecation window ops-warden asked for in WARDEN-IN-0001 and the only
|
||||||
|
# change the rename needs here to keep routing working.
|
||||||
|
#
|
||||||
|
# `owner_repo` is deliberately NOT flipped, and the reason is not inertia. In this
|
||||||
|
# catalog `owner_repo` is not purely a repository coordinate: src/warden/policy.py
|
||||||
|
# sends it verbatim as `resource.system` (and as `context.owner_repo`) on every
|
||||||
|
# /v1/check. FLEX-DEC-2026-013 keeps runtime names as `flex-auth`, so flipping this
|
||||||
|
# string would rename a policy resource the PDP matches on, under cover of a
|
||||||
|
# repository rename — a runtime change wearing a coordinate change's clothes. It
|
||||||
|
# flips when the runtime name does, not when the repository does.
|
||||||
owner_repo: flex-auth
|
owner_repo: flex-auth
|
||||||
subsystem: flex-auth
|
subsystem: flex-auth
|
||||||
warden_executes: false
|
warden_executes: false
|
||||||
|
|
@ -898,8 +924,8 @@ entries:
|
||||||
delegation:
|
delegation:
|
||||||
mode: interim
|
mode: interim
|
||||||
intended_owner: key-cape
|
intended_owner: key-cape
|
||||||
blocked_on: "Narrowed again 2026-09-09: the AUTHORITY is answered, the ARTIFACT is not. railiance-platform (msg 7c7228ac) confirmed steps 1-2 are theirs: executed by the platform operator attended, never by ops-warden, secrets-engine autonomously, or any unattended agent; transport is the governed openbao-platform-admin-login lane invoked only through `warden access openbao-platform-admin-login --exec -- <command>` with a unique metadata receipt path (RPF-WP-0017 output containment); authority is founder_required attended OIDC via netkingdom role=platform-admin. What is still missing is a reviewed rotation CCR — a two-custodian CAS rotation with a service restart is a distinct version-guarded operation, not an implementation detail of this lane, and it must name the CAS precondition and expected version on both custodians, sibling-field preservation, the restart window, bounded predecessor retention, and the reconcile-to-same-version failure step. That CCR is railiance-platform to write under RPF-WP-0035 once an owner asks for the rotation; ops-warden has asked key-cape whether to schedule it. Executable precedent for the same two-custodian shape: railiance-platform scripts/keycape_approval_custody.py, with its dated receipt under docs/evidence/ and review packet under docs/credential-lane-designs/. Prior (2026-09-08) narrowing to rotation steps 1-2 only: successor generation and the CAS write to both custodians (platform/workloads/rapp-qonto/keycape-client field client_secret, and sso/keycape-rapp-qonto-client key client-secret) remain custody/deployment acts. The key-cape-native exchange now exists (keycape service-token, 2026-09-05, KEY-WP-0014-T03) and step 3 verification exists as one command (keycape verify-client, 2026-09-08, including predecessor rejection and identical-secret detection); both are documented in key-cape/docs/native-authentication.md. The prior blocker recorded both as absent, which was accurate on 2026-08-28 and is not accurate now — corrected by key-cape (msg 08d42f47). Re-checked against key-cape source 2026-09-08."
|
blocked_on: "CHARACTER CHANGED 2026-09-10 (key-cape msgs 10cf8fca, 546f76e4), substance unchanged. This is no longer blocked on an OPEN QUESTION: the authority is named, the transport is named, and the rotation CCR is available on request. It is blocked on a DECISION TAKEN — key-cape put the question to the operator rather than answering for him, and the answer is NOT YET, with the offer standing open. ops-warden routed the ask and deliberately did not make it on key-cape's behalf (ADR-0003): a routing errand that implies an owner request manufactures a prepared CCR nobody decided to want. This schema carries no field distinguishing 'no authority exists' from 'authority exists, unexercised by owner decision' — the second is what is true here, and it is recorded in prose because inventing a delegation field to hold it would be a catalog change made to describe one lane. NOT A DEADLINE, and not remediation: key-cape checked and there is no incident behind it. KEY-WP-0011 recovered a real exposure on 2026-08-23, but the rapp-qonto client secret was not in that payload — it is an env: secretRef from a separate Kubernetes Secret, never inline in config.yaml, enforced by config validation. So this is lifecycle hygiene, which may wait for a chosen window; if anyone is carrying it as leftover incident work, it is not. WHAT REOPENS IT (events, never elapsed time): an actual or suspected exposure; the secret's age becoming a stated concern; a consumer requiring proof of rotation; or a decision to prove rotation step 4 before relying on it. Prior state, unchanged in substance: Narrowed again 2026-09-09: the AUTHORITY is answered, the ARTIFACT is not. railiance-platform (msg 7c7228ac) confirmed steps 1-2 are theirs: executed by the platform operator attended, never by ops-warden, secrets-engine autonomously, or any unattended agent; transport is the governed openbao-platform-admin-login lane invoked only through `warden access openbao-platform-admin-login --exec -- <command>` with a unique metadata receipt path (RPF-WP-0017 output containment); authority is founder_required attended OIDC via netkingdom role=platform-admin. What is still missing is a reviewed rotation CCR — a two-custodian CAS rotation with a service restart is a distinct version-guarded operation, not an implementation detail of this lane, and it must name the CAS precondition and expected version on both custodians, sibling-field preservation, the restart window, bounded predecessor retention, and the reconcile-to-same-version failure step. That CCR is railiance-platform to write under RPF-WP-0035 once an owner asks for the rotation; ops-warden has asked key-cape whether to schedule it. Executable precedent for the same two-custodian shape: railiance-platform scripts/keycape_approval_custody.py, with its dated receipt under docs/evidence/ and review packet under docs/credential-lane-designs/. Prior (2026-09-08) narrowing to rotation steps 1-2 only: successor generation and the CAS write to both custodians (platform/workloads/rapp-qonto/keycape-client field client_secret, and sso/keycape-rapp-qonto-client key client-secret) remain custody/deployment acts. The key-cape-native exchange now exists (keycape service-token, 2026-09-05, KEY-WP-0014-T03) and step 3 verification exists as one command (keycape verify-client, 2026-09-08, including predecessor rejection and identical-secret detection); both are documented in key-cape/docs/native-authentication.md. The prior blocker recorded both as absent, which was accurate on 2026-08-28 and is not accurate now — corrected by key-cape (msg 08d42f47). Re-checked against key-cape source 2026-09-08."
|
||||||
reviewed: "2026-09-09"
|
reviewed: "2026-09-21"
|
||||||
verified: owner-confirmed
|
verified: owner-confirmed
|
||||||
risk: high
|
risk: high
|
||||||
workload_ref:
|
workload_ref:
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,14 @@ def test_repo_catalog_uses_only_explicit_workload_references():
|
||||||
report = build(ROOT / "registry/routing/catalog.yaml", Path.home())
|
report = build(ROOT / "registry/routing/catalog.yaml", Path.home())
|
||||||
assert report["ok"] is True
|
assert report["ok"] is True
|
||||||
assert len(report["resolved"]) == 3
|
assert len(report["resolved"]) == 3
|
||||||
assert len(report["unknown"]) == 18
|
assert len(report["unknown"]) == 20
|
||||||
# 12 since WARDEN-WP-0034: the layer-declaration route is repository
|
# 15 since 2026-09-21: the layer-declaration route is repository conformance
|
||||||
# conformance guidance, not a workload delivery lane. The two NetKingdom SSO
|
# guidance, not a workload delivery lane, and the two NetKingdom SSO lanes
|
||||||
# lanes (c374d41) remain provider/control-plane credentials as well.
|
# (c374d41) remain provider/control-plane credentials. Lanes added after
|
||||||
assert len(report["not_applicable"]) == 12
|
# 2026-09-09 moved the denominator without moving `resolved`; these counts
|
||||||
|
# and pep-stance.yaml's classification_coverage measure the same populations
|
||||||
|
# and must be updated together.
|
||||||
|
assert len(report["not_applicable"]) == 15
|
||||||
assert {row["lane"] for row in report["resolved"]} == {
|
assert {row["lane"] for row in report["resolved"]} == {
|
||||||
"ops-warden-warden-sign-token",
|
"ops-warden-warden-sign-token",
|
||||||
"issue-core-ingestion-api-key",
|
"issue-core-ingestion-api-key",
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ Owner: `railiance-platform` (OpenBao) · provisioning CCR-2026-0001 (commit 8f61
|
||||||
> unverified for writes until its package token is rotated and re-proven.
|
> unverified for writes until its package token is rotated and re-proven.
|
||||||
|
|
||||||
The npm publish token for `@whynot/design` on the coulomb Forgejo npm registry
|
The npm publish token for `@whynot/design` on the coulomb Forgejo npm registry
|
||||||
(KV field `npm_token`; reaching the publish command as `NPM_AUTH_TOKEN`)
|
(KV field `NPM_AUTH_TOKEN`, which is also the name the publish command reads it under)
|
||||||
(`https://forgejo.coulomb.social/api/packages/coulomb/npm/`). ops-warden **does not hold
|
(`https://forgejo.coulomb.social/api/packages/coulomb/npm/`). ops-warden **does not hold
|
||||||
this token** — it is the access front door: `warden access` proxies the read from OpenBao
|
this token** — it is the access front door: `warden access` proxies the read from OpenBao
|
||||||
**as the caller** and never persists, caches, or logs the value.
|
**as the caller** and never persists, caches, or logs the value.
|
||||||
|
|
@ -23,8 +23,8 @@ this token** — it is the access front door: `warden access` proxies the read f
|
||||||
| Field | Value |
|
| Field | Value |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| OpenBao path | `platform/workloads/coulomb/whynot-design/npm-publish` |
|
| OpenBao path | `platform/workloads/coulomb/whynot-design/npm-publish` |
|
||||||
| KV field | `npm_token` |
|
| KV field | `NPM_AUTH_TOKEN` — the only field present at this path (attended enumeration 2026-09-10, railiance-platform `docs/evidence/2026-09-10-npm-lane-field-resolution.json`) |
|
||||||
| Injected env var | `NPM_AUTH_TOKEN` (set by the publication-scope policy; not a KV key) |
|
| Injected env var | `NPM_AUTH_TOKEN` — same name as the KV field, which is what made the 2026-09-09 `npm_token` change look plausible |
|
||||||
| KV mount | `platform` |
|
| KV mount | `platform` |
|
||||||
| Read policy | `workload-kv-read-whynot-design-npm-publish` |
|
| Read policy | `workload-kv-read-whynot-design-npm-publish` |
|
||||||
| OIDC login | `bao login -method=oidc -path=netkingdom role=whynot-design-workload-kv-read` |
|
| OIDC login | `bao login -method=oidc -path=netkingdom role=whynot-design-workload-kv-read` |
|
||||||
|
|
@ -35,6 +35,17 @@ this token** — it is the access front door: `warden access` proxies the read f
|
||||||
> The `platform/workloads/whynot-design/whynot-design/npm-publish` path from early in the
|
> The `platform/workloads/whynot-design/whynot-design/npm-publish` path from early in the
|
||||||
> provisioning thread is **superseded** — the live path is under the `coulomb` tenant.
|
> provisioning thread is **superseded** — the live path is under the `coulomb` tenant.
|
||||||
|
|
||||||
|
> **A second, ungoverned location exists and is not this lane.**
|
||||||
|
> `secret/coulomb/whynot-design/npm/publish` (v1, created 2026-07-03, never updated) sits
|
||||||
|
> outside this lane's exact-path policy and outside any CCR. It was found by metadata read
|
||||||
|
> only; its field names were not enumerated, its value was not read, and it was not
|
||||||
|
> deleted — a location holding real credential material is disposed of deliberately by its
|
||||||
|
> owner, not tidied away by whoever finds it. railiance-platform tracks it as
|
||||||
|
> `RPF-WP-0035-T07`, with an open hypothesis that the native `secrets-engine exec` front
|
||||||
|
> door below may be reading it rather than the governed path. If that proves true, this
|
||||||
|
> lane's acceptance evidence describes a path its consumer does not use. Do not route
|
||||||
|
> around the governed path on that suspicion; the question is with its owners.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Worker checklist
|
## Worker checklist
|
||||||
|
|
@ -61,12 +72,12 @@ this token** — it is the access front door: `warden access` proxies the read f
|
||||||
token fragment at `forgejo.coulomb.social`:
|
token fragment at `forgejo.coulomb.social`:
|
||||||
```bash
|
```bash
|
||||||
# --exec needs the env-var name. The zone-aware policy gate always runs first.
|
# --exec needs the env-var name. The zone-aware policy gate always runs first.
|
||||||
warden access whynot-design-npm-publish --field npm_token \
|
warden access whynot-design-npm-publish --field NPM_AUTH_TOKEN \
|
||||||
--exec -- npm view @whynot/design@<version> version \
|
--exec -- npm view @whynot/design@<version> version \
|
||||||
--registry=https://forgejo.coulomb.social/api/packages/coulomb/npm/
|
--registry=https://forgejo.coulomb.social/api/packages/coulomb/npm/
|
||||||
warden access whynot-design-npm-publish --field npm_token \
|
warden access whynot-design-npm-publish --field NPM_AUTH_TOKEN \
|
||||||
--exec -- npm publish
|
--exec -- npm publish
|
||||||
warden access whynot-design-npm-publish --field npm_token --fetch
|
warden access whynot-design-npm-publish --field NPM_AUTH_TOKEN --fetch
|
||||||
```
|
```
|
||||||
On either path the value transits to you (or the child env) and never enters
|
On either path the value transits to you (or the child env) and never enters
|
||||||
ops-warden's memory, disk, or audit log.
|
ops-warden's memory, disk, or audit log.
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ planning_priority: P1
|
||||||
depends_on_workplans:
|
depends_on_workplans:
|
||||||
- WARDEN-WP-0030
|
- WARDEN-WP-0030
|
||||||
created: "2026-08-29"
|
created: "2026-08-29"
|
||||||
updated: "2026-09-05"
|
updated: "2026-09-21"
|
||||||
state_hub_workstream_id: "ae3ff76f-883d-5e2f-b6aa-144d61e8fdef"
|
state_hub_workstream_id: "ae3ff76f-883d-5e2f-b6aa-144d61e8fdef"
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -231,6 +231,45 @@ cost, and issuance on this lane is too sparse (3 signature records across 79 day
|
||||||
T05 stays `wait` on the remaining two: `ops-mason` (no stance map published) and
|
T05 stays `wait` on the remaining two: `ops-mason` (no stance map published) and
|
||||||
`railiance-infra` (KRL distribution versus TTL expiry). Neither has replied.
|
`railiance-infra` (KRL distribution versus TTL expiry). Neither has replied.
|
||||||
|
|
||||||
|
## Await gate-house's §11 precedence and case-sensitivity ruling
|
||||||
|
|
||||||
|
```task
|
||||||
|
id: WARDEN-WP-0034-T06
|
||||||
|
status: wait
|
||||||
|
priority: low
|
||||||
|
```
|
||||||
|
|
||||||
|
ops-warden declares `layer: Staff` in `INTENT.md` frontmatter and `layer: staff`
|
||||||
|
in `layer.yaml`. §11 permits both forms and is silent on which governs when both
|
||||||
|
exist and disagree, so two conformance runs over this repository can disagree
|
||||||
|
while both follow the standard. Nine of nine repositories carrying both forms do
|
||||||
|
the same thing (flex-auth `tools/survey_layer_declarations.go`, receipt
|
||||||
|
`docs/evidence/2026-09-21-layer-declaration-survey.json`).
|
||||||
|
|
||||||
|
**Waiting on gate-house for two rulings**: which form governs, and whether the §3
|
||||||
|
vocabulary is case-sensitive. The custodian's estate-wide sweep adds a third that
|
||||||
|
bears on it — §3's table capitalises and types engines `Engines` while §4's
|
||||||
|
catalog rows type them `Engine`, so the standard disagrees with itself one level
|
||||||
|
below B1.
|
||||||
|
|
||||||
|
**Deliberately not acting.** Aligning the two files now means choosing an answer
|
||||||
|
gate-house owns, and doing it in the one place §11 says another repository may
|
||||||
|
not speak for us. It would also erase the evidence the ruling is being made
|
||||||
|
against: the finding is visible because nine repositories exhibit it, and a
|
||||||
|
repository that quietly normalises itself makes the estate read as more
|
||||||
|
conformant than it is. Position recorded in
|
||||||
|
`docs/layer-declaration-precedence.md`; both files carry a comment saying not to
|
||||||
|
"fix" the divergence.
|
||||||
|
|
||||||
|
**Done when:** gate-house rules, the non-governing file is changed to match in
|
||||||
|
one commit, and a regression test asserts the two declarations agree so the next
|
||||||
|
divergence is caught rather than surveyed.
|
||||||
|
|
||||||
|
Raised by flex-auth's corrected B1 (message `719b3e9e`, 2026-09-21), which
|
||||||
|
withdrew an earlier claim that the estate disagreed *across* repositories. The
|
||||||
|
withdrawal matters to this task: the original finding would have had ops-warden
|
||||||
|
changing a file to match an estate consensus that did not exist.
|
||||||
|
|
||||||
## Related
|
## Related
|
||||||
|
|
||||||
Review 2026-09-05: reviewed the pending implementation and fixed the identity
|
Review 2026-09-05: reviewed the pending implementation and fixed the identity
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ flavor: planning
|
||||||
owner: codex
|
owner: codex
|
||||||
topic_slug: whynot-design-forgejo-npm-lane
|
topic_slug: whynot-design-forgejo-npm-lane
|
||||||
created: "2026-09-04"
|
created: "2026-09-04"
|
||||||
updated: "2026-09-04"
|
updated: "2026-09-21"
|
||||||
state_hub_workstream_id: "42a097db-1c24-558e-a724-030bb2b4443e"
|
state_hub_workstream_id: "42a097db-1c24-558e-a724-030bb2b4443e"
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -110,3 +110,54 @@ production authority reports not-ready regardless of which path the catalog name
|
||||||
T03 still waits on the human rotation of the dedicated Forgejo package token; the
|
T03 still waits on the human rotation of the dedicated Forgejo package token; the
|
||||||
path question does not block that, it determines whether the pointer is correct
|
path question does not block that, it determines whether the pointer is correct
|
||||||
once it rotates.
|
once it rotates.
|
||||||
|
|
||||||
|
**2026-09-21 — field reverted to `NPM_AUTH_TOKEN`; path confirmed; a second
|
||||||
|
location found.** `railiance-platform`, who holds custody of the path, answered
|
||||||
|
both halves (msgs `c6841bdb`, `79f3e047`) and the answer reverses the 2026-09-09
|
||||||
|
change above.
|
||||||
|
|
||||||
|
An attended founder session enumerated the field names present at
|
||||||
|
`platform/workloads/coulomb/whynot-design/npm-publish`: read-only, no mutation,
|
||||||
|
no value emitted, `attended_identity` true. **Exactly one field is present, and
|
||||||
|
it is `NPM_AUTH_TOKEN`.** Receipt: `railiance-platform
|
||||||
|
docs/evidence/2026-09-10-npm-lane-field-resolution.json`, commit `9d24086`. The
|
||||||
|
both-fields reconciliation offered the day before is ruled out by the same
|
||||||
|
enumeration. `CCR-2026-0001` has carried two dated receipts naming that field
|
||||||
|
since 2026-06-28, one of them an attended founder fetch that exited zero — which
|
||||||
|
is itself proof the field exists.
|
||||||
|
|
||||||
|
So `npm_token` is wrong *for this path*, and the catalog and playbook are
|
||||||
|
reverted to `NPM_AUTH_TOKEN`. Reverting is a correction back to the evidenced
|
||||||
|
value, not a new lane change.
|
||||||
|
|
||||||
|
The lesson is the one this plan already recorded, one level in. On 2026-09-09
|
||||||
|
this file wrote that adopting a correction from `secrets-engine` rather than
|
||||||
|
re-deriving it was the right shape. It was the right *source* and the wrong
|
||||||
|
*standard of evidence*: a correction adopted from a coordination message is
|
||||||
|
still an unverified mutation, even when it is only a field name in a catalog,
|
||||||
|
and this one would have failed at the rotation T03 is waiting for — the moment
|
||||||
|
it is most expensive to discover. railiance-platform's phrasing, kept because it
|
||||||
|
is better than ours: it will break "at the moment you least want it to".
|
||||||
|
|
||||||
|
**The second location, which is not ours to dispose of.**
|
||||||
|
`secret/coulomb/whynot-design/npm/publish` exists — version 1, created
|
||||||
|
2026-07-03T15:00:44Z, never updated, five days *after* the governed lane was
|
||||||
|
verified. It sits outside this lane's exact-path policy and outside any CCR.
|
||||||
|
railiance-platform read metadata only: field names were not enumerated, the
|
||||||
|
value was not read, nothing was deleted, because a location holding real
|
||||||
|
credential material is disposed of deliberately by its owner rather than tidied
|
||||||
|
away by whoever finds it.
|
||||||
|
|
||||||
|
Their unconfirmed hypothesis, recorded because it changes what this lane's
|
||||||
|
acceptance evidence means if true: `secrets-engine`'s lowercase field may belong
|
||||||
|
to *that* path, their catalog may declare that location, and the proven pilot
|
||||||
|
publish may have been reading the duplicate all along. If so, a working
|
||||||
|
production lane has been running ungoverned and this lane's acceptance evidence
|
||||||
|
describes a path its consumer does not use. Tracked as `RPF-WP-0035-T07`;
|
||||||
|
railiance-platform has asked `secrets-engine` which location their publish
|
||||||
|
reads, and ops-warden has asked the same about the native
|
||||||
|
`secrets-engine exec` front door this catalog points at (`exec_owner`).
|
||||||
|
|
||||||
|
Recorded in the catalog and in `wiki/playbooks/whynot-design-npm-publish.md` as
|
||||||
|
an explicit non-lane rather than deleted from the record. Not routed around: the
|
||||||
|
governed path stays the pointer.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue