Specify prj- drivers and cross-owner wait mode.
Some checks failed
CI Smoke / host-smoke (push) Waiting to run
CI Smoke / container-smoke (push) Waiting to run
check / test (push) Has been cancelled

COORDINATION-WP-0005: map project-repository workplans onto
CoordinationCase, refuse residual as a driver, and document the wait
mode without enabling live worker injection.

Assistant: grok
Assistant-Session: 01a09dc1-b21e-77e1-919e-fcad2f82b267
This commit is contained in:
tegwick 2026-09-14 16:46:45 +02:00
parent b69839b5ef
commit d2802fc55d
9 changed files with 582 additions and 6 deletions

View file

@ -14,6 +14,8 @@
* `ProductRequirementsDocument.md`
* `RuntimeArchitectureAndAdapterSubsystem.md`
* `AdapterInterfaceSpecification.md`
* `coordination-model-v0.2.md` — project-repository drivers (COORDINATION-WP-0005)
* `cross-owner-wait-mode-v0.1.md`
## 2. Purpose

View file

@ -0,0 +1,123 @@
# coordination-model-v0.2.md
## 1. Document Status
**Document:** coordination-model-v0.2.md
**Project:** coordination-engine
**Version:** 0.2
**Status:** Addendum to v0.1 (COORDINATION-WP-0005)
**Scope:** Project-repository workplans as coordination drivers
**Extends:** `spec/coordination-model-v0.1.md`
**Related:** `spec/cross-owner-wait-mode-v0.1.md`,
`spec/worker-coordination-service-v0.1.md`,
`the-custodian/canon/architecture/adr-005-cross-repo-workplans-project-repos.md`,
`the-custodian/canon/standards/project-repository-flavor_v0.1.md`
v0.1 remains the ontology. This addendum maps **estate work records** onto
that ontology. It does not replace actors, goals, commitments, or observation
loops.
## 2. Purpose
Cross-repository work in this estate is supposed to live in a **project
repository** (`prj-<slug>`, `repo_flavor: project`, ADR-005). Agents were
instead minting stranded `wait` notes on product workplans. The engine must
treat a `prj-` workplan as the **driver** of a `CoordinationCase`, and
product-repo workplans as **implementers**.
## 3. Out of scope
- The engine **does not author workplans**. Files remain source of truth
(ADR-001). State Hub remains the work-record read model.
- The engine **does not replace State Hub**, Fabric, or product
implementation in participating repos.
- The engine **does not vend credentials**. `ops-warden` issues SSH
certificates only.
- This addendum **does not enable live worker injection**. Wake/lease
remains the v0.1 worker-coordination service, off until an operator
starts it.
## 4. Driver and implementer
| Role | Binding | Authority |
| --- | --- | --- |
| **Driver** | Workplan whose repo is `prj-*` / `category: project` / `repo_flavor: project` | Sequences the effort, names participating repos, holds `depends_on` and related child ids. Does not implement production code. |
| **Implementer** | Workplan in a participating product/tooling repo | Owns code, tests, deployables, and local tasks. |
Participant roles on the case (v0.1 `Participant.roles[]`):
- `driver` — the project-repository actor (system: State Hub record +
project repo)
- `implementer` — each participating product repo (system)
- `observer` — State Hub / Fabric (read-only)
- `agent` — a worker only when the v0.1 service has selected that gita
repo as a wake target
A workplan with `flavor: residual` is **not** a driver and is **not**
actionable demand unless promoted (STATE-WP-0092). Unspecified flavor is
relevant.
## 5. Mapping onto v0.1
```text
prj- workplan → CoordinationCase
goal ← GOAL.md outcome + workplan title
driver ← the prj- workplan (commitment: sequence the effort)
implementers ← child workplans in other repos (related / depends_on)
commitments ← depends_on edges (kind: response | completion)
observations ← State Hub task/workplan status, receipts
```
`depends_on` is a **commitment**, not prose. The obligor is the
implementer (or upstream driver) named by the target id. The beneficiary
is the waiting plan. Satisfaction is the target reaching a terminal
satisfactory status (`done` / `finished` / `archived`), matching the
v0.1 worker-coordination dependency rule.
`related:` without `depends_on` is context, not a commitment.
## 6. Case identity
```yaml
CoordinationCase:
id: "case:prj:{repo_slug}:{workplan_id}" # derived, not authored
scenario_type: project_driver
driver_workplan_id: string # hub UUID or canonical id
driver_repo: prj-*
implementers:
- repo: string
workplan_id: string?
role: implementer
commitments: # from depends_on
- kind: completion
obligor_workplan_id: string
beneficiary_workplan_id: string
flavor: planning | implementation | ... # driver's flavor
```
The engine derives this object from hub JSON. It does not POST a
workplan.
## 7. Worked example — `prj-helixforge-factory` / `HFACT-WP-0001`
Repo `prj-helixforge-factory` is `repo_flavor: project`. Workplan
`HFACT-WP-0001` (“Establish the internal HelixForge software factory on
Railiance”) is the driver. It states that it owns integration acceptance
and handoff and **neither replaces nor copies child implementation
plans**.
Implementers named in `related:` include `GLAS-WP-0012`, `SAND-WP-0015`,
`REINAH-WP-0003`, `ACTIVITY-WP-0032`, `KEY-WP-0013`, `INFD-WP-0001`,
`APPROVAL-WP-0002`, `SECRETS-WP-0009`, `AUDIT-WP-0009`, `RPF-WP-0038`.
Those remain implementer workplans in their owning repos.
A wait on `KEY-WP-0013` from the factory driver is a **commitment** on
the key-cape implementer, not a stranded `wait` on the driver with no
observer. Cross-owner handling is `spec/cross-owner-wait-mode-v0.1.md`.
## 8. Compatibility
v0.1 cases that are not `scenario_type: project_driver` are unchanged.
The worker-coordination service continues to poll ready/active
implementer tasks. This addendum tells it (and agents) which workplan is
the driver when one exists.

