Compare commits
No commits in common. "97c7eea1da9857b160d7f9933279405d19284749" and "3686f8994bef468499abf58ddb6020503ed285e6" have entirely different histories.
97c7eea1da
...
3686f8994b
13 changed files with 46 additions and 1030 deletions
|
|
@ -1,14 +1,13 @@
|
||||||
{
|
{
|
||||||
"schema": "repo_manager.index.v1",
|
"schema": "repo_manager.index.v1",
|
||||||
"slug": "layer-model-v03-review",
|
"slug": "layer-model-assent",
|
||||||
"repo_root": "/home/worsch/kings-guard",
|
"repo_root": "/home/worsch/kings-guard",
|
||||||
"head_sha": "3686f8994bef468499abf58ddb6020503ed285e6",
|
"head_sha": "7c8ef38ee0603c4ca23e69abaff689b86da752b4",
|
||||||
"observed_at": "2026-08-28T20:40:12.405988Z",
|
"observed_at": "2026-08-28T19:30:17.391432Z",
|
||||||
"source_fingerprint": "cfeafedc875687fa1f24d10127b22b0b6dcce30f1faddf803b7c2a19e046cf12",
|
"source_fingerprint": "ff379cda32bd3d625590480dbf164739c18022680a8390e4cd6a48514324cc5c",
|
||||||
"source_files": [
|
"source_files": [
|
||||||
".repo-classification.yaml",
|
".repo-classification.yaml",
|
||||||
"INTENT.md",
|
"INTENT.md",
|
||||||
"decisions/decisions.md",
|
|
||||||
"intakes/intakes.md",
|
"intakes/intakes.md",
|
||||||
"workplans/KG-WP-0001-statehub-bootstrap.md",
|
"workplans/KG-WP-0001-statehub-bootstrap.md",
|
||||||
"workplans/KG-WP-0002-canonical-immune-contracts-and-posture-pilot.md"
|
"workplans/KG-WP-0002-canonical-immune-contracts-and-posture-pilot.md"
|
||||||
|
|
@ -104,60 +103,20 @@
|
||||||
"parent_id": "KG-WP-0002",
|
"parent_id": "KG-WP-0002",
|
||||||
"extra": {}
|
"extra": {}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"kind": "decision",
|
|
||||||
"id": "KG-DEC-2026-001",
|
|
||||||
"status": "resolved",
|
|
||||||
"title": "Assent to Staff placement, release of control-plane vocabulary, and the posture asymmetry",
|
|
||||||
"source_path": "decisions/decisions.md",
|
|
||||||
"uuid": "80313094-9b5d-4954-b37b-3313deac6b65",
|
|
||||||
"parent_id": null,
|
|
||||||
"extra": {
|
|
||||||
"record": {
|
|
||||||
"id": "KG-DEC-2026-001",
|
|
||||||
"kind": "decision",
|
|
||||||
"title": "Assent to Staff placement, release of control-plane vocabulary, and the posture asymmetry",
|
|
||||||
"status": "resolved",
|
|
||||||
"owner": "Bernd Worsch",
|
|
||||||
"repo": "kings-guard",
|
|
||||||
"standard": "net-kingdom/canon/standards/security-layer-model_v0.1.md",
|
|
||||||
"origin_ref": "KG-IN-0001",
|
|
||||||
"related": [
|
|
||||||
"gate-house/decisions/decisions.md GH-DEC-2026-001",
|
|
||||||
"gate-house/history/2026-08-28-security-layer-model-and-gate-house-recut.md"
|
|
||||||
],
|
|
||||||
"affects": [
|
|
||||||
"kings-guard",
|
|
||||||
"gate-house",
|
|
||||||
"net-kingdom",
|
|
||||||
"access-engine",
|
|
||||||
"secrets-engine",
|
|
||||||
"user-engine"
|
|
||||||
],
|
|
||||||
"created": "2026-08-28",
|
|
||||||
"updated": "2026-08-28",
|
|
||||||
"decided_by": "Bernd Worsch",
|
|
||||||
"disposition": "assent-with-finding",
|
|
||||||
"state_hub_decision_id": "80313094-9b5d-4954-b37b-3313deac6b65"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"kind": "intake",
|
"kind": "intake",
|
||||||
"id": "KG-IN-0001",
|
"id": "KG-IN-0001",
|
||||||
"status": "closed",
|
"status": "open",
|
||||||
"title": "Assent requested: Staff layer placement, control-plane vocabulary, and the posture asymmetry",
|
"title": "Assent requested: Staff layer placement, control-plane vocabulary, and the posture asymmetry",
|
||||||
"source_path": "intakes/intakes.md",
|
"source_path": "intakes/intakes.md",
|
||||||
"uuid": "01a049ea-2e37-7dde-9772-fab7e788d8d7",
|
"uuid": null,
|
||||||
"parent_id": null,
|
"parent_id": null,
|
||||||
"extra": {
|
"extra": {
|
||||||
"record": {
|
"record": {
|
||||||
"id": "KG-IN-0001",
|
"id": "KG-IN-0001",
|
||||||
"kind": "intake",
|
"kind": "intake",
|
||||||
"title": "Assent requested: Staff layer placement, control-plane vocabulary, and the posture asymmetry",
|
"title": "Assent requested: Staff layer placement, control-plane vocabulary, and the posture asymmetry",
|
||||||
"status": "closed",
|
"status": "open",
|
||||||
"outcome": "absorbed",
|
|
||||||
"promoted_to": "KG-DEC-2026-001",
|
|
||||||
"origin": "cross-repo",
|
"origin": "cross-repo",
|
||||||
"origin_ref": "gate-house GH-DEC-2026-001",
|
"origin_ref": "gate-house GH-DEC-2026-001",
|
||||||
"priority": "medium",
|
"priority": "medium",
|
||||||
|
|
@ -166,61 +125,7 @@
|
||||||
"standard": "net-kingdom/canon/standards/security-layer-model_v0.1.md",
|
"standard": "net-kingdom/canon/standards/security-layer-model_v0.1.md",
|
||||||
"description": "gate-house asks kings-guard to assent to its placement in the NetKingdom security layer model. (1) kings-guard is Staff \u2014 agentic and non-deterministic \u2014 not an Engine. Acting at runtime does not make a repository an Engine; being agentic makes it Staff. (2) Consequently its self-description as an adaptive security control plane needs revisiting: control plane is Engine-layer vocabulary (standard section 8). This is not a demotion \u2014 it is the reason kings-guard may contain a threat only by calling an engine, never by reaching into OpenBao or a cluster directly (the binding rule, standard section 5: Staff never touches Tooling directly). (3) The posture contract with gate-house and its asymmetry: adaptive systems may reduce authority, require step-up, or request containment; they must never probabilistically manufacture additional authority. kings-guard publishes posture, gate-house defines its authority meaning, access-engine renders it. If the binding rule is impractical for containment in a real incident, say so \u2014 that is exactly the kind of finding that should change the doctrine rather than be worked around.",
|
"description": "gate-house asks kings-guard to assent to its placement in the NetKingdom security layer model. (1) kings-guard is Staff \u2014 agentic and non-deterministic \u2014 not an Engine. Acting at runtime does not make a repository an Engine; being agentic makes it Staff. (2) Consequently its self-description as an adaptive security control plane needs revisiting: control plane is Engine-layer vocabulary (standard section 8). This is not a demotion \u2014 it is the reason kings-guard may contain a threat only by calling an engine, never by reaching into OpenBao or a cluster directly (the binding rule, standard section 5: Staff never touches Tooling directly). (3) The posture contract with gate-house and its asymmetry: adaptive systems may reduce authority, require step-up, or request containment; they must never probabilistically manufacture additional authority. kings-guard publishes posture, gate-house defines its authority meaning, access-engine renders it. If the binding rule is impractical for containment in a real incident, say so \u2014 that is exactly the kind of finding that should change the doctrine rather than be worked around.",
|
||||||
"created": "2026-08-28T19:30:17.201213Z",
|
"created": "2026-08-28T19:30:17.201213Z",
|
||||||
"updated": "2026-08-28T19:30:17.201213Z",
|
"updated": "2026-08-28T19:30:17.201213Z"
|
||||||
"closed": "2026-08-28",
|
|
||||||
"resolution": "Assent with finding. All three points assented and adopted in INTENT.md, SCOPE.md, README.md, AGENTS.md, and docs/AdjacentSystemBoundary.md. The invited challenge to the binding rule was taken up and answered: do not weaken section 5 \u2014 but section 4 catalogs kings-guard as owning containment while no engine exposes a containment surface, so the charter is currently undischargeable. Two rulings requested of gate-house. Full record: decisions/decisions.md KG-DEC-2026-001. Vocabulary sweep of the architecture spec handed off as KG-IN-0002.",
|
|
||||||
"state_hub_intake_id": "01a049ea-2e37-7dde-9772-fab7e788d8d7"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"kind": "intake",
|
|
||||||
"id": "KG-IN-0002",
|
|
||||||
"status": "open",
|
|
||||||
"title": "Sweep \"control plane\" and layer vocabulary through NetKingdomImmuneArchitecture.md",
|
|
||||||
"source_path": "intakes/intakes.md",
|
|
||||||
"uuid": "01a049ea-3a04-74b9-a9b1-e2630f8d5628",
|
|
||||||
"parent_id": null,
|
|
||||||
"extra": {
|
|
||||||
"record": {
|
|
||||||
"id": "KG-IN-0002",
|
|
||||||
"kind": "intake",
|
|
||||||
"title": "Sweep \"control plane\" and layer vocabulary through NetKingdomImmuneArchitecture.md",
|
|
||||||
"status": "open",
|
|
||||||
"origin": "residual",
|
|
||||||
"origin_ref": "KG-DEC-2026-001",
|
|
||||||
"priority": "low",
|
|
||||||
"owner": "kings-guard",
|
|
||||||
"standard": "net-kingdom/canon/standards/security-layer-model_v0.1.md",
|
|
||||||
"description": "specs/NetKingdomImmuneArchitecture.md (approx. 1900 lines) predates the NetKingdom Security Layer Model and uses \"control plane\" in several places \u2014 including a \"Platform Immune Control Plane\" subgraph \u2014 where the layer model reserves that vocabulary for the Engine layer. A scoping note now sits at the head of the document so no reading takes it as a kings-guard self-description, but the body is not adapted. Sweep it: separate the components that are engine-layer authorities from the observation-and-judgment surface kings-guard actually owns, and check that no part of the architecture places a decision point in Staff (layer model section 6).",
|
|
||||||
"created": "2026-08-28",
|
|
||||||
"updated": "2026-08-28",
|
|
||||||
"state_hub_intake_id": "01a049ea-3a04-74b9-a9b1-e2630f8d5628"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"kind": "intake",
|
|
||||||
"id": "KG-IN-0003",
|
|
||||||
"status": "open",
|
|
||||||
"title": "Review requested: security layer model v0.3 (maturity-engine, and the posture/maturity boundary)",
|
|
||||||
"source_path": "intakes/intakes.md",
|
|
||||||
"uuid": null,
|
|
||||||
"parent_id": null,
|
|
||||||
"extra": {
|
|
||||||
"record": {
|
|
||||||
"id": "KG-IN-0003",
|
|
||||||
"kind": "intake",
|
|
||||||
"title": "Review requested: security layer model v0.3 (maturity-engine, and the posture/maturity boundary)",
|
|
||||||
"status": "open",
|
|
||||||
"origin": "cross-repo",
|
|
||||||
"origin_ref": "net-kingdom security-layer-model_v0.3",
|
|
||||||
"priority": "medium",
|
|
||||||
"owner": "kings-guard",
|
|
||||||
"requested_by": "gate-house",
|
|
||||||
"description": "v0.3 is proposed and changes sections 4, 9 and 13 only; the v0.2 assent record stands. It responds directly to KG-DEC-2026-001. Section 9.5 assigns graded progression to a new maturity-engine, which now owns the gap register with intended_owner, blocked_on and review dates, and capability readiness \u2014 so your three declared engine gaps and the pending containment claim become queryable facts rather than footnotes in a standard. Your finding also produced 9.1 in v0.2, and v0.3 applies it to gate-house itself: gate-house was catalogued as owning conformance review with no engine to act through, exactly the defect you named for containment, and it now acts through maturity-engine. THE QUESTION FOR YOU is a boundary we have not drawn: posture and maturity are both graded, and we do not want two engines grading the same subject. Our reading is that posture is volatile current security state about an actor, published by kings-guard and rendered by access-engine, while maturity is slow progression of a capability against declared criteria. If that line is wrong, or if maturity-engine would absorb something you consider posture, say so now \u2014 a second grading authority would be the same shape of mistake as a second decision point. Also worth your view: does capability readiness for containment belong in maturity-engine, or does tracking your own gaps there create a dependency you would rather not carry during an incident? Assent, revision, or rejection acceptable.",
|
|
||||||
"created": "2026-08-28T20:40:12.260389Z",
|
|
||||||
"updated": "2026-08-28T20:40:12.260389Z"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -230,15 +135,15 @@
|
||||||
"type": "repo.command.applied",
|
"type": "repo.command.applied",
|
||||||
"command": "repo.work.create_intake",
|
"command": "repo.work.create_intake",
|
||||||
"operation": "create",
|
"operation": "create",
|
||||||
"correlation_id": "aae5e5ae-a706-4da5-82fc-a0fb8982ca5b",
|
"correlation_id": "f9b8b130-71f6-41b9-9f06-e28d2abda2d4",
|
||||||
"kind": "intake",
|
"kind": "intake",
|
||||||
"id": "KG-IN-0003",
|
"id": "KG-IN-0001",
|
||||||
"git_sha": "3686f8994bef468499abf58ddb6020503ed285e6",
|
"git_sha": "7c8ef38ee0603c4ca23e69abaff689b86da752b4",
|
||||||
"files_touched": [
|
"files_touched": [
|
||||||
"intakes/intakes.md"
|
"intakes/intakes.md"
|
||||||
],
|
],
|
||||||
"source": "repo-manager",
|
"source": "repo-manager",
|
||||||
"emitted_at": "2026-08-28T20:40:12.406045Z"
|
"emitted_at": "2026-08-28T19:30:17.391507Z"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
120
INTENT.md
120
INTENT.md
|
|
@ -1,76 +1,28 @@
|
||||||
---
|
|
||||||
# NetKingdom security layer declaration (statute §11, companion §2).
|
|
||||||
# Machine-readable form; the prose below is the same claim in our own voice.
|
|
||||||
# Full contact map and gap records: layer.yaml
|
|
||||||
layer: Staff
|
|
||||||
role: null # Engines only
|
|
||||||
standard: net-kingdom/canon/standards/security-layer-model_v0.7.md
|
|
||||||
standard_version: "0.7"
|
|
||||||
declared_by: decisions/decisions.md#KG-DEC-2026-001
|
|
||||||
declared_at: "2026-08-29"
|
|
||||||
conformance_state: blocked-clean
|
|
||||||
principal_kinds: [human, agent]
|
|
||||||
---
|
|
||||||
|
|
||||||
# INTENT
|
# INTENT
|
||||||
|
|
||||||
> **Layer: Staff.** *(NetKingdom Security Layer Model
|
> **Layer: Staff.** *(NetKingdom Security Layer Model v0.1, §4 catalog —
|
||||||
> `net-kingdom/canon/standards/security-layer-model_v0.7.md`, **accepted**, §4
|
> `net-kingdom/canon/standards/security-layer-model_v0.1.md`; ratified by
|
||||||
> catalog; working form: `net-kingdom/SECURITY-COMPANION.md`;
|
> `gate-house/decisions/decisions.md` GH-DEC-2026-001; assented here by
|
||||||
> ratified by `gate-house/decisions/decisions.md` GH-DEC-2026-001; assented here
|
> `decisions/decisions.md` KG-DEC-2026-001 on 2026-08-28.)*
|
||||||
> by `decisions/decisions.md` KG-DEC-2026-001 on 2026-08-28, against v0.1.)*
|
|
||||||
>
|
>
|
||||||
> **The declaration is the frontmatter above plus `layer.yaml`**, checked by
|
> kings-guard is **interactive and non-deterministic**: adaptive defence,
|
||||||
> `scripts/check_layer_conformance.py` and tested in
|
> observation, containment. Acting at runtime does not make a repository an
|
||||||
> `tests/test_layer_conformance.py`. Prose cannot distinguish a declaration from
|
> Engine; being agentic makes it Staff.
|
||||||
> a transcribed review, so those are authoritative and this note is commentary
|
|
||||||
> in kings-guard's own voice, as the companion asks.
|
|
||||||
>
|
|
||||||
> **Catalog entry (v0.7 §4):** adaptive defence and judgment; observation of
|
|
||||||
> Staff-reachable sources — identity and secret observation **pending**;
|
|
||||||
> **proposes** containment, which it does not own.
|
|
||||||
>
|
|
||||||
> kings-guard is **interactive and non-deterministic**. Acting at runtime does
|
|
||||||
> not make a repository an Engine; being agentic makes it Staff.
|
|
||||||
>
|
>
|
||||||
> **The binding rule (§5): Staff never touches Tooling directly. It acts only
|
> **The binding rule (§5): Staff never touches Tooling directly. It acts only
|
||||||
> through Engine APIs.** kings-guard holds no direct client for a Tooling-layer
|
> through Engine APIs.** kings-guard holds no direct client for a Tooling-layer
|
||||||
> system — no database connection, no OpenBao client, no cluster mutation, and
|
> system — no database connection, no OpenBao client, no cluster mutation. It
|
||||||
> no §5.1 diagnostic read or §5.2 conduit either. Under §11 that is
|
> may contain a threat only by calling an engine. Where no engine exposes a
|
||||||
> **blocked-clean**: the capabilities needing such a contact sit at zero rather
|
> capability kings-guard needs, that is raised as an **engine gap**, never
|
||||||
> than being taken locally, and §11 rules that this MUST NOT rank below
|
> solved locally; the open gaps are listed under *System boundary* below.
|
||||||
> conforming.
|
|
||||||
>
|
|
||||||
> **Containment is not ours (§9.2).** v0.6 moved it off this repository
|
|
||||||
> entirely: reduce authority, require step-up, and isolate a workload are
|
|
||||||
> authority-changing operations, so they are rendered by an Engine and enforced
|
|
||||||
> by a PEP. **kings-guard proposes containment; it never performs it.** The
|
|
||||||
> actuation surface is unowned and held at zero estate-wide, so no argument
|
|
||||||
> anywhere may assume containment is automatic.
|
|
||||||
>
|
|
||||||
> **The agent principal (§3.4).** kings-guard is Staff of the agentic kind, and
|
|
||||||
> v0.7 binds that principal with four rules this repository offered to accept
|
|
||||||
> before they were written. They are adopted here as repository invariants:
|
|
||||||
> **no standing credential** — authority is per task, time-bounded, attributable
|
|
||||||
> to the principal acted for; **tool use is a §5.2 conduit or an Engine API, and
|
|
||||||
> there is no third route** — a callable tool means the operation exists, not
|
|
||||||
> that this actor may invoke it; **agent memory is not a state plane** — immune
|
|
||||||
> memory, tool-call traces and prompt caches are kings-guard's own and MUST NOT
|
|
||||||
> become state another layer depends on at runtime unless catalogued as Tooling;
|
|
||||||
> **every action is reconstructable as the caller's**, bounded by §9.6.
|
|
||||||
>
|
|
||||||
> The third rule constrains this repository's own roadmap and is the one to
|
|
||||||
> watch: federated immune memory (*Direction of Evolution* stage 5) is exactly
|
|
||||||
> the shape that could drift into a state plane, and it may not.
|
|
||||||
>
|
>
|
||||||
> **Posture contract.** kings-guard **publishes** posture; `gate-house` defines
|
> **Posture contract.** kings-guard **publishes** posture; `gate-house` defines
|
||||||
> its authority meaning; `access-engine` renders it. Posture is not a privilege
|
> its authority meaning; `access-engine` renders it. Posture is not a privilege
|
||||||
> source. The asymmetry is absolute: kings-guard may **reduce** authority,
|
> source. The asymmetry is absolute: kings-guard may **reduce** authority,
|
||||||
> **require step-up**, or **request containment**; it MUST NOT probabilistically
|
> **require step-up**, or **request containment**; it MUST NOT probabilistically
|
||||||
> manufacture additional authority. Every effector request carries an explicit
|
> manufacture additional authority. Every effector request it emits therefore
|
||||||
> authority boundary. Under incomplete observation this asymmetry is what bounds
|
> carries an explicit authority boundary and is advisory unless the owning
|
||||||
> the damage: a suppressed event can only cost a tightening that should have
|
> system has already delegated a narrow, deterministic action lane.
|
||||||
> happened, never manufacture authority through us (§8, §9.6).
|
|
||||||
|
|
||||||
> This file captures **why this repository exists**, the **direction it is
|
> This file captures **why this repository exists**, the **direction it is
|
||||||
> moving toward**, and the **kind of system it is meant to become**.
|
> moving toward**, and the **kind of system it is meant to become**.
|
||||||
|
|
@ -191,19 +143,11 @@ Capabilities kings-guard needs that no engine exposes today. Under the binding
|
||||||
rule these are gaps to close in the owning engine, not work to route around.
|
rule these are gaps to close in the owning engine, not work to route around.
|
||||||
None is a standing licence to reach into Tooling.
|
None is a standing licence to reach into Tooling.
|
||||||
|
|
||||||
These are **unowned capabilities**, not §5.3 declared contacts: kings-guard
|
| Gap | Needed for | Owning engine | Status |
|
||||||
makes no direct Tooling contact for any of them. v0.5 §11 added the
|
| --- | --- | --- | --- |
|
||||||
**blocked-clean** state for exactly this case, on kings-guard's finding, and
|
| Authentication and assurance evidence (token assurance, attestation outcomes, authentication anomalies) exposed as an engine surface | identity-drift posture | `user-engine` / `access-engine` | open — no engine surface; kings-guard consumes fixtures only |
|
||||||
ruled that it MUST NOT rank below conforming.
|
| Secret-use evidence (lease, revocation, mount and rotation metadata) exposed as an engine surface | secret-abuse posture | `secrets-engine` | open — no engine surface; kings-guard consumes fixtures only |
|
||||||
|
| A containment surface — reduce authority, require step-up, isolate a workload — callable as a deterministic engine API, and available while an incident is in progress | bounded response | `access-engine`, runtime engines | open — see KG-DEC-2026-001 §Finding |
|
||||||
`layer.yaml` is the authoritative machine-readable form; this table is the
|
|
||||||
human-readable view of it.
|
|
||||||
|
|
||||||
| `capability` | Needed for | `intended_owner` | `blocked_on` | `review` |
|
|
||||||
| --- | --- | --- | --- | --- |
|
|
||||||
| Authentication and assurance evidence (token assurance, attestation outcomes, authentication anomalies) exposed as an engine surface | identity-drift posture | identity layer + `audit-core` — **`access-engine` declined** (v0.6 §13); reproposed, not assented | no engine surface exists; kings-guard consumes fixtures only | 2026-11-28 |
|
|
||||||
| Secret-use evidence (lease, revocation, mount and rotation metadata) exposed as an engine surface | secret-abuse posture | `secrets-engine` | no engine surface exists; kings-guard consumes fixtures only | 2026-11-28 |
|
|
||||||
| Actuation surface — reduce authority, require step-up, isolate a workload — as a deterministic engine API carrying a decision record | containment kings-guard **proposes but does not own** | `access-engine` + runtime PEPs; not reviewed (`FLEX-DEC-2026-002`) | ruled an Engine concept held at zero (v0.6 §9.2); recorded here as a dependency, not a kings-guard gap to close | 2026-11-28 |
|
|
||||||
|
|
||||||
Until a gap closes, the corresponding posture lane stays advisory and
|
Until a gap closes, the corresponding posture lane stays advisory and
|
||||||
fixture-driven. kings-guard MUST NOT open a direct path to the Tooling system
|
fixture-driven. kings-guard MUST NOT open a direct path to the Tooling system
|
||||||
|
|
@ -262,7 +206,7 @@ Kings Guard is:
|
||||||
- an adaptive defence concept and implementation home, in the Staff layer;
|
- an adaptive defence concept and implementation home, in the Staff layer;
|
||||||
- a contract layer for healthy intent, observations, signals, posture, and
|
- a contract layer for healthy intent, observations, signals, posture, and
|
||||||
effectors;
|
effectors;
|
||||||
- a coordination system for detection, containment **proposal**, recovery, and governed memory;
|
- a coordination system for detection, containment, recovery, and memory;
|
||||||
- a reference architecture for recursive, compartment-aware cloud defense.
|
- a reference architecture for recursive, compartment-aware cloud defense.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -271,9 +215,6 @@ Kings Guard is:
|
||||||
|
|
||||||
Kings Guard is not:
|
Kings Guard is not:
|
||||||
|
|
||||||
- an actuator — it proposes containment and never performs it (§9.2);
|
|
||||||
- a holder of any standing credential (§3.4 rule 1);
|
|
||||||
- a state plane for any other layer, its immune memory included (§3.4 rule 3);
|
|
||||||
- an identity provider;
|
- an identity provider;
|
||||||
- an authorization registry;
|
- an authorization registry;
|
||||||
- a secret store;
|
- a secret store;
|
||||||
|
|
@ -291,26 +232,13 @@ The repository should evolve through clear layers:
|
||||||
phenotype, observation, signal, effector, tolerance, inflammation, and
|
phenotype, observation, signal, effector, tolerance, inflammation, and
|
||||||
immune memory.
|
immune memory.
|
||||||
2. **Assessment loop:** provide a minimal service that ingests observations,
|
2. **Assessment loop:** provide a minimal service that ingests observations,
|
||||||
evaluates posture against declared intent, and produces typed signals —
|
evaluates posture against declared intent, and produces typed signals.
|
||||||
against **real emitted events**, not fixtures. §12's fourth step
|
3. **Bounded response:** integrate with selected effectors for isolation,
|
||||||
("kings-guard observes it in operation") is the estate's, and it is
|
throttling, revocation, or reconstitution under explicit policy.
|
||||||
unstaffed until this stage is live. Completeness of the stream is part of
|
|
||||||
the judgment, not an assumption about it (§9.6).
|
|
||||||
3. **Bounded proposal:** emit containment *requests* — isolation, throttling,
|
|
||||||
revocation, reconstitution — as typed, authority-bounded proposals to the
|
|
||||||
engine that renders them. kings-guard never actuates (§9.2); the actuation
|
|
||||||
surface is an Engine concept and is unowned estate-wide. This stage is
|
|
||||||
complete when the proposals are well-formed and reconstructable, not when
|
|
||||||
anything is contained.
|
|
||||||
4. **Recovery and validation:** prove that known-good restoration can be
|
4. **Recovery and validation:** prove that known-good restoration can be
|
||||||
coordinated and verified, not merely requested.
|
coordinated and verified, not merely requested.
|
||||||
5. **Federated memory:** retain reusable defensive knowledge without exposing
|
5. **Federated memory:** retain reusable defensive knowledge without exposing
|
||||||
tenant-confidential operational detail — and **without becoming a state
|
tenant-confidential operational detail.
|
||||||
plane**. Under §3.4 rule 3 agent memory may not become state another layer
|
|
||||||
depends on at runtime. Immune memory may inform kings-guard's own judgment
|
|
||||||
and may be published as evidence; no engine, PEP, or workload may read it as
|
|
||||||
an input it depends on. If that ever becomes desirable it is a Tooling
|
|
||||||
catalog change under §4, not a quiet integration.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
7
Makefile
7
Makefile
|
|
@ -1,6 +1,6 @@
|
||||||
PYTHON ?= python3
|
PYTHON ?= python3
|
||||||
|
|
||||||
.PHONY: install-dev test lint run-demo check-layer
|
.PHONY: install-dev test lint run-demo
|
||||||
|
|
||||||
install-dev:
|
install-dev:
|
||||||
$(PYTHON) -m pip install -e ".[dev]"
|
$(PYTHON) -m pip install -e ".[dev]"
|
||||||
|
|
@ -11,10 +11,5 @@ test:
|
||||||
lint:
|
lint:
|
||||||
$(PYTHON) -m ruff check src tests
|
$(PYTHON) -m ruff check src tests
|
||||||
|
|
||||||
# NetKingdom Security Layer Model §11 — makes the no-Tooling-client claim
|
|
||||||
# checkable rather than asserted. See layer.yaml.
|
|
||||||
check-layer:
|
|
||||||
$(PYTHON) scripts/check_layer_conformance.py --report
|
|
||||||
|
|
||||||
run-demo:
|
run-demo:
|
||||||
PYTHONPATH=src $(PYTHON) -m kings_guard.main --pilot qonto-assistant
|
PYTHONPATH=src $(PYTHON) -m kings_guard.main --pilot qonto-assistant
|
||||||
|
|
|
||||||
45
SCOPE.md
45
SCOPE.md
|
|
@ -9,7 +9,7 @@
|
||||||
**Staff** — interactive, non-deterministic; adaptive defence, observation,
|
**Staff** — interactive, non-deterministic; adaptive defence, observation,
|
||||||
containment. Binding rule: kings-guard never touches Tooling directly; it acts
|
containment. Binding rule: kings-guard never touches Tooling directly; it acts
|
||||||
only through Engine APIs. See `INTENT.md` and
|
only through Engine APIs. See `INTENT.md` and
|
||||||
`net-kingdom/canon/standards/security-layer-model_v0.6.md`.
|
`net-kingdom/canon/standards/security-layer-model_v0.1.md`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -23,13 +23,9 @@ platforms.
|
||||||
## Core Idea
|
## Core Idea
|
||||||
|
|
||||||
`kings-guard` turns declared healthy intent plus observed runtime behavior into
|
`kings-guard` turns declared healthy intent plus observed runtime behavior into
|
||||||
posture judgments, typed security signals, and bounded response **requests**. It
|
posture judgments, typed security signals, and bounded response requests. It
|
||||||
consumes evidence without replacing any system's primary authority, and it
|
consumes evidence from identity, authorization, secret, and runtime systems
|
||||||
actuates nothing: containment is rendered by an Engine and enforced by a PEP
|
without replacing those systems' primary authority.
|
||||||
(statute §9.2).
|
|
||||||
|
|
||||||
The one-line test for anything proposed here: **does it judge and propose, or
|
|
||||||
does it decide and act?** The first is in scope. The second is another layer's.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -37,37 +33,19 @@ does it decide and act?** The first is in scope. The second is another layer's.
|
||||||
|
|
||||||
- Canonical terminology and contracts for security genome, phenotype,
|
- Canonical terminology and contracts for security genome, phenotype,
|
||||||
observation, signal, effector, tolerance, inflammation, and immune memory.
|
observation, signal, effector, tolerance, inflammation, and immune memory.
|
||||||
- **Evidence classification** — marking each consumed stream load-bearing or
|
|
||||||
attributive (§9.6), since the obligations differ.
|
|
||||||
- **The emission-cadence declaration draft** (§17). kings-guard is its only
|
|
||||||
consumer and drafts it; Taxonomy owns it. Includes the reconciliation or
|
|
||||||
heartbeat form required for low-volume load-bearing classes, where rate
|
|
||||||
monitoring cannot work.
|
|
||||||
- **Stream-completeness judgment** — treating silence as a signal, and carrying
|
|
||||||
the resulting doubt in the posture output rather than reporting confidence in
|
|
||||||
a stream that may be incomplete.
|
|
||||||
- Reference architecture and boundary documents for adaptive defense in
|
- Reference architecture and boundary documents for adaptive defense in
|
||||||
multi-tenant and agent-active environments.
|
multi-tenant and agent-active environments.
|
||||||
- Minimal posture-evaluation loop design: ingest observations, compare against
|
- Minimal posture-evaluation loop design: ingest observations, compare against
|
||||||
intended healthy state, and emit typed posture/signal results.
|
intended healthy state, and emit typed posture/signal results.
|
||||||
- Integration seams to adjacent security systems, taken **through the owning
|
- Integration seams to adjacent security systems such as `key-cape`,
|
||||||
engine**: `access-engine` (the decision point, currently named `flex-auth`),
|
`flex-auth`, `secrets-engine`, `ops-warden`, and the Railiance runtime
|
||||||
`secrets-engine`, `user-engine`, `audit-core`, and the Railiance runtime
|
layers.
|
||||||
layers. `key-cape` and OpenBao are Tooling and are never contacted directly.
|
|
||||||
- Non-secret evidence, workplans, and repo-operational metadata.
|
- Non-secret evidence, workplans, and repo-operational metadata.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Out of Scope
|
## Out of Scope
|
||||||
|
|
||||||
- **Actuation of any kind.** Reduce authority, require step-up, isolate a
|
|
||||||
workload — these are authority-changing operations rendered by an Engine and
|
|
||||||
enforced by a PEP. kings-guard proposes them and never performs them, even
|
|
||||||
when no engine surface exists to receive the proposal.
|
|
||||||
- **Holding a standing credential** (§3.4 rule 1).
|
|
||||||
- **Becoming a state plane for another layer**, immune memory included
|
|
||||||
(§3.4 rule 3). Immune memory informs kings-guard's judgment and may be
|
|
||||||
published as evidence; nothing may depend on it at runtime.
|
|
||||||
- Identity issuance, login, MFA, or token minting.
|
- Identity issuance, login, MFA, or token minting.
|
||||||
- Any direct client for a Tooling-layer system (OpenBao, key-cape components,
|
- Any direct client for a Tooling-layer system (OpenBao, key-cape components,
|
||||||
a database, a cluster) — every such need routes through the owning engine.
|
a database, a cluster) — every such need routes through the owning engine.
|
||||||
|
|
@ -75,8 +53,6 @@ does it decide and act?** The first is in scope. The second is another layer's.
|
||||||
estate's only decision point.
|
estate's only decision point.
|
||||||
- "Control plane" as a self-description — that vocabulary belongs to the
|
- "Control plane" as a self-description — that vocabulary belongs to the
|
||||||
Engine layer.
|
Engine layer.
|
||||||
- Claiming that an event's absence from an archive proves it did not happen, or
|
|
||||||
that a quiet stream is a healthy one (§9.6).
|
|
||||||
- Authorization policy administration or final resource allow/deny decisions.
|
- Authorization policy administration or final resource allow/deny decisions.
|
||||||
- Secret custody, lease issuance, or raw secret-value delivery.
|
- Secret custody, lease issuance, or raw secret-value delivery.
|
||||||
- Infrastructure provisioning, workload deployment, or cluster/platform
|
- Infrastructure provisioning, workload deployment, or cluster/platform
|
||||||
|
|
@ -96,13 +72,6 @@ does it decide and act?** The first is in scope. The second is another layer's.
|
||||||
- The implementation currently evaluates normalized observations and emits
|
- The implementation currently evaluates normalized observations and emits
|
||||||
posture/signal results for one bounded pilot lane; it is not an enforcement
|
posture/signal results for one bounded pilot lane; it is not an enforcement
|
||||||
service and will not become one.
|
service and will not become one.
|
||||||
- `layer.yaml`, `scripts/check_layer_conformance.py` and
|
|
||||||
`tests/test_layer_conformance.py` make the no-Tooling-client claim executable;
|
|
||||||
the companion cites them estate-wide as the reference for a repository with no
|
|
||||||
Tooling contacts at all.
|
|
||||||
- **Every input is still a fixture.** No real emitted event has reached the
|
|
||||||
evaluator, so statute §12's fourth step remains unstaffed. Closing that is
|
|
||||||
`KG-WP-0003`.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,5 +19,4 @@
|
||||||
| task | KG-WP-0002-T04 | done | — | workplans/KG-WP-0002-canonical-immune-contracts-and-posture-pilot.md |
|
| task | KG-WP-0002-T04 | done | — | workplans/KG-WP-0002-canonical-immune-contracts-and-posture-pilot.md |
|
||||||
| intake | KG-IN-0001 | closed | — | intakes/intakes.md |
|
| intake | KG-IN-0001 | closed | — | intakes/intakes.md |
|
||||||
| intake | KG-IN-0002 | open | — | intakes/intakes.md |
|
| intake | KG-IN-0002 | open | — | intakes/intakes.md |
|
||||||
| intake | KG-IN-0003 | open | — | intakes/intakes.md |
|
|
||||||
| decision | KG-DEC-2026-001 | resolved | — | decisions/decisions.md |
|
| decision | KG-DEC-2026-001 | resolved | — | decisions/decisions.md |
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ The following rules apply to every integration below:
|
||||||
4. `kings-guard` must preserve **tenant isolation**: any retained evidence or
|
4. `kings-guard` must preserve **tenant isolation**: any retained evidence or
|
||||||
memory must stay bounded by declared confidentiality rules.
|
memory must stay bounded by declared confidentiality rules.
|
||||||
5. `kings-guard` is a **Staff-layer** repository and is bound by §5 of the
|
5. `kings-guard` is a **Staff-layer** repository and is bound by §5 of the
|
||||||
NetKingdom Security Layer Model v0.6: it never holds a direct client for a
|
NetKingdom Security Layer Model v0.1: it never holds a direct client for a
|
||||||
Tooling-layer system. Evidence from Tooling (OpenBao, key-cape components)
|
Tooling-layer system. Evidence from Tooling (OpenBao, key-cape components)
|
||||||
is consumed **through the owning engine**. Where no engine surface exists,
|
is consumed **through the owning engine**. Where no engine surface exists,
|
||||||
the lane stays fixture-driven and the gap is declared in `INTENT.md`.
|
the lane stays fixture-driven and the gap is declared in `INTENT.md`.
|
||||||
|
|
|
||||||
|
|
@ -1,184 +0,0 @@
|
||||||
---
|
|
||||||
title: "Scope vs Intent review against Security Layer Model v0.7"
|
|
||||||
date: 2026-08-29
|
|
||||||
repo: kings-guard
|
|
||||||
author: kings-guard
|
|
||||||
standard: net-kingdom/canon/standards/security-layer-model_v0.7.md
|
|
||||||
companion: net-kingdom/SECURITY-COMPANION.md
|
|
||||||
status: complete
|
|
||||||
outcome: KG-WP-0003
|
|
||||||
classification: Public
|
|
||||||
---
|
|
||||||
|
|
||||||
# Scope vs Intent review against Security Layer Model v0.7
|
|
||||||
|
|
||||||
The NetKingdom Security Layer Model reached **v0.7, accepted**, with a working
|
|
||||||
companion at `net-kingdom/SECURITY-COMPANION.md`. `INTENT.md` and `SCOPE.md`
|
|
||||||
have been adapted to it. This review compares the adapted documents against the
|
|
||||||
implementation and names what has to change.
|
|
||||||
|
|
||||||
The finding in one line: **the documents are now correct and the code has not
|
|
||||||
caught up.** Every gap below is a place where `INTENT.md` or `SCOPE.md` now
|
|
||||||
claims something `src/kings_guard/` does not do.
|
|
||||||
|
|
||||||
## 1. What the statute settled for this repository
|
|
||||||
|
|
||||||
Four of our review findings were adopted across v0.5–v0.7, and two of them
|
|
||||||
changed what this repository is:
|
|
||||||
|
|
||||||
- **Containment left us entirely (§9.2).** Reduce authority, require step-up,
|
|
||||||
isolate a workload are authority-changing operations, rendered by an Engine
|
|
||||||
and enforced by a PEP. kings-guard proposes containment and never performs it.
|
|
||||||
We had been carrying our inability to contain as our own gap; it was never
|
|
||||||
ours. The actuation surface is unowned estate-wide and held at zero.
|
|
||||||
- **The agent principal is now bound by four rules (§3.4).** v0.6 announced them
|
|
||||||
and never wrote them; we found that and offered to assent sight-unseen, and
|
|
||||||
v0.7 wrote them. They bind this repository harder than any other in the
|
|
||||||
catalog.
|
|
||||||
|
|
||||||
Two obligations arrived with them:
|
|
||||||
|
|
||||||
- **kings-guard drafts the emission-cadence declaration (§17)** — as its only
|
|
||||||
consumer. Ownership stays with Taxonomy; the draft is ours.
|
|
||||||
- **Load-bearing evidence MUST declare an expected cadence (§9.6)**, and for
|
|
||||||
low-volume classes — revocations, denials, containment — rate monitoring
|
|
||||||
cannot work, so the required form is reconciliation or a heartbeat.
|
|
||||||
|
|
||||||
Our catalog entry is now: *adaptive defence and judgment; observation of
|
|
||||||
Staff-reachable sources — identity and secret observation pending; proposes
|
|
||||||
containment, which it does not own.*
|
|
||||||
|
|
||||||
## 2. Where the repository conforms
|
|
||||||
|
|
||||||
Worth stating, because the conformance position is unusual and is the thing most
|
|
||||||
easily lost in a refactor:
|
|
||||||
|
|
||||||
- **No Tooling contact of any shape.** Not a §5.1 diagnostic read, not a §5.2
|
|
||||||
conduit, not a §5.3 declared gap. `dependencies = []` in `pyproject.toml` is
|
|
||||||
load-bearing for this and must stay empty.
|
|
||||||
- **Blocked-clean (§11)**, which the statute rules MUST NOT rank below
|
|
||||||
conforming. Three capabilities sit at zero rather than being taken locally.
|
|
||||||
- **The claim is executable**, not asserted: `layer.yaml`,
|
|
||||||
`scripts/check_layer_conformance.py`, `tests/test_layer_conformance.py`. The
|
|
||||||
companion cites these estate-wide as the reference for a repository with no
|
|
||||||
Tooling contacts at all.
|
|
||||||
- **The asymmetry holds in code.** Every `EffectorRequest` carries an explicit
|
|
||||||
`authority_boundary`; the values in use are `advisory_only` and
|
|
||||||
`metadata_only`. No path widens authority.
|
|
||||||
|
|
||||||
## 3. Gaps — Intent and Scope against the implementation
|
|
||||||
|
|
||||||
### G1. Evidence is not classified load-bearing or attributive — §9.6
|
|
||||||
|
|
||||||
`ImmuneObservation` carries `source_system` and no evidence class. The statute
|
|
||||||
attaches different obligations to each: a load-bearing source MUST declare a
|
|
||||||
cadence, must emit atomically, and its absence is a finding; an attributive
|
|
||||||
source SHOULD. Without the classification the evaluator cannot know which
|
|
||||||
obligation applies to a stream, and `SCOPE.md` now claims we classify.
|
|
||||||
|
|
||||||
*Necessity:* an evidence class on the observation and on the genome's declared
|
|
||||||
sources, with the obligation difference expressed in the contract document.
|
|
||||||
|
|
||||||
### G2. No emission-cadence declaration exists — §17, and it is ours to draft
|
|
||||||
|
|
||||||
`SecurityGenome` has no cadence field. We cannot implement silence-as-signal
|
|
||||||
without a schema for declared cadence, and inventing a local shape is the exact
|
|
||||||
drift §17 exists to prevent. The statute has accepted us as drafter.
|
|
||||||
|
|
||||||
*Necessity:* draft the declaration against `qonto-assistant` as the one real
|
|
||||||
source, covering both forms — expected rate for volume classes, and
|
|
||||||
reconciliation or heartbeat for low-volume load-bearing classes — and hand it to
|
|
||||||
Taxonomy. It belongs alongside the security genome: a source already declares
|
|
||||||
its intent there, and expected emission cadence is a claim of the same kind.
|
|
||||||
|
|
||||||
### G3. Silence is not a signal — §9.6
|
|
||||||
|
|
||||||
`PostureEvaluator.evaluate()` takes one observation and returns one assessment.
|
|
||||||
It is stateless and has no view of a stream. An event that is never emitted is
|
|
||||||
never evaluated: no finding, no signal, no posture change, and the last posture
|
|
||||||
stands. Suppression therefore biases posture **optimistic**, silently. This is
|
|
||||||
the failure the statute names, reproduced one layer up in the consumer.
|
|
||||||
|
|
||||||
*Necessity:* a stream-level evaluation path alongside the per-observation one —
|
|
||||||
cadence comparison for volume classes, reconciliation or heartbeat absence for
|
|
||||||
rare ones — emitting a finding when the stream itself goes quiet.
|
|
||||||
|
|
||||||
### G4. Confidence measures the record, not the stream — §9.6
|
|
||||||
|
|
||||||
`confidence_score` starts at 70 and rises with `policy_version`, `latency_ms`
|
|
||||||
and `resource_scope`. It is a measure of field richness in the record we
|
|
||||||
received. A perfectly-formed observation drawn from a 90%-suppressed stream
|
|
||||||
scores 85. The score cannot express the doubt the statute now requires us to
|
|
||||||
carry.
|
|
||||||
|
|
||||||
*Necessity:* separate completeness from richness. Posture output should carry a
|
|
||||||
stream-completeness dimension that degrades when cadence is unmet or a heartbeat
|
|
||||||
is missing, and `PostureAssessment` should be able to say *this judgment rests
|
|
||||||
on a stream I cannot vouch for.*
|
|
||||||
|
|
||||||
### G5. Nothing prevents immune memory becoming a state plane — §3.4 rule 3
|
|
||||||
|
|
||||||
`ImmuneMemoryEntry` exists with `confidentiality: str = "non-secret"` and no
|
|
||||||
rule about who may depend on it. `INTENT.md` stage 5 (federated memory) is
|
|
||||||
exactly the shape that could drift into a state plane, and the statute forbids
|
|
||||||
it unless catalogued as Tooling.
|
|
||||||
|
|
||||||
*Necessity:* state the constraint in `specs/ImmuneContracts.md` — immune memory
|
|
||||||
informs kings-guard's judgment and may be published as evidence; no engine, PEP
|
|
||||||
or workload may read it as a runtime input — and assert it in a test so the
|
|
||||||
drift is caught rather than argued.
|
|
||||||
|
|
||||||
### G6. Proposals carry no reference to what they were rendered against — §9.2
|
|
||||||
|
|
||||||
`EffectorRequest` has `target_system`, `action`, `authority_boundary`, `reason`,
|
|
||||||
`requires_human_approval`. §9.2 rules that a containment action is a decision
|
|
||||||
record, not a side channel. Our proposals are the input to such a record and
|
|
||||||
carry no request identity, so a proposal cannot be reconstructed against the
|
|
||||||
observation that produced it once it leaves this repository.
|
|
||||||
|
|
||||||
*Necessity:* carry the originating observation and signal identity on the
|
|
||||||
request, so the eventual decision record can name what it was rendered for.
|
|
||||||
|
|
||||||
### G7. The agent-principal rules are documented and unverified — §3.4
|
|
||||||
|
|
||||||
All four are now claimed in `INTENT.md`. None is checked. Rule 1 (no standing
|
|
||||||
credential) is mechanically checkable in this repository the same way the
|
|
||||||
no-Tooling-client claim is; rule 3 follows from G5.
|
|
||||||
|
|
||||||
*Necessity:* extend `scripts/check_layer_conformance.py` to cover what can be
|
|
||||||
checked, and record honestly which rules are assertion rather than test.
|
|
||||||
|
|
||||||
### G8. §12's fourth step is unstaffed — the pilot is fixture-only
|
|
||||||
|
|
||||||
Every input is a hand-built fixture. Ten tests pass and none has met a real
|
|
||||||
event. The statute records this as disclosed, and §19's verdict — the estate can
|
|
||||||
propose and decide but cannot watch or act — names us as the watching half.
|
|
||||||
|
|
||||||
Nothing blocks it: `qonto-assistant` publishes its own genome and audit stream,
|
|
||||||
needs no engine in the path, and its genome has not drifted since it was
|
|
||||||
written. This is the one substantial lane no engine gap touches.
|
|
||||||
|
|
||||||
*Necessity:* ingest real emitted events from `qonto-assistant`, confirm or
|
|
||||||
correct the observation mapping, keep the output advisory.
|
|
||||||
|
|
||||||
### G9. Residual vocabulary — KG-IN-0002
|
|
||||||
|
|
||||||
`specs/NetKingdomImmuneArchitecture.md` predates the model and still uses
|
|
||||||
"control plane" across ~1900 lines. A scoping note heads the file; the body is
|
|
||||||
unadapted. Now also carries the stale stage-3 framing that §9.2 corrected.
|
|
||||||
|
|
||||||
## 4. What is deliberately not being done
|
|
||||||
|
|
||||||
- **No engine gap is being worked around.** Identity and secret observation stay
|
|
||||||
at zero. The blocked-clean position is the point, not an inconvenience.
|
|
||||||
- **No actuation.** G6 makes proposals reconstructable; it does not make them
|
|
||||||
actionable, and nothing here moves toward an effector that acts.
|
|
||||||
- **No Tooling client**, including for live ingest in G8 — `qonto-assistant`
|
|
||||||
is a governed domain assistant publishing its own stream, not a Tooling row.
|
|
||||||
|
|
||||||
## 5. Disposition
|
|
||||||
|
|
||||||
`KG-WP-0003` carries G1–G8. G9 remains `KG-IN-0002`. The ordering is forced:
|
|
||||||
G2 unblocks G3, and G3 unblocks G4; G1 is a prerequisite for all three because
|
|
||||||
the obligation differs by evidence class. G8 is independent and is what makes
|
|
||||||
the rest testable against something real.
|
|
||||||
116
layer.yaml
116
layer.yaml
|
|
@ -1,116 +0,0 @@
|
||||||
# kings-guard — NetKingdom security layer declaration
|
|
||||||
#
|
|
||||||
# Framework: net-kingdom/canon/standards/security-layer-model_v0.7.md
|
|
||||||
# Assent: decisions/decisions.md KG-DEC-2026-001 (kings-guard's own voice, §11)
|
|
||||||
# Validate: python3 scripts/check_layer_conformance.py
|
|
||||||
#
|
|
||||||
# §11 (v0.6) requires a machine-readable declaration: prose cannot distinguish a
|
|
||||||
# declaration from a transcribed review. Form adapted from ops-warden's
|
|
||||||
# reference implementation, offered under §11.
|
|
||||||
#
|
|
||||||
# kings-guard's position is unusual and this file is shaped to state it exactly:
|
|
||||||
# there are NO Tooling contacts. Not a narrow one, not a read-only one. The
|
|
||||||
# capabilities that would need them sit at zero instead. Under §11 that is
|
|
||||||
# BLOCKED-CLEAN, which MUST NOT rank below conforming.
|
|
||||||
|
|
||||||
schema_version: "0.1"
|
|
||||||
framework: netkingdom-security-layer-model
|
|
||||||
standard_version: "0.7"
|
|
||||||
repository: kings-guard
|
|
||||||
layer: staff
|
|
||||||
declared_by: decisions/decisions.md#KG-DEC-2026-001
|
|
||||||
declared_at: "2026-08-29"
|
|
||||||
|
|
||||||
# §4 catalog entry, transcribed so drift between the catalog and this file is
|
|
||||||
# visible. The standard is authoritative for the row; this records what we
|
|
||||||
# understand ourselves to have been assigned.
|
|
||||||
# §3.4 — the four rules binding the agent principal. kings-guard offered to
|
|
||||||
# assent to these sight-unseen before they were written into v0.7.
|
|
||||||
agent_principal_rules:
|
|
||||||
no_standing_credential: true
|
|
||||||
tool_use_shapes: ["5.2-conduit", "engine-api"]
|
|
||||||
memory_is_not_a_state_plane: true
|
|
||||||
reconstructable_as_caller: true
|
|
||||||
|
|
||||||
catalog_entry:
|
|
||||||
owns:
|
|
||||||
- adaptive defence and judgment
|
|
||||||
- observation of Staff-reachable sources
|
|
||||||
pending:
|
|
||||||
- identity observation
|
|
||||||
- secret observation
|
|
||||||
proposes_but_does_not_own:
|
|
||||||
# §9.2 — actuation is an Engine concept held at zero. kings-guard proposes
|
|
||||||
# containment and never performs it. This is not our gap to close.
|
|
||||||
- containment
|
|
||||||
|
|
||||||
# §5 / §11: every direct contact with a Tooling-layer system (a §4 Tooling row),
|
|
||||||
# one entry each. Empty is a claim, and scripts/check_layer_conformance.py is
|
|
||||||
# what makes it checkable rather than asserted.
|
|
||||||
tooling_contacts: []
|
|
||||||
|
|
||||||
# §11 requires non-Tooling clients to be recorded "so the check is total".
|
|
||||||
non_tooling_clients:
|
|
||||||
- id: state-hub-work-records
|
|
||||||
target: state-hub
|
|
||||||
layer: not-catalogued
|
|
||||||
operation: "HTTP to the Custodian State Hub for work records and progress events"
|
|
||||||
write: true
|
|
||||||
note: >-
|
|
||||||
Outside §5 by the v0.5 scope rule: "Tooling-layer system" means a §4
|
|
||||||
Tooling row, and state-hub is not one. Recorded, not policed. Carries no
|
|
||||||
security authority and no secret payload.
|
|
||||||
|
|
||||||
# §11 blocked-clean. These are NOT §5.3 declared gaps: there is no contact to
|
|
||||||
# declare. Fields follow the §5.3 shape so one register can hold both kinds
|
|
||||||
# (§13 now carries the state column that keeps them distinct — raised by
|
|
||||||
# kings-guard against v0.4).
|
|
||||||
unowned_capabilities:
|
|
||||||
|
|
||||||
- id: authentication-assurance-evidence
|
|
||||||
state: unowned-capability
|
|
||||||
capability: >-
|
|
||||||
Token assurance, attestation outcomes and authentication anomalies exposed
|
|
||||||
as an engine surface, for identity-drift posture.
|
|
||||||
intended_owner: "identity layer + audit-core"
|
|
||||||
owner_status: "access-engine declined (v0.6 §13); reproposed, not assented"
|
|
||||||
blocked_on: >-
|
|
||||||
No engine exposes authentication evidence. key-cape is Tooling, so §5
|
|
||||||
forbids the direct route, and the capability stays at zero rather than
|
|
||||||
being taken locally.
|
|
||||||
review: "2026-11-28"
|
|
||||||
consequence: "identity-drift posture lane stays fixture-driven"
|
|
||||||
|
|
||||||
- id: secret-use-evidence
|
|
||||||
state: unowned-capability
|
|
||||||
capability: >-
|
|
||||||
Lease, revocation, mount and rotation metadata exposed as an engine
|
|
||||||
surface, for secret-abuse posture.
|
|
||||||
intended_owner: secrets-engine
|
|
||||||
owner_status: proposed
|
|
||||||
blocked_on: >-
|
|
||||||
No engine exposes secret-use evidence. OpenBao is Tooling; same reasoning
|
|
||||||
as above.
|
|
||||||
review: "2026-11-28"
|
|
||||||
consequence: "secret-abuse posture lane stays fixture-driven"
|
|
||||||
|
|
||||||
- id: actuation-surface
|
|
||||||
state: unowned-capability
|
|
||||||
capability: >-
|
|
||||||
Reduce authority, require step-up, isolate a workload — as a deterministic
|
|
||||||
engine API carrying a decision record.
|
|
||||||
intended_owner: "access-engine + runtime PEPs"
|
|
||||||
owner_status: "proposed; access-engine has not reviewed (FLEX-DEC-2026-002)"
|
|
||||||
blocked_on: >-
|
|
||||||
Ruled in v0.6 §9.2 to be an Engine concept, unowned and held at zero.
|
|
||||||
kings-guard proposes containment and does not own it, so this row is
|
|
||||||
recorded here as a dependency, not as a kings-guard gap to close.
|
|
||||||
review: "2026-11-28"
|
|
||||||
consequence: "no containment is possible anywhere in the estate"
|
|
||||||
|
|
||||||
# §5.1 read-only diagnostic observation of Tooling: none declared, none taken.
|
|
||||||
# §5.2 conduit: none. kings-guard runs no tool under a caller's identity.
|
|
||||||
declared_shapes:
|
|
||||||
"5.1": []
|
|
||||||
"5.2": []
|
|
||||||
"5.3": []
|
|
||||||
|
|
@ -16,10 +16,6 @@ dependencies = []
|
||||||
dev = [
|
dev = [
|
||||||
"pytest>=8.2,<9.0",
|
"pytest>=8.2,<9.0",
|
||||||
"ruff>=0.6,<1.0",
|
"ruff>=0.6,<1.0",
|
||||||
# Reads layer.yaml in scripts/check_layer_conformance.py. Deliberately a
|
|
||||||
# DEV dependency: `dependencies = []` above is load-bearing for the §5
|
|
||||||
# no-Tooling-client claim and must stay empty.
|
|
||||||
"pyyaml>=6.0,<7.0",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
|
|
|
||||||
|
|
@ -1,143 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
"""Check kings-guard against the NetKingdom security layer model (§5, §11).
|
|
||||||
|
|
||||||
Read-only. kings-guard's whole position under the standard rests on one claim:
|
|
||||||
|
|
||||||
it holds no direct client for any Tooling-layer system, and the
|
|
||||||
capabilities that would need one sit at zero instead (§11 blocked-clean)
|
|
||||||
|
|
||||||
That claim has been asserted in prose since KG-DEC-2026-001. §11 (v0.6) requires
|
|
||||||
a machine-readable declaration because prose cannot distinguish a declaration
|
|
||||||
from a transcribed review. This script is what makes the claim checkable: it
|
|
||||||
fails if a Tooling client appears in src/ without a matching layer.yaml entry.
|
|
||||||
|
|
||||||
The failure it exists to catch is a *convenience* — someone reaching for an
|
|
||||||
OpenBao or cluster client during an incident because the engine surface still
|
|
||||||
does not exist (§9.2). That is precisely the "small convenience" §6 warns about,
|
|
||||||
and it would arrive as a one-line import.
|
|
||||||
|
|
||||||
Review dates are reported, never enforced: a date-triggered failure breaks the
|
|
||||||
build on a calendar day with no code change.
|
|
||||||
|
|
||||||
Exit 0 clean, 1 undeclared contact found, 2 declaration malformed.
|
|
||||||
"""
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import ast
|
|
||||||
import sys
|
|
||||||
from datetime import date
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import yaml
|
|
||||||
|
|
||||||
ROOT = Path(__file__).resolve().parents[1]
|
|
||||||
SRC = ROOT / "src" / "kings_guard"
|
|
||||||
DECL = ROOT / "layer.yaml"
|
|
||||||
|
|
||||||
# Import roots that would constitute a direct Tooling-layer client under §4.
|
|
||||||
# Matched against the top-level module of every import in src/.
|
|
||||||
TOOLING_IMPORTS = {
|
|
||||||
"hvac": "OpenBao / Vault client",
|
|
||||||
"bao": "OpenBao client",
|
|
||||||
"kubernetes": "cluster client",
|
|
||||||
"kubernetes_asyncio": "cluster client",
|
|
||||||
"psycopg": "direct database connection",
|
|
||||||
"psycopg2": "direct database connection",
|
|
||||||
"asyncpg": "direct database connection",
|
|
||||||
"sqlalchemy": "direct database connection",
|
|
||||||
"pymysql": "direct database connection",
|
|
||||||
"redis": "direct datastore connection",
|
|
||||||
"ldap3": "direct LDAP client (key-cape tooling)",
|
|
||||||
"python_ldap": "direct LDAP client (key-cape tooling)",
|
|
||||||
"docker": "container runtime client",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def load_declaration() -> dict:
|
|
||||||
if not DECL.exists():
|
|
||||||
print(f"FAIL: no declaration at {DECL.relative_to(ROOT)} (§11)", file=sys.stderr)
|
|
||||||
raise SystemExit(2)
|
|
||||||
try:
|
|
||||||
data = yaml.safe_load(DECL.read_text())
|
|
||||||
except yaml.YAMLError as exc:
|
|
||||||
print(f"FAIL: {DECL.name} is not parseable: {exc}", file=sys.stderr)
|
|
||||||
raise SystemExit(2) from exc
|
|
||||||
for key in ("layer", "repository", "tooling_contacts", "standard_version"):
|
|
||||||
if key not in data:
|
|
||||||
print(f"FAIL: {DECL.name} missing required key '{key}' (§11)", file=sys.stderr)
|
|
||||||
raise SystemExit(2)
|
|
||||||
if data["layer"] != "staff":
|
|
||||||
print(f"FAIL: declared layer is '{data['layer']}', expected 'staff'", file=sys.stderr)
|
|
||||||
raise SystemExit(2)
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
def imported_modules(path: Path) -> set[str]:
|
|
||||||
"""Top-level module name of every import in one file."""
|
|
||||||
try:
|
|
||||||
tree = ast.parse(path.read_text())
|
|
||||||
except SyntaxError:
|
|
||||||
return set()
|
|
||||||
found: set[str] = set()
|
|
||||||
for node in ast.walk(tree):
|
|
||||||
if isinstance(node, ast.Import):
|
|
||||||
found.update(alias.name.split(".")[0] for alias in node.names)
|
|
||||||
elif isinstance(node, ast.ImportFrom):
|
|
||||||
if node.level == 0 and node.module:
|
|
||||||
found.add(node.module.split(".")[0])
|
|
||||||
return found
|
|
||||||
|
|
||||||
|
|
||||||
def scan() -> list[tuple[Path, str, str]]:
|
|
||||||
hits: list[tuple[Path, str, str]] = []
|
|
||||||
for path in sorted(SRC.rglob("*.py")):
|
|
||||||
for module in sorted(imported_modules(path)):
|
|
||||||
if module in TOOLING_IMPORTS:
|
|
||||||
hits.append((path, module, TOOLING_IMPORTS[module]))
|
|
||||||
return hits
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
|
||||||
parser.add_argument("--report", action="store_true", help="print the declaration summary")
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
decl = load_declaration()
|
|
||||||
declared = {c.get("id") for c in decl.get("tooling_contacts") or []}
|
|
||||||
hits = scan()
|
|
||||||
|
|
||||||
undeclared = [h for h in hits if h[1] not in declared]
|
|
||||||
|
|
||||||
if args.report:
|
|
||||||
print(f"kings-guard — layer {decl['layer']}, standard v{decl['standard_version']}")
|
|
||||||
print(f" tooling contacts declared: {len(declared)}")
|
|
||||||
print(f" unowned capabilities (§11 blocked-clean): "
|
|
||||||
f"{len(decl.get('unowned_capabilities') or [])}")
|
|
||||||
today = date.today()
|
|
||||||
for cap in decl.get("unowned_capabilities") or []:
|
|
||||||
review = cap.get("review")
|
|
||||||
stale = ""
|
|
||||||
if review and date.fromisoformat(str(review)) < today:
|
|
||||||
stale = " [REVIEW OVERDUE]"
|
|
||||||
print(f" - {cap['id']}: {cap.get('owner_status', '?')}{stale}")
|
|
||||||
|
|
||||||
if undeclared:
|
|
||||||
print("", file=sys.stderr)
|
|
||||||
print("FAIL: undeclared Tooling-layer client (§11 undeclared violation)", file=sys.stderr)
|
|
||||||
for path, module, what in undeclared:
|
|
||||||
rel = path.relative_to(ROOT)
|
|
||||||
print(f" {rel}: imports '{module}' — {what}", file=sys.stderr)
|
|
||||||
print("", file=sys.stderr)
|
|
||||||
print(" A Staff repository may not hold a direct Tooling client (§5).", file=sys.stderr)
|
|
||||||
print(" Route it through the owning engine, or if none exists, raise an", file=sys.stderr)
|
|
||||||
print(" engine gap — do not declare this to make the check pass.", file=sys.stderr)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
if not args.report:
|
|
||||||
print(f"OK: no direct Tooling client in {SRC.relative_to(ROOT)} (§5, §11)")
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
raise SystemExit(main())
|
|
||||||
|
|
@ -15,7 +15,7 @@ classification: Public
|
||||||
# NetKingdom Immune Architecture
|
# NetKingdom Immune Architecture
|
||||||
|
|
||||||
> **Layer note (2026-08-28).** kings-guard is a **Staff**-layer repository
|
> **Layer note (2026-08-28).** kings-guard is a **Staff**-layer repository
|
||||||
> under the NetKingdom Security Layer Model v0.6 (assented in
|
> under the NetKingdom Security Layer Model v0.1 (assented in
|
||||||
> `decisions/decisions.md` KG-DEC-2026-001). Where this document uses "control
|
> `decisions/decisions.md` KG-DEC-2026-001). Where this document uses "control
|
||||||
> plane", read it as naming an **estate-wide, Engine-layer** arrangement of
|
> plane", read it as naming an **estate-wide, Engine-layer** arrangement of
|
||||||
> deterministic authorities — never as a self-description of `kings-guard`,
|
> deterministic authorities — never as a self-description of `kings-guard`,
|
||||||
|
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
"""kings-guard's layer declaration is checkable, not merely asserted (§11).
|
|
||||||
|
|
||||||
The claim under test is the one our whole position rests on: no direct
|
|
||||||
Tooling-layer client. A test that only ran the checker against a clean tree
|
|
||||||
would prove nothing — it would pass just as happily if the checker were broken.
|
|
||||||
So the negative case is exercised too, on a synthetic tree.
|
|
||||||
"""
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
yaml = pytest.importorskip("yaml")
|
|
||||||
|
|
||||||
ROOT = Path(__file__).resolve().parents[1]
|
|
||||||
SCRIPT = ROOT / "scripts" / "check_layer_conformance.py"
|
|
||||||
DECL = ROOT / "layer.yaml"
|
|
||||||
|
|
||||||
|
|
||||||
def _run(*args: str) -> subprocess.CompletedProcess[str]:
|
|
||||||
return subprocess.run(
|
|
||||||
[sys.executable, str(SCRIPT), *args],
|
|
||||||
capture_output=True,
|
|
||||||
text=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_declaration_exists_and_declares_staff():
|
|
||||||
"""§11: an estate-authored repository declares its layer machine-readably."""
|
|
||||||
assert DECL.exists(), "no layer.yaml — §11 requires a machine-readable declaration"
|
|
||||||
data = yaml.safe_load(DECL.read_text())
|
|
||||||
assert data["repository"] == "kings-guard"
|
|
||||||
assert data["layer"] == "staff"
|
|
||||||
assert data["framework"] == "netkingdom-security-layer-model"
|
|
||||||
|
|
||||||
|
|
||||||
def test_no_tooling_contacts_declared():
|
|
||||||
"""The blocked-clean position: nothing to declare, because nothing is touched."""
|
|
||||||
data = yaml.safe_load(DECL.read_text())
|
|
||||||
assert data["tooling_contacts"] == [], (
|
|
||||||
"a Tooling contact appeared in the declaration; kings-guard's blocked-clean "
|
|
||||||
"position under §11 no longer holds and KG-DEC-2026-001 needs revisiting"
|
|
||||||
)
|
|
||||||
for shape, entries in data["declared_shapes"].items():
|
|
||||||
assert entries == [], f"§5.{shape} shape declared; see comment above"
|
|
||||||
|
|
||||||
|
|
||||||
def test_unowned_capabilities_carry_the_gap_record_fields():
|
|
||||||
"""§5.3 field shape, reused for §13 unowned-capability rows (§17 gap-record)."""
|
|
||||||
data = yaml.safe_load(DECL.read_text())
|
|
||||||
caps = data["unowned_capabilities"]
|
|
||||||
assert caps, "the three known gaps should be declared"
|
|
||||||
for cap in caps:
|
|
||||||
for field in ("capability", "intended_owner", "blocked_on", "review", "state"):
|
|
||||||
assert cap.get(field), f"{cap.get('id')} missing '{field}'"
|
|
||||||
assert cap["state"] == "unowned-capability"
|
|
||||||
|
|
||||||
|
|
||||||
def test_checker_passes_on_the_real_tree():
|
|
||||||
result = _run()
|
|
||||||
assert result.returncode == 0, result.stderr
|
|
||||||
|
|
||||||
|
|
||||||
def test_checker_catches_an_undeclared_tooling_client(tmp_path, monkeypatch):
|
|
||||||
"""The negative case: a direct OpenBao client must fail the check.
|
|
||||||
|
|
||||||
This is the convenience §6 warns about — it would arrive as one import.
|
|
||||||
"""
|
|
||||||
import importlib.util
|
|
||||||
|
|
||||||
spec = importlib.util.spec_from_file_location("check_layer_conformance", SCRIPT)
|
|
||||||
module = importlib.util.module_from_spec(spec)
|
|
||||||
spec.loader.exec_module(module)
|
|
||||||
|
|
||||||
fake_src = tmp_path / "src" / "kings_guard"
|
|
||||||
fake_src.mkdir(parents=True)
|
|
||||||
(fake_src / "effector.py").write_text(
|
|
||||||
"import hvac\n\n\ndef contain(actor):\n hvac.Client().revoke(actor)\n"
|
|
||||||
)
|
|
||||||
monkeypatch.setattr(module, "SRC", fake_src)
|
|
||||||
monkeypatch.setattr(module, "ROOT", tmp_path)
|
|
||||||
|
|
||||||
hits = module.scan()
|
|
||||||
assert hits, "a direct OpenBao client was not detected — the checker is blind"
|
|
||||||
assert hits[0][1] == "hvac"
|
|
||||||
|
|
@ -1,245 +0,0 @@
|
||||||
---
|
|
||||||
id: KG-WP-0003
|
|
||||||
type: workplan
|
|
||||||
title: "Evidence completeness and live observation"
|
|
||||||
domain: infotech
|
|
||||||
repo: kings-guard
|
|
||||||
status: ready
|
|
||||||
owner: kings-guard
|
|
||||||
topic_slug: netkingdom
|
|
||||||
created: "2026-08-29"
|
|
||||||
updated: "2026-08-29"
|
|
||||||
source_review: history/2026-08-29-layer-model-v0.7-scope-intent-review.md
|
|
||||||
standard: net-kingdom/canon/standards/security-layer-model_v0.7.md
|
|
||||||
---
|
|
||||||
|
|
||||||
# Evidence completeness and live observation
|
|
||||||
|
|
||||||
Close the gap between what `INTENT.md` and `SCOPE.md` now claim under Security
|
|
||||||
Layer Model v0.7 and what `src/kings_guard/` actually does. Carries G1–G8 of
|
|
||||||
`history/2026-08-29-layer-model-v0.7-scope-intent-review.md`.
|
|
||||||
|
|
||||||
Two things are being fixed. The repository consumes evidence and treats a quiet
|
|
||||||
stream as a healthy one, which the statute now forbids (§9.6). And statute §12's
|
|
||||||
fourth step — *kings-guard observes it in operation* — is unstaffed, because
|
|
||||||
every input is a fixture.
|
|
||||||
|
|
||||||
## Boundaries this workplan does not cross
|
|
||||||
|
|
||||||
- **No actuation.** kings-guard proposes containment and never performs it
|
|
||||||
(§9.2). T06 makes proposals reconstructable; it does not make them act.
|
|
||||||
- **No Tooling contact.** `dependencies = []` stays empty; `make check-layer`
|
|
||||||
must stay green on every task. `qonto-assistant` publishes its own stream and
|
|
||||||
is not a Tooling row, so T07 needs no engine in the path.
|
|
||||||
- **No engine gap worked around.** Identity and secret observation stay at zero.
|
|
||||||
|
|
||||||
## Dependency order
|
|
||||||
|
|
||||||
```text
|
|
||||||
T01 evidence classification
|
|
||||||
-> T02 emission-cadence declaration (draft, handed to Taxonomy)
|
|
||||||
-> T03 stream-completeness evaluation
|
|
||||||
-> T04 completeness in the posture output
|
|
||||||
T05 immune memory is not a state plane (independent)
|
|
||||||
T06 proposals carry their origin (independent)
|
|
||||||
T07 live observation (independent; makes the rest real)
|
|
||||||
T08 agent-principal conformance checks (after T05)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Task: Classify consumed evidence load-bearing or attributive
|
|
||||||
|
|
||||||
```task
|
|
||||||
id: KG-WP-0003-T01
|
|
||||||
status: todo
|
|
||||||
priority: high
|
|
||||||
```
|
|
||||||
|
|
||||||
Statute §9.6 attaches different obligations to each class, and the repository
|
|
||||||
currently records neither. `ImmuneObservation` carries `source_system` and no
|
|
||||||
class; `SecurityGenome` declares no sources at all.
|
|
||||||
|
|
||||||
Done when:
|
|
||||||
|
|
||||||
- the evidence class is expressible on a declared source and on an observation;
|
|
||||||
- `specs/ImmuneContracts.md` states the obligation difference — a load-bearing
|
|
||||||
source MUST declare a cadence, an attributive source SHOULD — and states that
|
|
||||||
the class is the source's declaration, not kings-guard's inference;
|
|
||||||
- the `qonto-assistant` fixture declares a class for its audit stream, with the
|
|
||||||
reasoning recorded;
|
|
||||||
- tests cover both classes.
|
|
||||||
|
|
||||||
## Task: Draft the emission-cadence declaration and hand it to Taxonomy
|
|
||||||
|
|
||||||
```task
|
|
||||||
id: KG-WP-0003-T02
|
|
||||||
status: todo
|
|
||||||
priority: high
|
|
||||||
```
|
|
||||||
|
|
||||||
Statute §17 requires the artifact and records kings-guard as its drafter, being
|
|
||||||
its only consumer. Ownership stays with Taxonomy. Inventing a local shape is the
|
|
||||||
drift §17 exists to prevent, so this is a draft for handover, not an internal
|
|
||||||
schema.
|
|
||||||
|
|
||||||
Must cover both forms, because one does not substitute for the other:
|
|
||||||
|
|
||||||
- an **expected rate** for volume classes;
|
|
||||||
- **reconciliation or a heartbeat** for low-volume load-bearing classes —
|
|
||||||
revocations, denials, containment actions — where rate monitoring cannot work
|
|
||||||
because a suppressed month is indistinguishable from a quiet one. The required
|
|
||||||
property is a positive claim that can itself go missing.
|
|
||||||
|
|
||||||
Done when:
|
|
||||||
|
|
||||||
- the draft lives in `specs/` and is written against `qonto-assistant` as the
|
|
||||||
one real source;
|
|
||||||
- it explains where the declaration belongs — alongside the security genome, on
|
|
||||||
the argument that expected cadence is a claim of intent like the rest of the
|
|
||||||
genome — and why;
|
|
||||||
- `GH-WP-0002-T04` is referenced as the reference instance for the heartbeat
|
|
||||||
form;
|
|
||||||
- it is sent to gate-house and to the Taxonomy repositories for ownership, and
|
|
||||||
the handover is recorded.
|
|
||||||
|
|
||||||
## Task: Evaluate the stream, not only the observation
|
|
||||||
|
|
||||||
```task
|
|
||||||
id: KG-WP-0003-T03
|
|
||||||
status: todo
|
|
||||||
priority: high
|
|
||||||
```
|
|
||||||
|
|
||||||
`PostureEvaluator.evaluate()` is stateless and per-observation. An event that is
|
|
||||||
never emitted is never evaluated, so the last posture stands and suppression
|
|
||||||
biases posture optimistic. Silence must become a finding in its own right.
|
|
||||||
|
|
||||||
Done when:
|
|
||||||
|
|
||||||
- a stream-level evaluation path exists alongside the per-observation one;
|
|
||||||
- an unmet declared cadence produces a finding;
|
|
||||||
- a missing heartbeat, or a reconciliation divergence between the source's own
|
|
||||||
state transitions and the evidence count per class, produces a finding;
|
|
||||||
- the findings are distinguishable from content findings — the stream observed,
|
|
||||||
not its contents;
|
|
||||||
- no Tooling contact is introduced; the source publishes its own stream.
|
|
||||||
|
|
||||||
## Task: Carry stream completeness in the posture output
|
|
||||||
|
|
||||||
```task
|
|
||||||
id: KG-WP-0003-T04
|
|
||||||
status: todo
|
|
||||||
priority: high
|
|
||||||
```
|
|
||||||
|
|
||||||
`confidence_score` starts at 70 and rises with field richness of the record
|
|
||||||
received. It measures the record, never the stream: a well-formed observation
|
|
||||||
from a 90%-suppressed stream scores 85. The judgment must be able to say *this
|
|
||||||
rests on a stream I cannot vouch for.*
|
|
||||||
|
|
||||||
Done when:
|
|
||||||
|
|
||||||
- completeness is separated from richness in `PostureAssessment`;
|
|
||||||
- an unmet cadence or missing heartbeat degrades the completeness dimension;
|
|
||||||
- the rationale text says so in words, not only in a number;
|
|
||||||
- a posture derived from an incomplete stream can never read as more trustworthy
|
|
||||||
than one derived from a complete one.
|
|
||||||
|
|
||||||
## Task: State and test that immune memory is not a state plane
|
|
||||||
|
|
||||||
```task
|
|
||||||
id: KG-WP-0003-T05
|
|
||||||
status: todo
|
|
||||||
priority: medium
|
|
||||||
```
|
|
||||||
|
|
||||||
Statute §3.4 rule 3: agent memory, tool-call traces and prompt caches MUST NOT
|
|
||||||
become state another layer depends on at runtime unless catalogued as Tooling.
|
|
||||||
`ImmuneMemoryEntry` has no such rule, and `INTENT.md` stage 5 (federated memory)
|
|
||||||
is exactly the shape that could drift into one.
|
|
||||||
|
|
||||||
Done when:
|
|
||||||
|
|
||||||
- `specs/ImmuneContracts.md` states it: immune memory informs kings-guard's own
|
|
||||||
judgment and may be published as evidence; no engine, PEP or workload may read
|
|
||||||
it as a runtime input, and making it one is a §4 Tooling catalog change;
|
|
||||||
- a test asserts the constraint rather than leaving it to prose;
|
|
||||||
- the constraint is reflected in the `Direction of Evolution` stage-5 entry.
|
|
||||||
|
|
||||||
## Task: Make containment proposals reconstructable to their origin
|
|
||||||
|
|
||||||
```task
|
|
||||||
id: KG-WP-0003-T06
|
|
||||||
status: todo
|
|
||||||
priority: medium
|
|
||||||
```
|
|
||||||
|
|
||||||
§9.2 rules that a containment action is a decision record, not a side channel.
|
|
||||||
`EffectorRequest` names a target and an action and carries no reference to what
|
|
||||||
produced it, so once a proposal leaves this repository it cannot be tied back to
|
|
||||||
the observation that caused it.
|
|
||||||
|
|
||||||
Done when:
|
|
||||||
|
|
||||||
- an effector request carries the originating observation and signal identity;
|
|
||||||
- the eventual decision record can name what the proposal was rendered for;
|
|
||||||
- `docs/AdjacentSystemBoundary.md` states the expectation on the receiving side;
|
|
||||||
- the authority boundary remains explicit and no value widens authority.
|
|
||||||
|
|
||||||
## Task: Observe qonto-assistant in operation
|
|
||||||
|
|
||||||
```task
|
|
||||||
id: KG-WP-0003-T07
|
|
||||||
status: todo
|
|
||||||
priority: high
|
|
||||||
```
|
|
||||||
|
|
||||||
Statute §12's fourth step is aspiration until this is done, and §19's verdict
|
|
||||||
names kings-guard as the watching half of *can propose and decide but cannot
|
|
||||||
watch or act*. Every input today is a hand-built fixture; ten tests pass and
|
|
||||||
none has met a real event.
|
|
||||||
|
|
||||||
Nothing blocks it. `qonto-assistant` publishes its own genome record and audit
|
|
||||||
stream, needs no engine in the path, and its genome has not drifted since it was
|
|
||||||
written.
|
|
||||||
|
|
||||||
Done when:
|
|
||||||
|
|
||||||
- real emitted audit events from `qonto-assistant` reach the evaluator;
|
|
||||||
- the observation mapping is confirmed against real events or corrected, and the
|
|
||||||
correction is reported back to `qonto-assistant`;
|
|
||||||
- output stays advisory — posture hints and metadata-only evidence, nothing that
|
|
||||||
actuates;
|
|
||||||
- the fixture is retained as a regression case rather than deleted;
|
|
||||||
- gate-house is told that step four is staffed, with what was found.
|
|
||||||
|
|
||||||
## Task: Check the agent-principal rules that can be checked
|
|
||||||
|
|
||||||
```task
|
|
||||||
id: KG-WP-0003-T08
|
|
||||||
status: todo
|
|
||||||
priority: medium
|
|
||||||
```
|
|
||||||
|
|
||||||
All four §3.4 rules are now claimed in `INTENT.md` and none is verified. The
|
|
||||||
no-Tooling-client claim showed the pattern: a claim in prose becomes a claim in
|
|
||||||
a test, and the test carries the reason.
|
|
||||||
|
|
||||||
Done when:
|
|
||||||
|
|
||||||
- `scripts/check_layer_conformance.py` covers what is mechanically checkable —
|
|
||||||
at minimum rule 1, no standing credential held in the repository or its
|
|
||||||
configuration;
|
|
||||||
- rule 3 is covered by T05;
|
|
||||||
- rules that remain assertion rather than test are recorded as such in
|
|
||||||
`layer.yaml`, honestly, rather than implied to be checked;
|
|
||||||
- `make check-layer` stays green.
|
|
||||||
|
|
||||||
## Success criteria
|
|
||||||
|
|
||||||
1. Every task above is `done`.
|
|
||||||
2. `make test` and `make check-layer` both pass.
|
|
||||||
3. `pyproject.toml` still declares `dependencies = []`.
|
|
||||||
4. `INTENT.md` and `SCOPE.md` claim nothing the implementation does not do.
|
|
||||||
5. The emission-cadence draft has been handed to Taxonomy and the handover
|
|
||||||
recorded.
|
|
||||||
6. gate-house has been told that §12's fourth step is staffed.
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue