diff --git a/skills/implementing-tickets/SKILL.md b/skills/implementing-tickets/SKILL.md index 80ef4a09be..98aeb1f05e 100644 --- a/skills/implementing-tickets/SKILL.md +++ b/skills/implementing-tickets/SKILL.md @@ -65,20 +65,12 @@ VERDICT IS YOUR FIRST BOARD WRITE. Dispatch wrote nothing. - Pass → {{BOARD_SCRIPTS}}/board-transition.sh {{ISSUE_NUMBER}} in-progress then a one-line gate comment: gh issue comment {{ISSUE_NUMBER}} --body "[gate] pass — {{ENGINE_NAME}}/: " -- Fail → the park state itself, with the required note. Park discriminant — - WHO UNPARKS IT: - - The human as themselves — a decision only they can make, or a - real-world input only they possess (credentials, auth, production - data) → needs-human. Note = the crisp question list, each with your - recommended answer. - - Knowledge work anyone could do, but substantial enough to be its own - work-unit (or its outcome needs human review before decisions harden) - → needs-info. Note = what is missing and why gating cannot proceed. - - Ongoing steering of the work's CORE — an architecture spine or - product-core design whose decisions are so entangled that each answer - reshapes the next question, impossible to carry as a question list → - interactive-preferred. Any ENUMERABLE set of open decisions, however - many and whatever the ticket's size, is needs-human — not steering. +- Fail → the park state itself, with the required note. The park + discriminant — WHO UNPARKS IT — and the full state vocabulary are owned + by doperpowers:issue-tracker, the board schema's single home: open that + skill and classify the park against it before writing anything. In + particular, waiting on other tickets is never a park state there — + dependencies are edges, and the ticket goes back to ready-for-agent. Every park additionally carries a 3–6 line ORIENTATION SUMMARY in its comment (what you read, what you learned, where the answers will land) — it prices the fresh-dispatch fallback cheaply while you are still diff --git a/skills/implementing-tickets/references/implement-decompose.md b/skills/implementing-tickets/references/implement-decompose.md index bee61ddea6..f4cd44b74e 100644 --- a/skills/implementing-tickets/references/implement-decompose.md +++ b/skills/implementing-tickets/references/implement-decompose.md @@ -18,10 +18,9 @@ only the PROCEDURE and grants no authority beyond your prompt's. 2. Flesh out each child body (`gh issue edit --body-file -`) to the pre-spec bar: a fresh-context worker can start from the body alone. -3. Gate-triage each child HONESTLY: `ready-for-agent` only if YOU believe - it passes the Ticket Gate; an open human decision → born `needs-human`; - product-core steering → born `interactive-preferred` — required notes - always. +3. Gate-triage each child HONESTLY per the doperpowers:issue-tracker + ticket contract and park discriminant — `ready-for-agent` only if YOU + believe it passes the Ticket Gate. 4. Register only children you can spec self-contained NOW. Contingent later phases live as a `## Roadmap` section in the parent body — the diff --git a/skills/implementing-tickets/references/operation-manual.md b/skills/implementing-tickets/references/operation-manual.md index 3ed63bd20a..c71d5acacb 100644 --- a/skills/implementing-tickets/references/operation-manual.md +++ b/skills/implementing-tickets/references/operation-manual.md @@ -54,21 +54,12 @@ No → `interactive-preferred`. ## Park discriminant — who unparks it? -- **The human as themselves** (a decision only they can make, or a - real-world input only they possess: credentials, auth, production data) - → `needs-human`. Note = the question list, each with a recommended answer. -- **Knowledge work anyone could do** but substantial enough to be its own - work-unit → `needs-info` (rare by design — the research threshold above - keeps orient-work lookups out of it). -- **Ongoing steering of the work's core, not one answer** — an - architecture spine or product-core design whose decisions are so - entangled that each answer reshapes the next question (a question list - cannot carry them) → `interactive-preferred` — summons the human into a - live doperpowers:brainstorming session; the note says which decision - areas need steering. Any *enumerable* set of open decisions, however - many and whatever the ticket's size, is `needs-human` — in practice - this state is rare and marks genuinely architecture-heavy or - taste-shaped work. +Owned by doperpowers:issue-tracker — the board schema's single home +(state vocabulary, park discriminant, dependencies-are-edges); workers +and operators classify every park there, one copy, no drift. The worker +protocol layers on only the worker-side park mechanics: the required +note, the 3–6 line orientation summary, and ending the turn with the +park stated crisply. ## Decompose — the one scoping behavior diff --git a/skills/issue-tracker/SKILL.md b/skills/issue-tracker/SKILL.md index e7c5f04339..6948e3b91c 100644 --- a/skills/issue-tracker/SKILL.md +++ b/skills/issue-tracker/SKILL.md @@ -67,12 +67,20 @@ the review loop (doperpowers:reviewing-prs) a PR passes through | `wontfix` | **closed — not planned** | rejected | **required** | | `deferred` | open + `status:deferred` | tracked, not now | optional | -**Park discriminant — who unparks it?** The human acting as themselves (a -decision, or a real-world input) → `needs-human`. Knowledge work that anyone -could in principle do (substantial research, spec-deepening) → `needs-info`. -Not one answer but ongoing steering → `interactive-preferred`. (`blocked` -was retired in v8: its meaning was absorbed by `needs-human`; lint names any -legacy label with the migration FIX.) +**Park discriminant — who unparks it?** This paragraph is the single +authoritative copy — worker protocols route here instead of restating it. +The human acting as themselves (a decision, or a real-world input) → +`needs-human`; the note is the crisp question list, each with a +recommended answer. Knowledge work that anyone could in principle do +(substantial research, spec-deepening) → `needs-info`; the note says what +is missing. Not one answer but ongoing steering of the work's core → +`interactive-preferred`; any ENUMERABLE set of open decisions, however +many, is `needs-human` — not steering. Waiting on other tickets is NOT a +park: dependencies are edges — cut `blocked-by` and return the ticket to +`ready-for-agent` (the note names any banked branch); the unblock sweep +re-surfaces it the moment its blockers land, which no park state does. +(`blocked` was retired in v8: its meaning was absorbed by `needs-human`; +lint names any legacy label with the migration FIX.) Exactly one `status:*` label on every open issue; terminal states are the close reason (no label). An issue outside this scheme is `untracked` (no diff --git a/skills/orchestrating-daemons/SKILL.md b/skills/orchestrating-daemons/SKILL.md index 7022b65308..4e8b7213a8 100644 --- a/skills/orchestrating-daemons/SKILL.md +++ b/skills/orchestrating-daemons/SKILL.md @@ -50,7 +50,7 @@ For the escape-hatch case only — pipeline workers are spawned by their dispatc ## Escalation -Fleet-of-workers escalation lives in the board pipeline: implement and review workers park their own tickets (`needs-human` / `needs-info` / `interactive-preferred`, per the who-unparks discriminant in doperpowers:implementing-tickets), the human answers on the ticket at their next wake, and nobody sits between a worker and the board. A park is a pause, not a death: a `needs-human` answer is relayed to the worker's still-bound session by the wake ritual (issue-tracker's `board-answer.sh`), so the worker resumes with its orientation intact. +Fleet-of-workers escalation lives in the board pipeline: implement and review workers park their own tickets (`needs-human` / `needs-info` / `interactive-preferred`, per the who-unparks discriminant in doperpowers:issue-tracker, the board schema's single home), the human answers on the ticket at their next wake, and nobody sits between a worker and the board. A park is a pause, not a death: a `needs-human` answer is relayed to the worker's still-bound session by the wake ritual (issue-tracker's `board-answer.sh`), so the worker resumes with its orientation intact. For a hand-driven ad-hoc daemon: answer mechanical/technical questions yourself and resume — you are trusted for those calls. A genuine product/taste/approval fork is the signal the work was ticket-shaped after all — register it on the board and park it `needs-human` with the question as the note. Only in a truly board-less context, `daemon-mark.sh awaiting-human ""` queues it for the human's next check-in; wake the human now (PushNotification) only for something destructive/irreversible about to happen or a security / data-loss / production risk that can't wait. diff --git a/tests/implementing-tickets/test-protocol-content.sh b/tests/implementing-tickets/test-protocol-content.sh index ed1742387b..878bc990aa 100755 --- a/tests/implementing-tickets/test-protocol-content.sh +++ b/tests/implementing-tickets/test-protocol-content.sh @@ -57,7 +57,8 @@ assert_contains "$proto" "ORIENTATION SUMMARY" "park orientation summary mandate assert_contains "$proto" "no live progress mirror" "no-mirror doctrine stated in the protocol" assert_contains "$proto" "big-but-ATOMIC" "atomic-counts-as-one-unit scoping clause present" assert_contains "$proto" "land on main independently" "landability decompose criterion present" -assert_contains "$proto" "ENUMERABLE" "enumerable-decisions→needs-human discriminant present" +assert_contains "$proto" "single home" "park discriminant routes to issue-tracker (single-source)" +assert_not_contains "$proto" "Knowledge work anyone could do" "needs-info definition not re-vendored in the protocol" assert_contains "$proto" "doperpowers:reviewing-prs" "handoff to the review loop named" assert_not_contains "$proto" '"ticket":' "the JSON proposal block is dead" assert_not_contains "$proto" "→ blocked" "no retired blocked vocabulary" @@ -178,6 +179,18 @@ assert_contains "$tracker" "worker-bootstrap.md" "ritual: renders the bootstrap, assert_not_contains "$tracker" "embedded verbatim" "ritual: verbatim-embed spawn retired" assert_not_contains "$tracker" "implement-worker-protocol.md" "ritual: no reference to the retired protocol file" +echo "board schema single-source (issue-tracker owns the discriminant):" +assert_contains "$tracker" "Park discriminant — who unparks it?" "tracker: canonical discriminant lives here" +assert_contains "$tracker" "recommended answer" "tracker: needs-human note contract (question list with recommendations)" +assert_contains "$tracker" "ENUMERABLE" "tracker: enumerable-decisions→needs-human rule is canonical here" +assert_contains "$tracker" "Waiting on other tickets" "tracker: dependency-wait is not a park (edges + ready-for-agent)" +assert_contains "$tracker" "which no park state does" "tracker: sweep rationale recorded (why edges beat park states)" +daemons="$(cat "$REPO_ROOT/skills/orchestrating-daemons/SKILL.md")" +assert_contains "$daemons" "discriminant in doperpowers:issue-tracker" "daemons: discriminant pointer targets the schema owner" +assert_not_contains "$daemons" "discriminant in doperpowers:implementing-tickets" "daemons: no stale pointer at the old vendored copy" +assert_contains "$decomp" "doperpowers:issue-tracker" "decompose doc: child gate-triage routes through the ticket contract" +assert_not_contains "$manual" "Knowledge work anyone could do" "manual: discriminant not re-vendored (routes to issue-tracker)" + echo if [ "$FAILURES" -gt 0 ]; then echo "$FAILURES test(s) FAILED"; exit 1; fi echo "all tests passed"