View file

@ -0,0 +1,109 @@
# Cross-owner wait handling mode v0.1
Status: specified (COORDINATION-WP-0005-T02). Not a live wake enablement.
Owner: coordination-engine.
Reconciles with: `spec/worker-coordination-service-v0.1.md` (do not fork
leases, safety, TAMQ, or receipts).
Ontology: `spec/coordination-model-v0.2.md`.
## Problem
Repo A sets a task `wait` because repo Bs owner has not returned. Nobody
observes B. The wait becomes a stranded inbox. That pattern is the top
theme holding the open-workplan count up.
## Mode (replace “set wait and hope”)
### Entry
Any of:
1. A task is `wait` / `needs_human` and names another repo, owner, or
workplan id.
2. A workplan is `blocked` on a `depends_on` target whose `repo` is not
this repo.
3. A `prj-` driver lists both repos (preferred). If no driver exists,
still open a **case object** from the waiting plan — do not author a
new workplan.
Do **not** enter this mode for `flavor: residual` unless the flavor has
been promoted.
### Observe
Read the foreign owners record from State Hub (workplan, tasks,
`depends_on`, flavor, repo classification). Do not copy their task list
into this repo. Do not PATCH their tasks.
### Attach
Open or attach a `CoordinationCase` (`scenario_type: project_driver`
when a `prj-` workplan exists, otherwise `scenario_type: cross_owner_wait`).
The waiting plan is the beneficiary. The foreign plan is the obligor
commitment.
### Act (only if the v0.1 service is already running)
Lease/wakeup **only** selected gita-registered worker targets for the
implementer that is actually unblocked. Safety, sensitive-text stops,
human flags, and “no silent reroute” are exactly the v0.1 worker service.
This mode does not add a second wakeup path.
If the service is not running, the case still exists as a derived object
and a hub-projectable receipt of `observed` / `waiting`. Agents follow
the instruction pack instead of injecting workers.
### Checkpoint
Reuse v0.1 checkpoint shape (summary, files_changed, next_action,
blocked_reason, 8 KiB, local). `blocked_reason` stops automatic
continuation. A checkpoint is not completion.
### Fail closed
Missing authorization, unregistered target, residual-as-driver, or
attempt to reassign another owners task → `stopped` with reason. Never
silently re-assign.
### Exit
| Exit | Condition |
| --- | --- |
| `satisfied` | Obligor workplan/task reaches `done`/`finished`/`archived` |
| `stopped` | Safety, human, missing auth, residual driver |
| `waiting` | Foreign record still open; case remains attached |
## Receipt shape (hub-projectable)
Extends the v0.1 sanitized receipt (state, reason, lease/trigger ids).
Additional fields (no payloads, no secrets):
```yaml
scenario_type: project_driver | cross_owner_wait
case_id: string
driver_workplan_id: string?
driver_repo: string?
obligor_workplan_id: string
beneficiary_workplan_id: string
flavor: string?
```
Projection remains `POST /progress/` with
`event_type: coordination_receipt` as in the v0.1 Hub adapter. Queued
edge-relay receipts are not proof of central publication.
## Common estate pattern
Repo A (e.g. `net-kingdom`) blocked on repo B (e.g. `key-cape`,
`flex-auth`, OpenBao owner). If `HFACT-WP-0001` (or another `prj-`
driver) already lists both, attach there. Otherwise derive
`cross_owner_wait` from As waiting workplan. Observe B. Do not implement
Bs tasks from As session. Do not message `ops-warden` for a secret.
## Anti-patterns
- Stranded `wait` with no case and no observer
- Copying Bs tasks into As workplan
- Treating `flavor: residual` as a driver
- Inventing `warden secret` / asking ops-warden for API keys
- Enabling live worker injection as a side effect of documenting this mode

View file

@ -12,6 +12,11 @@ that repository. This package installs `coordination-engine`, never `tamq`.
## Observation and actionability
Cross-owner waits that used to become stranded `wait` notes are specified in
`spec/cross-owner-wait-mode-v0.1.md`. That mode **reuses** this service's
observation, leases, safety gates and receipts; it does not add a second
wakeup path or enable live injection.
The runtime polls State Hub's repos, workplans, tasks, dependency edges and unread
messages. It dispatches only after a complete successful snapshot, only for
explicitly configured gita repositories. It refreshes gita before addressing a