Commit graph

492 commits

Author SHA1 Message Date
9781102e29 Deploy KeyCape canonical subject fix
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a058f3-8ba0-7692-a042-9a870fc3d663
2026-09-01 00:03:08 +02:00
d4e57e6312 docs: refresh published security canon index
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a058f3-8ba0-7692-a042-9a870fc3d663
2026-08-31 21:17:38 +02:00
ce198fc290 derive state hub identifiers
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a053ff-1d6f-7fe2-ac1c-a6eb40a42a0c
2026-08-31 19:08:31 +02:00
9a7f5c9337 Intake NET-IN-0002: amend tenant-engine boundary contract
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 1s
Requested by tenant-engine TEN-WP-0011-T06 after the v0.7 Engine/PIP
declaration and shipped guardrails.

Assistant: grok
Assistant-Session: 01a04cea-e5e8-7081-a0fc-808ebbc35fa9
2026-08-29 13:02:58 +02:00
66dc491dc0 Accept the security layer model; companion v0.2 to the repository root
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
The standard is accepted at v0.7 on the owner's decision. §14 keeps two things
apart, as ops-warden asked: boundary assent, given by four repositories at the
version named in each record and undisturbed since; and revision review, where
all four reviewed v0.6 and every change in v0.7 is the adopted remedy of a
finding they raised. What is not claimed: nobody has reviewed v0.7 as text.

Accepting a standard nobody has re-read is deliberate. The estate will learn
more from using it than from another round of prose, and the v0.7 changes were
requested rather than invented. Findings against the accepted text stay
welcome — that is §12's normal business, not an exception.

The companion moves from canon/standards to the repository root as
SECURITY-COMPANION.md and becomes v0.2, so onboarding starts at the front door
rather than three directories down. One copy, not two: a second copy of a fact
is how the estate gets two sources for it.

v0.2 closes the gap access-engine found in v0.1 — it said publish your stance
map without saying where, and omitted the inventory obligation, so a repository
could satisfy it faithfully and no register would learn of its stance. It also
carries what v0.7 added: the corrected PEP obligations, the evidence threat
decomposition with its stated residual, cadence as MUST for load-bearing
sources with heartbeat for rare ones, the four agent rules and the glas-harness
seam, and the Railiance axes with their unsettled mapping.

It points readers at ops-warden for how to get things done. The companion says
what the rules are; ops-warden stewards the paths through them.

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
2026-08-29 11:28:49 +02:00
ce2554fdc9 Security Layer Model v0.7 — write the rule v0.6 only announced
Four reviews. kings-guard found that v0.6 claimed a human/agent principal
separation in §1 and §15 while §3.4 was byte-identical to v0.5: a silent edit
failure, and their framing is the right one — a rule stated about a standard in
its own change log is not a rule, which is §11's principle turned on the
standard. The same failure had dropped two §16 entries. Both restored.

§3.4 is now written: no standing credential, conduit or engine API only, agent
memory is not a state plane, every action reconstructable as the caller's, and
the seam with glas-harness for session semantics.

The rest are collisions between rules each written for its own clean case:

- §6.4(1) forbade what §6.4(3) blesses. A PEP may proceed under its declared
  §9.3 stance where the application of that stance is recorded in place of the
  decision — stricter than v0.6, since a fail-open result becomes metadata
  rather than silence. Raised by ops-warden, the reference shape it made a
  violation.
- §6.4(2) forbade the session-bound allow §9.7.1 permits. Now scoped to replay
  outside the decision's own binding and lifetime, with access-engine's
  canonical request digest as the mechanical test. Negative caching ruled
  permitted where the refusal is recorded and the lifetime declared.
- §13.1 now exists: v0.6 mandated a stance-map register and implemented none.
  Its first inventory has one row, which is the finding.
- §9.6 gained a threat decomposition after audit-core corrected its own remedy:
  atomicity prevents accidental omission, cadence and reconciliation detect the
  adversarial case, nothing prevents it at a compromised source. Cadence is now
  MUST for load-bearing sources, with heartbeat or reconciliation required for
  low-volume classes where rate monitoring cannot work.
- §9.7.2 splits by role: per input class at a PDP, one boundary deadline at a
  PEP.
- §17 moves the decision-record schema to access-engine, which argued it against
  its own interest.
- §13 stops attributing the actuation gap to kings-guard; §19 removed, since a
  verdict inside a standard grades the document it lives in.

§20 records the Railiance interaction boundary on railiance-master's own
definitions: the four axes, that a workload is a managed running deployable so
approvals are never one, and that rein-* is not a fifth axis but a glas-harness
concern. What is unsettled is listed as unsettled.

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
2026-08-29 10:44:53 +02:00
8a17551103 Add the agent companion to the security layer model
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
v0.6 is dense, self-referential, and written for readers who already live in the
estate. That is acceptable in canon and poor as a contract for the nine
repositories yet to declare and for the Staff agents expected to conform.

