Answer the exec-path question: the front door reads the ungoverned duplicate.
ops-warden and railiance-platform asked, independently, which OpenBao location `secrets-engine exec --catalog whynot-design-npm-publish` reads. Answered from this repository's own code and catalog with no OpenBao read and no value. It reads `secret/coulomb/whynot-design/npm/publish` — the legacy, ungoverned duplicate. `_fetch_value` concatenates the catalog's `mount` and `path` with no override or fallback, so the proven pilot published from the duplicate and the lowercase `npm_token` field is the field there. ops-warden's front door names this repository as exec_owner, so it currently routes callers at a path no CCR covers. Recorded in SECRETS-WP-0006 with what a move to the governed lane requires, and flagged that the duplicate must not be destroyed until the lane moves. Whether the two locations hold the same value is a value comparison and is not answered here. Also records GH-DEC-2026-017 against SECRETS-WP-0008: INTENT.md governs, the sidecar is derived, the vocabulary is case-insensitive so nothing is re-spelled, and standard_version comes out of layer.yaml once ops-warden updates the reference form this repository copied. 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
e5672846ab
commit
550ba95a67
3 changed files with 162 additions and 1 deletions
|
|
@ -17,10 +17,23 @@ prompts, workplans, or normal logs.
|
|||
| Org/repo | `coulomb/whynot-design` |
|
||||
| npm package | `@whynot/design` |
|
||||
| npm registry | `https://forgejo.coulomb.social/api/packages/coulomb/npm/` |
|
||||
| Catalog mount/path | `secret/coulomb/whynot-design/npm/publish` |
|
||||
| Catalog mount/path | `secret/coulomb/whynot-design/npm/publish` **(ungoverned legacy — see below)** |
|
||||
| Catalog field | `npm_token` |
|
||||
| Injected env var | `NPM_AUTH_TOKEN` |
|
||||
|
||||
> **Governance status, 2026-09-21.** The catalog mount/path above is the
|
||||
> location `secrets-engine exec` actually reads — confirmed from
|
||||
> `exec_delivery._fetch_value`, which concatenates `entry.mount` and
|
||||
> `entry.path` with no override — and it is the **ungoverned duplicate**. The
|
||||
> governed lane is `platform/workloads/coulomb/whynot-design/npm-publish` under
|
||||
> CCR-2026-0001, field `NPM_AUTH_TOKEN`. The lowercase `npm_token` in the table
|
||||
> above is the field at the legacy path, which is why the two records disagreed
|
||||
> without either being wrong. Moving to the governed path is a reviewed lane
|
||||
> change with its own approval; the steps are recorded in
|
||||
> `workplans/SECRETS-WP-0006-catalog-lane-adoption.md` (2026-09-21). Until that
|
||||
> move completes and re-verifies, the legacy path must not be destroyed or
|
||||
> wrapped — it is the live publish path.
|
||||
|
||||
The decision UUID above is resolved from State Hub in normal operation. A
|
||||
UUID-named local fixture exists only as an offline fallback for throwaway demos.
|
||||
|
||||
|
|
|
|||
|
|
@ -328,3 +328,89 @@ routing/proxy retirement; SECRETS-WP-0007-T04/T07 retain general native readines
|
|||
Do not reuse the consumed approvals or treat the temporary key-check overlay as
|
||||
approval for a radar trial recipient. IR-WP-0005 owns radar delivery acceptance;
|
||||
IR-WP-0006 owns the outstanding USD 0.023712 billing reservation.
|
||||
|
||||
|
||||
### 2026-09-21 answered: the exec front door reads the ungoverned legacy path
|
||||
|
||||
ops-warden (`abf27efc`) and railiance-platform (RPF-WP-0035-T07, `09b719fe`)
|
||||
asked the same location-only question. Answered from this repository's own code
|
||||
and catalog, with no OpenBao read and no value of any kind.
|
||||
|
||||
**`secrets-engine exec --catalog whynot-design-npm-publish` reads
|
||||
`secret/coulomb/whynot-design/npm/publish`.** That is the legacy, ungoverned
|
||||
duplicate, not the governed lane.
|
||||
|
||||
Derivation, which is short because there is no indirection to hide in:
|
||||
|
||||
- `catalog/whynot-design-npm-publish.yaml` declares `mount: secret` and
|
||||
`path: coulomb/whynot-design/npm/publish`.
|
||||
- `exec_with_secret` delegates the read to `_fetch_value` in
|
||||
`src/secrets_engine/exec_delivery.py`, which issues
|
||||
`kv get -format=json {entry.mount}/{entry.path}` inside the lane's AppRole
|
||||
session. The path is the catalog pointer, concatenated, with no override,
|
||||
fallback, alias, or environment substitution anywhere on the exec path.
|
||||
- `publication_policy.resolve` and `delivery_config.npm` decide the injected
|
||||
env-var name and the npm registry. Neither touches the KV location. Nothing
|
||||
in `routing.py`, `safe_paths.py`, or the policy layer rewrites mount or path.
|
||||
|
||||
So railiance-platform's straightforward reading was the right one. The proven
|
||||
2026-07-03 `@whynot/design` pilot published by reading the legacy duplicate, and
|
||||
the lowercase `npm_token` field this repository has consistently reported is the
|
||||
field **there** — which is why it never appeared at the governed path and why
|
||||
nobody's record was wrong. ops-warden's `NPM_AUTH_TOKEN` and this repository's
|
||||
`npm_token` were each correct about the location each side was describing.
|
||||
|
||||
The consequence is the one ops-warden named and it should be stated plainly
|
||||
rather than softened: ops-warden's routing catalog lists secrets-engine as
|
||||
`exec_owner` and routes callers here as the primary front door, so that front
|
||||
door currently points at a path no CCR covers, and CCR-2026-0001's acceptance
|
||||
evidence describes a path its consumer does not use. That is a real governance
|
||||
gap, not a bookkeeping mismatch.
|
||||
|
||||
**Not answerable here, and not attempted:** whether the two locations hold the
|
||||
same value. That is a value comparison. This repository will not read, fetch,
|
||||
fingerprint, or compare either value, and has not. It is custody's question and
|
||||
needs no answer from us to proceed with the path move.
|
||||
|
||||
#### What it would take to move to the governed path
|
||||
|
||||
The move is a reviewed production lane change, not an edit. In order:
|
||||
|
||||
1. **Custody confirms the governed lane is consumable by this lane's identity.**
|
||||
`platform/workloads/coulomb/whynot-design/npm-publish` under CCR-2026-0001
|
||||
grants read to the workload policy; the AppRole this engine's delivery
|
||||
session assumes must be admitted on `platform/data/...` and
|
||||
`platform/metadata/...` of exactly that path. Without that, the edit produces
|
||||
a lane that denies on read.
|
||||
2. **Reconcile the field name in the same change.** The catalog declares
|
||||
`npm_token`; the governed path was enumerated by railiance-platform on
|
||||
2026-09-10 as holding exactly one field, `NPM_AUTH_TOKEN`. Moving the path
|
||||
without moving `fields:` produces `field 'npm_token' absent in lane` from
|
||||
`_fetch_value`. The injected env var is separately resolved and stays
|
||||
`NPM_AUTH_TOKEN` while netkingdom is `maturity-build`; after the move the KV
|
||||
field name and the injected env-var name coincide, which is a coincidence and
|
||||
must be annotated as one so the category error corrected on 2026-09-09 is not
|
||||
reintroduced.
|
||||
3. **Carry an approval.** The lane's `approval.model` is `decision`; this is a
|
||||
production lane pointer change and takes its own approved decision, not the
|
||||
existing `e6381a56` pilot decision.
|
||||
4. **Re-verify positive and negative.** The lane's declared expectations — the
|
||||
approved consumer reads the field, an unrelated identity is denied — must be
|
||||
re-run against the governed path before the old pointer is abandoned.
|
||||
5. **Update the derived records:** `docs/whynot-design-real-publish-closeout.md`
|
||||
pointer table, `docs/hardening-backlog.md` (which already names both
|
||||
locations), and `docs/cli.md`.
|
||||
6. **Only then is destruction of the duplicate safe.** RPF-WP-0035-T07 holds
|
||||
destruction pending this confirmation, correctly. The confirmation it was
|
||||
waiting for is now given, and it is the unwelcome one: the duplicate is the
|
||||
live consumer path, so it must not be destroyed or wrapped until this lane
|
||||
has moved and re-verified. Destroying it today breaks production publish.
|
||||
|
||||
Note also `scripts/demo-e2e.sh:66`, which grants a policy on
|
||||
`secret/data/prod/coulomb/whynot-design/npm` — a third, demo-only spelling under
|
||||
a `prod/` prefix. It is a throwaway demo fixture and not a consumer lane, but it
|
||||
should be renamed away from `prod` when the lane moves so it cannot be mistaken
|
||||
for a fourth location.
|
||||
|
||||
`SECRETS-WP-0006-T06` stays `wait`: this answer unblocks the question, not the
|
||||
lane change, which needs custody's step 1 and its own approval.
|
||||
|
|
|
|||
|
|
@ -354,6 +354,68 @@ Acceptance:
|
|||
- No fallback from JWT/service-auth failure into bootstrap or AppRole.
|
||||
- Issued delivery sessions continue to self-revoke as in WP-0007-T05.
|
||||
|
||||
### 2026-09-21 GH-DEC-2026-017 — section 11 layer declaration ruled
|
||||
|
||||
Read from `gate-house/decisions/decisions.md`, not from message text.
|
||||
`secrets-engine` is a named affected repository and carries both permitted
|
||||
forms, so all four parts apply here. State Hub decision id
|
||||
`82dd0fea-fabb-4940-92d5-d6e2ea9985f5`.
|
||||
|
||||
What the ruling settles for this repository:
|
||||
|
||||
1. **`INTENT.md` governs.** Our declaration is the `layer: Engine` key in
|
||||
`INTENT.md` frontmatter. `layer.yaml` is a **derived artifact**: it must be
|
||||
marked as derived, must name `INTENT.md` as what it derives from, and must
|
||||
agree with it. Our `layer.yaml` already carries `declared_by: INTENT.md` and
|
||||
a `Voice: INTENT.md (this repository's own declaration, §11)` header comment,
|
||||
so we are among the repositories already treating the sidecar as derived in
|
||||
substance. What is missing is the explicit derived marking the ruling now
|
||||
requires as a field rather than a comment.
|
||||
2. **The §3 vocabulary is case-insensitive and comparison must ASCII case-fold.**
|
||||
Our `INTENT.md` says `Engine` and our `layer.yaml` says `engine`. Under §2 of
|
||||
the ruling that is **conforming**, it was never a disagreement about a layer,
|
||||
and **nothing here is re-spelled**. flex-auth withdrew the casing finding
|
||||
itself (message `962bf395`) and its validator is the thing that changes. We
|
||||
do not touch either file's spelling, and we do not "align" them.
|
||||
3. **The vocabulary is closed with four tokens** — `Taxonomy`, `Tooling`,
|
||||
`Engine`, `Staff`. `Engine` is in it; no action.
|
||||
4. **`standard_version` comes out of the declaration.** Our `layer.yaml` carries
|
||||
`standard_version: "0.7"`. A declaration asserts a standing property and must
|
||||
not carry a standard version; version-scoped state belongs in the derived
|
||||
conformance record, which must name what it derives from and the version or
|
||||
commit it was derived at.
|
||||
|
||||
**Deliberately not done in this session.** The ruling states that
|
||||
`standard_version` is not one repository's habit but **ops-warden's reference
|
||||
form**, which this repository copied along with seven others, and that ops-warden
|
||||
is asked to make the change there rather than each adopter deciding independently.
|
||||
ops-warden is updating that reference form in a parallel session. Inventing our
|
||||
own sidecar shape ahead of it would produce exactly the divergence the ruling
|
||||
exists to close, so we record the requirement and wait for the reference form.
|
||||
|
||||
What `secrets-engine` will need, once the reference form lands:
|
||||
|
||||
- Adopt the reference form's derived-artifact marking in `layer.yaml`, keeping
|
||||
`declared_by: INTENT.md` or whatever field the reference form names for it.
|
||||
- Remove `standard_version: "0.7"` from `layer.yaml`.
|
||||
- Move the version the conformance run was derived at into our derived
|
||||
conformance record, per the reference form's field for it. Our conformance
|
||||
checker is `scripts/check_layer_conformance.py`; it reads `layer.yaml` today
|
||||
and will need to read `INTENT.md` as the governing form, read the sidecar as
|
||||
well, and **report a disagreement between them as a finding** rather than
|
||||
resolve it by precedence. A casing-only difference is not such a disagreement.
|
||||
- Keep `framework:`, `layer:`, `role:` and the substantive §3/§5/§6/§9.6
|
||||
content unchanged. `role:` is explicitly not ruled and stays as it is.
|
||||
- The `Framework:` header comment in `layer.yaml` cites
|
||||
`security-layer-model_v0.7.md` while the ruling is issued against `v0.8`.
|
||||
That is a citation in a comment, not a declaration version, so it is out of
|
||||
scope for part 4 — but it should be refreshed in the same commit so the two
|
||||
are not confused for each other.
|
||||
|
||||
No task is opened here by hand. This is a note against the workplan that already
|
||||
owns `layer.yaml` / `pep-stance.yaml` / INTENT frontmatter staying in one voice;
|
||||
the work lands under that exit criterion when ops-warden's form is published.
|
||||
|
||||
## Exit criteria
|
||||
|
||||
- The published PEP stance is the shipped default and stance application is
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue