Correct repo flavor to product; add SCOPE, AGENTS, classification

fix-consistency surfaced that GOAL.md's `repo_flavor: project` was wrong.
project-repository-flavor_v0.1.md reserves the prj- flavor for bounded
cross-repo coordination efforts and says durable products use INTENT.md and an
ordinary category. informed-decision is a durable product, so the C-35
"prj- flavor forbids shipping both INTENT.md and GOAL.md" contradiction was
self-inflicted rather than a real conflict.

- .repo-classification.yaml: category product, domain infotech.
- GOAL.md: drop repo_flavor/project_status, add a flavor note explaining that
  GOAL.md is retained as the stage statement alongside a stable INTENT.md.
- SCOPE.md: honestly empty — states that nothing is implemented and that
  INFD-WP-0001-T06 rewrites it after the gate-house ruling and the specs.
- AGENTS.md: shared State Hub / session / workplan boilerplate, plus the hard
  rules for this repository — never decide, never own approval state, never
  invent identity, never let awareness enter view_hash, never let an agent
  bind, never fork the schema, fail closed.
- INFD-WP-0001: T01 records both corrections; T06 now rewrites SCOPE.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3W1dQG7GFFM9d94jFx7iR

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1565372@bnt-lap001
Assistant-Session: 16bb2f25-b34c-49ef-8e94-5fec3567a568
This commit is contained in:
tegwick 2026-09-09 12:38:41 +02:00
parent 0f5a6c4f59
commit 309bea463e
6 changed files with 461 additions and 10 deletions

28
.repo-classification.yaml Normal file
View file

@ -0,0 +1,28 @@
repo_classification:
standard: Repo Classification Standard
version: "1.0"
classified_at: "2026-09-09"
classified_by: claude
category: product
domain: infotech
secondary_domains: []
capability_tags:
- governance
- evidence
- identity
- user-interface
- audit
business_stake:
- technology
- legal
- operations
business_mechanics:
- control
- operation
notes: >-
Presentation and binding surface for decisions — the Decision Memo, and the
browser-facing approver UI that approval-engine deliberately does not
contain. Category is product, not project: this is a durable offering with
emerging product requirements (see workplans/INFD-WP-0001 T03), not a
bounded cross-repo coordination effort, so the prj- flavor does not apply.
Not a decision point; access-engine remains the only PDP.

296
AGENTS.md Normal file
View file

@ -0,0 +1,296 @@
# informed-decision — Agent Instructions
## Repo Identity
**Purpose:** Presentation and binding surface for decisions — the Decision Memo, and the browser-facing approver UI that approval-engine does not contain.
**Domain:** infotech
**Repo slug:** informed-decision
**Topic ID:** `a6c6e745-bf54-4465-9340-1534a2be493e`
**Workplan prefix:** `INFD-WP-`
**Category:** product (not `prj-` project flavor — see `.repo-classification.yaml`)
Read in this order: `INTENT.md` (stable purpose) → `GOAL.md` (current stage) →
`SCOPE.md` (what actually exists) → `workplans/`.
`history/20260909-initial-exploration/` is the founding provenance record and is
**never edited**. Governed copies of the schema, canonicalizer and vectors live
in `schemas/` and the package once `INFD-WP-0001-T06` promotes them.
---
## State Hub Integration
The Custodian State Hub tracks work across all domains. Codex uses HTTP REST and
the `statehub` CLI by default. MCP is opt-in because the current Codex MCP bridge
adds severe call latency; the full administrative MCP surface remains available
to clients that need it.
| Context | URL |
|---------|-----|
| Local workstation | `http://127.0.0.1:8000` |
| Remote via tunnel | `http://127.0.0.1:18000` |
| Optional local edge relay | http://127.0.0.1:18080 |
When an operator has enabled the edge relay, set API_BASE to the relay URL.
Queueable writes return an explicit queued receipt if the central hub is
unreachable. Treat that as pending local evidence, then ask the operator to run
statehub outbox status/replay after connectivity returns.
Codex workspace-write sandboxes need network access enabled to reach the host's
loopback listener. Bootstrap this once with `make -C ~/state-hub configure-codex`
and restart Codex. The canonical REST health endpoint is `/state/health`, not
`/health`. If a sandboxed loopback probe fails, retry it with escalated execution
before declaring State Hub unavailable; a managed Codex permission profile may
still enforce isolated networking. Experimental MCP can be enabled explicitly
with `make -C ~/state-hub configure-codex WITH_MCP=1`.
### Orient at session start
```bash
# Offline brief — works without hub connection
cat .custodian-brief.md
# Active workplans for this domain
curl -s "http://127.0.0.1:8000/workplans/?topic_id=cee7bedf-2b48-46ef-8601-006474f2ad7a&status=active" \
| python3 -m json.tool
# Check inbox
curl -s "http://127.0.0.1:8000/messages/?to_agent=informed-decision&unread_only=true" \
| python3 -m json.tool
```
Mark a message read:
```bash
curl -s -X PATCH "http://127.0.0.1:8000/messages/<id>/read" \
-H "Content-Type: application/json" -d '{}'
```
### Log progress (required at session close)
```bash
curl -s -X POST http://127.0.0.1:8000/progress/ \
-H "Content-Type: application/json" \
-d '{
"summary": "what was done",
"event_type": "note",
"author": "codex",
"workplan_id": "<uuid>",
"task_id": "<uuid>"
}'
```
Omit `workplan_id` / `task_id` when not applicable.
### Update task status
```bash
curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
-H "Content-Type: application/json" \
-d '{"status": "progress"}'
# values: wait | todo | progress | done | cancel
```
### Flag a task for human review
```bash
curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
-H "Content-Type: application/json" \
-d '{"needs_human": true, "intervention_note": "reason"}'
```
---
## Session Protocol
**Start:**
1. `cat .custodian-brief.md` — domain goal and open workplans (offline-safe)
2. Check inbox: `GET /messages/?to_agent=informed-decision&unread_only=true`; mark read
3. Scan workplans: `ls workplans/` — note `status: ready`, `active`, or `blocked` files and open tasks
4. Check human-needed tasks: `GET /tasks/?needs_human=true`
**During work:**
- Update task statuses in workplan files as tasks progress
- Record significant decisions via `POST /decisions/`
**Close:**
1. Update workplan file task statuses to reflect progress
2. If finishing a workplan: hand off **residuals** as live work records first
(intake with `origin: residual` + `origin_ref: <WP-id>`, or a next workplan /
decision / engagement). Do not park leftovers only in prose or `SCOPE.md`.
Canon: `the-custodian/canon/standards/work-record-types_v0.1.md` § Residuals.
3. Log: `POST /progress/` with a summary of what changed (name handoff ids)
4. After workplan file changes, run:
```bash
statehub fix-consistency
```
Coding agents should run this directly; ask the operator only if the CLI or
State Hub API is unavailable. This syncs task status from files into the hub DB.
If C-06/C-11 reports that this host is not the identifier registrar, do not
retry, export `STATEHUB_REGISTRAR`, or register records by hand. Commit and
push the file-backed work first, then run the repo-manager fallback once:
```bash
uv run --project ~/repo-manager rmgr registrar-reconcile \
--path . --confirm-primary --push
```
If unavailable, send one deduplicated registrar request to `repo-manager`
naming the repo and canonical ids; UUID absence does not block local work.
---
## Credential and access routing
**Audience:** Codex, Claude Code, Grok, and custodian agents that call **llm-connect**
for inference. Run this check **before** requesting secrets, API keys, SSH access,
login tokens, or database passwords — in any repo, not only `ops-warden`.
The companion (`net-kingdom/SECURITY-COMPANION.md`) says what the rules are;
`ops-warden` stewards the paths through them. **Do not** message `ops-warden`
on State Hub expecting a secret value; the reply is a pointer, not a key.
### Lookup (do this first)
```bash
warden route find "<describe your need>" --json
warden route show <catalog-id> --json
```
Requires the `warden` CLI from `~/ops-warden`.
| Agent runtime | How to orient |
| --- | --- |
| **Codex / Grok** (shell, HTTP State Hub) | `warden route`; inbox `to_agent=informed-decision` is for coordination, not secret vending |
| **Claude Code** (MCP when available) | domain summary for workplans; **still** use `warden route` for credential ownership |
| **llm-connect** | Never put secret retrieval in prompts |
### Quick routing table
| I need… | Owner | ops-warden executes? |
| --- | --- | --- |
| SSH cert (`adm`/`agt`/`atm`) | ops-warden | **Yes**`warden sign` |
| API key, DB password, provider token | OpenBao | No — route only |
| Login / OIDC / MFA | key-cape | No — route only |
| Authorization decision | access-engine (`flex-auth`) | No — route only |
| Approval current-state | **this engine** (not yet implemented) | No |
| SSH tunnel | ops-bridge | No — route only |
### Anti-patterns
- Asking State Hub or `ops-warden` to vend a secret
- Pasting secrets into Git, State Hub, workplans, logs, or chat
- Treating a callable tool as permission (companion §7)
**Canon:** `~/ops-warden/wiki/CredentialRouting.md`
<!-- REPO-AGENTS-EXTENSIONS -->
<!-- Append repo-specific agent instructions below this marker.
The state-hub template sync preserves content after this line. -->
## This repository's layer
**Provisional: PEP-shaped**, statute §6.4 / companion §5. Not ratified — the
catalog row does not exist and `layer.yaml` is not written yet.
`INFD-WP-0001-T02` takes the placement to `gate-house`; the ruling wins over
anything asserted in `INTENT.md` or here.
Hard rules, regardless of how the ruling lands:
- **Never decide.** No endpoint in this repository answers "may this actor do
X". That is `access-engine`, always and only (statute §6). This surface
renders a question and records a human's answer; a disposition is evidence of
an act, not an authorization verdict.
- **Never own approval state.** `approval-engine` is the sole mutator. Do not
cache validity, do not infer consumption from a decision record, and do not
request scope `approval:consume` — the engine refuses it for human principals
and consumption belongs to the PEP that causes the side effect
(`GH-DEC-2026-003`).
- **Never invent identity.** Every principal is authenticated by `key-cape`.
No local credential, no self-issued assurance level.
- **Never let awareness enter the signature.** `view_hash` covers only what the
person committed to. Proposed roles, other-tenant orientation and last-session
summaries are hashed separately and are unsigned unless explicitly promoted
into `awareness_promoted`.
- **Never let an agent bind.** An agent may assemble a memo; only a human
completes a disposition.
- **Never fork the schema.** A field added for approvals must be expressible for
an L0 login banner, or it does not go in the shared object.
- **Fail closed.** Degrading into showing a memo that cannot be bound is
acceptable. Degrading into binding without evidence is not.
- Remote hub: this host reaches State Hub on `http://127.0.0.1:8000` (primary
on railiance01). Do not use `127.0.0.1:18000` — that reverse tunnel is being
retired (`CUST-WP-0067`).
---
## Workplan Convention (ADR-001)
Work items originate as files in this repo — not in the hub. The hub is a
read/cache/index layer that rebuilds from files.
**File location:** `workplans/INFD-WP-NNNN-<slug>.md`
**Archived location:** finished workplans may move to
`workplans/archived/YYMMDD-INFD-WP-NNNN-<slug>.md`. The `YYMMDD` prefix is
the completion/archive date; the frontmatter `id` does not change.
**Ad Hoc Tasks:** small opportunistic fixes discovered during a session use
`workplans/ADHOC-YYYY-MM-DD.md`, workplan id
`INFD-WP-ADHOC-YYYY-MM-DD`, and task ids
`INFD-WP-ADHOC-YYYY-MM-DD-T01`, etc. `APPROVAL-WP` includes its final `-WP`
token. Unqualified historic `ADHOC-*` ids are grandfathered and must not be
copied into new records. Use this only for low-risk work completed directly;
create a normal workplan for anything needing analysis, design, approval,
dependencies, or multiple phases.
**Frontmatter:**
```yaml
---
id: INFD-WP-NNNN
type: workplan
title: "..."
domain: infotech
repo: approval-engine
status: proposed | ready | active | blocked | backlog | finished | archived
owner: codex
topic_slug: ...
created: "YYYY-MM-DD"
updated: "YYYY-MM-DD"
state_hub_workstream_id: "<uuid>" # fix-consistency — do not edit (legacy field name; workplan UUID)
---
```
Use `proposed` for a new draft, `ready` after review against current repo
state, and `finished` after implementation. `stalled` and `needs_review` are
derived health labels, not frontmatter statuses.
**Terminology:** workplan is the fleet term; `workstream` appears only in legacy
API/MCP/frontmatter bridges until `STATE-WP-0069` retires them — see
`the-custodian/canon/standards/workplan-terminology-fleet_v0.1.md`.
**Task block format** (one per `##` section):
```
## Task Title
` ` `task
id: INFD-WP-NNNN-T01
status: wait | todo | progress | done | cancel
priority: high | medium | low
state_hub_task_id: "<uuid>" # written by fix-consistency — do not edit
` ` `
Task description text.
```
Status progression: `todo``progress``done`; use `wait` for waiting/blocked work and `cancel` for stopped work.
**Residuals when finishing:** actionable leftovers become live work records
before `status: finished` — usually an intake (`origin: residual`,
`origin_ref: INFD-WP-NNNN`) or a spawned workplan. Residual is a *role*,
not a kind. Fleet list lives on State Hub, not in `SCOPE.md`.
To create a new workplan:
1. Write the file following the format above
2. Run `statehub fix-consistency` locally.
3. On a non-registrar C-06/C-11 skip, use the repo-manager fallback documented
above exactly once; never set registrar authority directly.

12
GOAL.md
View file

@ -1,11 +1,19 @@
---
repo: informed-decision
repo_flavor: project
project_status: active
category: product
stage: 1
stage_status: active
started: "2026-09-09"
---
> **Flavor note.** This is a durable **product** repository, not a `prj-`
> project repository. Per `project-repository-flavor_v0.1.md`, durable products
> use `INTENT.md` and an ordinary category; the `prj-` flavor is for bounded
> cross-repo coordination efforts and is not used here. `GOAL.md` is retained
> as the *stage* statement: `INTENT.md` is stable and aspirational, this file
> is what the current stage must achieve and is replaced when the stage turns
> over.
# Goal — informed-decision, Stage 1
## Outcome

75
SCOPE.md Normal file
View file

@ -0,0 +1,75 @@
# SCOPE
> Implemented-and-first-cut boundary for agents and contributors. Aspirational
> direction belongs in `INTENT.md`; the current stage belongs in `GOAL.md`;
> current work and gates belong in `workplans/`.
## Status — 2026-09-09
**Nothing is implemented.** This repository currently contains founding
documents, the preserved founding exploration under `history/`, and
`workplans/INFD-WP-0001`. There is no package, no service, no deployment, and
no UI.
This file exists because the Repo Manager requires it and because an honest
empty boundary is more useful than an imagined one. It is rewritten in
`INFD-WP-0001-T06`, once the `gate-house` layer ruling (T02) and the
specifications (T03T05) have fixed the real boundary. **Do not read the
sections below as describing working code.**
## One-liner
informed-decision is the presentation and binding surface for decisions: it
renders a Decision Memo to the human who holds the mandate, records what was
shown, and binds their identity to the act — and owns the browser-facing
approver UI that `approval-engine` deliberately does not contain.
## Core Idea
A decision surface is not a workflow engine and not a decision point. This
repository owns the Decision Memo object, the presentation record, the
canonicalization that produces `view_hash` / `awareness_hash`, the disposition
vocabulary, and the evidence bundle export. It does not evaluate whether an act
is permitted, does not hold approval current-state, and does not archive the
trail.
## In Scope — first cut (Stage 1, not yet built)
- The Decision Memo object and its versions, promoted from
`history/20260909-initial-exploration/` into governed `schemas/`.
- Canonicalization of the binding and awareness documents, with the four
isolation vectors under test.
- The presentation record: what was rendered, to whom, when, in which locale
and UI release.
- Required-highlight acknowledgment as a precondition of binding.
- The disposition vocabulary — `comment`, `discuss`, `return`, `forward`,
`escalate`, `acknowledge`, `accept`, `decline`, `withdraw`, `configure`
and its legality tables.
- The browser-facing OIDC client for human principals: authorization-code +
PKCE against `key-cape`, yielding a token with `aud=approval-engine`,
`principal_type: human`, scope `approval:approve`.
- An L3 approver surface calling `approval-engine`'s approval-entry mutation.
- The evidence bundle as an offline-verifiable export.
## Out of Scope
- Authorization decisions — `access-engine`, always and only (statute §6).
- The approval object, its state machine, validity and consumption —
`approval-engine`. This surface never caches validity, never infers
consumption, never requests `approval:consume`.
- Approval doctrine: which acts require approval, how many approvers, which
separations of duty — `gate-house`.
- Identity and authentication — `key-cape`. Identity is imported, never
invented here.
- The evidence archive — `audit-core`. This repository emits and exports.
- Credentials materialized after a decision — `secrets-engine`.
- Notification transport, ticketing, and general workflow.
- L4/L5, QES, QTSP integration, qualified archival retention.
- The mandate graph. Stage 1 routes to a named approver and does not maintain a
map of who may bind what — a known, accepted limitation recorded in `GOAL.md`.
## Layer placement
**Provisional and unratified.** The working position is PEP-shaped under
statute §6.4 and companion §5. `layer.yaml` does not exist yet and is written
from the `gate-house` ruling in `INFD-WP-0001-T02`, not from this file.

