diff --git a/.claude/skills/sce-brownfield/SKILL.md b/.claude/skills/sce-brownfield/SKILL.md index d82518da..cd589a10 100644 --- a/.claude/skills/sce-brownfield/SKILL.md +++ b/.claude/skills/sce-brownfield/SKILL.md @@ -11,8 +11,8 @@ compatibility: claude 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command. Follow the canonical workflow's steps, gates, +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 @@ -30,6 +30,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume 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. + This workflow reconstructs durable `context/` memory for a repository that has none, or that has gaps. It is a cold-start and gap-fill tool, not a recurring context-maintenance or drift-repair command. Ongoing maintenance stays owned by @@ -328,7 +333,7 @@ gaps, and the audit outcome. Stop. - Never write a fact scoring below `50` as truth. - Never resolve a material contradiction without disclosing it. - Never write a confidence score, hash, timestamp, or date under `context/`. -- Never invoke another skill, sibling package, or workflow command. +- Never invoke another SCE skill, sibling SCE package, or SCE workflow command. - Never synchronize context, validate a plan, select or execute a task, or create a Git commit. - Never treat this workflow as recurring context maintenance. diff --git a/.claude/skills/sce-change-to-plan/SKILL.md b/.claude/skills/sce-change-to-plan/SKILL.md index 7fbc8c03..fe97c838 100644 --- a/.claude/skills/sce-change-to-plan/SKILL.md +++ b/.claude/skills/sce-change-to-plan/SKILL.md @@ -11,8 +11,8 @@ compatibility: claude 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command. Follow the canonical workflow's steps, gates, +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. ## Phase references @@ -49,6 +49,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume this same skill in the same session. Never expose an internal phase result as the workflow's final response. +Relevant non-SCE skills may be used as helper capabilities during the active step. +They are not workflow handoffs: when a helper returns, control returns to the active +step. Helper use must preserve the canonical phase order, gates, waits, writes, +validation, stops, and terminal user-visible output. + ## Input `$ARGUMENTS` is the change request, in free-form prose. diff --git a/.claude/skills/sce-commit/SKILL.md b/.claude/skills/sce-commit/SKILL.md index c8dd2fa5..bfbc2b9d 100644 --- a/.claude/skills/sce-commit/SKILL.md +++ b/.claude/skills/sce-commit/SKILL.md @@ -11,8 +11,8 @@ compatibility: claude 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command. Follow the canonical workflow's steps, gates, +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. ## Phase reference @@ -41,6 +41,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume this same skill in the same session. Never expose an internal phase result as the workflow's final response. +Relevant non-SCE skills may be used as helper capabilities during the active step. +They are not workflow handoffs: when a helper returns, control returns to the active +step. Helper use must preserve the canonical phase order, gates, waits, writes, +validation, stops, and terminal user-visible output. + ## Input `$ARGUMENTS` is optional. Split it into two parts before invoking the skill: diff --git a/.claude/skills/sce-commit/references/atomic-commit.md b/.claude/skills/sce-commit/references/atomic-commit.md index ecdeb3bd..a2404c4c 100644 --- a/.claude/skills/sce-commit/references/atomic-commit.md +++ b/.claude/skills/sce-commit/references/atomic-commit.md @@ -1,78 +1,83 @@ -# Atomic commit phase +# SCE Atomic Commit -Both workflow paths run this phase. The regular path runs it with `mode: regular` -after the staging gate; the bypass path runs it with `mode: bypass` after -confirming staged content exists. +## Purpose -Input: the mode, supplied by the workflow from an explicit user-supplied token, -and the commit context. +Turn the current staged changes into atomic repository-style commit messages. -This phase exclusively owns: +Write messages matching: -- Reading and analyzing the staged diff. -- Deciding whether staged changes form one coherent unit or several. -- Classifying staged scope and applying context-file guidance gating. -- Writing every commit message subject and body. -- Applying the plan-citation body rule. +`references/commit-message-style.md` -Do not duplicate any of it elsewhere in the workflow. Do not write commit messages -outside this phase. +Return a result matching: -Never infer the mode, and never switch modes mid-analysis. +`references/commit-contract.yaml` -Commit context refines wording only. The staged diff decides what the change is; -context never overrides staged truth, and never adds a claim the diff does not -support. +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 +`git commit`. + +## Input + +A mode (`regular` or `bypass`) and optional commit context, in free-form prose. + +The mode is supplied by the workflow from an explicit user-supplied token. +Never infer it, and never switch modes mid-analysis. + +Commit context refines wording only. The staged diff decides what the change +is; context never overrides staged truth, and never adds a claim the diff does +not support. Do not accept an unstaged diff, a working-tree summary, or a conversational description as a substitute for the staged diff. -## 1. Read the staged diff +## Workflow + +### 1. Read the staged diff Read the staged changes with `git diff --cached`, and the staged file list with `git diff --cached --name-status`. Read staged file contents only when the diff alone does not explain the change. -Set internal status `blocked` when nothing is staged. +Return `blocked` when nothing is staged. -## 2. Identify coherent units +### 2. Identify coherent units Infer the main reason for the staged change from the diff first. A coherent unit is one goal a reviewer would accept as a single commit. Group staged files by that goal, not by directory. -In `bypass` mode, stop grouping here: the result is exactly one message covering -all staged files, whether or not the diff is coherent. Do not propose splits, and -do not report split guidance. +In `bypass` mode, stop grouping here: the result is exactly one message +covering all staged files, whether or not the diff is coherent. Do not propose +splits, and do not report split guidance. -## 3. Choose a scope for each unit +### 3. Choose a scope for each unit Use the smallest stable subsystem or module name recognizable in the repository. When no such name applies, use the primary directory or package of the unit's changes. -## 4. Write each message +### 4. Write each message -Follow `references/output.md` for the subject pattern, the body rules, issue -references, the plan-citation rule, and the anti-patterns. +Follow `references/commit-message-style.md` for the subject pattern, the body +rules, issue references, the plan-citation rule, and the anti-patterns. -## 5. Apply the plan-citation rule +### 5. Apply the plan-citation rule -When the unit's staged files include `context/plans/*.md`, cite the affected plan -slug and updated task IDs in the body. +When the unit's staged files include `context/plans/*.md`, cite the affected +plan slug and updated task IDs in the body. When the staged plan diff does not expose the slug or task ID clearly enough to cite faithfully: -- In `regular` mode, set internal status `blocked` and ask for the reference to be - stated or staged explicitly. +- In `regular` mode, return `blocked` and ask for the reference to be stated or + staged explicitly. - In `bypass` mode, infer the citation when the diff supports it, and otherwise omit it. Never stop, and never invent a slug or task ID. -## 6. Apply context-file guidance gating +### 6. Apply context-file guidance gating This step applies in `regular` mode only. Skip it entirely in `bypass` mode; do not classify staged scope there. @@ -80,10 +85,10 @@ not classify staged scope there. Classify the staged diff: - Context-only (`context/**`): context-file-focused guidance is allowed. -- Mixed (`context/**` plus non-`context/**`): suppress default context-file commit - reminders and give guidance that reflects the full staged scope. +- Mixed (`context/**` plus non-`context/**`): suppress default context-file + commit reminders and give guidance that reflects the full staged scope. -## 7. Propose split guidance +### 7. Propose split guidance This step applies in `regular` mode only. @@ -91,10 +96,10 @@ When the units found in step 2 pursue unrelated goals, return one message per unit, and state why the split is recommended and which staged files belong to each. -When the staged changes form one unit, return one message and no split guidance. -Do not split coherent work to appear thorough. +When the staged changes form one unit, return one message and no split +guidance. Do not split coherent work to appear thorough. -## 8. Validate the result +### 8. Validate the result Confirm before returning that: @@ -103,15 +108,15 @@ Confirm before returning that: - No plan slug or task ID appears that the staged diff does not support. - The mode's own constraints hold. -## 9. Return internal state +### 9. Return YAML -Set exactly one internal state: +Return exactly one YAML document matching `references/commit-contract.yaml`: - `proposal` in `regular` mode, with one or more messages. - `bypass_message` in `bypass` mode, with exactly one message. - `blocked` when messages cannot be written faithfully. -Record only the internal state. Do not add explanatory prose before or after it. +Return only the YAML document. Do not add explanatory prose before or after it. ## Atomic commit boundaries @@ -128,3 +133,13 @@ Do not: - Mention `context/` synchronization activity in a commit message. - Claim a message was committed. - Run plan, task, or validation workflows. +## Completion + +The skill 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. +- One valid terminal YAML result matching `references/commit-contract.yaml` was + returned. + + diff --git a/.claude/skills/sce-commit/references/output.md b/.claude/skills/sce-commit/references/output.md index fb62021a..9fdbaddc 100644 --- a/.claude/skills/sce-commit/references/output.md +++ b/.claude/skills/sce-commit/references/output.md @@ -36,67 +36,3 @@ Committed {commit-hash} ## Bypass Git failure Present Git's failure unchanged and stop without retrying. - -# Commit message style - -The wording rules for every message the **Atomic commit phase** returns, in either -mode. This file is the only authority for message content and shape. - -Messages are carried in the result's `message` field, subject first, then one -blank line, then the body. - -## Subject - -Pattern: - -`: ` - -- Scope is the smallest stable subsystem or module name recognizable in the - repository. When no such name applies, use the primary directory or package - of the change. -- Start the summary with an imperative verb: Fix, Add, Remove, Implement, - Refactor, Simplify, Rename, Update, Ensure, Allow. -- Capitalize the verb. Do not end the subject with a period. -- Keep it concrete and technical. Name what changed, not how it felt. - -## Body - -Include a body whenever the subject alone leaves the change unexplained. Omit -it for changes whose subject is self-evident. - -A body says what was wrong or missing, why it mattered, what changed -conceptually, and the impact. It does not restate the subject in longer words, -and it does not narrate the editing process. - -Wrap the body at a readable width and separate paragraphs with a blank line. - -## Issue references - -Put each issue reference on its own line at the end of the body, for example -`Fixes #123`. - -Reference only issues the staged diff or the supplied commit context names. Do -not infer an issue number from a branch name. - -## Plan citations - -When a commit's staged files include `context/plans/*.md`, the body must also -cite: - -- The affected plan slug. -- Every updated task ID (`T0X`). - -Cite only what the staged plan diff shows. When the diff does not expose the -slug or task IDs clearly enough to cite faithfully, the skill's mode decides -what happens — the ambiguity is not resolved here by guessing. - -## Anti-patterns - -- Vague subjects: "cleanup", "updates", "various fixes". -- A body that repeats the subject without adding why or impact. -- Playful tone in a fix, security change, or architectural change. -- Mentioning `context/` synchronization activity. -- Inventing plan slugs, task IDs, or issue references. -- Splitting changes that already form one coherent unit. -- Forcing unrelated goals into a single commit. -- Describing intent the staged diff does not support. diff --git a/.claude/skills/sce-handover/SKILL.md b/.claude/skills/sce-handover/SKILL.md index d5240687..8ce56bb8 100644 --- a/.claude/skills/sce-handover/SKILL.md +++ b/.claude/skills/sce-handover/SKILL.md @@ -11,8 +11,8 @@ compatibility: claude 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command. Follow the canonical workflow's steps, gates, +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 @@ -30,6 +30,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume 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 and selects the mode: @@ -154,7 +159,7 @@ guidance is the entire loader contract. one handover document it writes. - Loader mode never edits a file, writes a new file, or changes plan or task state. -- Never invoke another skill, sibling package, or workflow command. +- Never invoke another SCE skill, sibling SCE package, or SCE workflow command. - Never treat a file outside `context/handovers/`, or a non-Markdown file, as a loadable handover. - Never create the `context/` root; `sce setup --bootstrap-context` owns that. diff --git a/.claude/skills/sce-next-task/SKILL.md b/.claude/skills/sce-next-task/SKILL.md index e510892c..85450eef 100644 --- a/.claude/skills/sce-next-task/SKILL.md +++ b/.claude/skills/sce-next-task/SKILL.md @@ -11,9 +11,9 @@ compatibility: claude 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command except `sce-decision`, and invoke `sce-decision` only from the -successful context-synchronization decision gate. Follow the canonical workflow's steps, gates, +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. ## Phase references @@ -50,6 +50,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume this same skill in the same session. Never expose an internal phase result as the workflow's final response. +Relevant non-SCE skills may be used as helper capabilities during the active step. +They are not workflow handoffs: when a helper returns, control returns to the active +step. Helper use must preserve the canonical phase order, gates, waits, writes, +validation, stops, and terminal user-visible output. + ## Input Parse `$ARGUMENTS` into three positional parts before invoking any phase: diff --git a/.claude/skills/sce-next-task/references/context-sync.md b/.claude/skills/sce-next-task/references/context-sync.md index 06413b09..3c5cb8b4 100644 --- a/.claude/skills/sce-next-task/references/context-sync.md +++ b/.claude/skills/sce-next-task/references/context-sync.md @@ -310,7 +310,8 @@ Do not: - Create the context root. `sce setup --bootstrap-context` owns that. - Narrate changed files as documentation. Feature existence is the only reason to document a change that introduced no other durable knowledge. -- Invoke any sibling skill except `sce-decision`, or invoke `sce-decision` - outside the decision gate in successful context synchronization. +- Invoke any sibling SCE skill, sibling SCE package, or SCE workflow command + 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. diff --git a/.claude/skills/sce-validate/SKILL.md b/.claude/skills/sce-validate/SKILL.md index 0ee099f0..95d91248 100644 --- a/.claude/skills/sce-validate/SKILL.md +++ b/.claude/skills/sce-validate/SKILL.md @@ -11,9 +11,9 @@ compatibility: claude 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command except `sce-decision`, and invoke `sce-decision` only from the -successful context-synchronization decision gate. Follow the canonical workflow's steps, gates, +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. ## Phase references @@ -50,6 +50,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume this same skill in the same session. Never expose an internal phase result as the workflow's final response. +Relevant non-SCE skills may be used as helper capabilities during the active step. +They are not workflow handoffs: when a helper returns, control returns to the active +step. Helper use must preserve the canonical phase order, gates, waits, writes, +validation, stops, and terminal user-visible output. + ## Input `$ARGUMENTS` is the plan name or plan path. diff --git a/.claude/skills/sce-validate/references/context-sync.md b/.claude/skills/sce-validate/references/context-sync.md index d6a45d46..bdd0c223 100644 --- a/.claude/skills/sce-validate/references/context-sync.md +++ b/.claude/skills/sce-validate/references/context-sync.md @@ -1,21 +1,39 @@ -# Plan context synchronization phase +# SCE Plan Context Sync -Run this phase for step 2 of the workflow, and only with a `Status: validated` -Markdown result from the validation phase. It is the plan-level final context -pass: it starts from the plan's `Context sync` requirements and the validated -implementation, and closes gaps that remain after any task-level syncs already -ran. +## Purpose -Do not run this phase for `failed` or `blocked`. Those are not success states. -Same rule as the task context synchronization phase: context sync runs only after -a successful prior phase. +Reconcile one fully validated plan with the repository's durable context and +return a Markdown report. -Pass the validated result verbatim. It is the authoritative handoff, and this -phase owns reading the plan path, required context paths, validation evidence, -and reported context impact out of it. +This phase owns: -Do not restate, summarize, or reconstruct any part of the validation result. Do -not reconstruct a missing validation result from conversation history. +- Validating the validation handoff. +- Confirming the context root exists. +- Discovering the context required by the finished plan. +- Deciding whether durable context changed. +- Editing and verifying the affected context files. +- Returning one Markdown synchronization report. + +Use the report format in: + +`references/sync-report.md` + +Task-level context sync may already have run after individual tasks. This phase +is the plan-level final pass: it starts from the plan's `Context sync` +requirements and the validated implementation, and closes gaps that remain. + + + +## Input + +The complete Markdown result returned by the validation phase. + +The validation result must report: + +```markdown +**Status:** validated +**Plan:** {plan path} +``` Treat that Markdown as the authoritative handoff for: @@ -25,7 +43,15 @@ Treat that Markdown as the authoritative handoff for: - Scaffolding removals. - Reported context impact, required context paths, and affected areas. -## 2.1 Validate the validation handoff +This phase must not be invoked for `failed` or `blocked` validation results. +Those are not success states. Same rule as `sce-task-context-sync`: context sync +runs only after a successful prior phase. + +Do not reconstruct a missing validation result from conversation history. + +## Workflow + +### 1. Validate the validation handoff Confirm that: @@ -35,26 +61,26 @@ Confirm that: - Commands run are present. - A context-impact classification is present. -If the handoff is missing required information or is internally contradictory, do -not modify context. Return a `blocked` Markdown report. +If the handoff is missing required information or is internally contradictory, +do not modify context. Return a `blocked` Markdown report. -## 2.2 Confirm the context root +### 2. Confirm the context root -When `context/` does not exist, there is no durable memory to synchronize. Do not -create it, and do not write context files outside it. +When `context/` does not exist, there is no durable memory to synchronize. +Do not create it, and do not write context files outside it. Return a `blocked` report whose required action is: `sce setup --bootstrap-context` -State that validation itself succeeded and is recorded in the plan, and that plan -context synchronization should run again once the context root exists. +State that validation itself succeeded and is recorded in the plan, and that +plan context synchronization should run again once the context root exists. Bootstrapping is the user's action, not this phase's. -## 2.3 Discover applicable context +### 3. Discover applicable context -Start with the validated internal state: +Start with the validated Markdown result: - **Context impact** classification, required context, and affected areas. - Acceptance-criteria evidence. @@ -80,7 +106,7 @@ Do not scan or rewrite the entire `context/` tree by default. Do not create a new context file when an existing authoritative file can be updated coherently. -### The mandatory root pass +#### The mandatory root pass Every invocation verifies these five files against code truth, whatever the reported classification is: @@ -93,19 +119,19 @@ reported classification is: Verifying is not editing. A classification that warrants no root edit still requires reading each of these and confirming it is not contradicted by the -finished implementation. A file that is absent is a gap; record it in the report -rather than creating it to satisfy the pass. +finished implementation. A file that is absent is a gap; record it in the +report rather than creating it to satisfy the pass. -Report each of the five as verified or edited. Never declare synchronization done -while one of them is unchecked. +Report each of the five as verified or edited. Never declare synchronization +done while one of them is unchecked. -### Plan context requirements +#### Plan context requirements Every path or statement listed under the plan's `Context sync` section must be accounted for in the report as already accurate or updated. A requirement the finished code still does not satisfy is a blocker, not a note. -## 2.4 Determine whether durable context changed +### 4. Determine whether durable context changed Use the reported context impact as a strong hint, then verify it against the finished implementation and existing context. @@ -130,11 +156,11 @@ Do not document: - Generic engineering practices. Interpret impact classifications as follows. Each governs which files are -*edited*; none of them waives the mandatory root pass or the plan's Context sync -requirements. +*edited*; none of them waives the mandatory root pass or the plan's Context +sync requirements. -- `none`: Make no edits beyond any correction the root pass or unmet plan context - requirement turns up. +- `none`: Make no edits beyond any correction the root pass or unmet plan + context requirement turns up. - `local`: Update the nearest existing authoritative context only when the new behavior is not reliably discoverable from code. - `domain`: Update affected domain context and the context map when its links or @@ -144,7 +170,7 @@ requirements. If the reported classification is inconsistent with the actual change, use the verified classification and explain the difference in the report. -## 2.5 Record qualifying architecture decisions +### 5. Record qualifying architecture decisions During this successful synchronization, determine whether the completed change establishes or changes a system-wide important constraint involving one or more @@ -187,7 +213,7 @@ handoff and during context synchronization. Do not invoke it from a non-success branch or for any non-decision purpose. When no decision qualifies, continue without invoking it and record that outcome in synchronization evidence. -## 2.6 Synchronize context +### 6. Synchronize context Make the smallest coherent documentation change that preserves repository truth. @@ -207,47 +233,47 @@ Create a new context file only when: - No existing file owns it coherently. - The new file has a clear place in the context map. -### Feature existence +#### Feature existence Every feature the finished plan implemented must have at least one durable canonical description discoverable from `context/`, in a domain file under `context/{domain}/` or in `context/overview.md` for a cross-cutting feature. When the plan delivered a feature no context file describes, add that -description. Prefer a small, precise domain file over overloading `overview.md` -with detail. +description. Prefer a small, precise domain file over overloading +`overview.md` with detail. -This is not license to narrate the diff: describe what the feature is and how it -behaves, not what was edited during the plan. +This is not license to narrate the diff: describe what the feature is and how +it behaves, not what was edited during the plan. -### Glossary +#### Glossary Add a `context/glossary.md` entry for any domain language the plan introduced. New terminology is durable knowledge whatever the classification is. -### File hygiene +#### File hygiene Every context file this phase writes must satisfy: - One topic per file. -- At most 250 lines. When an edit would push a file past 250 lines, split it into - focused files and link them rather than letting it grow. +- At most 250 lines. When an edit would push a file past 250 lines, split it + into focused files and link them rather than letting it grow. - Relative paths in every link to another context file. -- A Mermaid diagram where structure, boundaries, or flows are complex enough that - prose alone would not carry them. +- A Mermaid diagram where structure, boundaries, or flows are complex enough + that prose alone would not carry them. - Concrete code examples only where they clarify non-trivial behavior. When detail outgrows a shared file, migrate it into `context/{domain}/`, leave a concise pointer behind, and link the new file from `context/context-map.md`. -## 2.7 Verify synchronization +### 7. Verify synchronization After edits, verify: - Every changed context file accurately reflects the finished implementation. - No edited statement contradicts the code, plan, or validation evidence. -- Every qualifying decision has one written or reused ADR path in the report, and - the report states when no decision qualified. +- Every qualifying decision has one written or reused ADR path in the report, + and the report states when no decision qualified. - Every file in the mandatory root pass was read and confirmed against code truth, whether or not it was edited. - Every plan `Context sync` requirement is met. @@ -270,19 +296,20 @@ If synchronization cannot be completed without inventing facts or resolving a material contradiction, preserve safe edits when appropriate and return a `blocked` report. -## 2.8 Return the Markdown report +### 8. Return the Markdown report -Set exactly one report status: +Return exactly one report status: - `synced` - `no_context_change` - `blocked` -`synced` means context files were updated and verified. `no_context_change` means -existing context was checked and no edit was warranted. `blocked` means context -could not be synchronized safely. +`synced` means context files were updated and verified. `no_context_change` +means existing context was checked and no edit was warranted. `blocked` means +context could not be synchronized safely. -Record only the Markdown report. Do not add explanatory prose before or after it. +Return only the Markdown report. Do not add explanatory prose before or after +it. ## Plan context synchronization boundaries @@ -298,9 +325,26 @@ Do not: - Select or execute an implementation task. - Create a Git commit or push changes. - Create the context root. `sce setup --bootstrap-context` owns that. -- Narrate changed files as documentation. Feature existence is the only reason to - document a change that introduced no other durable knowledge. -- Invoke any sibling skill except `sce-decision`, or invoke `sce-decision` - outside the decision gate in successful context synchronization. +- Narrate changed files as documentation. Feature existence is the only reason + to document a change that introduced no other durable knowledge. +- Invoke any sibling SCE skill, sibling SCE package, or SCE workflow command + except `sce-decision`, or invoke `sce-decision` outside the decision gate in + successful context synchronization. - Delete a context file that has uncommitted changes. -- Return internal state. +- Return YAML. + +## Completion + +The phase is complete after: + +- The context root was confirmed, or a `blocked` report named + `sce setup --bootstrap-context` as the required action. +- The mandatory root pass was run. +- Plan context requirements were checked. +- The decision gate recorded every qualifying ADR path, found no qualifying + decision, or returned a synchronization blocker. +- Applicable durable context was synchronized and verified, no context change + was warranted, or a synchronization blocker was reported. +- One Markdown report matching `references/sync-report.md` was returned. + + diff --git a/.claude/skills/sce-validate/references/output.md b/.claude/skills/sce-validate/references/output.md index 88c75575..9cc8a19b 100644 --- a/.claude/skills/sce-validate/references/output.md +++ b/.claude/skills/sce-validate/references/output.md @@ -1,30 +1,3 @@ -# Validate output layouts - -Use only the applicable layout. Values come from internal workflow state. - -The `blocked` and `failed` layouts are stated once, under **Validation Result** -below. - -## Context synchronization blocked - -State that validation passed and its report is recorded, then report the context -failure, preserved edits, required action, and retry condition. State that durable -context remains out of date and synchronization must finish before closure. - -## Completion - -```markdown -------------------------------------- - -# Plan {plan-name} validated. - -All implementation tasks were already complete. -Final validation passed. -Durable context is synchronized. - -Validation report: {plan-path} -``` - # Validation Result Return only one completed Markdown report using the applicable variant below. @@ -37,8 +10,8 @@ The `Status` value must be exactly one of: - `blocked` The plan-file `## Validation Report` section is written separately using -`references/validation-report.md`. This layout carries the validation phase's -result into the workflow's own branches. +`references/validation-report.md`. This file is the skill's return value to the +invoking workflow. ## Validated variant @@ -205,171 +178,9 @@ returns `validated` and plan context sync completes. - The failed variant must be self-contained enough to hand to another session without the original chat. - Include **Context impact** only on `validated`. Omit it on `failed` and - `blocked`; plan context sync is not run for non-success states. + `blocked`; plan context sync is not invoked for non-success states. - Do not include context synchronization results in this report. The invoking - workflow runs the **Plan context synchronization phase** only after `validated`. + workflow runs `sce-plan-context-sync` only after `validated`. - Do not select or describe an unrelated next implementation task when status is `validated`. - Omit empty optional sections rather than writing placeholders. - -# Plan Context Sync Report - -Return only one completed Markdown report using the applicable variant below. -Do not include unused sections, placeholders, YAML, or a fenced code block. - -The `Status` value must be exactly one of: - -- `synced` -- `no_context_change` -- `blocked` - -The input validation status is always `validated` and does not need to be -repeated as a separate workflow state. This report is not produced for -`failed` or `blocked` validation results. - -## Synced variant - -# Plan Context Sync Report - -**Status:** synced -**Plan:** `{plan path}` - -## Context impact - -**Classification:** `{local | domain | root}` -**Affected areas:** `{comma-separated areas}` - -{Explain which durable behavior, architecture, terminology, operation, or -constraint required plan-level synchronization after validation.} - -## Plan context requirements - -- `{required context path or statement from the plan}` — {met by edit | already accurate} - -## Updated context - -- `{context file}` — {concise description of the durable truth updated} - -## Architecture decisions - -- `{written or reused ADR path}` — {decision and status} -- None qualified. - -## Root pass - -- `context/overview.md` — {verified | edited | absent} -- `context/architecture.md` — {verified | edited | absent} -- `context/glossary.md` — {verified | edited | absent} -- `context/patterns.md` — {verified | edited | absent} -- `context/context-map.md` — {verified | edited | absent} - -## Feature existence - -- `{feature}` — `{context file that canonically describes it}` - -## Verification - -- {How the edited context was checked against the finished implementation and validation evidence.} -- {File hygiene: line counts, relative links, diagrams where structure is complex.} -- {Documentation, link, or formatting checks that were run, when applicable.} - -## Notes - -{Include only non-blocking information worth retaining. -Omit this section when unnecessary.} - ---- - -## No-context-change variant - -# Plan Context Sync Report - -**Status:** no_context_change -**Plan:** `{plan path}` - -## Context impact - -**Classification:** none - -{Explain why the finished plan introduced no durable, non-obvious repository -knowledge requiring an update, or why existing context already matched.} - -## Plan context requirements - -- `{required context path or statement from the plan}` — already accurate -- None listed by the plan. - -## Context reviewed - -- `{context file or area}` — {what was checked and why it remains accurate} - -## Architecture decisions - -- `{reused ADR path}` — {decision and status} -- None qualified. - -## Root pass - -- `context/overview.md` — {verified | absent} -- `context/architecture.md` — {verified | absent} -- `context/glossary.md` — {verified | absent} -- `context/patterns.md` — {verified | absent} -- `context/context-map.md` — {verified | absent} - -## Feature existence - -- `{feature}` — `{context file that canonically describes it}`, already present. - -## Verification - -- {How existing context was compared with the finished implementation and validation evidence.} - ---- - -## Blocked variant - -# Plan Context Sync Report - -**Status:** blocked -**Plan:** `{plan path}` - -## Blocker - -**Problem:** {specific synchronization blocker} -**Impact:** {why context cannot be made authoritative safely} -**Required action:** {decision or correction required} - -## Context changes - -- {List safe context edits preserved, or state `No context files were changed.`} - -## Architecture decisions - -- `{ADR path written or reused before the blocker}` — {decision and status} -- None written or reused before the blocker. - -## Retry condition - -{State the concrete condition under which plan context synchronization should -run again.} - -## Report rules - -- Name exact context files when they were changed or reviewed. -- Under **Architecture decisions**, list every ADR path written or reused during - the decision gate. In a successful report, state `None qualified.` when the - gate skipped invocation. In a blocked report, state - `None written or reused before the blocker.` when applicable. -- Report every file in the root pass, including any that is absent. -- Report the missing context root as `blocked`, with `sce setup - --bootstrap-context` as the required action and the existence of `context/` as - the retry condition. -- Cover every path or statement listed in the plan's `Context sync` section - under **Plan context requirements**. -- Omit **Feature existence** only when the plan implemented no feature. -- Describe durable truth, not validation-session chronology. -- Keep evidence concise and factual. -- Do not claim implementation tasks remain open. -- Do not reopen validation checks. -- Do not recommend a next implementation task unless context cannot be repaired - without one, and then only as the required action. diff --git a/.claude/skills/sce-validate/references/validation-report.md b/.claude/skills/sce-validate/references/validation-report.md index deaa9a0b..c99ad85e 100644 --- a/.claude/skills/sce-validate/references/validation-report.md +++ b/.claude/skills/sce-validate/references/validation-report.md @@ -1,14 +1,14 @@ -# Internal persisted-document format: Plan-file validation report +# Plan-file Validation Report -The Markdown section the **Validation phase** appends to the plan file when -returning `validated` or `failed`. Write it at the end of -`context/plans/{plan_name}.md` under exactly one `## Validation Report` heading. +The Markdown section `sce-validation` appends to the plan file when returning +`validated` or `failed`. Write it at the end of `context/plans/{plan_name}.md` +under exactly one `## Validation Report` heading. This is plan-file content. The result returned to the workflow is defined -separately in `references/output.md`. +separately in `references/validation-result.md`. -Do not author this section while planning. Only `/validate` through the -**Validation phase** writes it. +Do not author this section while planning. Only `/validate` through `sce-validation` +writes it. ## Layout @@ -58,14 +58,14 @@ After repairs, rerun: 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. +- 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. + 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 **Scaffolding removed**, list only temporary debug code, intermediate artifacts, or throwaway files introduced during the change. Write `None.` when nothing temporary remained. diff --git a/.claude/skills/sce-validate/references/validation.md b/.claude/skills/sce-validate/references/validation.md index 38e8944f..08d7f5a8 100644 --- a/.claude/skills/sce-validate/references/validation.md +++ b/.claude/skills/sce-validate/references/validation.md @@ -1,42 +1,60 @@ -# Validation phase +# SCE Validation -Run this phase for step 1 of the workflow. It resolves one plan, confirms the -implementation is finished, runs the plan's checks, and records what it found. +## Purpose -Input: the plan name or path, unmodified. +Prove that one finished SCE plan meets its acceptance criteria and repository +validation bar, then record the evidence on the plan and return one Markdown +result. -This phase exclusively owns: +This phase owns: - Resolving one plan. - Confirming every implementation task is complete. -- Running full validation and acceptance-criteria checks. -- Removing temporary scaffolding. +- Running the plan's full validation commands and each acceptance criterion + check. +- Removing temporary scaffolding introduced by the change. - Writing the Validation Report into the plan. +- Marking acceptance criteria against the evidence. - Returning one Markdown validation result. -Do not duplicate any of it elsewhere in the workflow. +Return a result matching: -## 1.1 Resolve the plan +`references/validation-result.md` + +Write plan-file evidence matching: + +`references/validation-report.md` + +Context synchronization is not this phase's job. The invoking `/validate` +workflow runs `sce-plan-context-sync` only after a `validated` result. + +## Input + +A plan name or path. + +## Workflow + +### 1. Resolve the plan Resolve the supplied plan name or path to exactly one existing plan under `context/plans/`. -When no plan can be found, set internal status `blocked`. +When no plan can be found, return `blocked`. -When multiple plans match and none can be selected safely, set internal status -`blocked` with the matching candidates. +When multiple plans match and none can be selected safely, return `blocked` +with the matching candidates. Read the selected plan before exploring the repository. -## 1.2 Confirm implementation is finished +### 2. Confirm implementation is finished -Set internal status `blocked` with incomplete tasks listed when any -implementation task remains incomplete. +Return `blocked` with incomplete tasks listed when any implementation task +remains incomplete. Final validation measures finished work. Do not run the full suite against a partial stack, and do not complete remaining tasks here. -## 1.3 Read the validation contract from the plan +### 3. Read the validation contract from the plan From the plan, collect: @@ -44,15 +62,14 @@ From the plan, collect: - The `Full validation` command list. - The `Context sync` requirements, for the context-impact handoff only. -Set internal status `blocked` when the plan has no usable acceptance criteria, or -when no validation commands can be determined from the plan or repository -conventions. +Return `blocked` when the plan has no usable acceptance criteria, or when no +validation commands can be determined from the plan or repository conventions. Prefer the plan's authored checks. Fall back to repository-primary test, lint, and format commands only when `Full validation` is absent, and record that fallback under notes on a `validated` or `failed` result. -## 1.4 Remove temporary scaffolding +### 4. Remove temporary scaffolding Before or while running checks, remove temporary scaffolding introduced during the change when it is clearly throwaway: @@ -65,7 +82,7 @@ Do not delete durable product code, tests, configuration, or context files. Record every removed path. When nothing temporary remains, report `None.` -## 1.5 Run full validation and acceptance checks +### 5. Run full validation and acceptance checks Run the plan's `Full validation` commands. @@ -81,16 +98,16 @@ not this skill. Never report a check as passed unless it ran successfully or the authorized inspection confirmed the criterion. -Do not run task-by-task implementation work for incomplete tasks. That belongs to -`/next-task`. +Do not run task-by-task implementation work for incomplete tasks. That belongs +to `/next-task`. -## 1.6 Update the plan +### 6. Update the plan For `validated` and `failed` outcomes: - Mark each acceptance criterion checkbox to match the evidence. - Append or replace the plan's `## Validation Report` section using - `references/validation-report.md`. Read that file before writing the section. + `references/validation-report.md`. - When status is `failed`, the plan-file report must include the retry command `/validate {plan path}`. @@ -98,11 +115,10 @@ Do not reopen completed tasks, rewrite task evidence, or change the task stack. For `blocked`, leave the plan file unchanged. -## 1.7 Determine context impact for the handoff +### 7. Determine context impact for the handoff -On `validated` only, classify the durable context impact of the finished plan so -the **Plan context synchronization phase** can start from the plan's own -requirements: +On `validated` only, classify the durable context impact of the finished plan +so `sce-plan-context-sync` can start from the plan's own requirements: - Start from the plan's `Context sync` section. - Inspect what the completed implementation actually changed when needed. @@ -114,33 +130,20 @@ Do not edit context files here. On `failed` or `blocked`, omit context impact; context sync will not run. -## 1.8 Return the internal state +### 8. Return the Markdown result -Set exactly one internal state: +Return exactly one Markdown result: - `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 `references/output.md`, ending - recommended work with `/validate {plan path}`. + unsatisfied. Shape it as a session handoff per + `references/validation-result.md`, ending recommended work with + `/validate {plan path}`. - `blocked` when validation cannot proceed safely. -Record only the Markdown report. Do not add explanatory prose before or after it. -Do not return internal state. - -A `validated` result is the authoritative handoff into step 2, which reads the -plan path, required context paths, validation evidence, and reported context -impact out of it. It must report: - -```markdown -**Status:** validated -**Plan:** {plan path} -``` - -and must carry the resolved plan path, validation commands and outcomes, -acceptance-criteria evidence, scaffolding removals, and the reported context -impact with required context paths and affected areas. Step 2 is forbidden from -reconstructing any of that, so it has to be present here. +Return only the Markdown report. Do not add explanatory prose before or after +it. Do not return YAML. ## Validation boundaries @@ -157,5 +160,16 @@ Do not: - Create a Git commit or push changes. - Invent acceptance criteria the plan does not state. - Claim verification that was not performed. -- Return a internal state. -- Run plan context synchronization. The workflow owns that step. +- Return a YAML result. +- Invoke plan context sync. The workflow owns that step. +## Completion + +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 `references/validation-result.md` was + returned. + + diff --git a/.opencode/agent/Shared Context Code.md b/.opencode/agent/Shared Context Code.md index 3808766d..3b823efd 100644 --- a/.opencode/agent/Shared Context Code.md +++ b/.opencode/agent/Shared Context Code.md @@ -22,7 +22,8 @@ permission: lsp: allow doom_loop: ask skill: - "*": ask + "*": allow + "sce-*": deny "sce-next-task": allow "sce-validate": allow "sce-commit": allow diff --git a/.opencode/agent/Shared Context Plan.md b/.opencode/agent/Shared Context Plan.md index fa7abbcf..31b782e1 100644 --- a/.opencode/agent/Shared Context Plan.md +++ b/.opencode/agent/Shared Context Plan.md @@ -22,7 +22,8 @@ permission: lsp: allow doom_loop: ask skill: - "*": ask + "*": allow + "sce-*": deny "sce-change-to-plan": allow --- diff --git a/.opencode/skills/sce-brownfield/SKILL.md b/.opencode/skills/sce-brownfield/SKILL.md index 7499d16c..58262165 100644 --- a/.opencode/skills/sce-brownfield/SKILL.md +++ b/.opencode/skills/sce-brownfield/SKILL.md @@ -11,8 +11,8 @@ compatibility: opencode 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command. Follow the canonical workflow's steps, gates, +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 @@ -30,6 +30,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume 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. + This workflow reconstructs durable `context/` memory for a repository that has none, or that has gaps. It is a cold-start and gap-fill tool, not a recurring context-maintenance or drift-repair command. Ongoing maintenance stays owned by @@ -328,7 +333,7 @@ gaps, and the audit outcome. Stop. - Never write a fact scoring below `50` as truth. - Never resolve a material contradiction without disclosing it. - Never write a confidence score, hash, timestamp, or date under `context/`. -- Never invoke another skill, sibling package, or workflow command. +- Never invoke another SCE skill, sibling SCE package, or SCE workflow command. - Never synchronize context, validate a plan, select or execute a task, or create a Git commit. - Never treat this workflow as recurring context maintenance. diff --git a/.opencode/skills/sce-change-to-plan/SKILL.md b/.opencode/skills/sce-change-to-plan/SKILL.md index e3d9b57b..510f1c47 100644 --- a/.opencode/skills/sce-change-to-plan/SKILL.md +++ b/.opencode/skills/sce-change-to-plan/SKILL.md @@ -11,8 +11,8 @@ compatibility: opencode 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command. Follow the canonical workflow's steps, gates, +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. ## Phase references @@ -49,6 +49,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume 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/.opencode/skills/sce-commit/SKILL.md b/.opencode/skills/sce-commit/SKILL.md index 91c8a724..1abbe352 100644 --- a/.opencode/skills/sce-commit/SKILL.md +++ b/.opencode/skills/sce-commit/SKILL.md @@ -11,8 +11,8 @@ compatibility: opencode 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command. Follow the canonical workflow's steps, gates, +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. ## Phase reference @@ -41,6 +41,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume this same skill in the same session. Never expose an internal phase result as the workflow's final response. +Relevant non-SCE skills may be used as helper capabilities during the active step. +They are not workflow handoffs: when a helper returns, control returns to the active +step. Helper use must preserve the canonical phase order, gates, waits, writes, +validation, stops, and terminal user-visible output. + ## Input `$ARGUMENTS` is optional. Split it into two parts before invoking the skill: diff --git a/.opencode/skills/sce-commit/references/atomic-commit.md b/.opencode/skills/sce-commit/references/atomic-commit.md index ecdeb3bd..a2404c4c 100644 --- a/.opencode/skills/sce-commit/references/atomic-commit.md +++ b/.opencode/skills/sce-commit/references/atomic-commit.md @@ -1,78 +1,83 @@ -# Atomic commit phase +# SCE Atomic Commit -Both workflow paths run this phase. The regular path runs it with `mode: regular` -after the staging gate; the bypass path runs it with `mode: bypass` after -confirming staged content exists. +## Purpose -Input: the mode, supplied by the workflow from an explicit user-supplied token, -and the commit context. +Turn the current staged changes into atomic repository-style commit messages. -This phase exclusively owns: +Write messages matching: -- Reading and analyzing the staged diff. -- Deciding whether staged changes form one coherent unit or several. -- Classifying staged scope and applying context-file guidance gating. -- Writing every commit message subject and body. -- Applying the plan-citation body rule. +`references/commit-message-style.md` -Do not duplicate any of it elsewhere in the workflow. Do not write commit messages -outside this phase. +Return a result matching: -Never infer the mode, and never switch modes mid-analysis. +`references/commit-contract.yaml` -Commit context refines wording only. The staged diff decides what the change is; -context never overrides staged truth, and never adds a claim the diff does not -support. +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 +`git commit`. + +## Input + +A mode (`regular` or `bypass`) and optional commit context, in free-form prose. + +The mode is supplied by the workflow from an explicit user-supplied token. +Never infer it, and never switch modes mid-analysis. + +Commit context refines wording only. The staged diff decides what the change +is; context never overrides staged truth, and never adds a claim the diff does +not support. Do not accept an unstaged diff, a working-tree summary, or a conversational description as a substitute for the staged diff. -## 1. Read the staged diff +## Workflow + +### 1. Read the staged diff Read the staged changes with `git diff --cached`, and the staged file list with `git diff --cached --name-status`. Read staged file contents only when the diff alone does not explain the change. -Set internal status `blocked` when nothing is staged. +Return `blocked` when nothing is staged. -## 2. Identify coherent units +### 2. Identify coherent units Infer the main reason for the staged change from the diff first. A coherent unit is one goal a reviewer would accept as a single commit. Group staged files by that goal, not by directory. -In `bypass` mode, stop grouping here: the result is exactly one message covering -all staged files, whether or not the diff is coherent. Do not propose splits, and -do not report split guidance. +In `bypass` mode, stop grouping here: the result is exactly one message +covering all staged files, whether or not the diff is coherent. Do not propose +splits, and do not report split guidance. -## 3. Choose a scope for each unit +### 3. Choose a scope for each unit Use the smallest stable subsystem or module name recognizable in the repository. When no such name applies, use the primary directory or package of the unit's changes. -## 4. Write each message +### 4. Write each message -Follow `references/output.md` for the subject pattern, the body rules, issue -references, the plan-citation rule, and the anti-patterns. +Follow `references/commit-message-style.md` for the subject pattern, the body +rules, issue references, the plan-citation rule, and the anti-patterns. -## 5. Apply the plan-citation rule +### 5. Apply the plan-citation rule -When the unit's staged files include `context/plans/*.md`, cite the affected plan -slug and updated task IDs in the body. +When the unit's staged files include `context/plans/*.md`, cite the affected +plan slug and updated task IDs in the body. When the staged plan diff does not expose the slug or task ID clearly enough to cite faithfully: -- In `regular` mode, set internal status `blocked` and ask for the reference to be - stated or staged explicitly. +- In `regular` mode, return `blocked` and ask for the reference to be stated or + staged explicitly. - In `bypass` mode, infer the citation when the diff supports it, and otherwise omit it. Never stop, and never invent a slug or task ID. -## 6. Apply context-file guidance gating +### 6. Apply context-file guidance gating This step applies in `regular` mode only. Skip it entirely in `bypass` mode; do not classify staged scope there. @@ -80,10 +85,10 @@ not classify staged scope there. Classify the staged diff: - Context-only (`context/**`): context-file-focused guidance is allowed. -- Mixed (`context/**` plus non-`context/**`): suppress default context-file commit - reminders and give guidance that reflects the full staged scope. +- Mixed (`context/**` plus non-`context/**`): suppress default context-file + commit reminders and give guidance that reflects the full staged scope. -## 7. Propose split guidance +### 7. Propose split guidance This step applies in `regular` mode only. @@ -91,10 +96,10 @@ When the units found in step 2 pursue unrelated goals, return one message per unit, and state why the split is recommended and which staged files belong to each. -When the staged changes form one unit, return one message and no split guidance. -Do not split coherent work to appear thorough. +When the staged changes form one unit, return one message and no split +guidance. Do not split coherent work to appear thorough. -## 8. Validate the result +### 8. Validate the result Confirm before returning that: @@ -103,15 +108,15 @@ Confirm before returning that: - No plan slug or task ID appears that the staged diff does not support. - The mode's own constraints hold. -## 9. Return internal state +### 9. Return YAML -Set exactly one internal state: +Return exactly one YAML document matching `references/commit-contract.yaml`: - `proposal` in `regular` mode, with one or more messages. - `bypass_message` in `bypass` mode, with exactly one message. - `blocked` when messages cannot be written faithfully. -Record only the internal state. Do not add explanatory prose before or after it. +Return only the YAML document. Do not add explanatory prose before or after it. ## Atomic commit boundaries @@ -128,3 +133,13 @@ Do not: - Mention `context/` synchronization activity in a commit message. - Claim a message was committed. - Run plan, task, or validation workflows. +## Completion + +The skill 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. +- One valid terminal YAML result matching `references/commit-contract.yaml` was + returned. + + diff --git a/.opencode/skills/sce-commit/references/output.md b/.opencode/skills/sce-commit/references/output.md index fb62021a..9fdbaddc 100644 --- a/.opencode/skills/sce-commit/references/output.md +++ b/.opencode/skills/sce-commit/references/output.md @@ -36,67 +36,3 @@ Committed {commit-hash} ## Bypass Git failure Present Git's failure unchanged and stop without retrying. - -# Commit message style - -The wording rules for every message the **Atomic commit phase** returns, in either -mode. This file is the only authority for message content and shape. - -Messages are carried in the result's `message` field, subject first, then one -blank line, then the body. - -## Subject - -Pattern: - -`: ` - -- Scope is the smallest stable subsystem or module name recognizable in the - repository. When no such name applies, use the primary directory or package - of the change. -- Start the summary with an imperative verb: Fix, Add, Remove, Implement, - Refactor, Simplify, Rename, Update, Ensure, Allow. -- Capitalize the verb. Do not end the subject with a period. -- Keep it concrete and technical. Name what changed, not how it felt. - -## Body - -Include a body whenever the subject alone leaves the change unexplained. Omit -it for changes whose subject is self-evident. - -A body says what was wrong or missing, why it mattered, what changed -conceptually, and the impact. It does not restate the subject in longer words, -and it does not narrate the editing process. - -Wrap the body at a readable width and separate paragraphs with a blank line. - -## Issue references - -Put each issue reference on its own line at the end of the body, for example -`Fixes #123`. - -Reference only issues the staged diff or the supplied commit context names. Do -not infer an issue number from a branch name. - -## Plan citations - -When a commit's staged files include `context/plans/*.md`, the body must also -cite: - -- The affected plan slug. -- Every updated task ID (`T0X`). - -Cite only what the staged plan diff shows. When the diff does not expose the -slug or task IDs clearly enough to cite faithfully, the skill's mode decides -what happens — the ambiguity is not resolved here by guessing. - -## Anti-patterns - -- Vague subjects: "cleanup", "updates", "various fixes". -- A body that repeats the subject without adding why or impact. -- Playful tone in a fix, security change, or architectural change. -- Mentioning `context/` synchronization activity. -- Inventing plan slugs, task IDs, or issue references. -- Splitting changes that already form one coherent unit. -- Forcing unrelated goals into a single commit. -- Describing intent the staged diff does not support. diff --git a/.opencode/skills/sce-handover/SKILL.md b/.opencode/skills/sce-handover/SKILL.md index b7163aa7..a512ff8b 100644 --- a/.opencode/skills/sce-handover/SKILL.md +++ b/.opencode/skills/sce-handover/SKILL.md @@ -11,8 +11,8 @@ compatibility: opencode 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command. Follow the canonical workflow's steps, gates, +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 @@ -30,6 +30,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume 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 and selects the mode: @@ -154,7 +159,7 @@ guidance is the entire loader contract. one handover document it writes. - Loader mode never edits a file, writes a new file, or changes plan or task state. -- Never invoke another skill, sibling package, or workflow command. +- Never invoke another SCE skill, sibling SCE package, or SCE workflow command. - Never treat a file outside `context/handovers/`, or a non-Markdown file, as a loadable handover. - Never create the `context/` root; `sce setup --bootstrap-context` owns that. diff --git a/.opencode/skills/sce-next-task/SKILL.md b/.opencode/skills/sce-next-task/SKILL.md index 06bb58cc..384550a8 100644 --- a/.opencode/skills/sce-next-task/SKILL.md +++ b/.opencode/skills/sce-next-task/SKILL.md @@ -11,9 +11,9 @@ compatibility: opencode 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command except `sce-decision`, and invoke `sce-decision` only from the -successful context-synchronization decision gate. Follow the canonical workflow's steps, gates, +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. ## Phase references @@ -50,6 +50,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume this same skill in the same session. Never expose an internal phase result as the workflow's final response. +Relevant non-SCE skills may be used as helper capabilities during the active step. +They are not workflow handoffs: when a helper returns, control returns to the active +step. Helper use must preserve the canonical phase order, gates, waits, writes, +validation, stops, and terminal user-visible output. + ## Input Parse `$ARGUMENTS` into three positional parts before invoking any phase: diff --git a/.opencode/skills/sce-next-task/references/context-sync.md b/.opencode/skills/sce-next-task/references/context-sync.md index 06413b09..3c5cb8b4 100644 --- a/.opencode/skills/sce-next-task/references/context-sync.md +++ b/.opencode/skills/sce-next-task/references/context-sync.md @@ -310,7 +310,8 @@ Do not: - Create the context root. `sce setup --bootstrap-context` owns that. - Narrate changed files as documentation. Feature existence is the only reason to document a change that introduced no other durable knowledge. -- Invoke any sibling skill except `sce-decision`, or invoke `sce-decision` - outside the decision gate in successful context synchronization. +- Invoke any sibling SCE skill, sibling SCE package, or SCE workflow command + 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. diff --git a/.opencode/skills/sce-validate/SKILL.md b/.opencode/skills/sce-validate/SKILL.md index 898fb185..7b8f68fa 100644 --- a/.opencode/skills/sce-validate/SKILL.md +++ b/.opencode/skills/sce-validate/SKILL.md @@ -11,9 +11,9 @@ compatibility: opencode 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command except `sce-decision`, and invoke `sce-decision` only from the -successful context-synchronization decision gate. Follow the canonical workflow's steps, gates, +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. ## Phase references @@ -50,6 +50,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume this same skill in the same session. Never expose an internal phase result as the workflow's final response. +Relevant non-SCE skills may be used as helper capabilities during the active step. +They are not workflow handoffs: when a helper returns, control returns to the active +step. Helper use must preserve the canonical phase order, gates, waits, writes, +validation, stops, and terminal user-visible output. + ## Input `$ARGUMENTS` is the plan name or plan path. diff --git a/.opencode/skills/sce-validate/references/context-sync.md b/.opencode/skills/sce-validate/references/context-sync.md index d6a45d46..bdd0c223 100644 --- a/.opencode/skills/sce-validate/references/context-sync.md +++ b/.opencode/skills/sce-validate/references/context-sync.md @@ -1,21 +1,39 @@ -# Plan context synchronization phase +# SCE Plan Context Sync -Run this phase for step 2 of the workflow, and only with a `Status: validated` -Markdown result from the validation phase. It is the plan-level final context -pass: it starts from the plan's `Context sync` requirements and the validated -implementation, and closes gaps that remain after any task-level syncs already -ran. +## Purpose -Do not run this phase for `failed` or `blocked`. Those are not success states. -Same rule as the task context synchronization phase: context sync runs only after -a successful prior phase. +Reconcile one fully validated plan with the repository's durable context and +return a Markdown report. -Pass the validated result verbatim. It is the authoritative handoff, and this -phase owns reading the plan path, required context paths, validation evidence, -and reported context impact out of it. +This phase owns: -Do not restate, summarize, or reconstruct any part of the validation result. Do -not reconstruct a missing validation result from conversation history. +- Validating the validation handoff. +- Confirming the context root exists. +- Discovering the context required by the finished plan. +- Deciding whether durable context changed. +- Editing and verifying the affected context files. +- Returning one Markdown synchronization report. + +Use the report format in: + +`references/sync-report.md` + +Task-level context sync may already have run after individual tasks. This phase +is the plan-level final pass: it starts from the plan's `Context sync` +requirements and the validated implementation, and closes gaps that remain. + + + +## Input + +The complete Markdown result returned by the validation phase. + +The validation result must report: + +```markdown +**Status:** validated +**Plan:** {plan path} +``` Treat that Markdown as the authoritative handoff for: @@ -25,7 +43,15 @@ Treat that Markdown as the authoritative handoff for: - Scaffolding removals. - Reported context impact, required context paths, and affected areas. -## 2.1 Validate the validation handoff +This phase must not be invoked for `failed` or `blocked` validation results. +Those are not success states. Same rule as `sce-task-context-sync`: context sync +runs only after a successful prior phase. + +Do not reconstruct a missing validation result from conversation history. + +## Workflow + +### 1. Validate the validation handoff Confirm that: @@ -35,26 +61,26 @@ Confirm that: - Commands run are present. - A context-impact classification is present. -If the handoff is missing required information or is internally contradictory, do -not modify context. Return a `blocked` Markdown report. +If the handoff is missing required information or is internally contradictory, +do not modify context. Return a `blocked` Markdown report. -## 2.2 Confirm the context root +### 2. Confirm the context root -When `context/` does not exist, there is no durable memory to synchronize. Do not -create it, and do not write context files outside it. +When `context/` does not exist, there is no durable memory to synchronize. +Do not create it, and do not write context files outside it. Return a `blocked` report whose required action is: `sce setup --bootstrap-context` -State that validation itself succeeded and is recorded in the plan, and that plan -context synchronization should run again once the context root exists. +State that validation itself succeeded and is recorded in the plan, and that +plan context synchronization should run again once the context root exists. Bootstrapping is the user's action, not this phase's. -## 2.3 Discover applicable context +### 3. Discover applicable context -Start with the validated internal state: +Start with the validated Markdown result: - **Context impact** classification, required context, and affected areas. - Acceptance-criteria evidence. @@ -80,7 +106,7 @@ Do not scan or rewrite the entire `context/` tree by default. Do not create a new context file when an existing authoritative file can be updated coherently. -### The mandatory root pass +#### The mandatory root pass Every invocation verifies these five files against code truth, whatever the reported classification is: @@ -93,19 +119,19 @@ reported classification is: Verifying is not editing. A classification that warrants no root edit still requires reading each of these and confirming it is not contradicted by the -finished implementation. A file that is absent is a gap; record it in the report -rather than creating it to satisfy the pass. +finished implementation. A file that is absent is a gap; record it in the +report rather than creating it to satisfy the pass. -Report each of the five as verified or edited. Never declare synchronization done -while one of them is unchecked. +Report each of the five as verified or edited. Never declare synchronization +done while one of them is unchecked. -### Plan context requirements +#### Plan context requirements Every path or statement listed under the plan's `Context sync` section must be accounted for in the report as already accurate or updated. A requirement the finished code still does not satisfy is a blocker, not a note. -## 2.4 Determine whether durable context changed +### 4. Determine whether durable context changed Use the reported context impact as a strong hint, then verify it against the finished implementation and existing context. @@ -130,11 +156,11 @@ Do not document: - Generic engineering practices. Interpret impact classifications as follows. Each governs which files are -*edited*; none of them waives the mandatory root pass or the plan's Context sync -requirements. +*edited*; none of them waives the mandatory root pass or the plan's Context +sync requirements. -- `none`: Make no edits beyond any correction the root pass or unmet plan context - requirement turns up. +- `none`: Make no edits beyond any correction the root pass or unmet plan + context requirement turns up. - `local`: Update the nearest existing authoritative context only when the new behavior is not reliably discoverable from code. - `domain`: Update affected domain context and the context map when its links or @@ -144,7 +170,7 @@ requirements. If the reported classification is inconsistent with the actual change, use the verified classification and explain the difference in the report. -## 2.5 Record qualifying architecture decisions +### 5. Record qualifying architecture decisions During this successful synchronization, determine whether the completed change establishes or changes a system-wide important constraint involving one or more @@ -187,7 +213,7 @@ handoff and during context synchronization. Do not invoke it from a non-success branch or for any non-decision purpose. When no decision qualifies, continue without invoking it and record that outcome in synchronization evidence. -## 2.6 Synchronize context +### 6. Synchronize context Make the smallest coherent documentation change that preserves repository truth. @@ -207,47 +233,47 @@ Create a new context file only when: - No existing file owns it coherently. - The new file has a clear place in the context map. -### Feature existence +#### Feature existence Every feature the finished plan implemented must have at least one durable canonical description discoverable from `context/`, in a domain file under `context/{domain}/` or in `context/overview.md` for a cross-cutting feature. When the plan delivered a feature no context file describes, add that -description. Prefer a small, precise domain file over overloading `overview.md` -with detail. +description. Prefer a small, precise domain file over overloading +`overview.md` with detail. -This is not license to narrate the diff: describe what the feature is and how it -behaves, not what was edited during the plan. +This is not license to narrate the diff: describe what the feature is and how +it behaves, not what was edited during the plan. -### Glossary +#### Glossary Add a `context/glossary.md` entry for any domain language the plan introduced. New terminology is durable knowledge whatever the classification is. -### File hygiene +#### File hygiene Every context file this phase writes must satisfy: - One topic per file. -- At most 250 lines. When an edit would push a file past 250 lines, split it into - focused files and link them rather than letting it grow. +- At most 250 lines. When an edit would push a file past 250 lines, split it + into focused files and link them rather than letting it grow. - Relative paths in every link to another context file. -- A Mermaid diagram where structure, boundaries, or flows are complex enough that - prose alone would not carry them. +- A Mermaid diagram where structure, boundaries, or flows are complex enough + that prose alone would not carry them. - Concrete code examples only where they clarify non-trivial behavior. When detail outgrows a shared file, migrate it into `context/{domain}/`, leave a concise pointer behind, and link the new file from `context/context-map.md`. -## 2.7 Verify synchronization +### 7. Verify synchronization After edits, verify: - Every changed context file accurately reflects the finished implementation. - No edited statement contradicts the code, plan, or validation evidence. -- Every qualifying decision has one written or reused ADR path in the report, and - the report states when no decision qualified. +- Every qualifying decision has one written or reused ADR path in the report, + and the report states when no decision qualified. - Every file in the mandatory root pass was read and confirmed against code truth, whether or not it was edited. - Every plan `Context sync` requirement is met. @@ -270,19 +296,20 @@ If synchronization cannot be completed without inventing facts or resolving a material contradiction, preserve safe edits when appropriate and return a `blocked` report. -## 2.8 Return the Markdown report +### 8. Return the Markdown report -Set exactly one report status: +Return exactly one report status: - `synced` - `no_context_change` - `blocked` -`synced` means context files were updated and verified. `no_context_change` means -existing context was checked and no edit was warranted. `blocked` means context -could not be synchronized safely. +`synced` means context files were updated and verified. `no_context_change` +means existing context was checked and no edit was warranted. `blocked` means +context could not be synchronized safely. -Record only the Markdown report. Do not add explanatory prose before or after it. +Return only the Markdown report. Do not add explanatory prose before or after +it. ## Plan context synchronization boundaries @@ -298,9 +325,26 @@ Do not: - Select or execute an implementation task. - Create a Git commit or push changes. - Create the context root. `sce setup --bootstrap-context` owns that. -- Narrate changed files as documentation. Feature existence is the only reason to - document a change that introduced no other durable knowledge. -- Invoke any sibling skill except `sce-decision`, or invoke `sce-decision` - outside the decision gate in successful context synchronization. +- Narrate changed files as documentation. Feature existence is the only reason + to document a change that introduced no other durable knowledge. +- Invoke any sibling SCE skill, sibling SCE package, or SCE workflow command + except `sce-decision`, or invoke `sce-decision` outside the decision gate in + successful context synchronization. - Delete a context file that has uncommitted changes. -- Return internal state. +- Return YAML. + +## Completion + +The phase is complete after: + +- The context root was confirmed, or a `blocked` report named + `sce setup --bootstrap-context` as the required action. +- The mandatory root pass was run. +- Plan context requirements were checked. +- The decision gate recorded every qualifying ADR path, found no qualifying + decision, or returned a synchronization blocker. +- Applicable durable context was synchronized and verified, no context change + was warranted, or a synchronization blocker was reported. +- One Markdown report matching `references/sync-report.md` was returned. + + diff --git a/.opencode/skills/sce-validate/references/output.md b/.opencode/skills/sce-validate/references/output.md index 88c75575..9cc8a19b 100644 --- a/.opencode/skills/sce-validate/references/output.md +++ b/.opencode/skills/sce-validate/references/output.md @@ -1,30 +1,3 @@ -# Validate output layouts - -Use only the applicable layout. Values come from internal workflow state. - -The `blocked` and `failed` layouts are stated once, under **Validation Result** -below. - -## Context synchronization blocked - -State that validation passed and its report is recorded, then report the context -failure, preserved edits, required action, and retry condition. State that durable -context remains out of date and synchronization must finish before closure. - -## Completion - -```markdown -------------------------------------- - -# Plan {plan-name} validated. - -All implementation tasks were already complete. -Final validation passed. -Durable context is synchronized. - -Validation report: {plan-path} -``` - # Validation Result Return only one completed Markdown report using the applicable variant below. @@ -37,8 +10,8 @@ The `Status` value must be exactly one of: - `blocked` The plan-file `## Validation Report` section is written separately using -`references/validation-report.md`. This layout carries the validation phase's -result into the workflow's own branches. +`references/validation-report.md`. This file is the skill's return value to the +invoking workflow. ## Validated variant @@ -205,171 +178,9 @@ returns `validated` and plan context sync completes. - The failed variant must be self-contained enough to hand to another session without the original chat. - Include **Context impact** only on `validated`. Omit it on `failed` and - `blocked`; plan context sync is not run for non-success states. + `blocked`; plan context sync is not invoked for non-success states. - Do not include context synchronization results in this report. The invoking - workflow runs the **Plan context synchronization phase** only after `validated`. + workflow runs `sce-plan-context-sync` only after `validated`. - Do not select or describe an unrelated next implementation task when status is `validated`. - Omit empty optional sections rather than writing placeholders. - -# Plan Context Sync Report - -Return only one completed Markdown report using the applicable variant below. -Do not include unused sections, placeholders, YAML, or a fenced code block. - -The `Status` value must be exactly one of: - -- `synced` -- `no_context_change` -- `blocked` - -The input validation status is always `validated` and does not need to be -repeated as a separate workflow state. This report is not produced for -`failed` or `blocked` validation results. - -## Synced variant - -# Plan Context Sync Report - -**Status:** synced -**Plan:** `{plan path}` - -## Context impact - -**Classification:** `{local | domain | root}` -**Affected areas:** `{comma-separated areas}` - -{Explain which durable behavior, architecture, terminology, operation, or -constraint required plan-level synchronization after validation.} - -## Plan context requirements - -- `{required context path or statement from the plan}` — {met by edit | already accurate} - -## Updated context - -- `{context file}` — {concise description of the durable truth updated} - -## Architecture decisions - -- `{written or reused ADR path}` — {decision and status} -- None qualified. - -## Root pass - -- `context/overview.md` — {verified | edited | absent} -- `context/architecture.md` — {verified | edited | absent} -- `context/glossary.md` — {verified | edited | absent} -- `context/patterns.md` — {verified | edited | absent} -- `context/context-map.md` — {verified | edited | absent} - -## Feature existence - -- `{feature}` — `{context file that canonically describes it}` - -## Verification - -- {How the edited context was checked against the finished implementation and validation evidence.} -- {File hygiene: line counts, relative links, diagrams where structure is complex.} -- {Documentation, link, or formatting checks that were run, when applicable.} - -## Notes - -{Include only non-blocking information worth retaining. -Omit this section when unnecessary.} - ---- - -## No-context-change variant - -# Plan Context Sync Report - -**Status:** no_context_change -**Plan:** `{plan path}` - -## Context impact - -**Classification:** none - -{Explain why the finished plan introduced no durable, non-obvious repository -knowledge requiring an update, or why existing context already matched.} - -## Plan context requirements - -- `{required context path or statement from the plan}` — already accurate -- None listed by the plan. - -## Context reviewed - -- `{context file or area}` — {what was checked and why it remains accurate} - -## Architecture decisions - -- `{reused ADR path}` — {decision and status} -- None qualified. - -## Root pass - -- `context/overview.md` — {verified | absent} -- `context/architecture.md` — {verified | absent} -- `context/glossary.md` — {verified | absent} -- `context/patterns.md` — {verified | absent} -- `context/context-map.md` — {verified | absent} - -## Feature existence - -- `{feature}` — `{context file that canonically describes it}`, already present. - -## Verification - -- {How existing context was compared with the finished implementation and validation evidence.} - ---- - -## Blocked variant - -# Plan Context Sync Report - -**Status:** blocked -**Plan:** `{plan path}` - -## Blocker - -**Problem:** {specific synchronization blocker} -**Impact:** {why context cannot be made authoritative safely} -**Required action:** {decision or correction required} - -## Context changes - -- {List safe context edits preserved, or state `No context files were changed.`} - -## Architecture decisions - -- `{ADR path written or reused before the blocker}` — {decision and status} -- None written or reused before the blocker. - -## Retry condition - -{State the concrete condition under which plan context synchronization should -run again.} - -## Report rules - -- Name exact context files when they were changed or reviewed. -- Under **Architecture decisions**, list every ADR path written or reused during - the decision gate. In a successful report, state `None qualified.` when the - gate skipped invocation. In a blocked report, state - `None written or reused before the blocker.` when applicable. -- Report every file in the root pass, including any that is absent. -- Report the missing context root as `blocked`, with `sce setup - --bootstrap-context` as the required action and the existence of `context/` as - the retry condition. -- Cover every path or statement listed in the plan's `Context sync` section - under **Plan context requirements**. -- Omit **Feature existence** only when the plan implemented no feature. -- Describe durable truth, not validation-session chronology. -- Keep evidence concise and factual. -- Do not claim implementation tasks remain open. -- Do not reopen validation checks. -- Do not recommend a next implementation task unless context cannot be repaired - without one, and then only as the required action. diff --git a/.opencode/skills/sce-validate/references/validation-report.md b/.opencode/skills/sce-validate/references/validation-report.md index deaa9a0b..c99ad85e 100644 --- a/.opencode/skills/sce-validate/references/validation-report.md +++ b/.opencode/skills/sce-validate/references/validation-report.md @@ -1,14 +1,14 @@ -# Internal persisted-document format: Plan-file validation report +# Plan-file Validation Report -The Markdown section the **Validation phase** appends to the plan file when -returning `validated` or `failed`. Write it at the end of -`context/plans/{plan_name}.md` under exactly one `## Validation Report` heading. +The Markdown section `sce-validation` appends to the plan file when returning +`validated` or `failed`. Write it at the end of `context/plans/{plan_name}.md` +under exactly one `## Validation Report` heading. This is plan-file content. The result returned to the workflow is defined -separately in `references/output.md`. +separately in `references/validation-result.md`. -Do not author this section while planning. Only `/validate` through the -**Validation phase** writes it. +Do not author this section while planning. Only `/validate` through `sce-validation` +writes it. ## Layout @@ -58,14 +58,14 @@ After repairs, rerun: 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. +- 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. + 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 **Scaffolding removed**, list only temporary debug code, intermediate artifacts, or throwaway files introduced during the change. Write `None.` when nothing temporary remained. diff --git a/.opencode/skills/sce-validate/references/validation.md b/.opencode/skills/sce-validate/references/validation.md index 38e8944f..08d7f5a8 100644 --- a/.opencode/skills/sce-validate/references/validation.md +++ b/.opencode/skills/sce-validate/references/validation.md @@ -1,42 +1,60 @@ -# Validation phase +# SCE Validation -Run this phase for step 1 of the workflow. It resolves one plan, confirms the -implementation is finished, runs the plan's checks, and records what it found. +## Purpose -Input: the plan name or path, unmodified. +Prove that one finished SCE plan meets its acceptance criteria and repository +validation bar, then record the evidence on the plan and return one Markdown +result. -This phase exclusively owns: +This phase owns: - Resolving one plan. - Confirming every implementation task is complete. -- Running full validation and acceptance-criteria checks. -- Removing temporary scaffolding. +- Running the plan's full validation commands and each acceptance criterion + check. +- Removing temporary scaffolding introduced by the change. - Writing the Validation Report into the plan. +- Marking acceptance criteria against the evidence. - Returning one Markdown validation result. -Do not duplicate any of it elsewhere in the workflow. +Return a result matching: -## 1.1 Resolve the plan +`references/validation-result.md` + +Write plan-file evidence matching: + +`references/validation-report.md` + +Context synchronization is not this phase's job. The invoking `/validate` +workflow runs `sce-plan-context-sync` only after a `validated` result. + +## Input + +A plan name or path. + +## Workflow + +### 1. Resolve the plan Resolve the supplied plan name or path to exactly one existing plan under `context/plans/`. -When no plan can be found, set internal status `blocked`. +When no plan can be found, return `blocked`. -When multiple plans match and none can be selected safely, set internal status -`blocked` with the matching candidates. +When multiple plans match and none can be selected safely, return `blocked` +with the matching candidates. Read the selected plan before exploring the repository. -## 1.2 Confirm implementation is finished +### 2. Confirm implementation is finished -Set internal status `blocked` with incomplete tasks listed when any -implementation task remains incomplete. +Return `blocked` with incomplete tasks listed when any implementation task +remains incomplete. Final validation measures finished work. Do not run the full suite against a partial stack, and do not complete remaining tasks here. -## 1.3 Read the validation contract from the plan +### 3. Read the validation contract from the plan From the plan, collect: @@ -44,15 +62,14 @@ From the plan, collect: - The `Full validation` command list. - The `Context sync` requirements, for the context-impact handoff only. -Set internal status `blocked` when the plan has no usable acceptance criteria, or -when no validation commands can be determined from the plan or repository -conventions. +Return `blocked` when the plan has no usable acceptance criteria, or when no +validation commands can be determined from the plan or repository conventions. Prefer the plan's authored checks. Fall back to repository-primary test, lint, and format commands only when `Full validation` is absent, and record that fallback under notes on a `validated` or `failed` result. -## 1.4 Remove temporary scaffolding +### 4. Remove temporary scaffolding Before or while running checks, remove temporary scaffolding introduced during the change when it is clearly throwaway: @@ -65,7 +82,7 @@ Do not delete durable product code, tests, configuration, or context files. Record every removed path. When nothing temporary remains, report `None.` -## 1.5 Run full validation and acceptance checks +### 5. Run full validation and acceptance checks Run the plan's `Full validation` commands. @@ -81,16 +98,16 @@ not this skill. Never report a check as passed unless it ran successfully or the authorized inspection confirmed the criterion. -Do not run task-by-task implementation work for incomplete tasks. That belongs to -`/next-task`. +Do not run task-by-task implementation work for incomplete tasks. That belongs +to `/next-task`. -## 1.6 Update the plan +### 6. Update the plan For `validated` and `failed` outcomes: - Mark each acceptance criterion checkbox to match the evidence. - Append or replace the plan's `## Validation Report` section using - `references/validation-report.md`. Read that file before writing the section. + `references/validation-report.md`. - When status is `failed`, the plan-file report must include the retry command `/validate {plan path}`. @@ -98,11 +115,10 @@ Do not reopen completed tasks, rewrite task evidence, or change the task stack. For `blocked`, leave the plan file unchanged. -## 1.7 Determine context impact for the handoff +### 7. Determine context impact for the handoff -On `validated` only, classify the durable context impact of the finished plan so -the **Plan context synchronization phase** can start from the plan's own -requirements: +On `validated` only, classify the durable context impact of the finished plan +so `sce-plan-context-sync` can start from the plan's own requirements: - Start from the plan's `Context sync` section. - Inspect what the completed implementation actually changed when needed. @@ -114,33 +130,20 @@ Do not edit context files here. On `failed` or `blocked`, omit context impact; context sync will not run. -## 1.8 Return the internal state +### 8. Return the Markdown result -Set exactly one internal state: +Return exactly one Markdown result: - `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 `references/output.md`, ending - recommended work with `/validate {plan path}`. + unsatisfied. Shape it as a session handoff per + `references/validation-result.md`, ending recommended work with + `/validate {plan path}`. - `blocked` when validation cannot proceed safely. -Record only the Markdown report. Do not add explanatory prose before or after it. -Do not return internal state. - -A `validated` result is the authoritative handoff into step 2, which reads the -plan path, required context paths, validation evidence, and reported context -impact out of it. It must report: - -```markdown -**Status:** validated -**Plan:** {plan path} -``` - -and must carry the resolved plan path, validation commands and outcomes, -acceptance-criteria evidence, scaffolding removals, and the reported context -impact with required context paths and affected areas. Step 2 is forbidden from -reconstructing any of that, so it has to be present here. +Return only the Markdown report. Do not add explanatory prose before or after +it. Do not return YAML. ## Validation boundaries @@ -157,5 +160,16 @@ Do not: - Create a Git commit or push changes. - Invent acceptance criteria the plan does not state. - Claim verification that was not performed. -- Return a internal state. -- Run plan context synchronization. The workflow owns that step. +- Return a YAML result. +- Invoke plan context sync. The workflow owns that step. +## Completion + +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 `references/validation-result.md` was + returned. + + diff --git a/.pi/skills/sce-brownfield/SKILL.md b/.pi/skills/sce-brownfield/SKILL.md index 38f88e72..d58c34f7 100644 --- a/.pi/skills/sce-brownfield/SKILL.md +++ b/.pi/skills/sce-brownfield/SKILL.md @@ -10,8 +10,8 @@ description: > 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command. Follow the canonical workflow's steps, gates, +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 @@ -29,6 +29,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume 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. + This workflow reconstructs durable `context/` memory for a repository that has none, or that has gaps. It is a cold-start and gap-fill tool, not a recurring context-maintenance or drift-repair command. Ongoing maintenance stays owned by @@ -327,7 +332,7 @@ gaps, and the audit outcome. Stop. - Never write a fact scoring below `50` as truth. - Never resolve a material contradiction without disclosing it. - Never write a confidence score, hash, timestamp, or date under `context/`. -- Never invoke another skill, sibling package, or workflow command. +- Never invoke another SCE skill, sibling SCE package, or SCE workflow command. - Never synchronize context, validate a plan, select or execute a task, or create a Git commit. - Never treat this workflow as recurring context maintenance. diff --git a/.pi/skills/sce-change-to-plan/SKILL.md b/.pi/skills/sce-change-to-plan/SKILL.md index 2697e80d..a96a1b71 100644 --- a/.pi/skills/sce-change-to-plan/SKILL.md +++ b/.pi/skills/sce-change-to-plan/SKILL.md @@ -10,8 +10,8 @@ description: > 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command. Follow the canonical workflow's steps, gates, +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. ## Phase references @@ -48,6 +48,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume this same skill in the same session. Never expose an internal phase result as the workflow's final response. +Relevant non-SCE skills may be used as helper capabilities during the active step. +They are not workflow handoffs: when a helper returns, control returns to the active +step. Helper use must preserve the canonical phase order, gates, waits, writes, +validation, stops, and terminal user-visible output. + ## Input `$ARGUMENTS` is the change request, in free-form prose. diff --git a/.pi/skills/sce-commit/SKILL.md b/.pi/skills/sce-commit/SKILL.md index 1eeecb78..07059111 100644 --- a/.pi/skills/sce-commit/SKILL.md +++ b/.pi/skills/sce-commit/SKILL.md @@ -10,8 +10,8 @@ description: > 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command. Follow the canonical workflow's steps, gates, +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. ## Phase reference @@ -40,6 +40,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume this same skill in the same session. Never expose an internal phase result as the workflow's final response. +Relevant non-SCE skills may be used as helper capabilities during the active step. +They are not workflow handoffs: when a helper returns, control returns to the active +step. Helper use must preserve the canonical phase order, gates, waits, writes, +validation, stops, and terminal user-visible output. + ## Input `$ARGUMENTS` is optional. Split it into two parts before invoking the skill: diff --git a/.pi/skills/sce-commit/references/atomic-commit.md b/.pi/skills/sce-commit/references/atomic-commit.md index ecdeb3bd..a2404c4c 100644 --- a/.pi/skills/sce-commit/references/atomic-commit.md +++ b/.pi/skills/sce-commit/references/atomic-commit.md @@ -1,78 +1,83 @@ -# Atomic commit phase +# SCE Atomic Commit -Both workflow paths run this phase. The regular path runs it with `mode: regular` -after the staging gate; the bypass path runs it with `mode: bypass` after -confirming staged content exists. +## Purpose -Input: the mode, supplied by the workflow from an explicit user-supplied token, -and the commit context. +Turn the current staged changes into atomic repository-style commit messages. -This phase exclusively owns: +Write messages matching: -- Reading and analyzing the staged diff. -- Deciding whether staged changes form one coherent unit or several. -- Classifying staged scope and applying context-file guidance gating. -- Writing every commit message subject and body. -- Applying the plan-citation body rule. +`references/commit-message-style.md` -Do not duplicate any of it elsewhere in the workflow. Do not write commit messages -outside this phase. +Return a result matching: -Never infer the mode, and never switch modes mid-analysis. +`references/commit-contract.yaml` -Commit context refines wording only. The staged diff decides what the change is; -context never overrides staged truth, and never adds a claim the diff does not -support. +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 +`git commit`. + +## Input + +A mode (`regular` or `bypass`) and optional commit context, in free-form prose. + +The mode is supplied by the workflow from an explicit user-supplied token. +Never infer it, and never switch modes mid-analysis. + +Commit context refines wording only. The staged diff decides what the change +is; context never overrides staged truth, and never adds a claim the diff does +not support. Do not accept an unstaged diff, a working-tree summary, or a conversational description as a substitute for the staged diff. -## 1. Read the staged diff +## Workflow + +### 1. Read the staged diff Read the staged changes with `git diff --cached`, and the staged file list with `git diff --cached --name-status`. Read staged file contents only when the diff alone does not explain the change. -Set internal status `blocked` when nothing is staged. +Return `blocked` when nothing is staged. -## 2. Identify coherent units +### 2. Identify coherent units Infer the main reason for the staged change from the diff first. A coherent unit is one goal a reviewer would accept as a single commit. Group staged files by that goal, not by directory. -In `bypass` mode, stop grouping here: the result is exactly one message covering -all staged files, whether or not the diff is coherent. Do not propose splits, and -do not report split guidance. +In `bypass` mode, stop grouping here: the result is exactly one message +covering all staged files, whether or not the diff is coherent. Do not propose +splits, and do not report split guidance. -## 3. Choose a scope for each unit +### 3. Choose a scope for each unit Use the smallest stable subsystem or module name recognizable in the repository. When no such name applies, use the primary directory or package of the unit's changes. -## 4. Write each message +### 4. Write each message -Follow `references/output.md` for the subject pattern, the body rules, issue -references, the plan-citation rule, and the anti-patterns. +Follow `references/commit-message-style.md` for the subject pattern, the body +rules, issue references, the plan-citation rule, and the anti-patterns. -## 5. Apply the plan-citation rule +### 5. Apply the plan-citation rule -When the unit's staged files include `context/plans/*.md`, cite the affected plan -slug and updated task IDs in the body. +When the unit's staged files include `context/plans/*.md`, cite the affected +plan slug and updated task IDs in the body. When the staged plan diff does not expose the slug or task ID clearly enough to cite faithfully: -- In `regular` mode, set internal status `blocked` and ask for the reference to be - stated or staged explicitly. +- In `regular` mode, return `blocked` and ask for the reference to be stated or + staged explicitly. - In `bypass` mode, infer the citation when the diff supports it, and otherwise omit it. Never stop, and never invent a slug or task ID. -## 6. Apply context-file guidance gating +### 6. Apply context-file guidance gating This step applies in `regular` mode only. Skip it entirely in `bypass` mode; do not classify staged scope there. @@ -80,10 +85,10 @@ not classify staged scope there. Classify the staged diff: - Context-only (`context/**`): context-file-focused guidance is allowed. -- Mixed (`context/**` plus non-`context/**`): suppress default context-file commit - reminders and give guidance that reflects the full staged scope. +- Mixed (`context/**` plus non-`context/**`): suppress default context-file + commit reminders and give guidance that reflects the full staged scope. -## 7. Propose split guidance +### 7. Propose split guidance This step applies in `regular` mode only. @@ -91,10 +96,10 @@ When the units found in step 2 pursue unrelated goals, return one message per unit, and state why the split is recommended and which staged files belong to each. -When the staged changes form one unit, return one message and no split guidance. -Do not split coherent work to appear thorough. +When the staged changes form one unit, return one message and no split +guidance. Do not split coherent work to appear thorough. -## 8. Validate the result +### 8. Validate the result Confirm before returning that: @@ -103,15 +108,15 @@ Confirm before returning that: - No plan slug or task ID appears that the staged diff does not support. - The mode's own constraints hold. -## 9. Return internal state +### 9. Return YAML -Set exactly one internal state: +Return exactly one YAML document matching `references/commit-contract.yaml`: - `proposal` in `regular` mode, with one or more messages. - `bypass_message` in `bypass` mode, with exactly one message. - `blocked` when messages cannot be written faithfully. -Record only the internal state. Do not add explanatory prose before or after it. +Return only the YAML document. Do not add explanatory prose before or after it. ## Atomic commit boundaries @@ -128,3 +133,13 @@ Do not: - Mention `context/` synchronization activity in a commit message. - Claim a message was committed. - Run plan, task, or validation workflows. +## Completion + +The skill 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. +- One valid terminal YAML result matching `references/commit-contract.yaml` was + returned. + + diff --git a/.pi/skills/sce-commit/references/output.md b/.pi/skills/sce-commit/references/output.md index fb62021a..9fdbaddc 100644 --- a/.pi/skills/sce-commit/references/output.md +++ b/.pi/skills/sce-commit/references/output.md @@ -36,67 +36,3 @@ Committed {commit-hash} ## Bypass Git failure Present Git's failure unchanged and stop without retrying. - -# Commit message style - -The wording rules for every message the **Atomic commit phase** returns, in either -mode. This file is the only authority for message content and shape. - -Messages are carried in the result's `message` field, subject first, then one -blank line, then the body. - -## Subject - -Pattern: - -`: ` - -- Scope is the smallest stable subsystem or module name recognizable in the - repository. When no such name applies, use the primary directory or package - of the change. -- Start the summary with an imperative verb: Fix, Add, Remove, Implement, - Refactor, Simplify, Rename, Update, Ensure, Allow. -- Capitalize the verb. Do not end the subject with a period. -- Keep it concrete and technical. Name what changed, not how it felt. - -## Body - -Include a body whenever the subject alone leaves the change unexplained. Omit -it for changes whose subject is self-evident. - -A body says what was wrong or missing, why it mattered, what changed -conceptually, and the impact. It does not restate the subject in longer words, -and it does not narrate the editing process. - -Wrap the body at a readable width and separate paragraphs with a blank line. - -## Issue references - -Put each issue reference on its own line at the end of the body, for example -`Fixes #123`. - -Reference only issues the staged diff or the supplied commit context names. Do -not infer an issue number from a branch name. - -## Plan citations - -When a commit's staged files include `context/plans/*.md`, the body must also -cite: - -- The affected plan slug. -- Every updated task ID (`T0X`). - -Cite only what the staged plan diff shows. When the diff does not expose the -slug or task IDs clearly enough to cite faithfully, the skill's mode decides -what happens — the ambiguity is not resolved here by guessing. - -## Anti-patterns - -- Vague subjects: "cleanup", "updates", "various fixes". -- A body that repeats the subject without adding why or impact. -- Playful tone in a fix, security change, or architectural change. -- Mentioning `context/` synchronization activity. -- Inventing plan slugs, task IDs, or issue references. -- Splitting changes that already form one coherent unit. -- Forcing unrelated goals into a single commit. -- Describing intent the staged diff does not support. diff --git a/.pi/skills/sce-handover/SKILL.md b/.pi/skills/sce-handover/SKILL.md index 7cc67510..80daabab 100644 --- a/.pi/skills/sce-handover/SKILL.md +++ b/.pi/skills/sce-handover/SKILL.md @@ -10,8 +10,8 @@ description: > 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command. Follow the canonical workflow's steps, gates, +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 @@ -29,6 +29,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume 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 and selects the mode: @@ -153,7 +158,7 @@ guidance is the entire loader contract. one handover document it writes. - Loader mode never edits a file, writes a new file, or changes plan or task state. -- Never invoke another skill, sibling package, or workflow command. +- Never invoke another SCE skill, sibling SCE package, or SCE workflow command. - Never treat a file outside `context/handovers/`, or a non-Markdown file, as a loadable handover. - Never create the `context/` root; `sce setup --bootstrap-context` owns that. diff --git a/.pi/skills/sce-next-task/SKILL.md b/.pi/skills/sce-next-task/SKILL.md index 9ba319be..6bc2e8a4 100644 --- a/.pi/skills/sce-next-task/SKILL.md +++ b/.pi/skills/sce-next-task/SKILL.md @@ -10,9 +10,9 @@ description: > 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command except `sce-decision`, and invoke `sce-decision` only from the -successful context-synchronization decision gate. Follow the canonical workflow's steps, gates, +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. ## Phase references @@ -49,6 +49,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume this same skill in the same session. Never expose an internal phase result as the workflow's final response. +Relevant non-SCE skills may be used as helper capabilities during the active step. +They are not workflow handoffs: when a helper returns, control returns to the active +step. Helper use must preserve the canonical phase order, gates, waits, writes, +validation, stops, and terminal user-visible output. + ## Input Parse `$ARGUMENTS` into three positional parts before invoking any phase: diff --git a/.pi/skills/sce-next-task/references/context-sync.md b/.pi/skills/sce-next-task/references/context-sync.md index 06413b09..3c5cb8b4 100644 --- a/.pi/skills/sce-next-task/references/context-sync.md +++ b/.pi/skills/sce-next-task/references/context-sync.md @@ -310,7 +310,8 @@ Do not: - Create the context root. `sce setup --bootstrap-context` owns that. - Narrate changed files as documentation. Feature existence is the only reason to document a change that introduced no other durable knowledge. -- Invoke any sibling skill except `sce-decision`, or invoke `sce-decision` - outside the decision gate in successful context synchronization. +- Invoke any sibling SCE skill, sibling SCE package, or SCE workflow command + 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. diff --git a/.pi/skills/sce-validate/SKILL.md b/.pi/skills/sce-validate/SKILL.md index d109947e..8572da99 100644 --- a/.pi/skills/sce-validate/SKILL.md +++ b/.pi/skills/sce-validate/SKILL.md @@ -10,9 +10,9 @@ description: > 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command except `sce-decision`, and invoke `sce-decision` only from the -successful context-synchronization decision gate. Follow the canonical workflow's steps, gates, +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. ## Phase references @@ -49,6 +49,11 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume this same skill in the same session. Never expose an internal phase result as the workflow's final response. +Relevant non-SCE skills may be used as helper capabilities during the active step. +They are not workflow handoffs: when a helper returns, control returns to the active +step. Helper use must preserve the canonical phase order, gates, waits, writes, +validation, stops, and terminal user-visible output. + ## Input `$ARGUMENTS` is the plan name or plan path. diff --git a/.pi/skills/sce-validate/references/context-sync.md b/.pi/skills/sce-validate/references/context-sync.md index d6a45d46..bdd0c223 100644 --- a/.pi/skills/sce-validate/references/context-sync.md +++ b/.pi/skills/sce-validate/references/context-sync.md @@ -1,21 +1,39 @@ -# Plan context synchronization phase +# SCE Plan Context Sync -Run this phase for step 2 of the workflow, and only with a `Status: validated` -Markdown result from the validation phase. It is the plan-level final context -pass: it starts from the plan's `Context sync` requirements and the validated -implementation, and closes gaps that remain after any task-level syncs already -ran. +## Purpose -Do not run this phase for `failed` or `blocked`. Those are not success states. -Same rule as the task context synchronization phase: context sync runs only after -a successful prior phase. +Reconcile one fully validated plan with the repository's durable context and +return a Markdown report. -Pass the validated result verbatim. It is the authoritative handoff, and this -phase owns reading the plan path, required context paths, validation evidence, -and reported context impact out of it. +This phase owns: -Do not restate, summarize, or reconstruct any part of the validation result. Do -not reconstruct a missing validation result from conversation history. +- Validating the validation handoff. +- Confirming the context root exists. +- Discovering the context required by the finished plan. +- Deciding whether durable context changed. +- Editing and verifying the affected context files. +- Returning one Markdown synchronization report. + +Use the report format in: + +`references/sync-report.md` + +Task-level context sync may already have run after individual tasks. This phase +is the plan-level final pass: it starts from the plan's `Context sync` +requirements and the validated implementation, and closes gaps that remain. + + + +## Input + +The complete Markdown result returned by the validation phase. + +The validation result must report: + +```markdown +**Status:** validated +**Plan:** {plan path} +``` Treat that Markdown as the authoritative handoff for: @@ -25,7 +43,15 @@ Treat that Markdown as the authoritative handoff for: - Scaffolding removals. - Reported context impact, required context paths, and affected areas. -## 2.1 Validate the validation handoff +This phase must not be invoked for `failed` or `blocked` validation results. +Those are not success states. Same rule as `sce-task-context-sync`: context sync +runs only after a successful prior phase. + +Do not reconstruct a missing validation result from conversation history. + +## Workflow + +### 1. Validate the validation handoff Confirm that: @@ -35,26 +61,26 @@ Confirm that: - Commands run are present. - A context-impact classification is present. -If the handoff is missing required information or is internally contradictory, do -not modify context. Return a `blocked` Markdown report. +If the handoff is missing required information or is internally contradictory, +do not modify context. Return a `blocked` Markdown report. -## 2.2 Confirm the context root +### 2. Confirm the context root -When `context/` does not exist, there is no durable memory to synchronize. Do not -create it, and do not write context files outside it. +When `context/` does not exist, there is no durable memory to synchronize. +Do not create it, and do not write context files outside it. Return a `blocked` report whose required action is: `sce setup --bootstrap-context` -State that validation itself succeeded and is recorded in the plan, and that plan -context synchronization should run again once the context root exists. +State that validation itself succeeded and is recorded in the plan, and that +plan context synchronization should run again once the context root exists. Bootstrapping is the user's action, not this phase's. -## 2.3 Discover applicable context +### 3. Discover applicable context -Start with the validated internal state: +Start with the validated Markdown result: - **Context impact** classification, required context, and affected areas. - Acceptance-criteria evidence. @@ -80,7 +106,7 @@ Do not scan or rewrite the entire `context/` tree by default. Do not create a new context file when an existing authoritative file can be updated coherently. -### The mandatory root pass +#### The mandatory root pass Every invocation verifies these five files against code truth, whatever the reported classification is: @@ -93,19 +119,19 @@ reported classification is: Verifying is not editing. A classification that warrants no root edit still requires reading each of these and confirming it is not contradicted by the -finished implementation. A file that is absent is a gap; record it in the report -rather than creating it to satisfy the pass. +finished implementation. A file that is absent is a gap; record it in the +report rather than creating it to satisfy the pass. -Report each of the five as verified or edited. Never declare synchronization done -while one of them is unchecked. +Report each of the five as verified or edited. Never declare synchronization +done while one of them is unchecked. -### Plan context requirements +#### Plan context requirements Every path or statement listed under the plan's `Context sync` section must be accounted for in the report as already accurate or updated. A requirement the finished code still does not satisfy is a blocker, not a note. -## 2.4 Determine whether durable context changed +### 4. Determine whether durable context changed Use the reported context impact as a strong hint, then verify it against the finished implementation and existing context. @@ -130,11 +156,11 @@ Do not document: - Generic engineering practices. Interpret impact classifications as follows. Each governs which files are -*edited*; none of them waives the mandatory root pass or the plan's Context sync -requirements. +*edited*; none of them waives the mandatory root pass or the plan's Context +sync requirements. -- `none`: Make no edits beyond any correction the root pass or unmet plan context - requirement turns up. +- `none`: Make no edits beyond any correction the root pass or unmet plan + context requirement turns up. - `local`: Update the nearest existing authoritative context only when the new behavior is not reliably discoverable from code. - `domain`: Update affected domain context and the context map when its links or @@ -144,7 +170,7 @@ requirements. If the reported classification is inconsistent with the actual change, use the verified classification and explain the difference in the report. -## 2.5 Record qualifying architecture decisions +### 5. Record qualifying architecture decisions During this successful synchronization, determine whether the completed change establishes or changes a system-wide important constraint involving one or more @@ -187,7 +213,7 @@ handoff and during context synchronization. Do not invoke it from a non-success branch or for any non-decision purpose. When no decision qualifies, continue without invoking it and record that outcome in synchronization evidence. -## 2.6 Synchronize context +### 6. Synchronize context Make the smallest coherent documentation change that preserves repository truth. @@ -207,47 +233,47 @@ Create a new context file only when: - No existing file owns it coherently. - The new file has a clear place in the context map. -### Feature existence +#### Feature existence Every feature the finished plan implemented must have at least one durable canonical description discoverable from `context/`, in a domain file under `context/{domain}/` or in `context/overview.md` for a cross-cutting feature. When the plan delivered a feature no context file describes, add that -description. Prefer a small, precise domain file over overloading `overview.md` -with detail. +description. Prefer a small, precise domain file over overloading +`overview.md` with detail. -This is not license to narrate the diff: describe what the feature is and how it -behaves, not what was edited during the plan. +This is not license to narrate the diff: describe what the feature is and how +it behaves, not what was edited during the plan. -### Glossary +#### Glossary Add a `context/glossary.md` entry for any domain language the plan introduced. New terminology is durable knowledge whatever the classification is. -### File hygiene +#### File hygiene Every context file this phase writes must satisfy: - One topic per file. -- At most 250 lines. When an edit would push a file past 250 lines, split it into - focused files and link them rather than letting it grow. +- At most 250 lines. When an edit would push a file past 250 lines, split it + into focused files and link them rather than letting it grow. - Relative paths in every link to another context file. -- A Mermaid diagram where structure, boundaries, or flows are complex enough that - prose alone would not carry them. +- A Mermaid diagram where structure, boundaries, or flows are complex enough + that prose alone would not carry them. - Concrete code examples only where they clarify non-trivial behavior. When detail outgrows a shared file, migrate it into `context/{domain}/`, leave a concise pointer behind, and link the new file from `context/context-map.md`. -## 2.7 Verify synchronization +### 7. Verify synchronization After edits, verify: - Every changed context file accurately reflects the finished implementation. - No edited statement contradicts the code, plan, or validation evidence. -- Every qualifying decision has one written or reused ADR path in the report, and - the report states when no decision qualified. +- Every qualifying decision has one written or reused ADR path in the report, + and the report states when no decision qualified. - Every file in the mandatory root pass was read and confirmed against code truth, whether or not it was edited. - Every plan `Context sync` requirement is met. @@ -270,19 +296,20 @@ If synchronization cannot be completed without inventing facts or resolving a material contradiction, preserve safe edits when appropriate and return a `blocked` report. -## 2.8 Return the Markdown report +### 8. Return the Markdown report -Set exactly one report status: +Return exactly one report status: - `synced` - `no_context_change` - `blocked` -`synced` means context files were updated and verified. `no_context_change` means -existing context was checked and no edit was warranted. `blocked` means context -could not be synchronized safely. +`synced` means context files were updated and verified. `no_context_change` +means existing context was checked and no edit was warranted. `blocked` means +context could not be synchronized safely. -Record only the Markdown report. Do not add explanatory prose before or after it. +Return only the Markdown report. Do not add explanatory prose before or after +it. ## Plan context synchronization boundaries @@ -298,9 +325,26 @@ Do not: - Select or execute an implementation task. - Create a Git commit or push changes. - Create the context root. `sce setup --bootstrap-context` owns that. -- Narrate changed files as documentation. Feature existence is the only reason to - document a change that introduced no other durable knowledge. -- Invoke any sibling skill except `sce-decision`, or invoke `sce-decision` - outside the decision gate in successful context synchronization. +- Narrate changed files as documentation. Feature existence is the only reason + to document a change that introduced no other durable knowledge. +- Invoke any sibling SCE skill, sibling SCE package, or SCE workflow command + except `sce-decision`, or invoke `sce-decision` outside the decision gate in + successful context synchronization. - Delete a context file that has uncommitted changes. -- Return internal state. +- Return YAML. + +## Completion + +The phase is complete after: + +- The context root was confirmed, or a `blocked` report named + `sce setup --bootstrap-context` as the required action. +- The mandatory root pass was run. +- Plan context requirements were checked. +- The decision gate recorded every qualifying ADR path, found no qualifying + decision, or returned a synchronization blocker. +- Applicable durable context was synchronized and verified, no context change + was warranted, or a synchronization blocker was reported. +- One Markdown report matching `references/sync-report.md` was returned. + + diff --git a/.pi/skills/sce-validate/references/output.md b/.pi/skills/sce-validate/references/output.md index 88c75575..9cc8a19b 100644 --- a/.pi/skills/sce-validate/references/output.md +++ b/.pi/skills/sce-validate/references/output.md @@ -1,30 +1,3 @@ -# Validate output layouts - -Use only the applicable layout. Values come from internal workflow state. - -The `blocked` and `failed` layouts are stated once, under **Validation Result** -below. - -## Context synchronization blocked - -State that validation passed and its report is recorded, then report the context -failure, preserved edits, required action, and retry condition. State that durable -context remains out of date and synchronization must finish before closure. - -## Completion - -```markdown -------------------------------------- - -# Plan {plan-name} validated. - -All implementation tasks were already complete. -Final validation passed. -Durable context is synchronized. - -Validation report: {plan-path} -``` - # Validation Result Return only one completed Markdown report using the applicable variant below. @@ -37,8 +10,8 @@ The `Status` value must be exactly one of: - `blocked` The plan-file `## Validation Report` section is written separately using -`references/validation-report.md`. This layout carries the validation phase's -result into the workflow's own branches. +`references/validation-report.md`. This file is the skill's return value to the +invoking workflow. ## Validated variant @@ -205,171 +178,9 @@ returns `validated` and plan context sync completes. - The failed variant must be self-contained enough to hand to another session without the original chat. - Include **Context impact** only on `validated`. Omit it on `failed` and - `blocked`; plan context sync is not run for non-success states. + `blocked`; plan context sync is not invoked for non-success states. - Do not include context synchronization results in this report. The invoking - workflow runs the **Plan context synchronization phase** only after `validated`. + workflow runs `sce-plan-context-sync` only after `validated`. - Do not select or describe an unrelated next implementation task when status is `validated`. - Omit empty optional sections rather than writing placeholders. - -# Plan Context Sync Report - -Return only one completed Markdown report using the applicable variant below. -Do not include unused sections, placeholders, YAML, or a fenced code block. - -The `Status` value must be exactly one of: - -- `synced` -- `no_context_change` -- `blocked` - -The input validation status is always `validated` and does not need to be -repeated as a separate workflow state. This report is not produced for -`failed` or `blocked` validation results. - -## Synced variant - -# Plan Context Sync Report - -**Status:** synced -**Plan:** `{plan path}` - -## Context impact - -**Classification:** `{local | domain | root}` -**Affected areas:** `{comma-separated areas}` - -{Explain which durable behavior, architecture, terminology, operation, or -constraint required plan-level synchronization after validation.} - -## Plan context requirements - -- `{required context path or statement from the plan}` — {met by edit | already accurate} - -## Updated context - -- `{context file}` — {concise description of the durable truth updated} - -## Architecture decisions - -- `{written or reused ADR path}` — {decision and status} -- None qualified. - -## Root pass - -- `context/overview.md` — {verified | edited | absent} -- `context/architecture.md` — {verified | edited | absent} -- `context/glossary.md` — {verified | edited | absent} -- `context/patterns.md` — {verified | edited | absent} -- `context/context-map.md` — {verified | edited | absent} - -## Feature existence - -- `{feature}` — `{context file that canonically describes it}` - -## Verification - -- {How the edited context was checked against the finished implementation and validation evidence.} -- {File hygiene: line counts, relative links, diagrams where structure is complex.} -- {Documentation, link, or formatting checks that were run, when applicable.} - -## Notes - -{Include only non-blocking information worth retaining. -Omit this section when unnecessary.} - ---- - -## No-context-change variant - -# Plan Context Sync Report - -**Status:** no_context_change -**Plan:** `{plan path}` - -## Context impact - -**Classification:** none - -{Explain why the finished plan introduced no durable, non-obvious repository -knowledge requiring an update, or why existing context already matched.} - -## Plan context requirements - -- `{required context path or statement from the plan}` — already accurate -- None listed by the plan. - -## Context reviewed - -- `{context file or area}` — {what was checked and why it remains accurate} - -## Architecture decisions - -- `{reused ADR path}` — {decision and status} -- None qualified. - -## Root pass - -- `context/overview.md` — {verified | absent} -- `context/architecture.md` — {verified | absent} -- `context/glossary.md` — {verified | absent} -- `context/patterns.md` — {verified | absent} -- `context/context-map.md` — {verified | absent} - -## Feature existence - -- `{feature}` — `{context file that canonically describes it}`, already present. - -## Verification - -- {How existing context was compared with the finished implementation and validation evidence.} - ---- - -## Blocked variant - -# Plan Context Sync Report - -**Status:** blocked -**Plan:** `{plan path}` - -## Blocker - -**Problem:** {specific synchronization blocker} -**Impact:** {why context cannot be made authoritative safely} -**Required action:** {decision or correction required} - -## Context changes - -- {List safe context edits preserved, or state `No context files were changed.`} - -## Architecture decisions - -- `{ADR path written or reused before the blocker}` — {decision and status} -- None written or reused before the blocker. - -## Retry condition - -{State the concrete condition under which plan context synchronization should -run again.} - -## Report rules - -- Name exact context files when they were changed or reviewed. -- Under **Architecture decisions**, list every ADR path written or reused during - the decision gate. In a successful report, state `None qualified.` when the - gate skipped invocation. In a blocked report, state - `None written or reused before the blocker.` when applicable. -- Report every file in the root pass, including any that is absent. -- Report the missing context root as `blocked`, with `sce setup - --bootstrap-context` as the required action and the existence of `context/` as - the retry condition. -- Cover every path or statement listed in the plan's `Context sync` section - under **Plan context requirements**. -- Omit **Feature existence** only when the plan implemented no feature. -- Describe durable truth, not validation-session chronology. -- Keep evidence concise and factual. -- Do not claim implementation tasks remain open. -- Do not reopen validation checks. -- Do not recommend a next implementation task unless context cannot be repaired - without one, and then only as the required action. diff --git a/.pi/skills/sce-validate/references/validation-report.md b/.pi/skills/sce-validate/references/validation-report.md index deaa9a0b..c99ad85e 100644 --- a/.pi/skills/sce-validate/references/validation-report.md +++ b/.pi/skills/sce-validate/references/validation-report.md @@ -1,14 +1,14 @@ -# Internal persisted-document format: Plan-file validation report +# Plan-file Validation Report -The Markdown section the **Validation phase** appends to the plan file when -returning `validated` or `failed`. Write it at the end of -`context/plans/{plan_name}.md` under exactly one `## Validation Report` heading. +The Markdown section `sce-validation` appends to the plan file when returning +`validated` or `failed`. Write it at the end of `context/plans/{plan_name}.md` +under exactly one `## Validation Report` heading. This is plan-file content. The result returned to the workflow is defined -separately in `references/output.md`. +separately in `references/validation-result.md`. -Do not author this section while planning. Only `/validate` through the -**Validation phase** writes it. +Do not author this section while planning. Only `/validate` through `sce-validation` +writes it. ## Layout @@ -58,14 +58,14 @@ After repairs, rerun: 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. +- 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. + 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 **Scaffolding removed**, list only temporary debug code, intermediate artifacts, or throwaway files introduced during the change. Write `None.` when nothing temporary remained. diff --git a/.pi/skills/sce-validate/references/validation.md b/.pi/skills/sce-validate/references/validation.md index 38e8944f..08d7f5a8 100644 --- a/.pi/skills/sce-validate/references/validation.md +++ b/.pi/skills/sce-validate/references/validation.md @@ -1,42 +1,60 @@ -# Validation phase +# SCE Validation -Run this phase for step 1 of the workflow. It resolves one plan, confirms the -implementation is finished, runs the plan's checks, and records what it found. +## Purpose -Input: the plan name or path, unmodified. +Prove that one finished SCE plan meets its acceptance criteria and repository +validation bar, then record the evidence on the plan and return one Markdown +result. -This phase exclusively owns: +This phase owns: - Resolving one plan. - Confirming every implementation task is complete. -- Running full validation and acceptance-criteria checks. -- Removing temporary scaffolding. +- Running the plan's full validation commands and each acceptance criterion + check. +- Removing temporary scaffolding introduced by the change. - Writing the Validation Report into the plan. +- Marking acceptance criteria against the evidence. - Returning one Markdown validation result. -Do not duplicate any of it elsewhere in the workflow. +Return a result matching: -## 1.1 Resolve the plan +`references/validation-result.md` + +Write plan-file evidence matching: + +`references/validation-report.md` + +Context synchronization is not this phase's job. The invoking `/validate` +workflow runs `sce-plan-context-sync` only after a `validated` result. + +## Input + +A plan name or path. + +## Workflow + +### 1. Resolve the plan Resolve the supplied plan name or path to exactly one existing plan under `context/plans/`. -When no plan can be found, set internal status `blocked`. +When no plan can be found, return `blocked`. -When multiple plans match and none can be selected safely, set internal status -`blocked` with the matching candidates. +When multiple plans match and none can be selected safely, return `blocked` +with the matching candidates. Read the selected plan before exploring the repository. -## 1.2 Confirm implementation is finished +### 2. Confirm implementation is finished -Set internal status `blocked` with incomplete tasks listed when any -implementation task remains incomplete. +Return `blocked` with incomplete tasks listed when any implementation task +remains incomplete. Final validation measures finished work. Do not run the full suite against a partial stack, and do not complete remaining tasks here. -## 1.3 Read the validation contract from the plan +### 3. Read the validation contract from the plan From the plan, collect: @@ -44,15 +62,14 @@ From the plan, collect: - The `Full validation` command list. - The `Context sync` requirements, for the context-impact handoff only. -Set internal status `blocked` when the plan has no usable acceptance criteria, or -when no validation commands can be determined from the plan or repository -conventions. +Return `blocked` when the plan has no usable acceptance criteria, or when no +validation commands can be determined from the plan or repository conventions. Prefer the plan's authored checks. Fall back to repository-primary test, lint, and format commands only when `Full validation` is absent, and record that fallback under notes on a `validated` or `failed` result. -## 1.4 Remove temporary scaffolding +### 4. Remove temporary scaffolding Before or while running checks, remove temporary scaffolding introduced during the change when it is clearly throwaway: @@ -65,7 +82,7 @@ Do not delete durable product code, tests, configuration, or context files. Record every removed path. When nothing temporary remains, report `None.` -## 1.5 Run full validation and acceptance checks +### 5. Run full validation and acceptance checks Run the plan's `Full validation` commands. @@ -81,16 +98,16 @@ not this skill. Never report a check as passed unless it ran successfully or the authorized inspection confirmed the criterion. -Do not run task-by-task implementation work for incomplete tasks. That belongs to -`/next-task`. +Do not run task-by-task implementation work for incomplete tasks. That belongs +to `/next-task`. -## 1.6 Update the plan +### 6. Update the plan For `validated` and `failed` outcomes: - Mark each acceptance criterion checkbox to match the evidence. - Append or replace the plan's `## Validation Report` section using - `references/validation-report.md`. Read that file before writing the section. + `references/validation-report.md`. - When status is `failed`, the plan-file report must include the retry command `/validate {plan path}`. @@ -98,11 +115,10 @@ Do not reopen completed tasks, rewrite task evidence, or change the task stack. For `blocked`, leave the plan file unchanged. -## 1.7 Determine context impact for the handoff +### 7. Determine context impact for the handoff -On `validated` only, classify the durable context impact of the finished plan so -the **Plan context synchronization phase** can start from the plan's own -requirements: +On `validated` only, classify the durable context impact of the finished plan +so `sce-plan-context-sync` can start from the plan's own requirements: - Start from the plan's `Context sync` section. - Inspect what the completed implementation actually changed when needed. @@ -114,33 +130,20 @@ Do not edit context files here. On `failed` or `blocked`, omit context impact; context sync will not run. -## 1.8 Return the internal state +### 8. Return the Markdown result -Set exactly one internal state: +Return exactly one Markdown result: - `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 `references/output.md`, ending - recommended work with `/validate {plan path}`. + unsatisfied. Shape it as a session handoff per + `references/validation-result.md`, ending recommended work with + `/validate {plan path}`. - `blocked` when validation cannot proceed safely. -Record only the Markdown report. Do not add explanatory prose before or after it. -Do not return internal state. - -A `validated` result is the authoritative handoff into step 2, which reads the -plan path, required context paths, validation evidence, and reported context -impact out of it. It must report: - -```markdown -**Status:** validated -**Plan:** {plan path} -``` - -and must carry the resolved plan path, validation commands and outcomes, -acceptance-criteria evidence, scaffolding removals, and the reported context -impact with required context paths and affected areas. Step 2 is forbidden from -reconstructing any of that, so it has to be present here. +Return only the Markdown report. Do not add explanatory prose before or after +it. Do not return YAML. ## Validation boundaries @@ -157,5 +160,16 @@ Do not: - Create a Git commit or push changes. - Invent acceptance criteria the plan does not state. - Claim verification that was not performed. -- Return a internal state. -- Run plan context synchronization. The workflow owns that step. +- Return a YAML result. +- Invoke plan context sync. The workflow owns that step. +## Completion + +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 `references/validation-result.md` was + returned. + + diff --git a/config/pkl/base/workflow-brownfield.pkl b/config/pkl/base/workflow-brownfield.pkl index e5c55d2f..06b587b6 100644 --- a/config/pkl/base/workflow-brownfield.pkl +++ b/config/pkl/base/workflow-brownfield.pkl @@ -39,8 +39,8 @@ local titleAndPurpose = model.semanticReference.apply( 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-skill handoffs. Do not invoke another SCE skill, sibling package, or - workflow command. Follow the canonical workflow's steps, gates, + 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. \(scopeStatement) @@ -58,6 +58,8 @@ local titleAndPurpose = model.semanticReference.apply( canonical workflow says to continue. Stop only at a user wait or terminal branch. Clarification and bootstrap waits resume this same skill in the same session. Never expose an internal phase result as the workflow's final response. + + \(model.helperSkillCompositionRule) """ + "\n\n", scopeStatement + "\n\n" ) @@ -356,7 +358,7 @@ local renderSkillBody = (mode: model.WorkflowRenderMode) -> """ - Never write a fact scoring below `50` as truth. - Never resolve a material contradiction without disclosing it. - Never write a confidence score, hash, timestamp, or date under `context/`. - - Never invoke another skill, sibling package, or workflow command. + - Never invoke another SCE skill, sibling SCE package, or SCE workflow command. - Never synchronize context, validate a plan, select or execute a task, or create a Git commit. - Never treat this workflow as recurring context maintenance. diff --git a/config/pkl/base/workflow-change-to-plan.pkl b/config/pkl/base/workflow-change-to-plan.pkl index f76222db..097d9fc2 100644 --- a/config/pkl/base/workflow-change-to-plan.pkl +++ b/config/pkl/base/workflow-change-to-plan.pkl @@ -7,8 +7,8 @@ changeToPlanSkillBody = """ 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command. Follow the canonical workflow's steps, gates, +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. ## Phase references @@ -45,6 +45,8 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume this same skill in the same session. Never expose an internal phase result as the workflow's final response. +\(model.helperSkillCompositionRule) + ## Input `$ARGUMENTS` is the change request, in free-form prose. diff --git a/config/pkl/base/workflow-commit.pkl b/config/pkl/base/workflow-commit.pkl index 8db36282..d157895e 100644 --- a/config/pkl/base/workflow-commit.pkl +++ b/config/pkl/base/workflow-commit.pkl @@ -708,8 +708,8 @@ local commitSkillBody = """ 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command. Follow the canonical workflow's steps, gates, +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. ## Phase reference @@ -738,6 +738,8 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume this same skill in the same session. Never expose an internal phase result as the workflow's final response. +\(model.helperSkillCompositionRule) + ## Input `$ARGUMENTS` is optional. Split it into two parts before invoking the skill: diff --git a/config/pkl/base/workflow-content.pkl b/config/pkl/base/workflow-content.pkl index d9f682e7..9c5bd268 100644 --- a/config/pkl/base/workflow-content.pkl +++ b/config/pkl/base/workflow-content.pkl @@ -169,6 +169,15 @@ hidden commandBanner = (workflowName: String) -> packageOnlyBlock.apply("\(workf hidden inlinePhaseBody = (phaseBody: WorkflowBody) -> compositeOnlyBlock.apply(phaseBody.render.apply("composite")) +/// Non-SCE skills may help with work inside the active workflow step without +/// becoming an alternate owner of the workflow's control flow. +helperSkillCompositionRule = """ +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. +""" + /// Canonical composite workflow bodies and package-local references for the /// four phase-based workflows. Target renderers add only supported entrypoint /// frontmatter; all operational and persisted-document content remains @@ -180,9 +189,9 @@ nextTaskSkillBody = """ 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command except `sce-decision`, and invoke `sce-decision` only from the -successful context-synchronization decision gate. Follow the canonical workflow's steps, gates, +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. ## Phase references @@ -219,6 +228,8 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume this same skill in the same session. Never expose an internal phase result as the workflow's final response. +\(helperSkillCompositionRule) + ## Input Parse `$ARGUMENTS` into three positional parts before invoking any phase: @@ -342,9 +353,9 @@ validateSkillBody = """ 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-skill handoffs. Do not invoke another SCE skill, sibling package, or -workflow command except `sce-decision`, and invoke `sce-decision` only from the -successful context-synchronization decision gate. Follow the canonical workflow's steps, gates, +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. ## Phase references @@ -381,6 +392,8 @@ Approval, clarification, revision, failed-validation repair, and bootstrap waits resume this same skill in the same session. Never expose an internal phase result as the workflow's final response. +\(helperSkillCompositionRule) + ## Input `$ARGUMENTS` is the plan name or plan path. diff --git a/config/pkl/base/workflow-context-sync.pkl b/config/pkl/base/workflow-context-sync.pkl index a06a34ce..404c36a0 100644 --- a/config/pkl/base/workflow-context-sync.pkl +++ b/config/pkl/base/workflow-context-sync.pkl @@ -416,8 +416,9 @@ local taskRoleData = new SyncRole { - Create the context root. `sce setup --bootstrap-context` owns that. - Narrate changed files as documentation. Feature existence is the only reason to document a change that introduced no other durable knowledge. - - Invoke any sibling skill except `sce-decision`, or invoke `sce-decision` - outside the decision gate in successful context synchronization. + - Invoke any sibling SCE skill, sibling SCE package, or SCE workflow command + except `sce-decision`, or invoke `sce-decision` outside the decision gate in + successful context synchronization. - Delete a context file that has uncommitted changes. - \(returnExecutionStyleResult.render.apply(mode)). """ @@ -749,8 +750,9 @@ local planRoleData = new SyncRole { - Create the context root. `sce setup --bootstrap-context` owns that. - Narrate changed files as documentation. Feature existence is the only reason to document a change that introduced no other durable knowledge. - - Invoke any sibling skill except `sce-decision`, or invoke `sce-decision` - outside the decision gate in successful context synchronization. + - Invoke any sibling SCE skill, sibling SCE package, or SCE workflow command + except `sce-decision`, or invoke `sce-decision` outside the decision gate in + successful context synchronization. - Delete a context file that has uncommitted changes. - \(returnInternalState.render.apply(mode)). """ @@ -1390,8 +1392,9 @@ Do not: - Create the context root. `sce setup --bootstrap-context` owns that. - Narrate changed files as documentation. Feature existence is the only reason to document a change that introduced no other durable knowledge. -- Invoke any sibling skill except `sce-decision`, or invoke `sce-decision` - outside the decision gate in successful context synchronization. +- Invoke any sibling SCE skill, sibling SCE package, or SCE workflow command + 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. """ diff --git a/config/pkl/base/workflow-handover.pkl b/config/pkl/base/workflow-handover.pkl index 239487cb..4232bb0b 100644 --- a/config/pkl/base/workflow-handover.pkl +++ b/config/pkl/base/workflow-handover.pkl @@ -29,8 +29,8 @@ local titleAndPurpose = model.packageOnlyBlock.apply(""" user-visible response. This is a two-mode, single-pass workflow: writer mode captures the current session and repository state as one durable handover document; loader mode reads back an existing handover for continuation in - another session. Neither mode invokes another skill, sibling package, or - workflow command, and neither mode waits for user input mid-run. + another session. Neither mode invokes another SCE skill, sibling SCE package, or + SCE workflow command, and neither mode waits for user input mid-run. ## User-visible output @@ -38,6 +38,8 @@ local titleAndPurpose = model.packageOnlyBlock.apply(""" 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. + + \(model.helperSkillCompositionRule) """) local renderPersistedFormatBody = """ @@ -220,7 +222,7 @@ local renderSkillBody = (mode: model.WorkflowRenderMode) -> """ one handover document it writes. - Loader mode never edits a file, writes a new file, or changes plan or task state. - - Never invoke another skill, sibling package, or workflow command. + - Never invoke another SCE skill, sibling SCE package, or SCE workflow command. - Never treat a file outside `context/handovers/`, or a non-Markdown file, as a loadable handover. - Never create the `context/` root; `sce setup --bootstrap-context` owns that. diff --git a/config/pkl/check-generated.sh b/config/pkl/check-generated.sh index c7bca18e..3df9a904 100755 --- a/config/pkl/check-generated.sh +++ b/config/pkl/check-generated.sh @@ -96,6 +96,18 @@ expect_pkl_fixture_failure \ expect_pkl_fixture_failure \ "config/pkl/renderers/fixtures/output-dedup-check.pkl" \ "generated SKILL.md reproduces a references/output.md fenced layout verbatim" +expect_pkl_fixture_failure \ + "config/pkl/renderers/fixtures/unscoped-skill-prohibition-check.pkl" \ + "generated workflow skill contains an unscoped skill prohibition" +expect_pkl_fixture_failure \ + "config/pkl/renderers/fixtures/missing-helper-skill-rule-check.pkl" \ + "generated workflow skill is missing the required helper-skill composition rule" +expect_pkl_fixture_failure \ + "config/pkl/renderers/fixtures/opencode-arbitrary-sce-permission-check.pkl" \ + "OpenCode skill permissions must reject arbitrary SCE permissions" +expect_pkl_fixture_failure \ + "config/pkl/renderers/fixtures/opencode-skill-permission-order-check.pkl" \ + "OpenCode skill permissions must preserve the wildcard, deny, and explicit-allow order" "$producer" "$repo_root" "$generated_input_root" generated_root="$generated_input_root/pkl-generated" diff --git a/config/pkl/renderers/fixtures/blank-line-run-check.pkl b/config/pkl/renderers/fixtures/blank-line-run-check.pkl index caa27f1c..2fe9a16d 100644 --- a/config/pkl/renderers/fixtures/blank-line-run-check.pkl +++ b/config/pkl/renderers/fixtures/blank-line-run-check.pkl @@ -11,4 +11,4 @@ local documentsWithBlankLineRun = new Mapping { result = if ( documentsWithBlankLineRun.every((_, text) -> !text.contains("\n\n\n")) ) "negative fixture unexpectedly contained no blank-line run" -else error("generated workflow document contains two or more consecutive blank lines") +else throw("generated workflow document contains two or more consecutive blank lines") diff --git a/config/pkl/renderers/fixtures/extra-artifact-check.pkl b/config/pkl/renderers/fixtures/extra-artifact-check.pkl index da8bb718..c9cfc8b6 100644 --- a/config/pkl/renderers/fixtures/extra-artifact-check.pkl +++ b/config/pkl/renderers/fixtures/extra-artifact-check.pkl @@ -11,4 +11,4 @@ result = if ( artifactsWithExtraPath.length == contract.expectedArtifactPaths.length && contract.expectedArtifactPaths.every((path, _) -> artifactsWithExtraPath.containsKey(path)) ) "negative fixture unexpectedly matched" -else error("generated artifact inventory does not match the exact expected path contract") +else throw("generated artifact inventory does not match the exact expected path contract") diff --git a/config/pkl/renderers/fixtures/forbidden-workflow-reference-check.pkl b/config/pkl/renderers/fixtures/forbidden-workflow-reference-check.pkl index 7af58fac..05903da7 100644 --- a/config/pkl/renderers/fixtures/forbidden-workflow-reference-check.pkl +++ b/config/pkl/renderers/fixtures/forbidden-workflow-reference-check.pkl @@ -11,4 +11,4 @@ local documentsWithForbiddenReference = new Mapping { result = if ( documentsWithForbiddenReference.every((_, text) -> !text.contains("sce-plan-review")) ) "negative fixture unexpectedly contained no forbidden reference" -else error("generated workflow document contains a forbidden sibling-package reference or unresolved internalization token") +else throw("generated workflow document contains a forbidden sibling-package reference or unresolved internalization token") diff --git a/config/pkl/renderers/fixtures/missing-artifact-check.pkl b/config/pkl/renderers/fixtures/missing-artifact-check.pkl index 9c2a96d4..2385c967 100644 --- a/config/pkl/renderers/fixtures/missing-artifact-check.pkl +++ b/config/pkl/renderers/fixtures/missing-artifact-check.pkl @@ -12,4 +12,4 @@ result = if ( artifactsWithMissingPath.length == contract.expectedArtifactPaths.length && contract.expectedArtifactPaths.every((path, _) -> artifactsWithMissingPath.containsKey(path)) ) "negative fixture unexpectedly matched" -else error("generated artifact inventory does not match the exact expected path contract") +else throw("generated artifact inventory does not match the exact expected path contract") diff --git a/config/pkl/renderers/fixtures/missing-helper-skill-rule-check.pkl b/config/pkl/renderers/fixtures/missing-helper-skill-rule-check.pkl new file mode 100644 index 00000000..7d294914 --- /dev/null +++ b/config/pkl/renderers/fixtures/missing-helper-skill-rule-check.pkl @@ -0,0 +1,23 @@ +import "../generation-contract-check.pkl" as contract + +local documentsWithoutHelperRule = new Mapping { + for (path, text in contract.workflowDocuments) { + [path] = if (path == "config/.claude/skills/sce-validate/SKILL.md") + "missing helper rule" + else text + } +} + +result = if ( + documentsWithoutHelperRule.every((path, text) -> + !path.endsWith("/SKILL.md") + || path.contains("/skills/sce-decision/") + || ( + text.contains("Relevant non-SCE skills may be used as helper capabilities during the active step.") + && text.contains("They are not workflow handoffs: when a helper returns, control returns to the active") + && text.contains("step. Helper use must preserve the canonical phase order, gates, waits, writes,") + && text.contains("validation, stops, and terminal user-visible output.") + ) + ) +) "negative fixture unexpectedly contained the helper rule in every workflow" +else throw("generated workflow skill is missing the required helper-skill composition rule") diff --git a/config/pkl/renderers/fixtures/opencode-arbitrary-sce-permission-check.pkl b/config/pkl/renderers/fixtures/opencode-arbitrary-sce-permission-check.pkl new file mode 100644 index 00000000..974fd455 --- /dev/null +++ b/config/pkl/renderers/fixtures/opencode-arbitrary-sce-permission-check.pkl @@ -0,0 +1,23 @@ +import "../generation-contract-check.pkl" as contract + +local renderedWithArbitraryPermission = """ +skill: + "*": allow + "sce-*": deny + "sce-next-task": allow + "sce-validate": allow + "sce-commit": allow + "sce-handover": allow + "sce-brownfield": allow + "sce-decision": allow + "sce-arbitrary": allow +--- +""" + +result = if ( + contract.assertOpenCodeSkillPermissionText.apply( + renderedWithArbitraryPermission, + "shared-context-code" + ) +) "negative fixture unexpectedly accepted an arbitrary SCE permission" +else throw("OpenCode skill permissions must reject arbitrary SCE permissions") diff --git a/config/pkl/renderers/fixtures/opencode-skill-permission-order-check.pkl b/config/pkl/renderers/fixtures/opencode-skill-permission-order-check.pkl new file mode 100644 index 00000000..8f6032cb --- /dev/null +++ b/config/pkl/renderers/fixtures/opencode-skill-permission-order-check.pkl @@ -0,0 +1,22 @@ +import "../generation-contract-check.pkl" as contract + +local renderedWithWrongOrder = """ +skill: + "sce-*": deny + "*": allow + "sce-next-task": allow + "sce-validate": allow + "sce-commit": allow + "sce-handover": allow + "sce-brownfield": allow + "sce-decision": allow +--- +""" + +result = if ( + contract.assertOpenCodeSkillPermissionText.apply( + renderedWithWrongOrder, + "shared-context-code" + ) +) "negative fixture unexpectedly accepted the wrong OpenCode permission order" +else throw("OpenCode skill permissions must preserve the wildcard, deny, and explicit-allow order") diff --git a/config/pkl/renderers/fixtures/output-dedup-check.pkl b/config/pkl/renderers/fixtures/output-dedup-check.pkl index cd04c92e..e7a22f20 100644 --- a/config/pkl/renderers/fixtures/output-dedup-check.pkl +++ b/config/pkl/renderers/fixtures/output-dedup-check.pkl @@ -20,4 +20,4 @@ result = if ( contract.fencedBlocksIn.apply(text).every((block) -> !skillText.contains(block)) ) ) "negative fixture unexpectedly contained no duplicated layout" -else error("generated SKILL.md reproduces a references/output.md fenced layout verbatim") +else throw("generated SKILL.md reproduces a references/output.md fenced layout verbatim") diff --git a/config/pkl/renderers/fixtures/unscoped-skill-prohibition-check.pkl b/config/pkl/renderers/fixtures/unscoped-skill-prohibition-check.pkl new file mode 100644 index 00000000..c4cd3240 --- /dev/null +++ b/config/pkl/renderers/fixtures/unscoped-skill-prohibition-check.pkl @@ -0,0 +1,18 @@ +import "../generation-contract-check.pkl" as contract + +local documentsWithUnscopedProhibition = new Mapping { + for (path, text in contract.workflowDocuments) { + [path] = if (path == "config/.opencode/skills/sce-next-task/SKILL.md") + "\(text)\nNever invoke another skill, sibling package, or workflow command." + else text + } +} + +result = if ( + documentsWithUnscopedProhibition.every((path, text) -> + !path.endsWith("/SKILL.md") + || path.contains("/skills/sce-decision/") + || !text.contains("Never invoke another skill") + ) +) "negative fixture unexpectedly contained no unscoped prohibition" +else throw("generated workflow skill contains an unscoped skill prohibition") diff --git a/config/pkl/renderers/generation-contract-check.pkl b/config/pkl/renderers/generation-contract-check.pkl index d4aebffb..7e1726ce 100644 --- a/config/pkl/renderers/generation-contract-check.pkl +++ b/config/pkl/renderers/generation-contract-check.pkl @@ -164,7 +164,27 @@ local requiredHandoverSkillTokens = new Listing { "Next Recommended Step" "Writer mode never overwrites an existing handover file" "Loading is read-only" - "Never invoke another skill, sibling package, or workflow command" + "Never invoke another SCE skill, sibling SCE package, or SCE workflow command" +} + +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" + "step. Helper use must preserve the canonical phase order, gates, waits, writes," + "validation, stops, and terminal user-visible output." +} + +local requiredScopedWorkflowTokens = new Listing { + "not inter-SCE workflow handoffs." + "Do not invoke another SCE skill, sibling SCE" + "SCE workflow command" +} + +local forbiddenUnscopedWorkflowTokens = new Listing { + "Never invoke another skill" + "Do not invoke another skill" + "never invoke another skill" + "not inter-skill handoffs" } /// The five behaviors `/brownfield` cannot lose without becoming a different @@ -279,6 +299,31 @@ local assertDecisionWorkflowReferences = (documents: Mapping) -> ) "generated decision invocation: synchronization-only" else throw("generated workflow document violates the synchronization-only sce-decision exception") +local expectedOpenCodeSkillPermission = (agentSlug: String) -> + let (ownedWorkflowLines = (new Listing { + for (_, workflow in catalog.workflows) { + when (workflow.openCodeAgentSlug == agentSlug) { + " \"\(workflow.skillSlug)\": allow" + } + } + }).join("\n")) + " \"*\": allow\n" + + " \"sce-*\": deny\n" + + ownedWorkflowLines + + if (agentSlug == "shared-context-code") "\n \"sce-decision\": allow" else "" + +hidden assertOpenCodeSkillPermissionText = (rendered: String, agentSlug: String) -> + rendered.split("skill:\n")[1].split("\n---")[0] + == expectedOpenCodeSkillPermission.apply(agentSlug) + +local assertOpenCodeSkillPermissions = (agents) -> + if ( + new Listing { "shared-context-plan"; "shared-context-code" }.every((agentSlug) -> + assertOpenCodeSkillPermissionText.apply(agents[agentSlug].rendered, agentSlug) + ) + ) "OpenCode skill permissions: ordered and catalog-derived" + else throw("OpenCode skill permissions must allow non-SCE skills, deny arbitrary SCE skills, and list only ordered catalog-owned workflows") + local assertOpenCodeDecisionPermission = (agents) -> let (codeAgent = agents["shared-context-code"].rendered) let (planAgent = agents["shared-context-plan"].rendered) @@ -288,6 +333,27 @@ local assertOpenCodeDecisionPermission = (agents) -> ) "OpenCode decision permission: code agent only" else throw("OpenCode sce-decision permission must be derived only for the code agent") +local assertWorkflowHelperComposition = (documents: Mapping) -> + if ( + documents.every((path, text) -> + !path.endsWith("/SKILL.md") + || requiredHelperSkillCompositionTokens.every((token) -> text.contains(token)) + ) + ) "generated workflow helper composition: complete" + else throw("generated workflow skill is missing the required helper-skill composition rule") + +local assertScopedWorkflowProhibitions = (documents: Mapping) -> + if ( + documents.every((path, text) -> + !path.endsWith("/SKILL.md") + || ( + requiredScopedWorkflowTokens.every((token) -> text.contains(token)) + && forbiddenUnscopedWorkflowTokens.every((token) -> !text.contains(token)) + ) + ) + ) "generated workflow prohibitions: SCE-scoped" + else throw("generated workflow skill contains an unscoped skill prohibition") + local assertDecisionDocumentPaths = (documents: Mapping) -> if ( documents.length == expectedDecisionDocumentPaths.length @@ -395,8 +461,11 @@ contractChecks { ["artifact-paths"] = assertExactArtifactPaths.apply(generatedArtifacts) ["optional-workflow-manifest"] = assertOptionalWorkflowManifest.apply(generatedArtifacts) ["workflow-references"] = assertWorkflowReferences.apply(workflowDocuments) + ["workflow-helper-composition"] = assertWorkflowHelperComposition.apply(compositeWorkflowDocuments) + ["workflow-prohibition-scope"] = assertScopedWorkflowProhibitions.apply(compositeWorkflowDocuments) ["phase-reference-contract"] = assertPhaseReferenceContract.apply(workflowDocuments) ["decision-invocation"] = assertDecisionWorkflowReferences.apply(compositeWorkflowDocuments) + ["opencode-skill-permissions"] = assertOpenCodeSkillPermissions.apply(opencode.agents) ["opencode-decision-permission"] = assertOpenCodeDecisionPermission.apply(opencode.agents) ["decision-package-paths"] = assertDecisionDocumentPaths.apply(decisionSkillDocuments) ["decision-package-content"] = assertDecisionContent.apply(decisionSkillDocuments) diff --git a/config/pkl/renderers/opencode-metadata.pkl b/config/pkl/renderers/opencode-metadata.pkl index 02fb2728..e248210a 100644 --- a/config/pkl/renderers/opencode-metadata.pkl +++ b/config/pkl/renderers/opencode-metadata.pkl @@ -53,7 +53,8 @@ permission: lsp: allow doom_loop: ask skill: - "*": ask + "*": allow + "sce-*": deny \(workflowSkillPermissionLines.apply("shared-context-plan")) """ ["shared-context-code"] = """ @@ -76,7 +77,8 @@ permission: lsp: allow doom_loop: ask skill: - "*": ask + "*": allow + "sce-*": deny \(workflowSkillPermissionLines.apply("shared-context-code")) """ } diff --git a/config/pkl/renderers/workflow-composite.pkl b/config/pkl/renderers/workflow-composite.pkl index afb8d510..7a3e3758 100644 --- a/config/pkl/renderers/workflow-composite.pkl +++ b/config/pkl/renderers/workflow-composite.pkl @@ -43,17 +43,17 @@ local renderStructuredInternalDocument = (document: model.WorkflowDocument) -> local renderCanonicalWorkflow = (workflow: CompositeWorkflow) -> workflow.structuredSource.command.render.apply("composite", "").text -local siblingSkillRule = (workflow: CompositeWorkflow) -> +local siblingSceWorkflowRule = (workflow: CompositeWorkflow) -> if (workflow.slug == "next-task" || workflow.slug == "validate") """ - not inter-skill handoffs. Do not invoke another SCE skill, sibling package, or - workflow command except `sce-decision`, and invoke `sce-decision` only from the - successful context-synchronization decision gate. + 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. """ else """ - not inter-skill handoffs. Do not invoke another SCE skill, sibling package, or - workflow command. + not inter-SCE workflow handoffs. Do not invoke another SCE skill, sibling SCE + package, or SCE workflow command. """ local renderPhases = (workflow: CompositeWorkflow) -> @@ -105,7 +105,7 @@ local renderSkill = (workflow: CompositeWorkflow, extraFrontmatterLines: String) 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, - \(siblingSkillRule.apply(workflow)) Follow the canonical workflow's steps, gates, + \(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 @@ -122,6 +122,8 @@ local renderSkill = (workflow: CompositeWorkflow, extraFrontmatterLines: String) Approval, clarification, revision, failed-validation repair, and bootstrap waits resume this same skill in the same session. Never expose an internal phase result as the workflow's final response. + + \(model.helperSkillCompositionRule) """ renderCanonicalWorkflow.apply(workflow) when (workflow.structuredSource.phases.length > 0) { diff --git a/context/architecture.md b/context/architecture.md index e90d231e..2277fec6 100644 --- a/context/architecture.md +++ b/context/architecture.md @@ -44,15 +44,15 @@ The scaffold provides stable canonical content-unit identifiers and reusable tar Renderer modules apply target-specific metadata/frontmatter rules while reusing canonical content bodies: -- All three renderers consume the six canonical workflow packages as behavior sources and emit the same six command-routed workflow packages: `sce-change-to-plan`, `sce-next-task`, `sce-validate`, `sce-commit`, `sce-handover`, and `sce-brownfield`. Each renderer also emits the standalone internal `sce-decision` package with `SKILL.md` plus `references/adr-template.md`; it stays outside workflow composition and has no command or prompt. For the four phase-based workflows, `workflow-composite.pkl` renders one `SKILL.md` that owns input parsing, phase order, branching, waits, and same-session resume, plus package-local references for each phase and persisted-document format. The applicable reference must be read before its phase runs. `references/output.md` remains the sole owner of human-visible gates and terminal layouts. Phase statuses remain internal, commands and prompts still invoke exactly one workflow skill, and the only sibling handoff remains the successful synchronization gate's bounded `sce-decision` invocation. `sce-handover` and `sce-brownfield` are phase-free and retain their two-file package shape. OpenCode, Claude, and Pi render identical package-relative inventories and document bodies for each workflow, apart from supported target frontmatter. -- Per-target differences are confined to frontmatter and the surrounding non-workflow outputs. The manual OpenCode renderer adds `agent`, `entry-skill`, and a one-entry `skills` list to command frontmatter, adds `compatibility: opencode` to package entrypoints, and emits two thin routing agents. Catalog-derived workflow permissions remain role-specific; only the Code agent also allows `sce-decision` for the synchronization exception. The Claude renderer adds `compatibility: claude` plus command `allowed-tools:` and emits no agents; Claude settings and the hook helper remain separate retained outputs. The Pi renderer adds no frontmatter to either prompts or skills. +- All three renderers consume the six canonical workflow packages as behavior sources and emit the same six command-routed workflow packages: `sce-change-to-plan`, `sce-next-task`, `sce-validate`, `sce-commit`, `sce-handover`, and `sce-brownfield`. Each renderer also emits the standalone internal `sce-decision` package with `SKILL.md` plus `references/adr-template.md`; it stays outside workflow composition and has no command or prompt. For the four phase-based workflows, `workflow-composite.pkl` renders one `SKILL.md` that owns input parsing, phase order, branching, waits, and same-session resume, plus package-local references for each phase and persisted-document format. The applicable reference must be read before its phase runs. `references/output.md` remains the sole owner of human-visible gates and terminal layouts. Phase statuses remain internal, commands and prompts still invoke exactly one workflow skill, and SCE sibling handoffs remain limited to the successful synchronization gate's bounded `sce-decision` invocation; relevant non-SCE skills may help within the active step and must return control without weakening its invariants. `sce-handover` and `sce-brownfield` are phase-free and retain their two-file package shape. OpenCode, Claude, and Pi render identical package-relative inventories and document bodies for each workflow, apart from supported target frontmatter. +- Per-target differences are confined to frontmatter and the surrounding non-workflow outputs. The manual OpenCode renderer adds `agent`, `entry-skill`, and a one-entry `skills` list to command frontmatter, adds `compatibility: opencode` to package entrypoints, and emits two thin routing agents. Each OpenCode agent allows ordinary non-SCE skills by default, denies the `sce-*` wildcard, and then allows only its catalog-derived owned workflow skills; only the Code agent additionally allows `sce-decision` for the synchronization exception. The Claude renderer adds `compatibility: claude` plus command `allowed-tools:` and emits no agents; Claude settings and the hook helper remain separate retained outputs. The Pi renderer adds no frontmatter to either prompts or skills. - Pi renderer consumes the same shared workflow composition as OpenCode and Claude. It emits exactly six thin prompts to `config/.pi/prompts/{slug}.md`, each routing to exactly one workflow skill, four phase-reference workflow packages plus two phase-free two-file packages under `config/.pi/skills/{slug}/`, and the standalone `sce-decision` package beside them. Pi prompts and skills carry no target-specific frontmatter beyond the shared description and argument hint, so Pi passes the empty extra-frontmatter string to both package render paths. It emits no Pi agent-role prompts. Pi has no settings/plugin manifest; runtime integration remains the project-local extension emitted verbatim from `config/lib/pi-plugin/sce-pi-extension.ts` to `config/.pi/extensions/sce/index.ts` (auto-discovered by Pi, no registration manifest; see `context/sce/pi-extension-runtime.md`). - Workflow composition itself is shared rather than per target. `config/pkl/renderers/workflow-composite.pkl` owns the six composite workflow definitions and assembles their references, while each composite looks up its typed identity in `config/pkl/base/workflow-catalog.pkl` and migrated workflow modules supply canonical phase, persisted-document, and output documents. Every workflow supplies a required `StructuredCompositeSource`, so commands, phase documents, persisted-document formats, and output references render in package or composite mode before Markdown assembly. The renderer has no nullable legacy adapter, frontmatter stripping, or prose-wide replacement chain. Its `renderSkill`, `renderCommand`, and `skillDocuments` entrypoints take a newline-terminated `extraFrontmatterLines` string carrying only the frontmatter a target supports; a target that adds none passes the empty string. `renderSkill` assembles the document as an ordered section list — preamble (purpose, user-visible output, and the composite control-flow rules, all stated before the workflow's `## Input`), then the workflow body, then the phase appendix and any persisted-document formats, each emitted only when its listing is non-empty. Claude passes `compatibility: claude` for skills and a catalog-derived `allowed-tools` line for commands. The `renderSkill` preamble also carries the no-improvisation rule that every generated workflow `SKILL.md` states on every target: the executing agent follows the canonical workflow's steps, gates, and stops exactly as written and never invents, skips, reorders, or merges a step, and its user-visible output is limited to the `references/output.md` layouts with no invented layout and no added preamble, commentary, summary, or extra section. The rule is prose instruction only; the generation contract checks assert paths and metadata, not agent behavior. - Shared renderer document types and OpenCode plugin-registration helpers live in `config/pkl/renderers/common.pkl`. - The canonical OpenCode plugin-registration source for generated SCE plugins lives in `config/pkl/base/opencode.pkl`; `config/pkl/renderers/common.pkl` re-exports the shared plugin list and JSON-ready paths for OpenCode renderers, and the current generated registration scope is limited to SCE-managed plugins emitted by this repo (`sce-bash-policy` and `sce-agent-trace`). -- Target renderers remain responsible for formatting target-supported metadata. OpenCode metadata owns thin-agent presentation and compatibility while deriving workflow permission lines from catalog role assignments; OpenCode command routing derives the same role and skill identity from the catalog. Claude metadata derives command tools from catalog records. Pi has no metadata module because it adds no target-specific frontmatter. +- Target renderers remain responsible for formatting target-supported metadata. OpenCode metadata owns thin-agent presentation and compatibility while deriving the ordered permission blocks — non-SCE wildcard allow, `sce-*` wildcard deny, then catalog-owned workflow allows — from catalog role assignments; OpenCode command routing derives the same role and skill identity from the catalog. Claude metadata derives command tools from catalog records. Pi has no metadata module because it adds no target-specific frontmatter. - `config/pkl/renderers/metadata-coverage-check.pkl` derives commands and exact package-relative workflow-document expectations from the typed catalog and the four phase-reference inventories, adds the unchanged phase-free and decision-package expectations, verifies every command's one-to-one workflow-skill route for all three targets, and forces every rendered document and target metadata lookup to evaluate. -- `config/pkl/renderers/generation-contract-check.pkl` independently derives the complete expected artifact paths from those target document inventories plus explicitly retained non-workflow assets, compares them with `generate.pkl`'s `output.files`, and requires exactly 101 paths — stated as a literal `expectedArtifactPathCount` inside the same assertion so an unintended inventory change fails rather than redefining the expectation. It asserts the generated `config/optional-workflows.json` against the catalog (`optional-workflow-manifest`): every optional workflow appears with its catalog title and both slugs, no core workflow id appears, and `schemaVersion` is present. It also verifies that every required phase reference exists and is cited by its owning `SKILL.md`, scans generated workflow entrypoint `SKILL.md` documents for stale phase-skill slugs and unresolved package-local reference tokens while allowing package-local reference prose to mention its own persisted-format history, asserts the exact cross-target `sce-decision` paths plus its required gate, status, immutability, handoff, and ADR-template content, permits `sce-decision` references only in `sce-next-task` and `sce-validate`, verifies the Code-only OpenCode decision permission, asserts the generated `sce-handover` `SKILL.md` covers both writer- and loader-mode content on all three targets, asserts the generated `sce-brownfield` `SKILL.md` still carries the bootstrap gate, documentation-discovery sweep, no-network rule, sub-`50` blocking threshold, always-disclosed contradiction contract, and additive-vs-`rebuild` write rule on all three targets, rejects two or more consecutive blank lines in generated workflow entrypoint `SKILL.md` documents (`no-blank-line-runs`), and rejects any generated `SKILL.md` that reproduces one of its sibling `references/output.md` fenced layouts verbatim (`output-dedup`, matched fence markers included). Checked-in negative fixtures prove that deterministic extra and missing artifacts, a forbidden workflow reference, a blank-line run, and a duplicated output layout each fail the contract. +- `config/pkl/renderers/generation-contract-check.pkl` independently derives the complete expected artifact paths from those target document inventories plus explicitly retained non-workflow assets, compares them with `generate.pkl`'s `output.files`, and requires exactly 101 paths — stated as a literal `expectedArtifactPathCount` inside the same assertion so an unintended inventory change fails rather than redefining the expectation. It asserts the generated `config/optional-workflows.json` against the catalog (`optional-workflow-manifest`): every optional workflow appears with its catalog title and both slugs, no core workflow id appears, and `schemaVersion` is present. It also verifies that every required phase reference exists and is cited by its owning `SKILL.md`, scans generated workflow entrypoint `SKILL.md` documents for stale phase-skill slugs and unresolved package-local reference tokens while allowing package-local reference prose to mention its own persisted-format history, asserts the shared non-SCE helper-composition rule and SCE-scoped workflow prohibitions on every generated workflow skill, asserts the exact cross-target `sce-decision` paths plus its required gate, status, immutability, handoff, and ADR-template content, permits `sce-decision` references only in `sce-next-task` and `sce-validate`, verifies the exact catalog-derived OpenCode skill permission order and Code-only OpenCode decision permission, asserts the generated `sce-handover` `SKILL.md` covers both writer- and loader-mode content on all three targets, asserts the generated `sce-brownfield` `SKILL.md` still carries the bootstrap gate, documentation-discovery sweep, no-network rule, sub-`50` blocking threshold, always-disclosed contradiction contract, and additive-vs-`rebuild` write rule on all three targets, rejects two or more consecutive blank lines in generated workflow entrypoint `SKILL.md` documents (`no-blank-line-runs`), and rejects any generated `SKILL.md` that reproduces one of its sibling `references/output.md` fenced layouts verbatim (`output-dedup`, matched fence markers included). Checked-in negative fixtures prove that deterministic extra and missing artifacts, a forbidden workflow reference, missing helper composition, unscoped prohibitions, arbitrary or misordered OpenCode permissions, a blank-line run, and a duplicated output layout each fail the contract. - OpenCode, Claude, and Pi renderers expose command documents plus flattened `{skill slug}/{package-relative path}` skill documents consumed by `config/pkl/generate.pkl`; every target's flattened inventory contains `SKILL.md` and `references/output.md` for each workflow slug plus `sce-decision/SKILL.md` and `sce-decision/references/adr-template.md`. - `config/pkl/generate.pkl` emits deterministic `output.files` mappings for all authored generated targets: OpenCode's six workflow commands, four phase-reference workflow packages, two phase-free workflow packages, standalone two-file decision package, and two thin routing agents; Claude's six thin commands, the same workflow-package inventories, and standalone decision package with no agents; Claude project settings and hook helper; shared bash-policy preset assets; OpenCode plugin entrypoints (`sce-bash-policy.ts` and `sce-agent-trace.ts`); generated OpenCode `opencode.json`; the Pi target tree (six thin workflow prompts, the same four phase-reference and two phase-free workflow packages, the standalone two-file decision package, and the extension emitted verbatim from `config/lib/pi-plugin/sce-pi-extension.ts`); the generated `sce/config.json` schema artifact; and the optional-workflow manifest at `config/optional-workflows.json`. The removed `config/automated/.opencode` profile has no generator ownership or output mappings. - Generated-file warning markers are not injected by the generator: Markdown outputs render deterministic frontmatter + body, and shared library outputs are emitted without a leading generated warning header. @@ -195,6 +195,6 @@ Shared Context Plan and Shared Context Code remain separate architectural roles. - Reuse is handled through shared canonical guidance blocks and skill-owned phase contracts, not by collapsing both roles into one agent. - OpenCode agents are thin routing surfaces rather than behavior owners: Plan routes to `/change-to-plan`; Code routes to `/next-task`, `/validate`, `/commit`, `/handover`, and `/brownfield`. Claude and Pi have no generated agents. Workflow commands and self-contained skill packages are the sole behavior owners. - The canonical `/change-to-plan` workflow sequences `sce-context-load` and `sce-plan-authoring`; `/next-task` sequences `sce-plan-review`, `sce-task-execution`, and `sce-task-context-sync`; `/validate` sequences `sce-validation` and validated-only `sce-plan-context-sync`; `/commit` sequences around `sce-atomic-commit`; `/handover` and `/brownfield` have no sibling phases at all — their single `sce-handover` and `sce-brownfield` skills own their whole routing directly. Those phase modules are canonical authoring source; no target generates them as packages. -- Every target embeds those same phase boundaries inside `sce-change-to-plan`, `sce-next-task`, `sce-validate`, `sce-commit`, `sce-handover`, and `sce-brownfield`, so no generated command or prompt invokes a phase or sibling SCE package. Workflow skills invoke no sibling except the successful task/plan synchronization decision gate's bounded `sce-decision` call. +- Every target embeds those same phase boundaries inside `sce-change-to-plan`, `sce-next-task`, `sce-validate`, `sce-commit`, `sce-handover`, and `sce-brownfield`, so no generated command or prompt invokes a phase or sibling SCE package. Workflow skills may use relevant non-SCE helpers inside the active step, but the helper returns control to that step; the only SCE sibling invocation remains the successful task/plan synchronization decision gate's bounded `sce-decision` call. - OpenCode, Claude, and Pi all generate `/handover` routed to exactly `sce-handover` (see [Handover workflow](sce/handover-workflow.md)) and `/brownfield` routed to exactly `sce-brownfield` (see [Brownfield workflow](sce/brownfield-workflow.md)); the automated OpenCode profile is removed. - `/brownfield` is the only workflow outside the task and plan synchronization phases authorized to write durable `context/`, under its own additive-by-default boundary; see [Context workflow rules](sce/context-workflow-rules.md). diff --git a/context/context-map.md b/context/context-map.md index 5cef3cca..9bea165a 100644 --- a/context/context-map.md +++ b/context/context-map.md @@ -104,6 +104,7 @@ Recent decision records: - `context/decisions/2026-07-29-cross-target-workflow-skill-packages.md` (accepted history for the cross-target four-workflow single-skill model; its exact two-file phase-based package inventory is superseded, while single-skill control flow and internal phase state remain in force) - `context/decisions/2026-08-03-package-local-phase-reference-workflow-packages.md` (supersedes the two-file clause for phase-based workflow packages: `SKILL.md` retains control flow while package-local references own phase instructions and persisted-document formats on all three targets) - `context/decisions/2026-07-30-synchronization-scoped-decision-writing.md` (accepted standalone `sce-decision` package, synchronization-only sibling invocation, decision threshold, default status, and immutable accepted-ADR policy) +- `context/decisions/2026-08-07-sce-workflow-helper-composition.md` (accepted SCE workflow ownership boundary: non-SCE in-step helpers return control to the active step, while arbitrary SCE workflow chaining remains prohibited) - `context/decisions/2026-07-27-ephemeral-pkl-build-generation.md` (removes committed generated targets; establishes pre-Cargo generation, validated copying into Cargo `OUT_DIR`, and crates.io/Flatpak packaging fallbacks) - `context/decisions/2026-03-09-migrate-lexopt-to-clap.md` (CLI argument parsing migration from lexopt to clap derive macros) - `context/decisions/2026-03-25-first-install-channels.md` (approved first-wave install/distribution scope for `sce`, canonical naming, and Nix-owned build policy) diff --git a/context/decisions/2026-08-07-sce-workflow-helper-composition.md b/context/decisions/2026-08-07-sce-workflow-helper-composition.md new file mode 100644 index 00000000..998ac439 --- /dev/null +++ b/context/decisions/2026-08-07-sce-workflow-helper-composition.md @@ -0,0 +1,77 @@ +# Decision: Allow Non-SCE Helper Skills Inside SCE Workflow Steps + +Date: 2026-08-07 +Status: Accepted +Plan: `context/plans/update-sce-skill-orchestration.md` +Task: `T01` +Supersedes: `2026-07-30-synchronization-scoped-decision-writing.md` (only its absolute sibling-invocation prohibition) + +## Context + +The cross-target single-skill model keeps workflow control flow, gates, waits, +writes, validation, stops, and terminal output inside each SCE workflow skill. +The canonical wording nevertheless prohibited invoking any sibling skill without +scoping that rule to SCE workflow packages, which also made unrelated helper +capabilities appear forbidden. The generated workflows need one consistent +ownership boundary across OpenCode, Claude, and Pi. + +## Decision + +SCE workflow skills remain the exclusive owners of SCE workflow control flow and +must not chain arbitrary SCE skills, packages, or workflow commands. Relevant +non-SCE skills may be used as helper capabilities during the active step; when a +helper returns, control returns to that step, and helper use must preserve phase +order, gates, waits, writes, validation, stops, and terminal user-visible output. + +## Rationale + +This preserves the single-skill state-transport boundary while allowing unrelated +skills to contribute capabilities without becoming workflow owners or handoffs. +A shared target-neutral rule keeps the distinction identical across all targets. + +## Alternatives considered + +- **Keep the unscoped prohibition** — Prevents useful unrelated helper composition + and makes the intended SCE ownership boundary ambiguous. +- **Allow arbitrary SCE workflow chaining** — Reintroduces the inter-skill control- + flow and state-transport risk that the single-skill model removed. +- **Let each target define its own helper policy** — Creates cross-target drift in + canonical workflow behavior. + +## Compatibility and risks + +- Generated workflow prose changes on all three targets, but workflow phase order, + gates, waits, writes, validation, stops, and output contracts remain unchanged. +- A helper could be mistaken for a workflow handoff; the shared rule explicitly + requires return to the active step and preserves every control-flow invariant. + +## Guardrails + +- Scope workflow-control prohibitions to SCE skills, packages, and commands. +- Keep helper composition target-neutral and shared by the composite preamble. +- Permit no arbitrary SCE workflow chaining; retain the synchronization-only + `sce-decision` exception. +- Do not change generated target trees or runtime permission behavior in this task. + +## Consequences + +- Non-SCE helper skills are composable within an active SCE step without weakening + workflow ownership. +- All generated SCE workflow skills state the same helper-return and invariant rule. +- The prior absolute sibling-invocation wording is no longer current; its + synchronization-only `sce-decision` exception and single-skill ownership remain. + +## Follow-up + +- T02 and T03 continue the planned OpenCode permission and generated-contract work. + +## References + +- Plan: [`update-sce-skill-orchestration`](../plans/update-sce-skill-orchestration.md) +- Task: `T01` +- Current-state context: [`Architecture`](../architecture.md) +- Current-state context: [`Patterns`](../patterns.md) +- Current-state context: [`Shared Context Code Workflows`](../sce/shared-context-code-workflow.md) +- Evidence: [`workflow composite renderer`](../../config/pkl/renderers/workflow-composite.pkl) +- Evidence: [`workflow content primitives`](../../config/pkl/base/workflow-content.pkl) +- Related decision: [`Allow Decision Writing During Successful Context Synchronization`](2026-07-30-synchronization-scoped-decision-writing.md) diff --git a/context/glossary.md b/context/glossary.md index 099d5092..67510f9a 100644 --- a/context/glossary.md +++ b/context/glossary.md @@ -1,6 +1,6 @@ # Glossary -- `pkl-check-generated`: Flake app exposed as `nix run .#pkl-check-generated`; canonical ephemeral-generation check that rejects committed target/schema/mirror outputs, evaluates exact workflow metadata, the complete 101-path generated artifact contract, and the optional-workflow manifest's content against the catalog, rejects stale sibling-package references or unresolved internalization tokens in workflow entrypoint `SKILL.md` documents, proves extra/missing/reference failures through negative fixtures, and delegates deterministic generation plus payload/input inventories to the generated-input producer while preserving its established inventory report. +- `pkl-check-generated`: Flake app exposed as `nix run .#pkl-check-generated`; canonical ephemeral-generation check that rejects committed target/schema/mirror outputs, evaluates exact workflow metadata, the complete 101-path generated artifact contract, and the optional-workflow manifest's content against the catalog, requires the shared helper-composition rule and SCE-scoped workflow prohibitions, enforces ordered catalog-derived OpenCode skill permissions, rejects stale sibling-package references or unresolved internalization tokens in workflow entrypoint `SKILL.md` documents, proves extra/missing/reference/orchestration/permission failures through negative fixtures, and delegates deterministic generation plus payload/input inventories to the generated-input producer while preserving its established inventory report. - `repo-level verification preference`: Current repository guidance that contributor-facing validation/check flows should prefer `nix flake check`; direct Cargo verification commands are secondary and used only when explicitly requested or for narrow targeted debugging, while `cargo fmt` remains the explicit autofix path. - lightweight post-task verification baseline: Required quick checks after each completed task in this repo: `nix run .#pkl-check-generated` and `nix flake check`. - disposable plan lifecycle: Policy where `context/plans/` holds active execution artifacts only; completed plans are disposable and durable outcomes must be reflected in current-state context files and/or `context/decisions/`. @@ -10,7 +10,7 @@ - `CLI generated-input handoff`: Repository-build contract rooted at the temporary directory named by `SCE_CLI_GENERATED_INPUT_DIR`. `config/pkl/generator-inputs.txt` declares the canonical `config/pkl` and referenced `config/lib` inputs; `scripts/produce-cli-generated-input.sh` discovers those files, generates Pkl twice, rejects nondeterminism and in-flight input mutation, and atomically places `pkl-generated/`, its exact `SHA256SUMS`, and `INPUTS.SHA256SUMS` there. `scripts/run-cli-cargo.sh` delegates production and removes its temporary handoff after Cargo exits. `cli/build.rs` verifies payload integrity and input freshness before copying `pkl-generated/` into Cargo `OUT_DIR`; missing, incomplete, modified, or stale handoffs fail rather than invoking Pkl or falling back to packaged assets. - `generated-input producer`: Repository-owned `scripts/produce-cli-generated-input.sh` contract driven by `config/pkl/generator-inputs.txt`. It is the canonical owner for expanding repository-relative generator inputs, snapshotting their inventory, two-pass Pkl evaluation, byte-tree determinism comparison, payload and canonical-input SHA-256 inventories, input-mutation rejection, atomic output publication, and private staging cleanup. The repository Cargo wrapper, generated-output check, package-fallback preparation, and Nix `cliGeneratedInput` derivation all consume it. - `Pi workflow package`: Generated Pi workflow surface consisting of one thin prompt in `config/.pi/prompts/` plus the one workflow skill package under `config/.pi/skills/` that the prompt routes to. Phase-based workflows include `SKILL.md`, `references/output.md`, and named phase or persisted-document references; phase-free workflows contain the two core files only. Pi currently receives `/change-to-plan`, `/next-task`, `/validate`, `/commit`, `/handover`, and `/brownfield` this way and has no generated agent-role prompts. -- `workflow skill package`: One of the six renderer-composed packages (`sce-change-to-plan`, `sce-next-task`, `sce-validate`, `sce-commit`, `sce-handover`, `sce-brownfield`) emitted for every target. Its `SKILL.md` owns the canonical phase sequence, internal status branching, user waits and same-session resume behavior, and continuation; each phase-based workflow reads package-local phase references before acting, while `sce-handover` and `sce-brownfield` have no phases and retain two-file packages. The sole sibling exception lets successful `sce-next-task` and `sce-validate` synchronization invoke `sce-decision` for one qualifying system-wide decision. `references/output.md` remains the sole owner of human-visible layouts. The canonical phase modules remain authoring inputs to composition and are not generated as packages for any target. +- `workflow skill package`: One of the six renderer-composed packages (`sce-change-to-plan`, `sce-next-task`, `sce-validate`, `sce-commit`, `sce-handover`, `sce-brownfield`) emitted for every target. Its `SKILL.md` owns the canonical phase sequence, internal status branching, user waits and same-session resume behavior, and continuation; each phase-based workflow reads package-local phase references before acting, while `sce-handover` and `sce-brownfield` have no phases and retain two-file packages. Relevant non-SCE skills may assist inside an active step but return control to it without changing workflow invariants. The sole SCE sibling exception lets successful `sce-next-task` and `sce-validate` synchronization invoke `sce-decision` for one qualifying system-wide decision. `references/output.md` remains the sole owner of human-visible layouts. The canonical phase modules remain authoring inputs to composition and are not generated as packages for any target. - `decision skill package`: Standalone internal `sce-decision` package emitted for OpenCode, Claude, and Pi from `config/pkl/base/decision-skill.pkl`, outside the command workflow catalog. Its `SKILL.md` accepts one qualifying system-wide decision from successful task or plan synchronization, enforces one dated ADR with allowed status vocabulary and `Accepted` default, never edits an accepted ADR, and returns a deterministic written-or-blocked handoff. Its only other file is `references/adr-template.md`; no user-facing command or prompt routes to it, and no workflow invokes it outside the synchronization decision gate. - `workflow catalog`: The typed mapping in `config/pkl/base/workflow-catalog.pkl` that declares each of the six workflows once and owns its command slug, skill slug, title, description, argument hint, OpenCode routing role, Claude allowed tools, and its `optional` flag. Composite identity, OpenCode routing/permissions, Claude tool frontmatter, and metadata coverage derive from these records; behavior remains in canonical phase modules and formatting remains renderer-owned. - `optional workflow`: A catalog workflow whose `WorkflowRecord.optional` flag is `true`. Optionality is an install-time concern only: the workflow is still authored, composed, and generated for OpenCode, Claude, and Pi exactly like a core workflow, and its generated files remain part of the ephemeral payload and the generation contract. `brownfield` is the only optional workflow; the other five leave the flag at its `false` default. @@ -19,11 +19,12 @@ - `optional-workflow selection`: The set of optional workflow ids a repository has opted into. `iter_embedded_assets_for_setup_target_with_selection` in `cli/src/services/setup/mod.rs` applies it by excluding each unselected workflow's `{command_dir}/{command_slug}.md` file and `{skills_dir}/{skill_slug}/` subtree per target, leaving all other embedded assets untouched. `sce setup` resolves it per run — from the interactive multi-select, else `--workflow`, else the persisted value — installs by it, and persists it; its persisted form is the `integrations.optional_workflows` config key. `sce doctor` reads that same persisted key and applies the same filter, so it expects an optional workflow's files only where the repository opted in. See [setup local bootstrap](sce/setup-repo-local-config-bootstrap.md). - `sce setup --workflow`: Repeatable `sce setup` flag naming one optional workflow id to install for the run. Passing it at all makes the listed ids the exact selection for that run; omitting it reuses the persisted `integrations.optional_workflows`, so a repeat run never silently uninstalls a previously selected optional workflow. Unknown ids are rejected before any file is written, with the embedded catalog's available ids named in the error. It is rejected alongside `--bootstrap-context` and on a hooks-only run, neither of which installs target assets. - `integrations.optional_workflows`: Repo-local `sce/config.json` key recording a repository's optional-workflow selection as a unique array of optional workflow ids. Its accepted values are derived from the workflow catalog's `optional` records in `config/pkl/base/sce-config-schema.pkl`, and `cli/src/services/config/` parses it into `IntegrationsConfig.optional_workflows` alongside `integrations.target`, validating each id against the embedded optional-workflow catalog. See [CLI config precedence contract](cli/config-precedence-contract.md). -- `sce-handover`: Self-contained skill package (`SKILL.md` plus `references/output.md`) invoked by the `/handover` command, registered in `config/pkl/base/workflow-catalog.pkl` and generated for OpenCode, Claude, and Pi. Dual-mode: empty arguments select writer mode, which gathers session and repository facts and writes exactly one handover document; one path argument selects read-only loader mode, which validates and presents an existing handover for continuation. It has no phases and invokes no sibling skill; see [Handover workflow](sce/handover-workflow.md). +- `sce-handover`: Self-contained skill package (`SKILL.md` plus `references/output.md`) invoked by the `/handover` command, registered in `config/pkl/base/workflow-catalog.pkl` and generated for OpenCode, Claude, and Pi. Dual-mode: empty arguments select writer mode, which gathers session and repository facts and writes exactly one handover document; one path argument selects read-only loader mode, which validates and presents an existing handover for continuation. It has no phases or SCE workflow handoffs; relevant non-SCE helpers, if used, return control to the active step. See [Handover workflow](sce/handover-workflow.md). - `sce-brownfield`: Self-contained, phase-free skill package (`SKILL.md` plus `references/output.md`) invoked by `/brownfield` to reconstruct durable `context/` memory from an existing repository's own evidence. Its canonical source is `config/pkl/base/workflow-brownfield.pkl`; it is the sixth record in `config/pkl/base/workflow-catalog.pkl` and is generated for OpenCode, Claude, and Pi under the `shared-context-code` routing role. Local evidence only, in priority order (current code, then executable configuration, then discovered documentation plus argument-supplied paths, then at least three months of Git history), with no network access; it never creates the `context/` root and never writes outside it. See [Brownfield workflow](sce/brownfield-workflow.md). - brownfield confidence model: The internal `1`–`100` score `sce-brownfield` assigns to every fact it would write as durable truth, banded as `Verified` (`90`–`100`), `Strongly supported` (`70`–`89`), `Inferred` (`50`–`69`), and `Clarification required` (`1`–`49`), plus `Contradiction resolved` for a fact scored after conflicting evidence was resolved. Anything below `50` blocks with grouped clarification questions and is never written as truth. Scores are internal state and chat evidence only; no score is written under `context/`. - brownfield `rebuild` mode: The mode `sce-brownfield` enters when the literal token `rebuild` is the first argument, and the only thing that grants it rewrite authority over existing context files. Writes are otherwise additive — missing files and missing domains only. Even in `rebuild` mode no context file is deleted, `context/plans/`, `context/handovers/`, `context/decisions/`, and `context/tmp/` are untouched, and a file with uncommitted changes is not modified. The mode is never inferred from conversation content or repository state. - handover document: The four-required-section Markdown file (`Current Task State`, `Decisions Made`, `Open Questions / Blockers`, `Next Recommended Step`, plus a trailing `Assumptions` section) that `sce-handover` writer mode persists under `context/handovers/`, named by the active plan task or a collision-safe timestamp when no single task is unambiguous. +- `non-SCE helper skill composition`: The workflow rule shared by every generated SCE workflow skill: a relevant non-SCE skill may assist during the active step, but it is not a workflow handoff; control returns to the active step and canonical phase order, gates, waits, writes, validation, stops, and terminal output remain unchanged. Arbitrary SCE workflow chaining remains prohibited, with only the synchronization-scoped `sce-decision` exception. - `workflow composite renderer`: The shared, target-neutral Pkl module at `config/pkl/renderers/workflow-composite.pkl` that renders each canonical workflow as one workflow-level `SKILL.md` plus deterministic package-local documents. The four phase-based workflows emit named phase and persisted-document references; phase-free workflows emit only `references/output.md` beside the entrypoint. It requires structured composite sources for all six workflows and performs no frontmatter stripping or prose-wide internalization. All three targets render through it, parameterized only by the extra frontmatter each supports. - `structured workflow rendering`: Canonical Pkl representation centered on the shared model in `workflow-content.pkl`, where package-vs-composite mode is selected through typed frontmatter, body, semantic-reference, structured-document, composite-source, heading-scale (`PhaseHeadings`), and single-mode block values before Markdown assembly. Canonical workflow modules supply workflow-specific behavior and migrated package-local phase, persisted-document, and output documents as named values; all six workflows render their commands and applicable internal documents without frontmatter stripping or prose-wide replacement. - `canonical phase module`: One of the eight phase definitions in `config/pkl/base/workflow-*.pkl` (`sce-context-load`, `sce-plan-authoring`, `sce-plan-review`, `sce-task-execution`, `sce-task-context-sync`, `sce-validation`, `sce-plan-context-sync`, `sce-atomic-commit`). Each is the single behavioral source for its phase and an authoring input to the composite renderer. Since 2026-07-29 no target generates them as installable skill packages; the names denote canonical source and the internal phases inside a composed `SKILL.md`. diff --git a/context/overview.md b/context/overview.md index 8863c65f..ff109f4c 100644 --- a/context/overview.md +++ b/context/overview.md @@ -1,6 +1,6 @@ # Overview -This repository maintains shared assistant configuration for OpenCode, Claude, and Pi from a single canonical Pkl authoring source. One typed workflow catalog owns the six workflows' shared identity and target routing metadata, while canonical workflow/phase modules own behavior and migrated package-local documents, and target renderers own formatting. Generated target layouts are ephemeral: repository builds consume a pre-Cargo generated payload through `SCE_CLI_GENERATED_INPUT_DIR`, crates.io and Flatpak stage packaging-only fallbacks, and `config/.opencode`, `config/.claude`, `config/.pi`, and the generated SCE config schema are not committed. The catalog also marks a workflow `optional` — currently only `brownfield` — which changes nothing about generation and is projected into a generated `config/optional-workflows.json` manifest for install-time consumers. `nix run .#pkl-check-generated` preserves its exact 101-path artifact, metadata/package, phase-reference, internal-reference, optional-workflow-manifest, required-path, and forbidden-path checks while delegating deterministic payload production and inventories to the shared generated-input producer; `nix flake check` runs the same contract. The target matrix contains one manual OpenCode profile plus Claude and Pi; the former automated OpenCode profile has been removed. +This repository maintains shared assistant configuration for OpenCode, Claude, and Pi from a single canonical Pkl authoring source. One typed workflow catalog owns the six workflows' shared identity and target routing metadata, while canonical workflow/phase modules own behavior and migrated package-local documents, and target renderers own formatting. Generated target layouts are ephemeral: repository builds consume a pre-Cargo generated payload through `SCE_CLI_GENERATED_INPUT_DIR`, crates.io and Flatpak stage packaging-only fallbacks, and `config/.opencode`, `config/.claude`, `config/.pi`, and the generated SCE config schema are not committed. The catalog also marks a workflow `optional` — currently only `brownfield` — which changes nothing about generation and is projected into a generated `config/optional-workflows.json` manifest for install-time consumers. `nix run .#pkl-check-generated` preserves its exact 101-path artifact, metadata/package, phase-reference, internal-reference, optional-workflow-manifest, workflow-orchestration, OpenCode-permission, required-path, and forbidden-path checks while delegating deterministic payload production and inventories to the shared generated-input producer; `nix flake check` runs the same contract. The target matrix contains one manual OpenCode profile plus Claude and Pi; the former automated OpenCode profile has been removed. It also includes a Rust CLI (`sce`) for Shared Context Engineering workflows: auth, config inspection, setup, doctor, agent-trace hooks, bash-policy evaluation, and trace database inspection. See `context/architecture.md` for module-level boundaries and `context/context-map.md` for the full domain file index. @@ -54,8 +54,8 @@ The current supported automated release target matrix is `x86_64-unknown-linux-m The downstream publish-stage implementation is now complete for both registries: `.github/workflows/publish-crates.yml` publishes the checked-in crate version after `.version`/tag/Cargo parity checks, and `.github/workflows/publish-npm.yml` publishes the checked-in npm package after `.version`/tag/npm parity checks plus verification of the canonical `sce-v-npm.tgz` GitHub release asset. The repository root now also owns the canonical Biome contract for the current JavaScript tooling slice: `biome.json` scopes formatting/linting to `npm/` and the shared `config/lib/` plugin package root while excluding package-local `node_modules/`, and the root Nix dev shell provides the `biome` binary so contributors do not need a host-installed formatter/linter for those areas. Flatpak validation/build orchestration is reduced to a minimal app surface: Linux flake apps expose the umbrella `sce-flatpak` (`nix run .#sce-flatpak -- ` for `validate`, `prepare-local-manifest`, etc.) plus `release-flatpak-package`, `release-flatpak-bundle`, and the `regenerate-flatpak-manifest` / `regenerate-cargo-sources` helpers; the previously separate `flatpak-validate`, `flatpak-local-manifest`, and `flatpak-build` wrapper apps are removed. Default `nix flake check` keeps the lightweight Nix-built static/AppStream validator plus the parity checks (`flatpak-manifest-parity`, `cargo-sources-parity`) and does not run a network-heavy Flatpak build. The former standalone install-channel integration runner and `install-channel-integration-tests` flake app are not active current-state surfaces. -Shared Context Plan and Shared Context Code remain separate OpenCode routing roles: the generated Plan agent routes only to `/change-to-plan`, while the generated Code agent routes to `/next-task`, `/validate`, `/commit`, `/handover`, and `/brownfield`. Workflow behavior lives in the six workflow entrypoints and their six skill packages rather than in agent bodies. `config/pkl/base/workflow-catalog.pkl` assigns each workflow to its role, and OpenCode command routing plus each agent's `skill:` permission allowlist derive from those records: `sce-change-to-plan` for Plan; `sce-next-task`, `sce-validate`, `sce-commit`, `sce-handover`, and `sce-brownfield` for Code. -The canonical workflow definitions remain phase-decomposed as authoring source: `/change-to-plan` sequences `sce-context-load` then `sce-plan-authoring`; `/next-task` sequences `sce-plan-review`, `sce-task-execution`, and `sce-task-context-sync`; `/validate` sequences `sce-validation` then `sce-plan-context-sync`; `/commit` delegates staged-diff analysis and message generation to `sce-atomic-commit`; `/handover` has no phases, since writer and loader mode never invoke a sibling or wait mid-run; `/brownfield` likewise has none, since its single skill owns investigation, the blocking clarification gate, writing, and reporting itself. No target generates those phase modules as packages. All three consume them as inputs to the shared `workflow-composite.pkl` renderer, which composes each workflow into one skill package. Every workflow supplies typed package/composite render values for frontmatter, bodies, semantic references, phases, persisted-document formats where applicable, and output references; the composite renderer performs no prose-wide internalization or frontmatter stripping. +Shared Context Plan and Shared Context Code remain separate OpenCode routing roles: the generated Plan agent routes only to `/change-to-plan`, while the generated Code agent routes to `/next-task`, `/validate`, `/commit`, `/handover`, and `/brownfield`. Workflow behavior lives in the six workflow entrypoints and their six skill packages rather than in agent bodies. `config/pkl/base/workflow-catalog.pkl` assigns each workflow to its role, and OpenCode command routing plus each agent's ordered `skill:` permissions derive from those records: ordinary non-SCE skills are allowed by the wildcard, arbitrary `sce-*` skills are denied, and only the role's owned workflows are allowed after that deny — `sce-change-to-plan` for Plan; `sce-next-task`, `sce-validate`, `sce-commit`, `sce-handover`, and `sce-brownfield` for Code. The Code agent additionally allows `sce-decision` for synchronization. +The canonical workflow definitions remain phase-decomposed as authoring source: `/change-to-plan` sequences `sce-context-load` then `sce-plan-authoring`; `/next-task` sequences `sce-plan-review`, `sce-task-execution`, and `sce-task-context-sync`; `/validate` sequences `sce-validation` then `sce-plan-context-sync`; `/commit` delegates staged-diff analysis and message generation to `sce-atomic-commit`; `/handover` has no phases, since writer and loader mode has no SCE sibling handoff or wait mid-run; `/brownfield` likewise has none, since its single skill owns investigation, the blocking clarification gate, writing, and reporting itself. Relevant non-SCE skills may help inside an active workflow step, but they return control to that step without changing its canonical invariants. No target generates those phase modules as packages. All three consume them as inputs to the shared `workflow-composite.pkl` renderer, which composes each workflow into one skill package. Every workflow supplies typed package/composite render values for frontmatter, bodies, semantic references, phases, persisted-document formats where applicable, and output references; the composite renderer performs no prose-wide internalization or frontmatter stripping. Every target preserves the same gates and lifecycle semantics through six renderer-composed workflow packages: `sce-change-to-plan`, `sce-next-task`, `sce-validate`, `sce-commit`, `sce-handover`, and `sce-brownfield`. Each thin command or Pi prompt invokes exactly one corresponding skill, and OpenCode command frontmatter names that single skill as both `entry-skill` and the whole `skills` chain. Each phase-based package keeps control flow, internal status branching, waits, and same-session resume in `SKILL.md`, while package-local Markdown references own phase instructions and persisted-document formats; `references/output.md` remains the sole definition of human-visible gates and terminal Markdown. Phase-free workflows retain `SKILL.md` plus `references/output.md`. No target emits phase-skill packages or inter-skill machine contracts; phase statuses stay internal to one skill invocation. Context sync uses an important-change gate: cross-cutting/policy/architecture/terminology changes require root shared-file edits, while localized tasks run verify-only root checks without default churn. OpenCode and Claude no longer generate legacy bootstrap or context-sync skills; `/commit` and `/handover` are generated only as catalog-registered composite workflow packages. OpenCode retains only thin routing agents, while Claude emits no agents. The superseded grouped Markdown catalog and automated OpenCode profile have been removed from Pkl ownership and generated outputs. @@ -103,7 +103,7 @@ Lightweight post-task verification baseline (required after each completed task) ## Cross-target parity -- OpenCode, Claude, and Pi are generated from canonical Pkl content with per-target capability mapping. All three receive the same six command-routed workflow packages plus a standalone internal `sce-decision` package. The decision package contains `SKILL.md` and `references/adr-template.md`, defines one qualifying system-wide decision per immutable dated ADR, defaults new records to `Accepted`, and returns a written-or-blocked internal handoff. It has no user-facing command or prompt and is not part of the workflow catalog. Successful task and plan synchronization apply the system-wide decision gate before current-state context edits, reuse existing ADRs, and invoke `sce-decision` only for qualifying decisions; this is the sole sibling-skill exception. Pi consumes exactly six thin prompts with no agent-role prompts and no added frontmatter. Manual OpenCode consumes exactly six commands plus two thin routing agents, and its Code agent alone allows internal `sce-decision` invocation. Claude consumes exactly six thin commands with no generated agents; its generated settings and hook helper remain. The four phase-based command-routed packages add package-local phase and persisted-document references beside `SKILL.md` and `references/output.md`; the two phase-free workflows retain their two-file packages. +- OpenCode, Claude, and Pi are generated from canonical Pkl content with per-target capability mapping. All three receive the same six command-routed workflow packages plus a standalone internal `sce-decision` package. The decision package contains `SKILL.md` and `references/adr-template.md`, defines one qualifying system-wide decision per immutable dated ADR, defaults new records to `Accepted`, and returns a written-or-blocked internal handoff. It has no user-facing command or prompt and is not part of the workflow catalog. Successful task and plan synchronization apply the system-wide decision gate before current-state context edits, reuse existing ADRs, and invoke `sce-decision` only for qualifying SCE decisions; non-SCE helper skills remain usable inside an active step without becoming workflow handoffs. Pi consumes exactly six thin prompts with no agent-role prompts and no added frontmatter. Manual OpenCode consumes exactly six commands plus two thin routing agents, and its Code agent alone allows internal `sce-decision` invocation. Claude consumes exactly six thin commands with no generated agents; its generated settings and hook helper remain. The four phase-based command-routed packages add package-local phase and persisted-document references beside `SKILL.md` and `references/output.md`; the two phase-free workflows retain their two-file packages. - When capabilities differ, parity is implemented by supported target-specific behavior rather than forcing unsupported fields. ## Context navigation diff --git a/context/patterns.md b/context/patterns.md index a5bda2c9..98082dde 100644 --- a/context/patterns.md +++ b/context/patterns.md @@ -66,19 +66,19 @@ - Keep accepted ADRs immutable. Record a correction, reversal, or replacement in a new dated ADR that references and supersedes the accepted record; default a new decision to `Accepted` unless its request explicitly names another allowed status. - Declare the six workflows' command slug, skill slug, title, description, argument hint, OpenCode routing role, Claude allowed tools, and `optional` flag exactly once in the typed `config/pkl/base/workflow-catalog.pkl`. Marking a workflow `optional` is an install-time statement only; it never conditions generation, and the manifest that carries it (`config/pkl/base/optional-workflow-manifest.pkl` → `config/optional-workflows.json`) is derived from the catalog rather than hand-listed. Composite, target-routing, permission, and coverage consumers must iterate or look up those records rather than maintain parallel per-workflow matrices. Adding a workflow is one catalog record plus one base module plus one composite registration; the only hand-maintained number is the exact generated-artifact count in `generation-contract-check.pkl`, which is deliberately literal so an unintended inventory change fails. - Keep cross-target generated-config primitives in focused base modules under `config/pkl/base/` and re-export them through `config/pkl/renderers/common.pkl` when multiple renderers need the same contract. A migrated workflow's package-local phase, persisted-document, and output references are canonical named document values in that workflow module, not parallel snapshots in `workflow-content.pkl` or the composite renderer. -- Model workflow skills as self-contained packages with deterministic package-relative document paths, including nested `references/` files. Shared Pkl skeletons may instantiate multiple skills, but every rendered skill must receive complete local documents. The only allowed sibling dependency is `sce-decision`, invoked once per qualifying decision from successful task or plan synchronization. +- Model workflow skills as self-contained packages with deterministic package-relative document paths, including nested `references/` files. Shared Pkl skeletons may instantiate multiple skills, but every rendered skill must receive complete local documents. SCE workflow skills own SCE control flow and may use relevant non-SCE skills as in-step helpers; helpers return control to the active step and preserve its order, gates, waits, writes, validation, stops, and output. The only allowed SCE sibling dependency is `sce-decision`, invoked once per qualifying decision from successful task or plan synchronization. - Use the project-root `.pi/` workflows as the behavioral baseline for canonical workflow packages; do not use generated target Markdown as an authoring source. - 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 and persisted-document references and require `SKILL.md` to read each reference before its phase runs. Phase-free workflows retain their two-file package shape. -- Keep cross-workflow agent-behavior policy such as the no-improvisation rule in the shared `renderSkill` preamble of `workflow-composite.pkl`, which every workflow and target already composes through. 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. +- 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. 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. - 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. Derive workflow permissions from catalog role assignments, and derive the additional `sce-decision` permission only for the Code agent. +- 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. - Keep `config/pkl/renderers/metadata-coverage-check.pkl` as a fail-fast exact-inventory guard deriving command slugs, skill entrypoints, and package-local workflow paths from the typed catalog, while independently retaining the expected OpenCode agent inventory and per-target one-to-one command-to-workflow-skill route assertions; run it whenever workflow documents or target metadata change. -- Keep `config/pkl/renderers/generation-contract-check.pkl` independent of `generate.pkl` output assembly when deriving expected paths: build the exact target paths from renderer document inventories, name retained non-workflow assets explicitly, compare against all `output.files`, require every phase-based `SKILL.md` to cite each emitted phase reference, and reject stale phase-skill slugs or unresolved package-local reference tokens in generated workflow entrypoint `SKILL.md` documents. Package-local reference prose is allowed to mention its own persisted-format history. It also rejects two or more consecutive blank lines in generated workflow entrypoint `SKILL.md` documents (`no-blank-line-runs`) and any `SKILL.md` that reproduces a sibling `references/output.md` fenced layout verbatim (`output-dedup`). Preserve controlled negative fixtures for extra paths, missing paths, forbidden references, blank-line runs, and duplicated output layouts. +- Keep `config/pkl/renderers/generation-contract-check.pkl` independent of `generate.pkl` output assembly when deriving expected paths: build the exact target paths from renderer document inventories, name retained non-workflow assets explicitly, compare against all `output.files`, require every phase-based `SKILL.md` to cite each emitted phase reference, require the shared non-SCE helper-composition rule and SCE-scoped workflow prohibitions in every generated workflow skill, enforce the exact catalog-derived OpenCode skill permission order, and reject stale phase-skill slugs or unresolved package-local reference tokens in generated workflow entrypoint `SKILL.md` documents. Package-local reference prose is allowed to mention its own persisted-format history. It also rejects two or more consecutive blank lines in generated workflow entrypoint `SKILL.md` documents (`no-blank-line-runs`) and any `SKILL.md` that reproduces a sibling `references/output.md` fenced layout verbatim (`output-dedup`). Preserve controlled negative fixtures for extra paths, missing paths, forbidden references, missing helper composition, unscoped prohibitions, arbitrary or misordered OpenCode permissions, blank-line runs, and duplicated output layouts. - Workflow renderers may extend canonical frontmatter only with target-supported metadata, must preserve behavior, and append only the required final newline at the output mapping. Structured composition renders semantic package/composite differences at their source while preserving one owner for every canonical gate, branch, write, and continuation. Composite mode emits a document's body only: frontmatter is a package-mode concern, so an embedded command or phase contributes no `name:`, `description:`, or `argument-hint:` line to the composed `SKILL.md`. Suppression happens in the typed model, never by parsing or stripping Markdown markers. Every reference a rendered document states must resolve in the mode that states it: composite text may name a section embedded in the same `SKILL.md` or the sibling `references/output.md`, but a sentence whose only target is a package-mode file — a `references/*-contract.yaml`, a removed `.md`, or the composed workflow itself — is package-only and its composite spelling drops the sentence rather than pointing at nothing. A phase's terminal internal states are named by its own steps, so dropping such a pointer removes no instruction. Migrate one workflow at a time and compare its OpenCode, Claude, and Pi paths against a retained pre-task root. Byte-identical generated payload is the regression guard for refactors that must preserve output; when a change intentionally alters generated text, the guard becomes the reviewed diff against that retained root, showing only the intended additions and removals. -- Every target's commands (Pi: prompts) must stay thin and invoke exactly one corresponding workflow skill (`sce-change-to-plan`, `sce-next-task`, `sce-validate`, or `sce-commit`). They must not sequence phase skills. The workflow skill executes package-local phases directly, after reading the applicable reference, and keeps phase statuses as internal state. Only the successful task/plan synchronization decision gate may invoke sibling `sce-decision`; preserve that exception as exact rather than general sibling orchestration. +- Every target's commands (Pi: prompts) must stay thin and invoke exactly one corresponding workflow skill (`sce-change-to-plan`, `sce-next-task`, `sce-validate`, or `sce-commit`). They must not sequence phase skills. The workflow skill executes package-local phases directly, after reading the applicable reference, and keeps phase statuses as internal state. Relevant non-SCE helper skills may run inside the active step only as helpers that return control to that step; only the successful task/plan synchronization decision gate may invoke sibling SCE `sce-decision`, preserving that exception as exact rather than general SCE orchestration. - A phase-based workflow package contains `SKILL.md`, `references/output.md`, and named package-local references for its phase instructions and persisted-file templates. `SKILL.md` alone owns ordering, branching, waits, and same-session resume; it reads the applicable reference before phase side effects. Phase-free workflows contain exactly `SKILL.md` and `references/output.md`. Put every and only human-visible gate, report, and terminal response layout in `output.md`. State each layout exactly once inside `output.md`: when a phase's return-value layout and a workflow branch's layout describe the same output, keep the fuller statement (the one carrying every status variant, field, and report rule) and let the other place point at that section by heading instead of restating it. An `output.md` section must not reference a document outside its own package; a mode-aware semantic reference is how composite text names the embedded section that replaced a package-mode file. A composed `SKILL.md` states no layout of its own: a branch that produces user-visible output names the `output.md` section it renders (`Render the **{Section}** layout from `references/output.md`.`) and keeps only what `output.md` does not carry — the branch condition, the field mapping that fills the layout, the wait, and every prohibition. Model this per layout as a mode-aware semantic reference whose package spelling is the inline block a standalone command file still owns and whose composite spelling is the citation; do not achieve it by deleting text the sibling `output.md` never states. Wait points such as bootstrap, clarification, revision, implementation approval, and failed-validation repair remain real same-session turn boundaries owned by the composite skill. - A phase-based workflow `SKILL.md` reads top to bottom as the control-flow document. Keep the phase-reference inventory ahead of `## Input`; state which reference each numbered workflow step reads before running; keep phase instructions and persisted-document formats in those named references rather than duplicating them in `SKILL.md`. A workflow that reaches the same phase from more than one step reuses one reference. Phase-free workflow rendering continues through the generic composite body path. - Keep the Markdown renderer contract in `config/pkl/renderers/common.pkl` limited to deterministic `frontmatter + body` assembly without injected generated-file marker text. @@ -104,7 +104,7 @@ ## Internal subagent parity mapping - Encode internal-agent parity by target capability, not by forcing unsupported frontmatter keys. -- Keep manual OpenCode Plan and Code agent bodies limited to routing to their approved commands; keep target permissions and presentation metadata in `config/pkl/renderers/opencode-metadata.pkl`. +- Keep manual OpenCode Plan and Code agent bodies limited to routing to their approved commands; keep target permissions and presentation metadata in `config/pkl/renderers/opencode-metadata.pkl`. Their skill permission order must allow ordinary non-SCE helpers, deny arbitrary SCE workflow chaining, and place catalog-derived owned-workflow allows after that deny. - Do not generate Claude agents; Claude receives six thin commands, six renderer-composed workflow skill packages, and the standalone internal `sce-decision` package, with supported command tools and one-to-one workflow-skill slugs owned under `config/pkl/renderers/`. - Keep parity decisions reproducible by validating generated outputs directly. diff --git a/context/plans/update-sce-skill-orchestration.md b/context/plans/update-sce-skill-orchestration.md new file mode 100644 index 00000000..a2dcbc6d --- /dev/null +++ b/context/plans/update-sce-skill-orchestration.md @@ -0,0 +1,118 @@ +# Plan: update-sce-skill-orchestration + +## Change summary + +Update the canonical workflow-rendering sources so SCE skills retain exclusive ownership of SCE workflow control flow while unrelated skills remain usable as helper capabilities during the active step. Replace broad skill prohibitions in canonical workflow Purpose/Rules content with SCE-scoped wording, and add one shared target-neutral helper-composition rule that preserves phase order, gates, waits, writes, validation, stops, and output contracts. + +Update the catalog-derived OpenCode agent permission rendering so non-SCE skills are allowed by default, arbitrary `sce-*` skills are denied, and each agent's explicitly owned SCE workflows (plus the existing Code-agent `sce-decision` exception) are allowed after the wildcard deny. Preserve Claude's generic `Skill` tool exposure and Pi's extension/runtime behavior. Strengthen generated-output contract checks and inspect temporary OpenCode, Claude, and Pi payloads without modifying ephemeral generated trees. + +## Acceptance criteria + +How this plan is proven complete. Each criterion is observable and names the check that proves it. `/validate` runs these checks; no task in the stack performs final validation. + +- [x] AC1: Every generated SCE workflow skill scopes workflow-control prohibitions to SCE skills/packages/commands and explicitly permits relevant non-SCE helper skills while stating that helper use returns control to the active step without weakening its invariants; no generated workflow contains an unscoped `Never invoke another skill`-style prohibition. + - Validate: Generate a temporary payload and inspect every `SKILL.md` under `.opencode/skills/`, `.claude/skills/`, and `.pi/skills/`; run focused searches for unscoped prohibition text and required helper-rule language. +- [x] AC2: Generated OpenCode Plan and Code agents allow ordinary non-SCE skills without prompting, deny arbitrary `sce-*` skills, and allow only their catalog-derived owned SCE workflows after the deny rule; the Code agent retains the synchronization-only `sce-decision` permission. + - Validate: Inspect temporary `.opencode/agent/` output and assert the ordered `skill` entries for both agents; run the generated contract checks. +- [x] AC3: Claude generated commands continue to expose `Skill` where catalog metadata requires it and have no new SCE-specific permission allowlist; Pi receives the corrected workflow text and its generated extension is unchanged. + - Validate: Inspect temporary `.claude/commands/`, `.claude/skills/`, `.pi/prompts/`, `.pi/skills/`, and `.pi/extensions/sce/index.ts`; compare the extension content to its canonical source and check Claude command frontmatter for `Skill`. +- [x] AC4: Existing workflow control-flow semantics and generated artifact shape remain unchanged apart from the intended wording and OpenCode permission changes. + - Validate: Review the temporary generated diff and run `nix run .#pkl-check-generated` plus `nix flake check`. + +### Full validation + +Repository-wide checks `/validate` runs after the last task, regardless of which criterion they map to. + +- `nix run .#pkl-check-generated` +- `nix flake check` +- `nix run .#pkl-generate -- "$(mktemp -d)"` followed by inspection of `.opencode/agent/`, `.opencode/skills/`, `.claude/commands/`, `.claude/skills/`, `.pi/prompts/`, and `.pi/skills/` in the temporary output. + +### Context sync + +- `context/overview.md` — current cross-target workflow orchestration and OpenCode routing/permission behavior. +- `context/architecture.md` — shared composite-rendering and target-boundary ownership. +- `context/patterns.md` — canonical helper-skill composition and OpenCode permission derivation rules. +- `context/glossary.md` — terminology for SCE workflow ownership versus non-SCE helper capability composition, if needed. +- `context/sce/shared-context-plan-workflow.md` +- `context/sce/shared-context-code-workflow.md` +- `context/sce/brownfield-workflow.md` +- `context/sce/handover-workflow.md` + +## Constraints and non-goals + +- **In scope:** Canonical Pkl workflow prose and shared composite preamble; catalog-derived OpenCode agent skill permissions; generated-output contract assertions needed to prevent regression; temporary generated-output inspection and related durable-context synchronization. +- **Out of scope:** Generated `.opencode`, `.claude`, and `.pi` trees; Rust CLI behavior; Claude permission restrictions; Pi extension policy enforcement, tracing, or runtime behavior; workflow phase order, gates, waits, stop conditions, write boundaries, validation logic, output layouts, command routing, or same-session resume semantics. +- **Constraints:** Edit canonical `config/pkl/` sources only; keep shared helper wording target-neutral and single-owned; derive explicit OpenCode SCE permissions from `workflow-catalog.pkl`; keep permission rule order with `skill: "*": allow`, `sce-*`: deny, then explicit allows; preserve Claude's catalog-derived `Skill` tool metadata and Pi's empty target-specific frontmatter. +- **Non-goal:** Do not weaken SCE determinism by allowing arbitrary SCE workflow chaining or by turning helper skills into workflow handoffs. + +## Assumptions + +- The request describes new work rather than an update to an existing plan; no matching plan exists under `context/plans/`. +- The existing `sce-decision` Code-agent permission remains the only non-catalog internal SCE exception, and its synchronization-only gate is unchanged. +- Existing generation-contract infrastructure is the appropriate place for cross-target wording and permission invariants; no new test framework is needed. + +## Task stack + +- [x] T01: `Scope canonical workflow orchestration rules and add helper composition` (status:done) + - Implementation evidence: Scoped canonical workflow prohibitions to SCE skills/packages/commands across the composite renderer, workflow bodies, brownfield/handover rules, and context-sync rules; added the shared target-neutral helper composition rule preserving return-to-step, phase order, gates, waits, writes, validation, stops, and terminal output. + - Task ID: T01 + - Goal: Update canonical workflow Purpose/Rules prose and the shared composite preamble so SCE skills forbid only SCE workflow chaining while relevant non-SCE helper skills are explicitly composable and must return control to the active workflow step without changing its control-flow or output invariants. + - Boundaries (in/out of scope): In — `config/pkl/renderers/workflow-composite.pkl`, `config/pkl/base/workflow-content.pkl`, the canonical workflow modules containing direct broad prohibitions (including change-to-plan, commit, brownfield, and handover), and any narrowly necessary source-level wording references. Out — OpenCode permission rendering, generated files, workflow behavior beyond the wording distinction, Claude/Pi runtime code, and durable context edits. + - Dependencies: none + - Done when: Every canonical Purpose/Rules prohibition is explicitly SCE-scoped; the shared composite preamble contains one target-neutral helper-skill composition rule covering return-to-step and preservation of step order, gates, waits, writes, validation, stops, and terminal output; package-mode brownfield and handover wording is aligned; no unrelated helper skill can reasonably be read as forbidden. + - Verification notes (commands or checks): Focused search across `config/pkl/` for broad prohibition phrases; evaluate affected Pkl modules through the Nix dev shell; inspect the source diff for unchanged gates, waits, boundaries, and output contracts. + - Verification evidence: Focused Pkl evaluations passed for the affected workflow sources and `workflow-composite.pkl`; temporary generation produced all 18 workflow `SKILL.md` files, with no unscoped prohibition matches and the helper-composition rule present in all 18; `git diff --check` passed. + +- [x] T02: `Derive ordered OpenCode SCE skill permissions from the workflow catalog` (status:done) + - Implementation evidence: Updated OpenCode agent skill permissions to allow non-SCE skills by default, deny arbitrary `sce-*` skills, and retain catalog-derived Plan/Code workflow allows after the deny rule, including the Code-only `sce-decision` exception. + - Task ID: T02 + - Goal: Change OpenCode agent permission rendering to allow non-SCE skills by default, deny arbitrary `sce-*` skills, and place catalog-derived explicit workflow permissions after the deny rule for Plan and Code agents. + - Boundaries (in/out of scope): In — `config/pkl/renderers/opencode-metadata.pkl` and focused OpenCode metadata/rendering assertions if required to express the ordering. Out — manually maintained workflow inventories, Claude allowed-tool metadata, Pi rendering, OpenCode command routing, and any change to the valid owned-workflow set or `sce-decision` synchronization exception. + - Dependencies: T01 + - Done when: Temporary generated Plan and Code agents contain `skill: "*": allow`, `sce-*`: deny, then only their catalog-derived explicit SCE allows; Plan allows only `sce-change-to-plan`, Code allows its catalog workflows plus `sce-decision`; normal non-SCE helper skills do not prompt and arbitrary SCE chaining remains denied. + - Verification notes (commands or checks): Evaluate `opencode-metadata.pkl` and `opencode-content.pkl`; generate a temporary payload and inspect both `.opencode/agent/` files for exact permission order and entries. + - Verification evidence: `nix develop -c pkl eval config/pkl/renderers/opencode-metadata.pkl` and `opencode-content.pkl` passed; temporary generation showed the exact ordered permissions for Plan and Code agents. + +- [x] T03: `Guard and verify cross-target generated orchestration contracts` (status:done) + - Implementation evidence: Added cross-target contract assertions for the shared helper-composition rule, SCE-scoped workflow prohibitions, and exact catalog-derived OpenCode skill permission ordering; updated the handover content guard to the scoped wording; added negative fixtures for each new failure mode and wired them into the generated-output check; corrected existing fixture failures to use the supported Pkl `throw` diagnostic path. + - Task ID: T03 + - Goal: Extend canonical generation-contract checks to require the helper-skill composition rule and the corrected SCE-scoped wording across all generated workflow skills, and to enforce the ordered OpenCode permission invariant while retaining existing inventory and behavior guards. + - Boundaries (in/out of scope): In — `config/pkl/renderers/generation-contract-check.pkl`, its existing focused fixtures/check wiring only where needed, and temporary-output inspection scripts or commands used by the verification record. Out — changing workflow semantics, adding generated artifacts, modifying target runtimes/extensions, or introducing a second workflow catalog. + - Dependencies: T01, T02 + - Done when: Generation fails for an unscoped skill prohibition, missing helper-composition rule, arbitrary SCE permission allowance, or wrong OpenCode rule order; generation still accepts the existing synchronization-only `sce-decision` exception and exact artifact inventory; all three target outputs are inspected from an explicit temporary root with no repository generated trees created. + - Verification notes (commands or checks): Run `nix run .#pkl-check-generated`; run `nix run .#pkl-generate -- "$(mktemp -d)"` and inspect `.opencode/agent/`, `.opencode/skills/`, `.claude/commands/`, `.claude/skills/`, `.pi/prompts/`, `.pi/skills/`, and `.pi/extensions/sce/index.ts`; run `nix flake check`. + - Verification evidence: `nix run .#pkl-check-generated` passed with the exact 101-file inventory and all new orchestration/permission contracts; all nine negative Pkl fixtures failed with their expected diagnostics; temporary generation inspected six helper-bearing workflow skills per target, two ordered OpenCode permission agents, six Claude commands with `Skill`, and a byte-identical Pi extension; `git diff --check` and `nix flake check` passed. + +## Open questions + +None. The requested ownership distinction, target behavior, permission ordering, source-of-truth boundary, and verification commands are explicit; remaining wording and assertion details are local implementation choices constrained by the existing renderer architecture. + +## Validation Report + +**Status:** validated +**Date:** 2026-08-07 + +### Commands run + +- `nix run .#pkl-check-generated` -> exit 0 (ephemeral generation passed with the exact 101-file inventory and all generated-output contracts) +- `nix flake check` -> exit 0 (all flake checks passed) +- `nix run .#pkl-generate -- ` followed by generated-output inspection -> exit 0 (all requested OpenCode, Claude, and Pi output directories passed inspection; 18 workflow skills had scoped helper wording, permissions were ordered exactly, all six Claude commands exposed `Skill`, and the Pi extension matched its canonical source) + +### Scaffolding removed + +- None. + +### Success-criteria verification + +- [x] AC1: Every generated SCE workflow skill scopes workflow-control prohibitions to SCE skills/packages/commands and explicitly permits relevant non-SCE helper skills while stating that helper use returns control to the active step without weakening its invariants; no generated workflow contains an unscoped `Never invoke another skill`-style prohibition. -> Temporary generation inspected all 18 workflow `SKILL.md` files; helper and return-to-step wording were present, with no unscoped prohibition. +- [x] AC2: Generated OpenCode Plan and Code agents allow ordinary non-SCE skills without prompting, deny arbitrary `sce-*` skills, and allow only their catalog-derived owned SCE workflows after the deny rule; the Code agent retains the synchronization-only `sce-decision` permission. -> Temporary Plan and Code agent output matched the exact ordered permission blocks. +- [x] AC3: Claude generated commands continue to expose `Skill` where catalog metadata requires it and have no new SCE-specific permission allowlist; Pi receives the corrected workflow text and its generated extension is unchanged. -> All six generated Claude commands exposed `Skill`; the generated Pi extension was byte-identical to `config/lib/pi-plugin/sce-pi-extension.ts`. +- [x] AC4: Existing workflow control-flow semantics and generated artifact shape remain unchanged apart from the intended wording and OpenCode permission changes. -> Temporary generated output inspection found the expected artifact shape and only the intended wording and OpenCode permission differences; both repository validation commands passed. + +### Failed checks and follow-ups + +- None. + +### Residual risks + +- None identified. diff --git a/context/sce/dedup-ownership-table.md b/context/sce/dedup-ownership-table.md index 39fc044a..a9a25528 100644 --- a/context/sce/dedup-ownership-table.md +++ b/context/sce/dedup-ownership-table.md @@ -30,6 +30,6 @@ - Keep Plan and Code routing roles separate without placing workflow doctrine in agent bodies. - Keep commands thin: each routes to exactly one workflow skill and owns no phase behavior. - Keep task and plan synchronization policy in the one shared Pkl skeleton even though each workflow skill composes its own instance. -- Keep `sce-decision` as the sole sibling-skill exception: only the decision gate in successful task or plan synchronization may invoke it, once per qualifying decision. +- 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 or plan synchronization's decision gate, once per qualifying decision. - Do not reintroduce removed `/handover`, 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 four 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. diff --git a/context/sce/handover-workflow.md b/context/sce/handover-workflow.md index 99613439..4065bb63 100644 --- a/context/sce/handover-workflow.md +++ b/context/sce/handover-workflow.md @@ -26,8 +26,9 @@ Purpose text. The package contains only `SKILL.md`, which owns mode routing, writer and loader behavior, and internal statuses, plus `references/output.md`, which -owns every human-visible layout. No sibling skill or workflow command is -invoked. +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. ## Modes diff --git a/context/sce/plan-code-overlap-map.md b/context/sce/plan-code-overlap-map.md index 32329157..6512fb47 100644 --- a/context/sce/plan-code-overlap-map.md +++ b/context/sce/plan-code-overlap-map.md @@ -23,7 +23,7 @@ - Workflow commands own only routing to one workflow skill. - Workflow skills own phase ordering, status branching, gates, edits, verification, and result/report formats. -- Thin OpenCode agents own only role-to-command routing and target permissions; their skill allowlists name exactly the four workflow slugs. +- Thin OpenCode agents own only role-to-command routing and target permissions; their ordered skill permissions allow ordinary non-SCE helpers, deny arbitrary `sce-*` skills, and allow only catalog-derived owned workflow slugs, with the Code-only synchronization exception for `sce-decision`. - Claude and Pi do not receive generated agents. - Each workflow package carries exactly one reference file, `references/output.md`, so it remains self-contained without cross-package dependencies. - The removed grouped shared-content catalog and automated OpenCode profile have no current owner or consumer. diff --git a/context/sce/shared-context-code-workflow.md b/context/sce/shared-context-code-workflow.md index c4ae1607..1e27ff71 100644 --- a/context/sce/shared-context-code-workflow.md +++ b/context/sce/shared-context-code-workflow.md @@ -43,7 +43,7 @@ Phase names below identify canonical modules in `config/pkl/base/workflow-next-t - Emits exactly one next-task command for the first unchecked task in plan order, or a `/validate` command when all implementation tasks are complete. - Never executes the continuation in the same invocation. -A context-sync blocker does not undo successful implementation: the task remains complete in the plan, but the workflow stops because durable context is stale. On every target, review, approval, execution, evidence recording, synchronization, and continuation are internal phases of one `sce-next-task` invocation. The sole sibling-skill exception is the synchronization decision gate's bounded invocation of `sce-decision`. +A context-sync blocker does not undo successful implementation: the task remains complete in the plan, but the workflow stops because durable context is stale. On every target, review, approval, execution, evidence recording, synchronization, and continuation are internal phases of one `sce-next-task` invocation. Relevant non-SCE skills may assist inside an active step only as helpers that return control to that step; the sole SCE sibling-skill exception is the synchronization decision gate's bounded invocation of `sce-decision`. ## `/validate` entrypoint @@ -53,7 +53,7 @@ A context-sync blocker does not undo successful implementation: the task remains 2. Failed or blocked validation ends the session without repair edits; retry uses `/validate {plan-path}`. 3. `sce-plan-context-sync` runs only from a successful `Status: validated` handoff, applies the same decision gate before current-state edits, and reconciles the completed plan with durable repository context. ADR paths already written during task synchronization are reused for the same decision. -On every target, `sce-validate/SKILL.md` dispatches workflow steps 1 and 2 through `references/validation.md` and `references/context-sync.md`, while `references/validation-report.md` owns the plan-file Validation Report format. Failed and blocked statuses stop before synchronization exactly as in the canonical flow. Final validation never runs from an individual implementation task. +On every target, `sce-validate/SKILL.md` dispatches workflow steps 1 and 2 through `references/validation.md` and `references/context-sync.md`, while `references/validation-report.md` owns the plan-file Validation Report format. Failed and blocked statuses stop before synchronization exactly as in the canonical flow. Final validation never runs from an individual implementation task. Non-SCE helper skills, when relevant, return control to the active validation or synchronization step without changing its workflow invariants. ## Flow @@ -83,7 +83,7 @@ flowchart TD - OpenCode, Claude, and Pi: thin commands (Pi: prompts) invoking `sce-next-task` or `sce-validate`. - `sce-next-task` packages contain `SKILL.md`, `references/{plan-review,task-execution,context-sync,output}.md`. - `sce-validate` packages contain `SKILL.md`, `references/{validation,context-sync,validation-report,output}.md`. -- OpenCode adds `entry-skill` and a one-entry `skills` list naming that skill. Its Code routing agent allows `sce-next-task`, `sce-validate`, and `sce-commit`, plus internal `sce-decision` invocation; the Plan agent does not allow `sce-decision`. +- OpenCode adds `entry-skill` and a one-entry `skills` list naming that skill. Its Plan and Code routing agents allow ordinary non-SCE skills by default, deny arbitrary `sce-*` skills, and then allow only catalog-owned workflows: Plan allows `sce-change-to-plan`; Code allows `sce-next-task`, `sce-validate`, `sce-commit`, `sce-handover`, and `sce-brownfield`, plus the synchronization-only `sce-decision` exception. ## Canonical sources