tenancy-posture draft-9: enforcement stance is not a seventh axis; reefs are canon's defect
Answers zone-engine ZONE-WP-0001-T01. Decision 5.6 — enforcement stance is a sibling standard, not an axis. The six ladders are monotone and the whole current/target/guard machinery depends on it; enforcement stance is not (ADR-0006 is the finding that the top rung is wrong for the SSH lane). And this framework is descriptive: an accurately declared exempt would be conformant and exempt. Membership is declared, stance belongs to the control owner. Zone membership rides tenancy.yaml under a reserved zones: key so the estate keeps one declaration surface; the schema permits it, unconstrained. Decisions 8.4.1/8.4.2 — 'substrate location is not evidence' stated once instead of three repo-local slogans, and the reef/P/V gap recorded as this document's defect rather than zone-engine's scope. NK-WP-0027 takes it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
4a915ce6c7
commit
9e041e3662
3 changed files with 512 additions and 86 deletions
|
|
@ -3,36 +3,93 @@
|
|||
"$id": "https://policy.coulomb.social/schemas/tenancy-posture/v0.1",
|
||||
"title": "NetKingdom tenancy posture declaration v0.1",
|
||||
"type": "object",
|
||||
"required": ["schema_version", "framework"],
|
||||
"required": [
|
||||
"schema_version",
|
||||
"framework"
|
||||
],
|
||||
"properties": {
|
||||
"schema_version": {"const": "0.1"},
|
||||
"framework": {"const": "netkingdom-tenancy-posture"},
|
||||
"service": {"$ref": "#/$defs/serviceName"},
|
||||
"role": {"type": "string", "minLength": 1},
|
||||
"tenancy": {"$ref": "#/$defs/tenancy"},
|
||||
"provider": {"$ref": "#/$defs/provider"},
|
||||
"evidence": {"$ref": "#/$defs/evidence"},
|
||||
"notes": {"$ref": "#/$defs/stringList"},
|
||||
"schema_version": {
|
||||
"const": "0.1"
|
||||
},
|
||||
"framework": {
|
||||
"const": "netkingdom-tenancy-posture"
|
||||
},
|
||||
"service": {
|
||||
"$ref": "#/$defs/serviceName"
|
||||
},
|
||||
"role": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"tenancy": {
|
||||
"$ref": "#/$defs/tenancy"
|
||||
},
|
||||
"provider": {
|
||||
"$ref": "#/$defs/provider"
|
||||
},
|
||||
"zones": {
|
||||
"description": "Reserved for security-zone membership (tenancy-posture_v0.1 Decision 5.6). Its internal shape is defined by the NetKingdom security-zone standard drafted by zone-engine, not by this schema, and is deliberately unconstrained here until that standard lands. Present so a conformant combined declaration is not rejected by this validator."
|
||||
},
|
||||
"evidence": {
|
||||
"$ref": "#/$defs/evidence"
|
||||
},
|
||||
"notes": {
|
||||
"$ref": "#/$defs/stringList"
|
||||
},
|
||||
"services": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {"$ref": "#/$defs/service"}
|
||||
"items": {
|
||||
"$ref": "#/$defs/service"
|
||||
}
|
||||
}
|
||||
},
|
||||
"oneOf": [
|
||||
{
|
||||
"required": ["service", "role", "tenancy"],
|
||||
"not": {"required": ["services"]}
|
||||
"required": [
|
||||
"service",
|
||||
"role",
|
||||
"tenancy"
|
||||
],
|
||||
"not": {
|
||||
"required": [
|
||||
"services"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"required": ["services"],
|
||||
"not": {"anyOf": [
|
||||
{"required": ["service"]},
|
||||
{"required": ["role"]},
|
||||
{"required": ["tenancy"]},
|
||||
{"required": ["provider"]},
|
||||
{"required": ["evidence"]}
|
||||
]}
|
||||
"required": [
|
||||
"services"
|
||||
],
|
||||
"not": {
|
||||
"anyOf": [
|
||||
{
|
||||
"required": [
|
||||
"service"
|
||||
]
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"role"
|
||||
]
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"tenancy"
|
||||
]
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"provider"
|
||||
]
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"evidence"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"additionalProperties": false,
|
||||
|
|
@ -42,24 +99,65 @@
|
|||
"pattern": "^[a-z0-9][a-z0-9._-]*$"
|
||||
},
|
||||
"axisName": {
|
||||
"enum": ["I", "A", "E", "P", "R", "V"]
|
||||
"enum": [
|
||||
"I",
|
||||
"A",
|
||||
"E",
|
||||
"P",
|
||||
"R",
|
||||
"V"
|
||||
]
|
||||
},
|
||||
"level": {
|
||||
"oneOf": [
|
||||
{"type": "integer", "minimum": 0, "maximum": 4},
|
||||
{"const": "n/a"}
|
||||
{
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 4
|
||||
},
|
||||
{
|
||||
"const": "n/a"
|
||||
}
|
||||
]
|
||||
},
|
||||
"axisVector": {
|
||||
"type": "object",
|
||||
"required": ["I", "A", "E", "P", "R", "V"],
|
||||
"required": [
|
||||
"I",
|
||||
"A",
|
||||
"E",
|
||||
"P",
|
||||
"R",
|
||||
"V"
|
||||
],
|
||||
"properties": {
|
||||
"I": {"oneOf": [{"type": "integer", "minimum": 0, "maximum": 3}, {"const": "n/a"}]},
|
||||
"A": {"$ref": "#/$defs/level"},
|
||||
"E": {"$ref": "#/$defs/level"},
|
||||
"P": {"$ref": "#/$defs/level"},
|
||||
"R": {"$ref": "#/$defs/level"},
|
||||
"V": {"$ref": "#/$defs/level"}
|
||||
"I": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 3
|
||||
},
|
||||
{
|
||||
"const": "n/a"
|
||||
}
|
||||
]
|
||||
},
|
||||
"A": {
|
||||
"$ref": "#/$defs/level"
|
||||
},
|
||||
"E": {
|
||||
"$ref": "#/$defs/level"
|
||||
},
|
||||
"P": {
|
||||
"$ref": "#/$defs/level"
|
||||
},
|
||||
"R": {
|
||||
"$ref": "#/$defs/level"
|
||||
},
|
||||
"V": {
|
||||
"$ref": "#/$defs/level"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
|
@ -67,97 +165,214 @@
|
|||
"type": "object",
|
||||
"minProperties": 1,
|
||||
"properties": {
|
||||
"I": {"oneOf": [{"type": "integer", "minimum": 0, "maximum": 3}, {"const": "n/a"}]},
|
||||
"A": {"$ref": "#/$defs/level"},
|
||||
"E": {"$ref": "#/$defs/level"},
|
||||
"P": {"$ref": "#/$defs/level"},
|
||||
"R": {"$ref": "#/$defs/level"},
|
||||
"V": {"$ref": "#/$defs/level"}
|
||||
"I": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 3
|
||||
},
|
||||
{
|
||||
"const": "n/a"
|
||||
}
|
||||
]
|
||||
},
|
||||
"A": {
|
||||
"$ref": "#/$defs/level"
|
||||
},
|
||||
"E": {
|
||||
"$ref": "#/$defs/level"
|
||||
},
|
||||
"P": {
|
||||
"$ref": "#/$defs/level"
|
||||
},
|
||||
"R": {
|
||||
"$ref": "#/$defs/level"
|
||||
},
|
||||
"V": {
|
||||
"$ref": "#/$defs/level"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"stringMap": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"type": "string", "minLength": 1}
|
||||
"additionalProperties": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"stringList": {
|
||||
"type": "array",
|
||||
"items": {"type": "string", "minLength": 1}
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"paths": {
|
||||
"type": "object",
|
||||
"propertyNames": {"$ref": "#/$defs/axisName"},
|
||||
"propertyNames": {
|
||||
"$ref": "#/$defs/axisName"
|
||||
},
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"minProperties": 1,
|
||||
"additionalProperties": {"$ref": "#/$defs/level"}
|
||||
"additionalProperties": {
|
||||
"$ref": "#/$defs/level"
|
||||
}
|
||||
}
|
||||
},
|
||||
"placementException": {
|
||||
"type": "object",
|
||||
"required": ["tenants", "P", "reason"],
|
||||
"required": [
|
||||
"tenants",
|
||||
"P",
|
||||
"reason"
|
||||
],
|
||||
"properties": {
|
||||
"tenants": {"$ref": "#/$defs/stringList"},
|
||||
"P": {"type": "integer", "minimum": 0, "maximum": 4},
|
||||
"reason": {"type": "string", "minLength": 1},
|
||||
"tier_ref": {"type": "string", "minLength": 1}
|
||||
"tenants": {
|
||||
"$ref": "#/$defs/stringList"
|
||||
},
|
||||
"P": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 4
|
||||
},
|
||||
"reason": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"tier_ref": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"tenancy": {
|
||||
"type": "object",
|
||||
"required": ["current", "target", "reviewed", "review_due", "service_class"],
|
||||
"required": [
|
||||
"current",
|
||||
"target",
|
||||
"reviewed",
|
||||
"review_due",
|
||||
"service_class"
|
||||
],
|
||||
"properties": {
|
||||
"current": {"$ref": "#/$defs/axisVector"},
|
||||
"implemented": {"$ref": "#/$defs/partialAxisVector"},
|
||||
"target": {"$ref": "#/$defs/axisVector"},
|
||||
"reviewed": {"type": "string", "format": "date"},
|
||||
"review_due": {"type": "string", "format": "date"},
|
||||
"service_class": {"enum": ["latency-critical", "interactive", "batch"]},
|
||||
"current": {
|
||||
"$ref": "#/$defs/axisVector"
|
||||
},
|
||||
"implemented": {
|
||||
"$ref": "#/$defs/partialAxisVector"
|
||||
},
|
||||
"target": {
|
||||
"$ref": "#/$defs/axisVector"
|
||||
},
|
||||
"reviewed": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"review_due": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"service_class": {
|
||||
"enum": [
|
||||
"latency-critical",
|
||||
"interactive",
|
||||
"batch"
|
||||
]
|
||||
},
|
||||
"permanent": {
|
||||
"type": "array",
|
||||
"uniqueItems": true,
|
||||
"items": {"$ref": "#/$defs/axisName"}
|
||||
"items": {
|
||||
"$ref": "#/$defs/axisName"
|
||||
}
|
||||
},
|
||||
"reason": {
|
||||
"$ref": "#/$defs/stringMap"
|
||||
},
|
||||
"gap": {
|
||||
"$ref": "#/$defs/stringMap"
|
||||
},
|
||||
"paths": {
|
||||
"$ref": "#/$defs/paths"
|
||||
},
|
||||
"reason": {"$ref": "#/$defs/stringMap"},
|
||||
"gap": {"$ref": "#/$defs/stringMap"},
|
||||
"paths": {"$ref": "#/$defs/paths"},
|
||||
"placement_exceptions": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/$defs/placementException"}
|
||||
"items": {
|
||||
"$ref": "#/$defs/placementException"
|
||||
}
|
||||
},
|
||||
"secondary_stores": {"$ref": "#/$defs/stringList"}
|
||||
"secondary_stores": {
|
||||
"$ref": "#/$defs/stringList"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"providerAxis": {
|
||||
"type": "object",
|
||||
"required": ["available", "maximum"],
|
||||
"required": [
|
||||
"available",
|
||||
"maximum"
|
||||
],
|
||||
"properties": {
|
||||
"available": {"$ref": "#/$defs/level"},
|
||||
"maximum": {"$ref": "#/$defs/level"},
|
||||
"conditions": {"$ref": "#/$defs/stringList"},
|
||||
"evidence": {"$ref": "#/$defs/stringList"},
|
||||
"reason": {"type": "string", "minLength": 1}
|
||||
"available": {
|
||||
"$ref": "#/$defs/level"
|
||||
},
|
||||
"maximum": {
|
||||
"$ref": "#/$defs/level"
|
||||
},
|
||||
"conditions": {
|
||||
"$ref": "#/$defs/stringList"
|
||||
},
|
||||
"evidence": {
|
||||
"$ref": "#/$defs/stringList"
|
||||
},
|
||||
"reason": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"provider": {
|
||||
"type": "object",
|
||||
"required": ["axes"],
|
||||
"required": [
|
||||
"axes"
|
||||
],
|
||||
"properties": {
|
||||
"capability": {"type": "string", "minLength": 1},
|
||||
"profile": {"type": "string", "minLength": 1},
|
||||
"capability": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"profile": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"axes": {
|
||||
"type": "object",
|
||||
"minProperties": 1,
|
||||
"properties": {
|
||||
"I": {"$ref": "#/$defs/providerAxis"},
|
||||
"A": {"$ref": "#/$defs/providerAxis"},
|
||||
"E": {"$ref": "#/$defs/providerAxis"},
|
||||
"P": {"$ref": "#/$defs/providerAxis"},
|
||||
"R": {"$ref": "#/$defs/providerAxis"},
|
||||
"V": {"$ref": "#/$defs/providerAxis"}
|
||||
"I": {
|
||||
"$ref": "#/$defs/providerAxis"
|
||||
},
|
||||
"A": {
|
||||
"$ref": "#/$defs/providerAxis"
|
||||
},
|
||||
"E": {
|
||||
"$ref": "#/$defs/providerAxis"
|
||||
},
|
||||
"P": {
|
||||
"$ref": "#/$defs/providerAxis"
|
||||
},
|
||||
"R": {
|
||||
"$ref": "#/$defs/providerAxis"
|
||||
},
|
||||
"V": {
|
||||
"$ref": "#/$defs/providerAxis"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
|
|
@ -168,21 +383,43 @@
|
|||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{"type": "string", "minLength": 1},
|
||||
{"$ref": "#/$defs/stringList"}
|
||||
{
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/stringList"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"service": {
|
||||
"type": "object",
|
||||
"required": ["service", "role", "tenancy"],
|
||||
"required": [
|
||||
"service",
|
||||
"role",
|
||||
"tenancy"
|
||||
],
|
||||
"properties": {
|
||||
"service": {"$ref": "#/$defs/serviceName"},
|
||||
"role": {"type": "string", "minLength": 1},
|
||||
"tenancy": {"$ref": "#/$defs/tenancy"},
|
||||
"provider": {"$ref": "#/$defs/provider"},
|
||||
"evidence": {"$ref": "#/$defs/evidence"},
|
||||
"notes": {"$ref": "#/$defs/stringList"}
|
||||
"service": {
|
||||
"$ref": "#/$defs/serviceName"
|
||||
},
|
||||
"role": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"tenancy": {
|
||||
"$ref": "#/$defs/tenancy"
|
||||
},
|
||||
"provider": {
|
||||
"$ref": "#/$defs/provider"
|
||||
},
|
||||
"evidence": {
|
||||
"$ref": "#/$defs/evidence"
|
||||
},
|
||||
"notes": {
|
||||
"$ref": "#/$defs/stringList"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ domain: netkingdom
|
|||
status: proposed
|
||||
version: "0.1"
|
||||
created: "2026-08-17"
|
||||
updated: "2026-08-17"
|
||||
updated: "2026-08-19"
|
||||
scope: multi-tenancy-security-framework
|
||||
revision: "draft-8"
|
||||
revision: "draft-9"
|
||||
owner: net-kingdom
|
||||
last_reviewed: "2026-08-17"
|
||||
last_reviewed: "2026-08-19"
|
||||
review_interval: 6m
|
||||
declaration_schema: canon/schemas/tenancy-posture_v0.1.schema.json
|
||||
adr:
|
||||
|
|
@ -28,7 +28,7 @@ related:
|
|||
|
||||
## Status
|
||||
|
||||
**Proposed, draft-8; ratification-ready.** Relocated from
|
||||
**Proposed, draft-9; ratification-ready.** Relocated from
|
||||
`the-custodian/canon/architecture` on
|
||||
2026-08-17: multi-tenancy is part of the IT-security framework NetKingdom
|
||||
provides, so this framework belongs in NetKingdom canon beside the IAM Profile
|
||||
|
|
@ -59,6 +59,12 @@ and the tenant-engine boundary contract, not in the work-factory canon.
|
|||
customer language. It also corrects the distinction between an implemented
|
||||
control and an evidenced current level.
|
||||
|
||||
- **draft-9** answers `zone-engine`'s `ZONE-WP-0001-T01`. It rules that
|
||||
enforcement stance is **not** a seventh axis (Decision 5.6) while reserving
|
||||
`zones:` in `tenancy.yaml` so the estate keeps one declaration surface, and it
|
||||
records the reef/`P`/`V` reconciliation as an open defect of this document
|
||||
rather than of the repo that noticed it (Decision 8.4).
|
||||
|
||||
**Reviewed by all six. The score:** six repos found three live defects in their
|
||||
own code by reading the ladders — `tenant-engine`'s unfiltered
|
||||
event accessor, `audit-core`'s unfiltered read path, `flex-auth`'s
|
||||
|
|
@ -583,6 +589,67 @@ it.
|
|||
A provider's own `P` is `n/a`, not a number. `apps-pg` *provides* `P1`; it is
|
||||
not *at* `P1`, and writing `P: 1` there would later read as an isolation claim.
|
||||
|
||||
**Decision 5.6 — enforcement stance is not a seventh axis, and `zones:` is
|
||||
reserved in this file.** `zone-engine` asked whether *enforcement stance* —
|
||||
whether a given control is enforced, advisory or exempt in a given band of the
|
||||
estate — should fold in here rather than become a second standard. It should
|
||||
not, for a reason that is structural rather than territorial.
|
||||
|
||||
**Every one of the six ladders is monotone: higher is stronger, and higher is
|
||||
what a service wants.** That assumption is load-bearing throughout. §12's
|
||||
*improve* step moves a service up. §12's *guard* checks that none is below what
|
||||
it declared. §6 has to make a special allowance for a level that is
|
||||
*permanently* low by design, and §12's guard is told not to nag it — the
|
||||
allowance exists because low-is-normal is the exception here.
|
||||
|
||||
Enforcement stance is not monotone. The correct stance for a bootstrap lane is
|
||||
deliberately and permanently *below* the top rung, and the top rung is
|
||||
sometimes the wrong answer outright: `ops-warden`'s `ADR-0006` is exactly the
|
||||
finding that a fail-closed authorization gate on the SSH lane the tunnels
|
||||
depend on is not a stronger position, it is an outage. A ladder whose top is
|
||||
sometimes wrong is an enumeration, not a ladder, and putting one inside this
|
||||
vector would break `current`/`target`/`gap`, the guard, and §6 for the six that
|
||||
are.
|
||||
|
||||
§8.3 already refused an axis for a weaker reason than this one — that a QoS
|
||||
level would be an unenforced claim. Enforcement stance *is* enforced. It fails
|
||||
the other half of the same test.
|
||||
|
||||
There is a second, sharper reason. §6's conformance rule is *accuracy, not
|
||||
altitude*, and it works because this framework is **descriptive**: it never
|
||||
blocks anything by itself. Prescription enters only through §11 and Decision
|
||||
8.2, where a **requirer** — never the declaring repo — sets a minimum level and
|
||||
the two are machine-reconciled. Enforcement stance is prescriptive by nature.
|
||||
Fold it in as an axis and an accurately declared `exempt` becomes conformant
|
||||
*and* exempt: a conformance rule that hands out the exemption it exists to
|
||||
audit. The declarer must not be the party that sets the stance.
|
||||
|
||||
So the split is the one `flex-auth` already argued to `zone-engine`:
|
||||
**membership is data and is declared; stance is a rule and belongs to the
|
||||
control's owner.** Membership is posture-shaped and behaves like a level.
|
||||
Stance behaves like a tier minimum under Decision 8.2 — asserted elsewhere,
|
||||
joined by machine.
|
||||
|
||||
**What canon rules, and it is binding on the sibling standard:**
|
||||
|
||||
- A security-zone standard is a **separate document** in this family, drafted
|
||||
by `zone-engine` and published in NetKingdom canon beside this one and the
|
||||
`*-engine` boundary contracts. It carries over §6 verbatim and §13's evidence
|
||||
discipline.
|
||||
- **Zone membership is declared in `tenancy.yaml`**, under a reserved top-level
|
||||
`zones:` key, sibling to `tenancy:` and `provider:` — *not* inside
|
||||
`tenancy.current`. Decision 5.4 makes this file the repo's single posture
|
||||
declaration surface, and a second root file would recreate the divergence
|
||||
§5.4 was written to end. One file, one review cadence, one validator; two
|
||||
standards, because the two have different owners and different conformance
|
||||
semantics.
|
||||
- `organization_posture` (`ops-warden` WP-0029) does **not** belong in this
|
||||
file at all, under either key. It is a fleet-wide, time-varying scalar
|
||||
describing the estate, not a property of the declaring service, and a
|
||||
per-repo copy of a global would go stale in as many places as there are
|
||||
repos. It is an *input* to stance selection and should be read by the zone
|
||||
model, not absorbed into a declaration.
|
||||
|
||||
Worked examples after applying the evidence rule and minimum-across-paths rule
|
||||
consistently:
|
||||
|
||||
|
|
@ -752,6 +819,46 @@ things, none of which is priority:
|
|||
classes are co-resident. An unenforceable risk that nobody can see is strictly
|
||||
worse than one that is stated.
|
||||
|
||||
### 8.4 Substrate location is not evidence — and reefs are not reconciled with `P` or `V`
|
||||
|
||||
**Decision 8.4.1 — location is not evidence of any property of the workload on
|
||||
it.** Three repos have now written this rule locally in three vocabularies:
|
||||
`railiance-master`'s *topology is not readiness*, `zone-engine`'s *placement is
|
||||
not posture*, and §3.1 here, which requires every use of "isolation" to name
|
||||
its axis. They are one rule. Stated once: **the substrate a workload sits on is
|
||||
never, by itself, evidence for a level on any ladder in this framework.**
|
||||
Binding to a reef, being on a dedicated instance, or naming a rail proves
|
||||
placement and nothing else. Other repos should cite this rather than restate
|
||||
it.
|
||||
|
||||
**Decision 8.4.2 — the reef taxonomy and this framework are not reconciled, and
|
||||
that is this document's defect.** `zone-engine` asked whether canon should
|
||||
reconcile reefs with the posture axes, on the assumption that this was a scope
|
||||
question for the zone model. It is not: the unreconciled pair is not
|
||||
zone ↔ reef, it is **reef ↔ `P` and `V`**, and it belongs to canon.
|
||||
|
||||
`repo-manager` owns substrate placement (`reef-railiance`, `reef-storage`) with
|
||||
an explicit residual-risk acceptance attached to a binding. §7 and §8 of this
|
||||
document presuppose that placement is fully described by the `P` ladder. It is
|
||||
not. `P` grades **tenant data isolation within a datastore**; a reef is a named
|
||||
**compute substrate carrying an accepted residual risk**. The `P` ladder has no
|
||||
rung meaning "single node, shared control plane, risk accepted", and inventing
|
||||
one would be the fabrication §6 prohibits.
|
||||
|
||||
The live consequence is on `V`, not `P`. §4.6 already warns that "a dedicated
|
||||
cluster can still be a single instance on a single node", and Decision 4.6.1
|
||||
makes `V` the minimum across the synchronous path. `reef-railiance` is
|
||||
single-node with a shared control plane, which **caps `V` for every workload
|
||||
bound to it** regardless of that workload's own replica count — which Decision
|
||||
4.6.1 already says is not evidence. Nothing today joins the reef's facts to a
|
||||
consumer's `V` declaration, so a rapp can declare `V2` accurately by its own
|
||||
reading and be wrong by this document's own composition rule.
|
||||
|
||||
This is `railiance-platform`'s provider-declaration finding (Decision 5.5)
|
||||
generalised one layer down. A reef is a **provider** and has nowhere to state
|
||||
what it makes reachable. Tracked as `NK-WP-0027`; the fix is canon's, and the
|
||||
zone model is not blocked on it.
|
||||
|
||||
The known escalation short of P2 is gateway-level prioritisation — ordering
|
||||
submissions in a connection proxy by the requesting tenant's current
|
||||
consumption. It is real, it is where the industry puts this when it must, and
|
||||
|
|
|
|||
82
workplans/NK-WP-0027-reef-placement-reconciliation.md
Normal file
82
workplans/NK-WP-0027-reef-placement-reconciliation.md
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
---
|
||||
id: NK-WP-0027
|
||||
type: workplan
|
||||
title: "Reconcile the reef taxonomy with the P and V ladders"
|
||||
domain: infotech
|
||||
repo: net-kingdom
|
||||
status: proposed
|
||||
owner: net-kingdom
|
||||
topic_slug: netkingdom
|
||||
planning_priority: P2
|
||||
created: "2026-08-19"
|
||||
updated: "2026-08-19"
|
||||
---
|
||||
|
||||
# NK-WP-0027 — Reefs, placement, and what a substrate makes reachable
|
||||
|
||||
Raised by answering `zone-engine`'s `ZONE-WP-0001-T01`. `zone-engine` asked
|
||||
whether canon should reconcile security zones with reefs, expecting the answer
|
||||
to enlarge *its* scope. It does not: a zone is genuinely not a reef, and
|
||||
`zone-engine` should keep *placement is not posture* and move on. The
|
||||
unreconciled pair is **reef ↔ `P` and `V` in `tenancy-posture_v0.1`**, and it
|
||||
is this repo's defect, recorded as Decision 8.4.2 in draft-9.
|
||||
|
||||
`repo-manager` owns substrate placement (`reef-railiance`, `reef-storage`) with
|
||||
residual-risk acceptance attached to a binding. §7 and §8 of the standard
|
||||
presuppose placement is fully described by the `P` ladder. `P` grades tenant
|
||||
data isolation *within a datastore*; a reef is a named compute substrate
|
||||
carrying an accepted residual risk. There is no rung for "single node, shared
|
||||
control plane, risk accepted", and there should not be one — inventing it is
|
||||
the fabrication §6 prohibits.
|
||||
|
||||
The live consequence is on `V`. Decision 4.6.1 makes `V` the minimum across the
|
||||
synchronous path and says a replica count is not evidence. `reef-railiance` is
|
||||
single-node with a shared control plane and therefore caps `V` for everything
|
||||
bound to it. Nothing joins those facts today, so a rapp can declare `V2`
|
||||
accurately by its own reading and be wrong by the standard's own composition
|
||||
rule. This is Decision 5.5's provider-declaration finding one layer down: a
|
||||
reef is a provider with nowhere to say what it makes reachable.
|
||||
|
||||
```task
|
||||
id: NK-WP-0027-T01
|
||||
status: todo
|
||||
priority: medium
|
||||
```
|
||||
|
||||
**Establish the boundary between a reef and the `P` ladder in canon text.** Say
|
||||
what each answers, why a reef is not a `P` level, and which of `P`'s couplings
|
||||
(§3.2) a reef binding does and does not satisfy. Do not extend the `P` ladder.
|
||||
|
||||
```task
|
||||
id: NK-WP-0027-T02
|
||||
status: todo
|
||||
priority: medium
|
||||
```
|
||||
|
||||
**Extend Decision 5.5's provider declaration to substrate providers, and agree
|
||||
it with `repo-manager`.** A reef should state, per axis it bounds, the maximum
|
||||
level it makes reachable and what a consumer must do to reach it — the same
|
||||
sentence `apps-pg` now owes its consumers. `reef-railiance`'s first line is
|
||||
almost certainly a `V` ceiling. This is a proposal to `repo-manager`, not a
|
||||
canon fiat: it owns the reef vocabulary and the acceptance record.
|
||||
|
||||
```task
|
||||
id: NK-WP-0027-T03
|
||||
status: wait
|
||||
priority: low
|
||||
```
|
||||
|
||||
**Join reef ceilings to consumer `V` declarations mechanically.** Waits on T02.
|
||||
Decision 8.2's pattern applies — the requirer asserts, the declarer declares,
|
||||
a machine reconciles. Until then a consumer bound to a reef declares `V` with
|
||||
the reef named as a synchronous dependency, which is already required by
|
||||
Decision 4.6.1 and is not being done.
|
||||
|
||||
## Related
|
||||
|
||||
- `canon/standards/tenancy-posture_v0.1.md` Decisions 4.6.1, 5.5, 8.4.1, 8.4.2
|
||||
- `repo-manager/docs/RailianceAppDeploymentGuide.md` — reefs, `bound_reefs`
|
||||
- `railiance-master/docs/adr/ADR-0006-reef-production-admission.md` — topology
|
||||
is not readiness
|
||||
- `zone-engine/workplans/ZONE-WP-0001-security-zone-model.md` — where the
|
||||
question came from, and why it is not answered there
|
||||
Loading…
Add table
Add a link
Reference in a new issue