The companion is the operative form: the rules, no change log, no review
archaeology. Machine-readable layer key, the three sanctioned Tooling shapes as
a table, the PEP obligations, the evidence bound with the two unsound claims
written out, the four agent rules, and the four conformance states. The statute
governs on disagreement, and a disagreement is reportable as a finding.

Its §9 records that operations is HelixForge's responsibility — reef, rail,
rapp, rein — consuming the NetKingdom security and approval framework, and that
the interface is NOT yet specified. What holds today is only what holds for any
consumer. No mapping of those concepts onto the layer model should be assumed
until it is written; the statute's §16 carries the same open question.

Its §10 states the two things the estate cannot do yet — nothing is observed in
production, nothing can be contained automatically — so no reader plans around
a capability that does not exist.

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
2026-08-29 09:25:40 +02:00
745dffb8ac Security Layer Model v0.6 — type the engines, name the gate, hold actuation at zero
From the independent assessment of 2026-08-29, which found the model sound as a
layering constitution and incomplete as a self-healing one: cognition,
authority, and execution are specified, but the two verbs that close a healing
loop — observe in production, actuate through a deterministic surface — are
pending, and one is unstaffed.

Section numbers below §14 are unchanged; the estate cites them.

- §3.3 types the Engine layer: PDP, PIP, Evidence, Lifecycle, with a role column
  in §4. Collapsing them hid different failure modes — a PIP outage is input
  degradation, a PDP outage is consumer residue, an evidence-plane outage must
  not block the operation it records. A new engine is a PIP unless amended.
- §6.4 names the enforcement point. The standard was precise about the decision
  and silent about the gate, so enforcement lived in Staff runbooks. Four
  obligations: no side effect without a decision record, no local recaching of
  the verdict, a declared unreachable-engine stance, reconstructability.
- §9.2 replaced. Containment was marked pending against kings-guard, the right
  mark on the wrong repository: reduce, step-up, and isolate are
  authority-changing operations, so they are rendered by an Engine and enforced
  by a PEP. Actuation is an unowned Engine concept held at zero. Staff proposes
  containment and never performs it.
- §3.4 separates human and agent principals inside Staff — same permissions,
  different blast radius. No standing credential, conduit or engine API only,
  agent memory is not a state plane, every action reconstructable as the
  caller's.
- §9.7 puts time into the model: explicit lifetimes, revocation visibility
  deadlines, consumption as a state change never inferred from a decision
  record, and the three race modes named. §9.8 states what holds under
  partition.
- §17 requires the Taxonomy artifacts — claim, decision-record, gap-record, and
  emission-cadence schemas — without which §6.2 and §11 are reviewable but not
  compileable. Ownership proposed, not assigned.
- §18 composes the sibling standards, which had been cited in frontmatter and
  nowhere in the rules.
- §5 sunsets the uncatalogued-infrastructure carve-out. §5.3 declines a proposed
  fourth "operator of third-party Tooling" shape: it would convert a tracked gap
  into a permanent allowance, which is the relabelling failure this standard
  exists to prevent.
- §10 gains the six artifacts a layer change must carry, written from the
  zone-engine case, including a permission freeze during the cut.
