--- id: netkingdom-posture-feedback-v0.1 type: standard title: "NetKingdom Posture Feedback v0.1" domain: netkingdom status: proposed version: "0.1" owner: net-kingdom created: "2026-08-23" updated: "2026-08-23" last_reviewed: "2026-08-23" review_interval: 3m scope: self-optimizing-security schema: - canon/schemas/posture-feedback-report_v0.1.schema.json validator: - tools/posture-feedback/posture_feedback.py related: - canon/standards/tenancy-posture_v0.1.md - canon/standards/security-zones_v0.1.md --- # NetKingdom Posture Feedback v0.1 ## 1. Purpose This contract is the first bounded C6 feedback mechanism. It turns explicit posture review dates, evidence freshness, implemented-but-unevidenced controls, and declared gaps into deterministic remediation **proposals**. It does not modify a posture level, policy, declaration, workplan, State Hub, or runtime. Human or separately governed automation decides whether a proposal becomes work. ## 2. Deterministic time Evaluation requires an explicit RFC 3339 `as_of` timestamp. Wall-clock time is never read implicitly. A date-only `review_due` remains current through that calendar date in UTC and becomes overdue on the following UTC date. A non-negative horizon in days identifies items due soon. Changing the horizon changes the report digest and is therefore visible. ## 3. Owner resolution The evaluator routes only from authoritative declaration fields: - posture review, gaps, and implemented controls: `responsible_repo`; - evidence replacement: `evidence_freshness..responsible_repo`; - security-zone review: `zones.responsible_party`. If the relevant field is absent, owner resolution is `unknown`. The evaluator must not infer ownership from the service name, repository path, Git remote, previous work, or another policy subject. ## 4. Finding classes | Finding | Trigger | Severity | | --- | --- | --- | | `posture-review-overdue` | `as_of` is after `tenancy.review_due` | high | | `posture-review-due-soon` | review is within the horizon | medium | | `zone-review-overdue` | `as_of` is after `zones.review_due` | high | | `zone-review-due-soon` | zone review is within the horizon | medium | | `evidence-freshness-unknown` | a current adversarial level has no complete freshness entry | high | | `evidence-expired` | `as_of` is after `valid_until` | high | | `evidence-due-soon` | evidence expires within the horizon | medium | | `implemented-not-evidenced` | an `implemented` level is above `current` | medium | | `declared-gap` | a non-empty `tenancy.gap` entry exists | low | The review horizon does not generate a due-soon finding for an item already overdue or expired. Exact equality with a timestamp is still valid; expiry is strictly `as_of > valid_until`. Current adversarial levels are `E2`, `R4`, and `V2`–`V4`. This vocabulary comes from Tenancy Posture §13. Mechanical evidence is evaluated for expiry only when its declaration explicitly supplies `valid_until`. ## 5. Proposal and safety boundary Every finding receives a stable id derived from its source declaration, service, finding class, control, and due value. It contains the authoritative owner or `unknown`, current evidence state, reason, and recommended action. For declarations under the workspace containing this repository, the source is normalized to `/` so absolute checkout locations do not perturb the identity. This source normalization identifies an input only; it is never an ownership inference. Every report declares: ```yaml automation: mode: proposal-only external_write_permitted: false policy_mutation_permitted: false declaration_mutation_permitted: false ``` Expired or unknown evidence does not silently inherit freshness and does not silently downgrade a level. It makes the uncertainty visible for governed review. Consumers that use the report as an admission gate may fail closed on high findings, but that is a separate owner decision. ## 6. Exit behavior The CLI emits a report conforming to `posture-feedback-report_v0.1.schema.json`. `--fail-on high` exits non-zero when at least one high-severity finding exists; `medium` includes medium and high; `low` includes every finding; `none` reports without a finding-based failure. Invalid declarations always exit non-zero.