All four reviewing repositories returned findings on v0.4 and one contested a
rule. Every change below came from a reviewer, not from gate-house.
- §9.1 split into `pending` (no route, capability zero) and `declared-gap`
(route exists under §5.3, capability works). v0.4's single mark would have
forced a false "pending" onto ops-warden's production SSH issuance —
the fix was worse than the defect, and the defect was in this section.
- §9.3 rewritten. flex-auth contested it and was right: it collapsed "engine
reachable but degraded" with "engine unreachable", and the second has no
evaluator in the path to express anything. Input degradation is the engine's;
unreachability is the consumer's, bounded by a declared auditable total
stance — which ops-warden ADR-0009 already satisfies. v0.4 had ruled against
shipped behaviour in a repository that assented to it.
- §5 scoped: "Tooling-layer system" means a §4 Tooling row. Without this every
Staff repository was in undeclared violation for writing progress events.
- §9.4 requires the outbox to be local — no synchronous audit-core dependency
inside the state-change transaction, so an audit outage cannot block a
revocation.
- §9.5 forbids compiling maturity levels into registry content while decision
provenance carries no registry-snapshot digest.
- §9.6 gained load-bearing versus attributive evidence, the mirror rule that
absence is not evidence of non-occurrence, and kings-guard's finding that
suppression biases posture optimistic and silently.
- §11 gained a fourth state: blocked-clean, which MUST NOT rank below
conforming. A repository that declined a break-glass path and left a
capability at zero complied at cost; one that quietly opened a client and
declared nothing did not.
- §11 gained a machine-readable declaration form; ops-warden's layer.yaml is
the reference implementation.
- §13 gained state and owner-status columns; access-engine's decline of
authentication evidence is recorded.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2564823@bnt-lap001
Assistant-Session: 2a7ed827-4928-4b9f-8613-9135c9cadfe9
Regenerated by fix-consistency; adds the inbound layer-declaration intake.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2564823@bnt-lap001
Assistant-Session: 2a7ed827-4928-4b9f-8613-9135c9cadfe9
Conformance sweep across the §4 catalog found two defects in this standard.
§11 required every catalogued repository to declare its layer in INTENT.md,
which OpenBao cannot do — the estate catalogues it but does not author it. That
is the §9.1 defect applied to conformance rather than capability: a rule
assigning an obligation the holder cannot discharge. For components the estate
does not author, the catalog row is the declaration.
§11 also did not say what a declaration is. A layer stated about a repository
by another repository is not one. The nine repositories carrying gate-house's
layering review note appear to declare a layer, but the words are gate-house's
and sit above a line admitting the body is unadapted — assertion, not assent,
which is the pattern this estate rejects.
§14 now records the honest count: seven of fifteen estate-authored repositories
have declared in their own voice. Adoption is not claimed on the basis of notes
gate-house wrote into other repositories.
Amended in place rather than versioned: v0.4 is proposed and unassented.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2564823@bnt-lap001
Assistant-Session: 2a7ed827-4928-4b9f-8613-9135c9cadfe9
audit-core assented to the approval evidence half with conditions and
corrected the rationale twice. Both corrections were against wording this
standard had taken from that repository's INTENT rather than its contract.
- §4 catalogues audit-core as an Engine, on its own declaration. v0.3 named it
as an owner in §9.4 and §13 without listing it — a §11 defect in the standard
itself, which audit-core raised.
- §9.4 rationale rewritten to cite docs/integrity.md rather than INTENT
principle 6: an in-database chain detects a rewritten payload only if the
attacker does not recompute the suffix, which a database owner can, and even
with external attestation the store is not WORM or object lock. tamper
evidence is conditional on live preconditions.
- §9.4 gained emission atomicity as approval-engine's obligation, and the
prohibition on audit-core exposing an approval-validity query — a boundary
audit-core stated unprompted, applying §6.1 to itself.
- §9.6 added, estate-wide: evidence proves alteration and truncation, not
omission at source. A suppressed revocation leaves the chain intact and
verification reports intact. "The audit record proves it happened" is unsound
and is replaced with the sound form.
- §13 gained two gaps: stronger approval custody (unassigned — deciding whether
approvals need archival custody distinct from other sources is doctrine work
not yet done) and emission atomicity (approval-engine).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2564823@bnt-lap001
Assistant-Session: 2a7ed827-4928-4b9f-8613-9135c9cadfe9
v0.2 recorded the approval object as the one open architectural hole, and
carried a latent instance of its own §9.1 rule: gate-house was catalogued as
owning conformance review with no engine to act through. Two engines were
seeded to close both.
- §9.4: the approval object goes to approval-engine — not Staff (§3.4 forbids
the runtime state), not access-engine (an evaluator owning what it evaluates
is self-dealing), not audit-core (append-only is the opposite property).
access-engine consumes approvals as input claims under §6.2; audit-core takes
the tamper-evident evidence. Operative state and evidence record are separate
artifacts with separate owners.
- §9.5: graded progression goes to maturity-engine. gate-house judges and
proposes; maturity-engine computes and remembers. Carries the guardrail that
a level may never gate a decision directly — under §6.1 that would be a
second decision point by the graded back door.
- §4 catalog gained both engines; §13 register updated.
Status proposed: the new engines are seeded by owner direction with no other
side to assent yet, and the approval evidence half needs audit-core's assent.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2564823@bnt-lap001
Assistant-Session: 2a7ed827-4928-4b9f-8613-9135c9cadfe9
All three repositories whose boundaries moved assented, each with a decision
record (flex-auth FLEX-DEC-2026-001, kings-guard KG-DEC-2026-001, ops-warden
ADR-0010), and each returned a finding. v0.2 carries the results and is
accepted; v0.1 is marked superseded and retained because the twelve estate
INTENT review notes cite it.
- §5 restructured into three sanctioned shapes: read-only diagnostics, conduit
(ops-warden's question, ruled), and declared engine gap (ops-warden's
amendment, accepted). v0.1 offered only the first, which is narrower than the
estate as it stands — a rule with no lane for a real sanctioned case gets
satisfied by relabelling rather than by closing the gap.
- §6.2 added: doctrine must reach the decision as an input claim or a versioned
policy rule. This is §6.1 applied to gate-house on the same terms it applies
to engines, drawn back by flex-auth.
- §9 added: the catalog may not assign a capability the rules forbid
discharging. Containment marked pending an engine surface; degraded-mode
fallback ruled into access-engine rather than Staff.
- §11: conformance now has three states, distinguishing a tracked gap from an
undeclared violation.
- §12 made normative, stating that an unsatisfiability finding is a success of
the conformance loop.
- §13 added: open gaps register, including the unowned approval storage and
lifecycle capability — recorded, deliberately not assigned.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2564823@bnt-lap001
Assistant-Session: 2a7ed827-4928-4b9f-8613-9135c9cadfe9
The layer model is now published as
net-kingdom/canon/standards/security-layer-model_v0.1.md (proposed) and
ratified by gate-house GH-DEC-2026-001. The note previously said the
standard was not yet written.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2564823@bnt-lap001
Assistant-Session: 2a7ed827-4928-4b9f-8613-9135c9cadfe9
States how the security estate is layered — Taxonomy, Tooling, Engines,
Staff — distinguished by determinism and by the artifact each layer
produces, and what each layer may own.
Carries two normative rules. §5: Staff never touches Tooling directly; it
acts only through Engine APIs — the architectural form of "no privilege
from cognition", and mechanically checkable. §6: access-engine is the only
policy decision point, generalizing to the whole estate the ruling first
drawn in zone-engine/INTENT.md §5, and barring any Staff repository from
hosting a decision point.
Also fixes the vocabulary the estate has used for more than one thing:
access lane vs access rule, doctrine vs runbook, control plane as Engine
vocabulary, and the posture asymmetry.
Owner gate-house, published by net-kingdom. Status proposed: the two
adaptations carrying the most weight — flex-auth's reframing and rename to
access-engine, and kings-guard and ops-warden releasing vocabulary — are
not yet assented by their owners.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2564823@bnt-lap001
Assistant-Session: 2a7ed827-4928-4b9f-8613-9135c9cadfe9
Records this repository's layer in the NetKingdom IT-security layer model
(Taxonomy / Tooling / Engines / Staff) and what should change in this INTENT
as a result. Links to the review that established the model:
gate-house/history/2026-08-28-security-layer-model-and-gate-house-recut.md
The note flags pending adaptation only; the body is unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2564823@bnt-lap001
Assistant-Session: 2a7ed827-4928-4b9f-8613-9135c9cadfe9
The patch scripts used during NK-WP-0033 write timestamped .bak- files
beside what they change. Useful during a session, noise afterwards, and
they block registrar reconciliation, which requires a clean worktree.
Git history is the real backup.
Also removes a stray zero-byte file named HTTP (2026-08-27 20:08),
almost certainly a mistyped shell redirect. Empty, nothing lost.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 3377672@bnt-lap001
Assistant-Session: 15463ccf-238f-4e13-b163-93aa25c6d166
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 3377672@bnt-lap001
Assistant-Session: 15463ccf-238f-4e13-b163-93aa25c6d166
verify-t06.sh reported success against a resolver that had been
unsaveable since creation and a reconciliation script that could never
complete a run. It asserted that objects existed rather than that the
property held.
A check that reports green while the system is broken is worse than no
check, because it is believed.
T01 rewrites it to prove a user resolves and MFA validates, and must be
demonstrated failing with the tuning fields cleared — not argued. T02
audits the sibling scripts for the same shape, output a table rather
than a rewrite. T03 labels 32 attended scripts with exercise status,
where "unknown" is permitted and more useful than a guess. T04 extracts
the one privacyIDEA request helper whose absence let a fixed defect be
reintroduced verbatim in the same directory.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 3377672@bnt-lap001
Assistant-Session: 15463ccf-238f-4e13-b163-93aa25c6d166
Five custom_metadata fields on every path in operators/ and
platform/workloads/: description, owner, used_by, rotation, on_loss.
Non-secret, so anyone orienting themselves can read all of them without
being granted a value.
on_loss is the field the section exists for. When the LLDAP admin
predecessor was destroyed on 2026-08-27 the answer had to be
reconstructed from first principles under pressure; written down in
advance it is one line.
used_by is the second lesson: rotation without a consumer list is how
privacyIDEA's resolver was left holding a superseded bind credential for
four days while everything else had been reconciled.
Inventory with ops-mason/scripts/custody-inventory.py. It reports 21
paths today, 17 undescribed — the four described are the ones this
session touched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 3377672@bnt-lap001
Assistant-Session: 15463ccf-238f-4e13-b163-93aa25c6d166
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 3377672@bnt-lap001
Assistant-Session: 15463ccf-238f-4e13-b163-93aa25c6d166
Three gaps from NK-WP-0033, none of them the fault we set out to fix.
Operator custody (platform-root-custody.md). This document named a
password-safe entry that had never been created, so the 2026-08-23
rotation had nowhere to put the new LLDAP admin value and the outgoing
one survived only in a browser entry that was overwritten on 2026-08-27.
Decided: operators/<subsystem>/<account> in OpenBao for everything
reachable once logged in, plus a short closed offline list for what you
need when OpenBao is not — platform-root's own password, unseal shares,
break-glass. Anything on that list in OpenBao would be circular;
anything not on it does not belong in the packet.
The rule that closes it: every rotation names, as a numbered step, where
the outgoing and incoming values go. NK-WP-0033-T04 rotated four classes
with no such step, and that is the root cause of the session that
followed — not the four software defects it also surfaced.
Secret disclosure by trust stage, tied to the existing S0-S6 table. A
fingerprint may be spoken to confirm two parties hold the same
credential; the whole value never may. Used ad hoc throughout 2026-08-27
and worth writing down.
Attended procedures (new standard). reconcile-lldap-resolver-live.sh was
approved, documented, revision-pinned and had never run; its first
execution found four defects, two of which meant it could never have
completed. verify-t06.sh passed throughout. An unexecuted procedure is
unfinished work and must say so in its runbook header.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 3377672@bnt-lap001
Assistant-Session: 15463ccf-238f-4e13-b163-93aa25c6d166
The live-file pass missed these: archived ad-hocs carry a YYMMDD- filename
prefix, so the ADHOC-* glob did not match them. They still derive from the
forge, so they are live records rather than dead files.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
`ADHOC-YYYY-MM-DD` is unique per date but not per repository, so any two repos
opening an ad-hoc on the same day collide. The 2026-08-26 fleet projection
reset refused 9 records for exactly this reason.
Canon (work-record-types_v0.1, CUST-WP-0066) settled the form as
`{PREFIX}-WP-ADHOC-YYYY-MM-DD`, filename unchanged, and grandfathered existing
ids on the condition they are never *silently* re-derived. This is the explicit
migration that clause allows for.
The hub id is derived from the record id, so a changed id is a different
record: stale state_hub_*_id fields are dropped and fix-consistency re-derives.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
Updated by fix-consistency on 2026-08-27:
- update .custodian-brief.md for net-kingdom
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 3377672@bnt-lap001
Assistant-Session: 15463ccf-238f-4e13-b163-93aa25c6d166
platform-root login is restored and the resolver holds the current bind
credential, so T04's outstanding reconciliation is done. No green receipt
yet — the run of record is a FAIL at resolver-lookup, and T05 stays open.
Records four things the session established:
- the predecessor is dead, observed twice by hand, but not by receipt;
- the value is unrecoverable, because no KeePassXC database has ever
existed despite platform-root-custody.md naming a safe entry, and the
only copy lived in a Firefox entry overwritten during the session.
T04 replaced the credential with no step to update operator custody —
the root cause of the whole session;
- the reconciliation script had never completed a run (4a38511);
- verify-t06.sh reported success at bootstrap against a resolver that
was misconfigured and a reconciliation path that could not execute.
That blind spot is open and is the finding worth acting on.
Also corrects the record: the stale bind credential was real but did not
cause the lookup failure. The HTTP 400 was our own request builder.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 3377672@bnt-lap001
Assistant-Session: 15463ccf-238f-4e13-b163-93aa25c6d166
reconcile-lldap-resolver-live.sh had never completed a run. Four defects,
found by running it on 2026-08-27:
1. request() set Content-Type: application/json on every call, including
bodyless GETs. Werkzeug 3.x rejects those in front of privacyIDEA, so
every GET returned an HTML 400 while POSTs succeeded — the resolver
write landed and the lookup immediately after it did not.
bootstrap-realm.sh already fixed this in pi_api and said why; this
script was written later and did not inherit it.
2. GET /user/ returns result.value as a list of user objects, not a dict
carrying "users". With the 400 fixed, the lookup finally reached the
parse and raised AttributeError past the except clause, so the run
died as a traceback instead of a receipt. Both shapes now accepted,
and the except clause catches parse errors so a failed run still
names the phase it died in.
3. A resolver write replaces the whole object, so TIMEOUT,
CACHE_TIMEOUT and SIZELIMIT were dropped by every --apply. A resolver
with them unset still resolves users, but the WebUI refuses to save
or test it — so the script silently un-repaired a resolver an
operator had fixed by hand. Now sent, defaulting to the verified
5/120/500 and overridable per run. Same omission fixed in
bootstrap-realm.sh, which created the resolver that way originally.
4. The predecessor prompt could not be left empty, so an operator who
had lost the exposed credential had to type a placeholder — which
also fails the bind and was recorded as a PASSING denial proof.
--predecessor-unavailable skips the bind and records NOT-PROVEN.
--note carries operator context into the receipt line itself, so the
claim and its caveat travel together.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 3377672@bnt-lap001
Assistant-Session: 15463ccf-238f-4e13-b163-93aa25c6d166
A missing newline fused the closing delimiter onto the last frontmatter value
(`- KONT-WP-0016---`), or fused a value onto the following key. Either way the
frontmatter never terminates and the whole body is swallowed.
Because workplan files are selected by `type: workplan`, such a file is not
invalid but invisible: it appears in no projection, raises no error, and is
reported as neither a workplan nor a problem. A forge-derived reset would
therefore read its correct hub record as no longer deriving and propose retiring
live work.
Only the missing newline is inserted; no value is altered.
Refs STATE-WP-0083-T08
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
Updated by fix-consistency on 2026-08-25:
- update .custodian-brief.md for net-kingdom
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
These workplans exist only in the retired local hub. Their random pre-ADR-007
identifiers are refused by C-06 as stale references, so they cannot be
registered. Deriving from the canonical record id takes no identity from
anything: central does not hold them and the old ids die with the cache.
Records central already holds were deliberately left untouched.
Refs CUST-WP-0068-T06
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
Updated by fix-consistency on 2026-08-25:
- update .custodian-brief.md for net-kingdom
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
The remote row pointed at 127.0.0.1:18000, a reverse tunnel back to the
workstation. On railiance01 the State Hub runs in the cluster on that same
machine, so the request left the box and came back to reach a local service.
Refs CUST-WP-0067-T07
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006