coordination-engine/spec/cross-owner-wait-mode-v0.1.md
tegwick 354e800d3b
All checks were successful
check / test (push) Successful in 1m42s
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Add kind: decision commitments and depends_on entry for cross-owner waits (CUST-WP-0074-T03)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: claude-fable-5-1
Assistant-Process: 237582@bnt-lap001
Assistant-Session: f2b3d9f1-8fb9-4b9c-bc2b-837ec5dfc826
2026-09-28 22:14:39 +02:00

121 lines
4.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 B’s 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` with a task-block `depends_on` naming a workplan or
task in another repo (fleet standard
`the-custodian/canon/standards/task-wait-qualifiers_v0.1.md`). Prose
that names another repo, owner or workplan id without `depends_on`
remains an entry condition only until the CUST-WP-0074-T05 backfill
completes; it is an unqualified wait and should be converted.
2. A workplan is `blocked` on a `depends_on` target whose `repo` is not
this repo.
A task with `needs_human: true` is a **human gate**, not a cross-owner
wait. It does not enter this mode; it is a `kind: decision` commitment
(coordination-model v0.2 §5) satisfied only by the named person or the
resolution of its `decision_id`. A task carrying both `depends_on` and
`needs_human: true` enters this mode for the `depends_on` part only.
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 owner’s 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. A human-gate task
(`needs_human: true`) is never leased or woken: it is a stop condition,
and a worker that reaches one checkpoints with `blocked_reason` and exits.
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 owner’s 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 A’s waiting workplan. Observe B. Do not implement
B’s tasks from A’s session. Do not message `ops-warden` for a secret.
## Anti-patterns
- Stranded `wait` with no case and no observer
- Copying B’s tasks into A’s 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