- §2 lifts the observation rule so it cannot be lost in a summary. §13 separates
  its three normative rules from the table, now a snapshot due to move into
  maturity-engine. §16 decides the approval custody question: no. §19 records
  the fitness verdict.

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
2026-08-29 03:32:58 +02:00
0efa06fe5c Security Layer Model v0.5 — four reviews, nine changes
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
2026-08-29 02:54:25 +02:00
bbdff49abf Refresh work-record index
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
2026-08-29 02:45:20 +02:00
repo-manager
f4f013279d repo.work.create_intake NET-IN-0001
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
correlation_id: 980dc589-1d44-4097-b2f6-419e5bd21fd1
reason: Request own-voice layer declaration under §11
source: repo-manager

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2564823@bnt-lap001
Assistant-Session: 2a7ed827-4928-4b9f-8613-9135c9cadfe9
2026-08-28 23:01:51 +02:00
2aaf46ce95 Amend §11: who must declare, and what a declaration is
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
2026-08-28 23:01:35 +02:00
584738bd9f Security Layer Model v0.4 — audit-core assent and its corrections
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
2026-08-28 22:54:50 +02:00
90cc64f728 Security Layer Model v0.3 — assign approvals and maturity
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
2026-08-28 22:34:58 +02:00
27a31f3f8f Security Layer Model v0.2 — accepted
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
2026-08-28 22:00:31 +02:00
c42086d475 Point layering note at the published standard
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
2026-08-28 21:21:07 +02:00
1c3a9b46e3 Add NetKingdom Security Layer Model v0.1 (proposed)
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
2026-08-28 20:59:00 +02:00
56f5ba8a2c Note NetKingdom layering review in INTENT
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
2026-08-28 20:33:42 +02:00
repo-manager
d9baa06f7e chore(registrar): assign State Hub identifiers
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 3377672@bnt-lap001
Assistant-Session: 15463ccf-238f-4e13-b163-93aa25c6d166
2026-08-28 11:56:08 +02:00
2dc7258bf5 chore: ignore patch backups
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
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
2026-08-28 11:54:39 +02:00
745b54d786 chore(work-records): regenerate
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
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
2026-08-28 11:52:57 +02:00
13d41b953e feat(workplan): open NK-WP-0034 for verification that verifies
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
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
2026-08-28 11:50:51 +02:00
e7d326458c docs(custody): every credential says what it is
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
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
2026-08-28 11:42:51 +02:00
3252e68a84 chore(work-records): regenerate
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
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
2026-08-28 10:35:46 +02:00
c99b8da41f docs: name where operator credentials live, and label unexercised procedures
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
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
2026-08-28 10:33:48 +02:00
fd86397f52 fix(workplans): qualify archived ad-hoc identifiers
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
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
2026-08-28 00:34:01 +02:00
13001a1452 fix(workplans): qualify ad-hoc identifiers with the repository prefix
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
`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
2026-08-28 00:28:23 +02:00
custodian-sync
c499843091 chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
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
2026-08-27 22:22:03 +02:00
0f5f56275c docs(nk-wp-0033): record the 2026-08-27 attended session findings
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
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
2026-08-27 22:20:48 +02:00
4a38511d11 fix(privacyidea): repair the resolver reconciliation script (NK-WP-0033)
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
2026-08-27 22:20:03 +02:00
7ce02957b3 fix(workplans): terminate frontmatter that ran into the document
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
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
2026-08-26 08:28:56 +02:00
custodian-sync
0d01f08976 chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
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
2026-08-25 20:15:52 +02:00
82452d655f fix(workplans): adopt ADR-007 derived identifiers for unregistered records
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
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
2026-08-25 20:14:28 +02:00
custodian-sync
623e9d24ba chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
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
2026-08-25 19:54:47 +02:00
80c3a76431 chore: commit work in progress before registrar reconciliation
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Refs CUST-WP-0068

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
2026-08-25 19:53:36 +02:00
eebf5de371 docs(agents): repoint remote State Hub URL to the in-cluster address
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
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
2026-08-25 00:21:25 +02:00
5b0a521c9a NK-WP-0033 add attended resolver reconciliation receipt
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02929-244b-7391-b933-c04010e8eedb
2026-08-23 15:18:29 +02:00
eec7007c21 docs(security): pin privacyidea resolver reconciliation
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02929-244b-7391-b933-c04010e8eedb
2026-08-23 15:05:18 +02:00
dc21d246e4 chore(consistency): record resolver follow-up status
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02e3f-7301-7622-9be1-12e5f352881c
2026-08-23 14:45:44 +02:00
custodian-sync
1b60031b1d chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Updated by fix-consistency on 2026-08-23:
  - update .custodian-brief.md for net-kingdom

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02e3f-7301-7622-9be1-12e5f352881c
2026-08-23 14:44:13 +02:00
f2e578cf3e feat(privacyidea): add guarded resolver reconciliation helper
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02929-244b-7391-b933-c04010e8eedb
2026-08-23 14:43:39 +02:00
edee5c28ab docs: record downstream rotation follow-up
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02e3f-7301-7622-9be1-12e5f352881c
2026-08-23 14:42:59 +02:00
c956ceba19 fix(authelia): load rotated client verifier from secret file
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02929-244b-7391-b933-c04010e8eedb
2026-08-23 14:39:32 +02:00
custodian-sync
d4333f02e0 chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Updated by fix-consistency on 2026-08-23:
  - update .custodian-brief.md for net-kingdom

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02929-244b-7391-b933-c04010e8eedb
2026-08-23 14:19:44 +02:00
c24d67bb85 docs(security): map KeyCape rotation dependencies
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02929-244b-7391-b933-c04010e8eedb
2026-08-23 14:17:42 +02:00
repo-manager
9ae4e24305 chore(registrar): assign State Hub identifiers
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02929-244b-7391-b933-c04010e8eedb
2026-08-23 14:08:12 +02:00
custodian-sync
7b2c9e8aa9 chore(consistency): sync task status from DB [auto]
Some checks are pending
CI Smoke / host-smoke (push) Waiting to run
CI Smoke / container-smoke (push) Waiting to run
Updated by fix-consistency on 2026-08-23:
  - update .custodian-brief.md for net-kingdom

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02929-244b-7391-b933-c04010e8eedb
2026-08-23 14:08:11 +02:00
9264a8a613 docs(security): open KeyCape exposure rotation incident
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02929-244b-7391-b933-c04010e8eedb
2026-08-23 14:05:07 +02:00
61aeafef71 feat(NK-WP-0032): admit OpenBao operator loopback callback
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02b90-83bf-75c2-81c8-aa705414e4d4
2026-08-23 14:01:57 +02:00
6700f1c1c3 docs(posture): record repaired estate baseline
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02929-244b-7391-b933-c04010e8eedb
2026-08-23 13:28:08 +02:00