19
WORK-RECORDS.md Normal file
View file

@ -0,0 +1,19 @@
# Work Records — informed-decision
> Generated by `statehub fix-consistency` (CUST-WP-0061-T04, work-record
> stage 3). Do not edit by hand — edit the source file/block listed for
> each record and re-run fix-consistency to refresh this index. Archived
> workplans are omitted; closed decisions/intakes/engagements stay listed
> so recently-resolved work is still visible. [auto]
| Kind | ID | Status | Lane | Source |
| --- | --- | --- | --- | --- |
| workplan | INFD-WP-0001 | proposed | — | workplans/INFD-WP-0001-founding-specs-and-approver-ui-ownership.md |
| task | INFD-WP-0001-T01 | done | — | workplans/INFD-WP-0001-founding-specs-and-approver-ui-ownership.md |
| task | INFD-WP-0001-T02 | todo | — | workplans/INFD-WP-0001-founding-specs-and-approver-ui-ownership.md |
| task | INFD-WP-0001-T03 | todo | — | workplans/INFD-WP-0001-founding-specs-and-approver-ui-ownership.md |
| task | INFD-WP-0001-T04 | todo | — | workplans/INFD-WP-0001-founding-specs-and-approver-ui-ownership.md |
| task | INFD-WP-0001-T05 | todo | — | workplans/INFD-WP-0001-founding-specs-and-approver-ui-ownership.md |
| task | INFD-WP-0001-T06 | todo | — | workplans/INFD-WP-0001-founding-specs-and-approver-ui-ownership.md |
| task | INFD-WP-0001-T07 | todo | — | workplans/INFD-WP-0001-founding-specs-and-approver-ui-ownership.md |
| task | INFD-WP-0001-T08 | todo | — | workplans/INFD-WP-0001-founding-specs-and-approver-ui-ownership.md |

View file

@ -11,6 +11,7 @@ created: "2026-09-09"
updated: "2026-09-09"
origin: founding
origin_ref: history/20260909-initial-exploration/InitialExploration.md
state_hub_workstream_id: "a985a65a-08f7-5a39-8645-b618ea022657"
---
# INFD-WP-0001 — Founding specs and approver-UI ownership
@ -44,6 +45,7 @@ walking skeleton**. Full L3 product build is residual and belongs to
id: INFD-WP-0001-T01
status: done
priority: high
state_hub_task_id: "abe83f6a-18d2-5fe5-bd01-56b6fd0babbe"
```
Write the repository's stable statements of purpose and current stage, derived
@ -56,10 +58,23 @@ invariants and definition of done; `README.md` orients a new reader in under a
minute; `history/20260909-initial-exploration/` is preserved unmodified as the
provenance record.
Completed 2026-09-09: `INTENT.md`, `GOAL.md` and `README.md` written. `SCOPE.md`
is deliberately deferred to T06 — a scope file written before the layer ruling
and the specs would describe an imagined boundary, which is the drift `SCOPE.md`
exists to prevent.
Completed 2026-09-09: `INTENT.md`, `GOAL.md`, `README.md`, `SCOPE.md`,
`AGENTS.md` and `.repo-classification.yaml` written; repo registered in the
State Hub and `INFD-WP-0001` indexed by `fix-consistency`.
Two corrections made during the same task, recorded rather than silently fixed:
- `GOAL.md` first declared `repo_flavor: project`. That is wrong.
`project-repository-flavor_v0.1.md` reserves the `prj-` flavor for bounded
cross-repo coordination efforts and states that durable products use
`INTENT.md` and an ordinary category. This is a durable product;
`.repo-classification.yaml` sets `category: product`. `GOAL.md` is retained
as the *stage* statement, which the flavor standard does not forbid.
- `SCOPE.md` was initially deferred to T06 on the reasoning that a scope file
written before the layer ruling describes an imagined boundary. The Repo
Manager requires it (C-35), and the reasoning was better served by writing an
honestly empty one: the shipped `SCOPE.md` states plainly that nothing is
implemented and that T06 rewrites it. T06 now rewrites rather than creates.
## Settle layer placement and approver-UI ownership with gate-house
@ -67,6 +82,7 @@ exists to prevent.
id: INFD-WP-0001-T02
status: todo
priority: high
state_hub_task_id: "4f94134b-2260-5404-84e0-12f2b08ef565"
```
Take the ownership question to `gate-house` as doctrine rather than asserting a
@ -104,6 +120,7 @@ recorded as a decision, not left implicit. Blocking for T05 and T07.
id: INFD-WP-0001-T03
status: todo
priority: high
state_hub_task_id: "86465a35-1af5-5956-a767-57ad838dffa9"
```
Write `docs/specs/ProductRequirementsDocument.md` for Stage 1: the L3 approval
@ -130,6 +147,7 @@ names what it is deliberately not requiring and why.
id: INFD-WP-0001-T04
status: todo
priority: medium
state_hub_task_id: "00a83db5-fe0e-522a-b885-6f9ef034bc07"
```
Write `docs/specs/UseCaseCatalog.md` covering the full depth spectrum L0L5, with
@ -156,6 +174,7 @@ catalog states for each level which estate repository would consume it.
id: INFD-WP-0001-T05
status: todo
priority: high
state_hub_task_id: "20ea118e-0657-5054-8aa2-b316444f4000"
```
Write `docs/specs/ArchitectureBlueprint.md`. Depends on T02 — the layer ruling
@ -186,6 +205,7 @@ are placeholders.
id: INFD-WP-0001-T06
status: todo
priority: high
state_hub_task_id: "47cb3f7a-e349-5c81-a304-86275e058a85"
```
Promote the exploration artifacts from `history/` into governed, tested
@ -210,13 +230,16 @@ offline, its relationship to `audit-core`'s archive, and — carried over from
that a hash chain proves records were not altered after arrival and cannot prove
a record was never sent.
Write `SCOPE.md` as the last step of this task, once the layer ruling and the
specs have fixed the real boundary.
**Rewrite** `SCOPE.md` as the last step of this task. The version shipped in
T01 is honestly empty — it states that nothing is implemented. Replace it with
the real implemented-and-first-cut boundary once the layer ruling and the specs
have fixed it, and drop the T01 status banner.
Acceptance: schema, canonicalizer and vectors live outside `history/` and are
exercised in CI; the three published expected hashes reproduce byte-for-byte;
`EvidenceModel.md` states the residual it does not close; `SCOPE.md` exists and
describes the implemented-and-first-cut boundary, not the aspiration.
`EvidenceModel.md` states the residual it does not close; `SCOPE.md` describes
the implemented-and-first-cut boundary rather than the aspiration, and no longer
carries the T01 "nothing is implemented" banner.
## Publish the OIDC browser-client contract to key-cape
@ -224,6 +247,7 @@ describes the implemented-and-first-cut boundary, not the aspiration.
id: INFD-WP-0001-T07
status: todo
priority: high
state_hub_task_id: "38a83a76-f152-55bf-8a9a-6132fd6d9642"
```
Own and publish the two strings `approval-engine` could not supply: the human
@ -253,6 +277,7 @@ repository.**
id: INFD-WP-0001-T08
status: todo
priority: medium
state_hub_task_id: "b5c1d329-9580-5672-9640-2930cbbb729a"
```
Prove the specs against reality with the thinnest possible L3 path: sign in via