policy-nexus/docs/publication-contract.md
tegwick 5a6e78f746 build: review staged source inventory without changing owner dispositions
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a15374-f59f-7a31-86d2-d23b5d2ed181
2026-10-19 13:42:46 +02:00

200 lines
8.2 KiB
Markdown

# Publication contract for source owners
How a governing document gets a permanent address on
`https://policy.coulomb.social`. This note is the owner-facing contract
from PNEX-WP-0002-T01. It is not itself a published policy
document.
`policy-nexus` publishes. It does not author your document and it does
not write back.
## What can be published
| Kind | What it is | Typical source path |
| --- | --- | --- |
| `standards` | Governing standard | `canon/standards/<name>_vN.md` |
| `architecture` | One arc42 document per system | `docs/architecture/<system>_v0.1.md` or `canon/architecture/<system>_v0.1.md` |
| `constitution` | Estate constitution | `canon/constitution/` |
| `adr` | Architecture decision record | `docs/adr/<file>.md` |
| `findings` | A finding explicitly marked public by `risk-nexus` | `findings/RISK-F-NNNN-<slug>.md` |
| `methods` | A public risk judgement instrument | `docs/method/<name>.md` |
Risk findings and methods are published only after `risk-nexus` has made the
disclosure decision and an explicit `publication.json` entry names the file.
Embargoed or restricted findings fail that admission test. Workplans, evidence,
runbooks, review ledgers, rulings, and general docs are out.
An ADR is published only after an explicit `publication.json` entry.
Architecture documents follow the same rule. Discovery
(`source-inventory.config.json`) is not publication.
## Front-matter the builder requires
```yaml
---
id: <globally-unique-id>
title: "Human title"
status: proposed | accepted | adopted | fixed | superseded | withdrawn
owner: <owning-repo-or-canon-owner>
revision: "accepted-1"
last_reviewed: "YYYY-MM-DD"
review_interval: 6m
---
```
| Field | Rule |
| --- | --- |
| `id` | Must equal the `publication.json` `id`. Globally unique. Repo-prefix ADRs (`RMASTER-ADR-0001`, `policy-nexus-adr-0001`). Bare `ADR-001` will collide. |
| `title` | Shown on the page and the site index. |
| `status` | Honesty with the body. If the prose says relocated, the status is `superseded`. |
| `owner` | Who answers for the content. |
| `revision` or `version` | Becomes the immutable revision slug. |
| `last_reviewed` or `updated` | ISO date. Currency starts here. |
| `review_interval` | `Nd`, `Nm`, or `Ny`. Default `6m` if you do not declare one; the publication entry may also set it. |
A document missing any of those fields fails the build. Do not ask this
repo to invent them.
## Addresses
From ADR-0001:
```text
/<kind>/<document>/<version>/
/<kind>/<document>/<version>/revisions/<revision>/
```
- `<kind>` is one of the six kinds above.
- `<document>` is a kebab-case slug, unique on the site. If two systems
would share a short name, prefix with the system slug
(`railiance-repository-prefix`, not `repository-prefix`).
- `<version>` is the document series (`v0.1`, `v1`). A new major version
is a new current address; the old one stays and is marked superseded.
- `<revision>` is the front-matter `revision` (for example `draft-8`,
`accepted-1`). That URL is write-once.
Examples:
```text
/standards/tenancy-posture/v0.1/
/architecture/policy-nexus/v0.1/
/adr/addressing-and-permanence/v1/
/adr/railiance-repository-prefix/v1/
/findings/flex-auth-unauthenticated-check/v1/
/methods/risk-severity/v1/
```
No URL is derived from a checkout path, branch, or build number.
## Architecture documents (arc42)
One markdown file per system, following
`markitect-main/examples/templates/TEMPLATE-ARC42.md`.
- Chapter 9 **lists** that system's ADRs (id, status, pointer). It does
not paste them.
- First-wave complete means chapters **1, 3, 4, 5.1, 9 and 12** are
real. Every other chapter is real or explicitly `N/A` with a reason.
- A stub that can be published early has real chapters **1, 3 and 9**
plus this front-matter.
Validate:
```sh
markitect validate docs/architecture/<system>_v0.1.md \
--schema /path/to/markitect-main/markitect/schemas/arc42-schema-v1.0.md
```
Catalog id: `arc42-v1`.
## Infospace index
The collection index lives at
`the-custodian/canon/architecture/infospace/`. It **references** the
owning-repo documents. It does not copy them. InfoTechCanon owns the
information-space model, not this estate's building-block view.
```sh
markitect infospace check --config \
the-custodian/canon/architecture/infospace/infospace.yaml
```
## How to request publication
1. Put the front-matter on the source document in the owning repo.
2. For an architecture document, meet the stub or first-wave bar above.
3. Open a PR against `policy-nexus` that adds one `publication.json`
entry (and a `repositories` path if the repo is new here).
4. `make check` and `make build` must pass.
Do not glob a tree into `publication.json`. Inventory records every
matching source; publication stays one explicit entry per document.
## First-wave architecture collection
| Publication id | System slug | Owning repo | Source path |
| --- | --- | --- | --- |
| `coulomb-estate-architecture` | `coulomb-estate` | `the-custodian` | `canon/architecture/coulomb-estate_v0.1.md` |
| `railiance-architecture` | `railiance` | `railiance-master` | `docs/architecture/railiance_v0.1.md` |
| `net-kingdom-architecture` | `net-kingdom` | `net-kingdom` | `docs/architecture/net-kingdom_v0.1.md` |
| `state-hub-architecture` | `state-hub` | `state-hub` | `docs/architecture/state-hub_v0.1.md` |
| `policy-nexus-architecture` | `policy-nexus` | `policy-nexus` | `docs/architecture/policy-nexus_v0.1.md` |
## Machine-readable build-mode authorization
The build-mode standard's publication entry declares
`guardrail_path: guardrails/build-mode-change-authorization.json`. The builder
extracts its single machine-checkable YAML block from the canonical Markdown
and emits JSON at that stable path. No second policy copy is maintained. The
release manifest binds the artifact digest to the document's source provenance;
release verification rejects missing, changed or unsupported rule artifacts.
`expires_on` is shown in the document header.
A consumer can evaluate a change record with the stdlib-only checker:
```sh
python3 tools/guardrails.py build/guardrails/build-mode-change-authorization.json change.json --build-mode
```
```json
{
"categories": [],
"diff_ref": "reviewed.patch",
"rollback": "Restore the previous deployment image and source revision",
"abort_owner": "owning-repo",
"receipt_path": "execution-receipt.json"
}
```
Category declarations are mandatory, even when empty. The checker returns
`blue` only with all four nonempty preparation references and confirmed build
mode. Missing references, unknown categories or unconfirmed/expired build mode
return `incomplete`. Red overrides orange when both are declared. Only `blue`
returns exit code zero. Classification does not verify the referenced review or
grant credentials, autopilot, public publication approval or runtime authority.
Public publication goes in the founder's daily red-lane batch; orange identity
acts go in the attended-window checklist. Source generation and local checks can
proceed before publication approval.
## Review staged inventory changes
The inventory's discovery selectors and each row's disposition/reason are
reviewed source. `source_inventory.py refresh` rewrites the inventory and must
be followed by review; its default metadata-pending rows are not public
publication consent.
Before applying such changes, run `make source-inventory-review`. It reads the
Git index, so unstaged selectors or documents do not enter the proposed delta.
The existing refresh function runs only on a temporary copy. The command writes
`build/source-inventory-review.json` (ignored, not a second registry), exits 1
when added/removed source rows require review, and leaves authored files and the
Git index unchanged. Existing dispositions and reasons are preserved; duplicate
rows, symlink inputs and unresolved index conflicts fail closed. Review and edit
the authoritative source explicitly, then stage it and rerun review/source-audit.
No candidate is automatically applied or committed.
The existing scheduled `.forgejo/workflows/publish-image.yaml` already generates
release inventory evidence and publication artifacts from fetched source
revisions. The review command is not another scheduler or release gate; current
source-audit, currency and founder publication requirements remain in force.