From 91fc89b70ff5e6a630ec8ae5df18ec12ce079757 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2026 08:27:47 +0000 Subject: [PATCH 01/12] config: Compress workflow execution preambles Render one compact execution contract in five workflows across four targets. Preserve phase bodies, gates, permissions, layouts, and unrelated generated artifacts. Add independent contract and negative-fixture checks, refresh fifteen tracked mirrors, and update the affected context. Preamble bytes decrease by 48.62-50.98 percent. Focused generation checks and all-artifact comparisons passed; full Nix CI remains pending. Plan: compress-workflow-execution-preamble, T01. --- .agents/skills/sce-change-to-plan/SKILL.md | 38 +-- .agents/skills/sce-commit/SKILL.md | 38 +-- .agents/skills/sce-handover/SKILL.md | 38 +-- .agents/skills/sce-next-task/SKILL.md | 39 +-- .agents/skills/sce-validate/SKILL.md | 37 +-- .claude/skills/sce-change-to-plan/SKILL.md | 38 +-- .claude/skills/sce-commit/SKILL.md | 38 +-- .claude/skills/sce-handover/SKILL.md | 38 +-- .claude/skills/sce-next-task/SKILL.md | 39 +-- .claude/skills/sce-validate/SKILL.md | 37 +-- .pi/skills/sce-change-to-plan/SKILL.md | 38 +-- .pi/skills/sce-commit/SKILL.md | 38 +-- .pi/skills/sce-handover/SKILL.md | 38 +-- .pi/skills/sce-next-task/SKILL.md | 39 +-- .pi/skills/sce-validate/SKILL.md | 37 +-- config/pkl/base/workflow-change-to-plan.pkl | 25 +- config/pkl/base/workflow-commit.pkl | 25 +- config/pkl/base/workflow-content.pkl | 72 ++--- .../renderers/generation-contract-check.pkl | 85 +++++- config/pkl/renderers/workflow-composite.pkl | 55 ++-- context/glossary.md | 2 +- context/patterns.md | 2 +- .../compress-workflow-execution-preamble.md | 257 ++++++++++++++++++ context/sce/dedup-ownership-table.md | 1 + context/sce/handover-workflow.md | 8 +- 25 files changed, 574 insertions(+), 528 deletions(-) create mode 100644 context/plans/compress-workflow-execution-preamble.md diff --git a/.agents/skills/sce-change-to-plan/SKILL.md b/.agents/skills/sce-change-to-plan/SKILL.md index 9d33cd036..8d88bb175 100644 --- a/.agents/skills/sce-change-to-plan/SKILL.md +++ b/.agents/skills/sce-change-to-plan/SKILL.md @@ -6,13 +6,17 @@ description: > # SCE Change to Plan -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. +## Execution contract + +Own this workflow from input through its terminal user-visible response. +Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. +Keep phase results internal and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +Use only the specified `references/output.md` layouts for gates and terminal +responses. Do not expose raw state or add text around a layout. +Non-SCE helpers may assist, but must return to the active step without changing +phase order, gates, waits, writes, validation, stops, or terminal output. +Do not invoke another SCE skill, package, or workflow command. ## Phase references @@ -33,26 +37,6 @@ Read a step's reference before taking any action for that step, not after. Read only the reference for the step you have reached: a run that stops at the bootstrap gate never authors a plan, which is why they are separate files. -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result -as the workflow's final response. - -Relevant non-SCE skills may be used as helper capabilities during the active step. -They are not workflow handoffs: when a helper returns, control returns to the active -step. Helper use must preserve the canonical phase order, gates, waits, writes, -validation, stops, and terminal user-visible output. - ## Input `invocation input` is the change request, in free-form prose. diff --git a/.agents/skills/sce-commit/SKILL.md b/.agents/skills/sce-commit/SKILL.md index a5539c8c7..37e69ce35 100644 --- a/.agents/skills/sce-commit/SKILL.md +++ b/.agents/skills/sce-commit/SKILL.md @@ -6,13 +6,17 @@ description: > # SCE Commit -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. +## Execution contract + +Own this workflow from input through its terminal user-visible response. +Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. +Keep phase results internal and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +Use only the specified `references/output.md` layouts for gates and terminal +responses. Do not expose raw state or add text around a layout. +Non-SCE helpers may assist, but must return to the active step without changing +phase order, gates, waits, writes, validation, stops, or terminal output. +Do not invoke another SCE skill, package, or workflow command. ## Phase reference @@ -25,26 +29,6 @@ Read `references/atomic-commit.md` before running the phase, not after. A regula run that stops at the staging gate, and a bypass run that finds nothing staged, both end without ever needing it. -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result -as the workflow's final response. - -Relevant non-SCE skills may be used as helper capabilities during the active step. -They are not workflow handoffs: when a helper returns, control returns to the active -step. Helper use must preserve the canonical phase order, gates, waits, writes, -validation, stops, and terminal user-visible output. - ## Input `invocation input` is optional. Split it into two parts before invoking the skill: diff --git a/.agents/skills/sce-handover/SKILL.md b/.agents/skills/sce-handover/SKILL.md index 75d0cf72a..40095e848 100644 --- a/.agents/skills/sce-handover/SKILL.md +++ b/.agents/skills/sce-handover/SKILL.md @@ -6,33 +6,17 @@ description: > # SCE Handover -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. - -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result -as the workflow's final response. - -Relevant non-SCE skills may be used as helper capabilities during the active step. -They are not workflow handoffs: when a helper returns, control returns to the active -step. Helper use must preserve the canonical phase order, gates, waits, writes, -validation, stops, and terminal user-visible output. +## Execution contract + +Own this workflow from input through its terminal user-visible response. +Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. +Keep phase results internal and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +Use only the specified `references/output.md` layouts for gates and terminal +responses. Do not expose raw state or add text around a layout. +Non-SCE helpers may assist, but must return to the active step without changing +phase order, gates, waits, writes, validation, stops, or terminal output. +Do not invoke another SCE skill, package, or workflow command. ## Input diff --git a/.agents/skills/sce-next-task/SKILL.md b/.agents/skills/sce-next-task/SKILL.md index f3bb55663..2d11f1198 100644 --- a/.agents/skills/sce-next-task/SKILL.md +++ b/.agents/skills/sce-next-task/SKILL.md @@ -6,14 +6,18 @@ description: > # SCE Next Task -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command except `sce-decision`, and invoke `sce-decision` -only from the successful context-synchronization decision gate. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. +## Execution contract + +Own this workflow from input through its terminal user-visible response. +Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. +Keep phase results internal and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +Use only the specified `references/output.md` layouts for gates and terminal +responses. Do not expose raw state or add text around a layout. +Non-SCE helpers may assist, but must return to the active step without changing +phase order, gates, waits, writes, validation, stops, or terminal output. +Do not invoke another SCE skill, package, or workflow command except `sce-decision`, +and only from the successful context-synchronization decision gate. ## Phase references @@ -34,25 +38,6 @@ phase begun from this summary alone will already have skipped them. Read only th reference for the step you have reached: a run that stops at step 1 never needs the other two, which is why they are separate files. -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result as the workflow's final response. - -Relevant non-SCE skills may be used as helper capabilities during the active step. -They are not workflow handoffs: when a helper returns, control returns to the active -step. Helper use must preserve the canonical phase order, gates, waits, writes, -validation, stops, and terminal user-visible output. - ## Input Parse `invocation input` into three positional parts before invoking any phase: diff --git a/.agents/skills/sce-validate/SKILL.md b/.agents/skills/sce-validate/SKILL.md index df04f10df..cd8366bc8 100644 --- a/.agents/skills/sce-validate/SKILL.md +++ b/.agents/skills/sce-validate/SKILL.md @@ -6,13 +6,17 @@ description: > # SCE Validate -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. +## Execution contract + +Own this workflow from input through its terminal user-visible response. +Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. +Keep phase results internal and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +Use only the specified `references/output.md` layouts for gates and terminal +responses. Do not expose raw state or add text around a layout. +Non-SCE helpers may assist, but must return to the active step without changing +phase order, gates, waits, writes, validation, stops, or terminal output. +Do not invoke another SCE skill, package, or workflow command. ## Phase references @@ -30,25 +34,6 @@ written into the plan file. Step 1 points to it at the moment it is needed, on a Read the reference before taking any action for step 1, not after. -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result as the workflow's final response. - -Relevant non-SCE skills may be used as helper capabilities during the active step. -They are not workflow handoffs: when a helper returns, control returns to the active -step. Helper use must preserve the canonical phase order, gates, waits, writes, -validation, stops, and terminal user-visible output. - ## Input `invocation input` is the plan name or plan path. diff --git a/.claude/skills/sce-change-to-plan/SKILL.md b/.claude/skills/sce-change-to-plan/SKILL.md index 36744080d..d9bb76f94 100644 --- a/.claude/skills/sce-change-to-plan/SKILL.md +++ b/.claude/skills/sce-change-to-plan/SKILL.md @@ -7,13 +7,17 @@ compatibility: claude # SCE Change to Plan -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. +## Execution contract + +Own this workflow from input through its terminal user-visible response. +Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. +Keep phase results internal and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +Use only the specified `references/output.md` layouts for gates and terminal +responses. Do not expose raw state or add text around a layout. +Non-SCE helpers may assist, but must return to the active step without changing +phase order, gates, waits, writes, validation, stops, or terminal output. +Do not invoke another SCE skill, package, or workflow command. ## Phase references @@ -34,26 +38,6 @@ Read a step's reference before taking any action for that step, not after. Read only the reference for the step you have reached: a run that stops at the bootstrap gate never authors a plan, which is why they are separate files. -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result -as the workflow's final response. - -Relevant non-SCE skills may be used as helper capabilities during the active step. -They are not workflow handoffs: when a helper returns, control returns to the active -step. Helper use must preserve the canonical phase order, gates, waits, writes, -validation, stops, and terminal user-visible output. - ## Input `$ARGUMENTS` is the change request, in free-form prose. diff --git a/.claude/skills/sce-commit/SKILL.md b/.claude/skills/sce-commit/SKILL.md index 2987bef14..56693758c 100644 --- a/.claude/skills/sce-commit/SKILL.md +++ b/.claude/skills/sce-commit/SKILL.md @@ -7,13 +7,17 @@ compatibility: claude # SCE Commit -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. +## Execution contract + +Own this workflow from input through its terminal user-visible response. +Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. +Keep phase results internal and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +Use only the specified `references/output.md` layouts for gates and terminal +responses. Do not expose raw state or add text around a layout. +Non-SCE helpers may assist, but must return to the active step without changing +phase order, gates, waits, writes, validation, stops, or terminal output. +Do not invoke another SCE skill, package, or workflow command. ## Phase reference @@ -26,26 +30,6 @@ Read `references/atomic-commit.md` before running the phase, not after. A regula run that stops at the staging gate, and a bypass run that finds nothing staged, both end without ever needing it. -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result -as the workflow's final response. - -Relevant non-SCE skills may be used as helper capabilities during the active step. -They are not workflow handoffs: when a helper returns, control returns to the active -step. Helper use must preserve the canonical phase order, gates, waits, writes, -validation, stops, and terminal user-visible output. - ## Input `$ARGUMENTS` is optional. Split it into two parts before invoking the skill: diff --git a/.claude/skills/sce-handover/SKILL.md b/.claude/skills/sce-handover/SKILL.md index e9e3d6013..11c2e59a9 100644 --- a/.claude/skills/sce-handover/SKILL.md +++ b/.claude/skills/sce-handover/SKILL.md @@ -7,33 +7,17 @@ compatibility: claude # SCE Handover -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. - -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result -as the workflow's final response. - -Relevant non-SCE skills may be used as helper capabilities during the active step. -They are not workflow handoffs: when a helper returns, control returns to the active -step. Helper use must preserve the canonical phase order, gates, waits, writes, -validation, stops, and terminal user-visible output. +## Execution contract + +Own this workflow from input through its terminal user-visible response. +Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. +Keep phase results internal and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +Use only the specified `references/output.md` layouts for gates and terminal +responses. Do not expose raw state or add text around a layout. +Non-SCE helpers may assist, but must return to the active step without changing +phase order, gates, waits, writes, validation, stops, or terminal output. +Do not invoke another SCE skill, package, or workflow command. ## Input diff --git a/.claude/skills/sce-next-task/SKILL.md b/.claude/skills/sce-next-task/SKILL.md index 5c96a865a..51d3b716b 100644 --- a/.claude/skills/sce-next-task/SKILL.md +++ b/.claude/skills/sce-next-task/SKILL.md @@ -7,14 +7,18 @@ compatibility: claude # SCE Next Task -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command except `sce-decision`, and invoke `sce-decision` -only from the successful context-synchronization decision gate. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. +## Execution contract + +Own this workflow from input through its terminal user-visible response. +Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. +Keep phase results internal and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +Use only the specified `references/output.md` layouts for gates and terminal +responses. Do not expose raw state or add text around a layout. +Non-SCE helpers may assist, but must return to the active step without changing +phase order, gates, waits, writes, validation, stops, or terminal output. +Do not invoke another SCE skill, package, or workflow command except `sce-decision`, +and only from the successful context-synchronization decision gate. ## Phase references @@ -35,25 +39,6 @@ phase begun from this summary alone will already have skipped them. Read only th reference for the step you have reached: a run that stops at step 1 never needs the other two, which is why they are separate files. -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result as the workflow's final response. - -Relevant non-SCE skills may be used as helper capabilities during the active step. -They are not workflow handoffs: when a helper returns, control returns to the active -step. Helper use must preserve the canonical phase order, gates, waits, writes, -validation, stops, and terminal user-visible output. - ## Input Parse `$ARGUMENTS` into three positional parts before invoking any phase: diff --git a/.claude/skills/sce-validate/SKILL.md b/.claude/skills/sce-validate/SKILL.md index 5d45fbb26..e7e9d59c2 100644 --- a/.claude/skills/sce-validate/SKILL.md +++ b/.claude/skills/sce-validate/SKILL.md @@ -7,13 +7,17 @@ compatibility: claude # SCE Validate -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. +## Execution contract + +Own this workflow from input through its terminal user-visible response. +Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. +Keep phase results internal and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +Use only the specified `references/output.md` layouts for gates and terminal +responses. Do not expose raw state or add text around a layout. +Non-SCE helpers may assist, but must return to the active step without changing +phase order, gates, waits, writes, validation, stops, or terminal output. +Do not invoke another SCE skill, package, or workflow command. ## Phase references @@ -31,25 +35,6 @@ written into the plan file. Step 1 points to it at the moment it is needed, on a Read the reference before taking any action for step 1, not after. -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result as the workflow's final response. - -Relevant non-SCE skills may be used as helper capabilities during the active step. -They are not workflow handoffs: when a helper returns, control returns to the active -step. Helper use must preserve the canonical phase order, gates, waits, writes, -validation, stops, and terminal user-visible output. - ## Input `$ARGUMENTS` is the plan name or plan path. diff --git a/.pi/skills/sce-change-to-plan/SKILL.md b/.pi/skills/sce-change-to-plan/SKILL.md index 5a97185fc..37d2fcf0b 100644 --- a/.pi/skills/sce-change-to-plan/SKILL.md +++ b/.pi/skills/sce-change-to-plan/SKILL.md @@ -6,13 +6,17 @@ description: > # SCE Change to Plan -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. +## Execution contract + +Own this workflow from input through its terminal user-visible response. +Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. +Keep phase results internal and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +Use only the specified `references/output.md` layouts for gates and terminal +responses. Do not expose raw state or add text around a layout. +Non-SCE helpers may assist, but must return to the active step without changing +phase order, gates, waits, writes, validation, stops, or terminal output. +Do not invoke another SCE skill, package, or workflow command. ## Phase references @@ -33,26 +37,6 @@ Read a step's reference before taking any action for that step, not after. Read only the reference for the step you have reached: a run that stops at the bootstrap gate never authors a plan, which is why they are separate files. -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result -as the workflow's final response. - -Relevant non-SCE skills may be used as helper capabilities during the active step. -They are not workflow handoffs: when a helper returns, control returns to the active -step. Helper use must preserve the canonical phase order, gates, waits, writes, -validation, stops, and terminal user-visible output. - ## Input `$ARGUMENTS` is the change request, in free-form prose. diff --git a/.pi/skills/sce-commit/SKILL.md b/.pi/skills/sce-commit/SKILL.md index 262b2a35a..b92e98651 100644 --- a/.pi/skills/sce-commit/SKILL.md +++ b/.pi/skills/sce-commit/SKILL.md @@ -6,13 +6,17 @@ description: > # SCE Commit -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. +## Execution contract + +Own this workflow from input through its terminal user-visible response. +Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. +Keep phase results internal and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +Use only the specified `references/output.md` layouts for gates and terminal +responses. Do not expose raw state or add text around a layout. +Non-SCE helpers may assist, but must return to the active step without changing +phase order, gates, waits, writes, validation, stops, or terminal output. +Do not invoke another SCE skill, package, or workflow command. ## Phase reference @@ -25,26 +29,6 @@ Read `references/atomic-commit.md` before running the phase, not after. A regula run that stops at the staging gate, and a bypass run that finds nothing staged, both end without ever needing it. -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result -as the workflow's final response. - -Relevant non-SCE skills may be used as helper capabilities during the active step. -They are not workflow handoffs: when a helper returns, control returns to the active -step. Helper use must preserve the canonical phase order, gates, waits, writes, -validation, stops, and terminal user-visible output. - ## Input `$ARGUMENTS` is optional. Split it into two parts before invoking the skill: diff --git a/.pi/skills/sce-handover/SKILL.md b/.pi/skills/sce-handover/SKILL.md index 8e5d325ed..411276aac 100644 --- a/.pi/skills/sce-handover/SKILL.md +++ b/.pi/skills/sce-handover/SKILL.md @@ -6,33 +6,17 @@ description: > # SCE Handover -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. - -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result -as the workflow's final response. - -Relevant non-SCE skills may be used as helper capabilities during the active step. -They are not workflow handoffs: when a helper returns, control returns to the active -step. Helper use must preserve the canonical phase order, gates, waits, writes, -validation, stops, and terminal user-visible output. +## Execution contract + +Own this workflow from input through its terminal user-visible response. +Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. +Keep phase results internal and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +Use only the specified `references/output.md` layouts for gates and terminal +responses. Do not expose raw state or add text around a layout. +Non-SCE helpers may assist, but must return to the active step without changing +phase order, gates, waits, writes, validation, stops, or terminal output. +Do not invoke another SCE skill, package, or workflow command. ## Input diff --git a/.pi/skills/sce-next-task/SKILL.md b/.pi/skills/sce-next-task/SKILL.md index e4b4a3d2f..0f37cc458 100644 --- a/.pi/skills/sce-next-task/SKILL.md +++ b/.pi/skills/sce-next-task/SKILL.md @@ -6,14 +6,18 @@ description: > # SCE Next Task -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command except `sce-decision`, and invoke `sce-decision` -only from the successful context-synchronization decision gate. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. +## Execution contract + +Own this workflow from input through its terminal user-visible response. +Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. +Keep phase results internal and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +Use only the specified `references/output.md` layouts for gates and terminal +responses. Do not expose raw state or add text around a layout. +Non-SCE helpers may assist, but must return to the active step without changing +phase order, gates, waits, writes, validation, stops, or terminal output. +Do not invoke another SCE skill, package, or workflow command except `sce-decision`, +and only from the successful context-synchronization decision gate. ## Phase references @@ -34,25 +38,6 @@ phase begun from this summary alone will already have skipped them. Read only th reference for the step you have reached: a run that stops at step 1 never needs the other two, which is why they are separate files. -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result as the workflow's final response. - -Relevant non-SCE skills may be used as helper capabilities during the active step. -They are not workflow handoffs: when a helper returns, control returns to the active -step. Helper use must preserve the canonical phase order, gates, waits, writes, -validation, stops, and terminal user-visible output. - ## Input Parse `$ARGUMENTS` into three positional parts before invoking any phase: diff --git a/.pi/skills/sce-validate/SKILL.md b/.pi/skills/sce-validate/SKILL.md index b8c3864e7..389f4428d 100644 --- a/.pi/skills/sce-validate/SKILL.md +++ b/.pi/skills/sce-validate/SKILL.md @@ -6,13 +6,17 @@ description: > # SCE Validate -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. +## Execution contract + +Own this workflow from input through its terminal user-visible response. +Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. +Keep phase results internal and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +Use only the specified `references/output.md` layouts for gates and terminal +responses. Do not expose raw state or add text around a layout. +Non-SCE helpers may assist, but must return to the active step without changing +phase order, gates, waits, writes, validation, stops, or terminal output. +Do not invoke another SCE skill, package, or workflow command. ## Phase references @@ -30,25 +34,6 @@ written into the plan file. Step 1 points to it at the moment it is needed, on a Read the reference before taking any action for step 1, not after. -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result as the workflow's final response. - -Relevant non-SCE skills may be used as helper capabilities during the active step. -They are not workflow handoffs: when a helper returns, control returns to the active -step. Helper use must preserve the canonical phase order, gates, waits, writes, -validation, stops, and terminal user-visible output. - ## Input `$ARGUMENTS` is the plan name or plan path. diff --git a/config/pkl/base/workflow-change-to-plan.pkl b/config/pkl/base/workflow-change-to-plan.pkl index 501af0b64..c5ed8c1c3 100644 --- a/config/pkl/base/workflow-change-to-plan.pkl +++ b/config/pkl/base/workflow-change-to-plan.pkl @@ -3,13 +3,7 @@ import "workflow-content.pkl" as model changeToPlanSkillBody = (argumentsReference: String, invocationExample: String) -> """ # SCE Change to Plan -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. +\(model.executionContract.apply("standard")) ## Phase references @@ -30,23 +24,6 @@ Read a step's reference before taking any action for that step, not after. Read only the reference for the step you have reached: a run that stops at the bootstrap gate never authors a plan, which is why they are separate files. -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result -as the workflow's final response. - -\(model.helperSkillCompositionRule) - ## Input `\(argumentsReference)` is the change request, in free-form prose. diff --git a/config/pkl/base/workflow-commit.pkl b/config/pkl/base/workflow-commit.pkl index 8240845da..06cafd518 100644 --- a/config/pkl/base/workflow-commit.pkl +++ b/config/pkl/base/workflow-commit.pkl @@ -479,13 +479,7 @@ local renderCommitMessageStyle = (mode: model.WorkflowRenderMode) -> """ local commitSkillBody = (argumentsReference: String, invocationExample: String) -> """ # SCE Commit -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. +\(model.executionContract.apply("standard")) ## Phase reference @@ -498,23 +492,6 @@ Read `references/atomic-commit.md` before running the phase, not after. A regula run that stops at the staging gate, and a bypass run that finds nothing staged, both end without ever needing it. -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result -as the workflow's final response. - -\(model.helperSkillCompositionRule) - ## Input `\(argumentsReference)` is optional. Split it into two parts before invoking the skill: diff --git a/config/pkl/base/workflow-content.pkl b/config/pkl/base/workflow-content.pkl index ec2970a70..e9e5b6fef 100644 --- a/config/pkl/base/workflow-content.pkl +++ b/config/pkl/base/workflow-content.pkl @@ -208,17 +208,33 @@ validation, stops, and terminal user-visible output. /// four phase-based workflows. Target renderers add only supported entrypoint /// frontmatter; all operational and persisted-document content remains /// target-neutral. +/// Compact emitted contract. Legacy helper prose stays unchanged for other consumers. +typealias ExecutionContractVariant = "standard"|"task-decision" + +hidden executionContract = (variant: ExecutionContractVariant) -> + """ + ## Execution contract + + Own this workflow from input through its terminal user-visible response. + Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. + Keep phase results internal and continue immediately until a defined wait or stop. + Resume user waits in this same skill and session. + Use only the specified `references/output.md` layouts for gates and terminal + responses. Do not expose raw state or add text around a layout. + Non-SCE helpers may assist, but must return to the active step without changing + phase order, gates, waits, writes, validation, stops, or terminal output. + """ + "\n" + if (variant == "task-decision") + """ + Do not invoke another SCE skill, package, or workflow command except `sce-decision`, + and only from the successful context-synchronization decision gate. + """ + else + "Do not invoke another SCE skill, package, or workflow command." + nextTaskSkillBody = (argumentsReference: String, invocationExample: String) -> """ # SCE Next Task -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command except `sce-decision`, and invoke `sce-decision` -only from the successful context-synchronization decision gate. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. +\(executionContract.apply("task-decision")) ## Phase references @@ -239,22 +255,6 @@ phase begun from this summary alone will already have skipped them. Read only th reference for the step you have reached: a run that stops at step 1 never needs the other two, which is why they are separate files. -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result as the workflow's final response. - -\(helperSkillCompositionRule) - ## Input Parse `\(argumentsReference)` into three positional parts before invoking any phase: @@ -398,13 +398,7 @@ Stop. validateSkillBody = (argumentsReference: String, invocationExample: String) -> """ # SCE Validate -## Purpose - -Own this workflow from input parsing through its terminal user-visible response. -Execute the phases below directly and in order. Phase statuses are internal state, -not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE -package, or SCE workflow command. Follow the canonical workflow's steps, gates, -and stops exactly as written: never invent, skip, reorder, or merge a step. +\(executionContract.apply("standard")) ## Phase references @@ -422,22 +416,6 @@ written into the plan file. Step 1 points to it at the moment it is needed, on a Read the reference before taking any action for step 1, not after. -## User-visible output - -Use `references/output.md` for every gate and terminal response. Render no raw -internal state. The reference contains only human-visible Markdown layouts. -User-visible output is limited to those layouts: never invent a layout, and never -wrap one in an added preamble, commentary, summary, or extra section. - -## Composite control flow - -Keep phase results as internal state and continue immediately whenever the -canonical workflow says to continue. Stop only at a user wait or terminal branch. -Any workflow-defined user wait resumes this same skill in the same session. -Never expose an internal phase result as the workflow's final response. - -\(helperSkillCompositionRule) - ## Input `\(argumentsReference)` is the plan name or plan path. diff --git a/config/pkl/renderers/generation-contract-check.pkl b/config/pkl/renderers/generation-contract-check.pkl index bb8dc1038..c9d3d9b5c 100644 --- a/config/pkl/renderers/generation-contract-check.pkl +++ b/config/pkl/renderers/generation-contract-check.pkl @@ -255,6 +255,81 @@ local requiredHandoverSkillTokens = new Listing { "Never invoke another SCE skill, sibling SCE package, or SCE workflow command" } +local compactWorkflowSlugs = new Listing { + "change-to-plan"; "next-task"; "commit"; "validate"; "handover" +} + +hidden isCompactWorkflowPath = (path: String) -> + compactWorkflowSlugs.any((slug) -> path.endsWith("/skills/sce-\(slug)/SKILL.md")) + +// This oracle intentionally does not read the production rendering helper. +local expectedExecutionContract = (allowsDecision: Boolean) -> + """ + ## Execution contract + + Own this workflow from input through its terminal user-visible response. + Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. + Keep phase results internal and continue immediately until a defined wait or stop. + Resume user waits in this same skill and session. + Use only the specified `references/output.md` layouts for gates and terminal + responses. Do not expose raw state or add text around a layout. + Non-SCE helpers may assist, but must return to the active step without changing + phase order, gates, waits, writes, validation, stops, or terminal output. + """ + "\n" + if (allowsDecision) + """ + Do not invoke another SCE skill, package, or workflow command except `sce-decision`, + and only from the successful context-synchronization decision gate. + """ + else + "Do not invoke another SCE skill, package, or workflow command." + +local compactContractClauses = new Listing { + "Own this workflow from input through its terminal user-visible response." + "Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them." + "Keep phase results internal and continue immediately until a defined wait or stop." + "Resume user waits in this same skill and session." + "Use only the specified `references/output.md` layouts for gates and terminal\nresponses. Do not expose raw state or add text around a layout." + "Non-SCE helpers may assist, but must return to the active step without changing\nphase order, gates, waits, writes, validation, stops, or terminal output." +} + +hidden hasExpectedExecutionContract = (text: String, allowsDecision: Boolean) -> + text.split("## Execution contract\n").length == 2 + && text.contains(expectedExecutionContract.apply(allowsDecision)) + && !text.contains("## Purpose\n") + && !text.contains("## User-visible output\n") + && !text.contains("## Composite control flow\n") + && (text.contains("`sce-decision`") == allowsDecision) + && (!allowsDecision || !text.contains("Do not invoke another SCE skill, package, or workflow command.")) + +hidden assertCompactExecutionContracts = (documents: Mapping) -> + if ( + new Listing { ".opencode"; ".claude"; ".pi"; ".agents" }.every((target) -> + compactWorkflowSlugs.every((slug) -> + let (path = "config/\(target)/skills/sce-\(slug)/SKILL.md") + documents.containsKey(path) + && hasExpectedExecutionContract.apply(documents[path], slug == "next-task") + ) + ) + ) "compact execution contracts: five workflows, four targets, exact safeguards and permissions" + else throw("selected workflow has a missing, duplicated, or incorrect execution contract") + +hidden assertCompactExecutionContractFixtures = + let (standard = expectedExecutionContract.apply(false)) + let (decision = expectedExecutionContract.apply(true)) + if ( + hasExpectedExecutionContract.apply(standard, false) + && hasExpectedExecutionContract.apply(decision, true) + && compactContractClauses.every((clause) -> + !hasExpectedExecutionContract.apply(standard.replaceAll(clause, ""), false) + && !hasExpectedExecutionContract.apply(decision.replaceAll(clause, ""), true) + ) + && !hasExpectedExecutionContract.apply(standard, true) + && !hasExpectedExecutionContract.apply(decision, false) + && !hasExpectedExecutionContract.apply(decision + "\n" + "Do not invoke another SCE skill, package, or workflow command.", true) + && !hasExpectedExecutionContract.apply(standard + "\n" + standard, false) + ) "compact execution contract fixtures: omitted safeguards, wrong permissions, contradictions, duplicates rejected" + else throw("compact execution contract oracle accepted an invalid fixture") + local requiredHelperSkillCompositionTokens = new Listing { "Relevant non-SCE skills may be used as helper capabilities during the active step." "They are not workflow handoffs: when a helper returns, control returns to the active" @@ -442,7 +517,9 @@ local assertWorkflowHelperComposition = (documents: Mapping) -> if ( documents.every((path, text) -> !path.endsWith("/SKILL.md") - || requiredHelperSkillCompositionTokens.every((token) -> text.contains(token)) + || (if (isCompactWorkflowPath.apply(path)) + compactContractClauses.every((token) -> text.contains(token)) + else requiredHelperSkillCompositionTokens.every((token) -> text.contains(token))) ) ) "generated workflow helper composition: complete" else throw("generated workflow skill is missing the required helper-skill composition rule") @@ -452,7 +529,9 @@ local assertScopedWorkflowProhibitions = (documents: Mapping) -> documents.every((path, text) -> !path.endsWith("/SKILL.md") || ( - requiredScopedWorkflowTokens.every((token) -> text.contains(token)) + (if (isCompactWorkflowPath.apply(path)) + text.contains("Do not invoke another SCE skill, package, or workflow command") + else requiredScopedWorkflowTokens.every((token) -> text.contains(token))) && forbiddenUnscopedWorkflowTokens.every((token) -> !text.contains(token)) ) ) @@ -883,6 +962,8 @@ hidden assertValidateExcludesDecisionAndPlanSync = (documents: Mapping) -> else throw("generated sce-validate document must not contain a sce-decision reference or plan-context-sync wording") contractChecks { + ["compact-execution-contracts"] = assertCompactExecutionContracts.apply(workflowDocuments) + ["compact-execution-contract-negative-fixtures"] = assertCompactExecutionContractFixtures ["artifact-paths"] = assertExactArtifactPaths.apply(generatedArtifacts) ["codex-hook-invocation"] = assertCodexHookInvocationContract.apply(generatedArtifacts) ["codex-skills-exclude-arguments"] = assertCodexSkillsExcludeArguments.apply(generatedArtifacts) diff --git a/config/pkl/renderers/workflow-composite.pkl b/config/pkl/renderers/workflow-composite.pkl index d1acb21ee..edb6a7c0b 100644 --- a/config/pkl/renderers/workflow-composite.pkl +++ b/config/pkl/renderers/workflow-composite.pkl @@ -73,6 +73,37 @@ local renderInternalDocuments = (workflow: CompositeWorkflow) -> } }.join("\n\n") +/// Only handover uses the compact contract on this generic rendering path. +local renderCompositePreamble = (workflow: CompositeWorkflow) -> + if (workflow.slug == "handover") + model.executionContract.apply("standard") + else + """ + ## Purpose + + Own this workflow from input parsing through its terminal user-visible response. + Execute the phases below directly and in order. Phase statuses are internal state, + \(siblingSceWorkflowRule.apply(workflow)) Follow the canonical workflow's steps, gates, + and stops exactly as written: never invent, skip, reorder, or merge a step. + + ## User-visible output + + Use `references/output.md` for every gate and terminal response. Render no raw + internal state. The reference contains only human-visible Markdown layouts. + User-visible output is limited to those layouts: never invent a layout, and never + wrap one in an added preamble, commentary, summary, or extra section. + + ## Composite control flow + + Keep phase results as internal state and continue immediately whenever the + canonical workflow says to continue. Stop only at a user wait or terminal branch. + Any workflow-defined user wait resumes this same skill in the same session. + Never expose an internal phase result + as the workflow's final response. + + \(model.helperSkillCompositionRule) + """ + /// `extraFrontmatterLines` carries the target-specific frontmatter a skill /// entrypoint supports. Each line ends with a newline; a target that adds none /// passes the empty string. @@ -104,29 +135,7 @@ local renderSkill = (workflow: CompositeWorkflow, extraFrontmatterLines: String, # \(workflow.title) - ## Purpose - - Own this workflow from input parsing through its terminal user-visible response. - Execute the phases below directly and in order. Phase statuses are internal state, - \(siblingSceWorkflowRule.apply(workflow)) Follow the canonical workflow's steps, gates, - and stops exactly as written: never invent, skip, reorder, or merge a step. - - ## User-visible output - - Use `references/output.md` for every gate and terminal response. Render no raw - internal state. The reference contains only human-visible Markdown layouts. - User-visible output is limited to those layouts: never invent a layout, and never - wrap one in an added preamble, commentary, summary, or extra section. - - ## Composite control flow - - Keep phase results as internal state and continue immediately whenever the - canonical workflow says to continue. Stop only at a user wait or terminal branch. - Any workflow-defined user wait resumes this same skill in the same session. - Never expose an internal phase result - as the workflow's final response. - - \(model.helperSkillCompositionRule) + \(renderCompositePreamble.apply(workflow)) """ renderCanonicalWorkflow.apply(workflow, argumentsReference, invocationExample) when (workflow.structuredSource.phases.length > 0) { diff --git a/context/glossary.md b/context/glossary.md index e0827df96..92cfd21d6 100644 --- a/context/glossary.md +++ b/context/glossary.md @@ -32,7 +32,7 @@ - `workflow phase reference`: A package-local Markdown document emitted for one phase-based workflow step, such as `references/plan-review.md` or `references/context-sync.md`. It owns that phase's operational steps and boundaries and is read before the phase takes action; it does not create a sibling skill or transport phase state. - `baseline-relative task handoff`: The explicit `/next-task` execution result passed to task context synchronization. It contains the resolved plan and task identity, implementation-changed paths computed by comparing post-edit state with a pre-edit Git baseline, implementation summary, verification and done-check evidence, plan update, and context impact; unchanged pre-existing working-tree paths are excluded. Its persisted form is the same completed task record `/next-task` writes onto the task itself — `Completed`, `Files changed`, `Result`, `Verify` outcomes, and `Context impact`, identified only by plan path and task ID — with no separate synchronization-handoff structure, so a cross-session retry reads that record directly from the plan rather than depending on an out-of-band plan/task value supplied by the caller. - `workflow output reference`: The required `references/output.md` in every workflow skill package. It defines all and only that workflow's human-visible Markdown gates, reports, and terminal layouts. Phase-based packages also carry operational phase and persisted-document references, but those never own user-visible layouts. It is also the single statement of each layout: a `SKILL.md` branch that produces output cites the section it renders by heading rather than reproducing it. -- `no-improvisation rule`: The agent-behavior policy stated by the shared `renderSkill` preamble in every generated workflow `SKILL.md`, on every target. Its process half forbids inventing, skipping, reordering, or merging the canonical workflow's steps, gates, and stops; its output half limits user-visible output to the `references/output.md` layouts, forbidding invented layouts and any added preamble, commentary, summary, or extra section around them. It is prose instruction, not a machine-checked contract. See `context/architecture.md`. +- `no-improvisation rule`: The agent-behavior policy stated in every generated workflow `SKILL.md`: the five core workflows render the shared `executionContract` from `workflow-content.pkl`, while brownfield retains its existing preamble. Its process half forbids inventing, skipping, reordering, or merging the canonical workflow's steps, gates, and stops; its output half limits user-visible output to the `references/output.md` layouts, forbidding invented layouts and any added preamble, commentary, summary, or extra section around them. It is prose instruction, not a machine-checked contract. See `context/architecture.md`. - `atomic commit bypass mode`: The `/commit` mode selected when the exact first argument token is `oneshot` or `skip` (case-insensitive; the two aliases are behaviorally identical). It skips the staging-confirmation prompt and the context-file guidance gate, requires exactly one commit message covering all staged files with no split proposals, makes plan citations best-effort instead of blocking, and lets the command run exactly one `git commit`. Any other first token selects proposal-only regular mode. See `context/sce/atomic-commit-workflow.md`. - `split commit references`: The generated `sce-commit/references/atomic-commit.md`, `references/commit-message-style.md`, and `references/output.md` documents. The atomic reference owns staged-diff procedure, internal result branching, and commit boundaries; the style reference owns commit-message wording; and the output reference owns human-visible layouts. No `commit-contract.yaml` artifact or YAML result-contract section is generated. - `canonical OpenCode plugin registration source`: Shared Pkl-authored plugin-registration definition in `config/pkl/base/opencode.pkl`, re-exported from `config/pkl/renderers/common.pkl` as the canonical plugin list/path JSON consumed by OpenCode renderers before they emit generated `opencode.json` manifests; the current entries are `sce-bash-policy` and `sce-agent-trace`. diff --git a/context/patterns.md b/context/patterns.md index 998e61909..1b8e72265 100644 --- a/context/patterns.md +++ b/context/patterns.md @@ -72,7 +72,7 @@ - Keep OpenCode agents as thin routing surfaces when canonical workflow commands and skills own the behavior; do not duplicate workflow doctrine in agent bodies. - Implement target-specific formatting in dedicated renderer modules under `config/pkl/renderers/`, but keep workflow composition itself in the shared `workflow-composite.pkl`. Every canonical workflow must choose package-vs-composite wording through typed semantic references before Markdown assembly, not by stripping frontmatter or post-processing prose. Require a structured composite source for each workflow and do not reintroduce a legacy rewrite path. A target parameterizes composition only through the frontmatter lines it supports, never by forking the composition logic. - Compose each canonical workflow into one workflow-level skill package for every generated target; keep phase status handling internal to `SKILL.md`, emit no phase-skill package, and emit exactly one `references/output.md` containing that workflow's human-visible Markdown layouts. For the four phase-based workflows, emit named package-local phase, persisted-document, and supporting references and require `SKILL.md` to read each reference before its phase runs. Phase-free `/handover` also emits its package-local persisted-format template; `/brownfield` retains the two-file package shape. `/commit` emits exactly `references/{atomic-commit.md,commit-message-style.md,output.md}`: the atomic reference owns staged-diff procedure, internal result branching, and commit boundaries, the style reference owns message wording, and the output reference owns human-visible layouts. -- Keep cross-workflow agent-behavior policy such as the no-improvisation and non-SCE helper-composition rules in the shared `renderSkill` preamble of `workflow-composite.pkl`, which every workflow and target already composes through. Its generic control-flow wording says that any workflow-defined user wait resumes the same skill in the same session; workflow-specific wait semantics stay in the owning workflow. Do not copy the same prose into the four canonical `workflow-*.pkl` modules or into per-workflow `references/output.md` bodies, and do not add a strictness knob or per-workflow override for it. +- Author the compact execution contract once in `workflow-content.pkl` and render it inline into change-to-plan, next-task, commit, validate, and handover on all four targets. The first four consume it in their canonical skill bodies; handover consumes it through `workflow-composite.pkl`. Preserve brownfield and package-mode preambles. The standard variant prohibits SCE sibling workflows; only next-task permits `sce-decision` at successful task synchronization. Preserve ordered execution, same-skill/same-session resume, prescribed output, and non-SCE helper boundaries. Keep workflow-specific gates in their owners; do not add a runtime reference or a strictness override. - Keep shared renderer document and plugin-registration contracts in `config/pkl/renderers/common.pkl`; workflow identity metadata belongs in the typed workflow catalog rather than renderer-local description or routing maps. - Keep only actively consumed target metadata in dedicated modules (`opencode-metadata.pkl` and `claude-metadata.pkl`); Pi needs no metadata module because it adds no target-specific frontmatter. - Add OpenCode machine-readable orchestration metadata in `config/pkl/renderers/opencode-content.pkl`: catalog-derived `agent`, `entry-skill`, and a `skills` chain naming that command's single workflow skill. In `opencode-metadata.pkl`, derive ordered agent skill permissions from catalog role assignments: allow `*` for ordinary non-SCE skills, deny `sce-*`, then allow only the role's owned workflow skills; derive the additional `sce-decision` permission only for the Code agent. diff --git a/context/plans/compress-workflow-execution-preamble.md b/context/plans/compress-workflow-execution-preamble.md new file mode 100644 index 000000000..07a2468e9 --- /dev/null +++ b/context/plans/compress-workflow-execution-preamble.md @@ -0,0 +1,257 @@ +# Plan: compress-workflow-execution-preamble + +## Change summary + +Replace the repeated `Purpose`, `User-visible output`, and `Composite control flow` +sections with one shorter `Execution contract` in these five workflow entrypoints: +`sce-change-to-plan`, `sce-next-task`, `sce-commit`, `sce-validate`, and `sce-handover`. +Preserve their behavior, phase boundaries, arguments, permissions, gates, waits, +state transitions, and user-visible output layouts. + +Author the compact contract once in canonical Pkl and render it inline into each +selected skill. Do not introduce a shared runtime skill or an additional Markdown +file that the agent must load. The reduction must occur in the emitted Markdown, +not merely in the Pkl source. + +Planning baseline: `2d14959c6770d3635dfadb457e137c6fc05feba4` on `main`. +This plan covers finding 1 of the workflow duplication audit only. Implementation +and focused generation checks are complete. Full `nix flake check` remains for PR CI. + +## Acceptance criteria + +- [x] AC1: Each selected workflow has exactly one compact `Execution contract` + in generated Pi, Claude, OpenCode, and Codex entrypoints. Its former three + generic preamble sections are absent. Existing phase-reference sections remain. + - Validate: Extend and evaluate `config/pkl/renderers/generation-contract-check.pkl` + through `nix run .#pkl-check-generated`; check all five workflows on all four targets. +- [x] AC2: Every requirement from the removed preamble has an explicit equivalent: + workflow ownership, ordered steps/gates/stops, immediate continuation, defined + waits, same-skill/same-session resume, private phase state, prescribed output, + in-step helper boundaries, and sibling-workflow restrictions. + - Validate: Compare old and new requirements clause by clause. Assert the expected + rendered contract and each workflow's permission variant independently of the + new helper's output. Reject a fixture with an omitted safeguard or wrong variant. +- [x] AC3: Only `sce-next-task` permits `sce-decision`, and only at the successful + context-synchronization decision gate. No other selected workflow gains that + permission. Relevant non-SCE helpers remain permitted without taking control. + - Validate: Check the full generated entrypoints for the correct variant; include + negative fixtures for a missing next-task exception and an exception in validate. +- [x] AC4: Apart from the selected preamble replacements, generated payloads retain + the baseline inventory and content. Phase instructions, reference-loading rules, + input sections, workflow branches, final Rules sections, output/reference files, + frontmatter, commands, hooks, and metadata do not change. Brownfield and the + standalone decision package remain unchanged. + - Validate: Generate baseline and candidate payloads into separate temporary + directories. Compare path inventories and bytes, allowing only the three named + preamble sections to be replaced in the twenty selected SKILL.md files. Compare + phase-reference sections separately when their position changes. +- [x] AC5: For each selected workflow and target, the rendered replacement uses at + least 40% fewer UTF-8 bytes than the combined three removed sections. Report + before/after bytes, words, and nonblank lines, plus total SKILL.md bytes. + - Validate: Measure baseline and candidate generated files with identical section + boundaries and line wrapping. Exclude unchanged phase-reference sections from + the preamble comparison. Do not claim token savings without a named tokenizer. +- [x] AC6: Existing tracked Pi, Claude, and Codex skill mirrors receive the same + targeted preamble change from generated output, without unrelated rewrites or + tracked temporary generation directories. + - Validate: Inspect the Git diff and compare selected mirror preambles with the + corresponding generated target. Preserve all mirror content outside the named + sections, including pre-existing differences unrelated to this change. + +### Full validation + +- `nix run .#pkl-check-generated` +- `nix flake check` +- `git diff --check` +- Inspect baseline/candidate artifact comparison, requirement mapping, negative + fixture results, and rendered-size measurements recorded in task evidence. + +### Context sync + +- `context/sce/dedup-ownership-table.md`: record the compact contract's canonical + owner and preserve the existing owner/consumer boundaries. +- `context/sce/handover-workflow.md`: update its description of the old three-section + shared preamble without changing the writer/loader contract. +- Inspect other affected workflow context for references to the removed preamble + headings. Change only statements made stale by this implementation. +- Normal `/next-task` context synchronization still applies. Do not rewrite existing + architecture decisions or create an ADR merely because wording was shortened. + +## Task context synchronization lifecycle + +Every task carries `Context synchronization: pending | synced | blocked`. +A completed task must be `synced` before another task can start or the plan can +finish. Persist each transition to the plan, not to conversation state. +For `blocked`, record the blocker, required action, and retry condition. + +## Constraints and non-goals + +**In scope:** the three generic preamble sections in the five selected workflows, +a small canonical rendering helper, directly affected rendering call sites, +focused generation assertions, existing tracked mirrors, and corresponding context. + +**Out of scope:** synchronization-debt repair, execution-handoff schemas, approval +logic, decision qualification, task slicing, commit execution, report templates, +phase references, terminal Rules sections, brownfield behavior, and new commands. + +Keep `Phase references` tables and their read-before-action instructions intact. +Preserve target-specific frontmatter and Codex invocation-input wording. +Do not generalize this change into a new workflow framework or runtime dependency. +Do not globally shorten `helperSkillCompositionRule` if doing so changes unselected +consumers such as brownfield or package-mode documents. + +Follow the current repository generation policy: use temporary output roots, keep +`config/.opencode/`, `config/.claude/`, `config/.pi/`, and `cli/assets/generated/` +absent, and do not modify the runtime-managed root `.opencode/` tree. Verify +OpenCode's generated payload without committing that runtime tree. + +## Assumptions + +- "First change" refers to finding 1: the oversized shared execution preamble. +- Existing behavior is the baseline, including unrelated inconsistencies found in + the audit. Fix those in separate changes rather than silently resolving them here. +- Forty percent is a proposed acceptance threshold for this preamble-only change, + not a measured result or a claim about reducing the whole workflow by that amount. +- Generated-source checks establish textual coverage and artifact consistency; + they do not prove identical model behavior. Any agent-run evidence must be + separately labeled with its model, harness, inputs, and observed outcome. + +## Proposed execution contract + +Use the following wording as the implementation starting point. Final wording must +pass the requirement comparison and size checks above. + +```markdown +## Execution contract + +Own this workflow from input through its terminal user-visible response. +Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. +Keep phase results internal and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +Use only the specified `references/output.md` layouts for gates and terminal +responses. Do not expose raw state or add text around a layout. +Non-SCE helpers must return to the active step without changing phase order, +gates, waits, writes, validation, stops, or terminal output. +Do not invoke another SCE skill, package, or workflow command. +``` + +For `sce-next-task`, replace the final sentence, rather than appending a conflicting +unconditional prohibition: + +```markdown +Do not invoke another SCE skill, package, or workflow command except `sce-decision`, +and only from the successful context-synchronization decision gate. +``` + +## Implementation shape + +| Canonical source | Targeted change | +| --- | --- | +| `config/pkl/base/workflow-content.pkl` | Add the small shared contract renderer; use it in `nextTaskSkillBody` and `validateSkillBody`. | +| `config/pkl/base/workflow-change-to-plan.pkl` | Replace the three sections in `changeToPlanSkillBody`. | +| `config/pkl/base/workflow-commit.pkl` | Replace the three sections in `commitSkillBody`. | +| `config/pkl/renderers/workflow-composite.pkl` | Apply the compact contract to handover's generic rendering path; preserve brownfield output. | +| `config/pkl/renderers/generation-contract-check.pkl` | Add focused coverage and update only assertions that intentionally pin replaced wording. | +| `.pi/skills/`, `.claude/skills/`, `.agents/skills/` | Refresh only the selected entrypoint preambles in existing tracked mirrors. | + +Use two explicit contract variants: standard and next-task's decision exception. +Do not inherit the generic renderer's stale next-task-or-validate exception check: +the active validate body prohibits sibling invocation, and that must stay true. +Keep the helper at the source-generation level. Render its text directly into each +skill so loading behavior and the package inventory remain unchanged. + +## Task stack + +- [x] T01: `Compress the five workflow execution preambles without changing behavior` (status:done) + - Task ID: T01 + - Scope: In - the canonical sources, generation assertions, and selected tracked + entrypoint mirrors listed above. Out - all phase logic and other audit findings. + - Dependencies: none + - Done when: AC1-AC6 are covered by the implementation and its focused evidence; + every selected workflow has the compact contract, permissions remain correct, + protected payloads remain unchanged, and the rendered-size target is met. + - Verify: Evaluate the focused generation-contract checks; run the baseline/candidate + payload comparison; inspect the requirement mapping and permission negative + fixtures; measure rendered preamble sizes; run `git diff --check`. + - Completed: 2026-09-08 + - Files changed: `config/pkl/base/workflow-content.pkl`, `config/pkl/base/workflow-change-to-plan.pkl`, `config/pkl/base/workflow-commit.pkl`, `config/pkl/renderers/workflow-composite.pkl`, `config/pkl/renderers/generation-contract-check.pkl`, `.pi/skills/sce-change-to-plan/SKILL.md`, `.pi/skills/sce-next-task/SKILL.md`, `.pi/skills/sce-commit/SKILL.md`, `.pi/skills/sce-validate/SKILL.md`, `.pi/skills/sce-handover/SKILL.md`, `.claude/skills/sce-change-to-plan/SKILL.md`, `.claude/skills/sce-next-task/SKILL.md`, `.claude/skills/sce-commit/SKILL.md`, `.claude/skills/sce-validate/SKILL.md`, `.claude/skills/sce-handover/SKILL.md`, `.agents/skills/sce-change-to-plan/SKILL.md`, `.agents/skills/sce-next-task/SKILL.md`, `.agents/skills/sce-commit/SKILL.md`, `.agents/skills/sce-validate/SKILL.md`, `.agents/skills/sce-handover/SKILL.md`, `context/sce/dedup-ownership-table.md`, `context/sce/handover-workflow.md`, `context/patterns.md`, `context/glossary.md`, `context/plans/compress-workflow-execution-preamble.md`. + - Result: One inline compact contract renders across five workflows and four targets. Protected payloads and mirror content are preserved. + - Verify outcome: All focused generation assertions, negative fixtures, baseline/candidate byte comparisons, deterministic-generation comparisons, and `git diff --check` passed. + - Context impact: local; contract ownership and handover preamble descriptions updated; stale owner statements corrected in patterns and glossary. + - Context synchronization: synced + +Within T01, capture baseline artifacts and requirements before editing, introduce +and wire the shared contract, update directly affected checks, apply the targeted +mirror changes, and record evidence. Source, tests, and mirrors form one coherent +commit unit. Do not add a separate trailing validation or cleanup task. + +## Open questions + +None blocking. The change is limited to reducing duplicated instructions while +preserving their meaning. Revisit the wording rather than removing safeguards if +the proposed size target conflicts with requirement coverage. + +## Source references + +Paths are relative to this plan's intended location under `context/plans/`. + +- [Repository editing and generation policy](../../AGENTS.md) +- [Workflow content model and next-task/validate bodies](../../config/pkl/base/workflow-content.pkl) +- [Composite renderer and alternate rendering paths](../../config/pkl/renderers/workflow-composite.pkl) +- [Generation contract checks and target inventory](../../config/pkl/renderers/generation-contract-check.pkl) +- [Workflow ownership](../sce/dedup-ownership-table.md) + +## Continuation + +Implementation and context synchronization are complete. Final repository validation remains required: + +`/validate context/plans/compress-workflow-execution-preamble.md` + +## Focused verification evidence + +Baseline: `2d14959c6770d3635dfadb457e137c6fc05feba4`. Generated inventory: 141 files; exactly twenty selected entrypoints changed. All other artifacts matched byte-for-byte. Fifteen tracked mirrors matched the generated contract and retained all other content. + +`pkl eval config/pkl/renderers/generation-contract-check.pkl`, `nix run .#pkl-check-generated`, and `git diff --check`: passed. Generation into two independent candidate directories was byte-identical. Full `nix flake check`: not run by preparation; delegated to ordinary PR CI. + +The independent oracle rejected omitted safeguards, missing next-task permission, permission granted to a standard workflow, contradictory prohibition, and duplicate contracts. No model-execution equivalence or tokenizer-based reduction is claimed. + +| Requirement | Compact contract clause | +|---|---| +| Workflow ownership | Own this workflow from input through its terminal user-visible response. | +| Ordered steps, gates, and stops | Follow in order; do not add, skip, reorder, or merge them. | +| Internal state and immediate continuation | Keep phase results internal and continue immediately until a defined wait or stop. | +| Wait/resume ownership | Resume user waits in this same skill and session. | +| Output authority and no extra text | Use only specified output layouts; no raw state or text around a layout. | +| Non-SCE helper permission and boundaries | Helpers may assist, return to the active step, and preserve every listed boundary. | +| Sibling restriction | Standard prohibition; next-task alone permits sce-decision at the successful synchronization gate. | + +Measurements include one trailing newline per selected section, exclude unchanged phase-reference sections, and retain the existing prose wrapping. + +| Target/workflow | Preamble bytes | Words | Nonblank lines | Total SKILL.md bytes | Reduction | +|---|---:|---:|---:|---:|---:| +| `.agents/skills/sce-change-to-plan` | 1375 -> 674 | 206 -> 106 | 21 -> 10 | 10973 -> 10270 | 50.98% | +| `.agents/skills/sce-commit` | 1375 -> 674 | 206 -> 106 | 21 -> 10 | 6873 -> 6170 | 50.98% | +| `.agents/skills/sce-handover` | 1375 -> 674 | 206 -> 106 | 21 -> 10 | 6955 -> 6252 | 50.98% | +| `.agents/skills/sce-next-task` | 1487 -> 764 | 218 -> 116 | 21 -> 11 | 10130 -> 9405 | 48.62% | +| `.agents/skills/sce-validate` | 1375 -> 674 | 206 -> 106 | 20 -> 10 | 4893 -> 4190 | 50.98% | +| `.claude/skills/sce-change-to-plan` | 1375 -> 674 | 206 -> 106 | 21 -> 10 | 10918 -> 10215 | 50.98% | +| `.claude/skills/sce-commit` | 1375 -> 674 | 206 -> 106 | 21 -> 10 | 6846 -> 6143 | 50.98% | +| `.claude/skills/sce-handover` | 1375 -> 674 | 206 -> 106 | 21 -> 10 | 6894 -> 6191 | 50.98% | +| `.claude/skills/sce-next-task` | 1487 -> 764 | 218 -> 116 | 21 -> 11 | 10087 -> 9362 | 48.62% | +| `.claude/skills/sce-validate` | 1375 -> 674 | 206 -> 106 | 20 -> 10 | 4864 -> 4161 | 50.98% | +| `.opencode/skills/sce-change-to-plan` | 1375 -> 674 | 206 -> 106 | 21 -> 10 | 10920 -> 10217 | 50.98% | +| `.opencode/skills/sce-commit` | 1375 -> 674 | 206 -> 106 | 21 -> 10 | 6848 -> 6145 | 50.98% | +| `.opencode/skills/sce-handover` | 1375 -> 674 | 206 -> 106 | 21 -> 10 | 6896 -> 6193 | 50.98% | +| `.opencode/skills/sce-next-task` | 1487 -> 764 | 218 -> 116 | 21 -> 11 | 10089 -> 9364 | 48.62% | +| `.opencode/skills/sce-validate` | 1375 -> 674 | 206 -> 106 | 20 -> 10 | 4866 -> 4163 | 50.98% | +| `.pi/skills/sce-change-to-plan` | 1375 -> 674 | 206 -> 106 | 21 -> 10 | 10896 -> 10193 | 50.98% | +| `.pi/skills/sce-commit` | 1375 -> 674 | 206 -> 106 | 21 -> 10 | 6824 -> 6121 | 50.98% | +| `.pi/skills/sce-handover` | 1375 -> 674 | 206 -> 106 | 21 -> 10 | 6872 -> 6169 | 50.98% | +| `.pi/skills/sce-next-task` | 1487 -> 764 | 218 -> 116 | 21 -> 11 | 10065 -> 9340 | 48.62% | +| `.pi/skills/sce-validate` | 1375 -> 674 | 206 -> 106 | 20 -> 10 | 4842 -> 4139 | 50.98% | + +## Context synchronization evidence + +The five root context files were reviewed for generation and workflow claims affected by this change. `overview.md`, `architecture.md`, and `context-map.md` require no change. `patterns.md` and `glossary.md` now identify the compact contract owner without changing workflow behavior. The existing ownership-table and handover links remain valid; both domain documents describe the implementation. No new feature or qualifying architecture decision was introduced. + +The two additional root edits replace existing text without increasing line counts. No other root context changed. Full repository validation is still pending; successful focused checks do not imply that `nix flake check` has passed. diff --git a/context/sce/dedup-ownership-table.md b/context/sce/dedup-ownership-table.md index 32a940d98..cfaec0dc1 100644 --- a/context/sce/dedup-ownership-table.md +++ b/context/sce/dedup-ownership-table.md @@ -22,6 +22,7 @@ | Final validation and validation report | `sce-validation` in `workflow-validate.pkl` | `/validate`; composed into `sce-validate`; thin OpenCode Code agent | intentional/keep | | Validated-plan durable context synchronization | Retained plan instance from `workflow-context-sync.pkl` | No current workflow consumer; `/validate` is validation-only | retained source, not generated | | Staged-diff analysis and commit-message authoring | `sce-atomic-commit` in `workflow-commit.pkl` | `/commit`; composed into `sce-commit`; thin OpenCode Code agent | intentional/keep | +| Compact workflow execution contract | `executionContract` in `workflow-content.pkl` | Inline in change-to-plan, next-task, commit, validate, and handover entrypoints on all four targets; no extra runtime read | shared rendering, preserved behavior | | Workflow routing | Six command documents in the workflow modules | Thin OpenCode Plan/Code agents | intentional/keep | | Standalone ADR writing contract | `decision-skill.pkl` | Cross-target `sce-decision` package; successful task synchronization invokes it through the shared decision gate | intentional/keep | diff --git a/context/sce/handover-workflow.md b/context/sce/handover-workflow.md index dfda906c9..10be5cd6d 100644 --- a/context/sce/handover-workflow.md +++ b/context/sce/handover-workflow.md @@ -19,10 +19,10 @@ generation, the same as the other four workflows. Unlike the other four workflows, `sce-handover` has no phases: its base module's `structuredComposite.phases` listing is always empty, so its `SKILL.md` never renders an `## Embedded phase behavior` appendix. Composite-mode -rendering (used by every generated target) supplies the shared generic -Purpose / User-visible-output / Composite-control-flow preamble from -`workflow-composite.pkl`, distinct from the skill's own package-mode-only -Purpose text. +rendering (used by every generated target) supplies the compact `Execution contract` +from `executionContract` in `workflow-content.pkl` through `workflow-composite.pkl`. +It preserves the existing control-flow, output, and helper boundaries without an +additional runtime read. Package-mode-only Purpose text is unchanged. The package contains `SKILL.md`, which owns mode routing, writer and loader behavior, `references/handover-template.md`, which owns the persisted document From dafbafbbc7f6ae00f9d879b6d9d621000553efb8 Mon Sep 17 00:00:00 2001 From: David Abram Date: Tue, 8 Sep 2026 08:54:04 +0000 Subject: [PATCH 02/12] config: Deduplicate next-task approval gate --- .agents/skills/sce-next-task/SKILL.md | 16 +-- .../skills/sce-next-task/references/output.md | 13 +-- .../references/task-execution.md | 33 ++---- .claude/skills/sce-next-task/SKILL.md | 16 +-- .../skills/sce-next-task/references/output.md | 13 +-- .../references/task-execution.md | 33 ++---- .pi/skills/sce-next-task/SKILL.md | 16 +-- .pi/skills/sce-next-task/references/output.md | 13 +-- .../references/task-execution.md | 33 ++---- config/pkl/base/workflow-content.pkl | 16 +-- config/pkl/base/workflow-next-task.pkl | 101 ++++-------------- .../compress-workflow-execution-preamble.md | 26 ++++- context/sce/dedup-ownership-table.md | 2 +- 13 files changed, 94 insertions(+), 237 deletions(-) diff --git a/.agents/skills/sce-next-task/SKILL.md b/.agents/skills/sce-next-task/SKILL.md index 2d11f1198..691743b6c 100644 --- a/.agents/skills/sce-next-task/SKILL.md +++ b/.agents/skills/sce-next-task/SKILL.md @@ -101,18 +101,10 @@ action; otherwise it returns `sync_debt`, resolved by the branch above. Read `references/task-execution.md`, then run the **Task execution phase** with the complete `ready` result from the **Plan review phase**. -This phase always shows an implementation gate before it modifies any file, and it -is the only phase permitted to ask the user for confirmation. Both properties are -load-bearing, so reach them through the reference rather than acting from this -summary. - -Branch on `auto-approve`: - -`approved` -> Also pass the `approve` flag. The **Task execution phase** then shows its implementation gate as a summary and proceeds without asking. - -else -> Do not pass the `approve` flag. The **Task execution phase** shows its implementation gate and waits for the user's decision. - -Do not present an additional implementation confirmation. +Pass the `approve` flag only when `auto-approve` is `approved`; otherwise omit it. +The **Task execution phase** owns the implementation gate, approval question, wait, +user-decision handling, and no-edit-before-approval boundary. Do not duplicate that +procedure here or present an additional implementation confirmation. Branch on the execution result. diff --git a/.agents/skills/sce-next-task/references/output.md b/.agents/skills/sce-next-task/references/output.md index b6e772bde..3c4f5e2ab 100644 --- a/.agents/skills/sce-next-task/references/output.md +++ b/.agents/skills/sce-next-task/references/output.md @@ -127,14 +127,5 @@ When the `approve` flag is absent, end with exactly: When the `approve` flag is supplied, omit the question and end after **Verification**. -## Rules - -- Show the gate exactly once for an unchanged task. -- Do not modify files before approval. -- Do not add requirements absent from the reviewed task. -- Do not present multiple competing approaches unless a material decision is - required. -- Do not emit YAML while waiting for the user's answer. Stop after the gate and - wait. -- If the handoff is stale or incomplete, show the known task information and - identify the problem under **Risks or trade-offs**. +If the handoff is stale or incomplete, show the known task information and +identify the problem under **Risks or trade-offs**. diff --git a/.agents/skills/sce-next-task/references/task-execution.md b/.agents/skills/sce-next-task/references/task-execution.md index fe01b5304..975b716f3 100644 --- a/.agents/skills/sce-next-task/references/task-execution.md +++ b/.agents/skills/sce-next-task/references/task-execution.md @@ -6,15 +6,9 @@ application code, and the only one that asks the user for anything. Input: the complete `ready` result from the plan review phase, plus the `approve` flag when the user pre-approved this invocation. -This phase exclusively owns: - -- Presenting the implementation summary. -- Requesting implementation confirmation. -- Implementing the task. -- Running task-level verification. -- Updating the task status and evidence. - -Do not present an additional implementation confirmation anywhere else. +This phase owns the implementation gate and approval lifecycle, then implements, +verifies, and records exactly one approved task. No other phase may ask for implementation +confirmation. The `approve` flag means the user pre-approved this task when invoking the workflow. It suppresses the approval question and the wait. It never suppresses @@ -60,23 +54,12 @@ Do not reconstruct missing material requirements. At the start of the phase, before any file modification, present the task using `references/output.md`. -The gate must be shown even when: - -- The task appears straightforward. -- The workflow believes approval was already implied. -- The handoff is stale or incomplete. -- The user is likely to approve. - -When the `approve` flag is absent, end the gate with exactly one approval -question: - -`Continue with implementation now? (yes/no)` - -Stop and wait for the user's answer. Do not return internal state, and make no -file modifications, until the user has answered. +Always show the gate, including for straightforward, pre-approved, stale, or +incomplete input. `references/output.md` owns its exact content and question text. -When the `approve` flag is supplied, show the gate as a summary, omit the -approval question, do not wait, and continue at step 2.4. +Without `approve`, render the gate's approval question and wait. Do not return +internal state or modify files until the user answers. With `approve`, render the +gate without its question, do not wait, and continue at step 2.4. ## 2.3 Handle the user's decision diff --git a/.claude/skills/sce-next-task/SKILL.md b/.claude/skills/sce-next-task/SKILL.md index 51d3b716b..0d37b04be 100644 --- a/.claude/skills/sce-next-task/SKILL.md +++ b/.claude/skills/sce-next-task/SKILL.md @@ -100,18 +100,10 @@ action; otherwise it returns `sync_debt`, resolved by the branch above. Read `references/task-execution.md`, then run the **Task execution phase** with the complete `ready` result from the **Plan review phase**. -This phase always shows an implementation gate before it modifies any file, and it -is the only phase permitted to ask the user for confirmation. Both properties are -load-bearing, so reach them through the reference rather than acting from this -summary. - -Branch on `auto-approve`: - -`approved` -> Also pass the `approve` flag. The **Task execution phase** then shows its implementation gate as a summary and proceeds without asking. - -else -> Do not pass the `approve` flag. The **Task execution phase** shows its implementation gate and waits for the user's decision. - -Do not present an additional implementation confirmation. +Pass the `approve` flag only when `auto-approve` is `approved`; otherwise omit it. +The **Task execution phase** owns the implementation gate, approval question, wait, +user-decision handling, and no-edit-before-approval boundary. Do not duplicate that +procedure here or present an additional implementation confirmation. Branch on the execution result. diff --git a/.claude/skills/sce-next-task/references/output.md b/.claude/skills/sce-next-task/references/output.md index b6e772bde..3c4f5e2ab 100644 --- a/.claude/skills/sce-next-task/references/output.md +++ b/.claude/skills/sce-next-task/references/output.md @@ -127,14 +127,5 @@ When the `approve` flag is absent, end with exactly: When the `approve` flag is supplied, omit the question and end after **Verification**. -## Rules - -- Show the gate exactly once for an unchanged task. -- Do not modify files before approval. -- Do not add requirements absent from the reviewed task. -- Do not present multiple competing approaches unless a material decision is - required. -- Do not emit YAML while waiting for the user's answer. Stop after the gate and - wait. -- If the handoff is stale or incomplete, show the known task information and - identify the problem under **Risks or trade-offs**. +If the handoff is stale or incomplete, show the known task information and +identify the problem under **Risks or trade-offs**. diff --git a/.claude/skills/sce-next-task/references/task-execution.md b/.claude/skills/sce-next-task/references/task-execution.md index fe01b5304..975b716f3 100644 --- a/.claude/skills/sce-next-task/references/task-execution.md +++ b/.claude/skills/sce-next-task/references/task-execution.md @@ -6,15 +6,9 @@ application code, and the only one that asks the user for anything. Input: the complete `ready` result from the plan review phase, plus the `approve` flag when the user pre-approved this invocation. -This phase exclusively owns: - -- Presenting the implementation summary. -- Requesting implementation confirmation. -- Implementing the task. -- Running task-level verification. -- Updating the task status and evidence. - -Do not present an additional implementation confirmation anywhere else. +This phase owns the implementation gate and approval lifecycle, then implements, +verifies, and records exactly one approved task. No other phase may ask for implementation +confirmation. The `approve` flag means the user pre-approved this task when invoking the workflow. It suppresses the approval question and the wait. It never suppresses @@ -60,23 +54,12 @@ Do not reconstruct missing material requirements. At the start of the phase, before any file modification, present the task using `references/output.md`. -The gate must be shown even when: - -- The task appears straightforward. -- The workflow believes approval was already implied. -- The handoff is stale or incomplete. -- The user is likely to approve. - -When the `approve` flag is absent, end the gate with exactly one approval -question: - -`Continue with implementation now? (yes/no)` - -Stop and wait for the user's answer. Do not return internal state, and make no -file modifications, until the user has answered. +Always show the gate, including for straightforward, pre-approved, stale, or +incomplete input. `references/output.md` owns its exact content and question text. -When the `approve` flag is supplied, show the gate as a summary, omit the -approval question, do not wait, and continue at step 2.4. +Without `approve`, render the gate's approval question and wait. Do not return +internal state or modify files until the user answers. With `approve`, render the +gate without its question, do not wait, and continue at step 2.4. ## 2.3 Handle the user's decision diff --git a/.pi/skills/sce-next-task/SKILL.md b/.pi/skills/sce-next-task/SKILL.md index 0f37cc458..f0eb84c60 100644 --- a/.pi/skills/sce-next-task/SKILL.md +++ b/.pi/skills/sce-next-task/SKILL.md @@ -99,18 +99,10 @@ action; otherwise it returns `sync_debt`, resolved by the branch above. Read `references/task-execution.md`, then run the **Task execution phase** with the complete `ready` result from the **Plan review phase**. -This phase always shows an implementation gate before it modifies any file, and it -is the only phase permitted to ask the user for confirmation. Both properties are -load-bearing, so reach them through the reference rather than acting from this -summary. - -Branch on `auto-approve`: - -`approved` -> Also pass the `approve` flag. The **Task execution phase** then shows its implementation gate as a summary and proceeds without asking. - -else -> Do not pass the `approve` flag. The **Task execution phase** shows its implementation gate and waits for the user's decision. - -Do not present an additional implementation confirmation. +Pass the `approve` flag only when `auto-approve` is `approved`; otherwise omit it. +The **Task execution phase** owns the implementation gate, approval question, wait, +user-decision handling, and no-edit-before-approval boundary. Do not duplicate that +procedure here or present an additional implementation confirmation. Branch on the execution result. diff --git a/.pi/skills/sce-next-task/references/output.md b/.pi/skills/sce-next-task/references/output.md index b6e772bde..3c4f5e2ab 100644 --- a/.pi/skills/sce-next-task/references/output.md +++ b/.pi/skills/sce-next-task/references/output.md @@ -127,14 +127,5 @@ When the `approve` flag is absent, end with exactly: When the `approve` flag is supplied, omit the question and end after **Verification**. -## Rules - -- Show the gate exactly once for an unchanged task. -- Do not modify files before approval. -- Do not add requirements absent from the reviewed task. -- Do not present multiple competing approaches unless a material decision is - required. -- Do not emit YAML while waiting for the user's answer. Stop after the gate and - wait. -- If the handoff is stale or incomplete, show the known task information and - identify the problem under **Risks or trade-offs**. +If the handoff is stale or incomplete, show the known task information and +identify the problem under **Risks or trade-offs**. diff --git a/.pi/skills/sce-next-task/references/task-execution.md b/.pi/skills/sce-next-task/references/task-execution.md index fe01b5304..975b716f3 100644 --- a/.pi/skills/sce-next-task/references/task-execution.md +++ b/.pi/skills/sce-next-task/references/task-execution.md @@ -6,15 +6,9 @@ application code, and the only one that asks the user for anything. Input: the complete `ready` result from the plan review phase, plus the `approve` flag when the user pre-approved this invocation. -This phase exclusively owns: - -- Presenting the implementation summary. -- Requesting implementation confirmation. -- Implementing the task. -- Running task-level verification. -- Updating the task status and evidence. - -Do not present an additional implementation confirmation anywhere else. +This phase owns the implementation gate and approval lifecycle, then implements, +verifies, and records exactly one approved task. No other phase may ask for implementation +confirmation. The `approve` flag means the user pre-approved this task when invoking the workflow. It suppresses the approval question and the wait. It never suppresses @@ -60,23 +54,12 @@ Do not reconstruct missing material requirements. At the start of the phase, before any file modification, present the task using `references/output.md`. -The gate must be shown even when: - -- The task appears straightforward. -- The workflow believes approval was already implied. -- The handoff is stale or incomplete. -- The user is likely to approve. - -When the `approve` flag is absent, end the gate with exactly one approval -question: - -`Continue with implementation now? (yes/no)` - -Stop and wait for the user's answer. Do not return internal state, and make no -file modifications, until the user has answered. +Always show the gate, including for straightforward, pre-approved, stale, or +incomplete input. `references/output.md` owns its exact content and question text. -When the `approve` flag is supplied, show the gate as a summary, omit the -approval question, do not wait, and continue at step 2.4. +Without `approve`, render the gate's approval question and wait. Do not return +internal state or modify files until the user answers. With `approve`, render the +gate without its question, do not wait, and continue at step 2.4. ## 2.3 Handle the user's decision diff --git a/config/pkl/base/workflow-content.pkl b/config/pkl/base/workflow-content.pkl index e9e5b6fef..356a4faf7 100644 --- a/config/pkl/base/workflow-content.pkl +++ b/config/pkl/base/workflow-content.pkl @@ -316,18 +316,10 @@ action; otherwise it returns `sync_debt`, resolved by the branch above. Read `references/task-execution.md`, then run the **Task execution phase** with the complete `ready` result from the **Plan review phase**. -This phase always shows an implementation gate before it modifies any file, and it -is the only phase permitted to ask the user for confirmation. Both properties are -load-bearing, so reach them through the reference rather than acting from this -summary. - -Branch on `auto-approve`: - -`approved` -> Also pass the `approve` flag. The **Task execution phase** then shows its implementation gate as a summary and proceeds without asking. - -else -> Do not pass the `approve` flag. The **Task execution phase** shows its implementation gate and waits for the user's decision. - -Do not present an additional implementation confirmation. +Pass the `approve` flag only when `auto-approve` is `approved`; otherwise omit it. +The **Task execution phase** owns the implementation gate, approval question, wait, +user-decision handling, and no-edit-before-approval boundary. Do not duplicate that +procedure here or present an additional implementation confirmation. Branch on the execution result. diff --git a/config/pkl/base/workflow-next-task.pkl b/config/pkl/base/workflow-next-task.pkl index 43153aca7..73d47764b 100644 --- a/config/pkl/base/workflow-next-task.pkl +++ b/config/pkl/base/workflow-next-task.pkl @@ -285,21 +285,11 @@ local renderCommandBody = (mode: model.WorkflowRenderMode) -> """ \(invoke.render.apply(mode)) \(taskExecution.render.apply(mode)) with the complete `ready` result from \(planReview.render.apply(mode)). - Branch on `auto-approve`: - - `approved` -> Also pass the `approve` flag. \(taskExecutionUpper.render.apply(mode)) then shows its implementation gate as a summary and proceeds without asking. - - else -> Do not pass the `approve` flag. \(taskExecutionUpper.render.apply(mode)) shows its implementation gate and waits for the user's decision. - - \(taskExecutionUpper.render.apply(mode)) exclusively owns: - - - Presenting the implementation summary. - - Requesting implementation confirmation. - - Implementing the task. - - Running task-level verification. - - Updating the task status and evidence. - - Do not present an additional implementation confirmation. + Pass the `approve` flag only when `auto-approve` is `approved`; otherwise omit it. + \(taskExecutionUpper.render.apply(mode)) exclusively owns the implementation gate, + approval question, wait, decision handling, implementation, task-level verification, + and task-status/evidence update. Do not duplicate that procedure here or present an + additional implementation confirmation. \(model.inlinePhaseBody.apply(executionSkillBody).render.apply(mode))Branch on the execution result. @@ -888,23 +878,13 @@ local renderExecutionSkillBody = (mode: model.WorkflowRenderMode) -> """ At the start of the phase, before any file modification, present the task using \(implementationGate.render.apply(mode)). - The gate must be shown even when: - - - The task appears straightforward. - - The workflow believes approval was already implied. - - The handoff is stale or incomplete. - - The user is likely to approve. - - When the `approve` flag is absent, end the gate with exactly one approval - question: - - `Continue with implementation now? (yes/no)` - - Stop and wait for the user's answer. Do not \(returnYamlLower.render.apply(mode)), and make no file - modifications, until the user has answered. + Always show the gate, including for straightforward, pre-approved, stale, or + incomplete input. `references/output.md` owns its exact content and question text. - When the `approve` flag is supplied, show the gate as a summary, omit the - approval question, do not wait, and continue at \(taskExecutionHeadings.stepReference.apply(mode, 4)). + Without `approve`, render the gate's approval question and wait. Do not + \(returnYamlLower.render.apply(mode)) or modify files until the user answers. With `approve`, render + the gate without its question, do not wait, and continue at + \(taskExecutionHeadings.stepReference.apply(mode, 4)). \(taskExecutionHeadings.stepHeading.apply(mode, 3, "Handle the user's decision")) @@ -1474,17 +1454,8 @@ local renderImplementationGate = (mode: model.WorkflowRenderMode) -> """ When the `approve` flag is supplied, omit the question and end after **Verification**. - ## Rules - - - Show the gate exactly once for an unchanged task. - - Do not modify files before approval. - - Do not add requirements absent from the reviewed task. - - Do not present multiple competing approaches unless a material decision is - required. - - Do not emit YAML while waiting for the user's answer. Stop after the gate and - wait. - - If the handoff is stale or incomplete, show the known task information and - identify the problem under **Risks or trade-offs**. + If the handoff is stale or incomplete, show the known task information and + identify the problem under **Risks or trade-offs**. """ local IMPLEMENTATION_GATE = renderImplementationGate.apply("package") @@ -1652,15 +1623,9 @@ application code, and the only one that asks the user for anything. Input: the complete `ready` result from the plan review phase, plus the `approve` flag when the user pre-approved this invocation. -This phase exclusively owns: - -- Presenting the implementation summary. -- Requesting implementation confirmation. -- Implementing the task. -- Running task-level verification. -- Updating the task status and evidence. - -Do not present an additional implementation confirmation anywhere else. +This phase owns the implementation gate and approval lifecycle, then implements, +verifies, and records exactly one approved task. No other phase may ask for implementation +confirmation. The `approve` flag means the user pre-approved this task when invoking the workflow. It suppresses the approval question and the wait. It never suppresses @@ -1706,23 +1671,12 @@ Do not reconstruct missing material requirements. At the start of the phase, before any file modification, present the task using `references/output.md`. -The gate must be shown even when: - -- The task appears straightforward. -- The workflow believes approval was already implied. -- The handoff is stale or incomplete. -- The user is likely to approve. - -When the `approve` flag is absent, end the gate with exactly one approval -question: - -`Continue with implementation now? (yes/no)` - -Stop and wait for the user's answer. Do not return internal state, and make no -file modifications, until the user has answered. +Always show the gate, including for straightforward, pre-approved, stale, or +incomplete input. `references/output.md` owns its exact content and question text. -When the `approve` flag is supplied, show the gate as a summary, omit the -approval question, do not wait, and continue at step 2.4. +Without `approve`, render the gate's approval question and wait. Do not return +internal state or modify files until the user answers. With `approve`, render the +gate without its question, do not wait, and continue at step 2.4. ## 2.3 Handle the user's decision @@ -2022,17 +1976,8 @@ When the `approve` flag is absent, end with exactly: When the `approve` flag is supplied, omit the question and end after **Verification**. -## Rules - -- Show the gate exactly once for an unchanged task. -- Do not modify files before approval. -- Do not add requirements absent from the reviewed task. -- Do not present multiple competing approaches unless a material decision is - required. -- Do not emit YAML while waiting for the user's answer. Stop after the gate and - wait. -- If the handoff is stale or incomplete, show the known task information and - identify the problem under **Risks or trade-offs**. +If the handoff is stale or incomplete, show the known task information and +identify the problem under **Risks or trade-offs**. """ structuredComposite = new model.StructuredCompositeSource { diff --git a/context/plans/compress-workflow-execution-preamble.md b/context/plans/compress-workflow-execution-preamble.md index 07a2468e9..01cd02d64 100644 --- a/context/plans/compress-workflow-execution-preamble.md +++ b/context/plans/compress-workflow-execution-preamble.md @@ -14,8 +14,11 @@ file that the agent must load. The reduction must occur in the emitted Markdown, not merely in the Pkl source. Planning baseline: `2d14959c6770d3635dfadb457e137c6fc05feba4` on `main`. -This plan covers finding 1 of the workflow duplication audit only. Implementation -and focused generation checks are complete. Full `nix flake check` remains for PR CI. +This plan started with finding 1 of the workflow duplication audit. PR #270 now also +contains a separate follow-up commit for the next-task approval-gate duplication: the +entrypoint routes the optional approval flag, task execution owns approval behavior, and +`references/output.md` owns only the exact gate layout/question. Full `nix flake check` +remains for PR CI. ## Acceptance criteria @@ -255,3 +258,22 @@ Measurements include one trailing newline per selected section, exclude unchange The five root context files were reviewed for generation and workflow claims affected by this change. `overview.md`, `architecture.md`, and `context-map.md` require no change. `patterns.md` and `glossary.md` now identify the compact contract owner without changing workflow behavior. The existing ownership-table and handover links remain valid; both domain documents describe the implementation. No new feature or qualifying architecture decision was introduced. The two additional root edits replace existing text without increasing line counts. No other root context changed. Full repository validation is still pending; successful focused checks do not imply that `nix flake check` has passed. + +## Follow-up: approval-gate ownership deduplication + +- [x] T02: `Deduplicate next-task approval-gate procedure` (status:done) + - Scope: `sce-next-task` entrypoint, task-execution reference, output reference, + canonical Pkl source, generation assertions, tracked Pi/Claude/Codex mirrors, + and the ownership table. + - Ownership after change: the entrypoint parses `approved` and conditionally passes + `approve`; task execution exclusively owns show/wait/approve/decline/block and + the no-edit-before-approval boundary; `references/output.md` owns the gate field + order and exact approval question only. + - Behavior preserved: the gate is always shown, pre-approval never skips it, the + non-preapproved path waits in the same workflow, ambiguous answers may ask the + same question once more, rejection returns `declined`, and editing remains + forbidden before approval. + - Verify: existing generation contracts pass; rendered package inspection confirms + the exact approval question remains in `references/output.md`, not `SKILL.md` or + `task-execution.md`; generated inventory stays unchanged. + - Context synchronization: synced. diff --git a/context/sce/dedup-ownership-table.md b/context/sce/dedup-ownership-table.md index cfaec0dc1..f83750363 100644 --- a/context/sce/dedup-ownership-table.md +++ b/context/sce/dedup-ownership-table.md @@ -17,7 +17,7 @@ | Context discovery before planning | `sce-context-load` in `workflow-change-to-plan.pkl` | `/change-to-plan`; composed into `sce-change-to-plan` | intentional/keep | | Plan authoring, clarification, and task slicing | `sce-plan-authoring` in `workflow-change-to-plan.pkl` | `/change-to-plan`; composed into `sce-change-to-plan`; thin OpenCode Plan agent | intentional/keep | | Task resolution and readiness | `sce-plan-review` in `workflow-next-task.pkl` | `/next-task`; composed into `sce-next-task`; thin OpenCode Code agent | intentional/keep | -| Approval-gated one-task implementation | `sce-task-execution` in `workflow-next-task.pkl` | `/next-task`; composed into `sce-next-task`; thin OpenCode Code agent | intentional/keep | +| Approval-gated one-task implementation | `sce-task-execution` in `workflow-next-task.pkl` | `/next-task` parses and conditionally passes `approve`; `references/output.md` owns only exact gate content/order; composed into `sce-next-task`; thin OpenCode Code agent | intentional/keep | | Post-task durable context synchronization | Task instance from `workflow-context-sync.pkl` | `/next-task`; composed into `sce-next-task` | dedup/shared skeleton | | Final validation and validation report | `sce-validation` in `workflow-validate.pkl` | `/validate`; composed into `sce-validate`; thin OpenCode Code agent | intentional/keep | | Validated-plan durable context synchronization | Retained plan instance from `workflow-context-sync.pkl` | No current workflow consumer; `/validate` is validation-only | retained source, not generated | From 5bcf5888a2d3eae10e10ce410d9c3cc53b078b94 Mon Sep 17 00:00:00 2001 From: David Abram Date: Tue, 8 Sep 2026 09:24:35 +0000 Subject: [PATCH 03/12] config: Deduplicate next-task execution handoff --- .agents/skills/sce-next-task/SKILL.md | 5 +- .../sce-next-task/references/context-sync.md | 58 +++++++------------ .../references/task-execution.md | 18 +++--- .claude/skills/sce-next-task/SKILL.md | 5 +- .../sce-next-task/references/context-sync.md | 58 +++++++------------ .../references/task-execution.md | 18 +++--- .pi/skills/sce-next-task/SKILL.md | 5 +- .../sce-next-task/references/context-sync.md | 58 +++++++------------ .../references/task-execution.md | 18 +++--- config/pkl/base/workflow-content.pkl | 5 +- config/pkl/base/workflow-context-sync.pkl | 58 +++++++------------ config/pkl/base/workflow-next-task.pkl | 18 +++--- .../compress-workflow-execution-preamble.md | 21 +++++++ context/sce/dedup-ownership-table.md | 1 + 14 files changed, 146 insertions(+), 200 deletions(-) diff --git a/.agents/skills/sce-next-task/SKILL.md b/.agents/skills/sce-next-task/SKILL.md index 691743b6c..ef400e215 100644 --- a/.agents/skills/sce-next-task/SKILL.md +++ b/.agents/skills/sce-next-task/SKILL.md @@ -122,9 +122,8 @@ Read `references/context-sync.md`, then run the **Task context synchronization phase** with the complete `complete` result returned by the **Task execution phase**. -Pass that result verbatim. It is the authoritative handoff, and the **Task context synchronization phase** owns reading the plan, task, changed files, verification evidence, and reported context impact out of it. - -Do not restate, summarize, or reconstruct any part of the execution result. +Pass that `complete` result verbatim as the authoritative live handoff to the +**Task context synchronization phase**. Do not restate, summarize, or reconstruct it. This phase verifies the five root context files on every invocation, whatever the change's reported impact, so it is never correct to skip it as unnecessary. diff --git a/.agents/skills/sce-next-task/references/context-sync.md b/.agents/skills/sce-next-task/references/context-sync.md index 30ec3eaee..2fd09db6f 100644 --- a/.agents/skills/sce-next-task/references/context-sync.md +++ b/.agents/skills/sce-next-task/references/context-sync.md @@ -10,18 +10,14 @@ Input: either the complete `complete` result from the task execution phase recovery step resolved for a `blocked` task, together with that task's own completed record — read directly from the plan — and its persisted `Context synchronization blocker` when present (cross-session retry). Whichever was -supplied is the authoritative source, and this phase owns reading the plan, -task, changed files, verification evidence, and reported context impact out -of it. +supplied is authoritative; this phase consumes it without redefining its shape. Do not restate, summarize, or reconstruct any part of it. Do not reconstruct a missing execution result or completed task record from conversation history. -A live execution result must have: - -```text -status: complete -``` +A live execution result must have `status: complete` and satisfy the complete +handoff contract in `references/task-execution.md`. Consume it verbatim; do not +redefine or reconstruct its fields here. A cross-session retry has no separate `status` field to check; the completed task record's presence in the plan, identified by plan path and task ID, is @@ -31,40 +27,30 @@ Use the report format in: `references/sync-report.md` -Treat whichever source was supplied — the live execution result, or the -completed task record read directly from the plan — as the authoritative -source for: - -- The resolved plan and completed task. -- `changes.files_changed`, or the completed task record's own `Files changed` - field on retry, already attributed relative to the pre-edit Git baseline. -- Files changed by implementation. -- The task's `Result` (or implementation summary, for a live result). -- `Verify` outcomes (or verification evidence, for a live result). -- Done-check evidence. -- Reported context impact. +For a cross-session retry, treat the completed task record read directly from +the plan as authoritative for task identity, `Files changed`, `Result`, `Verify` +outcomes, done-check evidence, and reported context impact. Its `Files changed` +field remains the pre-edit-baseline-relative attribution; do not replace it with +a whole-working-tree scan or a fresh diff against `HEAD`. This phase must not be run for `declined`, `blocked`, or `incomplete` execution results. ## 3.1 Validate the handoff -Confirm that: - -- A live execution result has `status` exactly `complete`; a cross-session - retry has no `status` field to check and is authoritative by the completed - task record's presence in the plan. -- A resolved plan path and task ID are present; a live execution result - carries them in its `plan` and `task` objects, and a cross-session retry - receives them directly from the caller that resolved the debt task. -- Exactly one completed task is identified, and — on retry — its record is - read directly from the plan by that plan path and task ID rather than - reconstructed in-band. -- Changed files and a `Result` (an implementation summary, for a live result) - are present. -- `Verify` outcomes (verification evidence, for a live result) are present. -- Done-check evidence is present. -- A context-impact classification is present. +For a live execution result, confirm `status` is exactly `complete` and the +result satisfies the complete handoff contract in `references/task-execution.md`. +Do not reconstruct missing fields. + +For a cross-session retry, confirm that: + +- A resolved plan path and task ID are present. +- Exactly one completed task record is read directly from the plan by that plan + path and task ID rather than reconstructed in-band. +- Its `Files changed` field is present as the pre-edit-baseline-relative + changed-file list. +- `Result`, `Verify` outcomes, done-check evidence, and a context-impact + classification are present. If the required information is missing, the completed task record cannot be read from the plan, or either is internally contradictory, do not modify diff --git a/.agents/skills/sce-next-task/references/task-execution.md b/.agents/skills/sce-next-task/references/task-execution.md index 975b716f3..77009315b 100644 --- a/.agents/skills/sce-next-task/references/task-execution.md +++ b/.agents/skills/sce-next-task/references/task-execution.md @@ -191,13 +191,11 @@ Set internal status `blocked` for every other non-successful outcome, including: Do not determine whether the plan is complete. The `/next-task` workflow owns that decision after context synchronization. -Before determining terminal status for a `complete` result, verify that the -handoff contains the resolved plan, task identity, baseline-relative changed -files, implementation summary, verification evidence, done-check evidence, plan -update, and context-impact classification listed above. The mandatory five-root- -file context pass remains required for every completed task, regardless of the -reported context-impact classification, because it is cheap, deterministic, and -load-bearing for context accuracy; `context_impact` must not be used to waive it. +Before returning a `complete` result, verify that it satisfies the authoritative +handoff contract above. The mandatory five-root-file context pass remains required +for every completed task, regardless of the reported context-impact classification, +because it is cheap, deterministic, and load-bearing for context accuracy; +`context_impact` must not be used to waive it. ## 2.9 Return internal state @@ -205,10 +203,8 @@ After the phase reaches a terminal state, set exactly one internal state. Record only the internal state. Do not add explanatory prose before or after it. -A `complete` result is the authoritative handoff into step 3, which reads the -plan, completed task, changed files, implementation summary, verification -evidence, done-check evidence, and context-impact classification out of it. Step -3 is forbidden from reconstructing any of that, so it has to be present here. +A `complete` result is the authoritative handoff into step 3. Pass it unchanged; +step 3 must consume it instead of reconstructing its fields. ## Task execution boundaries diff --git a/.claude/skills/sce-next-task/SKILL.md b/.claude/skills/sce-next-task/SKILL.md index 0d37b04be..cb19fecba 100644 --- a/.claude/skills/sce-next-task/SKILL.md +++ b/.claude/skills/sce-next-task/SKILL.md @@ -121,9 +121,8 @@ Read `references/context-sync.md`, then run the **Task context synchronization phase** with the complete `complete` result returned by the **Task execution phase**. -Pass that result verbatim. It is the authoritative handoff, and the **Task context synchronization phase** owns reading the plan, task, changed files, verification evidence, and reported context impact out of it. - -Do not restate, summarize, or reconstruct any part of the execution result. +Pass that `complete` result verbatim as the authoritative live handoff to the +**Task context synchronization phase**. Do not restate, summarize, or reconstruct it. This phase verifies the five root context files on every invocation, whatever the change's reported impact, so it is never correct to skip it as unnecessary. diff --git a/.claude/skills/sce-next-task/references/context-sync.md b/.claude/skills/sce-next-task/references/context-sync.md index 30ec3eaee..2fd09db6f 100644 --- a/.claude/skills/sce-next-task/references/context-sync.md +++ b/.claude/skills/sce-next-task/references/context-sync.md @@ -10,18 +10,14 @@ Input: either the complete `complete` result from the task execution phase recovery step resolved for a `blocked` task, together with that task's own completed record — read directly from the plan — and its persisted `Context synchronization blocker` when present (cross-session retry). Whichever was -supplied is the authoritative source, and this phase owns reading the plan, -task, changed files, verification evidence, and reported context impact out -of it. +supplied is authoritative; this phase consumes it without redefining its shape. Do not restate, summarize, or reconstruct any part of it. Do not reconstruct a missing execution result or completed task record from conversation history. -A live execution result must have: - -```text -status: complete -``` +A live execution result must have `status: complete` and satisfy the complete +handoff contract in `references/task-execution.md`. Consume it verbatim; do not +redefine or reconstruct its fields here. A cross-session retry has no separate `status` field to check; the completed task record's presence in the plan, identified by plan path and task ID, is @@ -31,40 +27,30 @@ Use the report format in: `references/sync-report.md` -Treat whichever source was supplied — the live execution result, or the -completed task record read directly from the plan — as the authoritative -source for: - -- The resolved plan and completed task. -- `changes.files_changed`, or the completed task record's own `Files changed` - field on retry, already attributed relative to the pre-edit Git baseline. -- Files changed by implementation. -- The task's `Result` (or implementation summary, for a live result). -- `Verify` outcomes (or verification evidence, for a live result). -- Done-check evidence. -- Reported context impact. +For a cross-session retry, treat the completed task record read directly from +the plan as authoritative for task identity, `Files changed`, `Result`, `Verify` +outcomes, done-check evidence, and reported context impact. Its `Files changed` +field remains the pre-edit-baseline-relative attribution; do not replace it with +a whole-working-tree scan or a fresh diff against `HEAD`. This phase must not be run for `declined`, `blocked`, or `incomplete` execution results. ## 3.1 Validate the handoff -Confirm that: - -- A live execution result has `status` exactly `complete`; a cross-session - retry has no `status` field to check and is authoritative by the completed - task record's presence in the plan. -- A resolved plan path and task ID are present; a live execution result - carries them in its `plan` and `task` objects, and a cross-session retry - receives them directly from the caller that resolved the debt task. -- Exactly one completed task is identified, and — on retry — its record is - read directly from the plan by that plan path and task ID rather than - reconstructed in-band. -- Changed files and a `Result` (an implementation summary, for a live result) - are present. -- `Verify` outcomes (verification evidence, for a live result) are present. -- Done-check evidence is present. -- A context-impact classification is present. +For a live execution result, confirm `status` is exactly `complete` and the +result satisfies the complete handoff contract in `references/task-execution.md`. +Do not reconstruct missing fields. + +For a cross-session retry, confirm that: + +- A resolved plan path and task ID are present. +- Exactly one completed task record is read directly from the plan by that plan + path and task ID rather than reconstructed in-band. +- Its `Files changed` field is present as the pre-edit-baseline-relative + changed-file list. +- `Result`, `Verify` outcomes, done-check evidence, and a context-impact + classification are present. If the required information is missing, the completed task record cannot be read from the plan, or either is internally contradictory, do not modify diff --git a/.claude/skills/sce-next-task/references/task-execution.md b/.claude/skills/sce-next-task/references/task-execution.md index 975b716f3..77009315b 100644 --- a/.claude/skills/sce-next-task/references/task-execution.md +++ b/.claude/skills/sce-next-task/references/task-execution.md @@ -191,13 +191,11 @@ Set internal status `blocked` for every other non-successful outcome, including: Do not determine whether the plan is complete. The `/next-task` workflow owns that decision after context synchronization. -Before determining terminal status for a `complete` result, verify that the -handoff contains the resolved plan, task identity, baseline-relative changed -files, implementation summary, verification evidence, done-check evidence, plan -update, and context-impact classification listed above. The mandatory five-root- -file context pass remains required for every completed task, regardless of the -reported context-impact classification, because it is cheap, deterministic, and -load-bearing for context accuracy; `context_impact` must not be used to waive it. +Before returning a `complete` result, verify that it satisfies the authoritative +handoff contract above. The mandatory five-root-file context pass remains required +for every completed task, regardless of the reported context-impact classification, +because it is cheap, deterministic, and load-bearing for context accuracy; +`context_impact` must not be used to waive it. ## 2.9 Return internal state @@ -205,10 +203,8 @@ After the phase reaches a terminal state, set exactly one internal state. Record only the internal state. Do not add explanatory prose before or after it. -A `complete` result is the authoritative handoff into step 3, which reads the -plan, completed task, changed files, implementation summary, verification -evidence, done-check evidence, and context-impact classification out of it. Step -3 is forbidden from reconstructing any of that, so it has to be present here. +A `complete` result is the authoritative handoff into step 3. Pass it unchanged; +step 3 must consume it instead of reconstructing its fields. ## Task execution boundaries diff --git a/.pi/skills/sce-next-task/SKILL.md b/.pi/skills/sce-next-task/SKILL.md index f0eb84c60..52d9bc22d 100644 --- a/.pi/skills/sce-next-task/SKILL.md +++ b/.pi/skills/sce-next-task/SKILL.md @@ -120,9 +120,8 @@ Read `references/context-sync.md`, then run the **Task context synchronization phase** with the complete `complete` result returned by the **Task execution phase**. -Pass that result verbatim. It is the authoritative handoff, and the **Task context synchronization phase** owns reading the plan, task, changed files, verification evidence, and reported context impact out of it. - -Do not restate, summarize, or reconstruct any part of the execution result. +Pass that `complete` result verbatim as the authoritative live handoff to the +**Task context synchronization phase**. Do not restate, summarize, or reconstruct it. This phase verifies the five root context files on every invocation, whatever the change's reported impact, so it is never correct to skip it as unnecessary. diff --git a/.pi/skills/sce-next-task/references/context-sync.md b/.pi/skills/sce-next-task/references/context-sync.md index 30ec3eaee..2fd09db6f 100644 --- a/.pi/skills/sce-next-task/references/context-sync.md +++ b/.pi/skills/sce-next-task/references/context-sync.md @@ -10,18 +10,14 @@ Input: either the complete `complete` result from the task execution phase recovery step resolved for a `blocked` task, together with that task's own completed record — read directly from the plan — and its persisted `Context synchronization blocker` when present (cross-session retry). Whichever was -supplied is the authoritative source, and this phase owns reading the plan, -task, changed files, verification evidence, and reported context impact out -of it. +supplied is authoritative; this phase consumes it without redefining its shape. Do not restate, summarize, or reconstruct any part of it. Do not reconstruct a missing execution result or completed task record from conversation history. -A live execution result must have: - -```text -status: complete -``` +A live execution result must have `status: complete` and satisfy the complete +handoff contract in `references/task-execution.md`. Consume it verbatim; do not +redefine or reconstruct its fields here. A cross-session retry has no separate `status` field to check; the completed task record's presence in the plan, identified by plan path and task ID, is @@ -31,40 +27,30 @@ Use the report format in: `references/sync-report.md` -Treat whichever source was supplied — the live execution result, or the -completed task record read directly from the plan — as the authoritative -source for: - -- The resolved plan and completed task. -- `changes.files_changed`, or the completed task record's own `Files changed` - field on retry, already attributed relative to the pre-edit Git baseline. -- Files changed by implementation. -- The task's `Result` (or implementation summary, for a live result). -- `Verify` outcomes (or verification evidence, for a live result). -- Done-check evidence. -- Reported context impact. +For a cross-session retry, treat the completed task record read directly from +the plan as authoritative for task identity, `Files changed`, `Result`, `Verify` +outcomes, done-check evidence, and reported context impact. Its `Files changed` +field remains the pre-edit-baseline-relative attribution; do not replace it with +a whole-working-tree scan or a fresh diff against `HEAD`. This phase must not be run for `declined`, `blocked`, or `incomplete` execution results. ## 3.1 Validate the handoff -Confirm that: - -- A live execution result has `status` exactly `complete`; a cross-session - retry has no `status` field to check and is authoritative by the completed - task record's presence in the plan. -- A resolved plan path and task ID are present; a live execution result - carries them in its `plan` and `task` objects, and a cross-session retry - receives them directly from the caller that resolved the debt task. -- Exactly one completed task is identified, and — on retry — its record is - read directly from the plan by that plan path and task ID rather than - reconstructed in-band. -- Changed files and a `Result` (an implementation summary, for a live result) - are present. -- `Verify` outcomes (verification evidence, for a live result) are present. -- Done-check evidence is present. -- A context-impact classification is present. +For a live execution result, confirm `status` is exactly `complete` and the +result satisfies the complete handoff contract in `references/task-execution.md`. +Do not reconstruct missing fields. + +For a cross-session retry, confirm that: + +- A resolved plan path and task ID are present. +- Exactly one completed task record is read directly from the plan by that plan + path and task ID rather than reconstructed in-band. +- Its `Files changed` field is present as the pre-edit-baseline-relative + changed-file list. +- `Result`, `Verify` outcomes, done-check evidence, and a context-impact + classification are present. If the required information is missing, the completed task record cannot be read from the plan, or either is internally contradictory, do not modify diff --git a/.pi/skills/sce-next-task/references/task-execution.md b/.pi/skills/sce-next-task/references/task-execution.md index 975b716f3..77009315b 100644 --- a/.pi/skills/sce-next-task/references/task-execution.md +++ b/.pi/skills/sce-next-task/references/task-execution.md @@ -191,13 +191,11 @@ Set internal status `blocked` for every other non-successful outcome, including: Do not determine whether the plan is complete. The `/next-task` workflow owns that decision after context synchronization. -Before determining terminal status for a `complete` result, verify that the -handoff contains the resolved plan, task identity, baseline-relative changed -files, implementation summary, verification evidence, done-check evidence, plan -update, and context-impact classification listed above. The mandatory five-root- -file context pass remains required for every completed task, regardless of the -reported context-impact classification, because it is cheap, deterministic, and -load-bearing for context accuracy; `context_impact` must not be used to waive it. +Before returning a `complete` result, verify that it satisfies the authoritative +handoff contract above. The mandatory five-root-file context pass remains required +for every completed task, regardless of the reported context-impact classification, +because it is cheap, deterministic, and load-bearing for context accuracy; +`context_impact` must not be used to waive it. ## 2.9 Return internal state @@ -205,10 +203,8 @@ After the phase reaches a terminal state, set exactly one internal state. Record only the internal state. Do not add explanatory prose before or after it. -A `complete` result is the authoritative handoff into step 3, which reads the -plan, completed task, changed files, implementation summary, verification -evidence, done-check evidence, and context-impact classification out of it. Step -3 is forbidden from reconstructing any of that, so it has to be present here. +A `complete` result is the authoritative handoff into step 3. Pass it unchanged; +step 3 must consume it instead of reconstructing its fields. ## Task execution boundaries diff --git a/config/pkl/base/workflow-content.pkl b/config/pkl/base/workflow-content.pkl index 356a4faf7..6906d10b1 100644 --- a/config/pkl/base/workflow-content.pkl +++ b/config/pkl/base/workflow-content.pkl @@ -337,9 +337,8 @@ Read `references/context-sync.md`, then run the **Task context synchronization phase** with the complete `complete` result returned by the **Task execution phase**. -Pass that result verbatim. It is the authoritative handoff, and the **Task context synchronization phase** owns reading the plan, task, changed files, verification evidence, and reported context impact out of it. - -Do not restate, summarize, or reconstruct any part of the execution result. +Pass that `complete` result verbatim as the authoritative live handoff to the +**Task context synchronization phase**. Do not restate, summarize, or reconstruct it. This phase verifies the five root context files on every invocation, whatever the change's reported impact, so it is never correct to skip it as unnecessary. diff --git a/config/pkl/base/workflow-context-sync.pkl b/config/pkl/base/workflow-context-sync.pkl index f75a5dfb4..b01956de4 100644 --- a/config/pkl/base/workflow-context-sync.pkl +++ b/config/pkl/base/workflow-context-sync.pkl @@ -1136,18 +1136,14 @@ Input: either the complete `complete` result from the task execution phase recovery step resolved for a `blocked` task, together with that task's own completed record — read directly from the plan — and its persisted `Context synchronization blocker` when present (cross-session retry). Whichever was -supplied is the authoritative source, and this phase owns reading the plan, -task, changed files, verification evidence, and reported context impact out -of it. +supplied is authoritative; this phase consumes it without redefining its shape. Do not restate, summarize, or reconstruct any part of it. Do not reconstruct a missing execution result or completed task record from conversation history. -A live execution result must have: - -```text -status: complete -``` +A live execution result must have `status: complete` and satisfy the complete +handoff contract in `references/task-execution.md`. Consume it verbatim; do not +redefine or reconstruct its fields here. A cross-session retry has no separate `status` field to check; the completed task record's presence in the plan, identified by plan path and task ID, is @@ -1157,40 +1153,30 @@ Use the report format in: `references/sync-report.md` -Treat whichever source was supplied — the live execution result, or the -completed task record read directly from the plan — as the authoritative -source for: - -- The resolved plan and completed task. -- `changes.files_changed`, or the completed task record's own `Files changed` - field on retry, already attributed relative to the pre-edit Git baseline. -- Files changed by implementation. -- The task's `Result` (or implementation summary, for a live result). -- `Verify` outcomes (or verification evidence, for a live result). -- Done-check evidence. -- Reported context impact. +For a cross-session retry, treat the completed task record read directly from +the plan as authoritative for task identity, `Files changed`, `Result`, `Verify` +outcomes, done-check evidence, and reported context impact. Its `Files changed` +field remains the pre-edit-baseline-relative attribution; do not replace it with +a whole-working-tree scan or a fresh diff against `HEAD`. This phase must not be run for `declined`, `blocked`, or `incomplete` execution results. ## 3.1 Validate the handoff -Confirm that: - -- A live execution result has `status` exactly `complete`; a cross-session - retry has no `status` field to check and is authoritative by the completed - task record's presence in the plan. -- A resolved plan path and task ID are present; a live execution result - carries them in its `plan` and `task` objects, and a cross-session retry - receives them directly from the caller that resolved the debt task. -- Exactly one completed task is identified, and — on retry — its record is - read directly from the plan by that plan path and task ID rather than - reconstructed in-band. -- Changed files and a `Result` (an implementation summary, for a live result) - are present. -- `Verify` outcomes (verification evidence, for a live result) are present. -- Done-check evidence is present. -- A context-impact classification is present. +For a live execution result, confirm `status` is exactly `complete` and the +result satisfies the complete handoff contract in `references/task-execution.md`. +Do not reconstruct missing fields. + +For a cross-session retry, confirm that: + +- A resolved plan path and task ID are present. +- Exactly one completed task record is read directly from the plan by that plan + path and task ID rather than reconstructed in-band. +- Its `Files changed` field is present as the pre-edit-baseline-relative + changed-file list. +- `Result`, `Verify` outcomes, done-check evidence, and a context-impact + classification are present. If the required information is missing, the completed task record cannot be read from the plan, or either is internally contradictory, do not modify diff --git a/config/pkl/base/workflow-next-task.pkl b/config/pkl/base/workflow-next-task.pkl index 73d47764b..1a1ab433f 100644 --- a/config/pkl/base/workflow-next-task.pkl +++ b/config/pkl/base/workflow-next-task.pkl @@ -1808,13 +1808,11 @@ Set internal status `blocked` for every other non-successful outcome, including: Do not determine whether the plan is complete. The `/next-task` workflow owns that decision after context synchronization. -Before determining terminal status for a `complete` result, verify that the -handoff contains the resolved plan, task identity, baseline-relative changed -files, implementation summary, verification evidence, done-check evidence, plan -update, and context-impact classification listed above. The mandatory five-root- -file context pass remains required for every completed task, regardless of the -reported context-impact classification, because it is cheap, deterministic, and -load-bearing for context accuracy; `context_impact` must not be used to waive it. +Before returning a `complete` result, verify that it satisfies the authoritative +handoff contract above. The mandatory five-root-file context pass remains required +for every completed task, regardless of the reported context-impact classification, +because it is cheap, deterministic, and load-bearing for context accuracy; +`context_impact` must not be used to waive it. ## 2.9 Return internal state @@ -1822,10 +1820,8 @@ After the phase reaches a terminal state, set exactly one internal state. Record only the internal state. Do not add explanatory prose before or after it. -A `complete` result is the authoritative handoff into step 3, which reads the -plan, completed task, changed files, implementation summary, verification -evidence, done-check evidence, and context-impact classification out of it. Step -3 is forbidden from reconstructing any of that, so it has to be present here. +A `complete` result is the authoritative handoff into step 3. Pass it unchanged; +step 3 must consume it instead of reconstructing its fields. ## Task execution boundaries diff --git a/context/plans/compress-workflow-execution-preamble.md b/context/plans/compress-workflow-execution-preamble.md index 01cd02d64..dabe60f1c 100644 --- a/context/plans/compress-workflow-execution-preamble.md +++ b/context/plans/compress-workflow-execution-preamble.md @@ -277,3 +277,24 @@ The two additional root edits replace existing text without increasing line coun the exact approval question remains in `references/output.md`, not `SKILL.md` or `task-execution.md`; generated inventory stays unchanged. - Context synchronization: synced. + + +## Follow-up: complete execution-handoff schema ownership + +- [x] T03: `Deduplicate next-task complete execution handoff schema` (status:done) + - Scope: the composite same-session `complete` result produced by task execution, + the next-task handoff boundary, task-context-sync consumption/validation, + canonical Pkl sources, tracked Pi/Claude/Codex mirrors, and the ownership table. + - Ownership after change: `references/task-execution.md` defines the composite + complete handoff fields once; `/next-task` passes the result verbatim; context + sync validates and consumes that contract without restating its live field list. + Package mode retains its existing `references/execution-contract.yaml`. + - Separate shape preserved: cross-session synchronization recovery continues to + consume the persisted completed-task record and blocker; this task does not alter + synchronization-debt recovery semantics. + - Result: the selected next-task entrypoint/execution/context-sync documents shrink + by 19 Markdown lines per tracked target. + - Verify: `pkl eval config/pkl/renderers/generation-contract-check.pkl`, + `nix run .#pkl-check-generated`, targeted ownership assertions across all three + tracked targets, and `git diff --check`. + - Context synchronization: synced. diff --git a/context/sce/dedup-ownership-table.md b/context/sce/dedup-ownership-table.md index f83750363..b4aa3e8c8 100644 --- a/context/sce/dedup-ownership-table.md +++ b/context/sce/dedup-ownership-table.md @@ -18,6 +18,7 @@ | Plan authoring, clarification, and task slicing | `sce-plan-authoring` in `workflow-change-to-plan.pkl` | `/change-to-plan`; composed into `sce-change-to-plan`; thin OpenCode Plan agent | intentional/keep | | Task resolution and readiness | `sce-plan-review` in `workflow-next-task.pkl` | `/next-task`; composed into `sce-next-task`; thin OpenCode Code agent | intentional/keep | | Approval-gated one-task implementation | `sce-task-execution` in `workflow-next-task.pkl` | `/next-task` parses and conditionally passes `approve`; `references/output.md` owns only exact gate content/order; composed into `sce-next-task`; thin OpenCode Code agent | intentional/keep | +| Live post-task execution handoff schema | composite `references/task-execution.md` generated from `nextTaskTaskExecutionReference` | `/next-task` passes the `complete` result verbatim; composite task context sync validates and consumes that contract without restating the live field list; package mode retains `references/execution-contract.yaml`; cross-session retry records remain a separate persisted shape | intentional/keep | | Post-task durable context synchronization | Task instance from `workflow-context-sync.pkl` | `/next-task`; composed into `sce-next-task` | dedup/shared skeleton | | Final validation and validation report | `sce-validation` in `workflow-validate.pkl` | `/validate`; composed into `sce-validate`; thin OpenCode Code agent | intentional/keep | | Validated-plan durable context synchronization | Retained plan instance from `workflow-context-sync.pkl` | No current workflow consumer; `/validate` is validation-only | retained source, not generated | From 1290925b2331c36aaf7c1c83a80c6afe534776fe Mon Sep 17 00:00:00 2001 From: David Abram Date: Tue, 8 Sep 2026 10:08:55 +0000 Subject: [PATCH 04/12] fix: Repair next-task sync debt recovery --- .agents/skills/sce-next-task/SKILL.md | 9 +++++---- .../sce-next-task/references/plan-review.md | 12 +++++++----- .claude/skills/sce-next-task/SKILL.md | 9 +++++---- .../sce-next-task/references/plan-review.md | 12 +++++++----- .pi/skills/sce-next-task/SKILL.md | 9 +++++---- .../sce-next-task/references/plan-review.md | 12 +++++++----- config/pkl/base/workflow-content.pkl | 9 +++++---- config/pkl/base/workflow-next-task.pkl | 12 +++++++----- .../renderers/generation-contract-check.pkl | 7 ++++++- .../compress-workflow-execution-preamble.md | 19 +++++++++++++++++++ context/sce/dedup-ownership-table.md | 1 + 11 files changed, 74 insertions(+), 37 deletions(-) diff --git a/.agents/skills/sce-next-task/SKILL.md b/.agents/skills/sce-next-task/SKILL.md index ef400e215..83db8f34f 100644 --- a/.agents/skills/sce-next-task/SKILL.md +++ b/.agents/skills/sce-next-task/SKILL.md @@ -71,7 +71,7 @@ Branch on `status`: `blocked` -> Do not run implementation. Render the **Review blocked** layout from `references/output.md`. When `candidates` is present the plan could not be resolved, and each entry is a candidate path for `/next-task {candidate-path}`. `executable_tasks_remaining` true means another task remains executable and `/next-task {plan-path} {task-id}` selects one; false means no task in the plan can proceed until the plan is updated. Do not print the raw result. Stop. -`sync_debt` -> Read `references/context-sync.md`, then run the **Task context synchronization phase** using the debt task's persisted `Context synchronization handoff` — and, when present, its persisted `Context synchronization blocker` — named by the **Plan review phase**. Do not reconstruct a missing handoff from conversation history. +`sync_debt` -> Read `references/context-sync.md`, then run the **Task context synchronization phase** with the resolved plan path, debt task ID/title, and completed task record returned by the **Plan review phase**, plus its persisted `Context synchronization blocker` when present. Pass that completed task record verbatim. Do not reconstruct missing task data from conversation history. Write the debt task's lifecycle to the plan: `synced`, clearing its blocker, required action, and retry condition, for `synced` or `no_context_change`; a refreshed `blocked` state with the report's blocker, required action, and retry condition for `blocked`. If that lifecycle write fails, treat the outcome as `blocked`. @@ -92,9 +92,10 @@ the plan, in plan order, regardless of its position relative to the task being selected or resumed, before allowing a new implementation task to start. A missing field, or any value other than `synced`, is unresolved synchronization debt. Never infer `synced` from conversation history. When the debt-carrying -task has no durable `Context synchronization handoff` subsection, the **Plan -review phase** returns `blocked` directly with a legacy-migration required -action; otherwise it returns `sync_debt`, resolved by the branch above. +task has no durable completed-task record, the **Plan review phase** returns +`blocked` directly with a legacy-migration required action; otherwise it returns +`sync_debt` with the resolved plan path, debt task ID/title, completed task +record, and persisted blocker when present, for the branch above to route. ### 2. Execute the task diff --git a/.agents/skills/sce-next-task/references/plan-review.md b/.agents/skills/sce-next-task/references/plan-review.md index 89e378f36..41f6c55c6 100644 --- a/.agents/skills/sce-next-task/references/plan-review.md +++ b/.agents/skills/sce-next-task/references/plan-review.md @@ -34,11 +34,12 @@ For the first task carrying debt: Set internal status `blocked` with a required action to migrate the plan (backfill the completion record, or resolve the debt manually) and a retry condition of the plan carrying that structure. Stop. -- Otherwise, set internal status `sync_debt`, naming the debt task (its ID and - title) and its own completed record — read directly from the plan by plan - path and task ID — including, when its field is `blocked`, its persisted - `Context synchronization blocker`. Do not run or cite the Task context - synchronization phase. Stop. Do not select or start a new task. +- Otherwise, set internal status `sync_debt`, naming the resolved plan path, + the debt task (its ID and title), and its own completed record — read + directly from the plan by plan path and task ID — including, when its field + is `blocked`, its persisted `Context synchronization blocker`. Do not run + or cite the Task context synchronization phase. Stop. Do not select or start + a new task. Only after every completed task is `synced` does task selection proceed. @@ -129,6 +130,7 @@ A `ready` result must identify: A `sync_debt` result must identify: +- The resolved plan path. - The debt-carrying task's ID and title. - Its own completed record, read directly from the plan by plan path and task ID. - Its persisted `Context synchronization blocker`, when present. diff --git a/.claude/skills/sce-next-task/SKILL.md b/.claude/skills/sce-next-task/SKILL.md index cb19fecba..c61e8208b 100644 --- a/.claude/skills/sce-next-task/SKILL.md +++ b/.claude/skills/sce-next-task/SKILL.md @@ -70,7 +70,7 @@ Branch on `status`: `blocked` -> Do not run implementation. Render the **Review blocked** layout from `references/output.md`. When `candidates` is present the plan could not be resolved, and each entry is a candidate path for `/next-task {candidate-path}`. `executable_tasks_remaining` true means another task remains executable and `/next-task {plan-path} {task-id}` selects one; false means no task in the plan can proceed until the plan is updated. Do not print the raw result. Stop. -`sync_debt` -> Read `references/context-sync.md`, then run the **Task context synchronization phase** using the debt task's persisted `Context synchronization handoff` — and, when present, its persisted `Context synchronization blocker` — named by the **Plan review phase**. Do not reconstruct a missing handoff from conversation history. +`sync_debt` -> Read `references/context-sync.md`, then run the **Task context synchronization phase** with the resolved plan path, debt task ID/title, and completed task record returned by the **Plan review phase**, plus its persisted `Context synchronization blocker` when present. Pass that completed task record verbatim. Do not reconstruct missing task data from conversation history. Write the debt task's lifecycle to the plan: `synced`, clearing its blocker, required action, and retry condition, for `synced` or `no_context_change`; a refreshed `blocked` state with the report's blocker, required action, and retry condition for `blocked`. If that lifecycle write fails, treat the outcome as `blocked`. @@ -91,9 +91,10 @@ the plan, in plan order, regardless of its position relative to the task being selected or resumed, before allowing a new implementation task to start. A missing field, or any value other than `synced`, is unresolved synchronization debt. Never infer `synced` from conversation history. When the debt-carrying -task has no durable `Context synchronization handoff` subsection, the **Plan -review phase** returns `blocked` directly with a legacy-migration required -action; otherwise it returns `sync_debt`, resolved by the branch above. +task has no durable completed-task record, the **Plan review phase** returns +`blocked` directly with a legacy-migration required action; otherwise it returns +`sync_debt` with the resolved plan path, debt task ID/title, completed task +record, and persisted blocker when present, for the branch above to route. ### 2. Execute the task diff --git a/.claude/skills/sce-next-task/references/plan-review.md b/.claude/skills/sce-next-task/references/plan-review.md index 89e378f36..41f6c55c6 100644 --- a/.claude/skills/sce-next-task/references/plan-review.md +++ b/.claude/skills/sce-next-task/references/plan-review.md @@ -34,11 +34,12 @@ For the first task carrying debt: Set internal status `blocked` with a required action to migrate the plan (backfill the completion record, or resolve the debt manually) and a retry condition of the plan carrying that structure. Stop. -- Otherwise, set internal status `sync_debt`, naming the debt task (its ID and - title) and its own completed record — read directly from the plan by plan - path and task ID — including, when its field is `blocked`, its persisted - `Context synchronization blocker`. Do not run or cite the Task context - synchronization phase. Stop. Do not select or start a new task. +- Otherwise, set internal status `sync_debt`, naming the resolved plan path, + the debt task (its ID and title), and its own completed record — read + directly from the plan by plan path and task ID — including, when its field + is `blocked`, its persisted `Context synchronization blocker`. Do not run + or cite the Task context synchronization phase. Stop. Do not select or start + a new task. Only after every completed task is `synced` does task selection proceed. @@ -129,6 +130,7 @@ A `ready` result must identify: A `sync_debt` result must identify: +- The resolved plan path. - The debt-carrying task's ID and title. - Its own completed record, read directly from the plan by plan path and task ID. - Its persisted `Context synchronization blocker`, when present. diff --git a/.pi/skills/sce-next-task/SKILL.md b/.pi/skills/sce-next-task/SKILL.md index 52d9bc22d..691237b47 100644 --- a/.pi/skills/sce-next-task/SKILL.md +++ b/.pi/skills/sce-next-task/SKILL.md @@ -69,7 +69,7 @@ Branch on `status`: `blocked` -> Do not run implementation. Render the **Review blocked** layout from `references/output.md`. When `candidates` is present the plan could not be resolved, and each entry is a candidate path for `/next-task {candidate-path}`. `executable_tasks_remaining` true means another task remains executable and `/next-task {plan-path} {task-id}` selects one; false means no task in the plan can proceed until the plan is updated. Do not print the raw result. Stop. -`sync_debt` -> Read `references/context-sync.md`, then run the **Task context synchronization phase** using the debt task's persisted `Context synchronization handoff` — and, when present, its persisted `Context synchronization blocker` — named by the **Plan review phase**. Do not reconstruct a missing handoff from conversation history. +`sync_debt` -> Read `references/context-sync.md`, then run the **Task context synchronization phase** with the resolved plan path, debt task ID/title, and completed task record returned by the **Plan review phase**, plus its persisted `Context synchronization blocker` when present. Pass that completed task record verbatim. Do not reconstruct missing task data from conversation history. Write the debt task's lifecycle to the plan: `synced`, clearing its blocker, required action, and retry condition, for `synced` or `no_context_change`; a refreshed `blocked` state with the report's blocker, required action, and retry condition for `blocked`. If that lifecycle write fails, treat the outcome as `blocked`. @@ -90,9 +90,10 @@ the plan, in plan order, regardless of its position relative to the task being selected or resumed, before allowing a new implementation task to start. A missing field, or any value other than `synced`, is unresolved synchronization debt. Never infer `synced` from conversation history. When the debt-carrying -task has no durable `Context synchronization handoff` subsection, the **Plan -review phase** returns `blocked` directly with a legacy-migration required -action; otherwise it returns `sync_debt`, resolved by the branch above. +task has no durable completed-task record, the **Plan review phase** returns +`blocked` directly with a legacy-migration required action; otherwise it returns +`sync_debt` with the resolved plan path, debt task ID/title, completed task +record, and persisted blocker when present, for the branch above to route. ### 2. Execute the task diff --git a/.pi/skills/sce-next-task/references/plan-review.md b/.pi/skills/sce-next-task/references/plan-review.md index 89e378f36..41f6c55c6 100644 --- a/.pi/skills/sce-next-task/references/plan-review.md +++ b/.pi/skills/sce-next-task/references/plan-review.md @@ -34,11 +34,12 @@ For the first task carrying debt: Set internal status `blocked` with a required action to migrate the plan (backfill the completion record, or resolve the debt manually) and a retry condition of the plan carrying that structure. Stop. -- Otherwise, set internal status `sync_debt`, naming the debt task (its ID and - title) and its own completed record — read directly from the plan by plan - path and task ID — including, when its field is `blocked`, its persisted - `Context synchronization blocker`. Do not run or cite the Task context - synchronization phase. Stop. Do not select or start a new task. +- Otherwise, set internal status `sync_debt`, naming the resolved plan path, + the debt task (its ID and title), and its own completed record — read + directly from the plan by plan path and task ID — including, when its field + is `blocked`, its persisted `Context synchronization blocker`. Do not run + or cite the Task context synchronization phase. Stop. Do not select or start + a new task. Only after every completed task is `synced` does task selection proceed. @@ -129,6 +130,7 @@ A `ready` result must identify: A `sync_debt` result must identify: +- The resolved plan path. - The debt-carrying task's ID and title. - Its own completed record, read directly from the plan by plan path and task ID. - Its persisted `Context synchronization blocker`, when present. diff --git a/config/pkl/base/workflow-content.pkl b/config/pkl/base/workflow-content.pkl index 6906d10b1..3f89889cc 100644 --- a/config/pkl/base/workflow-content.pkl +++ b/config/pkl/base/workflow-content.pkl @@ -286,7 +286,7 @@ Branch on `status`: `blocked` -> Do not run implementation. Render the **Review blocked** layout from `references/output.md`. When `candidates` is present the plan could not be resolved, and each entry is a candidate path for `/next-task {candidate-path}`. `executable_tasks_remaining` true means another task remains executable and `/next-task {plan-path} {task-id}` selects one; false means no task in the plan can proceed until the plan is updated. Do not print the raw result. Stop. -`sync_debt` -> Read `references/context-sync.md`, then run the **Task context synchronization phase** using the debt task's persisted `Context synchronization handoff` — and, when present, its persisted `Context synchronization blocker` — named by the **Plan review phase**. Do not reconstruct a missing handoff from conversation history. +`sync_debt` -> Read `references/context-sync.md`, then run the **Task context synchronization phase** with the resolved plan path, debt task ID/title, and completed task record returned by the **Plan review phase**, plus its persisted `Context synchronization blocker` when present. Pass that completed task record verbatim. Do not reconstruct missing task data from conversation history. Write the debt task's lifecycle to the plan: `synced`, clearing its blocker, required action, and retry condition, for `synced` or `no_context_change`; a refreshed `blocked` state with the report's blocker, required action, and retry condition for `blocked`. If that lifecycle write fails, treat the outcome as `blocked`. @@ -307,9 +307,10 @@ the plan, in plan order, regardless of its position relative to the task being selected or resumed, before allowing a new implementation task to start. A missing field, or any value other than `synced`, is unresolved synchronization debt. Never infer `synced` from conversation history. When the debt-carrying -task has no durable `Context synchronization handoff` subsection, the **Plan -review phase** returns `blocked` directly with a legacy-migration required -action; otherwise it returns `sync_debt`, resolved by the branch above. +task has no durable completed-task record, the **Plan review phase** returns +`blocked` directly with a legacy-migration required action; otherwise it returns +`sync_debt` with the resolved plan path, debt task ID/title, completed task +record, and persisted blocker when present, for the branch above to route. ### 2. Execute the task diff --git a/config/pkl/base/workflow-next-task.pkl b/config/pkl/base/workflow-next-task.pkl index 1a1ab433f..4556393bf 100644 --- a/config/pkl/base/workflow-next-task.pkl +++ b/config/pkl/base/workflow-next-task.pkl @@ -1497,11 +1497,12 @@ For the first task carrying debt: Set internal status `blocked` with a required action to migrate the plan (backfill the completion record, or resolve the debt manually) and a retry condition of the plan carrying that structure. Stop. -- Otherwise, set internal status `sync_debt`, naming the debt task (its ID and - title) and its own completed record — read directly from the plan by plan - path and task ID — including, when its field is `blocked`, its persisted - `Context synchronization blocker`. Do not run or cite the Task context - synchronization phase. Stop. Do not select or start a new task. +- Otherwise, set internal status `sync_debt`, naming the resolved plan path, + the debt task (its ID and title), and its own completed record — read + directly from the plan by plan path and task ID — including, when its field + is `blocked`, its persisted `Context synchronization blocker`. Do not run + or cite the Task context synchronization phase. Stop. Do not select or start + a new task. Only after every completed task is `synced` does task selection proceed. @@ -1592,6 +1593,7 @@ A `ready` result must identify: A `sync_debt` result must identify: +- The resolved plan path. - The debt-carrying task's ID and title. - Its own completed record, read directly from the plan by plan path and task ID. - Its persisted `Context synchronization blocker`, when present. diff --git a/config/pkl/renderers/generation-contract-check.pkl b/config/pkl/renderers/generation-contract-check.pkl index c9d3d9b5c..70ec95d44 100644 --- a/config/pkl/renderers/generation-contract-check.pkl +++ b/config/pkl/renderers/generation-contract-check.pkl @@ -852,6 +852,7 @@ hidden assertNextTaskCompactCompletionWriting = (documents: Mapping) -> local requiredPlanReviewCompletedRecordTokens = new Listing { "no durable completed-task record (no `Files changed`," "read directly from the plan by plan path and task ID" + "The resolved plan path." } hidden assertPlanReviewReadsCompletedRecord = (documents: Mapping) -> @@ -892,14 +893,18 @@ hidden assertSyncDebtRecoveryBranch = (documents: Mapping) -> !path.endsWith("/skills/sce-next-task/SKILL.md") || ( text.contains("`sync_debt` ->") + && !text.contains("Context synchronization handoff") && let (branch = text.drop(text.indexOf("`sync_debt` ->"))) let (paragraph = if (branch.contains("\n\n")) branch.take(branch.indexOf("\n\n")) else branch) paragraph.contains("references/context-sync.md") && paragraph.contains("Task context synchronization phase") + && paragraph.contains("resolved plan path") + && paragraph.contains("debt task ID/title") + && paragraph.contains("completed task record") && paragraph.indexOf("references/context-sync.md") < paragraph.indexOf("Task context synchronization phase") ) ) - ) "generated sce-next-task SKILL.md: sync-debt recovery cites context-sync.md before invoking the phase" + ) "generated sce-next-task SKILL.md: sync-debt recovery routes the resolved completed task record" else throw("sce-next-task SKILL.md sync-debt recovery branch must cite references/context-sync.md before invoking the Task context synchronization phase") hidden assertPlanReviewAllTasksScope = (documents: Mapping) -> diff --git a/context/plans/compress-workflow-execution-preamble.md b/context/plans/compress-workflow-execution-preamble.md index dabe60f1c..ba19e6cbf 100644 --- a/context/plans/compress-workflow-execution-preamble.md +++ b/context/plans/compress-workflow-execution-preamble.md @@ -298,3 +298,22 @@ The two additional root edits replace existing text without increasing line coun `nix run .#pkl-check-generated`, targeted ownership assertions across all three tracked targets, and `git diff --check`. - Context synchronization: synced. + + +## Follow-up: synchronization-debt recovery contract + +- [x] T04: `Repair next-task synchronization-debt recovery` (status:done) + - Scope: the composite `/next-task` sync-debt branch, plan-review's `sync_debt` + result identity, the generated semantic contract, the Pi/Claude/Codex tracked + mirrors, and the ownership table. + - Ownership after change: plan review resolves the plan path, debt task identity, + completed task record, and persisted blocker; `/next-task` routes that record + verbatim; task context sync validates and consumes it. No separate persisted + `Context synchronization handoff` object exists. + - Behavior preserved: all-completed-task debt scanning, legacy incomplete-record + blocking, lifecycle writes (`synced` / refreshed `blocked`), sync-specific blocked + output, and post-recovery re-review are unchanged. + - Verify: `pkl eval config/pkl/renderers/generation-contract-check.pkl`, + `nix run .#pkl-check-generated`, targeted Pi/Claude/Codex ownership assertions, + and `git diff --check`. + - Context synchronization: synced. diff --git a/context/sce/dedup-ownership-table.md b/context/sce/dedup-ownership-table.md index b4aa3e8c8..addc06b4a 100644 --- a/context/sce/dedup-ownership-table.md +++ b/context/sce/dedup-ownership-table.md @@ -19,6 +19,7 @@ | Task resolution and readiness | `sce-plan-review` in `workflow-next-task.pkl` | `/next-task`; composed into `sce-next-task`; thin OpenCode Code agent | intentional/keep | | Approval-gated one-task implementation | `sce-task-execution` in `workflow-next-task.pkl` | `/next-task` parses and conditionally passes `approve`; `references/output.md` owns only exact gate content/order; composed into `sce-next-task`; thin OpenCode Code agent | intentional/keep | | Live post-task execution handoff schema | composite `references/task-execution.md` generated from `nextTaskTaskExecutionReference` | `/next-task` passes the `complete` result verbatim; composite task context sync validates and consumes that contract without restating the live field list; package mode retains `references/execution-contract.yaml`; cross-session retry records remain a separate persisted shape | intentional/keep | +| Synchronization-debt recovery identity | `sce-plan-review` resolves the plan path, debt task identity, completed task record, and persisted blocker | `/next-task` only routes that resolved record to task context sync; task context sync validates and consumes it directly from the plan; no separate persisted handoff exists | intentional/keep | | Post-task durable context synchronization | Task instance from `workflow-context-sync.pkl` | `/next-task`; composed into `sce-next-task` | dedup/shared skeleton | | Final validation and validation report | `sce-validation` in `workflow-validate.pkl` | `/validate`; composed into `sce-validate`; thin OpenCode Code agent | intentional/keep | | Validated-plan durable context synchronization | Retained plan instance from `workflow-context-sync.pkl` | No current workflow consumer; `/validate` is validation-only | retained source, not generated | From 9ceef9074ac861190c4da11057a93eb08ab90e29 Mon Sep 17 00:00:00 2001 From: David Abram Date: Tue, 8 Sep 2026 10:23:19 +0000 Subject: [PATCH 05/12] config: Deduplicate next-task root context pass --- .../sce-next-task/references/context-sync.md | 14 +++----- .../references/task-execution.md | 5 +-- .../sce-next-task/references/context-sync.md | 14 +++----- .../references/task-execution.md | 5 +-- .../sce-next-task/references/context-sync.md | 14 +++----- .../references/task-execution.md | 5 +-- config/pkl/base/workflow-context-sync.pkl | 36 +++++++------------ config/pkl/base/workflow-next-task.pkl | 11 ++---- .../renderers/generation-contract-check.pkl | 31 ++++++++++++++++ .../compress-workflow-execution-preamble.md | 20 +++++++++++ context/sce/dedup-ownership-table.md | 1 + 11 files changed, 84 insertions(+), 72 deletions(-) diff --git a/.agents/skills/sce-next-task/references/context-sync.md b/.agents/skills/sce-next-task/references/context-sync.md index 2fd09db6f..fb330bb6d 100644 --- a/.agents/skills/sce-next-task/references/context-sync.md +++ b/.agents/skills/sce-next-task/references/context-sync.md @@ -82,15 +82,11 @@ Start with the execution result: Then inspect existing repository context in this order when present: -1. `context/context-map.md` -2. Context files for the affected domain or subsystem -3. `context/overview.md` -4. `context/architecture.md` -5. `context/glossary.md` -6. `context/patterns.md` -7. Operational, product, or decision records directly related to the change - -Use the context map and existing links to locate authoritative files. +1. The context map and its links to affected domain or subsystem context +2. The mandatory root pass defined below +3. Operational, product, or decision records directly related to the change + +The mandatory root-pass subsection owns the exact five-file root set. Do not scan or rewrite the entire `context/` tree by default. diff --git a/.agents/skills/sce-next-task/references/task-execution.md b/.agents/skills/sce-next-task/references/task-execution.md index 77009315b..2c64dff2a 100644 --- a/.agents/skills/sce-next-task/references/task-execution.md +++ b/.agents/skills/sce-next-task/references/task-execution.md @@ -192,10 +192,7 @@ Do not determine whether the plan is complete. The `/next-task` workflow owns that decision after context synchronization. Before returning a `complete` result, verify that it satisfies the authoritative -handoff contract above. The mandatory five-root-file context pass remains required -for every completed task, regardless of the reported context-impact classification, -because it is cheap, deterministic, and load-bearing for context accuracy; -`context_impact` must not be used to waive it. +handoff contract above. ## 2.9 Return internal state diff --git a/.claude/skills/sce-next-task/references/context-sync.md b/.claude/skills/sce-next-task/references/context-sync.md index 2fd09db6f..fb330bb6d 100644 --- a/.claude/skills/sce-next-task/references/context-sync.md +++ b/.claude/skills/sce-next-task/references/context-sync.md @@ -82,15 +82,11 @@ Start with the execution result: Then inspect existing repository context in this order when present: -1. `context/context-map.md` -2. Context files for the affected domain or subsystem -3. `context/overview.md` -4. `context/architecture.md` -5. `context/glossary.md` -6. `context/patterns.md` -7. Operational, product, or decision records directly related to the change - -Use the context map and existing links to locate authoritative files. +1. The context map and its links to affected domain or subsystem context +2. The mandatory root pass defined below +3. Operational, product, or decision records directly related to the change + +The mandatory root-pass subsection owns the exact five-file root set. Do not scan or rewrite the entire `context/` tree by default. diff --git a/.claude/skills/sce-next-task/references/task-execution.md b/.claude/skills/sce-next-task/references/task-execution.md index 77009315b..2c64dff2a 100644 --- a/.claude/skills/sce-next-task/references/task-execution.md +++ b/.claude/skills/sce-next-task/references/task-execution.md @@ -192,10 +192,7 @@ Do not determine whether the plan is complete. The `/next-task` workflow owns that decision after context synchronization. Before returning a `complete` result, verify that it satisfies the authoritative -handoff contract above. The mandatory five-root-file context pass remains required -for every completed task, regardless of the reported context-impact classification, -because it is cheap, deterministic, and load-bearing for context accuracy; -`context_impact` must not be used to waive it. +handoff contract above. ## 2.9 Return internal state diff --git a/.pi/skills/sce-next-task/references/context-sync.md b/.pi/skills/sce-next-task/references/context-sync.md index 2fd09db6f..fb330bb6d 100644 --- a/.pi/skills/sce-next-task/references/context-sync.md +++ b/.pi/skills/sce-next-task/references/context-sync.md @@ -82,15 +82,11 @@ Start with the execution result: Then inspect existing repository context in this order when present: -1. `context/context-map.md` -2. Context files for the affected domain or subsystem -3. `context/overview.md` -4. `context/architecture.md` -5. `context/glossary.md` -6. `context/patterns.md` -7. Operational, product, or decision records directly related to the change - -Use the context map and existing links to locate authoritative files. +1. The context map and its links to affected domain or subsystem context +2. The mandatory root pass defined below +3. Operational, product, or decision records directly related to the change + +The mandatory root-pass subsection owns the exact five-file root set. Do not scan or rewrite the entire `context/` tree by default. diff --git a/.pi/skills/sce-next-task/references/task-execution.md b/.pi/skills/sce-next-task/references/task-execution.md index 77009315b..2c64dff2a 100644 --- a/.pi/skills/sce-next-task/references/task-execution.md +++ b/.pi/skills/sce-next-task/references/task-execution.md @@ -192,10 +192,7 @@ Do not determine whether the plan is complete. The `/next-task` workflow owns that decision after context synchronization. Before returning a `complete` result, verify that it satisfies the authoritative -handoff contract above. The mandatory five-root-file context pass remains required -for every completed task, regardless of the reported context-impact classification, -because it is cheap, deterministic, and load-bearing for context accuracy; -`context_impact` must not be used to waive it. +handoff contract above. ## 2.9 Return internal state diff --git a/config/pkl/base/workflow-context-sync.pkl b/config/pkl/base/workflow-context-sync.pkl index b01956de4..0e60d9f7c 100644 --- a/config/pkl/base/workflow-context-sync.pkl +++ b/config/pkl/base/workflow-context-sync.pkl @@ -244,15 +244,11 @@ local taskRoleData = new SyncRole { Then inspect existing repository context in this order when present: - 1. `context/context-map.md` - 2. Context files for the affected domain or subsystem - 3. `context/overview.md` - 4. `context/architecture.md` - 5. `context/glossary.md` - 6. `context/patterns.md` - 7. Operational, product, or decision records directly related to the change + 1. The context map and its links to affected domain or subsystem context + 2. The mandatory root pass defined below + 3. Operational, product, or decision records directly related to the change - Use the context map and existing links to locate authoritative files. + The mandatory root-pass subsection owns the exact five-file root set. Do not scan or rewrite the entire `context/` tree by default. @@ -589,16 +585,12 @@ local planRoleData = new SyncRole { context in this order when present: 1. Paths named by the plan's `Context sync` section - 2. `context/context-map.md` - 3. Context files for the affected domain or subsystem - 4. `context/overview.md` - 5. `context/architecture.md` - 6. `context/glossary.md` - 7. `context/patterns.md` - 8. Operational, product, or decision records directly related to the finished + 2. The context map and its links to affected domain or subsystem context + 3. The mandatory root pass defined below + 4. Operational, product, or decision records directly related to the finished change - Use the context map and existing links to locate authoritative files. + The mandatory root-pass subsection owns the exact five-file root set. Do not scan or rewrite the entire `context/` tree by default. @@ -1208,15 +1200,11 @@ Start with the execution result: Then inspect existing repository context in this order when present: -1. `context/context-map.md` -2. Context files for the affected domain or subsystem -3. `context/overview.md` -4. `context/architecture.md` -5. `context/glossary.md` -6. `context/patterns.md` -7. Operational, product, or decision records directly related to the change +1. The context map and its links to affected domain or subsystem context +2. The mandatory root pass defined below +3. Operational, product, or decision records directly related to the change -Use the context map and existing links to locate authoritative files. +The mandatory root-pass subsection owns the exact five-file root set. Do not scan or rewrite the entire `context/` tree by default. diff --git a/config/pkl/base/workflow-next-task.pkl b/config/pkl/base/workflow-next-task.pkl index 4556393bf..234cdc46e 100644 --- a/config/pkl/base/workflow-next-task.pkl +++ b/config/pkl/base/workflow-next-task.pkl @@ -997,11 +997,7 @@ local renderExecutionSkillBody = (mode: model.WorkflowRenderMode) -> """ Before determining terminal status for a `complete` result, verify that the handoff contains the resolved plan, task identity, baseline-relative changed files, implementation summary, verification evidence, done-check evidence, - plan update, and context-impact classification listed above. The mandatory - five-root-file context pass remains required for every completed task, - regardless of the reported context-impact classification, because it is - cheap, deterministic, and load-bearing for context accuracy; `context_impact` - must not be used to waive it. + plan update, and context-impact classification listed above. \(taskExecutionHeadings.stepHeading.apply(mode, 8, "Determine the terminal status")) @@ -1811,10 +1807,7 @@ Do not determine whether the plan is complete. The `/next-task` workflow owns that decision after context synchronization. Before returning a `complete` result, verify that it satisfies the authoritative -handoff contract above. The mandatory five-root-file context pass remains required -for every completed task, regardless of the reported context-impact classification, -because it is cheap, deterministic, and load-bearing for context accuracy; -`context_impact` must not be used to waive it. +handoff contract above. ## 2.9 Return internal state diff --git a/config/pkl/renderers/generation-contract-check.pkl b/config/pkl/renderers/generation-contract-check.pkl index 70ec95d44..9a49b828b 100644 --- a/config/pkl/renderers/generation-contract-check.pkl +++ b/config/pkl/renderers/generation-contract-check.pkl @@ -887,6 +887,36 @@ hidden assertContextSyncValidatesTaskRecord = (documents: Mapping) -> ) "sce-next-task context-sync reference: validates the completed task record, not a persisted handoff" else throw("sce-next-task context-sync.md must validate the completed task record directly from the plan and must not reference a persisted Context synchronization handoff") +local mandatoryRootContextPaths = new Listing { + "`context/overview.md`" + "`context/architecture.md`" + "`context/glossary.md`" + "`context/patterns.md`" + "`context/context-map.md`" +} + +hidden assertNextTaskRootPassOwnership = (documents: Mapping) -> + if ( + documents.every((path, text) -> + if (path.endsWith("/skills/sce-next-task/references/task-execution.md")) + !text.contains("five-root-file context pass") + && !text.contains("mandatory root pass") + else if (path.endsWith("/skills/sce-next-task/references/context-sync.md")) + text.contains("### The mandatory root pass") + && text.contains("## 3.3 Discover applicable context") + && text.contains("## 3.4 Determine whether durable context changed") + && let (discoveryTail = text.drop(text.indexOf("## 3.3 Discover applicable context"))) + let (discovery = discoveryTail.take(discoveryTail.indexOf("### The mandatory root pass"))) + let (rootTail = text.drop(text.indexOf("### The mandatory root pass"))) + let (rootPass = rootTail.take(rootTail.indexOf("## 3.4 Determine whether durable context changed"))) + discovery.contains("The mandatory root-pass subsection owns the exact five-file root set.") + && mandatoryRootContextPaths.every((rootPath) -> !discovery.contains(rootPath)) + && mandatoryRootContextPaths.every((rootPath) -> rootPass.contains(rootPath)) + else true + ) + ) "sce-next-task root pass: context-sync solely owns the exact five-file set" + else throw("sce-next-task must define the exact five-file mandatory root pass only in context-sync's mandatory-root-pass subsection; discovery may reference it by name and task-execution must not restate it") + hidden assertSyncDebtRecoveryBranch = (documents: Mapping) -> if ( documents.every((path, text) -> @@ -1011,6 +1041,7 @@ contractChecks { ["next-task-compact-completion-writing"] = assertNextTaskCompactCompletionWriting.apply(workflowDocuments) ["plan-review-reads-completed-record"] = assertPlanReviewReadsCompletedRecord.apply(workflowDocuments) ["context-sync-validates-task-record"] = assertContextSyncValidatesTaskRecord.apply(workflowDocuments) + ["next-task-root-pass-ownership"] = assertNextTaskRootPassOwnership.apply(workflowDocuments) ["sync-debt-recovery-branch"] = assertSyncDebtRecoveryBranch.apply(workflowDocuments) ["plan-review-all-tasks-scope"] = assertPlanReviewAllTasksScope.apply(workflowDocuments) ["sync-debt-blocked-routing"] = assertSyncDebtBlockedRouting.apply(workflowDocuments) diff --git a/context/plans/compress-workflow-execution-preamble.md b/context/plans/compress-workflow-execution-preamble.md index ba19e6cbf..920a507cf 100644 --- a/context/plans/compress-workflow-execution-preamble.md +++ b/context/plans/compress-workflow-execution-preamble.md @@ -317,3 +317,23 @@ The two additional root edits replace existing text without increasing line coun `nix run .#pkl-check-generated`, targeted Pi/Claude/Codex ownership assertions, and `git diff --check`. - Context synchronization: synced. + + +## Follow-up: mandatory root-pass ownership + +- [x] T05: `Deduplicate the mandatory five-root context pass` (status:done) + - Scope: next-task task execution and task context synchronization, the retained + plan-sync discovery list in the shared context-sync source, generated semantic + checks, tracked Pi/Claude/Codex mirrors, and the ownership table. + - Ownership after change: the task context-sync **mandatory root pass** subsection + is the sole owner of the exact five root paths. Discovery references that named + contract instead of relisting the paths; task execution only hands off + `context_impact` and does not restate synchronization policy. + - Behavior preserved: the same five root files remain mandatory on every task + synchronization invocation; missing files remain reportable gaps; impact + classifications still cannot waive the pass; synchronization verification still + requires every root file to be checked against code truth. + - Verify: `pkl eval config/pkl/renderers/generation-contract-check.pkl`, + `nix run .#pkl-check-generated`, targeted Pi/Claude/Codex ownership assertions, + and `git diff --check`. + - Context synchronization: synced. diff --git a/context/sce/dedup-ownership-table.md b/context/sce/dedup-ownership-table.md index addc06b4a..a9306b6f1 100644 --- a/context/sce/dedup-ownership-table.md +++ b/context/sce/dedup-ownership-table.md @@ -21,6 +21,7 @@ | Live post-task execution handoff schema | composite `references/task-execution.md` generated from `nextTaskTaskExecutionReference` | `/next-task` passes the `complete` result verbatim; composite task context sync validates and consumes that contract without restating the live field list; package mode retains `references/execution-contract.yaml`; cross-session retry records remain a separate persisted shape | intentional/keep | | Synchronization-debt recovery identity | `sce-plan-review` resolves the plan path, debt task identity, completed task record, and persisted blocker | `/next-task` only routes that resolved record to task context sync; task context sync validates and consumes it directly from the plan; no separate persisted handoff exists | intentional/keep | | Post-task durable context synchronization | Task instance from `workflow-context-sync.pkl` | `/next-task`; composed into `sce-next-task` | dedup/shared skeleton | +| Mandatory five-root context pass | `sce-task-context-sync` mandatory-root-pass subsection in `workflow-context-sync.pkl` | Task execution only hands off `context_impact`; context discovery references the named pass instead of relisting its five files; impact and verification sections may enforce the owned contract without redefining the file set | intentional/keep | | Final validation and validation report | `sce-validation` in `workflow-validate.pkl` | `/validate`; composed into `sce-validate`; thin OpenCode Code agent | intentional/keep | | Validated-plan durable context synchronization | Retained plan instance from `workflow-context-sync.pkl` | No current workflow consumer; `/validate` is validation-only | retained source, not generated | | Staged-diff analysis and commit-message authoring | `sce-atomic-commit` in `workflow-commit.pkl` | `/commit`; composed into `sce-commit`; thin OpenCode Code agent | intentional/keep | From 1d6552b6244155677f11890675569c5d6160d589 Mon Sep 17 00:00:00 2001 From: David Abram Date: Tue, 8 Sep 2026 10:35:30 +0000 Subject: [PATCH 06/12] config: Deduplicate change-to-plan template policy --- .../references/plan-authoring.md | 67 +++++++----------- .../references/plan-template.md | 1 + .../references/plan-authoring.md | 67 +++++++----------- .../references/plan-template.md | 1 + .../references/plan-authoring.md | 67 +++++++----------- .../references/plan-template.md | 1 + config/pkl/base/workflow-change-to-plan.pkl | 68 +++++++------------ .../renderers/generation-contract-check.pkl | 32 +++++++++ .../compress-workflow-execution-preamble.md | 24 +++++++ context/sce/dedup-ownership-table.md | 3 +- 10 files changed, 162 insertions(+), 169 deletions(-) diff --git a/.agents/skills/sce-change-to-plan/references/plan-authoring.md b/.agents/skills/sce-change-to-plan/references/plan-authoring.md index 17e054e2d..98335bf34 100644 --- a/.agents/skills/sce-change-to-plan/references/plan-authoring.md +++ b/.agents/skills/sce-change-to-plan/references/plan-authoring.md @@ -5,18 +5,19 @@ Run this phase for step 2 of the workflow, and again for each revision in step 4 Input: the change request, and the complete `loaded` brief from the context load phase. Pass the brief verbatim; do not restate, summarize, or reinterpret it. -This phase exclusively owns: +This phase owns the planning process: -- Resolving whether the request targets a new or an existing plan. -- The clarification gate. -- Normalizing the change summary, acceptance criteria, constraints, and non-goals. -- Slicing the task stack into one-task/one-atomic-commit units. -- Writing `context/plans/{plan_name}.md`. +- Resolve whether the request targets a new or an existing plan. +- Challenge the change and run the clarification gate. +- Derive plan-specific content from the request and loaded context. +- Decide task boundaries, dependencies, and ordering. +- Write or revise exactly one `context/plans/{plan_name}.md`. -Do not duplicate any of it elsewhere in the workflow. - -Use the document format in `references/plan-template.md`. Read it before writing -the plan file. +`references/plan-template.md` is the sole owner of the persisted plan schema and +generic document-authoring rules: acceptance-criteria format and validation +semantics, task fields and atomic slicing, the no-validation-task rule, completion +records, and existing-plan update preservation. Read it before authoring or +revising and apply those rules rather than restating them here. The workflow renders this phase's result as the summary defined in `references/output.md`. @@ -48,8 +49,9 @@ undecidable. Determine whether the request targets a new plan or an existing plan in `context/plans/`. -When it targets an existing plan, read that plan before authoring. Preserve its -completed tasks, their recorded evidence, its structure, and its terminology. +When it targets an existing plan, read that plan before authoring. Apply the +`Updating an existing plan` rules in `references/plan-template.md` when writing; +this step only resolves which plan is being revised. When multiple existing plans match and none can be selected safely, return `blocked` with the matching candidates. @@ -151,33 +153,17 @@ Do not explore the entire repository by default. ## 2.5 Author the acceptance criteria -State how the finished plan is proven, before slicing tasks. - -Each criterion describes observable behavior of the finished system and names the -check that proves it. Record repository-wide checks once under `Full validation`, -and the durable context the change must be reflected in under `Context sync`. - -`/validate` runs this section after the last task completes. It is the only place -a plan says how it is validated. +Derive the plan-specific success outcomes and checks before slicing tasks, then +apply the `Acceptance criteria rules` and exact section shape in +`references/plan-template.md`. The template owns their generic validation +semantics and placement. ## 2.6 Author the task stack -Slice the work into sequential tasks `T01..T0N` using the task format and the -atomic slicing contract in `references/plan-template.md`. - -Every executable task must be completable and landable as one coherent commit. -Split any task that would require multiple independent commits. Convert broad -wrappers such as `polish` or `finalize` into specific outcomes with concrete -acceptance checks. - -Order tasks so each one's declared dependencies precede it. - -The last task is an ordinary implementation task. Do not author a trailing -validation-and-cleanup task, or any task whose only purpose is running the full -check suite, verifying durable context, or removing scaffolding. - -Confirm every acceptance criterion is satisfied by at least one task. When one is -not, the task stack is incomplete. +Slice and order the plan-specific work after the acceptance criteria, applying the +`Task rules` and `No validation task` rules in `references/plan-template.md`. +The template owns the task field shape, atomic-commit constraint, dependency-order +rule, acceptance-coverage rule, and generic task exclusions. A finished stack always leaves at least one incomplete task, so the workflow can always hand off to `/next-task`. When the request resolves to a plan but produces @@ -187,10 +173,8 @@ by completed tasks, set internal status `blocked` with category ## 2.7 Write the plan -Write `context/plans/{plan_name}.md` using `references/plan-template.md`. - -When updating an existing plan, keep completed tasks and their evidence intact, -and append or renumber new tasks without disturbing recorded history. +Write `context/plans/{plan_name}.md` by applying `references/plan-template.md` +exactly. For revisions, apply its `Updating an existing plan` rules. ## 2.8 Return the result @@ -249,8 +233,7 @@ Do not: - Run task execution. - Synchronize context. - Run final validation. -- Author a validation, cleanup, or context-verification task. `/validate` owns - that phase. +- Write a plan that violates `references/plan-template.md`. - Set internal status `plan_ready` for a plan with no incomplete task. - Create a Git commit. - Author more than one plan. diff --git a/.agents/skills/sce-change-to-plan/references/plan-template.md b/.agents/skills/sce-change-to-plan/references/plan-template.md index 19e8a12a0..416ac8a6b 100644 --- a/.agents/skills/sce-change-to-plan/references/plan-template.md +++ b/.agents/skills/sce-change-to-plan/references/plan-template.md @@ -129,6 +129,7 @@ invent one: `None.` is the expected answer for a well-specified change.} ## Task rules +- Number tasks sequentially as `T01..T0N`. - Every task is a checkbox line so progress stays machine-readable: `- [ ] T01: {title} (status:todo)`. - Author each executable task as one atomic commit unit by default. diff --git a/.claude/skills/sce-change-to-plan/references/plan-authoring.md b/.claude/skills/sce-change-to-plan/references/plan-authoring.md index 17e054e2d..98335bf34 100644 --- a/.claude/skills/sce-change-to-plan/references/plan-authoring.md +++ b/.claude/skills/sce-change-to-plan/references/plan-authoring.md @@ -5,18 +5,19 @@ Run this phase for step 2 of the workflow, and again for each revision in step 4 Input: the change request, and the complete `loaded` brief from the context load phase. Pass the brief verbatim; do not restate, summarize, or reinterpret it. -This phase exclusively owns: +This phase owns the planning process: -- Resolving whether the request targets a new or an existing plan. -- The clarification gate. -- Normalizing the change summary, acceptance criteria, constraints, and non-goals. -- Slicing the task stack into one-task/one-atomic-commit units. -- Writing `context/plans/{plan_name}.md`. +- Resolve whether the request targets a new or an existing plan. +- Challenge the change and run the clarification gate. +- Derive plan-specific content from the request and loaded context. +- Decide task boundaries, dependencies, and ordering. +- Write or revise exactly one `context/plans/{plan_name}.md`. -Do not duplicate any of it elsewhere in the workflow. - -Use the document format in `references/plan-template.md`. Read it before writing -the plan file. +`references/plan-template.md` is the sole owner of the persisted plan schema and +generic document-authoring rules: acceptance-criteria format and validation +semantics, task fields and atomic slicing, the no-validation-task rule, completion +records, and existing-plan update preservation. Read it before authoring or +revising and apply those rules rather than restating them here. The workflow renders this phase's result as the summary defined in `references/output.md`. @@ -48,8 +49,9 @@ undecidable. Determine whether the request targets a new plan or an existing plan in `context/plans/`. -When it targets an existing plan, read that plan before authoring. Preserve its -completed tasks, their recorded evidence, its structure, and its terminology. +When it targets an existing plan, read that plan before authoring. Apply the +`Updating an existing plan` rules in `references/plan-template.md` when writing; +this step only resolves which plan is being revised. When multiple existing plans match and none can be selected safely, return `blocked` with the matching candidates. @@ -151,33 +153,17 @@ Do not explore the entire repository by default. ## 2.5 Author the acceptance criteria -State how the finished plan is proven, before slicing tasks. - -Each criterion describes observable behavior of the finished system and names the -check that proves it. Record repository-wide checks once under `Full validation`, -and the durable context the change must be reflected in under `Context sync`. - -`/validate` runs this section after the last task completes. It is the only place -a plan says how it is validated. +Derive the plan-specific success outcomes and checks before slicing tasks, then +apply the `Acceptance criteria rules` and exact section shape in +`references/plan-template.md`. The template owns their generic validation +semantics and placement. ## 2.6 Author the task stack -Slice the work into sequential tasks `T01..T0N` using the task format and the -atomic slicing contract in `references/plan-template.md`. - -Every executable task must be completable and landable as one coherent commit. -Split any task that would require multiple independent commits. Convert broad -wrappers such as `polish` or `finalize` into specific outcomes with concrete -acceptance checks. - -Order tasks so each one's declared dependencies precede it. - -The last task is an ordinary implementation task. Do not author a trailing -validation-and-cleanup task, or any task whose only purpose is running the full -check suite, verifying durable context, or removing scaffolding. - -Confirm every acceptance criterion is satisfied by at least one task. When one is -not, the task stack is incomplete. +Slice and order the plan-specific work after the acceptance criteria, applying the +`Task rules` and `No validation task` rules in `references/plan-template.md`. +The template owns the task field shape, atomic-commit constraint, dependency-order +rule, acceptance-coverage rule, and generic task exclusions. A finished stack always leaves at least one incomplete task, so the workflow can always hand off to `/next-task`. When the request resolves to a plan but produces @@ -187,10 +173,8 @@ by completed tasks, set internal status `blocked` with category ## 2.7 Write the plan -Write `context/plans/{plan_name}.md` using `references/plan-template.md`. - -When updating an existing plan, keep completed tasks and their evidence intact, -and append or renumber new tasks without disturbing recorded history. +Write `context/plans/{plan_name}.md` by applying `references/plan-template.md` +exactly. For revisions, apply its `Updating an existing plan` rules. ## 2.8 Return the result @@ -249,8 +233,7 @@ Do not: - Run task execution. - Synchronize context. - Run final validation. -- Author a validation, cleanup, or context-verification task. `/validate` owns - that phase. +- Write a plan that violates `references/plan-template.md`. - Set internal status `plan_ready` for a plan with no incomplete task. - Create a Git commit. - Author more than one plan. diff --git a/.claude/skills/sce-change-to-plan/references/plan-template.md b/.claude/skills/sce-change-to-plan/references/plan-template.md index 19e8a12a0..416ac8a6b 100644 --- a/.claude/skills/sce-change-to-plan/references/plan-template.md +++ b/.claude/skills/sce-change-to-plan/references/plan-template.md @@ -129,6 +129,7 @@ invent one: `None.` is the expected answer for a well-specified change.} ## Task rules +- Number tasks sequentially as `T01..T0N`. - Every task is a checkbox line so progress stays machine-readable: `- [ ] T01: {title} (status:todo)`. - Author each executable task as one atomic commit unit by default. diff --git a/.pi/skills/sce-change-to-plan/references/plan-authoring.md b/.pi/skills/sce-change-to-plan/references/plan-authoring.md index 17e054e2d..98335bf34 100644 --- a/.pi/skills/sce-change-to-plan/references/plan-authoring.md +++ b/.pi/skills/sce-change-to-plan/references/plan-authoring.md @@ -5,18 +5,19 @@ Run this phase for step 2 of the workflow, and again for each revision in step 4 Input: the change request, and the complete `loaded` brief from the context load phase. Pass the brief verbatim; do not restate, summarize, or reinterpret it. -This phase exclusively owns: +This phase owns the planning process: -- Resolving whether the request targets a new or an existing plan. -- The clarification gate. -- Normalizing the change summary, acceptance criteria, constraints, and non-goals. -- Slicing the task stack into one-task/one-atomic-commit units. -- Writing `context/plans/{plan_name}.md`. +- Resolve whether the request targets a new or an existing plan. +- Challenge the change and run the clarification gate. +- Derive plan-specific content from the request and loaded context. +- Decide task boundaries, dependencies, and ordering. +- Write or revise exactly one `context/plans/{plan_name}.md`. -Do not duplicate any of it elsewhere in the workflow. - -Use the document format in `references/plan-template.md`. Read it before writing -the plan file. +`references/plan-template.md` is the sole owner of the persisted plan schema and +generic document-authoring rules: acceptance-criteria format and validation +semantics, task fields and atomic slicing, the no-validation-task rule, completion +records, and existing-plan update preservation. Read it before authoring or +revising and apply those rules rather than restating them here. The workflow renders this phase's result as the summary defined in `references/output.md`. @@ -48,8 +49,9 @@ undecidable. Determine whether the request targets a new plan or an existing plan in `context/plans/`. -When it targets an existing plan, read that plan before authoring. Preserve its -completed tasks, their recorded evidence, its structure, and its terminology. +When it targets an existing plan, read that plan before authoring. Apply the +`Updating an existing plan` rules in `references/plan-template.md` when writing; +this step only resolves which plan is being revised. When multiple existing plans match and none can be selected safely, return `blocked` with the matching candidates. @@ -151,33 +153,17 @@ Do not explore the entire repository by default. ## 2.5 Author the acceptance criteria -State how the finished plan is proven, before slicing tasks. - -Each criterion describes observable behavior of the finished system and names the -check that proves it. Record repository-wide checks once under `Full validation`, -and the durable context the change must be reflected in under `Context sync`. - -`/validate` runs this section after the last task completes. It is the only place -a plan says how it is validated. +Derive the plan-specific success outcomes and checks before slicing tasks, then +apply the `Acceptance criteria rules` and exact section shape in +`references/plan-template.md`. The template owns their generic validation +semantics and placement. ## 2.6 Author the task stack -Slice the work into sequential tasks `T01..T0N` using the task format and the -atomic slicing contract in `references/plan-template.md`. - -Every executable task must be completable and landable as one coherent commit. -Split any task that would require multiple independent commits. Convert broad -wrappers such as `polish` or `finalize` into specific outcomes with concrete -acceptance checks. - -Order tasks so each one's declared dependencies precede it. - -The last task is an ordinary implementation task. Do not author a trailing -validation-and-cleanup task, or any task whose only purpose is running the full -check suite, verifying durable context, or removing scaffolding. - -Confirm every acceptance criterion is satisfied by at least one task. When one is -not, the task stack is incomplete. +Slice and order the plan-specific work after the acceptance criteria, applying the +`Task rules` and `No validation task` rules in `references/plan-template.md`. +The template owns the task field shape, atomic-commit constraint, dependency-order +rule, acceptance-coverage rule, and generic task exclusions. A finished stack always leaves at least one incomplete task, so the workflow can always hand off to `/next-task`. When the request resolves to a plan but produces @@ -187,10 +173,8 @@ by completed tasks, set internal status `blocked` with category ## 2.7 Write the plan -Write `context/plans/{plan_name}.md` using `references/plan-template.md`. - -When updating an existing plan, keep completed tasks and their evidence intact, -and append or renumber new tasks without disturbing recorded history. +Write `context/plans/{plan_name}.md` by applying `references/plan-template.md` +exactly. For revisions, apply its `Updating an existing plan` rules. ## 2.8 Return the result @@ -249,8 +233,7 @@ Do not: - Run task execution. - Synchronize context. - Run final validation. -- Author a validation, cleanup, or context-verification task. `/validate` owns - that phase. +- Write a plan that violates `references/plan-template.md`. - Set internal status `plan_ready` for a plan with no incomplete task. - Create a Git commit. - Author more than one plan. diff --git a/.pi/skills/sce-change-to-plan/references/plan-template.md b/.pi/skills/sce-change-to-plan/references/plan-template.md index 19e8a12a0..416ac8a6b 100644 --- a/.pi/skills/sce-change-to-plan/references/plan-template.md +++ b/.pi/skills/sce-change-to-plan/references/plan-template.md @@ -129,6 +129,7 @@ invent one: `None.` is the expected answer for a well-specified change.} ## Task rules +- Number tasks sequentially as `T01..T0N`. - Every task is a checkbox line so progress stays machine-readable: `- [ ] T01: {title} (status:todo)`. - Author each executable task as one atomic commit unit by default. diff --git a/config/pkl/base/workflow-change-to-plan.pkl b/config/pkl/base/workflow-change-to-plan.pkl index c5ed8c1c3..c55eaa0e4 100644 --- a/config/pkl/base/workflow-change-to-plan.pkl +++ b/config/pkl/base/workflow-change-to-plan.pkl @@ -248,18 +248,19 @@ Run this phase for step 2 of the workflow, and again for each revision in step 4 Input: the change request, and the complete `loaded` brief from the context load phase. Pass the brief verbatim; do not restate, summarize, or reinterpret it. -This phase exclusively owns: +This phase owns the planning process: -- Resolving whether the request targets a new or an existing plan. -- The clarification gate. -- Normalizing the change summary, acceptance criteria, constraints, and non-goals. -- Slicing the task stack into one-task/one-atomic-commit units. -- Writing `context/plans/{plan_name}.md`. +- Resolve whether the request targets a new or an existing plan. +- Challenge the change and run the clarification gate. +- Derive plan-specific content from the request and loaded context. +- Decide task boundaries, dependencies, and ordering. +- Write or revise exactly one `context/plans/{plan_name}.md`. -Do not duplicate any of it elsewhere in the workflow. - -Use the document format in `references/plan-template.md`. Read it before writing -the plan file. +`references/plan-template.md` is the sole owner of the persisted plan schema and +generic document-authoring rules: acceptance-criteria format and validation +semantics, task fields and atomic slicing, the no-validation-task rule, completion +records, and existing-plan update preservation. Read it before authoring or +revising and apply those rules rather than restating them here. The workflow renders this phase's result as the summary defined in `references/output.md`. @@ -291,8 +292,9 @@ undecidable. Determine whether the request targets a new plan or an existing plan in `context/plans/`. -When it targets an existing plan, read that plan before authoring. Preserve its -completed tasks, their recorded evidence, its structure, and its terminology. +When it targets an existing plan, read that plan before authoring. Apply the +`Updating an existing plan` rules in `references/plan-template.md` when writing; +this step only resolves which plan is being revised. When multiple existing plans match and none can be selected safely, return `blocked` with the matching candidates. @@ -394,33 +396,17 @@ Do not explore the entire repository by default. ## 2.5 Author the acceptance criteria -State how the finished plan is proven, before slicing tasks. - -Each criterion describes observable behavior of the finished system and names the -check that proves it. Record repository-wide checks once under `Full validation`, -and the durable context the change must be reflected in under `Context sync`. - -`/validate` runs this section after the last task completes. It is the only place -a plan says how it is validated. +Derive the plan-specific success outcomes and checks before slicing tasks, then +apply the `Acceptance criteria rules` and exact section shape in +`references/plan-template.md`. The template owns their generic validation +semantics and placement. ## 2.6 Author the task stack -Slice the work into sequential tasks `T01..T0N` using the task format and the -atomic slicing contract in `references/plan-template.md`. - -Every executable task must be completable and landable as one coherent commit. -Split any task that would require multiple independent commits. Convert broad -wrappers such as `polish` or `finalize` into specific outcomes with concrete -acceptance checks. - -Order tasks so each one's declared dependencies precede it. - -The last task is an ordinary implementation task. Do not author a trailing -validation-and-cleanup task, or any task whose only purpose is running the full -check suite, verifying durable context, or removing scaffolding. - -Confirm every acceptance criterion is satisfied by at least one task. When one is -not, the task stack is incomplete. +Slice and order the plan-specific work after the acceptance criteria, applying the +`Task rules` and `No validation task` rules in `references/plan-template.md`. +The template owns the task field shape, atomic-commit constraint, dependency-order +rule, acceptance-coverage rule, and generic task exclusions. A finished stack always leaves at least one incomplete task, so the workflow can always hand off to `/next-task`. When the request resolves to a plan but produces @@ -430,10 +416,8 @@ by completed tasks, set internal status `blocked` with category ## 2.7 Write the plan -Write `context/plans/{plan_name}.md` using `references/plan-template.md`. - -When updating an existing plan, keep completed tasks and their evidence intact, -and append or renumber new tasks without disturbing recorded history. +Write `context/plans/{plan_name}.md` by applying `references/plan-template.md` +exactly. For revisions, apply its `Updating an existing plan` rules. ## 2.8 Return the result @@ -492,8 +476,7 @@ Do not: - Run task execution. - Synchronize context. - Run final validation. -- Author a validation, cleanup, or context-verification task. `/validate` owns - that phase. +- Write a plan that violates `references/plan-template.md`. - Set internal status `plan_ready` for a plan with no incomplete task. - Create a Git commit. - Author more than one plan. @@ -633,6 +616,7 @@ invent one: `None.` is the expected answer for a well-specified change.} ## Task rules +- Number tasks sequentially as `T01..T0N`. - Every task is a checkbox line so progress stays machine-readable: `- [ ] T01: {title} (status:todo)`. - Author each executable task as one atomic commit unit by default. diff --git a/config/pkl/renderers/generation-contract-check.pkl b/config/pkl/renderers/generation-contract-check.pkl index 9a49b828b..28bc40ec1 100644 --- a/config/pkl/renderers/generation-contract-check.pkl +++ b/config/pkl/renderers/generation-contract-check.pkl @@ -829,6 +829,37 @@ hidden assertCompactPlanTemplateSchema = (documents: Mapping) -> ) "generated plan template: compact task/completion schema present, legacy fields absent" else throw("generated plan-template.md must use the compact task and completion schema and must not reference the removed Goal, Boundaries (in/out of scope), Verification notes, Implementation evidence, Verification evidence, or Context synchronization handoff fields") +local planTemplateOwnedPolicyTokens = new Listing { + "Acceptance criteria describe the finished system, not the work." + "Every criterion carries a `Validate:` line." + "List repository-wide checks once under `Full validation`" + "Number tasks sequentially as `T01..T0N`." + "Author each executable task as one atomic commit unit by default." + "Split any candidate task that would require multiple independent commits" + "The last task in the stack is an ordinary implementation task." + "Preserve completed tasks, their `(status:done)` markers" +} + +local requiredPlanAuthoringTemplateReferences = new Listing { + "`references/plan-template.md` is the sole owner of the persisted plan schema" + "`Acceptance criteria rules`" + "`Task rules` and `No validation task` rules" + "`Updating an existing plan` rules" +} + +hidden assertPlanTemplatePolicyOwnership = (documents: Mapping) -> + if ( + documents.every((path, text) -> + if (path.endsWith("/skills/sce-change-to-plan/references/plan-template.md")) + planTemplateOwnedPolicyTokens.every((token) -> text.contains(token)) + else if (path.endsWith("/skills/sce-change-to-plan/references/plan-authoring.md")) + requiredPlanAuthoringTemplateReferences.every((token) -> text.contains(token)) + && planTemplateOwnedPolicyTokens.every((token) -> !text.contains(token)) + else true + ) + ) "sce-change-to-plan: plan-template owns persisted schema and generic authoring policy" + else throw("sce-change-to-plan plan-template.md must own the persisted plan schema and generic acceptance/task/update rules; plan-authoring.md may reference those rules but must not restate them") + local requiredNextTaskCompletionWritingTokens = new Listing { "Record directly on the completed task:" "`Files changed`" @@ -1038,6 +1069,7 @@ contractChecks { ["no-stale-sync-debt-text"] = assertNoStaleSyncDebtText.apply(generatedArtifacts) ["plan-review-sync-debt-recovery"] = assertPlanReviewSyncDebtRecovery.apply(workflowDocuments) ["compact-plan-template-schema"] = assertCompactPlanTemplateSchema.apply(workflowDocuments) + ["plan-template-policy-ownership"] = assertPlanTemplatePolicyOwnership.apply(workflowDocuments) ["next-task-compact-completion-writing"] = assertNextTaskCompactCompletionWriting.apply(workflowDocuments) ["plan-review-reads-completed-record"] = assertPlanReviewReadsCompletedRecord.apply(workflowDocuments) ["context-sync-validates-task-record"] = assertContextSyncValidatesTaskRecord.apply(workflowDocuments) diff --git a/context/plans/compress-workflow-execution-preamble.md b/context/plans/compress-workflow-execution-preamble.md index 920a507cf..b4c3f9888 100644 --- a/context/plans/compress-workflow-execution-preamble.md +++ b/context/plans/compress-workflow-execution-preamble.md @@ -337,3 +337,27 @@ The two additional root edits replace existing text without increasing line coun `nix run .#pkl-check-generated`, targeted Pi/Claude/Codex ownership assertions, and `git diff --check`. - Context synchronization: synced. + + +## Follow-up: plan-template authoring-policy ownership + +- [x] T06: `Deduplicate plan authoring from the persisted plan template` (status:done) + - Scope: change-to-plan plan-authoring and plan-template references, canonical Pkl, + generated semantic checks, tracked Pi/Claude/Codex mirrors, and the ownership table. + - Ownership after change: `references/plan-template.md` solely owns the persisted + plan schema plus generic acceptance-criteria, task-format/atomic-slicing, + no-validation-task, completion-record, and existing-plan-update rules. The + Plan authoring phase owns process order, plan-specific decisions, clarification, + and the `no_actionable_work` outcome, and references the template at write boundaries. + - Behavior preserved: criteria are still authored before tasks; tasks remain + sequential atomic-commit units with ordered dependencies and no trailing validation + task; existing completed-task history stays protected; every written plan still uses + the same persisted schema. The sequential `T01..T0N` rule moved into the template + rather than being dropped. + - Result: plan-authoring + plan-template shrink by 16 Markdown + lines per tracked target, 48 lines across + Pi/Claude/Codex. + - Verify: `pkl eval config/pkl/renderers/generation-contract-check.pkl`, + `nix run .#pkl-check-generated`, targeted ownership assertions across all three + tracked targets, and `git diff --check`. + - Context synchronization: synced. diff --git a/context/sce/dedup-ownership-table.md b/context/sce/dedup-ownership-table.md index a9306b6f1..9e4f4db51 100644 --- a/context/sce/dedup-ownership-table.md +++ b/context/sce/dedup-ownership-table.md @@ -15,7 +15,8 @@ | Behavior domain | Canonical owner | Reference-only consumers | Label | | --- | --- | --- | --- | | Context discovery before planning | `sce-context-load` in `workflow-change-to-plan.pkl` | `/change-to-plan`; composed into `sce-change-to-plan` | intentional/keep | -| Plan authoring, clarification, and task slicing | `sce-plan-authoring` in `workflow-change-to-plan.pkl` | `/change-to-plan`; composed into `sce-change-to-plan`; thin OpenCode Plan agent | intentional/keep | +| Plan authoring process, clarification, and plan-specific task slicing | `sce-plan-authoring` in `workflow-change-to-plan.pkl` | `/change-to-plan`; reads the template before every write/revision; composed into `sce-change-to-plan`; thin OpenCode Plan agent | intentional/keep | +| Persisted plan schema and generic authoring rules | `references/plan-template.md` generated from `changeToPlanPlanTemplate` in `workflow-change-to-plan.pkl` | Plan authoring derives plan-specific content and applies the template's acceptance, task, no-validation-task, completion-record, and existing-plan-update rules without restating them | intentional/keep | | Task resolution and readiness | `sce-plan-review` in `workflow-next-task.pkl` | `/next-task`; composed into `sce-next-task`; thin OpenCode Code agent | intentional/keep | | Approval-gated one-task implementation | `sce-task-execution` in `workflow-next-task.pkl` | `/next-task` parses and conditionally passes `approve`; `references/output.md` owns only exact gate content/order; composed into `sce-next-task`; thin OpenCode Code agent | intentional/keep | | Live post-task execution handoff schema | composite `references/task-execution.md` generated from `nextTaskTaskExecutionReference` | `/next-task` passes the `complete` result verbatim; composite task context sync validates and consumes that contract without restating the live field list; package mode retains `references/execution-contract.yaml`; cross-session retry records remain a separate persisted shape | intentional/keep | From 9559ff97a3b664787fda04331f44dc85c73a07aa Mon Sep 17 00:00:00 2001 From: David Abram Date: Tue, 8 Sep 2026 11:07:46 +0000 Subject: [PATCH 07/12] config: Deduplicate commit bypass execution --- .agents/skills/sce-commit/SKILL.md | 18 +++----- .../sce-commit/references/atomic-commit.md | 5 ++- .claude/skills/sce-commit/SKILL.md | 18 +++----- .../sce-commit/references/atomic-commit.md | 5 ++- .pi/skills/sce-commit/SKILL.md | 18 +++----- .../sce-commit/references/atomic-commit.md | 5 ++- config/pkl/base/workflow-commit.pkl | 42 ++++++------------- .../renderers/generation-contract-check.pkl | 31 ++++++++++++++ .../compress-workflow-execution-preamble.md | 21 ++++++++++ context/sce/dedup-ownership-table.md | 1 + 10 files changed, 90 insertions(+), 74 deletions(-) diff --git a/.agents/skills/sce-commit/SKILL.md b/.agents/skills/sce-commit/SKILL.md index 37e69ce35..32c687074 100644 --- a/.agents/skills/sce-commit/SKILL.md +++ b/.agents/skills/sce-commit/SKILL.md @@ -120,25 +120,17 @@ a contract violation: report it and stop without committing. #### 3. Execute exactly one commit -Follow the **Bypass execution handoff** in `references/atomic-commit.md`: - -1. Create the commit-message temp file outside the repository working tree, and - write the returned `message` verbatim to it using a file-writing operation. Do - not interpolate the multiline message into shell source or a shell command. -2. Run `git commit -F ` exactly once. -3. Only after that command succeeds, retrieve the commit hash explicitly with - `git rev-parse --verify HEAD^{commit}`. Do not parse Git's human-readable - output. -4. Delete the temp file after the commit attempt, including on failure, where - practical. +Follow the **Bypass execution handoff** in `references/atomic-commit.md` exactly +as written. That handoff is the sole owner of the execution sequence; do not +reconstruct, supplement, or restate it here. On success, render the **Bypass success** layout from `references/output.md` and stop. On failure, render the **Bypass Git failure** layout from the same file and stop. -Do not retry, do not amend, do not stage additional files, and do not fabricate a -commit hash. +The handoff owns commit-failure handling. This workflow owns only the matching +user-visible result layout above. ## Rules diff --git a/.agents/skills/sce-commit/references/atomic-commit.md b/.agents/skills/sce-commit/references/atomic-commit.md index b41d362ad..5df2c0a8b 100644 --- a/.agents/skills/sce-commit/references/atomic-commit.md +++ b/.agents/skills/sce-commit/references/atomic-commit.md @@ -106,8 +106,9 @@ Confirm before returning that: ## Bypass execution handoff -This phase returns the message; the invoking `/commit` workflow performs the -bypass commit. When the mode is `bypass`, the invoking workflow must: +This subsection is the sole definition of the bypass execution sequence. This +phase returns the message; when the mode is `bypass`, the invoking `/commit` +workflow performs this handoff exactly as written: 1. Create the commit-message temp file outside the repository working tree, and write the returned `message` verbatim to it using a file-writing diff --git a/.claude/skills/sce-commit/SKILL.md b/.claude/skills/sce-commit/SKILL.md index 56693758c..fff451dd5 100644 --- a/.claude/skills/sce-commit/SKILL.md +++ b/.claude/skills/sce-commit/SKILL.md @@ -119,25 +119,17 @@ a contract violation: report it and stop without committing. #### 3. Execute exactly one commit -Follow the **Bypass execution handoff** in `references/atomic-commit.md`: - -1. Create the commit-message temp file outside the repository working tree, and - write the returned `message` verbatim to it using a file-writing operation. Do - not interpolate the multiline message into shell source or a shell command. -2. Run `git commit -F ` exactly once. -3. Only after that command succeeds, retrieve the commit hash explicitly with - `git rev-parse --verify HEAD^{commit}`. Do not parse Git's human-readable - output. -4. Delete the temp file after the commit attempt, including on failure, where - practical. +Follow the **Bypass execution handoff** in `references/atomic-commit.md` exactly +as written. That handoff is the sole owner of the execution sequence; do not +reconstruct, supplement, or restate it here. On success, render the **Bypass success** layout from `references/output.md` and stop. On failure, render the **Bypass Git failure** layout from the same file and stop. -Do not retry, do not amend, do not stage additional files, and do not fabricate a -commit hash. +The handoff owns commit-failure handling. This workflow owns only the matching +user-visible result layout above. ## Rules diff --git a/.claude/skills/sce-commit/references/atomic-commit.md b/.claude/skills/sce-commit/references/atomic-commit.md index b41d362ad..5df2c0a8b 100644 --- a/.claude/skills/sce-commit/references/atomic-commit.md +++ b/.claude/skills/sce-commit/references/atomic-commit.md @@ -106,8 +106,9 @@ Confirm before returning that: ## Bypass execution handoff -This phase returns the message; the invoking `/commit` workflow performs the -bypass commit. When the mode is `bypass`, the invoking workflow must: +This subsection is the sole definition of the bypass execution sequence. This +phase returns the message; when the mode is `bypass`, the invoking `/commit` +workflow performs this handoff exactly as written: 1. Create the commit-message temp file outside the repository working tree, and write the returned `message` verbatim to it using a file-writing diff --git a/.pi/skills/sce-commit/SKILL.md b/.pi/skills/sce-commit/SKILL.md index b92e98651..3087c1eb7 100644 --- a/.pi/skills/sce-commit/SKILL.md +++ b/.pi/skills/sce-commit/SKILL.md @@ -118,25 +118,17 @@ a contract violation: report it and stop without committing. #### 3. Execute exactly one commit -Follow the **Bypass execution handoff** in `references/atomic-commit.md`: - -1. Create the commit-message temp file outside the repository working tree, and - write the returned `message` verbatim to it using a file-writing operation. Do - not interpolate the multiline message into shell source or a shell command. -2. Run `git commit -F ` exactly once. -3. Only after that command succeeds, retrieve the commit hash explicitly with - `git rev-parse --verify HEAD^{commit}`. Do not parse Git's human-readable - output. -4. Delete the temp file after the commit attempt, including on failure, where - practical. +Follow the **Bypass execution handoff** in `references/atomic-commit.md` exactly +as written. That handoff is the sole owner of the execution sequence; do not +reconstruct, supplement, or restate it here. On success, render the **Bypass success** layout from `references/output.md` and stop. On failure, render the **Bypass Git failure** layout from the same file and stop. -Do not retry, do not amend, do not stage additional files, and do not fabricate a -commit hash. +The handoff owns commit-failure handling. This workflow owns only the matching +user-visible result layout above. ## Rules diff --git a/.pi/skills/sce-commit/references/atomic-commit.md b/.pi/skills/sce-commit/references/atomic-commit.md index b41d362ad..5df2c0a8b 100644 --- a/.pi/skills/sce-commit/references/atomic-commit.md +++ b/.pi/skills/sce-commit/references/atomic-commit.md @@ -106,8 +106,9 @@ Confirm before returning that: ## Bypass execution handoff -This phase returns the message; the invoking `/commit` workflow performs the -bypass commit. When the mode is `bypass`, the invoking workflow must: +This subsection is the sole definition of the bypass execution sequence. This +phase returns the message; when the mode is `bypass`, the invoking `/commit` +workflow performs this handoff exactly as written: 1. Create the commit-message temp file outside the repository working tree, and write the returned `message` verbatim to it using a file-writing diff --git a/config/pkl/base/workflow-commit.pkl b/config/pkl/base/workflow-commit.pkl index 06cafd518..612fa1178 100644 --- a/config/pkl/base/workflow-commit.pkl +++ b/config/pkl/base/workflow-commit.pkl @@ -202,23 +202,14 @@ local renderCommandBody = (mode: model.WorkflowRenderMode) -> """ #### 3. Execute exactly one commit - Follow the **Bypass execution handoff** in the Atomic commit reference: - - 1. Create the commit-message temp file outside the repository working tree, - and write the returned `message` verbatim to it using a file-writing - operation. Do not interpolate the multiline message into shell source or a - shell command. - 2. Run `git commit -F ` exactly once. - 3. Only after that command succeeds, retrieve the commit hash explicitly with - `git rev-parse --verify HEAD^{commit}`. Do not parse Git's human-readable - output. - 4. Delete the temp file after the commit attempt, including on failure, where - practical. + Follow the **Bypass execution handoff** in the Atomic commit reference exactly + as written. That handoff is the sole owner of the execution sequence; do not + reconstruct, supplement, or restate it here. \(bypassResultLayouts.render.apply(mode)) - On failure, report Git's failure unchanged and do not retry, amend, stage more - files, or fabricate a commit hash. + The handoff owns commit-failure handling. This workflow owns only the matching + user-visible result layout above. ## Rules @@ -359,8 +350,9 @@ local renderAtomicCommitSkillBody = (mode: model.WorkflowRenderMode) -> """ \(atomicCommitHeadings.section.apply(mode, "Bypass execution handoff")) - This phase returns the message; the invoking `/commit` workflow performs the - bypass commit. When the mode is `bypass`, the invoking workflow must: + This subsection is the sole definition of the bypass execution sequence. This + phase returns the message; when the mode is `bypass`, the invoking `/commit` + workflow performs this handoff exactly as written: 1. Create the commit-message temp file outside the repository working tree, and write the returned `message` verbatim to it using a file-writing @@ -581,25 +573,17 @@ a contract violation: report it and stop without committing. #### 3. Execute exactly one commit -Follow the **Bypass execution handoff** in `references/atomic-commit.md`: - -1. Create the commit-message temp file outside the repository working tree, and - write the returned `message` verbatim to it using a file-writing operation. Do - not interpolate the multiline message into shell source or a shell command. -2. Run `git commit -F ` exactly once. -3. Only after that command succeeds, retrieve the commit hash explicitly with - `git rev-parse --verify HEAD^{commit}`. Do not parse Git's human-readable - output. -4. Delete the temp file after the commit attempt, including on failure, where - practical. +Follow the **Bypass execution handoff** in `references/atomic-commit.md` exactly +as written. That handoff is the sole owner of the execution sequence; do not +reconstruct, supplement, or restate it here. On success, render the **Bypass success** layout from `references/output.md` and stop. On failure, render the **Bypass Git failure** layout from the same file and stop. -Do not retry, do not amend, do not stage additional files, and do not fabricate a -commit hash. +The handoff owns commit-failure handling. This workflow owns only the matching +user-visible result layout above. ## Rules diff --git a/config/pkl/renderers/generation-contract-check.pkl b/config/pkl/renderers/generation-contract-check.pkl index 28bc40ec1..8d40b5072 100644 --- a/config/pkl/renderers/generation-contract-check.pkl +++ b/config/pkl/renderers/generation-contract-check.pkl @@ -726,6 +726,36 @@ hidden assertAtomicCommitContent = (documents: Mapping) -> ) "sce-commit atomic reference: delegates message style and omits the result contract" else throw("atomic-commit.md must delegate message rules to commit-message-style.md and omit the removed result contract") +local requiredCommitBypassExecutionTokens = new Listing { + "This subsection is the sole definition of the bypass execution sequence." + "write the returned `message` verbatim" + "`git commit -F ` exactly once" + "`git rev-parse --verify HEAD^{commit}`" + "Delete the temp file after the commit attempt" + "Never retry, amend" +} + +local forbiddenCommitBypassEntrypointSequenceTokens = new Listing { + "write the returned `message` verbatim" + "`git commit -F ` exactly once" + "`git rev-parse --verify HEAD^{commit}`" + "Delete the temp file after the commit attempt" +} + +hidden assertCommitBypassExecutionOwnership = (documents: Mapping) -> + if ( + documents.every((path, text) -> + if (path.endsWith("/skills/sce-commit/references/atomic-commit.md")) + requiredCommitBypassExecutionTokens.every((token) -> text.contains(token)) + else if (path.endsWith("/skills/sce-commit/SKILL.md")) + text.contains("Follow the **Bypass execution handoff** in `references/atomic-commit.md` exactly") + && text.contains("That handoff is the sole owner of the execution sequence") + && forbiddenCommitBypassEntrypointSequenceTokens.every((token) -> !text.contains(token)) + else true + ) + ) "sce-commit bypass execution: atomic reference solely owns the exact execution sequence" + else throw("sce-commit must define the exact bypass temp-file/commit/hash/cleanup sequence only in references/atomic-commit.md; SKILL.md may invoke that handoff but must not restate it") + hidden assertNextTaskReportOwnership = (documents: Mapping) -> if ( documents.every((path, text) -> @@ -1064,6 +1094,7 @@ contractChecks { ["validate-forbidden-paths"] = assertValidateForbiddenPaths.apply(generatedArtifacts) ["commit-forbidden-paths"] = assertCommitForbiddenPaths.apply(generatedArtifacts) ["atomic-commit-content"] = assertAtomicCommitContent.apply(workflowDocuments) + ["commit-bypass-execution-ownership"] = assertCommitBypassExecutionOwnership.apply(workflowDocuments) ["next-task-report-ownership"] = assertNextTaskReportOwnership.apply(workflowDocuments) ["target-neutral-references"] = assertTargetNeutralReferences.apply(workflowDocuments) ["no-stale-sync-debt-text"] = assertNoStaleSyncDebtText.apply(generatedArtifacts) diff --git a/context/plans/compress-workflow-execution-preamble.md b/context/plans/compress-workflow-execution-preamble.md index b4c3f9888..728ae00f3 100644 --- a/context/plans/compress-workflow-execution-preamble.md +++ b/context/plans/compress-workflow-execution-preamble.md @@ -361,3 +361,24 @@ The two additional root edits replace existing text without increasing line coun `nix run .#pkl-check-generated`, targeted ownership assertions across all three tracked targets, and `git diff --check`. - Context synchronization: synced. + + +## Follow-up: commit bypass execution ownership + +- [x] T07: `Deduplicate commit bypass execution sequence` (status:done) + - Scope: `sce-commit` bypass step 3, the atomic-commit bypass handoff, canonical + Pkl, generated semantic checks, tracked Pi/Claude/Codex mirrors, and the ownership table. + - Ownership after change: `references/atomic-commit.md` **Bypass execution handoff** + solely defines the temp-file, verbatim-message write, single `git commit -F`, + post-success `HEAD^{commit}` lookup, commit-failure behavior, and cleanup sequence. + `/commit` invokes that handoff once and owns only success/failure layout selection. + - Behavior preserved: `oneshot` and `skip` remain identical; bypass still commits + at most once, never stages, never retries or amends, reads the hash only after a + successful commit, reports Git failure unchanged, and cleans up the temp file where practical. + - Result: `sce-commit/SKILL.md` plus `references/atomic-commit.md` shrink by + 7 Markdown lines per tracked target, 21 + lines across Pi/Claude/Codex. + - Verify: `pkl eval config/pkl/renderers/generation-contract-check.pkl`, + `nix run .#pkl-check-generated`, targeted ownership assertions across all three + tracked targets, and `git diff --check`. + - Context synchronization: synced. diff --git a/context/sce/dedup-ownership-table.md b/context/sce/dedup-ownership-table.md index 9e4f4db51..4cd739dd1 100644 --- a/context/sce/dedup-ownership-table.md +++ b/context/sce/dedup-ownership-table.md @@ -26,6 +26,7 @@ | Final validation and validation report | `sce-validation` in `workflow-validate.pkl` | `/validate`; composed into `sce-validate`; thin OpenCode Code agent | intentional/keep | | Validated-plan durable context synchronization | Retained plan instance from `workflow-context-sync.pkl` | No current workflow consumer; `/validate` is validation-only | retained source, not generated | | Staged-diff analysis and commit-message authoring | `sce-atomic-commit` in `workflow-commit.pkl` | `/commit`; composed into `sce-commit`; thin OpenCode Code agent | intentional/keep | +| Bypass commit execution sequence | `references/atomic-commit.md` **Bypass execution handoff**, generated from `renderAtomicCommitSkillBody` in `workflow-commit.pkl` | `/commit` executes the handoff exactly once after `bypass_message`; the workflow owns success/failure layout selection but does not restate temp-file, commit, hash, cleanup, or retry procedure | intentional/keep | | Compact workflow execution contract | `executionContract` in `workflow-content.pkl` | Inline in change-to-plan, next-task, commit, validate, and handover entrypoints on all four targets; no extra runtime read | shared rendering, preserved behavior | | Workflow routing | Six command documents in the workflow modules | Thin OpenCode Plan/Code agents | intentional/keep | | Standalone ADR writing contract | `decision-skill.pkl` | Cross-target `sce-decision` package; successful task synchronization invokes it through the shared decision gate | intentional/keep | From 58b7cd0eaa905976cee4297bd2ec27f10c06be7b Mon Sep 17 00:00:00 2001 From: David Abram Date: Tue, 8 Sep 2026 11:32:54 +0000 Subject: [PATCH 08/12] config: Deduplicate validation report policy --- .../references/validation-report.md | 36 +++++++-------- .../sce-validate/references/validation.md | 6 +-- .../references/validation-report.md | 36 +++++++-------- .../sce-validate/references/validation.md | 6 +-- .../references/validation-report.md | 36 +++++++-------- .../sce-validate/references/validation.md | 6 +-- config/pkl/base/workflow-validate.pkl | 42 ++++++++---------- .../renderers/generation-contract-check.pkl | 44 +++++++++++++++++++ .../compress-workflow-execution-preamble.md | 25 +++++++++++ context/sce/dedup-ownership-table.md | 3 +- 10 files changed, 143 insertions(+), 97 deletions(-) diff --git a/.agents/skills/sce-validate/references/validation-report.md b/.agents/skills/sce-validate/references/validation-report.md index 3121e1a48..2d5ed6218 100644 --- a/.agents/skills/sce-validate/references/validation-report.md +++ b/.agents/skills/sce-validate/references/validation-report.md @@ -7,6 +7,12 @@ under exactly one `## Validation Report` heading. This is plan-file content. The result returned to the workflow is defined separately in `references/validation.md`. +This reference owns only the persisted report's structure and presentation. +Validation execution owns command selection and execution, evidence +interpretation, acceptance-criterion state, outcome classification, and the +non-repairing boundary. Consume those results here; do not redefine or rerun +validation policy in this report reference. + Do not author this section while planning. Only `/validate` through `sce-validation` writes it. @@ -49,28 +55,18 @@ After repairs, rerun: ## Rules -- Use **Status:** `validated` only when every acceptance criterion is met and - every required full-validation command passed. -- Use **Status:** `failed` when evidence was captured but required checks or - criteria remain unsatisfied. -- List every command that ran under **Commands run**, including ones that - failed. Do not invent exit codes or outcomes. -- Prefer the plan's `Full validation` commands and each criterion's `Validate:` - line over rediscovering project defaults. Fall back to repository conventions - only when the plan omits them. -- Mark each acceptance criterion checkbox in the plan's `## Acceptance criteria` - section to match the evidence. Do not mark a criterion met unless the check - ran successfully or the inspection named by `Validate:` confirms it. -- Under **Failed checks and follow-ups**, record every failing check and its - evidence, including leftover debug-only flags, temporary artifacts, or local - scaffolding. Do not describe code or test edits made during validation; - validation does not modify tests or product code to clear failures. Write - `None.` when status is `validated`. +- Use the `validated` or `failed` status produced by validation execution; this + report does not redefine status-selection criteria. +- List every command result supplied by validation execution under **Commands + run**. Preserve its exit code and concise outcome; do not invent either. +- Under **Success-criteria verification**, render the acceptance-criterion + checkbox state and evidence already established by validation execution. Do + not independently re-evaluate or reclassify criteria here. +- Under **Failed checks and follow-ups**, render every failure and follow-up + supplied by validation execution. Write `None.` when status is `validated`. - When status is `failed`, always include **Retry** with the exact `/validate {plan path}` command. Omit **Retry** when status is `validated`. - Keep evidence concise and factual. Do not narrate the whole implementation - history. -- Do not claim durable context synchronization as part of validation. -- Do not rewrite task evidence or reopen completed tasks. + history or add execution-policy claims absent from the validation result. - When a previous `## Validation Report` already exists, replace it with the new one rather than stacking duplicates. diff --git a/.agents/skills/sce-validate/references/validation.md b/.agents/skills/sce-validate/references/validation.md index 1816eacaa..4b343f277 100644 --- a/.agents/skills/sce-validate/references/validation.md +++ b/.agents/skills/sce-validate/references/validation.md @@ -301,10 +301,8 @@ returns `validated`. - Name the exact `Plan:` path so every emitted command is runnable. - Use **Status:** exactly `validated`, `failed`, or `blocked`. -- Never claim a check passed unless it ran successfully or the authorized - inspection confirmed it. -- Do not modify tests or product code to clear a failure; record it under - **What failed**. +- Use the status and evidence already produced by validation execution; do not + upgrade, reinterpret, or invent results while formatting this report. - The failed variant must always end its **Recommended work** with `/validate {plan path}` as the final step after repairs. - The failed variant must be self-contained enough to hand to another session diff --git a/.claude/skills/sce-validate/references/validation-report.md b/.claude/skills/sce-validate/references/validation-report.md index 3121e1a48..2d5ed6218 100644 --- a/.claude/skills/sce-validate/references/validation-report.md +++ b/.claude/skills/sce-validate/references/validation-report.md @@ -7,6 +7,12 @@ under exactly one `## Validation Report` heading. This is plan-file content. The result returned to the workflow is defined separately in `references/validation.md`. +This reference owns only the persisted report's structure and presentation. +Validation execution owns command selection and execution, evidence +interpretation, acceptance-criterion state, outcome classification, and the +non-repairing boundary. Consume those results here; do not redefine or rerun +validation policy in this report reference. + Do not author this section while planning. Only `/validate` through `sce-validation` writes it. @@ -49,28 +55,18 @@ After repairs, rerun: ## Rules -- Use **Status:** `validated` only when every acceptance criterion is met and - every required full-validation command passed. -- Use **Status:** `failed` when evidence was captured but required checks or - criteria remain unsatisfied. -- List every command that ran under **Commands run**, including ones that - failed. Do not invent exit codes or outcomes. -- Prefer the plan's `Full validation` commands and each criterion's `Validate:` - line over rediscovering project defaults. Fall back to repository conventions - only when the plan omits them. -- Mark each acceptance criterion checkbox in the plan's `## Acceptance criteria` - section to match the evidence. Do not mark a criterion met unless the check - ran successfully or the inspection named by `Validate:` confirms it. -- Under **Failed checks and follow-ups**, record every failing check and its - evidence, including leftover debug-only flags, temporary artifacts, or local - scaffolding. Do not describe code or test edits made during validation; - validation does not modify tests or product code to clear failures. Write - `None.` when status is `validated`. +- Use the `validated` or `failed` status produced by validation execution; this + report does not redefine status-selection criteria. +- List every command result supplied by validation execution under **Commands + run**. Preserve its exit code and concise outcome; do not invent either. +- Under **Success-criteria verification**, render the acceptance-criterion + checkbox state and evidence already established by validation execution. Do + not independently re-evaluate or reclassify criteria here. +- Under **Failed checks and follow-ups**, render every failure and follow-up + supplied by validation execution. Write `None.` when status is `validated`. - When status is `failed`, always include **Retry** with the exact `/validate {plan path}` command. Omit **Retry** when status is `validated`. - Keep evidence concise and factual. Do not narrate the whole implementation - history. -- Do not claim durable context synchronization as part of validation. -- Do not rewrite task evidence or reopen completed tasks. + history or add execution-policy claims absent from the validation result. - When a previous `## Validation Report` already exists, replace it with the new one rather than stacking duplicates. diff --git a/.claude/skills/sce-validate/references/validation.md b/.claude/skills/sce-validate/references/validation.md index 1816eacaa..4b343f277 100644 --- a/.claude/skills/sce-validate/references/validation.md +++ b/.claude/skills/sce-validate/references/validation.md @@ -301,10 +301,8 @@ returns `validated`. - Name the exact `Plan:` path so every emitted command is runnable. - Use **Status:** exactly `validated`, `failed`, or `blocked`. -- Never claim a check passed unless it ran successfully or the authorized - inspection confirmed it. -- Do not modify tests or product code to clear a failure; record it under - **What failed**. +- Use the status and evidence already produced by validation execution; do not + upgrade, reinterpret, or invent results while formatting this report. - The failed variant must always end its **Recommended work** with `/validate {plan path}` as the final step after repairs. - The failed variant must be self-contained enough to hand to another session diff --git a/.pi/skills/sce-validate/references/validation-report.md b/.pi/skills/sce-validate/references/validation-report.md index 3121e1a48..2d5ed6218 100644 --- a/.pi/skills/sce-validate/references/validation-report.md +++ b/.pi/skills/sce-validate/references/validation-report.md @@ -7,6 +7,12 @@ under exactly one `## Validation Report` heading. This is plan-file content. The result returned to the workflow is defined separately in `references/validation.md`. +This reference owns only the persisted report's structure and presentation. +Validation execution owns command selection and execution, evidence +interpretation, acceptance-criterion state, outcome classification, and the +non-repairing boundary. Consume those results here; do not redefine or rerun +validation policy in this report reference. + Do not author this section while planning. Only `/validate` through `sce-validation` writes it. @@ -49,28 +55,18 @@ After repairs, rerun: ## Rules -- Use **Status:** `validated` only when every acceptance criterion is met and - every required full-validation command passed. -- Use **Status:** `failed` when evidence was captured but required checks or - criteria remain unsatisfied. -- List every command that ran under **Commands run**, including ones that - failed. Do not invent exit codes or outcomes. -- Prefer the plan's `Full validation` commands and each criterion's `Validate:` - line over rediscovering project defaults. Fall back to repository conventions - only when the plan omits them. -- Mark each acceptance criterion checkbox in the plan's `## Acceptance criteria` - section to match the evidence. Do not mark a criterion met unless the check - ran successfully or the inspection named by `Validate:` confirms it. -- Under **Failed checks and follow-ups**, record every failing check and its - evidence, including leftover debug-only flags, temporary artifacts, or local - scaffolding. Do not describe code or test edits made during validation; - validation does not modify tests or product code to clear failures. Write - `None.` when status is `validated`. +- Use the `validated` or `failed` status produced by validation execution; this + report does not redefine status-selection criteria. +- List every command result supplied by validation execution under **Commands + run**. Preserve its exit code and concise outcome; do not invent either. +- Under **Success-criteria verification**, render the acceptance-criterion + checkbox state and evidence already established by validation execution. Do + not independently re-evaluate or reclassify criteria here. +- Under **Failed checks and follow-ups**, render every failure and follow-up + supplied by validation execution. Write `None.` when status is `validated`. - When status is `failed`, always include **Retry** with the exact `/validate {plan path}` command. Omit **Retry** when status is `validated`. - Keep evidence concise and factual. Do not narrate the whole implementation - history. -- Do not claim durable context synchronization as part of validation. -- Do not rewrite task evidence or reopen completed tasks. + history or add execution-policy claims absent from the validation result. - When a previous `## Validation Report` already exists, replace it with the new one rather than stacking duplicates. diff --git a/.pi/skills/sce-validate/references/validation.md b/.pi/skills/sce-validate/references/validation.md index 1816eacaa..4b343f277 100644 --- a/.pi/skills/sce-validate/references/validation.md +++ b/.pi/skills/sce-validate/references/validation.md @@ -301,10 +301,8 @@ returns `validated`. - Name the exact `Plan:` path so every emitted command is runnable. - Use **Status:** exactly `validated`, `failed`, or `blocked`. -- Never claim a check passed unless it ran successfully or the authorized - inspection confirmed it. -- Do not modify tests or product code to clear a failure; record it under - **What failed**. +- Use the status and evidence already produced by validation execution; do not + upgrade, reinterpret, or invent results while formatting this report. - The failed variant must always end its **Recommended work** with `/validate {plan path}` as the final step after repairs. - The failed variant must be self-contained enough to hand to another session diff --git a/config/pkl/base/workflow-validate.pkl b/config/pkl/base/workflow-validate.pkl index 75d0ba3e8..c221fcd5b 100644 --- a/config/pkl/base/workflow-validate.pkl +++ b/config/pkl/base/workflow-validate.pkl @@ -360,6 +360,12 @@ local renderValidationReport = (mode: model.WorkflowRenderMode) -> """ This is plan-file content. The result returned to the workflow is defined separately in \(validationResultFileRef.render.apply(mode)). + + This reference owns only the persisted report's structure and presentation. + Validation execution owns command selection and execution, evidence + interpretation, acceptance-criterion state, outcome classification, and the + non-repairing boundary. Consume those results here; do not redefine or rerun + validation policy in this report reference. Do not author this section while planning. Only `/validate` through \(validation.render.apply(mode)) writes it. @@ -403,29 +409,19 @@ local renderValidationReport = (mode: model.WorkflowRenderMode) -> """ \(validationReportHeadings.section.apply(mode, "Rules")) - - Use **Status:** `validated` only when every acceptance criterion is met and - every required full-validation command passed. - - Use **Status:** `failed` when evidence was captured but required checks or - criteria remain unsatisfied. - - List every command that ran under **Commands run**, including ones that - failed. Do not invent exit codes or outcomes. - - Prefer the plan's `Full validation` commands and each criterion's `Validate:` - line over rediscovering project defaults. Fall back to repository conventions - only when the plan omits them. - - Mark each acceptance criterion checkbox in the plan's `## Acceptance criteria` - section to match the evidence. Do not mark a criterion met unless the check - ran successfully or the inspection named by `Validate:` confirms it. - - Under **Failed checks and follow-ups**, record every failing check and its - evidence, including leftover debug-only flags, temporary artifacts, or local - scaffolding. Do not describe code or test edits made during validation; - validation does not modify tests or product code to clear failures. Write - `None.` when status is `validated`. + - Use the `validated` or `failed` status produced by validation execution; this + report does not redefine status-selection criteria. + - List every command result supplied by validation execution under **Commands + run**. Preserve its exit code and concise outcome; do not invent either. + - Under **Success-criteria verification**, render the acceptance-criterion + checkbox state and evidence already established by validation execution. Do + not independently re-evaluate or reclassify criteria here. + - Under **Failed checks and follow-ups**, render every failure and follow-up + supplied by validation execution. Write `None.` when status is `validated`. - When status is `failed`, always include **Retry** with the exact `/validate {plan path}` command. Omit **Retry** when status is `validated`. - Keep evidence concise and factual. Do not narrate the whole implementation - history. - - Do not claim durable context synchronization as part of validation. - - Do not rewrite task evidence or reopen completed tasks. + history or add execution-policy claims absent from the validation result. - When a previous `## Validation Report` already exists, replace it with the new one rather than stacking duplicates. """ @@ -586,10 +582,8 @@ local renderValidationResult = (mode: model.WorkflowRenderMode) -> """ - Name the exact `Plan:` path so every emitted command is runnable. - Use **Status:** exactly `validated`, `failed`, or `blocked`. - - Never claim a check passed unless it ran successfully or the authorized - inspection confirmed it. - - Do not modify tests or product code to clear a failure; record it under - **What failed**. + - Use the status and evidence already produced by validation execution; do not + upgrade, reinterpret, or invent results while formatting this report. - The failed variant must always end its **Recommended work** with `/validate {plan path}` as the final step after repairs. - The failed variant must be self-contained enough to hand to another session diff --git a/config/pkl/renderers/generation-contract-check.pkl b/config/pkl/renderers/generation-contract-check.pkl index 8d40b5072..5f9821993 100644 --- a/config/pkl/renderers/generation-contract-check.pkl +++ b/config/pkl/renderers/generation-contract-check.pkl @@ -1026,6 +1026,49 @@ hidden assertSyncDebtBlockedRouting = (documents: Mapping) -> ) "generated sce-next-task SKILL.md: sync-debt recovery routes its blocked outcome to the Context synchronization blocked layout" else throw("sce-next-task SKILL.md sync-debt recovery blocked outcome must route to the Context synchronization blocked layout, not Review blocked") +local validationExecutionPolicyTokens = new Listing { + "Prefer the plan's authored checks." + "Treat leftover debug-only flags, temporary files" + "Never report a check as passed unless it ran successfully" + "repair belongs to a later work session" + "Do not reopen completed tasks, rewrite task evidence, or change the task stack." +} + +local validationReportForbiddenExecutionTokens = new Listing { + "Use **Status:** `validated` only when every acceptance criterion is met" + "Use **Status:** `failed` when evidence was captured" + "Prefer the plan's `Full validation` commands" + "Fall back to repository conventions" + "Do not mark a criterion met unless" + "leftover debug-only flags" + "validation does not modify tests or product code" + "Do not claim durable context synchronization" + "Do not rewrite task evidence or reopen completed tasks" +} + +local requiredValidationReportPresentationTokens = new Listing { + "This reference owns only the persisted report's structure and presentation." + "Validation execution owns command selection and execution" + "Use the `validated` or `failed` status produced by validation execution" + "render the acceptance-criterion" + "already established by validation execution" + "render every failure and follow-up" + "When a previous `## Validation Report` already exists, replace it" +} + +hidden assertValidationReportPolicyOwnership = (documents: Mapping) -> + if ( + documents.every((path, text) -> + if (path.endsWith("/skills/sce-validate/references/validation.md")) + validationExecutionPolicyTokens.every((token) -> text.contains(token)) + else if (path.endsWith("/skills/sce-validate/references/validation-report.md")) + requiredValidationReportPresentationTokens.every((token) -> text.contains(token)) + && validationReportForbiddenExecutionTokens.every((token) -> !text.contains(token)) + else true + ) + ) "sce-validate: validation owns execution policy and validation-report owns persisted presentation" + else throw("sce-validate validation.md must own command/evidence/classification/non-repair policy; validation-report.md may render established results but must not restate execution policy") + hidden assertValidationIsObservational = (documents: Mapping) -> let (forbidden = new Listing { "Repair application code during final validation" @@ -1108,6 +1151,7 @@ contractChecks { ["sync-debt-recovery-branch"] = assertSyncDebtRecoveryBranch.apply(workflowDocuments) ["plan-review-all-tasks-scope"] = assertPlanReviewAllTasksScope.apply(workflowDocuments) ["sync-debt-blocked-routing"] = assertSyncDebtBlockedRouting.apply(workflowDocuments) + ["validation-report-policy-ownership"] = assertValidationReportPolicyOwnership.apply(workflowDocuments) ["validation-observational"] = assertValidationIsObservational.apply(workflowDocuments) ["validate-decision-sync-boundary"] = assertValidateExcludesDecisionAndPlanSync.apply(workflowDocuments) } diff --git a/context/plans/compress-workflow-execution-preamble.md b/context/plans/compress-workflow-execution-preamble.md index 728ae00f3..0ffcdfa39 100644 --- a/context/plans/compress-workflow-execution-preamble.md +++ b/context/plans/compress-workflow-execution-preamble.md @@ -382,3 +382,28 @@ The two additional root edits replace existing text without increasing line coun `nix run .#pkl-check-generated`, targeted ownership assertions across all three tracked targets, and `git diff --check`. - Context synchronization: synced. + + +## Follow-up: validation report policy ownership + +- [x] T08: `Deduplicate validation execution policy from report formatting` (status:done) + - Scope: `sce-validate` validation phase, persisted `validation-report.md`, returned + validation-result formatting rules, canonical Pkl, generated semantic checks, + tracked Pi/Claude/Codex mirrors, and the ownership table. + - Ownership after change: `references/validation.md` owns command selection and + execution, evidence interpretation, acceptance-criterion state, outcome + classification, and non-repairing boundaries. `references/validation-report.md` + owns only persisted report structure/presentation and renders the phase's + established results without re-evaluating them. + - Behavior preserved: plan-authored checks remain preferred, repository fallback + still applies only when needed, debug/scaffolding evidence can still fail + validation, failures remain observational, acceptance checkboxes still follow + evidence, failed plan reports still carry `/validate {plan path}`, and prior + Validation Report sections are replaced rather than stacked. + - Result: `references/validation.md` plus `references/validation-report.md` shrink + by 6 Markdown lines per tracked target, 18 + lines across Pi/Claude/Codex. + - Verify: `pkl eval config/pkl/renderers/generation-contract-check.pkl`, + `nix run .#pkl-check-generated`, targeted ownership assertions across all three + tracked targets, and `git diff --check`. + - Context synchronization: synced. diff --git a/context/sce/dedup-ownership-table.md b/context/sce/dedup-ownership-table.md index 4cd739dd1..3ff2e7047 100644 --- a/context/sce/dedup-ownership-table.md +++ b/context/sce/dedup-ownership-table.md @@ -23,7 +23,8 @@ | Synchronization-debt recovery identity | `sce-plan-review` resolves the plan path, debt task identity, completed task record, and persisted blocker | `/next-task` only routes that resolved record to task context sync; task context sync validates and consumes it directly from the plan; no separate persisted handoff exists | intentional/keep | | Post-task durable context synchronization | Task instance from `workflow-context-sync.pkl` | `/next-task`; composed into `sce-next-task` | dedup/shared skeleton | | Mandatory five-root context pass | `sce-task-context-sync` mandatory-root-pass subsection in `workflow-context-sync.pkl` | Task execution only hands off `context_impact`; context discovery references the named pass instead of relisting its five files; impact and verification sections may enforce the owned contract without redefining the file set | intentional/keep | -| Final validation and validation report | `sce-validation` in `workflow-validate.pkl` | `/validate`; composed into `sce-validate`; thin OpenCode Code agent | intentional/keep | +| Final validation execution, evidence interpretation, and outcome classification | `references/validation.md` generated from `renderValidationSkillBody` in `workflow-validate.pkl` | `/validate` routes the phase; the persisted report and returned report formats consume established status/evidence without redefining command selection, pass/fail interpretation, or non-repairing boundaries | intentional/keep | +| Persisted plan-file Validation Report schema and presentation | `references/validation-report.md` generated from `renderValidationReport` in `workflow-validate.pkl` | Validation writes or replaces this section on `validated`/`failed`; it renders recorded command results, criterion states, failures, risks, and retry without re-running or redefining validation policy | intentional/keep | | Validated-plan durable context synchronization | Retained plan instance from `workflow-context-sync.pkl` | No current workflow consumer; `/validate` is validation-only | retained source, not generated | | Staged-diff analysis and commit-message authoring | `sce-atomic-commit` in `workflow-commit.pkl` | `/commit`; composed into `sce-commit`; thin OpenCode Code agent | intentional/keep | | Bypass commit execution sequence | `references/atomic-commit.md` **Bypass execution handoff**, generated from `renderAtomicCommitSkillBody` in `workflow-commit.pkl` | `/commit` executes the handoff exactly once after `bypass_message`; the workflow owns success/failure layout selection but does not restate temp-file, commit, hash, cleanup, or retry procedure | intentional/keep | From a4a2bf05cc471aa4ce54e85137b43d10bb3d346b Mon Sep 17 00:00:00 2001 From: David Abram Date: Tue, 8 Sep 2026 12:20:02 +0000 Subject: [PATCH 09/12] config: Deduplicate handover completeness contract --- .agents/skills/sce-handover/SKILL.md | 37 +++++--------- .../references/handover-template.md | 14 ++++- .claude/skills/sce-handover/SKILL.md | 37 +++++--------- .../references/handover-template.md | 14 ++++- .pi/skills/sce-handover/SKILL.md | 37 +++++--------- .../references/handover-template.md | 14 ++++- config/pkl/base/workflow-handover.pkl | 51 +++++++++---------- .../renderers/generation-contract-check.pkl | 48 +++++++++++++++-- .../compress-workflow-execution-preamble.md | 20 ++++++++ context/sce/dedup-ownership-table.md | 1 + context/sce/handover-workflow.md | 7 +-- 11 files changed, 165 insertions(+), 115 deletions(-) diff --git a/.agents/skills/sce-handover/SKILL.md b/.agents/skills/sce-handover/SKILL.md index 40095e848..67cd81aef 100644 --- a/.agents/skills/sce-handover/SKILL.md +++ b/.agents/skills/sce-handover/SKILL.md @@ -71,18 +71,10 @@ timestamp segment, rather than overwriting it. #### 3. Compose the handover document -Read `references/handover-template.md` before composing. It defines the -persisted-document format and is the only template authority. Populate all -four required sections: - -- `Current Task State` -- `Decisions Made` -- `Open Questions / Blockers` -- `Next Recommended Step` - -Every section must contain real content. Write `None identified.` (or a -section-appropriate equivalent) when nothing applies — never omit a required -section and never leave template placeholders in the written file. +Read `references/handover-template.md` before composing. It is the sole +authority for the persisted schema and **Completeness contract**. Populate its +layout from the gathered facts and satisfy that contract without redefining the +required-section set here. Label inferred or assumed details inline as assumptions; do not blend them with confirmed facts. @@ -96,8 +88,8 @@ the required action, and stop without writing a file. #### 5. Write exactly one file Write the composed document to the path resolved in step 2. Before reporting -success, confirm the written file contains all four required sections -populated with real content. +success, validate the written file against the template's **Completeness +contract**. #### 6. Report @@ -121,17 +113,12 @@ and stop. #### 2. Validate handover completeness -Read the file and confirm it contains all four required sections: -`Current Task State`, `Decisions Made`, `Open Questions / Blockers`, and -`Next Recommended Step`. For each section, inspect the content up to the -next required heading (or the end of the file): it must contain non-whitespace -content, and it must not consist only of an empty list marker, a template -placeholder such as `{What is being worked on...}`, or other unreplaced -`{...}` scaffolding. Explicit statements such as `None identified.` are real -content and are valid. - -When any required section is missing, empty, or placeholder-only, render the -**Loader blocked** layout (invalid handover) and stop. +Read the file and `references/handover-template.md`. Validate the file against +the template's **Completeness contract**; do not define a second required-section +list or a different content-validity rule here. + +When that contract fails, render the **Loader blocked** layout (invalid handover) +and stop. #### 3. Present for continuation diff --git a/.agents/skills/sce-handover/references/handover-template.md b/.agents/skills/sce-handover/references/handover-template.md index 51edfefbc..d934da801 100644 --- a/.agents/skills/sce-handover/references/handover-template.md +++ b/.agents/skills/sce-handover/references/handover-template.md @@ -35,12 +35,22 @@ enough to act on directly.} `None.`} ``` +### Completeness contract + +- The first four `##` sections shown in **Layout** are required and must appear + in that order. +- Each required section's content, up to the next `##` heading or the end of the + file, must contain non-whitespace content. An empty list marker, unreplaced + `{...}` placeholder, or other template scaffolding alone is invalid. +- Explicit `None identified.` statements or section-appropriate equivalents are + real content and are valid. +- Writer mode must satisfy this contract before reporting success; loader mode + validates the same contract before presenting a handover. + ### Rules - Include `Plan` and `Task` only when the session was working one identifiable plan task; omit them rather than guessing. -- Every one of the four required sections must appear, in this order, even - when its content is `None identified.` or an equivalent. - Keep `Assumptions` scoped to details actually labeled as inferred elsewhere in the document; do not duplicate confirmed facts here. - Describe durable state useful to a future session, not a transcript of this diff --git a/.claude/skills/sce-handover/SKILL.md b/.claude/skills/sce-handover/SKILL.md index 11c2e59a9..b1fd0f82c 100644 --- a/.claude/skills/sce-handover/SKILL.md +++ b/.claude/skills/sce-handover/SKILL.md @@ -70,18 +70,10 @@ timestamp segment, rather than overwriting it. #### 3. Compose the handover document -Read `references/handover-template.md` before composing. It defines the -persisted-document format and is the only template authority. Populate all -four required sections: - -- `Current Task State` -- `Decisions Made` -- `Open Questions / Blockers` -- `Next Recommended Step` - -Every section must contain real content. Write `None identified.` (or a -section-appropriate equivalent) when nothing applies — never omit a required -section and never leave template placeholders in the written file. +Read `references/handover-template.md` before composing. It is the sole +authority for the persisted schema and **Completeness contract**. Populate its +layout from the gathered facts and satisfy that contract without redefining the +required-section set here. Label inferred or assumed details inline as assumptions; do not blend them with confirmed facts. @@ -95,8 +87,8 @@ the required action, and stop without writing a file. #### 5. Write exactly one file Write the composed document to the path resolved in step 2. Before reporting -success, confirm the written file contains all four required sections -populated with real content. +success, validate the written file against the template's **Completeness +contract**. #### 6. Report @@ -120,17 +112,12 @@ and stop. #### 2. Validate handover completeness -Read the file and confirm it contains all four required sections: -`Current Task State`, `Decisions Made`, `Open Questions / Blockers`, and -`Next Recommended Step`. For each section, inspect the content up to the -next required heading (or the end of the file): it must contain non-whitespace -content, and it must not consist only of an empty list marker, a template -placeholder such as `{What is being worked on...}`, or other unreplaced -`{...}` scaffolding. Explicit statements such as `None identified.` are real -content and are valid. - -When any required section is missing, empty, or placeholder-only, render the -**Loader blocked** layout (invalid handover) and stop. +Read the file and `references/handover-template.md`. Validate the file against +the template's **Completeness contract**; do not define a second required-section +list or a different content-validity rule here. + +When that contract fails, render the **Loader blocked** layout (invalid handover) +and stop. #### 3. Present for continuation diff --git a/.claude/skills/sce-handover/references/handover-template.md b/.claude/skills/sce-handover/references/handover-template.md index 51edfefbc..d934da801 100644 --- a/.claude/skills/sce-handover/references/handover-template.md +++ b/.claude/skills/sce-handover/references/handover-template.md @@ -35,12 +35,22 @@ enough to act on directly.} `None.`} ``` +### Completeness contract + +- The first four `##` sections shown in **Layout** are required and must appear + in that order. +- Each required section's content, up to the next `##` heading or the end of the + file, must contain non-whitespace content. An empty list marker, unreplaced + `{...}` placeholder, or other template scaffolding alone is invalid. +- Explicit `None identified.` statements or section-appropriate equivalents are + real content and are valid. +- Writer mode must satisfy this contract before reporting success; loader mode + validates the same contract before presenting a handover. + ### Rules - Include `Plan` and `Task` only when the session was working one identifiable plan task; omit them rather than guessing. -- Every one of the four required sections must appear, in this order, even - when its content is `None identified.` or an equivalent. - Keep `Assumptions` scoped to details actually labeled as inferred elsewhere in the document; do not duplicate confirmed facts here. - Describe durable state useful to a future session, not a transcript of this diff --git a/.pi/skills/sce-handover/SKILL.md b/.pi/skills/sce-handover/SKILL.md index 411276aac..d91f6b957 100644 --- a/.pi/skills/sce-handover/SKILL.md +++ b/.pi/skills/sce-handover/SKILL.md @@ -69,18 +69,10 @@ timestamp segment, rather than overwriting it. #### 3. Compose the handover document -Read `references/handover-template.md` before composing. It defines the -persisted-document format and is the only template authority. Populate all -four required sections: - -- `Current Task State` -- `Decisions Made` -- `Open Questions / Blockers` -- `Next Recommended Step` - -Every section must contain real content. Write `None identified.` (or a -section-appropriate equivalent) when nothing applies — never omit a required -section and never leave template placeholders in the written file. +Read `references/handover-template.md` before composing. It is the sole +authority for the persisted schema and **Completeness contract**. Populate its +layout from the gathered facts and satisfy that contract without redefining the +required-section set here. Label inferred or assumed details inline as assumptions; do not blend them with confirmed facts. @@ -94,8 +86,8 @@ the required action, and stop without writing a file. #### 5. Write exactly one file Write the composed document to the path resolved in step 2. Before reporting -success, confirm the written file contains all four required sections -populated with real content. +success, validate the written file against the template's **Completeness +contract**. #### 6. Report @@ -119,17 +111,12 @@ and stop. #### 2. Validate handover completeness -Read the file and confirm it contains all four required sections: -`Current Task State`, `Decisions Made`, `Open Questions / Blockers`, and -`Next Recommended Step`. For each section, inspect the content up to the -next required heading (or the end of the file): it must contain non-whitespace -content, and it must not consist only of an empty list marker, a template -placeholder such as `{What is being worked on...}`, or other unreplaced -`{...}` scaffolding. Explicit statements such as `None identified.` are real -content and are valid. - -When any required section is missing, empty, or placeholder-only, render the -**Loader blocked** layout (invalid handover) and stop. +Read the file and `references/handover-template.md`. Validate the file against +the template's **Completeness contract**; do not define a second required-section +list or a different content-validity rule here. + +When that contract fails, render the **Loader blocked** layout (invalid handover) +and stop. #### 3. Present for continuation diff --git a/.pi/skills/sce-handover/references/handover-template.md b/.pi/skills/sce-handover/references/handover-template.md index 51edfefbc..d934da801 100644 --- a/.pi/skills/sce-handover/references/handover-template.md +++ b/.pi/skills/sce-handover/references/handover-template.md @@ -35,12 +35,22 @@ enough to act on directly.} `None.`} ``` +### Completeness contract + +- The first four `##` sections shown in **Layout** are required and must appear + in that order. +- Each required section's content, up to the next `##` heading or the end of the + file, must contain non-whitespace content. An empty list marker, unreplaced + `{...}` placeholder, or other template scaffolding alone is invalid. +- Explicit `None identified.` statements or section-appropriate equivalents are + real content and are valid. +- Writer mode must satisfy this contract before reporting success; loader mode + validates the same contract before presenting a handover. + ### Rules - Include `Plan` and `Task` only when the session was working one identifiable plan task; omit them rather than guessing. -- Every one of the four required sections must appear, in this order, even - when its content is `None identified.` or an equivalent. - Keep `Assumptions` scoped to details actually labeled as inferred elsewhere in the document; do not duplicate confirmed facts here. - Describe durable state useful to a future session, not a transcript of this diff --git a/config/pkl/base/workflow-handover.pkl b/config/pkl/base/workflow-handover.pkl index c6fc18fa1..0dc8760c7 100644 --- a/config/pkl/base/workflow-handover.pkl +++ b/config/pkl/base/workflow-handover.pkl @@ -80,12 +80,22 @@ local renderPersistedFormatBody = """ `None.`} ``` + ### Completeness contract + + - The first four `##` sections shown in **Layout** are required and must appear + in that order. + - Each required section's content, up to the next `##` heading or the end of the + file, must contain non-whitespace content. An empty list marker, unreplaced + `{...}` placeholder, or other template scaffolding alone is invalid. + - Explicit `None identified.` statements or section-appropriate equivalents are + real content and are valid. + - Writer mode must satisfy this contract before reporting success; loader mode + validates the same contract before presenting a handover. + ### Rules - Include `Plan` and `Task` only when the session was working one identifiable plan task; omit them rather than guessing. - - Every one of the four required sections must appear, in this order, even - when its content is `None identified.` or an equivalent. - Keep `Assumptions` scoped to details actually labeled as inferred elsewhere in the document; do not duplicate confirmed facts here. - Describe durable state useful to a future session, not a transcript of this @@ -144,18 +154,10 @@ local renderSkillBody = (mode: model.WorkflowRenderMode, argumentsReference: Str #### 3. Compose the handover document - Read `references/handover-template.md` before composing. It defines the - persisted-document format and is the only template authority. Populate all - four required sections: - - - `Current Task State` - - `Decisions Made` - - `Open Questions / Blockers` - - `Next Recommended Step` - - Every section must contain real content. Write `None identified.` (or a - section-appropriate equivalent) when nothing applies — never omit a required - section and never leave template placeholders in the written file. + Read `references/handover-template.md` before composing. It is the sole + authority for the persisted schema and **Completeness contract**. Populate its + layout from the gathered facts and satisfy that contract without redefining the + required-section set here. Label inferred or assumed details inline as assumptions; do not blend them with confirmed facts. @@ -169,8 +171,8 @@ local renderSkillBody = (mode: model.WorkflowRenderMode, argumentsReference: Str #### 5. Write exactly one file Write the composed document to the path resolved in step 2. Before reporting - success, confirm the written file contains all four required sections - populated with real content. + success, validate the written file against the template's **Completeness + contract**. #### 6. Report @@ -194,17 +196,12 @@ local renderSkillBody = (mode: model.WorkflowRenderMode, argumentsReference: Str #### 2. Validate handover completeness - Read the file and confirm it contains all four required sections: - `Current Task State`, `Decisions Made`, `Open Questions / Blockers`, and - `Next Recommended Step`. For each section, inspect the content up to the - next required heading (or the end of the file): it must contain non-whitespace - content, and it must not consist only of an empty list marker, a template - placeholder such as `{What is being worked on...}`, or other unreplaced - `{...}` scaffolding. Explicit statements such as `None identified.` are real - content and are valid. - - When any required section is missing, empty, or placeholder-only, render the - **Loader blocked** layout (invalid handover) and stop. + Read the file and `references/handover-template.md`. Validate the file against + the template's **Completeness contract**; do not define a second required-section + list or a different content-validity rule here. + + When that contract fails, render the **Loader blocked** layout (invalid handover) + and stop. #### 3. Present for continuation diff --git a/config/pkl/renderers/generation-contract-check.pkl b/config/pkl/renderers/generation-contract-check.pkl index 5f9821993..9cdda173e 100644 --- a/config/pkl/renderers/generation-contract-check.pkl +++ b/config/pkl/renderers/generation-contract-check.pkl @@ -246,15 +246,40 @@ local requiredHandoverSkillTokens = new Listing { "selects **loader mode**" "### Writer path (no arguments)" "### Loader path (one path argument)" - "Current Task State" - "Decisions Made" - "Open Questions / Blockers" - "Next Recommended Step" + "references/handover-template.md" + "**Completeness contract**" "Writer mode never overwrites an existing handover file" "Loading is read-only" "Never invoke another SCE skill, sibling SCE package, or SCE workflow command" } +local requiredHandoverTemplateCompletenessTokens = new Listing { + "### Completeness contract" + "first four `##` sections shown in **Layout** are required" + "next `##` heading or the end of the" + "empty list marker" + "`{...}` placeholder" + "Explicit `None identified.` statements" + "Writer mode must satisfy this contract before reporting success" + "validates the same contract before presenting a handover" +} + +local requiredHandoverSkillCompletenessConsumerTokens = new Listing { + "sole\nauthority for the persisted schema and **Completeness contract**" + "validate the written file against the template's **Completeness\ncontract**" + "Validate the file against\nthe template's **Completeness contract**" +} + +local forbiddenHandoverSkillCompletenessTokens = new Listing { + "`Current Task State`" + "`Decisions Made`" + "`Open Questions / Blockers`" + "`Next Recommended Step`" + "all four required sections" + "placeholder such as `{What is being worked on...}`" + "missing, empty, or placeholder-only" +} + local compactWorkflowSlugs = new Listing { "change-to-plan"; "next-task"; "commit"; "validate"; "handover" } @@ -583,6 +608,20 @@ local assertHandoverContent = (documents: Mapping) -> ) "generated handover package content: covers both modes" else throw("generated sce-handover SKILL.md is missing required writer/loader mode content") +hidden assertHandoverSchemaCompletenessOwnership = (documents: Mapping) -> + if ( + new Listing { ".opencode"; ".claude"; ".pi"; ".agents" }.every((target) -> + let (skillPath = "config/\(target)/skills/sce-handover/SKILL.md") + let (templatePath = "config/\(target)/skills/sce-handover/references/handover-template.md") + documents.containsKey(skillPath) + && documents.containsKey(templatePath) + && requiredHandoverSkillCompletenessConsumerTokens.every((token) -> documents[skillPath].contains(token)) + && forbiddenHandoverSkillCompletenessTokens.every((token) -> !documents[skillPath].contains(token)) + && requiredHandoverTemplateCompletenessTokens.every((token) -> documents[templatePath].contains(token)) + ) + ) "sce-handover: template solely owns persisted schema and completeness validity" + else throw("sce-handover handover-template.md must own required-section/completeness policy; SKILL.md may invoke that contract but must not restate it") + local assertBrownfieldContent = (documents: Mapping) -> if ( documents.length == 4 @@ -1129,6 +1168,7 @@ contractChecks { ["decision-package-paths"] = assertDecisionDocumentPaths.apply(decisionSkillDocuments) ["decision-package-content"] = assertDecisionContent.apply(decisionSkillDocuments) ["handover-package-content"] = assertHandoverContent.apply(handoverSkillDocuments) + ["handover-schema-completeness-ownership"] = assertHandoverSchemaCompletenessOwnership.apply(workflowDocuments) ["brownfield-package-content"] = assertBrownfieldContent.apply(brownfieldSkillDocuments) ["no-blank-line-runs"] = assertNoBlankLineRuns.apply(workflowDocuments) ["output-dedup"] = assertOutputNotDuplicated.apply(workflowDocuments) diff --git a/context/plans/compress-workflow-execution-preamble.md b/context/plans/compress-workflow-execution-preamble.md index 0ffcdfa39..445d91870 100644 --- a/context/plans/compress-workflow-execution-preamble.md +++ b/context/plans/compress-workflow-execution-preamble.md @@ -407,3 +407,23 @@ The two additional root edits replace existing text without increasing line coun `nix run .#pkl-check-generated`, targeted ownership assertions across all three tracked targets, and `git diff --check`. - Context synchronization: synced. + + +## Follow-up: handover schema and completeness ownership + +- [x] T09: `Deduplicate handover required-section and completeness contract` (status:done) + - Scope: `sce-handover` writer composition/post-write validation, loader completeness + validation, `references/handover-template.md`, canonical Pkl, generated semantic + checks, tracked Pi/Claude/Codex mirrors, handover context, and the ownership table. + - Ownership after change: `references/handover-template.md` solely owns persisted + schema and completeness validity. Writer and loader both consume that contract; + `SKILL.md` owns routing, path checks, read/write boundaries, and terminal layouts. + - Behavior preserved: same writer layout/order; `None identified.`-style content is + valid; whitespace-only, empty-list-marker, and unreplaced-placeholder-only required + sections remain invalid; loader stays read-only; writer validates before success. + - Result: `sce-handover/SKILL.md` plus `references/handover-template.md` shrink by + 3 Markdown lines per tracked target, 9 across + Pi/Claude/Codex. + - Verify: `pkl eval config/pkl/renderers/generation-contract-check.pkl`, + `nix run .#pkl-check-generated`, targeted ownership checks, and `git diff --check`. + - Context synchronization: synced. diff --git a/context/sce/dedup-ownership-table.md b/context/sce/dedup-ownership-table.md index 3ff2e7047..4d6d8833a 100644 --- a/context/sce/dedup-ownership-table.md +++ b/context/sce/dedup-ownership-table.md @@ -28,6 +28,7 @@ | Validated-plan durable context synchronization | Retained plan instance from `workflow-context-sync.pkl` | No current workflow consumer; `/validate` is validation-only | retained source, not generated | | Staged-diff analysis and commit-message authoring | `sce-atomic-commit` in `workflow-commit.pkl` | `/commit`; composed into `sce-commit`; thin OpenCode Code agent | intentional/keep | | Bypass commit execution sequence | `references/atomic-commit.md` **Bypass execution handoff**, generated from `renderAtomicCommitSkillBody` in `workflow-commit.pkl` | `/commit` executes the handoff exactly once after `bypass_message`; the workflow owns success/failure layout selection but does not restate temp-file, commit, hash, cleanup, or retry procedure | intentional/keep | +| Handover persisted schema and completeness validity | `references/handover-template.md` generated from `renderPersistedFormatBody` in `workflow-handover.pkl` | Writer composes and validates against this contract; loader validates against the same contract; `sce-handover/SKILL.md` owns routing, path checks, read/write boundaries, and terminal layout selection without restating required-section or content-validity rules | intentional/keep | | Compact workflow execution contract | `executionContract` in `workflow-content.pkl` | Inline in change-to-plan, next-task, commit, validate, and handover entrypoints on all four targets; no extra runtime read | shared rendering, preserved behavior | | Workflow routing | Six command documents in the workflow modules | Thin OpenCode Plan/Code agents | intentional/keep | | Standalone ADR writing contract | `decision-skill.pkl` | Cross-target `sce-decision` package; successful task synchronization invokes it through the shared decision gate | intentional/keep | diff --git a/context/sce/handover-workflow.md b/context/sce/handover-workflow.md index 10be5cd6d..25f1d22aa 100644 --- a/context/sce/handover-workflow.md +++ b/context/sce/handover-workflow.md @@ -24,9 +24,10 @@ from `executionContract` in `workflow-content.pkl` through `workflow-composite.p It preserves the existing control-flow, output, and helper boundaries without an additional runtime read. Package-mode-only Purpose text is unchanged. -The package contains `SKILL.md`, which owns mode routing, writer and loader -behavior, `references/handover-template.md`, which owns the persisted document -format, and `references/output.md`, which owns every human-visible layout. No +The package contains `SKILL.md`, which owns mode routing plus writer/loader +side-effect boundaries, `references/handover-template.md`, which solely owns +the persisted document schema and completeness contract, and +`references/output.md`, which owns every human-visible layout. No SCE sibling skill, package, or workflow command is invoked as a workflow handoff; relevant non-SCE helpers may assist inside the active step and return control to it. From 8988c291a85821dc4ca1d805c7e9ff718174739a Mon Sep 17 00:00:00 2001 From: David Abram Date: Tue, 8 Sep 2026 14:00:05 +0000 Subject: [PATCH 10/12] config: Deduplicate decision gate and ADR template --- .agents/skills/sce-decision/SKILL.md | 67 +++++------ .../sce-decision/references/adr-template.md | 4 +- .../sce-next-task/references/context-sync.md | 4 + .claude/skills/sce-decision/SKILL.md | 67 +++++------ .../sce-decision/references/adr-template.md | 4 +- .../sce-next-task/references/context-sync.md | 4 + .pi/skills/sce-decision/SKILL.md | 67 +++++------ .../sce-decision/references/adr-template.md | 4 +- .../sce-next-task/references/context-sync.md | 4 + config/pkl/base/decision-skill.pkl | 71 +++++------- config/pkl/base/workflow-context-sync.pkl | 8 ++ .../renderers/generation-contract-check.pkl | 104 ++++++++++++++---- .../compress-workflow-execution-preamble.md | 25 +++++ context/sce/dedup-ownership-table.md | 4 +- 14 files changed, 238 insertions(+), 199 deletions(-) diff --git a/.agents/skills/sce-decision/SKILL.md b/.agents/skills/sce-decision/SKILL.md index 543044c4d..789d792ba 100644 --- a/.agents/skills/sce-decision/SKILL.md +++ b/.agents/skills/sce-decision/SKILL.md @@ -1,17 +1,17 @@ --- name: sce-decision description: > - Write one immutable ADR for one qualifying system-wide decision + Write one immutable ADR for one decision already qualified by context synchronization --- # SCE Decision ## Purpose -Write exactly one architecture decision record for one qualifying system-wide -important decision during successful task context synchronization. Return -a deterministic internal handoff to the invoking synchronization phase. Do not -render an independent user-visible response. +Write exactly one architecture decision record for one decision already qualified +by successful task context synchronization. Return a deterministic internal +handoff to the invoking synchronization phase. Do not render an independent +user-visible response. ## Input @@ -28,28 +28,22 @@ synchronization. It must identify: Do not accept raw workflow arguments, ordinary phase state, multiple decisions, or direct user invocation. Do not reconstruct missing material facts. -## Decision gate - -A decision qualifies only when it establishes or changes a system-wide important -constraint involving at least one of: - -- System boundaries or ownership. -- Public or cross-domain interfaces. -- Data models or persistence. -- Compatibility contracts. -- Security posture. -- Deployment or distribution strategy. -- A major dependency. -- A similarly durable constraint that is costly or risky to reverse. - -Routine implementation details, local refactors, naming and formatting choices, -temporary experiments, and easily reversible choices do not qualify. When the -request does not demonstrate the threshold, return `not_qualified` (or -`skipped` when the caller deliberately skips the gate); do not create an ADR -merely because context synchronization occurred. A nonqualifying or skipped -result is non-blocking, so the invoking synchronization phase continues -normally. Reserve `blocked` for missing, contradictory, or otherwise unsafe -decision input or history. +## Qualification handoff + +The invoking task context synchronization phase solely owns the decision +qualification threshold and decides whether this skill is invoked. Treat the +caller's gate result as authoritative; do not redefine, broaden, or independently +rerun that threshold here. + +Require the request to state why the caller qualified the decision and include +supporting evidence. If the request explicitly represents a nonqualifying gate +outcome, return `not_qualified` (or `skipped` when the caller deliberately skipped +the gate) without writing an ADR. If a claimed qualification is unsupported by +its supplied evidence, return `not_qualified`. Missing, contradictory, or +otherwise unsafe material input remains `blocked`. + +`not_qualified` and `skipped` are non-blocking to the invoking synchronization +phase. ## Workflow @@ -91,21 +85,10 @@ deterministic slug; never add an arbitrary counter and never overwrite a record. ### 4. Write the ADR -Create exactly one file using `references/adr-template.md` and these rules: - -- **Context** states the forces and constraint that made a decision necessary. -- **Decision** states one resulting choice, not a list of unrelated choices. -- **Rationale** explains why this path best satisfies the constraints. -- **Alternatives considered** names credible alternatives and why they were not - selected. -- **Compatibility and risks** states compatibility effects, migration concerns, - and material risks with mitigations. -- **Guardrails** records durable limits that keep the decision narrow. -- **Consequences** records positive and negative resulting constraints. -- **Follow-up** lists only established work or conditions; use `None.` when no - follow-up is established. -- **References** links the plan, relevant tasks, evidence, current-state context, - related ADRs, and any superseded ADR. +Read `references/adr-template.md` before writing. It is the sole authority for +the persisted ADR schema and section semantics. Populate that template from the +validated request and evidence; do not restate or invent a parallel section +contract here. Use repository-relative Markdown links where practical. Describe durable truth, not the implementation session. Do not edit current-state context; the invoking diff --git a/.agents/skills/sce-decision/references/adr-template.md b/.agents/skills/sce-decision/references/adr-template.md index 31891d448..8c2b06e77 100644 --- a/.agents/skills/sce-decision/references/adr-template.md +++ b/.agents/skills/sce-decision/references/adr-template.md @@ -1,7 +1,7 @@ # Decision: {concise decision title} Date: {YYYY-MM-DD} -Status: {Proposed|Accepted|Rejected|Deprecated|Superseded} +Status: {validated decision status} Plan: `{context/plans/plan-name.md}` Task: `{task-id or comma-separated task IDs}` Supersedes: `{context/decisions/YYYY-MM-DD-prior-decision.md}` @@ -14,7 +14,7 @@ Omit `Task` or `Supersedes` only when it does not apply. Do not omit `Plan`. ## Decision -{Exactly one durable system-wide choice.} +{Exactly one durable choice already qualified by task context synchronization.} ## Rationale diff --git a/.agents/skills/sce-next-task/references/context-sync.md b/.agents/skills/sce-next-task/references/context-sync.md index fb330bb6d..057043313 100644 --- a/.agents/skills/sce-next-task/references/context-sync.md +++ b/.agents/skills/sce-next-task/references/context-sync.md @@ -157,6 +157,10 @@ verified classification and explain the difference in the report. ## 3.5 Record qualifying architecture decisions +This subsection is the sole owner of decision qualification. The threshold below +decides whether `sce-decision` is invoked; the decision skill consumes that gate +result and must not restate or broaden it. + During this successful synchronization, determine whether the completed change establishes or changes a system-wide important constraint involving one or more of: diff --git a/.claude/skills/sce-decision/SKILL.md b/.claude/skills/sce-decision/SKILL.md index 8b5d378ef..540a51aeb 100644 --- a/.claude/skills/sce-decision/SKILL.md +++ b/.claude/skills/sce-decision/SKILL.md @@ -1,7 +1,7 @@ --- name: sce-decision description: > - Write one immutable ADR for one qualifying system-wide decision + Write one immutable ADR for one decision already qualified by context synchronization compatibility: claude --- @@ -9,10 +9,10 @@ compatibility: claude ## Purpose -Write exactly one architecture decision record for one qualifying system-wide -important decision during successful task context synchronization. Return -a deterministic internal handoff to the invoking synchronization phase. Do not -render an independent user-visible response. +Write exactly one architecture decision record for one decision already qualified +by successful task context synchronization. Return a deterministic internal +handoff to the invoking synchronization phase. Do not render an independent +user-visible response. ## Input @@ -29,28 +29,22 @@ synchronization. It must identify: Do not accept raw workflow arguments, ordinary phase state, multiple decisions, or direct user invocation. Do not reconstruct missing material facts. -## Decision gate - -A decision qualifies only when it establishes or changes a system-wide important -constraint involving at least one of: - -- System boundaries or ownership. -- Public or cross-domain interfaces. -- Data models or persistence. -- Compatibility contracts. -- Security posture. -- Deployment or distribution strategy. -- A major dependency. -- A similarly durable constraint that is costly or risky to reverse. - -Routine implementation details, local refactors, naming and formatting choices, -temporary experiments, and easily reversible choices do not qualify. When the -request does not demonstrate the threshold, return `not_qualified` (or -`skipped` when the caller deliberately skips the gate); do not create an ADR -merely because context synchronization occurred. A nonqualifying or skipped -result is non-blocking, so the invoking synchronization phase continues -normally. Reserve `blocked` for missing, contradictory, or otherwise unsafe -decision input or history. +## Qualification handoff + +The invoking task context synchronization phase solely owns the decision +qualification threshold and decides whether this skill is invoked. Treat the +caller's gate result as authoritative; do not redefine, broaden, or independently +rerun that threshold here. + +Require the request to state why the caller qualified the decision and include +supporting evidence. If the request explicitly represents a nonqualifying gate +outcome, return `not_qualified` (or `skipped` when the caller deliberately skipped +the gate) without writing an ADR. If a claimed qualification is unsupported by +its supplied evidence, return `not_qualified`. Missing, contradictory, or +otherwise unsafe material input remains `blocked`. + +`not_qualified` and `skipped` are non-blocking to the invoking synchronization +phase. ## Workflow @@ -92,21 +86,10 @@ deterministic slug; never add an arbitrary counter and never overwrite a record. ### 4. Write the ADR -Create exactly one file using `references/adr-template.md` and these rules: - -- **Context** states the forces and constraint that made a decision necessary. -- **Decision** states one resulting choice, not a list of unrelated choices. -- **Rationale** explains why this path best satisfies the constraints. -- **Alternatives considered** names credible alternatives and why they were not - selected. -- **Compatibility and risks** states compatibility effects, migration concerns, - and material risks with mitigations. -- **Guardrails** records durable limits that keep the decision narrow. -- **Consequences** records positive and negative resulting constraints. -- **Follow-up** lists only established work or conditions; use `None.` when no - follow-up is established. -- **References** links the plan, relevant tasks, evidence, current-state context, - related ADRs, and any superseded ADR. +Read `references/adr-template.md` before writing. It is the sole authority for +the persisted ADR schema and section semantics. Populate that template from the +validated request and evidence; do not restate or invent a parallel section +contract here. Use repository-relative Markdown links where practical. Describe durable truth, not the implementation session. Do not edit current-state context; the invoking diff --git a/.claude/skills/sce-decision/references/adr-template.md b/.claude/skills/sce-decision/references/adr-template.md index 31891d448..8c2b06e77 100644 --- a/.claude/skills/sce-decision/references/adr-template.md +++ b/.claude/skills/sce-decision/references/adr-template.md @@ -1,7 +1,7 @@ # Decision: {concise decision title} Date: {YYYY-MM-DD} -Status: {Proposed|Accepted|Rejected|Deprecated|Superseded} +Status: {validated decision status} Plan: `{context/plans/plan-name.md}` Task: `{task-id or comma-separated task IDs}` Supersedes: `{context/decisions/YYYY-MM-DD-prior-decision.md}` @@ -14,7 +14,7 @@ Omit `Task` or `Supersedes` only when it does not apply. Do not omit `Plan`. ## Decision -{Exactly one durable system-wide choice.} +{Exactly one durable choice already qualified by task context synchronization.} ## Rationale diff --git a/.claude/skills/sce-next-task/references/context-sync.md b/.claude/skills/sce-next-task/references/context-sync.md index fb330bb6d..057043313 100644 --- a/.claude/skills/sce-next-task/references/context-sync.md +++ b/.claude/skills/sce-next-task/references/context-sync.md @@ -157,6 +157,10 @@ verified classification and explain the difference in the report. ## 3.5 Record qualifying architecture decisions +This subsection is the sole owner of decision qualification. The threshold below +decides whether `sce-decision` is invoked; the decision skill consumes that gate +result and must not restate or broaden it. + During this successful synchronization, determine whether the completed change establishes or changes a system-wide important constraint involving one or more of: diff --git a/.pi/skills/sce-decision/SKILL.md b/.pi/skills/sce-decision/SKILL.md index 543044c4d..789d792ba 100644 --- a/.pi/skills/sce-decision/SKILL.md +++ b/.pi/skills/sce-decision/SKILL.md @@ -1,17 +1,17 @@ --- name: sce-decision description: > - Write one immutable ADR for one qualifying system-wide decision + Write one immutable ADR for one decision already qualified by context synchronization --- # SCE Decision ## Purpose -Write exactly one architecture decision record for one qualifying system-wide -important decision during successful task context synchronization. Return -a deterministic internal handoff to the invoking synchronization phase. Do not -render an independent user-visible response. +Write exactly one architecture decision record for one decision already qualified +by successful task context synchronization. Return a deterministic internal +handoff to the invoking synchronization phase. Do not render an independent +user-visible response. ## Input @@ -28,28 +28,22 @@ synchronization. It must identify: Do not accept raw workflow arguments, ordinary phase state, multiple decisions, or direct user invocation. Do not reconstruct missing material facts. -## Decision gate - -A decision qualifies only when it establishes or changes a system-wide important -constraint involving at least one of: - -- System boundaries or ownership. -- Public or cross-domain interfaces. -- Data models or persistence. -- Compatibility contracts. -- Security posture. -- Deployment or distribution strategy. -- A major dependency. -- A similarly durable constraint that is costly or risky to reverse. - -Routine implementation details, local refactors, naming and formatting choices, -temporary experiments, and easily reversible choices do not qualify. When the -request does not demonstrate the threshold, return `not_qualified` (or -`skipped` when the caller deliberately skips the gate); do not create an ADR -merely because context synchronization occurred. A nonqualifying or skipped -result is non-blocking, so the invoking synchronization phase continues -normally. Reserve `blocked` for missing, contradictory, or otherwise unsafe -decision input or history. +## Qualification handoff + +The invoking task context synchronization phase solely owns the decision +qualification threshold and decides whether this skill is invoked. Treat the +caller's gate result as authoritative; do not redefine, broaden, or independently +rerun that threshold here. + +Require the request to state why the caller qualified the decision and include +supporting evidence. If the request explicitly represents a nonqualifying gate +outcome, return `not_qualified` (or `skipped` when the caller deliberately skipped +the gate) without writing an ADR. If a claimed qualification is unsupported by +its supplied evidence, return `not_qualified`. Missing, contradictory, or +otherwise unsafe material input remains `blocked`. + +`not_qualified` and `skipped` are non-blocking to the invoking synchronization +phase. ## Workflow @@ -91,21 +85,10 @@ deterministic slug; never add an arbitrary counter and never overwrite a record. ### 4. Write the ADR -Create exactly one file using `references/adr-template.md` and these rules: - -- **Context** states the forces and constraint that made a decision necessary. -- **Decision** states one resulting choice, not a list of unrelated choices. -- **Rationale** explains why this path best satisfies the constraints. -- **Alternatives considered** names credible alternatives and why they were not - selected. -- **Compatibility and risks** states compatibility effects, migration concerns, - and material risks with mitigations. -- **Guardrails** records durable limits that keep the decision narrow. -- **Consequences** records positive and negative resulting constraints. -- **Follow-up** lists only established work or conditions; use `None.` when no - follow-up is established. -- **References** links the plan, relevant tasks, evidence, current-state context, - related ADRs, and any superseded ADR. +Read `references/adr-template.md` before writing. It is the sole authority for +the persisted ADR schema and section semantics. Populate that template from the +validated request and evidence; do not restate or invent a parallel section +contract here. Use repository-relative Markdown links where practical. Describe durable truth, not the implementation session. Do not edit current-state context; the invoking diff --git a/.pi/skills/sce-decision/references/adr-template.md b/.pi/skills/sce-decision/references/adr-template.md index 31891d448..8c2b06e77 100644 --- a/.pi/skills/sce-decision/references/adr-template.md +++ b/.pi/skills/sce-decision/references/adr-template.md @@ -1,7 +1,7 @@ # Decision: {concise decision title} Date: {YYYY-MM-DD} -Status: {Proposed|Accepted|Rejected|Deprecated|Superseded} +Status: {validated decision status} Plan: `{context/plans/plan-name.md}` Task: `{task-id or comma-separated task IDs}` Supersedes: `{context/decisions/YYYY-MM-DD-prior-decision.md}` @@ -14,7 +14,7 @@ Omit `Task` or `Supersedes` only when it does not apply. Do not omit `Plan`. ## Decision -{Exactly one durable system-wide choice.} +{Exactly one durable choice already qualified by task context synchronization.} ## Rationale diff --git a/.pi/skills/sce-next-task/references/context-sync.md b/.pi/skills/sce-next-task/references/context-sync.md index fb330bb6d..057043313 100644 --- a/.pi/skills/sce-next-task/references/context-sync.md +++ b/.pi/skills/sce-next-task/references/context-sync.md @@ -157,6 +157,10 @@ verified classification and explain the difference in the report. ## 3.5 Record qualifying architecture decisions +This subsection is the sole owner of decision qualification. The threshold below +decides whether `sce-decision` is invoked; the decision skill consumes that gate +result and must not restate or broaden it. + During this successful synchronization, determine whether the completed change establishes or changes a system-wide important constraint involving one or more of: diff --git a/config/pkl/base/decision-skill.pkl b/config/pkl/base/decision-skill.pkl index a18192a8f..af32ce7e5 100644 --- a/config/pkl/base/decision-skill.pkl +++ b/config/pkl/base/decision-skill.pkl @@ -5,7 +5,7 @@ import "workflow-content.pkl" as model /// user-facing command or prompt routes to this skill. local SKILL_SLUG = "sce-decision" -local SKILL_DESCRIPTION = "Write one immutable ADR for one qualifying system-wide decision" +local SKILL_DESCRIPTION = "Write one immutable ADR for one decision already qualified by context synchronization" local skillText = (extraFrontmatterLines: String) -> """ --- @@ -18,10 +18,10 @@ description: > ## Purpose -Write exactly one architecture decision record for one qualifying system-wide -important decision during successful task context synchronization. Return -a deterministic internal handoff to the invoking synchronization phase. Do not -render an independent user-visible response. +Write exactly one architecture decision record for one decision already qualified +by successful task context synchronization. Return a deterministic internal +handoff to the invoking synchronization phase. Do not render an independent +user-visible response. ## Input @@ -38,28 +38,22 @@ synchronization. It must identify: Do not accept raw workflow arguments, ordinary phase state, multiple decisions, or direct user invocation. Do not reconstruct missing material facts. -## Decision gate - -A decision qualifies only when it establishes or changes a system-wide important -constraint involving at least one of: - -- System boundaries or ownership. -- Public or cross-domain interfaces. -- Data models or persistence. -- Compatibility contracts. -- Security posture. -- Deployment or distribution strategy. -- A major dependency. -- A similarly durable constraint that is costly or risky to reverse. - -Routine implementation details, local refactors, naming and formatting choices, -temporary experiments, and easily reversible choices do not qualify. When the -request does not demonstrate the threshold, return `not_qualified` (or -`skipped` when the caller deliberately skips the gate); do not create an ADR -merely because context synchronization occurred. A nonqualifying or skipped -result is non-blocking, so the invoking synchronization phase continues -normally. Reserve `blocked` for missing, contradictory, or otherwise unsafe -decision input or history. +## Qualification handoff + +The invoking task context synchronization phase solely owns the decision +qualification threshold and decides whether this skill is invoked. Treat the +caller's gate result as authoritative; do not redefine, broaden, or independently +rerun that threshold here. + +Require the request to state why the caller qualified the decision and include +supporting evidence. If the request explicitly represents a nonqualifying gate +outcome, return `not_qualified` (or `skipped` when the caller deliberately skipped +the gate) without writing an ADR. If a claimed qualification is unsupported by +its supplied evidence, return `not_qualified`. Missing, contradictory, or +otherwise unsafe material input remains `blocked`. + +`not_qualified` and `skipped` are non-blocking to the invoking synchronization +phase. ## Workflow @@ -101,21 +95,10 @@ deterministic slug; never add an arbitrary counter and never overwrite a record. ### 4. Write the ADR -Create exactly one file using `references/adr-template.md` and these rules: - -- **Context** states the forces and constraint that made a decision necessary. -- **Decision** states one resulting choice, not a list of unrelated choices. -- **Rationale** explains why this path best satisfies the constraints. -- **Alternatives considered** names credible alternatives and why they were not - selected. -- **Compatibility and risks** states compatibility effects, migration concerns, - and material risks with mitigations. -- **Guardrails** records durable limits that keep the decision narrow. -- **Consequences** records positive and negative resulting constraints. -- **Follow-up** lists only established work or conditions; use `None.` when no - follow-up is established. -- **References** links the plan, relevant tasks, evidence, current-state context, - related ADRs, and any superseded ADR. +Read `references/adr-template.md` before writing. It is the sole authority for +the persisted ADR schema and section semantics. Populate that template from the +validated request and evidence; do not restate or invent a parallel section +contract here. Use repository-relative Markdown links where practical. Describe durable truth, not the implementation session. Do not edit current-state context; the invoking @@ -163,7 +146,7 @@ local templateText = """ # Decision: {concise decision title} Date: {YYYY-MM-DD} -Status: {Proposed|Accepted|Rejected|Deprecated|Superseded} +Status: {validated decision status} Plan: `{context/plans/plan-name.md}` Task: `{task-id or comma-separated task IDs}` Supersedes: `{context/decisions/YYYY-MM-DD-prior-decision.md}` @@ -176,7 +159,7 @@ Omit `Task` or `Supersedes` only when it does not apply. Do not omit `Plan`. ## Decision -{Exactly one durable system-wide choice.} +{Exactly one durable choice already qualified by task context synchronization.} ## Rationale diff --git a/config/pkl/base/workflow-context-sync.pkl b/config/pkl/base/workflow-context-sync.pkl index 0e60d9f7c..88c230fb1 100644 --- a/config/pkl/base/workflow-context-sync.pkl +++ b/config/pkl/base/workflow-context-sync.pkl @@ -65,6 +65,10 @@ local skillText = (role: SyncRole, mode: workflow.WorkflowRenderMode) -> role.frontmatter.apply(mode) + "\n\n" + skillBody.apply(role, mode) local decisionGate = (evidenceSource: String, mode: workflow.WorkflowRenderMode) -> """ + This subsection is the sole owner of decision qualification. The threshold below + decides whether `sce-decision` is invoked; the decision skill consumes that gate + result and must not restate or broaden it. + During this successful synchronization, determine whether the completed change establishes or changes a system-wide important constraint involving one or more of: @@ -1275,6 +1279,10 @@ verified classification and explain the difference in the report. ## 3.5 Record qualifying architecture decisions +This subsection is the sole owner of decision qualification. The threshold below +decides whether `sce-decision` is invoked; the decision skill consumes that gate +result and must not restate or broaden it. + During this successful synchronization, determine whether the completed change establishes or changes a system-wide important constraint involving one or more of: diff --git a/config/pkl/renderers/generation-contract-check.pkl b/config/pkl/renderers/generation-contract-check.pkl index 9cdda173e..e6a3ecc1d 100644 --- a/config/pkl/renderers/generation-contract-check.pkl +++ b/config/pkl/renderers/generation-contract-check.pkl @@ -202,15 +202,7 @@ local expectedDecisionDocumentPaths = new Mapping { } local requiredDecisionSkillTokens = new Listing { - "qualifying system-wide" - "System boundaries or ownership" - "Public or cross-domain interfaces" - "Data models or persistence" - "Compatibility contracts" - "Security posture" - "Deployment or distribution strategy" - "major dependency" - "Routine implementation details" + "already qualified" "YYYY-MM-DD-.md" "`Proposed`" "`Accepted`" @@ -220,11 +212,18 @@ local requiredDecisionSkillTokens = new Listing { "otherwise default" "Never edit an ADR whose status is `Accepted`" "creates a new dated ADR" - "exactly one file" + "references/adr-template.md" + "exactly one ADR" "`written`" "`blocked`" } +local requiredDecisionOwnershipSkillTokens = new Listing { + "## Qualification handoff" + "Treat the caller's gate result as authoritative" + "sole authority for\nthe persisted ADR schema and section semantics" +} + local requiredDecisionWorkflowTokens = new Listing { "Record qualifying architecture decisions" "System boundaries or ownership" @@ -241,6 +240,42 @@ local requiredDecisionWorkflowTokens = new Listing { "On `blocked`" } +local requiredDecisionTemplateTokens = new Listing { + "## Context" + "## Decision" + "## Rationale" + "## Alternatives considered" + "## Compatibility and risks" + "## Guardrails" + "## Consequences" + "## Follow-up" + "## References" +} + +local forbiddenDecisionSkillGateTokens = new Listing { + "System boundaries or ownership" + "Public or cross-domain interfaces" + "Data models or persistence" + "Compatibility contracts" + "Security posture" + "Deployment or distribution strategy" + "A major dependency" + "Routine implementation details, local refactors" + "similarly durable constraint that is costly or risky to reverse" +} + +local forbiddenDecisionSkillTemplateRestatementTokens = new Listing { + "**Context** states" + "**Decision** states" + "**Rationale** explains" + "**Alternatives considered** names" + "**Compatibility and risks** states" + "**Guardrails** records" + "**Consequences** records" + "**Follow-up** lists" + "**References** links" +} + local requiredHandoverSkillTokens = new Listing { "selects **writer mode**" "selects **loader mode**" @@ -418,18 +453,6 @@ local requiredPhaseReferencesBySkill = new Mapping { } } -local requiredDecisionTemplateTokens = new Listing { - "## Context" - "## Decision" - "## Rationale" - "## Alternatives considered" - "## Compatibility and risks" - "## Guardrails" - "## Consequences" - "## Follow-up" - "## References" -} - local forbiddenWorkflowReferenceTokens = new Listing { "sce-context-load" "sce-plan-authoring" @@ -599,6 +622,42 @@ local assertDecisionContent = (documents: Mapping) -> ) "generated decision package content: complete" else throw("generated decision package is missing a required ADR rule or template section") +hidden assertDecisionGateTemplateOwnership = (artifacts: Mapping) -> + let (contexts = new Listing { + artifacts["config/.pi/skills/sce-next-task/references/context-sync.md"] + artifacts["config/.claude/skills/sce-next-task/references/context-sync.md"] + artifacts["config/.agents/skills/sce-next-task/references/context-sync.md"] + }) + let (skills = new Listing { + artifacts["config/.pi/skills/sce-decision/SKILL.md"] + artifacts["config/.claude/skills/sce-decision/SKILL.md"] + artifacts["config/.agents/skills/sce-decision/SKILL.md"] + }) + let (templates = new Listing { + artifacts["config/.pi/skills/sce-decision/references/adr-template.md"] + artifacts["config/.claude/skills/sce-decision/references/adr-template.md"] + artifacts["config/.agents/skills/sce-decision/references/adr-template.md"] + }) + if ( + contexts.every((text) -> text.contains("sole owner of decision qualification")) + && skills.every((text) -> + text.contains("## Qualification handoff") + && text.contains("caller's gate result as authoritative") + && text.contains("sole authority for") + && text.contains("persisted ADR schema and section semantics") + && !text.contains("## Decision gate") + && !text.contains("**Context** states") + && !text.contains("**Decision** states") + ) + && templates.every((text) -> + text.contains("Status: {validated decision status}") + && text.contains("## Context") + && text.contains("## Decision") + && text.contains("## Rationale") + && !text.contains("Proposed|Accepted|Rejected|Deprecated|Superseded") + ) + ) "sce-decision: context sync owns qualification and ADR template owns persisted section semantics" + else throw("decision qualification must be owned by tracked context-sync outputs while sce-decision consumes the gate and adr-template.md owns persisted ADR schema") local assertHandoverContent = (documents: Mapping) -> if ( documents.length == 4 @@ -1167,6 +1226,7 @@ contractChecks { ["opencode-decision-permission"] = assertOpenCodeDecisionPermission.apply(opencode.agents) ["decision-package-paths"] = assertDecisionDocumentPaths.apply(decisionSkillDocuments) ["decision-package-content"] = assertDecisionContent.apply(decisionSkillDocuments) + ["decision-gate-template-ownership"] = assertDecisionGateTemplateOwnership.apply(generatedArtifacts) ["handover-package-content"] = assertHandoverContent.apply(handoverSkillDocuments) ["handover-schema-completeness-ownership"] = assertHandoverSchemaCompletenessOwnership.apply(workflowDocuments) ["brownfield-package-content"] = assertBrownfieldContent.apply(brownfieldSkillDocuments) diff --git a/context/plans/compress-workflow-execution-preamble.md b/context/plans/compress-workflow-execution-preamble.md index 445d91870..99f9fca82 100644 --- a/context/plans/compress-workflow-execution-preamble.md +++ b/context/plans/compress-workflow-execution-preamble.md @@ -427,3 +427,28 @@ The two additional root edits replace existing text without increasing line coun - Verify: `pkl eval config/pkl/renderers/generation-contract-check.pkl`, `nix run .#pkl-check-generated`, targeted ownership checks, and `git diff --check`. - Context synchronization: synced. + + +## Follow-up: decision qualification and ADR-template ownership + +- [x] T10: `Deduplicate decision gate and ADR section semantics` (status:done) + - Scope: task context-sync decision qualification, the standalone `sce-decision` + package, `references/adr-template.md`, canonical Pkl, generated semantic checks, + tracked Pi/Claude/Codex mirrors, and the ownership table. + - Ownership after change: `decisionGate` in `workflow-context-sync.pkl` solely owns + the qualification threshold and invocation decision. `sce-decision/SKILL.md` + consumes the caller's gate result and owns ADR lifecycle/history/path/result + behavior. `references/adr-template.md` solely owns the persisted ADR schema and + section semantics. + - Behavior preserved: only successful task synchronization invokes `sce-decision`; + routine/reversible changes remain nonqualifying; one request still writes or + reuses at most one ADR; allowed status/default, immutability, supersession, + collision handling, nonblocking `not_qualified`/`skipped`, blocking unsafe input, + and internal result shapes remain unchanged. + - Result: the selected decision skill/template plus next-task context-sync documents + shrink by 13 Markdown lines per tracked target, 39 + across Pi/Claude/Codex. + - Verify: `pkl eval config/pkl/renderers/generation-contract-check.pkl`, + `nix run .#pkl-check-generated`, targeted ownership checks across all tracked + mirrors, and `git diff --check`. + - Context synchronization: synced. diff --git a/context/sce/dedup-ownership-table.md b/context/sce/dedup-ownership-table.md index 4d6d8833a..6dd351197 100644 --- a/context/sce/dedup-ownership-table.md +++ b/context/sce/dedup-ownership-table.md @@ -31,7 +31,9 @@ | Handover persisted schema and completeness validity | `references/handover-template.md` generated from `renderPersistedFormatBody` in `workflow-handover.pkl` | Writer composes and validates against this contract; loader validates against the same contract; `sce-handover/SKILL.md` owns routing, path checks, read/write boundaries, and terminal layout selection without restating required-section or content-validity rules | intentional/keep | | Compact workflow execution contract | `executionContract` in `workflow-content.pkl` | Inline in change-to-plan, next-task, commit, validate, and handover entrypoints on all four targets; no extra runtime read | shared rendering, preserved behavior | | Workflow routing | Six command documents in the workflow modules | Thin OpenCode Plan/Code agents | intentional/keep | -| Standalone ADR writing contract | `decision-skill.pkl` | Cross-target `sce-decision` package; successful task synchronization invokes it through the shared decision gate | intentional/keep | +| Decision qualification gate | `decisionGate` in `workflow-context-sync.pkl` | Successful task context synchronization decides qualification and invokes `sce-decision` once per qualifying decision; `sce-decision` consumes the caller's gate result without restating or broadening the threshold | intentional/keep | +| Standalone ADR lifecycle, history, path, and result contract | `sce-decision/SKILL.md` generated from `skillText` in `decision-skill.pkl` | Cross-target internal `sce-decision` package; consumes one already-qualified request, validates status/history/path safety, writes or reuses one ADR, and returns the internal result | intentional/keep | +| Persisted ADR schema and section semantics | `references/adr-template.md` generated from `templateText` in `decision-skill.pkl` | `sce-decision` reads and populates the template at the write boundary without restating the section schema or field semantics | intentional/keep | ## Guardrails From 0f8b2c54b756a3d0902718d30baedf4d72d859af Mon Sep 17 00:00:00 2001 From: David Abram Date: Tue, 8 Sep 2026 15:31:42 +0000 Subject: [PATCH 11/12] config: Normalize workflow language and format --- .agents/skills/sce-change-to-plan/SKILL.md | 6 +- .../references/context-load.md | 4 +- .../sce-change-to-plan/references/output.md | 32 ++--- .../references/plan-authoring.md | 36 ++---- .../references/plan-template.md | 6 +- .agents/skills/sce-commit/SKILL.md | 12 +- .../sce-commit/references/atomic-commit.md | 8 +- .agents/skills/sce-handover/SKILL.md | 6 +- .../references/handover-template.md | 14 ++- .../skills/sce-handover/references/output.md | 2 +- .agents/skills/sce-next-task/SKILL.md | 15 ++- .../sce-next-task/references/context-sync.md | 2 +- .../skills/sce-next-task/references/output.md | 2 +- .agents/skills/sce-validate/SKILL.md | 8 +- .../sce-validate/references/validation.md | 21 ++-- .claude/skills/sce-change-to-plan/SKILL.md | 6 +- .../references/context-load.md | 4 +- .../sce-change-to-plan/references/output.md | 32 ++--- .../references/plan-authoring.md | 36 ++---- .../references/plan-template.md | 6 +- .claude/skills/sce-commit/SKILL.md | 12 +- .../sce-commit/references/atomic-commit.md | 8 +- .claude/skills/sce-handover/SKILL.md | 6 +- .../references/handover-template.md | 14 ++- .../skills/sce-handover/references/output.md | 2 +- .claude/skills/sce-next-task/SKILL.md | 15 ++- .../sce-next-task/references/context-sync.md | 2 +- .../skills/sce-next-task/references/output.md | 2 +- .claude/skills/sce-validate/SKILL.md | 8 +- .../sce-validate/references/validation.md | 21 ++-- .pi/skills/sce-change-to-plan/SKILL.md | 6 +- .../references/context-load.md | 4 +- .../sce-change-to-plan/references/output.md | 32 ++--- .../references/plan-authoring.md | 36 ++---- .../references/plan-template.md | 6 +- .pi/skills/sce-commit/SKILL.md | 12 +- .../sce-commit/references/atomic-commit.md | 8 +- .pi/skills/sce-handover/SKILL.md | 6 +- .../references/handover-template.md | 14 ++- .pi/skills/sce-handover/references/output.md | 2 +- .pi/skills/sce-next-task/SKILL.md | 15 ++- .../sce-next-task/references/context-sync.md | 2 +- .pi/skills/sce-next-task/references/output.md | 2 +- .pi/skills/sce-validate/SKILL.md | 8 +- .../sce-validate/references/validation.md | 21 ++-- config/pkl/base/workflow-change-to-plan.pkl | 112 ++++++++---------- config/pkl/base/workflow-commit.pkl | 20 ++-- config/pkl/base/workflow-content.pkl | 17 ++- config/pkl/base/workflow-context-sync.pkl | 6 +- config/pkl/base/workflow-handover.pkl | 16 +-- config/pkl/base/workflow-next-task.pkl | 2 +- config/pkl/base/workflow-validate.pkl | 25 ++-- .../renderers/generation-contract-check.pkl | 47 ++++++-- .../compress-workflow-execution-preamble.md | 11 ++ context/sce/dedup-ownership-table.md | 13 ++ 55 files changed, 391 insertions(+), 400 deletions(-) diff --git a/.agents/skills/sce-change-to-plan/SKILL.md b/.agents/skills/sce-change-to-plan/SKILL.md index 8d88bb175..d7e569cb9 100644 --- a/.agents/skills/sce-change-to-plan/SKILL.md +++ b/.agents/skills/sce-change-to-plan/SKILL.md @@ -10,10 +10,10 @@ description: > Own this workflow from input through its terminal user-visible response. Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. -Keep phase results internal and continue immediately until a defined wait or stop. +Keep internal phase results private and continue immediately until a defined wait or stop. Resume user waits in this same skill and session. -Use only the specified `references/output.md` layouts for gates and terminal -responses. Do not expose raw state or add text around a layout. +Render user-visible output only from the named workflow layouts or phase reports. +Do not expose raw internal state or add text around a rendered layout or report. Non-SCE helpers may assist, but must return to the active step without changing phase order, gates, waits, writes, validation, stops, or terminal output. Do not invoke another SCE skill, package, or workflow command. diff --git a/.agents/skills/sce-change-to-plan/references/context-load.md b/.agents/skills/sce-change-to-plan/references/context-load.md index 197a28c2d..60cc26efb 100644 --- a/.agents/skills/sce-change-to-plan/references/context-load.md +++ b/.agents/skills/sce-change-to-plan/references/context-load.md @@ -61,7 +61,7 @@ sentence. ## 1.5 Return the brief -Set exactly one internal state: +Return one internal result with one of these statuses: - `loaded` - `bootstrap_required` @@ -69,7 +69,7 @@ Set exactly one internal state: Report facts the workflow can act on. A brief that only lists file paths has moved no knowledge. -Record only the internal state. Do not add explanatory prose before or after it. +Return only the internal result. Do not add explanatory prose before or after it. Step 2 consumes a `loaded` brief verbatim and treats its `key_facts` as recorded current state, its `gaps` as areas with no durable context, and its `drift` as diff --git a/.agents/skills/sce-change-to-plan/references/output.md b/.agents/skills/sce-change-to-plan/references/output.md index 170f39491..bc7e1a3fc 100644 --- a/.agents/skills/sce-change-to-plan/references/output.md +++ b/.agents/skills/sce-change-to-plan/references/output.md @@ -48,7 +48,7 @@ candidate plan paths and explain that naming one candidate resolves it. This plan is a draft. State a correction and it will be updated. -Next up: +Next step: {next-task-id} — {next-task-title} @@ -71,17 +71,17 @@ This is chat output, not a file. Nothing here is written to the plan. Path: {plan.path} -## Summary: +## Summary {plan summary} -## Tasks: +## Tasks 1. {task.id} — {task.title} 2. {task.id} — {task.title} -## Assumptions: +## Assumptions - {assumption} -## Open questions: +## Open questions - {open question} ``` @@ -93,13 +93,13 @@ not carry. - `Plan:` — `plan.name`. Append ` (updated)` when `plan.action` is `updated`. Render nothing extra when it is `created`. - `Path:` — `plan.path`, exactly as returned, so it stays runnable. -- `Summary:` — `summary`, as prose. This is the only place the reader learns +- `Summary` — `summary`, as prose. This is the only place the reader learns what the plan actually does, so never omit it and never replace it with a restatement of the task titles. -- `Tasks:` — one numbered line per entry in `tasks`, in plan order. Append +- `Tasks` — one numbered line per entry in `tasks`, in plan order. Append ` (done)` to any task whose `status` is `done`. -- `Assumptions:` — one line per entry in `assumptions`. -- `Open questions:` — one line per entry in `open_questions`. +- `Assumptions` — one line per entry in `assumptions`. +- `Open questions` — one line per entry in `open_questions`. ## Empty sections @@ -109,14 +109,14 @@ explicit `None.` confirms nothing is pending. When `assumptions` is empty: ``` -## Assumptions: +## Assumptions - None. ``` When `open_questions` is absent: ``` -## Open questions: +## Open questions - None. ``` @@ -137,16 +137,16 @@ When `open_questions` is absent: Path: context/plans/red-sce-banner.md -## Summary: -Renders the ASCII-art SCE banner at the top of `sce` help in red instead of the current gradient. Colour-disabled output is unchanged, and no other help surface is affected. +## Summary +Renders the ASCII-art SCE banner at the top of `sce` help in red instead of the current gradient. Color-disabled output is unchanged, and no other help surface is affected. -## Tasks: +## Tasks 1. T01 — Render the SCE banner in red -## Assumptions: +## Assumptions - "SCE letters" refers to the ASCII-art banner in top-level help. - Red is uniform terminal red when colors are enabled; plain ASCII remains unchanged otherwise. -## Open questions: +## Open questions - None. ``` diff --git a/.agents/skills/sce-change-to-plan/references/plan-authoring.md b/.agents/skills/sce-change-to-plan/references/plan-authoring.md index 98335bf34..fdd3abe7a 100644 --- a/.agents/skills/sce-change-to-plan/references/plan-authoring.md +++ b/.agents/skills/sce-change-to-plan/references/plan-authoring.md @@ -28,7 +28,7 @@ responsibility. The context brief is the durable memory this plan starts from. Treat its `key_facts` as recorded current state, its `gaps` as areas with no durable -context, and its `drift` as context the code has already outrun. +context, and its `drift` as recorded context that no longer matches the code. When no brief is supplied, load the context named by the change request before authoring, and follow the selection discipline in *Inspect relevant context*. @@ -178,13 +178,13 @@ exactly. For revisions, apply its `Updating an existing plan` rules. ## 2.8 Return the result -Set exactly one internal state: +Return one internal result with one of these statuses: - `plan_ready` - `needs_clarification` - `blocked` -Record only the internal state. Do not add explanatory prose before or after it. +Return only the internal result. Do not add explanatory prose before or after it. A `plan_ready` result always names the next task in `next_task`, and carries the `total_tasks` count and any open questions the summary needs. Step 3 renders those @@ -192,29 +192,13 @@ without recomputing them. ## Plan authoring tone -Every question and open question this phase writes is read by the user. Write -them the way a senior engineer talks in review: direct, specific, and unbothered -by the possibility of being unwelcome. - -- Ask about the thing that actually worries you, not a safer neighbouring thing. - A question you would not bother asking a colleague is not worth the user's - attention either. -- State a doubt as a doubt. "I do not think this is worth the two tasks it - costs, because X" is useful. "It may be worth considering whether this aligns - with broader goals" is noise. -- Name the alternative you have in mind. A challenge with no proposal behind it - is just friction. -- Do not open with praise, do not close with reassurance, and do not apologize - for asking. Do not pad a doubt with hedges to make it land more gently. -- Be persistent, not repetitive. Ask once, plainly, and let it stand; do not - restate the same doubt in three shapes to give it more weight. -- Being disagreeable is not the goal. Being easy to agree with is the failure - mode. A plan the user waves through without reading has cost them nothing and - bought them nothing. - -When the user overrules a doubt, record it and move on. Do not relitigate a -decision the user has made, and do not smuggle the objection back in as a -constraint, a non-goal, or a task. +Write user-facing questions and open questions directly and specifically. + +- Ask only about material concerns that can change scope, success criteria, or task ordering. +- State the concern and the concrete evidence for it. +- Name a smaller or safer alternative when one is known. +- Do not invent concerns, add praise or reassurance, or repeat the same concern in several forms. +- When the user overrules a concern, record the decision and continue. Do not reintroduce it as a constraint, non-goal, or task. ## Plan authoring boundaries diff --git a/.agents/skills/sce-change-to-plan/references/plan-template.md b/.agents/skills/sce-change-to-plan/references/plan-template.md index 416ac8a6b..fe0190b94 100644 --- a/.agents/skills/sce-change-to-plan/references/plan-template.md +++ b/.agents/skills/sce-change-to-plan/references/plan-template.md @@ -146,9 +146,9 @@ invent one: `None.` is the expected answer for a well-specified change.} - The last task in the stack is an ordinary implementation task. Do not author a trailing "validation and cleanup" task. -- Final validation, cleanup, and success-criteria verification are run by - `/validate` from the `Acceptance criteria` section after the last task - completes. +- Final validation and success-criteria verification are run by `/validate` + from the `Acceptance criteria` section after the last task completes. Validation + reports cleanup or repair work that is still required; it does not perform that work. - Do not author a task whose only purpose is running the full check suite, verifying durable context, or removing scaffolding. - A task may still create or update durable context when that context is part of diff --git a/.agents/skills/sce-commit/SKILL.md b/.agents/skills/sce-commit/SKILL.md index 32c687074..d48fa9c46 100644 --- a/.agents/skills/sce-commit/SKILL.md +++ b/.agents/skills/sce-commit/SKILL.md @@ -10,10 +10,10 @@ description: > Own this workflow from input through its terminal user-visible response. Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. -Keep phase results internal and continue immediately until a defined wait or stop. +Keep internal phase results private and continue immediately until a defined wait or stop. Resume user waits in this same skill and session. -Use only the specified `references/output.md` layouts for gates and terminal -responses. Do not expose raw state or add text around a layout. +Render user-visible output only from the named workflow layouts or phase reports. +Do not expose raw internal state or add text around a rendered layout or report. Non-SCE helpers may assist, but must return to the active step without changing phase order, gates, waits, writes, validation, stops, or terminal output. Do not invoke another SCE skill, package, or workflow command. @@ -99,14 +99,14 @@ Run `git diff --cached --quiet`. A zero exit status means nothing is staged. When nothing is staged, stop with the **No staged changes** layout from `references/output.md`. -Do not stage anything. Do not proceed to the skill. +Do not stage anything. Do not proceed to the phase. #### 2. Request one commit message Read `references/atomic-commit.md`, then run the **Atomic commit phase** with `mode: bypass` and the commit context. -Bypass mode is the skill's contract for producing exactly one message. Do not +Bypass mode is the phase's contract for producing exactly one message. Do not restate its overrides here; the **Atomic commit phase** owns them. Branch on `status`: @@ -115,7 +115,7 @@ Branch on `status`: `bypass_message` -> Continue to the next step. -The skill never returns `proposal` in bypass mode. Treat a `proposal` result as +The phase never returns `proposal` in bypass mode. Treat a `proposal` result as a contract violation: report it and stop without committing. #### 3. Execute exactly one commit diff --git a/.agents/skills/sce-commit/references/atomic-commit.md b/.agents/skills/sce-commit/references/atomic-commit.md index 5df2c0a8b..ba529bf29 100644 --- a/.agents/skills/sce-commit/references/atomic-commit.md +++ b/.agents/skills/sce-commit/references/atomic-commit.md @@ -1,4 +1,4 @@ -# SCE Atomic Commit +# Atomic commit phase ## Purpose @@ -8,8 +8,8 @@ Write messages matching: `references/commit-message-style.md` -Committing is not this skill's job. The invoking `/commit` workflow decides -whether a returned message is committed, and it is the only thing that runs +This phase does not commit. The invoking `/commit` workflow decides +whether a returned message is committed, and it is the only part that runs `git commit`. ## Input @@ -147,7 +147,7 @@ Do not: ## Completion -The skill is complete after: +The phase is complete after: - The staged diff was read, or reading it failed and was reported. - Messages were written for every staged file, or a blocker prevented it. diff --git a/.agents/skills/sce-handover/SKILL.md b/.agents/skills/sce-handover/SKILL.md index 67cd81aef..8c2827581 100644 --- a/.agents/skills/sce-handover/SKILL.md +++ b/.agents/skills/sce-handover/SKILL.md @@ -10,10 +10,10 @@ description: > Own this workflow from input through its terminal user-visible response. Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. -Keep phase results internal and continue immediately until a defined wait or stop. +Keep internal phase results private and continue immediately until a defined wait or stop. Resume user waits in this same skill and session. -Use only the specified `references/output.md` layouts for gates and terminal -responses. Do not expose raw state or add text around a layout. +Render user-visible output only from the named workflow layouts or phase reports. +Do not expose raw internal state or add text around a rendered layout or report. Non-SCE helpers may assist, but must return to the active step without changing phase order, gates, waits, writes, validation, stops, or terminal output. Do not invoke another SCE skill, package, or workflow command. diff --git a/.agents/skills/sce-handover/references/handover-template.md b/.agents/skills/sce-handover/references/handover-template.md index d934da801..8977f935b 100644 --- a/.agents/skills/sce-handover/references/handover-template.md +++ b/.agents/skills/sce-handover/references/handover-template.md @@ -1,8 +1,10 @@ +# Handover document format + The Markdown document writer mode creates under `context/handovers/{name}.md`. This is the persisted file's content, distinct from the terminal response defined in `references/output.md`. -### Layout +## Template ```markdown # Handover: {plan name or short session topic} @@ -35,9 +37,9 @@ enough to act on directly.} `None.`} ``` -### Completeness contract +## Completeness contract -- The first four `##` sections shown in **Layout** are required and must appear +- The first four `##` sections shown in **Template** are required and must appear in that order. - Each required section's content, up to the next `##` heading or the end of the file, must contain non-whitespace content. An empty list marker, unreplaced @@ -47,10 +49,10 @@ enough to act on directly.} - Writer mode must satisfy this contract before reporting success; loader mode validates the same contract before presenting a handover. -### Rules +## Rules -- Include `Plan` and `Task` only when the session was working one identifiable - plan task; omit them rather than guessing. +- Include `Plan` when one plan is known. Include `Task` only when one task is + known. Omit either field rather than guessing its value. - Keep `Assumptions` scoped to details actually labeled as inferred elsewhere in the document; do not duplicate confirmed facts here. - Describe durable state useful to a future session, not a transcript of this diff --git a/.agents/skills/sce-handover/references/output.md b/.agents/skills/sce-handover/references/output.md index 3d1e63891..e5e4b5211 100644 --- a/.agents/skills/sce-handover/references/output.md +++ b/.agents/skills/sce-handover/references/output.md @@ -83,7 +83,7 @@ This handover has been presented for continuation only. No file was edited, no plan task was marked complete, and the recommended next step was not started. ``` -# Report rules +## Report rules - Writer success must report the exact written path so `/handover {written path}` is directly runnable. diff --git a/.agents/skills/sce-next-task/SKILL.md b/.agents/skills/sce-next-task/SKILL.md index 83db8f34f..4eeae8510 100644 --- a/.agents/skills/sce-next-task/SKILL.md +++ b/.agents/skills/sce-next-task/SKILL.md @@ -10,10 +10,10 @@ description: > Own this workflow from input through its terminal user-visible response. Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. -Keep phase results internal and continue immediately until a defined wait or stop. +Keep internal phase results private and continue immediately until a defined wait or stop. Resume user waits in this same skill and session. -Use only the specified `references/output.md` layouts for gates and terminal -responses. Do not expose raw state or add text around a layout. +Render user-visible output only from the named workflow layouts or phase reports. +Do not expose raw internal state or add text around a rendered layout or report. Non-SCE helpers may assist, but must return to the active step without changing phase order, gates, waits, writes, validation, stops, or terminal output. Do not invoke another SCE skill, package, or workflow command except `sce-decision`, @@ -81,7 +81,7 @@ Branch on the outcome: `synced` | `no_context_change` -> Re-invoke the **Plan review phase** with the same `plan-name-or-path` and, when present, `task-id` to resume normal task selection. -`plan_complete` -> Render the **Plan already complete** layout from `references/output.md`. Stop. +`plan_complete` -> Render the **Implementation complete** layout from `references/output.md`. Stop. `ready` -> Pass the complete readiness result to the **Task execution phase**. @@ -120,10 +120,9 @@ Branch on the execution result. ### 3. Synchronize context Read `references/context-sync.md`, then run the **Task context synchronization -phase** with the complete `complete` result returned by the **Task execution -phase**. +phase** with the task execution result whose `status` is `complete`. -Pass that `complete` result verbatim as the authoritative live handoff to the +Pass that result unchanged as the authoritative live handoff to the **Task context synchronization phase**. Do not restate, summarize, or reconstruct it. This phase verifies the five root context files on every invocation, whatever the @@ -140,7 +139,7 @@ Branch on the synchronization result. Do not select another task. Stop. -`synced` | `no_context_change` -> Print out the report the **Task context synchronization phase** returned. Continue to the next step. +`synced` | `no_context_change` -> Render the Markdown report returned by the **Task context synchronization phase** unchanged. Continue to the next step. ### 4. Determine the continuation diff --git a/.agents/skills/sce-next-task/references/context-sync.md b/.agents/skills/sce-next-task/references/context-sync.md index 057043313..6e6074dcf 100644 --- a/.agents/skills/sce-next-task/references/context-sync.md +++ b/.agents/skills/sce-next-task/references/context-sync.md @@ -7,7 +7,7 @@ plan state. Input: either the complete `complete` result from the task execution phase (same-session), passed verbatim, or the plan path and task ID a plan-review -recovery step resolved for a `blocked` task, together with that task's own +recovery step resolved for a completed task with unresolved context synchronization, together with that task's own completed record — read directly from the plan — and its persisted `Context synchronization blocker` when present (cross-session retry). Whichever was supplied is authoritative; this phase consumes it without redefining its shape. diff --git a/.agents/skills/sce-next-task/references/output.md b/.agents/skills/sce-next-task/references/output.md index 3c4f5e2ab..40a66539f 100644 --- a/.agents/skills/sce-next-task/references/output.md +++ b/.agents/skills/sce-next-task/references/output.md @@ -8,7 +8,7 @@ Present the selected task, then each issue's problem, impact, and required decision. If plan resolution is ambiguous, list candidate paths and `/next-task {candidate-path}`. State whether another task remains executable. -## Plan already complete +## Implementation complete ```markdown ------------------------------------- diff --git a/.agents/skills/sce-validate/SKILL.md b/.agents/skills/sce-validate/SKILL.md index cd8366bc8..862f03953 100644 --- a/.agents/skills/sce-validate/SKILL.md +++ b/.agents/skills/sce-validate/SKILL.md @@ -10,10 +10,10 @@ description: > Own this workflow from input through its terminal user-visible response. Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. -Keep phase results internal and continue immediately until a defined wait or stop. +Keep internal phase results private and continue immediately until a defined wait or stop. Resume user waits in this same skill and session. -Use only the specified `references/output.md` layouts for gates and terminal -responses. Do not expose raw state or add text around a layout. +Render user-visible output only from the named workflow layouts or phase reports. +Do not expose raw internal state or add text around a rendered layout or report. Non-SCE helpers may assist, but must return to the active step without changing phase order, gates, waits, writes, validation, stops, or terminal output. Do not invoke another SCE skill, package, or workflow command. @@ -50,7 +50,7 @@ Pass the plan name or path to the **Validation phase** unmodified. Do not restat summarize, or pre-scope it. Every `{plan-path}` and `{candidate-path}` emitted anywhere in this workflow is -the path carried by the **Validation phase** in its Markdown result (`Plan:`, or a +the path carried by the **Validation phase** in its Markdown report (`Plan:`, or a candidate path), so every emitted command is directly runnable. For example: `$sce-validate my-plan`. diff --git a/.agents/skills/sce-validate/references/validation.md b/.agents/skills/sce-validate/references/validation.md index 4b343f277..50895cc83 100644 --- a/.agents/skills/sce-validate/references/validation.md +++ b/.agents/skills/sce-validate/references/validation.md @@ -1,4 +1,4 @@ -# SCE Validation +# Validation phase ## Purpose @@ -79,8 +79,7 @@ validation. When a check fails, record the failure and continue gathering evidence. Do not modify tests, application code, or configuration to make a check pass. Final -validation measures the finished work; repair belongs to a later work session, -not this skill. +validation measures the finished work; repair belongs to a normal work session outside this phase. Never report a check as passed unless it ran successfully or the authorized inspection confirmed the criterion. @@ -102,9 +101,9 @@ Do not reopen completed tasks, rewrite task evidence, or change the task stack. For `blocked`, leave the plan file unchanged. -### 6. Return the Markdown result +### 6. Return the Markdown report -Return exactly one Markdown result: +Return exactly one Markdown report: - `validated` when every acceptance criterion is met, required full validation passed, and the Validation Report was written. @@ -141,12 +140,12 @@ The phase is complete after: - One plan was resolved, or resolution failed and was reported. - Implementation completeness was checked. - Validation ran to a terminal state, or a blocker prevented it. -- One valid Markdown result matching the **Validation Result** section below in this file was +- One valid Markdown report matching the **Validation Result** section below in this file was returned. -# Validation Result +# Validation report Return only one completed Markdown report using the applicable variant below. Do not include unused sections, placeholders, YAML, or a fenced code block. @@ -158,10 +157,10 @@ The `Status` value must be exactly one of: - `blocked` The plan-file `## Validation Report` section is written separately using -`references/validation-report.md`. This file is the skill's return value to the +`references/validation-report.md`. This file is the phase's return value to the invoking workflow. -## Validated variant +## Validated report # Validation Report @@ -192,7 +191,7 @@ Omit this section when unnecessary.} --- -## Failed variant +## Failed report This variant is a session handoff. Another agent or a later session must be able to act from it alone. Write it as a prompt the user can paste forward, not @@ -256,7 +255,7 @@ returns `validated`. --- -## Blocked variant +## Blocked report # Validation blocked diff --git a/.claude/skills/sce-change-to-plan/SKILL.md b/.claude/skills/sce-change-to-plan/SKILL.md index d9bb76f94..6a049f92f 100644 --- a/.claude/skills/sce-change-to-plan/SKILL.md +++ b/.claude/skills/sce-change-to-plan/SKILL.md @@ -11,10 +11,10 @@ compatibility: claude Own this workflow from input through its terminal user-visible response. Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. -Keep phase results internal and continue immediately until a defined wait or stop. +Keep internal phase results private and continue immediately until a defined wait or stop. Resume user waits in this same skill and session. -Use only the specified `references/output.md` layouts for gates and terminal -responses. Do not expose raw state or add text around a layout. +Render user-visible output only from the named workflow layouts or phase reports. +Do not expose raw internal state or add text around a rendered layout or report. Non-SCE helpers may assist, but must return to the active step without changing phase order, gates, waits, writes, validation, stops, or terminal output. Do not invoke another SCE skill, package, or workflow command. diff --git a/.claude/skills/sce-change-to-plan/references/context-load.md b/.claude/skills/sce-change-to-plan/references/context-load.md index 197a28c2d..60cc26efb 100644 --- a/.claude/skills/sce-change-to-plan/references/context-load.md +++ b/.claude/skills/sce-change-to-plan/references/context-load.md @@ -61,7 +61,7 @@ sentence. ## 1.5 Return the brief -Set exactly one internal state: +Return one internal result with one of these statuses: - `loaded` - `bootstrap_required` @@ -69,7 +69,7 @@ Set exactly one internal state: Report facts the workflow can act on. A brief that only lists file paths has moved no knowledge. -Record only the internal state. Do not add explanatory prose before or after it. +Return only the internal result. Do not add explanatory prose before or after it. Step 2 consumes a `loaded` brief verbatim and treats its `key_facts` as recorded current state, its `gaps` as areas with no durable context, and its `drift` as diff --git a/.claude/skills/sce-change-to-plan/references/output.md b/.claude/skills/sce-change-to-plan/references/output.md index 170f39491..bc7e1a3fc 100644 --- a/.claude/skills/sce-change-to-plan/references/output.md +++ b/.claude/skills/sce-change-to-plan/references/output.md @@ -48,7 +48,7 @@ candidate plan paths and explain that naming one candidate resolves it. This plan is a draft. State a correction and it will be updated. -Next up: +Next step: {next-task-id} — {next-task-title} @@ -71,17 +71,17 @@ This is chat output, not a file. Nothing here is written to the plan. Path: {plan.path} -## Summary: +## Summary {plan summary} -## Tasks: +## Tasks 1. {task.id} — {task.title} 2. {task.id} — {task.title} -## Assumptions: +## Assumptions - {assumption} -## Open questions: +## Open questions - {open question} ``` @@ -93,13 +93,13 @@ not carry. - `Plan:` — `plan.name`. Append ` (updated)` when `plan.action` is `updated`. Render nothing extra when it is `created`. - `Path:` — `plan.path`, exactly as returned, so it stays runnable. -- `Summary:` — `summary`, as prose. This is the only place the reader learns +- `Summary` — `summary`, as prose. This is the only place the reader learns what the plan actually does, so never omit it and never replace it with a restatement of the task titles. -- `Tasks:` — one numbered line per entry in `tasks`, in plan order. Append +- `Tasks` — one numbered line per entry in `tasks`, in plan order. Append ` (done)` to any task whose `status` is `done`. -- `Assumptions:` — one line per entry in `assumptions`. -- `Open questions:` — one line per entry in `open_questions`. +- `Assumptions` — one line per entry in `assumptions`. +- `Open questions` — one line per entry in `open_questions`. ## Empty sections @@ -109,14 +109,14 @@ explicit `None.` confirms nothing is pending. When `assumptions` is empty: ``` -## Assumptions: +## Assumptions - None. ``` When `open_questions` is absent: ``` -## Open questions: +## Open questions - None. ``` @@ -137,16 +137,16 @@ When `open_questions` is absent: Path: context/plans/red-sce-banner.md -## Summary: -Renders the ASCII-art SCE banner at the top of `sce` help in red instead of the current gradient. Colour-disabled output is unchanged, and no other help surface is affected. +## Summary +Renders the ASCII-art SCE banner at the top of `sce` help in red instead of the current gradient. Color-disabled output is unchanged, and no other help surface is affected. -## Tasks: +## Tasks 1. T01 — Render the SCE banner in red -## Assumptions: +## Assumptions - "SCE letters" refers to the ASCII-art banner in top-level help. - Red is uniform terminal red when colors are enabled; plain ASCII remains unchanged otherwise. -## Open questions: +## Open questions - None. ``` diff --git a/.claude/skills/sce-change-to-plan/references/plan-authoring.md b/.claude/skills/sce-change-to-plan/references/plan-authoring.md index 98335bf34..fdd3abe7a 100644 --- a/.claude/skills/sce-change-to-plan/references/plan-authoring.md +++ b/.claude/skills/sce-change-to-plan/references/plan-authoring.md @@ -28,7 +28,7 @@ responsibility. The context brief is the durable memory this plan starts from. Treat its `key_facts` as recorded current state, its `gaps` as areas with no durable -context, and its `drift` as context the code has already outrun. +context, and its `drift` as recorded context that no longer matches the code. When no brief is supplied, load the context named by the change request before authoring, and follow the selection discipline in *Inspect relevant context*. @@ -178,13 +178,13 @@ exactly. For revisions, apply its `Updating an existing plan` rules. ## 2.8 Return the result -Set exactly one internal state: +Return one internal result with one of these statuses: - `plan_ready` - `needs_clarification` - `blocked` -Record only the internal state. Do not add explanatory prose before or after it. +Return only the internal result. Do not add explanatory prose before or after it. A `plan_ready` result always names the next task in `next_task`, and carries the `total_tasks` count and any open questions the summary needs. Step 3 renders those @@ -192,29 +192,13 @@ without recomputing them. ## Plan authoring tone -Every question and open question this phase writes is read by the user. Write -them the way a senior engineer talks in review: direct, specific, and unbothered -by the possibility of being unwelcome. - -- Ask about the thing that actually worries you, not a safer neighbouring thing. - A question you would not bother asking a colleague is not worth the user's - attention either. -- State a doubt as a doubt. "I do not think this is worth the two tasks it - costs, because X" is useful. "It may be worth considering whether this aligns - with broader goals" is noise. -- Name the alternative you have in mind. A challenge with no proposal behind it - is just friction. -- Do not open with praise, do not close with reassurance, and do not apologize - for asking. Do not pad a doubt with hedges to make it land more gently. -- Be persistent, not repetitive. Ask once, plainly, and let it stand; do not - restate the same doubt in three shapes to give it more weight. -- Being disagreeable is not the goal. Being easy to agree with is the failure - mode. A plan the user waves through without reading has cost them nothing and - bought them nothing. - -When the user overrules a doubt, record it and move on. Do not relitigate a -decision the user has made, and do not smuggle the objection back in as a -constraint, a non-goal, or a task. +Write user-facing questions and open questions directly and specifically. + +- Ask only about material concerns that can change scope, success criteria, or task ordering. +- State the concern and the concrete evidence for it. +- Name a smaller or safer alternative when one is known. +- Do not invent concerns, add praise or reassurance, or repeat the same concern in several forms. +- When the user overrules a concern, record the decision and continue. Do not reintroduce it as a constraint, non-goal, or task. ## Plan authoring boundaries diff --git a/.claude/skills/sce-change-to-plan/references/plan-template.md b/.claude/skills/sce-change-to-plan/references/plan-template.md index 416ac8a6b..fe0190b94 100644 --- a/.claude/skills/sce-change-to-plan/references/plan-template.md +++ b/.claude/skills/sce-change-to-plan/references/plan-template.md @@ -146,9 +146,9 @@ invent one: `None.` is the expected answer for a well-specified change.} - The last task in the stack is an ordinary implementation task. Do not author a trailing "validation and cleanup" task. -- Final validation, cleanup, and success-criteria verification are run by - `/validate` from the `Acceptance criteria` section after the last task - completes. +- Final validation and success-criteria verification are run by `/validate` + from the `Acceptance criteria` section after the last task completes. Validation + reports cleanup or repair work that is still required; it does not perform that work. - Do not author a task whose only purpose is running the full check suite, verifying durable context, or removing scaffolding. - A task may still create or update durable context when that context is part of diff --git a/.claude/skills/sce-commit/SKILL.md b/.claude/skills/sce-commit/SKILL.md index fff451dd5..5fe9ef0f5 100644 --- a/.claude/skills/sce-commit/SKILL.md +++ b/.claude/skills/sce-commit/SKILL.md @@ -11,10 +11,10 @@ compatibility: claude Own this workflow from input through its terminal user-visible response. Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. -Keep phase results internal and continue immediately until a defined wait or stop. +Keep internal phase results private and continue immediately until a defined wait or stop. Resume user waits in this same skill and session. -Use only the specified `references/output.md` layouts for gates and terminal -responses. Do not expose raw state or add text around a layout. +Render user-visible output only from the named workflow layouts or phase reports. +Do not expose raw internal state or add text around a rendered layout or report. Non-SCE helpers may assist, but must return to the active step without changing phase order, gates, waits, writes, validation, stops, or terminal output. Do not invoke another SCE skill, package, or workflow command. @@ -98,14 +98,14 @@ Run `git diff --cached --quiet`. A zero exit status means nothing is staged. When nothing is staged, stop with the **No staged changes** layout from `references/output.md`. -Do not stage anything. Do not proceed to the skill. +Do not stage anything. Do not proceed to the phase. #### 2. Request one commit message Read `references/atomic-commit.md`, then run the **Atomic commit phase** with `mode: bypass` and the commit context. -Bypass mode is the skill's contract for producing exactly one message. Do not +Bypass mode is the phase's contract for producing exactly one message. Do not restate its overrides here; the **Atomic commit phase** owns them. Branch on `status`: @@ -114,7 +114,7 @@ Branch on `status`: `bypass_message` -> Continue to the next step. -The skill never returns `proposal` in bypass mode. Treat a `proposal` result as +The phase never returns `proposal` in bypass mode. Treat a `proposal` result as a contract violation: report it and stop without committing. #### 3. Execute exactly one commit diff --git a/.claude/skills/sce-commit/references/atomic-commit.md b/.claude/skills/sce-commit/references/atomic-commit.md index 5df2c0a8b..ba529bf29 100644 --- a/.claude/skills/sce-commit/references/atomic-commit.md +++ b/.claude/skills/sce-commit/references/atomic-commit.md @@ -1,4 +1,4 @@ -# SCE Atomic Commit +# Atomic commit phase ## Purpose @@ -8,8 +8,8 @@ Write messages matching: `references/commit-message-style.md` -Committing is not this skill's job. The invoking `/commit` workflow decides -whether a returned message is committed, and it is the only thing that runs +This phase does not commit. The invoking `/commit` workflow decides +whether a returned message is committed, and it is the only part that runs `git commit`. ## Input @@ -147,7 +147,7 @@ Do not: ## Completion -The skill is complete after: +The phase is complete after: - The staged diff was read, or reading it failed and was reported. - Messages were written for every staged file, or a blocker prevented it. diff --git a/.claude/skills/sce-handover/SKILL.md b/.claude/skills/sce-handover/SKILL.md index b1fd0f82c..1e04509d8 100644 --- a/.claude/skills/sce-handover/SKILL.md +++ b/.claude/skills/sce-handover/SKILL.md @@ -11,10 +11,10 @@ compatibility: claude Own this workflow from input through its terminal user-visible response. Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. -Keep phase results internal and continue immediately until a defined wait or stop. +Keep internal phase results private and continue immediately until a defined wait or stop. Resume user waits in this same skill and session. -Use only the specified `references/output.md` layouts for gates and terminal -responses. Do not expose raw state or add text around a layout. +Render user-visible output only from the named workflow layouts or phase reports. +Do not expose raw internal state or add text around a rendered layout or report. Non-SCE helpers may assist, but must return to the active step without changing phase order, gates, waits, writes, validation, stops, or terminal output. Do not invoke another SCE skill, package, or workflow command. diff --git a/.claude/skills/sce-handover/references/handover-template.md b/.claude/skills/sce-handover/references/handover-template.md index d934da801..8977f935b 100644 --- a/.claude/skills/sce-handover/references/handover-template.md +++ b/.claude/skills/sce-handover/references/handover-template.md @@ -1,8 +1,10 @@ +# Handover document format + The Markdown document writer mode creates under `context/handovers/{name}.md`. This is the persisted file's content, distinct from the terminal response defined in `references/output.md`. -### Layout +## Template ```markdown # Handover: {plan name or short session topic} @@ -35,9 +37,9 @@ enough to act on directly.} `None.`} ``` -### Completeness contract +## Completeness contract -- The first four `##` sections shown in **Layout** are required and must appear +- The first four `##` sections shown in **Template** are required and must appear in that order. - Each required section's content, up to the next `##` heading or the end of the file, must contain non-whitespace content. An empty list marker, unreplaced @@ -47,10 +49,10 @@ enough to act on directly.} - Writer mode must satisfy this contract before reporting success; loader mode validates the same contract before presenting a handover. -### Rules +## Rules -- Include `Plan` and `Task` only when the session was working one identifiable - plan task; omit them rather than guessing. +- Include `Plan` when one plan is known. Include `Task` only when one task is + known. Omit either field rather than guessing its value. - Keep `Assumptions` scoped to details actually labeled as inferred elsewhere in the document; do not duplicate confirmed facts here. - Describe durable state useful to a future session, not a transcript of this diff --git a/.claude/skills/sce-handover/references/output.md b/.claude/skills/sce-handover/references/output.md index afe30b5fd..e5f719e80 100644 --- a/.claude/skills/sce-handover/references/output.md +++ b/.claude/skills/sce-handover/references/output.md @@ -83,7 +83,7 @@ This handover has been presented for continuation only. No file was edited, no plan task was marked complete, and the recommended next step was not started. ``` -# Report rules +## Report rules - Writer success must report the exact written path so `/handover {written path}` is directly runnable. diff --git a/.claude/skills/sce-next-task/SKILL.md b/.claude/skills/sce-next-task/SKILL.md index c61e8208b..ad4da900f 100644 --- a/.claude/skills/sce-next-task/SKILL.md +++ b/.claude/skills/sce-next-task/SKILL.md @@ -11,10 +11,10 @@ compatibility: claude Own this workflow from input through its terminal user-visible response. Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. -Keep phase results internal and continue immediately until a defined wait or stop. +Keep internal phase results private and continue immediately until a defined wait or stop. Resume user waits in this same skill and session. -Use only the specified `references/output.md` layouts for gates and terminal -responses. Do not expose raw state or add text around a layout. +Render user-visible output only from the named workflow layouts or phase reports. +Do not expose raw internal state or add text around a rendered layout or report. Non-SCE helpers may assist, but must return to the active step without changing phase order, gates, waits, writes, validation, stops, or terminal output. Do not invoke another SCE skill, package, or workflow command except `sce-decision`, @@ -80,7 +80,7 @@ Branch on the outcome: `synced` | `no_context_change` -> Re-invoke the **Plan review phase** with the same `plan-name-or-path` and, when present, `task-id` to resume normal task selection. -`plan_complete` -> Render the **Plan already complete** layout from `references/output.md`. Stop. +`plan_complete` -> Render the **Implementation complete** layout from `references/output.md`. Stop. `ready` -> Pass the complete readiness result to the **Task execution phase**. @@ -119,10 +119,9 @@ Branch on the execution result. ### 3. Synchronize context Read `references/context-sync.md`, then run the **Task context synchronization -phase** with the complete `complete` result returned by the **Task execution -phase**. +phase** with the task execution result whose `status` is `complete`. -Pass that `complete` result verbatim as the authoritative live handoff to the +Pass that result unchanged as the authoritative live handoff to the **Task context synchronization phase**. Do not restate, summarize, or reconstruct it. This phase verifies the five root context files on every invocation, whatever the @@ -139,7 +138,7 @@ Branch on the synchronization result. Do not select another task. Stop. -`synced` | `no_context_change` -> Print out the report the **Task context synchronization phase** returned. Continue to the next step. +`synced` | `no_context_change` -> Render the Markdown report returned by the **Task context synchronization phase** unchanged. Continue to the next step. ### 4. Determine the continuation diff --git a/.claude/skills/sce-next-task/references/context-sync.md b/.claude/skills/sce-next-task/references/context-sync.md index 057043313..6e6074dcf 100644 --- a/.claude/skills/sce-next-task/references/context-sync.md +++ b/.claude/skills/sce-next-task/references/context-sync.md @@ -7,7 +7,7 @@ plan state. Input: either the complete `complete` result from the task execution phase (same-session), passed verbatim, or the plan path and task ID a plan-review -recovery step resolved for a `blocked` task, together with that task's own +recovery step resolved for a completed task with unresolved context synchronization, together with that task's own completed record — read directly from the plan — and its persisted `Context synchronization blocker` when present (cross-session retry). Whichever was supplied is authoritative; this phase consumes it without redefining its shape. diff --git a/.claude/skills/sce-next-task/references/output.md b/.claude/skills/sce-next-task/references/output.md index 3c4f5e2ab..40a66539f 100644 --- a/.claude/skills/sce-next-task/references/output.md +++ b/.claude/skills/sce-next-task/references/output.md @@ -8,7 +8,7 @@ Present the selected task, then each issue's problem, impact, and required decision. If plan resolution is ambiguous, list candidate paths and `/next-task {candidate-path}`. State whether another task remains executable. -## Plan already complete +## Implementation complete ```markdown ------------------------------------- diff --git a/.claude/skills/sce-validate/SKILL.md b/.claude/skills/sce-validate/SKILL.md index e7e9d59c2..9f874f37c 100644 --- a/.claude/skills/sce-validate/SKILL.md +++ b/.claude/skills/sce-validate/SKILL.md @@ -11,10 +11,10 @@ compatibility: claude Own this workflow from input through its terminal user-visible response. Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. -Keep phase results internal and continue immediately until a defined wait or stop. +Keep internal phase results private and continue immediately until a defined wait or stop. Resume user waits in this same skill and session. -Use only the specified `references/output.md` layouts for gates and terminal -responses. Do not expose raw state or add text around a layout. +Render user-visible output only from the named workflow layouts or phase reports. +Do not expose raw internal state or add text around a rendered layout or report. Non-SCE helpers may assist, but must return to the active step without changing phase order, gates, waits, writes, validation, stops, or terminal output. Do not invoke another SCE skill, package, or workflow command. @@ -51,7 +51,7 @@ Pass the plan name or path to the **Validation phase** unmodified. Do not restat summarize, or pre-scope it. Every `{plan-path}` and `{candidate-path}` emitted anywhere in this workflow is -the path carried by the **Validation phase** in its Markdown result (`Plan:`, or a +the path carried by the **Validation phase** in its Markdown report (`Plan:`, or a candidate path), so every emitted command is directly runnable. ## Workflow diff --git a/.claude/skills/sce-validate/references/validation.md b/.claude/skills/sce-validate/references/validation.md index 4b343f277..50895cc83 100644 --- a/.claude/skills/sce-validate/references/validation.md +++ b/.claude/skills/sce-validate/references/validation.md @@ -1,4 +1,4 @@ -# SCE Validation +# Validation phase ## Purpose @@ -79,8 +79,7 @@ validation. When a check fails, record the failure and continue gathering evidence. Do not modify tests, application code, or configuration to make a check pass. Final -validation measures the finished work; repair belongs to a later work session, -not this skill. +validation measures the finished work; repair belongs to a normal work session outside this phase. Never report a check as passed unless it ran successfully or the authorized inspection confirmed the criterion. @@ -102,9 +101,9 @@ Do not reopen completed tasks, rewrite task evidence, or change the task stack. For `blocked`, leave the plan file unchanged. -### 6. Return the Markdown result +### 6. Return the Markdown report -Return exactly one Markdown result: +Return exactly one Markdown report: - `validated` when every acceptance criterion is met, required full validation passed, and the Validation Report was written. @@ -141,12 +140,12 @@ The phase is complete after: - One plan was resolved, or resolution failed and was reported. - Implementation completeness was checked. - Validation ran to a terminal state, or a blocker prevented it. -- One valid Markdown result matching the **Validation Result** section below in this file was +- One valid Markdown report matching the **Validation Result** section below in this file was returned. -# Validation Result +# Validation report Return only one completed Markdown report using the applicable variant below. Do not include unused sections, placeholders, YAML, or a fenced code block. @@ -158,10 +157,10 @@ The `Status` value must be exactly one of: - `blocked` The plan-file `## Validation Report` section is written separately using -`references/validation-report.md`. This file is the skill's return value to the +`references/validation-report.md`. This file is the phase's return value to the invoking workflow. -## Validated variant +## Validated report # Validation Report @@ -192,7 +191,7 @@ Omit this section when unnecessary.} --- -## Failed variant +## Failed report This variant is a session handoff. Another agent or a later session must be able to act from it alone. Write it as a prompt the user can paste forward, not @@ -256,7 +255,7 @@ returns `validated`. --- -## Blocked variant +## Blocked report # Validation blocked diff --git a/.pi/skills/sce-change-to-plan/SKILL.md b/.pi/skills/sce-change-to-plan/SKILL.md index 37d2fcf0b..4ce057d98 100644 --- a/.pi/skills/sce-change-to-plan/SKILL.md +++ b/.pi/skills/sce-change-to-plan/SKILL.md @@ -10,10 +10,10 @@ description: > Own this workflow from input through its terminal user-visible response. Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. -Keep phase results internal and continue immediately until a defined wait or stop. +Keep internal phase results private and continue immediately until a defined wait or stop. Resume user waits in this same skill and session. -Use only the specified `references/output.md` layouts for gates and terminal -responses. Do not expose raw state or add text around a layout. +Render user-visible output only from the named workflow layouts or phase reports. +Do not expose raw internal state or add text around a rendered layout or report. Non-SCE helpers may assist, but must return to the active step without changing phase order, gates, waits, writes, validation, stops, or terminal output. Do not invoke another SCE skill, package, or workflow command. diff --git a/.pi/skills/sce-change-to-plan/references/context-load.md b/.pi/skills/sce-change-to-plan/references/context-load.md index 197a28c2d..60cc26efb 100644 --- a/.pi/skills/sce-change-to-plan/references/context-load.md +++ b/.pi/skills/sce-change-to-plan/references/context-load.md @@ -61,7 +61,7 @@ sentence. ## 1.5 Return the brief -Set exactly one internal state: +Return one internal result with one of these statuses: - `loaded` - `bootstrap_required` @@ -69,7 +69,7 @@ Set exactly one internal state: Report facts the workflow can act on. A brief that only lists file paths has moved no knowledge. -Record only the internal state. Do not add explanatory prose before or after it. +Return only the internal result. Do not add explanatory prose before or after it. Step 2 consumes a `loaded` brief verbatim and treats its `key_facts` as recorded current state, its `gaps` as areas with no durable context, and its `drift` as diff --git a/.pi/skills/sce-change-to-plan/references/output.md b/.pi/skills/sce-change-to-plan/references/output.md index 170f39491..bc7e1a3fc 100644 --- a/.pi/skills/sce-change-to-plan/references/output.md +++ b/.pi/skills/sce-change-to-plan/references/output.md @@ -48,7 +48,7 @@ candidate plan paths and explain that naming one candidate resolves it. This plan is a draft. State a correction and it will be updated. -Next up: +Next step: {next-task-id} — {next-task-title} @@ -71,17 +71,17 @@ This is chat output, not a file. Nothing here is written to the plan. Path: {plan.path} -## Summary: +## Summary {plan summary} -## Tasks: +## Tasks 1. {task.id} — {task.title} 2. {task.id} — {task.title} -## Assumptions: +## Assumptions - {assumption} -## Open questions: +## Open questions - {open question} ``` @@ -93,13 +93,13 @@ not carry. - `Plan:` — `plan.name`. Append ` (updated)` when `plan.action` is `updated`. Render nothing extra when it is `created`. - `Path:` — `plan.path`, exactly as returned, so it stays runnable. -- `Summary:` — `summary`, as prose. This is the only place the reader learns +- `Summary` — `summary`, as prose. This is the only place the reader learns what the plan actually does, so never omit it and never replace it with a restatement of the task titles. -- `Tasks:` — one numbered line per entry in `tasks`, in plan order. Append +- `Tasks` — one numbered line per entry in `tasks`, in plan order. Append ` (done)` to any task whose `status` is `done`. -- `Assumptions:` — one line per entry in `assumptions`. -- `Open questions:` — one line per entry in `open_questions`. +- `Assumptions` — one line per entry in `assumptions`. +- `Open questions` — one line per entry in `open_questions`. ## Empty sections @@ -109,14 +109,14 @@ explicit `None.` confirms nothing is pending. When `assumptions` is empty: ``` -## Assumptions: +## Assumptions - None. ``` When `open_questions` is absent: ``` -## Open questions: +## Open questions - None. ``` @@ -137,16 +137,16 @@ When `open_questions` is absent: Path: context/plans/red-sce-banner.md -## Summary: -Renders the ASCII-art SCE banner at the top of `sce` help in red instead of the current gradient. Colour-disabled output is unchanged, and no other help surface is affected. +## Summary +Renders the ASCII-art SCE banner at the top of `sce` help in red instead of the current gradient. Color-disabled output is unchanged, and no other help surface is affected. -## Tasks: +## Tasks 1. T01 — Render the SCE banner in red -## Assumptions: +## Assumptions - "SCE letters" refers to the ASCII-art banner in top-level help. - Red is uniform terminal red when colors are enabled; plain ASCII remains unchanged otherwise. -## Open questions: +## Open questions - None. ``` diff --git a/.pi/skills/sce-change-to-plan/references/plan-authoring.md b/.pi/skills/sce-change-to-plan/references/plan-authoring.md index 98335bf34..fdd3abe7a 100644 --- a/.pi/skills/sce-change-to-plan/references/plan-authoring.md +++ b/.pi/skills/sce-change-to-plan/references/plan-authoring.md @@ -28,7 +28,7 @@ responsibility. The context brief is the durable memory this plan starts from. Treat its `key_facts` as recorded current state, its `gaps` as areas with no durable -context, and its `drift` as context the code has already outrun. +context, and its `drift` as recorded context that no longer matches the code. When no brief is supplied, load the context named by the change request before authoring, and follow the selection discipline in *Inspect relevant context*. @@ -178,13 +178,13 @@ exactly. For revisions, apply its `Updating an existing plan` rules. ## 2.8 Return the result -Set exactly one internal state: +Return one internal result with one of these statuses: - `plan_ready` - `needs_clarification` - `blocked` -Record only the internal state. Do not add explanatory prose before or after it. +Return only the internal result. Do not add explanatory prose before or after it. A `plan_ready` result always names the next task in `next_task`, and carries the `total_tasks` count and any open questions the summary needs. Step 3 renders those @@ -192,29 +192,13 @@ without recomputing them. ## Plan authoring tone -Every question and open question this phase writes is read by the user. Write -them the way a senior engineer talks in review: direct, specific, and unbothered -by the possibility of being unwelcome. - -- Ask about the thing that actually worries you, not a safer neighbouring thing. - A question you would not bother asking a colleague is not worth the user's - attention either. -- State a doubt as a doubt. "I do not think this is worth the two tasks it - costs, because X" is useful. "It may be worth considering whether this aligns - with broader goals" is noise. -- Name the alternative you have in mind. A challenge with no proposal behind it - is just friction. -- Do not open with praise, do not close with reassurance, and do not apologize - for asking. Do not pad a doubt with hedges to make it land more gently. -- Be persistent, not repetitive. Ask once, plainly, and let it stand; do not - restate the same doubt in three shapes to give it more weight. -- Being disagreeable is not the goal. Being easy to agree with is the failure - mode. A plan the user waves through without reading has cost them nothing and - bought them nothing. - -When the user overrules a doubt, record it and move on. Do not relitigate a -decision the user has made, and do not smuggle the objection back in as a -constraint, a non-goal, or a task. +Write user-facing questions and open questions directly and specifically. + +- Ask only about material concerns that can change scope, success criteria, or task ordering. +- State the concern and the concrete evidence for it. +- Name a smaller or safer alternative when one is known. +- Do not invent concerns, add praise or reassurance, or repeat the same concern in several forms. +- When the user overrules a concern, record the decision and continue. Do not reintroduce it as a constraint, non-goal, or task. ## Plan authoring boundaries diff --git a/.pi/skills/sce-change-to-plan/references/plan-template.md b/.pi/skills/sce-change-to-plan/references/plan-template.md index 416ac8a6b..fe0190b94 100644 --- a/.pi/skills/sce-change-to-plan/references/plan-template.md +++ b/.pi/skills/sce-change-to-plan/references/plan-template.md @@ -146,9 +146,9 @@ invent one: `None.` is the expected answer for a well-specified change.} - The last task in the stack is an ordinary implementation task. Do not author a trailing "validation and cleanup" task. -- Final validation, cleanup, and success-criteria verification are run by - `/validate` from the `Acceptance criteria` section after the last task - completes. +- Final validation and success-criteria verification are run by `/validate` + from the `Acceptance criteria` section after the last task completes. Validation + reports cleanup or repair work that is still required; it does not perform that work. - Do not author a task whose only purpose is running the full check suite, verifying durable context, or removing scaffolding. - A task may still create or update durable context when that context is part of diff --git a/.pi/skills/sce-commit/SKILL.md b/.pi/skills/sce-commit/SKILL.md index 3087c1eb7..0123adeae 100644 --- a/.pi/skills/sce-commit/SKILL.md +++ b/.pi/skills/sce-commit/SKILL.md @@ -10,10 +10,10 @@ description: > Own this workflow from input through its terminal user-visible response. Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. -Keep phase results internal and continue immediately until a defined wait or stop. +Keep internal phase results private and continue immediately until a defined wait or stop. Resume user waits in this same skill and session. -Use only the specified `references/output.md` layouts for gates and terminal -responses. Do not expose raw state or add text around a layout. +Render user-visible output only from the named workflow layouts or phase reports. +Do not expose raw internal state or add text around a rendered layout or report. Non-SCE helpers may assist, but must return to the active step without changing phase order, gates, waits, writes, validation, stops, or terminal output. Do not invoke another SCE skill, package, or workflow command. @@ -97,14 +97,14 @@ Run `git diff --cached --quiet`. A zero exit status means nothing is staged. When nothing is staged, stop with the **No staged changes** layout from `references/output.md`. -Do not stage anything. Do not proceed to the skill. +Do not stage anything. Do not proceed to the phase. #### 2. Request one commit message Read `references/atomic-commit.md`, then run the **Atomic commit phase** with `mode: bypass` and the commit context. -Bypass mode is the skill's contract for producing exactly one message. Do not +Bypass mode is the phase's contract for producing exactly one message. Do not restate its overrides here; the **Atomic commit phase** owns them. Branch on `status`: @@ -113,7 +113,7 @@ Branch on `status`: `bypass_message` -> Continue to the next step. -The skill never returns `proposal` in bypass mode. Treat a `proposal` result as +The phase never returns `proposal` in bypass mode. Treat a `proposal` result as a contract violation: report it and stop without committing. #### 3. Execute exactly one commit diff --git a/.pi/skills/sce-commit/references/atomic-commit.md b/.pi/skills/sce-commit/references/atomic-commit.md index 5df2c0a8b..ba529bf29 100644 --- a/.pi/skills/sce-commit/references/atomic-commit.md +++ b/.pi/skills/sce-commit/references/atomic-commit.md @@ -1,4 +1,4 @@ -# SCE Atomic Commit +# Atomic commit phase ## Purpose @@ -8,8 +8,8 @@ Write messages matching: `references/commit-message-style.md` -Committing is not this skill's job. The invoking `/commit` workflow decides -whether a returned message is committed, and it is the only thing that runs +This phase does not commit. The invoking `/commit` workflow decides +whether a returned message is committed, and it is the only part that runs `git commit`. ## Input @@ -147,7 +147,7 @@ Do not: ## Completion -The skill is complete after: +The phase is complete after: - The staged diff was read, or reading it failed and was reported. - Messages were written for every staged file, or a blocker prevented it. diff --git a/.pi/skills/sce-handover/SKILL.md b/.pi/skills/sce-handover/SKILL.md index d91f6b957..f986feda3 100644 --- a/.pi/skills/sce-handover/SKILL.md +++ b/.pi/skills/sce-handover/SKILL.md @@ -10,10 +10,10 @@ description: > Own this workflow from input through its terminal user-visible response. Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. -Keep phase results internal and continue immediately until a defined wait or stop. +Keep internal phase results private and continue immediately until a defined wait or stop. Resume user waits in this same skill and session. -Use only the specified `references/output.md` layouts for gates and terminal -responses. Do not expose raw state or add text around a layout. +Render user-visible output only from the named workflow layouts or phase reports. +Do not expose raw internal state or add text around a rendered layout or report. Non-SCE helpers may assist, but must return to the active step without changing phase order, gates, waits, writes, validation, stops, or terminal output. Do not invoke another SCE skill, package, or workflow command. diff --git a/.pi/skills/sce-handover/references/handover-template.md b/.pi/skills/sce-handover/references/handover-template.md index d934da801..8977f935b 100644 --- a/.pi/skills/sce-handover/references/handover-template.md +++ b/.pi/skills/sce-handover/references/handover-template.md @@ -1,8 +1,10 @@ +# Handover document format + The Markdown document writer mode creates under `context/handovers/{name}.md`. This is the persisted file's content, distinct from the terminal response defined in `references/output.md`. -### Layout +## Template ```markdown # Handover: {plan name or short session topic} @@ -35,9 +37,9 @@ enough to act on directly.} `None.`} ``` -### Completeness contract +## Completeness contract -- The first four `##` sections shown in **Layout** are required and must appear +- The first four `##` sections shown in **Template** are required and must appear in that order. - Each required section's content, up to the next `##` heading or the end of the file, must contain non-whitespace content. An empty list marker, unreplaced @@ -47,10 +49,10 @@ enough to act on directly.} - Writer mode must satisfy this contract before reporting success; loader mode validates the same contract before presenting a handover. -### Rules +## Rules -- Include `Plan` and `Task` only when the session was working one identifiable - plan task; omit them rather than guessing. +- Include `Plan` when one plan is known. Include `Task` only when one task is + known. Omit either field rather than guessing its value. - Keep `Assumptions` scoped to details actually labeled as inferred elsewhere in the document; do not duplicate confirmed facts here. - Describe durable state useful to a future session, not a transcript of this diff --git a/.pi/skills/sce-handover/references/output.md b/.pi/skills/sce-handover/references/output.md index afe30b5fd..e5f719e80 100644 --- a/.pi/skills/sce-handover/references/output.md +++ b/.pi/skills/sce-handover/references/output.md @@ -83,7 +83,7 @@ This handover has been presented for continuation only. No file was edited, no plan task was marked complete, and the recommended next step was not started. ``` -# Report rules +## Report rules - Writer success must report the exact written path so `/handover {written path}` is directly runnable. diff --git a/.pi/skills/sce-next-task/SKILL.md b/.pi/skills/sce-next-task/SKILL.md index 691237b47..8d51c3aeb 100644 --- a/.pi/skills/sce-next-task/SKILL.md +++ b/.pi/skills/sce-next-task/SKILL.md @@ -10,10 +10,10 @@ description: > Own this workflow from input through its terminal user-visible response. Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. -Keep phase results internal and continue immediately until a defined wait or stop. +Keep internal phase results private and continue immediately until a defined wait or stop. Resume user waits in this same skill and session. -Use only the specified `references/output.md` layouts for gates and terminal -responses. Do not expose raw state or add text around a layout. +Render user-visible output only from the named workflow layouts or phase reports. +Do not expose raw internal state or add text around a rendered layout or report. Non-SCE helpers may assist, but must return to the active step without changing phase order, gates, waits, writes, validation, stops, or terminal output. Do not invoke another SCE skill, package, or workflow command except `sce-decision`, @@ -79,7 +79,7 @@ Branch on the outcome: `synced` | `no_context_change` -> Re-invoke the **Plan review phase** with the same `plan-name-or-path` and, when present, `task-id` to resume normal task selection. -`plan_complete` -> Render the **Plan already complete** layout from `references/output.md`. Stop. +`plan_complete` -> Render the **Implementation complete** layout from `references/output.md`. Stop. `ready` -> Pass the complete readiness result to the **Task execution phase**. @@ -118,10 +118,9 @@ Branch on the execution result. ### 3. Synchronize context Read `references/context-sync.md`, then run the **Task context synchronization -phase** with the complete `complete` result returned by the **Task execution -phase**. +phase** with the task execution result whose `status` is `complete`. -Pass that `complete` result verbatim as the authoritative live handoff to the +Pass that result unchanged as the authoritative live handoff to the **Task context synchronization phase**. Do not restate, summarize, or reconstruct it. This phase verifies the five root context files on every invocation, whatever the @@ -138,7 +137,7 @@ Branch on the synchronization result. Do not select another task. Stop. -`synced` | `no_context_change` -> Print out the report the **Task context synchronization phase** returned. Continue to the next step. +`synced` | `no_context_change` -> Render the Markdown report returned by the **Task context synchronization phase** unchanged. Continue to the next step. ### 4. Determine the continuation diff --git a/.pi/skills/sce-next-task/references/context-sync.md b/.pi/skills/sce-next-task/references/context-sync.md index 057043313..6e6074dcf 100644 --- a/.pi/skills/sce-next-task/references/context-sync.md +++ b/.pi/skills/sce-next-task/references/context-sync.md @@ -7,7 +7,7 @@ plan state. Input: either the complete `complete` result from the task execution phase (same-session), passed verbatim, or the plan path and task ID a plan-review -recovery step resolved for a `blocked` task, together with that task's own +recovery step resolved for a completed task with unresolved context synchronization, together with that task's own completed record — read directly from the plan — and its persisted `Context synchronization blocker` when present (cross-session retry). Whichever was supplied is authoritative; this phase consumes it without redefining its shape. diff --git a/.pi/skills/sce-next-task/references/output.md b/.pi/skills/sce-next-task/references/output.md index 3c4f5e2ab..40a66539f 100644 --- a/.pi/skills/sce-next-task/references/output.md +++ b/.pi/skills/sce-next-task/references/output.md @@ -8,7 +8,7 @@ Present the selected task, then each issue's problem, impact, and required decision. If plan resolution is ambiguous, list candidate paths and `/next-task {candidate-path}`. State whether another task remains executable. -## Plan already complete +## Implementation complete ```markdown ------------------------------------- diff --git a/.pi/skills/sce-validate/SKILL.md b/.pi/skills/sce-validate/SKILL.md index 389f4428d..4dc14c48c 100644 --- a/.pi/skills/sce-validate/SKILL.md +++ b/.pi/skills/sce-validate/SKILL.md @@ -10,10 +10,10 @@ description: > Own this workflow from input through its terminal user-visible response. Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. -Keep phase results internal and continue immediately until a defined wait or stop. +Keep internal phase results private and continue immediately until a defined wait or stop. Resume user waits in this same skill and session. -Use only the specified `references/output.md` layouts for gates and terminal -responses. Do not expose raw state or add text around a layout. +Render user-visible output only from the named workflow layouts or phase reports. +Do not expose raw internal state or add text around a rendered layout or report. Non-SCE helpers may assist, but must return to the active step without changing phase order, gates, waits, writes, validation, stops, or terminal output. Do not invoke another SCE skill, package, or workflow command. @@ -50,7 +50,7 @@ Pass the plan name or path to the **Validation phase** unmodified. Do not restat summarize, or pre-scope it. Every `{plan-path}` and `{candidate-path}` emitted anywhere in this workflow is -the path carried by the **Validation phase** in its Markdown result (`Plan:`, or a +the path carried by the **Validation phase** in its Markdown report (`Plan:`, or a candidate path), so every emitted command is directly runnable. ## Workflow diff --git a/.pi/skills/sce-validate/references/validation.md b/.pi/skills/sce-validate/references/validation.md index 4b343f277..50895cc83 100644 --- a/.pi/skills/sce-validate/references/validation.md +++ b/.pi/skills/sce-validate/references/validation.md @@ -1,4 +1,4 @@ -# SCE Validation +# Validation phase ## Purpose @@ -79,8 +79,7 @@ validation. When a check fails, record the failure and continue gathering evidence. Do not modify tests, application code, or configuration to make a check pass. Final -validation measures the finished work; repair belongs to a later work session, -not this skill. +validation measures the finished work; repair belongs to a normal work session outside this phase. Never report a check as passed unless it ran successfully or the authorized inspection confirmed the criterion. @@ -102,9 +101,9 @@ Do not reopen completed tasks, rewrite task evidence, or change the task stack. For `blocked`, leave the plan file unchanged. -### 6. Return the Markdown result +### 6. Return the Markdown report -Return exactly one Markdown result: +Return exactly one Markdown report: - `validated` when every acceptance criterion is met, required full validation passed, and the Validation Report was written. @@ -141,12 +140,12 @@ The phase is complete after: - One plan was resolved, or resolution failed and was reported. - Implementation completeness was checked. - Validation ran to a terminal state, or a blocker prevented it. -- One valid Markdown result matching the **Validation Result** section below in this file was +- One valid Markdown report matching the **Validation Result** section below in this file was returned. -# Validation Result +# Validation report Return only one completed Markdown report using the applicable variant below. Do not include unused sections, placeholders, YAML, or a fenced code block. @@ -158,10 +157,10 @@ The `Status` value must be exactly one of: - `blocked` The plan-file `## Validation Report` section is written separately using -`references/validation-report.md`. This file is the skill's return value to the +`references/validation-report.md`. This file is the phase's return value to the invoking workflow. -## Validated variant +## Validated report # Validation Report @@ -192,7 +191,7 @@ Omit this section when unnecessary.} --- -## Failed variant +## Failed report This variant is a session handoff. Another agent or a later session must be able to act from it alone. Write it as a prompt the user can paste forward, not @@ -256,7 +255,7 @@ returns `validated`. --- -## Blocked variant +## Blocked report # Validation blocked diff --git a/config/pkl/base/workflow-change-to-plan.pkl b/config/pkl/base/workflow-change-to-plan.pkl index c55eaa0e4..5cae6b095 100644 --- a/config/pkl/base/workflow-change-to-plan.pkl +++ b/config/pkl/base/workflow-change-to-plan.pkl @@ -210,7 +210,7 @@ sentence. ## 1.5 Return the brief -Set exactly one internal state: +Return one internal result with one of these statuses: - `loaded` - `bootstrap_required` @@ -218,7 +218,7 @@ Set exactly one internal state: Report facts the workflow can act on. A brief that only lists file paths has moved no knowledge. -Record only the internal state. Do not add explanatory prose before or after it. +Return only the internal result. Do not add explanatory prose before or after it. Step 2 consumes a `loaded` brief verbatim and treats its `key_facts` as recorded current state, its `gaps` as areas with no durable context, and its `drift` as @@ -271,7 +271,7 @@ responsibility. The context brief is the durable memory this plan starts from. Treat its `key_facts` as recorded current state, its `gaps` as areas with no durable -context, and its `drift` as context the code has already outrun. +context, and its `drift` as recorded context that no longer matches the code. When no brief is supplied, load the context named by the change request before authoring, and follow the selection discipline in *Inspect relevant context*. @@ -421,13 +421,13 @@ exactly. For revisions, apply its `Updating an existing plan` rules. ## 2.8 Return the result -Set exactly one internal state: +Return one internal result with one of these statuses: - `plan_ready` - `needs_clarification` - `blocked` -Record only the internal state. Do not add explanatory prose before or after it. +Return only the internal result. Do not add explanatory prose before or after it. A `plan_ready` result always names the next task in `next_task`, and carries the `total_tasks` count and any open questions the summary needs. Step 3 renders those @@ -435,29 +435,13 @@ without recomputing them. ## Plan authoring tone -Every question and open question this phase writes is read by the user. Write -them the way a senior engineer talks in review: direct, specific, and unbothered -by the possibility of being unwelcome. - -- Ask about the thing that actually worries you, not a safer neighbouring thing. - A question you would not bother asking a colleague is not worth the user's - attention either. -- State a doubt as a doubt. "I do not think this is worth the two tasks it - costs, because X" is useful. "It may be worth considering whether this aligns - with broader goals" is noise. -- Name the alternative you have in mind. A challenge with no proposal behind it - is just friction. -- Do not open with praise, do not close with reassurance, and do not apologize - for asking. Do not pad a doubt with hedges to make it land more gently. -- Be persistent, not repetitive. Ask once, plainly, and let it stand; do not - restate the same doubt in three shapes to give it more weight. -- Being disagreeable is not the goal. Being easy to agree with is the failure - mode. A plan the user waves through without reading has cost them nothing and - bought them nothing. - -When the user overrules a doubt, record it and move on. Do not relitigate a -decision the user has made, and do not smuggle the objection back in as a -constraint, a non-goal, or a task. +Write user-facing questions and open questions directly and specifically. + +- Ask only about material concerns that can change scope, success criteria, or task ordering. +- State the concern and the concrete evidence for it. +- Name a smaller or safer alternative when one is known. +- Do not invent concerns, add praise or reassurance, or repeat the same concern in several forms. +- When the user overrules a concern, record the decision and continue. Do not reintroduce it as a constraint, non-goal, or task. ## Plan authoring boundaries @@ -633,9 +617,9 @@ invent one: `None.` is the expected answer for a well-specified change.} - The last task in the stack is an ordinary implementation task. Do not author a trailing "validation and cleanup" task. -- Final validation, cleanup, and success-criteria verification are run by - `/validate` from the `Acceptance criteria` section after the last task - completes. +- Final validation and success-criteria verification are run by `/validate` + from the `Acceptance criteria` section after the last task completes. Validation + reports cleanup or repair work that is still required; it does not perform that work. - Do not author a task whose only purpose is running the full check suite, verifying durable context, or removing scaffolding. - A task may still create or update durable context when that context is part of @@ -725,7 +709,7 @@ candidate plan paths and explain that naming one candidate resolves it. This plan is a draft. State a correction and it will be updated. -Next up: +Next step: {next-task-id} — {next-task-title} @@ -748,17 +732,17 @@ This is chat output, not a file. Nothing here is written to the plan. Path: {plan.path} -## Summary: +## Summary {plan summary} -## Tasks: +## Tasks 1. {task.id} — {task.title} 2. {task.id} — {task.title} -## Assumptions: +## Assumptions - {assumption} -## Open questions: +## Open questions - {open question} ``` @@ -770,13 +754,13 @@ not carry. - `Plan:` — `plan.name`. Append ` (updated)` when `plan.action` is `updated`. Render nothing extra when it is `created`. - `Path:` — `plan.path`, exactly as returned, so it stays runnable. -- `Summary:` — `summary`, as prose. This is the only place the reader learns +- `Summary` — `summary`, as prose. This is the only place the reader learns what the plan actually does, so never omit it and never replace it with a restatement of the task titles. -- `Tasks:` — one numbered line per entry in `tasks`, in plan order. Append +- `Tasks` — one numbered line per entry in `tasks`, in plan order. Append ` (done)` to any task whose `status` is `done`. -- `Assumptions:` — one line per entry in `assumptions`. -- `Open questions:` — one line per entry in `open_questions`. +- `Assumptions` — one line per entry in `assumptions`. +- `Open questions` — one line per entry in `open_questions`. ## Empty sections @@ -786,14 +770,14 @@ explicit `None.` confirms nothing is pending. When `assumptions` is empty: ``` -## Assumptions: +## Assumptions - None. ``` When `open_questions` is absent: ``` -## Open questions: +## Open questions - None. ``` @@ -814,17 +798,17 @@ When `open_questions` is absent: Path: context/plans/red-sce-banner.md -## Summary: -Renders the ASCII-art SCE banner at the top of `sce` help in red instead of the current gradient. Colour-disabled output is unchanged, and no other help surface is affected. +## Summary +Renders the ASCII-art SCE banner at the top of `sce` help in red instead of the current gradient. Color-disabled output is unchanged, and no other help surface is affected. -## Tasks: +## Tasks 1. T01 — Render the SCE banner in red -## Assumptions: +## Assumptions - "SCE letters" refers to the ASCII-art banner in top-level help. - Red is uniform terminal red when colors are enabled; plain ASCII remains unchanged otherwise. -## Open questions: +## Open questions - None. ``` """ @@ -975,7 +959,7 @@ local readyContinuationLayout = model.semanticReference.apply( This plan is a draft. State a correction and it will be updated. - Next up: + Next step: {next-task-id} — {next-task-title} @@ -1486,7 +1470,7 @@ local renderAuthoringSkillBody = (mode: model.WorkflowRenderMode) -> """ The context brief is the durable memory this plan starts from. Treat its `key_facts` as recorded current state, its `gaps` as areas with no durable - context, and its `drift` as context the code has already outrun. + context, and its `drift` as recorded context that no longer matches the code. When no brief is supplied, load the context named by the change request before authoring, and follow the selection discipline in *Inspect relevant context*. @@ -2205,17 +2189,17 @@ local PLAN_SUMMARY = """ Path: {plan.path} - ## Summary: + ## Summary {plan summary} - ## Tasks: + ## Tasks 1. {task.id} — {task.title} 2. {task.id} — {task.title} - ## Assumptions: + ## Assumptions - {assumption} - ## Open questions: + ## Open questions - {open question} ``` @@ -2227,13 +2211,13 @@ local PLAN_SUMMARY = """ - `Plan:` — `plan.name`. Append ` (updated)` when `plan.action` is `updated`. Render nothing extra when it is `created`. - `Path:` — `plan.path`, exactly as returned, so it stays runnable. - - `Summary:` — `summary`, as prose. This is the only place the reader learns + - `Summary` — `summary`, as prose. This is the only place the reader learns what the plan actually does, so never omit it and never replace it with a restatement of the task titles. - - `Tasks:` — one numbered line per entry in `tasks`, in plan order. Append + - `Tasks` — one numbered line per entry in `tasks`, in plan order. Append ` (done)` to any task whose `status` is `done`. - - `Assumptions:` — one line per entry in `assumptions`. - - `Open questions:` — one line per entry in `open_questions`. + - `Assumptions` — one line per entry in `assumptions`. + - `Open questions` — one line per entry in `open_questions`. ## Empty sections @@ -2243,14 +2227,14 @@ local PLAN_SUMMARY = """ When `assumptions` is empty: ``` - ## Assumptions: + ## Assumptions - None. ``` When `open_questions` is absent: ``` - ## Open questions: + ## Open questions - None. ``` @@ -2271,17 +2255,17 @@ local PLAN_SUMMARY = """ Path: context/plans/red-sce-banner.md - ## Summary: - Renders the ASCII-art SCE banner at the top of `sce` help in red instead of the current gradient. Colour-disabled output is unchanged, and no other help surface is affected. + ## Summary + Renders the ASCII-art SCE banner at the top of `sce` help in red instead of the current gradient. Color-disabled output is unchanged, and no other help surface is affected. - ## Tasks: + ## Tasks 1. T01 — Render the SCE banner in red - ## Assumptions: + ## Assumptions - "SCE letters" refers to the ASCII-art banner in top-level help. - Red is uniform terminal red when colors are enabled; plain ASCII remains unchanged otherwise. - ## Open questions: + ## Open questions - None. ``` """ diff --git a/config/pkl/base/workflow-commit.pkl b/config/pkl/base/workflow-commit.pkl index 612fa1178..3daf6e6c6 100644 --- a/config/pkl/base/workflow-commit.pkl +++ b/config/pkl/base/workflow-commit.pkl @@ -182,13 +182,13 @@ local renderCommandBody = (mode: model.WorkflowRenderMode) -> """ \(noStagedChangesLayout.render.apply(mode)) - Do not stage anything. Do not proceed to the skill. + Do not stage anything. Do not proceed to the phase. #### 2. Request one commit message \(invoke.render.apply(mode)) \(atomicCommit.render.apply(mode))\(bypassPhaseReferenceQualifier.render.apply(mode)) with `mode: bypass` and the commit context. - Bypass mode is the skill's contract for producing exactly one message. Do not + Bypass mode is the phase's contract for producing exactly one message. Do not restate its overrides here; \(atomicCommit.render.apply(mode)) owns them. \(commitContractHandoff.render.apply(mode)) @@ -197,7 +197,7 @@ local renderCommandBody = (mode: model.WorkflowRenderMode) -> """ `bypass_message` -> Continue to the next step. - The skill never returns `proposal` in bypass mode. Treat a `proposal` result as + The phase never returns `proposal` in bypass mode. Treat a `proposal` result as a contract violation: report it and stop without committing. #### 3. Execute exactly one commit @@ -245,7 +245,7 @@ local COMMAND = structuredCommand.render.apply("package", "").text local renderAtomicCommitSkillBody = (mode: model.WorkflowRenderMode) -> """ \(model.packageOnlyBlock.apply(""" - # SCE Atomic Commit + # Atomic commit phase ## Purpose @@ -255,8 +255,8 @@ local renderAtomicCommitSkillBody = (mode: model.WorkflowRenderMode) -> """ \(commitMessageStyle.render.apply(mode)) - Committing is not this skill's job. The invoking `/commit` workflow decides - whether a returned message is committed, and it is the only thing that runs + This phase does not commit. The invoking `/commit` workflow decides + whether a returned message is committed, and it is the only part that runs `git commit`. ## Input @@ -392,7 +392,7 @@ local renderAtomicCommitSkillBody = (mode: model.WorkflowRenderMode) -> """ ## Completion - The skill is complete after: + The phase is complete after: - The staged diff was read, or reading it failed and was reported. - Messages were written for every staged file, or a blocker prevented it. @@ -552,14 +552,14 @@ Run `git diff --cached --quiet`. A zero exit status means nothing is staged. When nothing is staged, stop with the **No staged changes** layout from `references/output.md`. -Do not stage anything. Do not proceed to the skill. +Do not stage anything. Do not proceed to the phase. #### 2. Request one commit message Read `references/atomic-commit.md`, then run the **Atomic commit phase** with `mode: bypass` and the commit context. -Bypass mode is the skill's contract for producing exactly one message. Do not +Bypass mode is the phase's contract for producing exactly one message. Do not restate its overrides here; the **Atomic commit phase** owns them. Branch on `status`: @@ -568,7 +568,7 @@ Branch on `status`: `bypass_message` -> Continue to the next step. -The skill never returns `proposal` in bypass mode. Treat a `proposal` result as +The phase never returns `proposal` in bypass mode. Treat a `proposal` result as a contract violation: report it and stop without committing. #### 3. Execute exactly one commit diff --git a/config/pkl/base/workflow-content.pkl b/config/pkl/base/workflow-content.pkl index 3f89889cc..cff15cbb6 100644 --- a/config/pkl/base/workflow-content.pkl +++ b/config/pkl/base/workflow-content.pkl @@ -217,10 +217,10 @@ hidden executionContract = (variant: ExecutionContractVariant) -> Own this workflow from input through its terminal user-visible response. Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. - Keep phase results internal and continue immediately until a defined wait or stop. + Keep internal phase results private and continue immediately until a defined wait or stop. Resume user waits in this same skill and session. - Use only the specified `references/output.md` layouts for gates and terminal - responses. Do not expose raw state or add text around a layout. + Render user-visible output only from the named workflow layouts or phase reports. + Do not expose raw internal state or add text around a rendered layout or report. Non-SCE helpers may assist, but must return to the active step without changing phase order, gates, waits, writes, validation, stops, or terminal output. """ + "\n" + if (variant == "task-decision") @@ -296,7 +296,7 @@ Branch on the outcome: `synced` | `no_context_change` -> Re-invoke the **Plan review phase** with the same `plan-name-or-path` and, when present, `task-id` to resume normal task selection. -`plan_complete` -> Render the **Plan already complete** layout from `references/output.md`. Stop. +`plan_complete` -> Render the **Implementation complete** layout from `references/output.md`. Stop. `ready` -> Pass the complete readiness result to the **Task execution phase**. @@ -335,10 +335,9 @@ Branch on the execution result. ### 3. Synchronize context Read `references/context-sync.md`, then run the **Task context synchronization -phase** with the complete `complete` result returned by the **Task execution -phase**. +phase** with the task execution result whose `status` is `complete`. -Pass that `complete` result verbatim as the authoritative live handoff to the +Pass that result unchanged as the authoritative live handoff to the **Task context synchronization phase**. Do not restate, summarize, or reconstruct it. This phase verifies the five root context files on every invocation, whatever the @@ -355,7 +354,7 @@ Branch on the synchronization result. Do not select another task. Stop. -`synced` | `no_context_change` -> Print out the report the **Task context synchronization phase** returned. Continue to the next step. +`synced` | `no_context_change` -> Render the Markdown report returned by the **Task context synchronization phase** unchanged. Continue to the next step. ### 4. Determine the continuation @@ -424,7 +423,7 @@ Pass the plan name or path to the **Validation phase** unmodified. Do not restat summarize, or pre-scope it. Every `{plan-path}` and `{candidate-path}` emitted anywhere in this workflow is -the path carried by the **Validation phase** in its Markdown result (`Plan:`, or a +the path carried by the **Validation phase** in its Markdown report (`Plan:`, or a candidate path), so every emitted command is directly runnable. \(invocationExampleParagraph.apply(invocationExample))## Workflow diff --git a/config/pkl/base/workflow-context-sync.pkl b/config/pkl/base/workflow-context-sync.pkl index 88c230fb1..f694996d7 100644 --- a/config/pkl/base/workflow-context-sync.pkl +++ b/config/pkl/base/workflow-context-sync.pkl @@ -66,7 +66,7 @@ local skillText = (role: SyncRole, mode: workflow.WorkflowRenderMode) -> local decisionGate = (evidenceSource: String, mode: workflow.WorkflowRenderMode) -> """ This subsection is the sole owner of decision qualification. The threshold below - decides whether `sce-decision` is invoked; the decision skill consumes that gate + decides whether `sce-decision` is invoked; the decision skill consumes that qualification result and must not restate or broaden it. During this successful synchronization, determine whether the completed change @@ -156,7 +156,7 @@ local taskRoleData = new SyncRole { Either the complete result returned by the task-execution phase (same-session), or the plan path and task ID a plan-review recovery step - resolved for a `blocked` task, together with that task's own completed + resolved for a completed task with unresolved context synchronization, together with that task's own completed record — read directly from the plan — and its persisted `Context synchronization blocker` when present (cross-session retry). """).render.apply(mode))A live execution result must have: @@ -1129,7 +1129,7 @@ plan state. Input: either the complete `complete` result from the task execution phase (same-session), passed verbatim, or the plan path and task ID a plan-review -recovery step resolved for a `blocked` task, together with that task's own +recovery step resolved for a completed task with unresolved context synchronization, together with that task's own completed record — read directly from the plan — and its persisted `Context synchronization blocker` when present (cross-session retry). Whichever was supplied is authoritative; this phase consumes it without redefining its shape. diff --git a/config/pkl/base/workflow-handover.pkl b/config/pkl/base/workflow-handover.pkl index 0dc8760c7..b11b9e001 100644 --- a/config/pkl/base/workflow-handover.pkl +++ b/config/pkl/base/workflow-handover.pkl @@ -43,11 +43,13 @@ local titleAndPurpose = model.packageOnlyBlock.apply(""" """) local renderPersistedFormatBody = """ + # Handover document format + The Markdown document writer mode creates under `context/handovers/{name}.md`. This is the persisted file's content, distinct from the terminal response defined in `references/output.md`. - ### Layout + ## Template ```markdown # Handover: {plan name or short session topic} @@ -80,9 +82,9 @@ local renderPersistedFormatBody = """ `None.`} ``` - ### Completeness contract + ## Completeness contract - - The first four `##` sections shown in **Layout** are required and must appear + - The first four `##` sections shown in **Template** are required and must appear in that order. - Each required section's content, up to the next `##` heading or the end of the file, must contain non-whitespace content. An empty list marker, unreplaced @@ -92,10 +94,10 @@ local renderPersistedFormatBody = """ - Writer mode must satisfy this contract before reporting success; loader mode validates the same contract before presenting a handover. - ### Rules + ## Rules - - Include `Plan` and `Task` only when the session was working one identifiable - plan task; omit them rather than guessing. + - Include `Plan` when one plan is known. Include `Task` only when one task is + known. Omit either field rather than guessing its value. - Keep `Assumptions` scoped to details actually labeled as inferred elsewhere in the document; do not duplicate confirmed facts here. - Describe durable state useful to a future session, not a transcript of this @@ -330,7 +332,7 @@ local OUTPUT_MD = (argumentsReference: String) -> """ plan task was marked complete, and the recommended next step was not started. ``` - # Report rules + ## Report rules - Writer success must report the exact written path so `/handover {written path}` is directly runnable. diff --git a/config/pkl/base/workflow-next-task.pkl b/config/pkl/base/workflow-next-task.pkl index 234cdc46e..b0a746a7a 100644 --- a/config/pkl/base/workflow-next-task.pkl +++ b/config/pkl/base/workflow-next-task.pkl @@ -1848,7 +1848,7 @@ Present the selected task, then each issue's problem, impact, and required decision. If plan resolution is ambiguous, list candidate paths and `/next-task {candidate-path}`. State whether another task remains executable. -## Plan already complete +## Implementation complete ```markdown ------------------------------------- diff --git a/config/pkl/base/workflow-validate.pkl b/config/pkl/base/workflow-validate.pkl index c221fcd5b..8b2d3d813 100644 --- a/config/pkl/base/workflow-validate.pkl +++ b/config/pkl/base/workflow-validate.pkl @@ -18,7 +18,7 @@ local validationReport = model.semanticReference.apply("`references/validation-r local reportVersusResult = model.semanticReference.apply( """ The plan-file `## Validation Report` section is written separately using - `references/validation-report.md`. This file is the skill's return value to the + `references/validation-report.md`. This file is the phase's return value to the invoking workflow. """, """ @@ -32,7 +32,7 @@ local reportVersusResult = model.semanticReference.apply( /// workflow uses the same emitted document, so the reference remains unchanged. local validationResultHandoff = model.semanticReference.apply( """ - The skill must return a Markdown result matching its validation result contract. + The phase must return a Markdown report matching its validation result contract. Branch on the report's `Status:`. """, "Branch on the report's `Status:`." @@ -40,9 +40,9 @@ local validationResultHandoff = model.semanticReference.apply( local invoke = model.semanticReference.apply("Invoke", "Run") local invokedSkills = model.semanticReference.apply("invoked skills", "embedded phases") local invokedSkill = model.semanticReference.apply("invoked skill", "embedded phase") -local markdownResult = model.semanticReference.apply("Markdown result", "internal state") +local markdownResult = model.semanticReference.apply("Markdown report", "internal state") local returningValidationResult = model.semanticReference.apply("Returning one Markdown validation result", "Recording one Markdown validation result") -local returnExactlyOneMarkdownResult = model.semanticReference.apply("Return exactly one Markdown result", "Set exactly one internal state") +local returnExactlyOneMarkdownResult = model.semanticReference.apply("Return exactly one Markdown report", "Set exactly one internal state") local returnOnlyMarkdownReport = model.semanticReference.apply("Return only the Markdown report", "Record only the Markdown report") local returnLower = model.semanticReference.apply("return", "set internal status") local returnUpper = model.semanticReference.apply("Return", "Set internal status") @@ -106,7 +106,7 @@ local renderCommandBody = (mode: model.WorkflowRenderMode) -> """ summarize, or pre-scope it. Every `{plan-path}` and `{candidate-path}` emitted anywhere in this workflow is - the path carried by \(validation.render.apply(mode)) in its Markdown result (`Plan:`, or a + the path carried by \(validation.render.apply(mode)) in its Markdown report (`Plan:`, or a candidate path), so every emitted command is directly runnable. ## Workflow @@ -137,7 +137,7 @@ local renderCommandBody = (mode: model.WorkflowRenderMode) -> """ Do not rewrite it into a shorter summary. Do not drop the retry command. Do not add an alternate continuation that replaces `/validate`. Stop. - `validated` -> Print the complete validated Markdown result as returned. + `validated` -> Print the complete validated Markdown report as returned. Continue to the next step. ### 2. Report completion @@ -182,7 +182,7 @@ local COMMAND = structuredCommand.render.apply("package", "").text local renderValidationSkillBody = (mode: model.WorkflowRenderMode) -> """ \(model.packageOnlyBlock.apply(""" - # SCE Validation + # Validation phase ## Purpose @@ -260,8 +260,7 @@ local renderValidationSkillBody = (mode: model.WorkflowRenderMode) -> """ When a check fails, record the failure and continue gathering evidence. Do not modify tests, application code, or configuration to make a check pass. Final - validation measures the finished work; repair belongs to a later work session, - not this skill. + validation measures the finished work; repair belongs to a normal work session outside this phase. Never report a check as passed unless it ran successfully or the authorized inspection confirmed the criterion. @@ -429,7 +428,7 @@ local renderValidationReport = (mode: model.WorkflowRenderMode) -> """ local VALIDATION_REPORT = renderValidationReport.apply("package") local renderValidationResult = (mode: model.WorkflowRenderMode) -> """ - # Validation Result + # Validation report Return only one completed Markdown report using the applicable variant below. Do not include unused sections, placeholders, YAML, or a fenced code block. @@ -442,7 +441,7 @@ local renderValidationResult = (mode: model.WorkflowRenderMode) -> """ \(reportVersusResult.render.apply(mode)) - ## Validated variant + ## Validated report # Validation Report @@ -473,7 +472,7 @@ local renderValidationResult = (mode: model.WorkflowRenderMode) -> """ --- - ## Failed variant + ## Failed report This variant is a session handoff. Another agent or a later session must be able to act from it alone. Write it as a prompt the user can paste forward, not @@ -537,7 +536,7 @@ local renderValidationResult = (mode: model.WorkflowRenderMode) -> """ --- - ## Blocked variant + ## Blocked report # Validation blocked diff --git a/config/pkl/renderers/generation-contract-check.pkl b/config/pkl/renderers/generation-contract-check.pkl index e6a3ecc1d..a0556aec1 100644 --- a/config/pkl/renderers/generation-contract-check.pkl +++ b/config/pkl/renderers/generation-contract-check.pkl @@ -289,8 +289,8 @@ local requiredHandoverSkillTokens = new Listing { } local requiredHandoverTemplateCompletenessTokens = new Listing { - "### Completeness contract" - "first four `##` sections shown in **Layout** are required" + "## Completeness contract" + "first four `##` sections shown in **Template** are required" "next `##` heading or the end of the" "empty list marker" "`{...}` placeholder" @@ -329,10 +329,10 @@ local expectedExecutionContract = (allowsDecision: Boolean) -> Own this workflow from input through its terminal user-visible response. Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them. - Keep phase results internal and continue immediately until a defined wait or stop. + Keep internal phase results private and continue immediately until a defined wait or stop. Resume user waits in this same skill and session. - Use only the specified `references/output.md` layouts for gates and terminal - responses. Do not expose raw state or add text around a layout. + Render user-visible output only from the named workflow layouts or phase reports. + Do not expose raw internal state or add text around a rendered layout or report. Non-SCE helpers may assist, but must return to the active step without changing phase order, gates, waits, writes, validation, stops, or terminal output. """ + "\n" + if (allowsDecision) @@ -346,9 +346,9 @@ local expectedExecutionContract = (allowsDecision: Boolean) -> local compactContractClauses = new Listing { "Own this workflow from input through its terminal user-visible response." "Follow its steps, gates, and stops in order; do not add, skip, reorder, or merge them." - "Keep phase results internal and continue immediately until a defined wait or stop." + "Keep internal phase results private and continue immediately until a defined wait or stop." "Resume user waits in this same skill and session." - "Use only the specified `references/output.md` layouts for gates and terminal\nresponses. Do not expose raw state or add text around a layout." + "Render user-visible output only from the named workflow layouts or phase reports.\nDo not expose raw internal state or add text around a rendered layout or report." "Non-SCE helpers may assist, but must return to the active step without changing\nphase order, gates, waits, writes, validation, stops, or terminal output." } @@ -1128,7 +1128,7 @@ local validationExecutionPolicyTokens = new Listing { "Prefer the plan's authored checks." "Treat leftover debug-only flags, temporary files" "Never report a check as passed unless it ran successfully" - "repair belongs to a later work session" + "repair belongs to a normal work session outside this phase" "Do not reopen completed tasks, rewrite task evidence, or change the task stack." } @@ -1198,7 +1198,38 @@ hidden assertValidateExcludesDecisionAndPlanSync = (documents: Mapping) -> ) "sce-validate package: no sce-decision reference or plan-context-sync wording" else throw("generated sce-validate document must not contain a sce-decision reference or plan-context-sync wording") + +hidden assertWorkflowLanguageConsistency = (artifacts: Mapping) -> + let (targets = new Listing { ".pi"; ".claude"; ".agents" }) + if ( + targets.every((target) -> + let (next = artifacts["config/\(target)/skills/sce-next-task/SKILL.md"]) + let (commitRef = artifacts["config/\(target)/skills/sce-commit/references/atomic-commit.md"]) + let (validationRef = artifacts["config/\(target)/skills/sce-validate/references/validation.md"]) + let (handoverTemplate = artifacts["config/\(target)/skills/sce-handover/references/handover-template.md"]) + let (planTemplate = artifacts["config/\(target)/skills/sce-change-to-plan/references/plan-template.md"]) + let (contextSync = artifacts["config/\(target)/skills/sce-next-task/references/context-sync.md"]) + next.contains("Keep internal phase results private") + && next.contains("named workflow layouts or phase reports") + && next.contains("**Implementation complete**") + && commitRef.contains("# Atomic commit phase") + && commitRef.contains("The phase is complete after:") + && !commitRef.contains("Committing is not this skill's job") + && validationRef.contains("# Validation phase") + && validationRef.contains("# Validation report") + && !validationRef.contains("# SCE Validation") + && handoverTemplate.contains("# Handover document format") + && handoverTemplate.contains("## Template") + && handoverTemplate.contains("Include `Plan` when one plan is known") + && planTemplate.contains("reports cleanup or repair work") + && planTemplate.contains("it does not perform that work") + && contextSync.contains("completed task with unresolved context synchronization") + ) + ) "workflow language: shared vocabulary, phase naming, report naming, and document format are consistent" + else throw("generated workflow language/format drifted from the shared T11 conventions") + contractChecks { + ["workflow-language-consistency"] = assertWorkflowLanguageConsistency.apply(generatedArtifacts) ["compact-execution-contracts"] = assertCompactExecutionContracts.apply(workflowDocuments) ["compact-execution-contract-negative-fixtures"] = assertCompactExecutionContractFixtures ["artifact-paths"] = assertExactArtifactPaths.apply(generatedArtifacts) diff --git a/context/plans/compress-workflow-execution-preamble.md b/context/plans/compress-workflow-execution-preamble.md index 99f9fca82..b7aacc885 100644 --- a/context/plans/compress-workflow-execution-preamble.md +++ b/context/plans/compress-workflow-execution-preamble.md @@ -452,3 +452,14 @@ The two additional root edits replace existing text without increasing line coun `nix run .#pkl-check-generated`, targeted ownership checks across all tracked mirrors, and `git diff --check`. - Context synchronization: synced. + +## Follow-up: workflow language and document consistency + +- [x] T11: `Normalize workflow language and document format` (status:done) + - Scope: shared workflow vocabulary, embedded-phase/reference wording, output/report terminology, plan-authoring tone, handover persisted-document format, validation non-repairing wording, canonical Pkl, generated Pi/Claude/Codex mirrors, semantic generation checks, and ownership context. + - Vocabulary after change: command = user invocation; workflow = complete procedure; phase = embedded operation; step = numbered action; internal result = structured private phase data; report = formatted Markdown; completion record = persisted task evidence; handover document = persisted session handover. + - Format after change: embedded references identify themselves as phases rather than sibling skills; persisted-format references use a document title plus Template/contract/rules sections; output headings use consistent sentence-case punctuation; output and validation prose distinguish internal results from rendered reports. + - Correctness fixes: `/validate` remains observational and reports cleanup/repair work instead of performing it; handover `Plan` and `Task` metadata are independently included only when known; context-sync recovery names completed tasks with unresolved synchronization; next-task calls the pre-validation terminal state `Implementation complete` rather than `Plan already complete`. + - Behavior preserved: command names, argument tokens, status values, approval gates, phase order, write permissions, persisted plan/task field names, decision qualification, and lifecycle transitions remain unchanged. + - Verify: `pkl eval config/pkl/renderers/generation-contract-check.pkl`; `nix run .#pkl-check-generated`; exact 141-artifact inventory; generated mirror parity; `git diff --check`; `workflow-language-consistency` semantic contract. + - Context synchronization: synced. diff --git a/context/sce/dedup-ownership-table.md b/context/sce/dedup-ownership-table.md index 6dd351197..fc474fc5c 100644 --- a/context/sce/dedup-ownership-table.md +++ b/context/sce/dedup-ownership-table.md @@ -43,3 +43,16 @@ - Keep SCE workflow control flow inside the owning workflow skill. Relevant non-SCE skills may assist as in-step helpers that return control to the active step; `sce-decision` remains the sole SCE sibling-skill exception, usable only from successful task synchronization's decision gate, once per qualifying decision. - Do not reintroduce the removed `/validate` plan-context-sync handoff, legacy context-sync, or automated-profile Markdown ownership. - Do not reintroduce phase skills as a generated surface. Workflow behavior belongs in the canonical modules and installation belongs to the six command-routed workflow packages (see [Atomic commit workflow](atomic-commit-workflow.md) for `/commit`). The standalone `sce-decision` package is a separate internal surface, not a generated phase package or user-facing workflow. + +## Workflow language conventions + +- **Command** is the user-facing invocation such as `/next-task`. +- **Workflow** is the complete procedure owned by a generated workflow `SKILL.md`. +- **Phase** is an embedded operation such as plan review, task execution, or validation. +- **Step** is one numbered action inside a workflow or phase. +- **Internal result** is structured phase data that is not shown directly. Its discriminator is `status`. +- **Report** is formatted Markdown shown to the user or persisted as a report section. +- **Completion record** is execution evidence persisted on a completed task in its plan. +- **Handover document** is the persisted session document under `context/handovers/`. + +Use the verbs consistently: run a phase, return an internal result, render a report or layout, and write a persisted file. Preserve distinct lifecycle terms such as task `done`, execution `complete`, context `synced`, and plan `validated`; do not collapse them into one generic success term. From 75d46db9c7ff574ea3f045b335092c42c871fb9a Mon Sep 17 00:00:00 2001 From: David Abram Date: Tue, 8 Sep 2026 15:49:59 +0000 Subject: [PATCH 12/12] config: Finalize workflow language consistency --- .../sce-change-to-plan/references/output.md | 8 +- .../references/plan-authoring.md | 12 ++- .agents/skills/sce-decision/SKILL.md | 10 +-- .../sce-next-task/references/context-sync.md | 6 +- .../skills/sce-next-task/references/output.md | 2 +- .../sce-next-task/references/plan-review.md | 4 +- .../references/task-execution.md | 6 +- .../references/validation-report.md | 2 +- .../sce-validate/references/validation.md | 8 +- .../sce-change-to-plan/references/output.md | 8 +- .../references/plan-authoring.md | 12 ++- .claude/skills/sce-decision/SKILL.md | 10 +-- .../sce-next-task/references/context-sync.md | 6 +- .../skills/sce-next-task/references/output.md | 2 +- .../sce-next-task/references/plan-review.md | 4 +- .../references/task-execution.md | 6 +- .../references/validation-report.md | 2 +- .../sce-validate/references/validation.md | 8 +- .../sce-change-to-plan/references/output.md | 8 +- .../references/plan-authoring.md | 12 ++- .pi/skills/sce-decision/SKILL.md | 10 +-- .../sce-next-task/references/context-sync.md | 6 +- .pi/skills/sce-next-task/references/output.md | 2 +- .../sce-next-task/references/plan-review.md | 4 +- .../references/task-execution.md | 6 +- .../references/validation-report.md | 2 +- .../sce-validate/references/validation.md | 8 +- config/pkl/base/decision-skill.pkl | 10 +-- config/pkl/base/workflow-change-to-plan.pkl | 20 ++--- config/pkl/base/workflow-context-sync.pkl | 6 +- config/pkl/base/workflow-next-task.pkl | 14 +-- config/pkl/base/workflow-validate.pkl | 14 +-- .../renderers/generation-contract-check.pkl | 6 ++ context/context-map.md | 1 + .../compress-workflow-execution-preamble.md | 4 +- context/sce/dedup-ownership-table.md | 13 +-- context/sce/workflow-vocabulary.md | 89 +++++++++++++++++++ 37 files changed, 216 insertions(+), 135 deletions(-) create mode 100644 context/sce/workflow-vocabulary.md diff --git a/.agents/skills/sce-change-to-plan/references/output.md b/.agents/skills/sce-change-to-plan/references/output.md index bc7e1a3fc..af24186bc 100644 --- a/.agents/skills/sce-change-to-plan/references/output.md +++ b/.agents/skills/sce-change-to-plan/references/output.md @@ -66,7 +66,7 @@ This is chat output, not a file. Nothing here is written to the plan. ## Layout -``` +```markdown # Plan: {plan.name} Path: {plan.path} @@ -108,14 +108,14 @@ explicit `None.` confirms nothing is pending. When `assumptions` is empty: -``` +```markdown ## Assumptions - None. ``` When `open_questions` is absent: -``` +```markdown ## Open questions - None. ``` @@ -132,7 +132,7 @@ When `open_questions` is absent: ## Example -``` +```markdown # Plan: red-sce-banner Path: context/plans/red-sce-banner.md diff --git a/.agents/skills/sce-change-to-plan/references/plan-authoring.md b/.agents/skills/sce-change-to-plan/references/plan-authoring.md index fdd3abe7a..0f08f5a06 100644 --- a/.agents/skills/sce-change-to-plan/references/plan-authoring.md +++ b/.agents/skills/sce-change-to-plan/references/plan-authoring.md @@ -13,11 +13,10 @@ This phase owns the planning process: - Decide task boundaries, dependencies, and ordering. - Write or revise exactly one `context/plans/{plan_name}.md`. -`references/plan-template.md` is the sole owner of the persisted plan schema and -generic document-authoring rules: acceptance-criteria format and validation -semantics, task fields and atomic slicing, the no-validation-task rule, completion -records, and existing-plan update preservation. Read it before authoring or -revising and apply those rules rather than restating them here. +`references/plan-template.md` is the sole owner of the persisted plan schema. +Read its `Acceptance criteria rules`, `Task rules` and `No validation task` rules, +and `Updating an existing plan` rules before authoring or revising. Apply those +rules rather than restating them here. The workflow renders this phase's result as the summary defined in `references/output.md`. @@ -162,8 +161,7 @@ semantics and placement. Slice and order the plan-specific work after the acceptance criteria, applying the `Task rules` and `No validation task` rules in `references/plan-template.md`. -The template owns the task field shape, atomic-commit constraint, dependency-order -rule, acceptance-coverage rule, and generic task exclusions. +Do not restate those generic task rules here. A finished stack always leaves at least one incomplete task, so the workflow can always hand off to `/next-task`. When the request resolves to a plan but produces diff --git a/.agents/skills/sce-decision/SKILL.md b/.agents/skills/sce-decision/SKILL.md index 789d792ba..32b74fefe 100644 --- a/.agents/skills/sce-decision/SKILL.md +++ b/.agents/skills/sce-decision/SKILL.md @@ -10,7 +10,7 @@ description: > Write exactly one architecture decision record for one decision already qualified by successful task context synchronization. Return a deterministic internal -handoff to the invoking synchronization phase. Do not render an independent +result to the invoking synchronization phase. Do not render an independent user-visible response. ## Input @@ -25,7 +25,7 @@ synchronization. It must identify: - Related current-state context and existing ADR paths. - An optional requested status. -Do not accept raw workflow arguments, ordinary phase state, multiple decisions, +Do not accept raw workflow arguments, ordinary phase result, multiple decisions, or direct user invocation. Do not reconstruct missing material facts. ## Qualification handoff @@ -101,9 +101,9 @@ the filename, status, sections, and references satisfy this contract; every referenced repository path exists when practical to check; and no accepted ADR was modified. -### 6. Return internal state +### 6. Return the result -Return exactly one internal handoff: +Return exactly one internal result: - `written`: include `status`, `adr_path`, `decision`, `decision_status`, `created` (`true` for a new ADR and `false` for reuse), `supersedes`, and @@ -115,7 +115,7 @@ Return exactly one internal handoff: `required_action`. Use this only when decision writing cannot proceed safely. Use stable field names and repository-relative paths. Return no prose before or -after the handoff. The invoking synchronization phase owns all user-visible +after the result. The invoking synchronization phase owns all user-visible reporting. ## Boundaries diff --git a/.agents/skills/sce-next-task/references/context-sync.md b/.agents/skills/sce-next-task/references/context-sync.md index 6e6074dcf..807b83ffa 100644 --- a/.agents/skills/sce-next-task/references/context-sync.md +++ b/.agents/skills/sce-next-task/references/context-sync.md @@ -5,8 +5,8 @@ Run this phase for step 3 of the workflow, and only when task execution returned session inherits what this task established. It never touches code, tests, or plan state. -Input: either the complete `complete` result from the task execution phase -(same-session), passed verbatim, or the plan path and task ID a plan-review +Input: either the task execution result with `status: complete` +(same-session), passed unchanged, or the plan path and task ID a plan-review recovery step resolved for a completed task with unresolved context synchronization, together with that task's own completed record — read directly from the plan — and its persisted `Context synchronization blocker` when present (cross-session retry). Whichever was @@ -331,4 +331,4 @@ Do not: except `sce-decision`, or invoke `sce-decision` outside the decision gate in successful context synchronization. - Delete a context file that has uncommitted changes. -- Return an execution-style internal state. +- Return a task-execution internal result. diff --git a/.agents/skills/sce-next-task/references/output.md b/.agents/skills/sce-next-task/references/output.md index 40a66539f..c8a9bcbef 100644 --- a/.agents/skills/sce-next-task/references/output.md +++ b/.agents/skills/sce-next-task/references/output.md @@ -48,7 +48,7 @@ be synchronized before continuing. {completed-tasks} of {total-tasks} tasks complete. -Next up: +Next step: {next-task-id} — {next-task-title} diff --git a/.agents/skills/sce-next-task/references/plan-review.md b/.agents/skills/sce-next-task/references/plan-review.md index 41f6c55c6..ae6a97b66 100644 --- a/.agents/skills/sce-next-task/references/plan-review.md +++ b/.agents/skills/sce-next-task/references/plan-review.md @@ -109,14 +109,14 @@ Set internal status `blocked` when a missing decision materially affects: ## 1.5 Return the result -Set exactly one internal state: +Return one internal result with one of these statuses: - `ready` - `blocked` - `plan_complete` - `sync_debt` -Record only the internal state. Do not add explanatory prose before or after it. +Return only the internal result. Do not add explanatory prose before or after it. A `ready` result must identify: diff --git a/.agents/skills/sce-next-task/references/task-execution.md b/.agents/skills/sce-next-task/references/task-execution.md index 2c64dff2a..ad9ce6373 100644 --- a/.agents/skills/sce-next-task/references/task-execution.md +++ b/.agents/skills/sce-next-task/references/task-execution.md @@ -194,11 +194,11 @@ that decision after context synchronization. Before returning a `complete` result, verify that it satisfies the authoritative handoff contract above. -## 2.9 Return internal state +## 2.9 Return the result -After the phase reaches a terminal state, set exactly one internal state. +After the phase reaches a terminal state, return exactly one internal result. -Record only the internal state. Do not add explanatory prose before or after it. +Return only the internal result. Do not add explanatory prose before or after it. A `complete` result is the authoritative handoff into step 3. Pass it unchanged; step 3 must consume it instead of reconstructing its fields. diff --git a/.agents/skills/sce-validate/references/validation-report.md b/.agents/skills/sce-validate/references/validation-report.md index 2d5ed6218..b0fa7778b 100644 --- a/.agents/skills/sce-validate/references/validation-report.md +++ b/.agents/skills/sce-validate/references/validation-report.md @@ -67,6 +67,6 @@ After repairs, rerun: - When status is `failed`, always include **Retry** with the exact `/validate {plan path}` command. Omit **Retry** when status is `validated`. - Keep evidence concise and factual. Do not narrate the whole implementation - history or add execution-policy claims absent from the validation result. + history or add execution-policy claims absent from the validation report. - When a previous `## Validation Report` already exists, replace it with the new one rather than stacking duplicates. diff --git a/.agents/skills/sce-validate/references/validation.md b/.agents/skills/sce-validate/references/validation.md index 50895cc83..440f21d47 100644 --- a/.agents/skills/sce-validate/references/validation.md +++ b/.agents/skills/sce-validate/references/validation.md @@ -14,11 +14,11 @@ This phase owns: check. - Writing the Validation Report into the plan. - Marking acceptance criteria against the evidence. -- Returning one Markdown validation result. +- Returning one Markdown validation report. Return a result matching: -the **Validation Result** section below in this file +the **Validation report** section below in this file Write plan-file evidence matching: @@ -109,7 +109,7 @@ Return exactly one Markdown report: passed, and the Validation Report was written. - `failed` when evidence was captured but required checks or criteria remain unsatisfied. Shape it as a session handoff per - the **Validation Result** section below in this file, ending recommended work with + the **Validation report** section below in this file, ending recommended work with `/validate {plan path}`. - `blocked` when validation cannot proceed safely. @@ -140,7 +140,7 @@ The phase is complete after: - One plan was resolved, or resolution failed and was reported. - Implementation completeness was checked. - Validation ran to a terminal state, or a blocker prevented it. -- One valid Markdown report matching the **Validation Result** section below in this file was +- One valid Markdown report matching the **Validation report** section below in this file was returned. diff --git a/.claude/skills/sce-change-to-plan/references/output.md b/.claude/skills/sce-change-to-plan/references/output.md index bc7e1a3fc..af24186bc 100644 --- a/.claude/skills/sce-change-to-plan/references/output.md +++ b/.claude/skills/sce-change-to-plan/references/output.md @@ -66,7 +66,7 @@ This is chat output, not a file. Nothing here is written to the plan. ## Layout -``` +```markdown # Plan: {plan.name} Path: {plan.path} @@ -108,14 +108,14 @@ explicit `None.` confirms nothing is pending. When `assumptions` is empty: -``` +```markdown ## Assumptions - None. ``` When `open_questions` is absent: -``` +```markdown ## Open questions - None. ``` @@ -132,7 +132,7 @@ When `open_questions` is absent: ## Example -``` +```markdown # Plan: red-sce-banner Path: context/plans/red-sce-banner.md diff --git a/.claude/skills/sce-change-to-plan/references/plan-authoring.md b/.claude/skills/sce-change-to-plan/references/plan-authoring.md index fdd3abe7a..0f08f5a06 100644 --- a/.claude/skills/sce-change-to-plan/references/plan-authoring.md +++ b/.claude/skills/sce-change-to-plan/references/plan-authoring.md @@ -13,11 +13,10 @@ This phase owns the planning process: - Decide task boundaries, dependencies, and ordering. - Write or revise exactly one `context/plans/{plan_name}.md`. -`references/plan-template.md` is the sole owner of the persisted plan schema and -generic document-authoring rules: acceptance-criteria format and validation -semantics, task fields and atomic slicing, the no-validation-task rule, completion -records, and existing-plan update preservation. Read it before authoring or -revising and apply those rules rather than restating them here. +`references/plan-template.md` is the sole owner of the persisted plan schema. +Read its `Acceptance criteria rules`, `Task rules` and `No validation task` rules, +and `Updating an existing plan` rules before authoring or revising. Apply those +rules rather than restating them here. The workflow renders this phase's result as the summary defined in `references/output.md`. @@ -162,8 +161,7 @@ semantics and placement. Slice and order the plan-specific work after the acceptance criteria, applying the `Task rules` and `No validation task` rules in `references/plan-template.md`. -The template owns the task field shape, atomic-commit constraint, dependency-order -rule, acceptance-coverage rule, and generic task exclusions. +Do not restate those generic task rules here. A finished stack always leaves at least one incomplete task, so the workflow can always hand off to `/next-task`. When the request resolves to a plan but produces diff --git a/.claude/skills/sce-decision/SKILL.md b/.claude/skills/sce-decision/SKILL.md index 540a51aeb..d75d761fb 100644 --- a/.claude/skills/sce-decision/SKILL.md +++ b/.claude/skills/sce-decision/SKILL.md @@ -11,7 +11,7 @@ compatibility: claude Write exactly one architecture decision record for one decision already qualified by successful task context synchronization. Return a deterministic internal -handoff to the invoking synchronization phase. Do not render an independent +result to the invoking synchronization phase. Do not render an independent user-visible response. ## Input @@ -26,7 +26,7 @@ synchronization. It must identify: - Related current-state context and existing ADR paths. - An optional requested status. -Do not accept raw workflow arguments, ordinary phase state, multiple decisions, +Do not accept raw workflow arguments, ordinary phase result, multiple decisions, or direct user invocation. Do not reconstruct missing material facts. ## Qualification handoff @@ -102,9 +102,9 @@ the filename, status, sections, and references satisfy this contract; every referenced repository path exists when practical to check; and no accepted ADR was modified. -### 6. Return internal state +### 6. Return the result -Return exactly one internal handoff: +Return exactly one internal result: - `written`: include `status`, `adr_path`, `decision`, `decision_status`, `created` (`true` for a new ADR and `false` for reuse), `supersedes`, and @@ -116,7 +116,7 @@ Return exactly one internal handoff: `required_action`. Use this only when decision writing cannot proceed safely. Use stable field names and repository-relative paths. Return no prose before or -after the handoff. The invoking synchronization phase owns all user-visible +after the result. The invoking synchronization phase owns all user-visible reporting. ## Boundaries diff --git a/.claude/skills/sce-next-task/references/context-sync.md b/.claude/skills/sce-next-task/references/context-sync.md index 6e6074dcf..807b83ffa 100644 --- a/.claude/skills/sce-next-task/references/context-sync.md +++ b/.claude/skills/sce-next-task/references/context-sync.md @@ -5,8 +5,8 @@ Run this phase for step 3 of the workflow, and only when task execution returned session inherits what this task established. It never touches code, tests, or plan state. -Input: either the complete `complete` result from the task execution phase -(same-session), passed verbatim, or the plan path and task ID a plan-review +Input: either the task execution result with `status: complete` +(same-session), passed unchanged, or the plan path and task ID a plan-review recovery step resolved for a completed task with unresolved context synchronization, together with that task's own completed record — read directly from the plan — and its persisted `Context synchronization blocker` when present (cross-session retry). Whichever was @@ -331,4 +331,4 @@ Do not: except `sce-decision`, or invoke `sce-decision` outside the decision gate in successful context synchronization. - Delete a context file that has uncommitted changes. -- Return an execution-style internal state. +- Return a task-execution internal result. diff --git a/.claude/skills/sce-next-task/references/output.md b/.claude/skills/sce-next-task/references/output.md index 40a66539f..c8a9bcbef 100644 --- a/.claude/skills/sce-next-task/references/output.md +++ b/.claude/skills/sce-next-task/references/output.md @@ -48,7 +48,7 @@ be synchronized before continuing. {completed-tasks} of {total-tasks} tasks complete. -Next up: +Next step: {next-task-id} — {next-task-title} diff --git a/.claude/skills/sce-next-task/references/plan-review.md b/.claude/skills/sce-next-task/references/plan-review.md index 41f6c55c6..ae6a97b66 100644 --- a/.claude/skills/sce-next-task/references/plan-review.md +++ b/.claude/skills/sce-next-task/references/plan-review.md @@ -109,14 +109,14 @@ Set internal status `blocked` when a missing decision materially affects: ## 1.5 Return the result -Set exactly one internal state: +Return one internal result with one of these statuses: - `ready` - `blocked` - `plan_complete` - `sync_debt` -Record only the internal state. Do not add explanatory prose before or after it. +Return only the internal result. Do not add explanatory prose before or after it. A `ready` result must identify: diff --git a/.claude/skills/sce-next-task/references/task-execution.md b/.claude/skills/sce-next-task/references/task-execution.md index 2c64dff2a..ad9ce6373 100644 --- a/.claude/skills/sce-next-task/references/task-execution.md +++ b/.claude/skills/sce-next-task/references/task-execution.md @@ -194,11 +194,11 @@ that decision after context synchronization. Before returning a `complete` result, verify that it satisfies the authoritative handoff contract above. -## 2.9 Return internal state +## 2.9 Return the result -After the phase reaches a terminal state, set exactly one internal state. +After the phase reaches a terminal state, return exactly one internal result. -Record only the internal state. Do not add explanatory prose before or after it. +Return only the internal result. Do not add explanatory prose before or after it. A `complete` result is the authoritative handoff into step 3. Pass it unchanged; step 3 must consume it instead of reconstructing its fields. diff --git a/.claude/skills/sce-validate/references/validation-report.md b/.claude/skills/sce-validate/references/validation-report.md index 2d5ed6218..b0fa7778b 100644 --- a/.claude/skills/sce-validate/references/validation-report.md +++ b/.claude/skills/sce-validate/references/validation-report.md @@ -67,6 +67,6 @@ After repairs, rerun: - When status is `failed`, always include **Retry** with the exact `/validate {plan path}` command. Omit **Retry** when status is `validated`. - Keep evidence concise and factual. Do not narrate the whole implementation - history or add execution-policy claims absent from the validation result. + history or add execution-policy claims absent from the validation report. - When a previous `## Validation Report` already exists, replace it with the new one rather than stacking duplicates. diff --git a/.claude/skills/sce-validate/references/validation.md b/.claude/skills/sce-validate/references/validation.md index 50895cc83..440f21d47 100644 --- a/.claude/skills/sce-validate/references/validation.md +++ b/.claude/skills/sce-validate/references/validation.md @@ -14,11 +14,11 @@ This phase owns: check. - Writing the Validation Report into the plan. - Marking acceptance criteria against the evidence. -- Returning one Markdown validation result. +- Returning one Markdown validation report. Return a result matching: -the **Validation Result** section below in this file +the **Validation report** section below in this file Write plan-file evidence matching: @@ -109,7 +109,7 @@ Return exactly one Markdown report: passed, and the Validation Report was written. - `failed` when evidence was captured but required checks or criteria remain unsatisfied. Shape it as a session handoff per - the **Validation Result** section below in this file, ending recommended work with + the **Validation report** section below in this file, ending recommended work with `/validate {plan path}`. - `blocked` when validation cannot proceed safely. @@ -140,7 +140,7 @@ The phase is complete after: - One plan was resolved, or resolution failed and was reported. - Implementation completeness was checked. - Validation ran to a terminal state, or a blocker prevented it. -- One valid Markdown report matching the **Validation Result** section below in this file was +- One valid Markdown report matching the **Validation report** section below in this file was returned. diff --git a/.pi/skills/sce-change-to-plan/references/output.md b/.pi/skills/sce-change-to-plan/references/output.md index bc7e1a3fc..af24186bc 100644 --- a/.pi/skills/sce-change-to-plan/references/output.md +++ b/.pi/skills/sce-change-to-plan/references/output.md @@ -66,7 +66,7 @@ This is chat output, not a file. Nothing here is written to the plan. ## Layout -``` +```markdown # Plan: {plan.name} Path: {plan.path} @@ -108,14 +108,14 @@ explicit `None.` confirms nothing is pending. When `assumptions` is empty: -``` +```markdown ## Assumptions - None. ``` When `open_questions` is absent: -``` +```markdown ## Open questions - None. ``` @@ -132,7 +132,7 @@ When `open_questions` is absent: ## Example -``` +```markdown # Plan: red-sce-banner Path: context/plans/red-sce-banner.md diff --git a/.pi/skills/sce-change-to-plan/references/plan-authoring.md b/.pi/skills/sce-change-to-plan/references/plan-authoring.md index fdd3abe7a..0f08f5a06 100644 --- a/.pi/skills/sce-change-to-plan/references/plan-authoring.md +++ b/.pi/skills/sce-change-to-plan/references/plan-authoring.md @@ -13,11 +13,10 @@ This phase owns the planning process: - Decide task boundaries, dependencies, and ordering. - Write or revise exactly one `context/plans/{plan_name}.md`. -`references/plan-template.md` is the sole owner of the persisted plan schema and -generic document-authoring rules: acceptance-criteria format and validation -semantics, task fields and atomic slicing, the no-validation-task rule, completion -records, and existing-plan update preservation. Read it before authoring or -revising and apply those rules rather than restating them here. +`references/plan-template.md` is the sole owner of the persisted plan schema. +Read its `Acceptance criteria rules`, `Task rules` and `No validation task` rules, +and `Updating an existing plan` rules before authoring or revising. Apply those +rules rather than restating them here. The workflow renders this phase's result as the summary defined in `references/output.md`. @@ -162,8 +161,7 @@ semantics and placement. Slice and order the plan-specific work after the acceptance criteria, applying the `Task rules` and `No validation task` rules in `references/plan-template.md`. -The template owns the task field shape, atomic-commit constraint, dependency-order -rule, acceptance-coverage rule, and generic task exclusions. +Do not restate those generic task rules here. A finished stack always leaves at least one incomplete task, so the workflow can always hand off to `/next-task`. When the request resolves to a plan but produces diff --git a/.pi/skills/sce-decision/SKILL.md b/.pi/skills/sce-decision/SKILL.md index 789d792ba..32b74fefe 100644 --- a/.pi/skills/sce-decision/SKILL.md +++ b/.pi/skills/sce-decision/SKILL.md @@ -10,7 +10,7 @@ description: > Write exactly one architecture decision record for one decision already qualified by successful task context synchronization. Return a deterministic internal -handoff to the invoking synchronization phase. Do not render an independent +result to the invoking synchronization phase. Do not render an independent user-visible response. ## Input @@ -25,7 +25,7 @@ synchronization. It must identify: - Related current-state context and existing ADR paths. - An optional requested status. -Do not accept raw workflow arguments, ordinary phase state, multiple decisions, +Do not accept raw workflow arguments, ordinary phase result, multiple decisions, or direct user invocation. Do not reconstruct missing material facts. ## Qualification handoff @@ -101,9 +101,9 @@ the filename, status, sections, and references satisfy this contract; every referenced repository path exists when practical to check; and no accepted ADR was modified. -### 6. Return internal state +### 6. Return the result -Return exactly one internal handoff: +Return exactly one internal result: - `written`: include `status`, `adr_path`, `decision`, `decision_status`, `created` (`true` for a new ADR and `false` for reuse), `supersedes`, and @@ -115,7 +115,7 @@ Return exactly one internal handoff: `required_action`. Use this only when decision writing cannot proceed safely. Use stable field names and repository-relative paths. Return no prose before or -after the handoff. The invoking synchronization phase owns all user-visible +after the result. The invoking synchronization phase owns all user-visible reporting. ## Boundaries diff --git a/.pi/skills/sce-next-task/references/context-sync.md b/.pi/skills/sce-next-task/references/context-sync.md index 6e6074dcf..807b83ffa 100644 --- a/.pi/skills/sce-next-task/references/context-sync.md +++ b/.pi/skills/sce-next-task/references/context-sync.md @@ -5,8 +5,8 @@ Run this phase for step 3 of the workflow, and only when task execution returned session inherits what this task established. It never touches code, tests, or plan state. -Input: either the complete `complete` result from the task execution phase -(same-session), passed verbatim, or the plan path and task ID a plan-review +Input: either the task execution result with `status: complete` +(same-session), passed unchanged, or the plan path and task ID a plan-review recovery step resolved for a completed task with unresolved context synchronization, together with that task's own completed record — read directly from the plan — and its persisted `Context synchronization blocker` when present (cross-session retry). Whichever was @@ -331,4 +331,4 @@ Do not: except `sce-decision`, or invoke `sce-decision` outside the decision gate in successful context synchronization. - Delete a context file that has uncommitted changes. -- Return an execution-style internal state. +- Return a task-execution internal result. diff --git a/.pi/skills/sce-next-task/references/output.md b/.pi/skills/sce-next-task/references/output.md index 40a66539f..c8a9bcbef 100644 --- a/.pi/skills/sce-next-task/references/output.md +++ b/.pi/skills/sce-next-task/references/output.md @@ -48,7 +48,7 @@ be synchronized before continuing. {completed-tasks} of {total-tasks} tasks complete. -Next up: +Next step: {next-task-id} — {next-task-title} diff --git a/.pi/skills/sce-next-task/references/plan-review.md b/.pi/skills/sce-next-task/references/plan-review.md index 41f6c55c6..ae6a97b66 100644 --- a/.pi/skills/sce-next-task/references/plan-review.md +++ b/.pi/skills/sce-next-task/references/plan-review.md @@ -109,14 +109,14 @@ Set internal status `blocked` when a missing decision materially affects: ## 1.5 Return the result -Set exactly one internal state: +Return one internal result with one of these statuses: - `ready` - `blocked` - `plan_complete` - `sync_debt` -Record only the internal state. Do not add explanatory prose before or after it. +Return only the internal result. Do not add explanatory prose before or after it. A `ready` result must identify: diff --git a/.pi/skills/sce-next-task/references/task-execution.md b/.pi/skills/sce-next-task/references/task-execution.md index 2c64dff2a..ad9ce6373 100644 --- a/.pi/skills/sce-next-task/references/task-execution.md +++ b/.pi/skills/sce-next-task/references/task-execution.md @@ -194,11 +194,11 @@ that decision after context synchronization. Before returning a `complete` result, verify that it satisfies the authoritative handoff contract above. -## 2.9 Return internal state +## 2.9 Return the result -After the phase reaches a terminal state, set exactly one internal state. +After the phase reaches a terminal state, return exactly one internal result. -Record only the internal state. Do not add explanatory prose before or after it. +Return only the internal result. Do not add explanatory prose before or after it. A `complete` result is the authoritative handoff into step 3. Pass it unchanged; step 3 must consume it instead of reconstructing its fields. diff --git a/.pi/skills/sce-validate/references/validation-report.md b/.pi/skills/sce-validate/references/validation-report.md index 2d5ed6218..b0fa7778b 100644 --- a/.pi/skills/sce-validate/references/validation-report.md +++ b/.pi/skills/sce-validate/references/validation-report.md @@ -67,6 +67,6 @@ After repairs, rerun: - When status is `failed`, always include **Retry** with the exact `/validate {plan path}` command. Omit **Retry** when status is `validated`. - Keep evidence concise and factual. Do not narrate the whole implementation - history or add execution-policy claims absent from the validation result. + history or add execution-policy claims absent from the validation report. - When a previous `## Validation Report` already exists, replace it with the new one rather than stacking duplicates. diff --git a/.pi/skills/sce-validate/references/validation.md b/.pi/skills/sce-validate/references/validation.md index 50895cc83..440f21d47 100644 --- a/.pi/skills/sce-validate/references/validation.md +++ b/.pi/skills/sce-validate/references/validation.md @@ -14,11 +14,11 @@ This phase owns: check. - Writing the Validation Report into the plan. - Marking acceptance criteria against the evidence. -- Returning one Markdown validation result. +- Returning one Markdown validation report. Return a result matching: -the **Validation Result** section below in this file +the **Validation report** section below in this file Write plan-file evidence matching: @@ -109,7 +109,7 @@ Return exactly one Markdown report: passed, and the Validation Report was written. - `failed` when evidence was captured but required checks or criteria remain unsatisfied. Shape it as a session handoff per - the **Validation Result** section below in this file, ending recommended work with + the **Validation report** section below in this file, ending recommended work with `/validate {plan path}`. - `blocked` when validation cannot proceed safely. @@ -140,7 +140,7 @@ The phase is complete after: - One plan was resolved, or resolution failed and was reported. - Implementation completeness was checked. - Validation ran to a terminal state, or a blocker prevented it. -- One valid Markdown report matching the **Validation Result** section below in this file was +- One valid Markdown report matching the **Validation report** section below in this file was returned. diff --git a/config/pkl/base/decision-skill.pkl b/config/pkl/base/decision-skill.pkl index af32ce7e5..2890eac29 100644 --- a/config/pkl/base/decision-skill.pkl +++ b/config/pkl/base/decision-skill.pkl @@ -20,7 +20,7 @@ description: > Write exactly one architecture decision record for one decision already qualified by successful task context synchronization. Return a deterministic internal -handoff to the invoking synchronization phase. Do not render an independent +result to the invoking synchronization phase. Do not render an independent user-visible response. ## Input @@ -35,7 +35,7 @@ synchronization. It must identify: - Related current-state context and existing ADR paths. - An optional requested status. -Do not accept raw workflow arguments, ordinary phase state, multiple decisions, +Do not accept raw workflow arguments, ordinary phase result, multiple decisions, or direct user invocation. Do not reconstruct missing material facts. ## Qualification handoff @@ -111,9 +111,9 @@ the filename, status, sections, and references satisfy this contract; every referenced repository path exists when practical to check; and no accepted ADR was modified. -### 6. Return internal state +### 6. Return the result -Return exactly one internal handoff: +Return exactly one internal result: - `written`: include `status`, `adr_path`, `decision`, `decision_status`, `created` (`true` for a new ADR and `false` for reuse), `supersedes`, and @@ -125,7 +125,7 @@ Return exactly one internal handoff: `required_action`. Use this only when decision writing cannot proceed safely. Use stable field names and repository-relative paths. Return no prose before or -after the handoff. The invoking synchronization phase owns all user-visible +after the result. The invoking synchronization phase owns all user-visible reporting. ## Boundaries diff --git a/config/pkl/base/workflow-change-to-plan.pkl b/config/pkl/base/workflow-change-to-plan.pkl index 5cae6b095..7f6988ce5 100644 --- a/config/pkl/base/workflow-change-to-plan.pkl +++ b/config/pkl/base/workflow-change-to-plan.pkl @@ -256,11 +256,10 @@ This phase owns the planning process: - Decide task boundaries, dependencies, and ordering. - Write or revise exactly one `context/plans/{plan_name}.md`. -`references/plan-template.md` is the sole owner of the persisted plan schema and -generic document-authoring rules: acceptance-criteria format and validation -semantics, task fields and atomic slicing, the no-validation-task rule, completion -records, and existing-plan update preservation. Read it before authoring or -revising and apply those rules rather than restating them here. +`references/plan-template.md` is the sole owner of the persisted plan schema. +Read its `Acceptance criteria rules`, `Task rules` and `No validation task` rules, +and `Updating an existing plan` rules before authoring or revising. Apply those +rules rather than restating them here. The workflow renders this phase's result as the summary defined in `references/output.md`. @@ -405,8 +404,7 @@ semantics and placement. Slice and order the plan-specific work after the acceptance criteria, applying the `Task rules` and `No validation task` rules in `references/plan-template.md`. -The template owns the task field shape, atomic-commit constraint, dependency-order -rule, acceptance-coverage rule, and generic task exclusions. +Do not restate those generic task rules here. A finished stack always leaves at least one incomplete task, so the workflow can always hand off to `/next-task`. When the request resolves to a plan but produces @@ -727,7 +725,7 @@ This is chat output, not a file. Nothing here is written to the plan. ## Layout -``` +```markdown # Plan: {plan.name} Path: {plan.path} @@ -769,14 +767,14 @@ explicit `None.` confirms nothing is pending. When `assumptions` is empty: -``` +```markdown ## Assumptions - None. ``` When `open_questions` is absent: -``` +```markdown ## Open questions - None. ``` @@ -793,7 +791,7 @@ When `open_questions` is absent: ## Example -``` +```markdown # Plan: red-sce-banner Path: context/plans/red-sce-banner.md diff --git a/config/pkl/base/workflow-context-sync.pkl b/config/pkl/base/workflow-context-sync.pkl index f694996d7..415636c20 100644 --- a/config/pkl/base/workflow-context-sync.pkl +++ b/config/pkl/base/workflow-context-sync.pkl @@ -1127,8 +1127,8 @@ Run this phase for step 3 of the workflow, and only when task execution returned session inherits what this task established. It never touches code, tests, or plan state. -Input: either the complete `complete` result from the task execution phase -(same-session), passed verbatim, or the plan path and task ID a plan-review +Input: either the task execution result with `status: complete` +(same-session), passed unchanged, or the plan path and task ID a plan-review recovery step resolved for a completed task with unresolved context synchronization, together with that task's own completed record — read directly from the plan — and its persisted `Context synchronization blocker` when present (cross-session retry). Whichever was @@ -1453,7 +1453,7 @@ Do not: except `sce-decision`, or invoke `sce-decision` outside the decision gate in successful context synchronization. - Delete a context file that has uncommitted changes. -- Return an execution-style internal state. +- Return a task-execution internal result. """ hidden taskSkillBody = new workflow.WorkflowBody { diff --git a/config/pkl/base/workflow-next-task.pkl b/config/pkl/base/workflow-next-task.pkl index b0a746a7a..b2169b861 100644 --- a/config/pkl/base/workflow-next-task.pkl +++ b/config/pkl/base/workflow-next-task.pkl @@ -190,7 +190,7 @@ local continuationLayouts = model.semanticReference.apply( {completed-tasks} of {total-tasks} tasks complete. - Next up: + Next step: {next-task-id} — {next-task-title} @@ -1568,14 +1568,14 @@ Set internal status `blocked` when a missing decision materially affects: ## 1.5 Return the result -Set exactly one internal state: +Return one internal result with one of these statuses: - `ready` - `blocked` - `plan_complete` - `sync_debt` -Record only the internal state. Do not add explanatory prose before or after it. +Return only the internal result. Do not add explanatory prose before or after it. A `ready` result must identify: @@ -1809,11 +1809,11 @@ that decision after context synchronization. Before returning a `complete` result, verify that it satisfies the authoritative handoff contract above. -## 2.9 Return internal state +## 2.9 Return the result -After the phase reaches a terminal state, set exactly one internal state. +After the phase reaches a terminal state, return exactly one internal result. -Record only the internal state. Do not add explanatory prose before or after it. +Return only the internal result. Do not add explanatory prose before or after it. A `complete` result is the authoritative handoff into step 3. Pass it unchanged; step 3 must consume it instead of reconstructing its fields. @@ -1888,7 +1888,7 @@ be synchronized before continuing. {completed-tasks} of {total-tasks} tasks complete. -Next up: +Next step: {next-task-id} — {next-task-title} diff --git a/config/pkl/base/workflow-validate.pkl b/config/pkl/base/workflow-validate.pkl index 8b2d3d813..e8b938ee2 100644 --- a/config/pkl/base/workflow-validate.pkl +++ b/config/pkl/base/workflow-validate.pkl @@ -6,8 +6,8 @@ local validationName = model.semanticReference.apply("sce-validation", "Validati /// Cited from inside `references/validation.md` itself, where the Validation /// Result contract is now appended below the phase steps. local validationResultSelfRef = model.semanticReference.apply( - "the **Validation Result** section below in this file", - "the **Validation Result** section below in this file" + "the **Validation report** section below in this file", + "the **Validation report** section below in this file" ) /// Cited from `references/validation-report.md`, a sibling file, so it must /// name `references/validation.md` explicitly rather than say "below". @@ -32,7 +32,7 @@ local reportVersusResult = model.semanticReference.apply( /// workflow uses the same emitted document, so the reference remains unchanged. local validationResultHandoff = model.semanticReference.apply( """ - The phase must return a Markdown report matching its validation result contract. + The phase must return a Markdown report matching its validation report contract. Branch on the report's `Status:`. """, "Branch on the report's `Status:`." @@ -41,7 +41,7 @@ local invoke = model.semanticReference.apply("Invoke", "Run") local invokedSkills = model.semanticReference.apply("invoked skills", "embedded phases") local invokedSkill = model.semanticReference.apply("invoked skill", "embedded phase") local markdownResult = model.semanticReference.apply("Markdown report", "internal state") -local returningValidationResult = model.semanticReference.apply("Returning one Markdown validation result", "Recording one Markdown validation result") +local returningValidationResult = model.semanticReference.apply("Returning one Markdown validation report", "Recording one Markdown validation report") local returnExactlyOneMarkdownResult = model.semanticReference.apply("Return exactly one Markdown report", "Set exactly one internal state") local returnOnlyMarkdownReport = model.semanticReference.apply("Return only the Markdown report", "Record only the Markdown report") local returnLower = model.semanticReference.apply("return", "set internal status") @@ -121,7 +121,7 @@ local renderCommandBody = (mode: model.WorkflowRenderMode) -> """ - Confirming every implementation task is complete. - Running full validation and acceptance-criteria checks. - Writing the Validation Report into the plan. - - Returning one Markdown validation result. + - Returning one Markdown validation report. Do not duplicate any of it. Do not write the Validation Report yourself. @@ -420,7 +420,7 @@ local renderValidationReport = (mode: model.WorkflowRenderMode) -> """ - When status is `failed`, always include **Retry** with the exact `/validate {plan path}` command. Omit **Retry** when status is `validated`. - Keep evidence concise and factual. Do not narrate the whole implementation - history or add execution-policy claims absent from the validation result. + history or add execution-policy claims absent from the validation report. - When a previous `## Validation Report` already exists, replace it with the new one rather than stacking duplicates. """ @@ -600,7 +600,7 @@ local VALIDATION_RESULT = renderValidationResult.apply("package") /// within this same file rather than at a separate `references/output.md`. local VALIDATION_REFERENCE = renderValidationSkillBody.apply("package") + "\n\n" + VALIDATION_RESULT -/// Composite-only user-visible layouts. The validation result contract lives +/// Composite-only user-visible layouts. The validation report contract lives /// in the validation reference, while this file carries the completion layout /// cited by the composite `SKILL.md`. local VALIDATE_OUTPUT_LAYOUTS = """ diff --git a/config/pkl/renderers/generation-contract-check.pkl b/config/pkl/renderers/generation-contract-check.pkl index a0556aec1..045228893 100644 --- a/config/pkl/renderers/generation-contract-check.pkl +++ b/config/pkl/renderers/generation-contract-check.pkl @@ -1224,12 +1224,18 @@ hidden assertWorkflowLanguageConsistency = (artifacts: Mapping) -> && planTemplate.contains("reports cleanup or repair work") && planTemplate.contains("it does not perform that work") && contextSync.contains("completed task with unresolved context synchronization") + && !next.contains("Next up:") + && !next.contains("Set exactly one internal state:") + && !next.contains("Record only the internal state") + && !validationRef.contains("Markdown result") + && !validationRef.contains("Validation Result") ) ) "workflow language: shared vocabulary, phase naming, report naming, and document format are consistent" else throw("generated workflow language/format drifted from the shared T11 conventions") contractChecks { ["workflow-language-consistency"] = assertWorkflowLanguageConsistency.apply(generatedArtifacts) + ["workflow-vocabulary-decision-result"] = if (generatedArtifacts["config/.pi/skills/sce-decision/SKILL.md"].contains("internal result") && !generatedArtifacts["config/.pi/skills/sce-decision/SKILL.md"].contains("Return internal state") && !generatedArtifacts["config/.pi/skills/sce-decision/SKILL.md"].contains("internal handoff")) "sce-decision: uses internal-result vocabulary" else throw("sce-decision vocabulary drifted from workflow-vocabulary.md") ["compact-execution-contracts"] = assertCompactExecutionContracts.apply(workflowDocuments) ["compact-execution-contract-negative-fixtures"] = assertCompactExecutionContractFixtures ["artifact-paths"] = assertExactArtifactPaths.apply(generatedArtifacts) diff --git a/context/context-map.md b/context/context-map.md index 253f11acf..1595d1de9 100644 --- a/context/context-map.md +++ b/context/context-map.md @@ -36,6 +36,7 @@ Feature/domain context: - [Context workflow rules](sce/context-workflow-rules.md) (canonical bootstrap, ongoing context maintenance, task synchronization, hygiene, discoverability, and feature-existence rules) - `context/sce/plan-code-overlap-map.md` (overlap matrix for thin OpenCode Plan/Code routing agents and six workflow packages, including task-only context synchronization ownership) - `context/sce/dedup-ownership-table.md` (canonical owner-vs-consumer boundaries for six workflow packages, canonical phase modules, the shared synchronization skeleton, and thin OpenCode agents) +- `context/sce/workflow-vocabulary.md` (canonical terminology, lifecycle language, verbs, and document-role conventions for SCE workflow and skill instructions) - [Atomic commit workflow](sce/atomic-commit-workflow.md) (`/commit` regular proposal-only mode vs `oneshot`/`skip` bypass mode, staged-truth and plan-citation rules, and the cross-target `sce-commit` package with package-local atomic procedure, message-style, and output references) - [Brownfield workflow](sce/brownfield-workflow.md) (`/brownfield`, the sixth canonical SCE workflow, generated for OpenCode, Claude, and Pi, and as a skill package with no command for Codex, from `config/pkl/base/workflow-brownfield.pkl`: the `[rebuild] [path ...]` argument contract, bootstrap gate, local-only evidence priority order with documentation sweep and three-month history floor, the `1`–`100` confidence model with its sub-`50` blocking clarification gate, always-disclosed contradiction handling, the additive-by-default writing contract whose sole rewrite path is `rebuild`, and its opt-in install status as the only optional workflow) - [Handover workflow](sce/handover-workflow.md) (`/handover`, the fifth canonical SCE workflow, generated for OpenCode, Claude, and Pi, and as a skill package with no command for Codex, from `config/pkl/base/workflow-handover.pkl`: dual writer/loader mode routing, the phase-free `sce-handover` package with a package-local persisted-format template and output layouts, active-task-or-timestamped writer naming, staged-plus-unstaged Git fact gathering, substantive four-section validation, concise writer success, and the read-only loader contract) diff --git a/context/plans/compress-workflow-execution-preamble.md b/context/plans/compress-workflow-execution-preamble.md index b7aacc885..a158b1497 100644 --- a/context/plans/compress-workflow-execution-preamble.md +++ b/context/plans/compress-workflow-execution-preamble.md @@ -456,8 +456,8 @@ The two additional root edits replace existing text without increasing line coun ## Follow-up: workflow language and document consistency - [x] T11: `Normalize workflow language and document format` (status:done) - - Scope: shared workflow vocabulary, embedded-phase/reference wording, output/report terminology, plan-authoring tone, handover persisted-document format, validation non-repairing wording, canonical Pkl, generated Pi/Claude/Codex mirrors, semantic generation checks, and ownership context. - - Vocabulary after change: command = user invocation; workflow = complete procedure; phase = embedded operation; step = numbered action; internal result = structured private phase data; report = formatted Markdown; completion record = persisted task evidence; handover document = persisted session handover. + - Scope: shared workflow vocabulary and its domain authority, embedded-phase/reference wording, output/report terminology, plan-authoring tone, handover persisted-document format, validation non-repairing wording, canonical Pkl, generated Pi/Claude/Codex mirrors, semantic generation checks, and ownership context. + - Vocabulary after change: `context/sce/workflow-vocabulary.md` is the single domain authority for command/workflow/skill/phase/step, internal-result/report/handoff terminology, lifecycle words, verbs, and document roles. - Format after change: embedded references identify themselves as phases rather than sibling skills; persisted-format references use a document title plus Template/contract/rules sections; output headings use consistent sentence-case punctuation; output and validation prose distinguish internal results from rendered reports. - Correctness fixes: `/validate` remains observational and reports cleanup/repair work instead of performing it; handover `Plan` and `Task` metadata are independently included only when known; context-sync recovery names completed tasks with unresolved synchronization; next-task calls the pre-validation terminal state `Implementation complete` rather than `Plan already complete`. - Behavior preserved: command names, argument tokens, status values, approval gates, phase order, write permissions, persisted plan/task field names, decision qualification, and lifecycle transitions remain unchanged. diff --git a/context/sce/dedup-ownership-table.md b/context/sce/dedup-ownership-table.md index fc474fc5c..a89c0df40 100644 --- a/context/sce/dedup-ownership-table.md +++ b/context/sce/dedup-ownership-table.md @@ -46,13 +46,6 @@ ## Workflow language conventions -- **Command** is the user-facing invocation such as `/next-task`. -- **Workflow** is the complete procedure owned by a generated workflow `SKILL.md`. -- **Phase** is an embedded operation such as plan review, task execution, or validation. -- **Step** is one numbered action inside a workflow or phase. -- **Internal result** is structured phase data that is not shown directly. Its discriminator is `status`. -- **Report** is formatted Markdown shown to the user or persisted as a report section. -- **Completion record** is execution evidence persisted on a completed task in its plan. -- **Handover document** is the persisted session document under `context/handovers/`. - -Use the verbs consistently: run a phase, return an internal result, render a report or layout, and write a persisted file. Preserve distinct lifecycle terms such as task `done`, execution `complete`, context `synced`, and plan `validated`; do not collapse them into one generic success term. +`workflow-vocabulary.md` is the sole authority for workflow and skill terminology, +lifecycle language, verbs, and document-role conventions. This ownership table +records behavior ownership only; do not duplicate the vocabulary here. diff --git a/context/sce/workflow-vocabulary.md b/context/sce/workflow-vocabulary.md new file mode 100644 index 000000000..5633322ab --- /dev/null +++ b/context/sce/workflow-vocabulary.md @@ -0,0 +1,89 @@ +# SCE workflow vocabulary + +This file is the canonical language guide for SCE workflow and skill instructions. +Use these terms consistently in canonical Pkl, generated workflow packages, and +workflow context. Do not create a second glossary for the same concepts. + +## Core terms + +- **Command** — a user-facing invocation such as `/next-task` or `/validate`. +- **Workflow** — the complete end-to-end procedure coordinated by a workflow + package's `SKILL.md`. +- **Skill** — an invokable instruction package. A workflow package is implemented + as a skill; `sce-decision` is an internal skill. Embedded phase references are + not skills. +- **Phase** — an embedded operation inside a workflow, such as plan review, task + execution, context synchronization, validation, or atomic commit analysis. +- **Step** — one numbered action inside a workflow or phase. +- **Reference** — a Markdown instruction, policy, format, or template file read by + a workflow, phase, or skill at a named boundary. +- **Internal result** — structured data returned to a caller and not rendered + directly to the user. `status` is its outcome discriminator. +- **Report** — formatted Markdown intended for a user or a persisted report + section. +- **Layout** — one named user-visible format in an output reference. +- **Handoff** — the act of passing an authoritative result or guidance to another + phase, skill, workflow step, or session. Do not use *handoff* as a second name + for every result object. +- **Completion record** — execution evidence persisted on a completed task in its + plan. +- **Handover document** — the persisted session-continuation document under + `context/handovers/`. + +## Verbs + +Use verbs according to the object they operate on: + +- **invoke** a skill or command; +- **run** a workflow or phase; +- **return** an internal result; +- **branch on** a result's `status`; +- **render** a report or named layout; +- **write** or **update** a persisted file; +- **pass** an authoritative result unchanged when the receiving contract requires + it. + +## Lifecycle vocabulary + +Keep lifecycle terms distinct because they describe different state domains: + +- a plan task is `done`; +- task execution returns `complete`; +- task context synchronization returns `synced` or `no_context_change`; +- final plan validation returns `validated`. + +When prose could be ambiguous, name the domain: *task execution is complete*, +*context synchronization is blocked*, or *plan validation failed*. Do not flatten +these into a generic *complete* or *success* state. + +## Instruction and output style + +- Use sentence-case headings without trailing punctuation. +- Use American English in workflow instructions and examples. +- Use **Next step** for user-visible continuation wording unless a persisted + schema owns a different heading. +- Call private structured phase data an **internal result**, not *internal state*. +- Call formatted validation and synchronization Markdown a **report**, not a + *result*. +- Keep user-visible output in the named layout or report that owns it. Do not add + wrapper prose around a rendered layout or report. +- Keep ownership rationale in workflow context such as + `dedup-ownership-table.md`; runtime instructions should say what to read or do, + not repeat a long list of everything another file owns. + +## Document roles + +Use document structure according to responsibility rather than forcing unrelated +files into one template: + +- **Workflow entrypoint:** execution contract, phase/reference routing, input, + workflow control flow, rules. +- **Phase reference:** phase title, purpose/input as needed, ordered procedure, + returned internal result or report, boundaries. +- **Output reference:** named user-visible layouts plus only the field-mapping or + rendering rules they require. +- **Persisted template/reference:** document title, template/schema, semantic or + completeness rules, and no workflow control flow. + +Specialized sections are allowed when they own a real contract, but equivalent +concepts must keep the vocabulary above.