diff --git a/.agents/skills/sce-change-to-plan/SKILL.md b/.agents/skills/sce-change-to-plan/SKILL.md index 9d33cd036..d7e569cb9 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 internal phase results private and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +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. ## 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-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..af24186bc 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} @@ -66,22 +66,22 @@ This is chat output, not a file. Nothing here is written to the plan. ## Layout -``` +```markdown # Plan: {plan.name} 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 @@ -108,15 +108,15 @@ explicit `None.` confirms nothing is pending. When `assumptions` is empty: -``` -## Assumptions: +```markdown +## Assumptions - None. ``` When `open_questions` is absent: -``` -## Open questions: +```markdown +## Open questions - None. ``` @@ -132,21 +132,21 @@ When `open_questions` is absent: ## Example -``` +```markdown # Plan: red-sce-banner 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 17e054e2d..0f08f5a06 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,18 @@ 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. +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`. @@ -27,7 +27,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*. @@ -48,8 +48,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 +152,16 @@ 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`. +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 @@ -187,20 +171,18 @@ 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 -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 @@ -208,29 +190,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 @@ -249,8 +215,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..fe0190b94 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. @@ -145,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 a5539c8c7..d48fa9c46 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 internal phase results private and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +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. ## 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: @@ -115,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`: @@ -131,30 +115,22 @@ 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 -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..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 @@ -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 @@ -146,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-decision/SKILL.md b/.agents/skills/sce-decision/SKILL.md index 543044c4d..32b74fefe 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 +result to the invoking synchronization phase. Do not render an independent +user-visible response. ## Input @@ -25,31 +25,25 @@ 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. -## 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 @@ -118,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 @@ -132,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-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-handover/SKILL.md b/.agents/skills/sce-handover/SKILL.md index 75d0cf72a..8c2827581 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 internal phase results private and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +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. ## Input @@ -87,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. @@ -112,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 @@ -137,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..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,12 +37,22 @@ enough to act on directly.} `None.`} ``` -### Rules +## Completeness contract + +- 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 + `{...}` 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. +- 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 f3bb55663..4eeae8510 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 internal phase results private and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +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`, +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: @@ -86,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`. @@ -96,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**. @@ -107,27 +92,20 @@ 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 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. @@ -142,12 +120,10 @@ 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**. - -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. +phase** with the task execution result whose `status` is `complete`. -Do not restate, summarize, or reconstruct any part of the execution result. +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 change's reported impact, so it is never correct to skip it as unnecessary. @@ -163,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 30ec3eaee..807b83ffa 100644 --- a/.agents/skills/sce-next-task/references/context-sync.md +++ b/.agents/skills/sce-next-task/references/context-sync.md @@ -5,23 +5,19 @@ 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 -recovery step resolved for a `blocked` task, together with that task's own +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 -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 @@ -96,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 +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. @@ -175,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: @@ -345,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 b6e772bde..c8a9bcbef 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 ------------------------------------- @@ -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} @@ -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/plan-review.md b/.agents/skills/sce-next-task/references/plan-review.md index 89e378f36..ae6a97b66 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. @@ -108,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: @@ -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/.agents/skills/sce-next-task/references/task-execution.md b/.agents/skills/sce-next-task/references/task-execution.md index fe01b5304..ad9ce6373 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 @@ -208,24 +191,17 @@ 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. -## 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, 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/.agents/skills/sce-validate/SKILL.md b/.agents/skills/sce-validate/SKILL.md index df04f10df..862f03953 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 internal phase results private and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +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. ## 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. @@ -65,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-report.md b/.agents/skills/sce-validate/references/validation-report.md index 3121e1a48..b0fa7778b 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 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 1816eacaa..440f21d47 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 @@ -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: @@ -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,15 +101,15 @@ 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. - `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. @@ -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 report** 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 @@ -301,10 +300,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-change-to-plan/SKILL.md b/.claude/skills/sce-change-to-plan/SKILL.md index 36744080d..6a049f92f 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 internal phase results private and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +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. ## 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-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..af24186bc 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} @@ -66,22 +66,22 @@ This is chat output, not a file. Nothing here is written to the plan. ## Layout -``` +```markdown # Plan: {plan.name} 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 @@ -108,15 +108,15 @@ explicit `None.` confirms nothing is pending. When `assumptions` is empty: -``` -## Assumptions: +```markdown +## Assumptions - None. ``` When `open_questions` is absent: -``` -## Open questions: +```markdown +## Open questions - None. ``` @@ -132,21 +132,21 @@ When `open_questions` is absent: ## Example -``` +```markdown # Plan: red-sce-banner 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 17e054e2d..0f08f5a06 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,18 @@ 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. +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`. @@ -27,7 +27,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*. @@ -48,8 +48,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 +152,16 @@ 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`. +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 @@ -187,20 +171,18 @@ 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 -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 @@ -208,29 +190,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 @@ -249,8 +215,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..fe0190b94 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. @@ -145,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 2987bef14..5fe9ef0f5 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 internal phase results private and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +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. ## 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: @@ -114,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`: @@ -130,30 +114,22 @@ 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 -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..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 @@ -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 @@ -146,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-decision/SKILL.md b/.claude/skills/sce-decision/SKILL.md index 8b5d378ef..d75d761fb 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 +result to the invoking synchronization phase. Do not render an independent +user-visible response. ## Input @@ -26,31 +26,25 @@ 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. -## 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 @@ -119,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 @@ -133,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-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-handover/SKILL.md b/.claude/skills/sce-handover/SKILL.md index e9e3d6013..1e04509d8 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 internal phase results private and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +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. ## Input @@ -86,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. @@ -111,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 @@ -136,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..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,12 +37,22 @@ enough to act on directly.} `None.`} ``` -### Rules +## Completeness contract + +- 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 + `{...}` 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. +- 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 5c96a865a..ad4da900f 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 internal phase results private and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +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`, +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: @@ -85,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`. @@ -95,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**. @@ -106,27 +91,20 @@ 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 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. @@ -141,12 +119,10 @@ 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**. - -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. +phase** with the task execution result whose `status` is `complete`. -Do not restate, summarize, or reconstruct any part of the execution result. +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 change's reported impact, so it is never correct to skip it as unnecessary. @@ -162,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 30ec3eaee..807b83ffa 100644 --- a/.claude/skills/sce-next-task/references/context-sync.md +++ b/.claude/skills/sce-next-task/references/context-sync.md @@ -5,23 +5,19 @@ 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 -recovery step resolved for a `blocked` task, together with that task's own +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 -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 @@ -96,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 +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. @@ -175,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: @@ -345,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 b6e772bde..c8a9bcbef 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 ------------------------------------- @@ -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} @@ -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/plan-review.md b/.claude/skills/sce-next-task/references/plan-review.md index 89e378f36..ae6a97b66 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. @@ -108,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: @@ -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/references/task-execution.md b/.claude/skills/sce-next-task/references/task-execution.md index fe01b5304..ad9ce6373 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 @@ -208,24 +191,17 @@ 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. -## 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, 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-validate/SKILL.md b/.claude/skills/sce-validate/SKILL.md index 5d45fbb26..9f874f37c 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 internal phase results private and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +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. ## 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. @@ -66,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-report.md b/.claude/skills/sce-validate/references/validation-report.md index 3121e1a48..b0fa7778b 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 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 1816eacaa..440f21d47 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 @@ -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: @@ -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,15 +101,15 @@ 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. - `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. @@ -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 report** 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 @@ -301,10 +300,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-change-to-plan/SKILL.md b/.pi/skills/sce-change-to-plan/SKILL.md index 5a97185fc..4ce057d98 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 internal phase results private and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +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. ## 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-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..af24186bc 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} @@ -66,22 +66,22 @@ This is chat output, not a file. Nothing here is written to the plan. ## Layout -``` +```markdown # Plan: {plan.name} 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 @@ -108,15 +108,15 @@ explicit `None.` confirms nothing is pending. When `assumptions` is empty: -``` -## Assumptions: +```markdown +## Assumptions - None. ``` When `open_questions` is absent: -``` -## Open questions: +```markdown +## Open questions - None. ``` @@ -132,21 +132,21 @@ When `open_questions` is absent: ## Example -``` +```markdown # Plan: red-sce-banner 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 17e054e2d..0f08f5a06 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,18 @@ 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. +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`. @@ -27,7 +27,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*. @@ -48,8 +48,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 +152,16 @@ 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`. +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 @@ -187,20 +171,18 @@ 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 -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 @@ -208,29 +190,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 @@ -249,8 +215,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..fe0190b94 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. @@ -145,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 262b2a35a..0123adeae 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 internal phase results private and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +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. ## 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: @@ -113,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`: @@ -129,30 +113,22 @@ 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 -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..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 @@ -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 @@ -146,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-decision/SKILL.md b/.pi/skills/sce-decision/SKILL.md index 543044c4d..32b74fefe 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 +result to the invoking synchronization phase. Do not render an independent +user-visible response. ## Input @@ -25,31 +25,25 @@ 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. -## 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 @@ -118,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 @@ -132,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-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-handover/SKILL.md b/.pi/skills/sce-handover/SKILL.md index 8e5d325ed..f986feda3 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 internal phase results private and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +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. ## Input @@ -85,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. @@ -110,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 @@ -135,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..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,12 +37,22 @@ enough to act on directly.} `None.`} ``` -### Rules +## Completeness contract + +- 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 + `{...}` 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. +- 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 e4b4a3d2f..8d51c3aeb 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 internal phase results private and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +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`, +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: @@ -84,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`. @@ -94,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**. @@ -105,27 +90,20 @@ 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 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. @@ -140,12 +118,10 @@ 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**. - -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. +phase** with the task execution result whose `status` is `complete`. -Do not restate, summarize, or reconstruct any part of the execution result. +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 change's reported impact, so it is never correct to skip it as unnecessary. @@ -161,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 30ec3eaee..807b83ffa 100644 --- a/.pi/skills/sce-next-task/references/context-sync.md +++ b/.pi/skills/sce-next-task/references/context-sync.md @@ -5,23 +5,19 @@ 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 -recovery step resolved for a `blocked` task, together with that task's own +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 -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 @@ -96,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 +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. @@ -175,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: @@ -345,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 b6e772bde..c8a9bcbef 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 ------------------------------------- @@ -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} @@ -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/plan-review.md b/.pi/skills/sce-next-task/references/plan-review.md index 89e378f36..ae6a97b66 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. @@ -108,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: @@ -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/references/task-execution.md b/.pi/skills/sce-next-task/references/task-execution.md index fe01b5304..ad9ce6373 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 @@ -208,24 +191,17 @@ 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. -## 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, 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-validate/SKILL.md b/.pi/skills/sce-validate/SKILL.md index b8c3864e7..4dc14c48c 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 internal phase results private and continue immediately until a defined wait or stop. +Resume user waits in this same skill and session. +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. ## 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. @@ -65,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-report.md b/.pi/skills/sce-validate/references/validation-report.md index 3121e1a48..b0fa7778b 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 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 1816eacaa..440f21d47 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 @@ -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: @@ -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,15 +101,15 @@ 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. - `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. @@ -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 report** 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 @@ -301,10 +300,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/decision-skill.pkl b/config/pkl/base/decision-skill.pkl index a18192a8f..2890eac29 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 +result to the invoking synchronization phase. Do not render an independent +user-visible response. ## Input @@ -35,31 +35,25 @@ 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. -## 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 @@ -128,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 @@ -142,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 @@ -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-change-to-plan.pkl b/config/pkl/base/workflow-change-to-plan.pkl index 501af0b64..7f6988ce5 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. @@ -233,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` @@ -241,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,18 +248,18 @@ 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: - -- 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`. +This phase owns the planning process: -Do not duplicate any of it elsewhere in the workflow. +- 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`. -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. +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`. @@ -293,7 +270,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*. @@ -314,8 +291,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. @@ -417,33 +395,16 @@ 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`. +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 @@ -453,20 +414,18 @@ 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 -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 @@ -474,29 +433,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 @@ -515,8 +458,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. @@ -656,6 +598,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. @@ -672,9 +615,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 @@ -764,7 +707,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} @@ -782,22 +725,22 @@ This is chat output, not a file. Nothing here is written to the plan. ## Layout -``` +```markdown # Plan: {plan.name} 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} ``` @@ -809,13 +752,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 @@ -824,15 +767,15 @@ explicit `None.` confirms nothing is pending. When `assumptions` is empty: -``` -## Assumptions: +```markdown +## Assumptions - None. ``` When `open_questions` is absent: -``` -## Open questions: +```markdown +## Open questions - None. ``` @@ -848,22 +791,22 @@ When `open_questions` is absent: ## Example -``` +```markdown # Plan: red-sce-banner 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. ``` """ @@ -1014,7 +957,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} @@ -1525,7 +1468,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*. @@ -2244,17 +2187,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} ``` @@ -2266,13 +2209,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 @@ -2282,14 +2225,14 @@ local PLAN_SUMMARY = """ When `assumptions` is empty: ``` - ## Assumptions: + ## Assumptions - None. ``` When `open_questions` is absent: ``` - ## Open questions: + ## Open questions - None. ``` @@ -2310,17 +2253,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 8240845da..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,28 +197,19 @@ 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 - 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 @@ -254,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 @@ -264,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 @@ -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 @@ -400,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. @@ -479,13 +471,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 +484,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: @@ -583,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`: @@ -599,30 +568,22 @@ 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 -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/base/workflow-content.pkl b/config/pkl/base/workflow-content.pkl index ec2970a70..cff15cbb6 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 internal phase results private and continue immediately until a defined wait or stop. + Resume user waits in this same skill and session. + 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") + """ + 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: @@ -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`. @@ -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**. @@ -307,27 +307,20 @@ 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 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. @@ -342,12 +335,10 @@ 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**. - -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. +phase** with the task execution result whose `status` is `complete`. -Do not restate, summarize, or reconstruct any part of the execution result. +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 change's reported impact, so it is never correct to skip it as unnecessary. @@ -363,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 @@ -398,13 +389,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 +407,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. @@ -454,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 f75a5dfb4..415636c20 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 qualification + 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: @@ -152,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: @@ -244,15 +248,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 +589,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. @@ -1131,23 +1127,19 @@ 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 -recovery step resolved for a `blocked` task, together with that task's own +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 -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 +1149,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 @@ -1222,15 +1204,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. @@ -1301,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: @@ -1471,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-handover.pkl b/config/pkl/base/workflow-handover.pkl index c6fc18fa1..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,12 +82,22 @@ local renderPersistedFormatBody = """ `None.`} ``` - ### Rules + ## Completeness contract + + - 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 + `{...}` 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. + - 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 @@ -144,18 +156,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 +173,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 +198,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. + 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 any required section is missing, empty, or placeholder-only, render the - **Loader blocked** layout (invalid handover) and stop. + When that contract fails, render the **Loader blocked** layout (invalid handover) + and stop. #### 3. Present for continuation @@ -333,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 43153aca7..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} @@ -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")) @@ -1017,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")) @@ -1474,17 +1450,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") @@ -1526,11 +1493,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. @@ -1600,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: @@ -1621,6 +1589,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. @@ -1652,15 +1621,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 +1669,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 @@ -1854,24 +1806,17 @@ 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. -## 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, 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 @@ -1903,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 ------------------------------------- @@ -1943,7 +1888,7 @@ be synchronized before continuing. {completed-tasks} of {total-tasks} tasks complete. -Next up: +Next step: {next-task-id} — {next-task-title} @@ -2022,17 +1967,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/config/pkl/base/workflow-validate.pkl b/config/pkl/base/workflow-validate.pkl index 75d0ba3e8..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". @@ -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 report 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 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 markdownResult = model.semanticReference.apply("Markdown report", "internal state") +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") 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 @@ -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. @@ -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. @@ -360,6 +359,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 +408,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 report. - When a previous `## Validation Report` already exists, replace it with the new one rather than stacking duplicates. """ @@ -433,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. @@ -446,7 +441,7 @@ local renderValidationResult = (mode: model.WorkflowRenderMode) -> """ \(reportVersusResult.render.apply(mode)) - ## Validated variant + ## Validated report # Validation Report @@ -477,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 @@ -541,7 +536,7 @@ local renderValidationResult = (mode: model.WorkflowRenderMode) -> """ --- - ## Blocked variant + ## Blocked report # Validation blocked @@ -586,10 +581,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 @@ -607,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 bb8dc1038..045228893 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,20 +240,156 @@ 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**" "### 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 **Template** 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" +} + +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 internal phase results private and continue immediately until a defined wait or stop. + Resume user waits in this same skill and session. + 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) + """ + 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 internal phase results private and continue immediately until a defined wait or stop." + "Resume user waits in this same skill and session." + "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." +} + +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" @@ -318,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" @@ -442,7 +565,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 +577,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)) ) ) @@ -495,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 @@ -504,6 +667,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 @@ -647,6 +824,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) -> @@ -750,6 +957,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`" @@ -773,6 +1011,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) -> @@ -807,20 +1046,54 @@ 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) -> !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) -> @@ -851,6 +1124,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 normal work session outside this phase" + "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" @@ -882,7 +1198,46 @@ 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") + && !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) ["codex-hook-invocation"] = assertCodexHookInvocationContract.apply(generatedArtifacts) ["codex-skills-exclude-arguments"] = assertCodexSkillsExcludeArguments.apply(generatedArtifacts) @@ -908,7 +1263,9 @@ 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) ["no-blank-line-runs"] = assertNoBlankLineRuns.apply(workflowDocuments) ["output-dedup"] = assertOutputNotDuplicated.apply(workflowDocuments) @@ -917,17 +1274,21 @@ 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) ["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) + ["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) + ["validation-report-policy-ownership"] = assertValidationReportPolicyOwnership.apply(workflowDocuments) ["validation-observational"] = assertValidationIsObservational.apply(workflowDocuments) ["validate-decision-sync-boundary"] = assertValidateExcludesDecisionAndPlanSync.apply(workflowDocuments) } 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/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/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..a158b1497 --- /dev/null +++ b/context/plans/compress-workflow-execution-preamble.md @@ -0,0 +1,465 @@ +# 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 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 + +- [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. + +## 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. + + +## 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. + + +## 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. + + +## 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. + + +## 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. + + +## 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. + + +## 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. + + +## 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. + + +## 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. + +## Follow-up: workflow language and document consistency + +- [x] T11: `Normalize workflow language and document format` (status:done) + - 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. + - 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 32a940d98..a89c0df40 100644 --- a/context/sce/dedup-ownership-table.md +++ b/context/sce/dedup-ownership-table.md @@ -15,15 +15,25 @@ | 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`; 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 | +| 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 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 | +| 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 @@ -33,3 +43,9 @@ - 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 + +`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/handover-workflow.md b/context/sce/handover-workflow.md index dfda906c9..25f1d22aa 100644 --- a/context/sce/handover-workflow.md +++ b/context/sce/handover-workflow.md @@ -19,14 +19,15 @@ 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. - -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 +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 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. 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.