diff --git a/.agents/skills/sce-decision/SKILL.md b/.agents/skills/sce-decision/SKILL.md index 543044c4d..789d792ba 100644 --- a/.agents/skills/sce-decision/SKILL.md +++ b/.agents/skills/sce-decision/SKILL.md @@ -1,17 +1,17 @@ --- name: sce-decision description: > - Write one immutable ADR for one qualifying system-wide decision + Write one immutable ADR for one decision already qualified by context synchronization --- # SCE Decision ## Purpose -Write exactly one architecture decision record for one qualifying system-wide -important decision during successful task context synchronization. Return -a deterministic internal handoff to the invoking synchronization phase. Do not -render an independent user-visible response. +Write exactly one architecture decision record for one decision already qualified +by successful task context synchronization. Return a deterministic internal +handoff to the invoking synchronization phase. Do not render an independent +user-visible response. ## Input @@ -28,28 +28,22 @@ synchronization. It must identify: Do not accept raw workflow arguments, ordinary phase state, multiple decisions, or direct user invocation. Do not reconstruct missing material facts. -## Decision gate - -A decision qualifies only when it establishes or changes a system-wide important -constraint involving at least one of: - -- System boundaries or ownership. -- Public or cross-domain interfaces. -- Data models or persistence. -- Compatibility contracts. -- Security posture. -- Deployment or distribution strategy. -- A major dependency. -- A similarly durable constraint that is costly or risky to reverse. - -Routine implementation details, local refactors, naming and formatting choices, -temporary experiments, and easily reversible choices do not qualify. When the -request does not demonstrate the threshold, return `not_qualified` (or -`skipped` when the caller deliberately skips the gate); do not create an ADR -merely because context synchronization occurred. A nonqualifying or skipped -result is non-blocking, so the invoking synchronization phase continues -normally. Reserve `blocked` for missing, contradictory, or otherwise unsafe -decision input or history. +## Qualification handoff + +The invoking task context synchronization phase solely owns the decision +qualification threshold and decides whether this skill is invoked. Treat the +caller's gate result as authoritative; do not redefine, broaden, or independently +rerun that threshold here. + +Require the request to state why the caller qualified the decision and include +supporting evidence. If the request explicitly represents a nonqualifying gate +outcome, return `not_qualified` (or `skipped` when the caller deliberately skipped +the gate) without writing an ADR. If a claimed qualification is unsupported by +its supplied evidence, return `not_qualified`. Missing, contradictory, or +otherwise unsafe material input remains `blocked`. + +`not_qualified` and `skipped` are non-blocking to the invoking synchronization +phase. ## Workflow @@ -91,21 +85,10 @@ deterministic slug; never add an arbitrary counter and never overwrite a record. ### 4. Write the ADR -Create exactly one file using `references/adr-template.md` and these rules: - -- **Context** states the forces and constraint that made a decision necessary. -- **Decision** states one resulting choice, not a list of unrelated choices. -- **Rationale** explains why this path best satisfies the constraints. -- **Alternatives considered** names credible alternatives and why they were not - selected. -- **Compatibility and risks** states compatibility effects, migration concerns, - and material risks with mitigations. -- **Guardrails** records durable limits that keep the decision narrow. -- **Consequences** records positive and negative resulting constraints. -- **Follow-up** lists only established work or conditions; use `None.` when no - follow-up is established. -- **References** links the plan, relevant tasks, evidence, current-state context, - related ADRs, and any superseded ADR. +Read `references/adr-template.md` before writing. It is the sole authority for +the persisted ADR schema and section semantics. Populate that template from the +validated request and evidence; do not restate or invent a parallel section +contract here. Use repository-relative Markdown links where practical. Describe durable truth, not the implementation session. Do not edit current-state context; the invoking diff --git a/.agents/skills/sce-decision/references/adr-template.md b/.agents/skills/sce-decision/references/adr-template.md index 31891d448..8c2b06e77 100644 --- a/.agents/skills/sce-decision/references/adr-template.md +++ b/.agents/skills/sce-decision/references/adr-template.md @@ -1,7 +1,7 @@ # Decision: {concise decision title} Date: {YYYY-MM-DD} -Status: {Proposed|Accepted|Rejected|Deprecated|Superseded} +Status: {validated decision status} Plan: `{context/plans/plan-name.md}` Task: `{task-id or comma-separated task IDs}` Supersedes: `{context/decisions/YYYY-MM-DD-prior-decision.md}` @@ -14,7 +14,7 @@ Omit `Task` or `Supersedes` only when it does not apply. Do not omit `Plan`. ## Decision -{Exactly one durable system-wide choice.} +{Exactly one durable choice already qualified by task context synchronization.} ## Rationale diff --git a/.agents/skills/sce-next-task/references/context-sync.md b/.agents/skills/sce-next-task/references/context-sync.md index fb330bb6d..057043313 100644 --- a/.agents/skills/sce-next-task/references/context-sync.md +++ b/.agents/skills/sce-next-task/references/context-sync.md @@ -157,6 +157,10 @@ verified classification and explain the difference in the report. ## 3.5 Record qualifying architecture decisions +This subsection is the sole owner of decision qualification. The threshold below +decides whether `sce-decision` is invoked; the decision skill consumes that gate +result and must not restate or broaden it. + During this successful synchronization, determine whether the completed change establishes or changes a system-wide important constraint involving one or more of: diff --git a/.claude/skills/sce-decision/SKILL.md b/.claude/skills/sce-decision/SKILL.md index 8b5d378ef..540a51aeb 100644 --- a/.claude/skills/sce-decision/SKILL.md +++ b/.claude/skills/sce-decision/SKILL.md @@ -1,7 +1,7 @@ --- name: sce-decision description: > - Write one immutable ADR for one qualifying system-wide decision + Write one immutable ADR for one decision already qualified by context synchronization compatibility: claude --- @@ -9,10 +9,10 @@ compatibility: claude ## Purpose -Write exactly one architecture decision record for one qualifying system-wide -important decision during successful task context synchronization. Return -a deterministic internal handoff to the invoking synchronization phase. Do not -render an independent user-visible response. +Write exactly one architecture decision record for one decision already qualified +by successful task context synchronization. Return a deterministic internal +handoff to the invoking synchronization phase. Do not render an independent +user-visible response. ## Input @@ -29,28 +29,22 @@ synchronization. It must identify: Do not accept raw workflow arguments, ordinary phase state, multiple decisions, or direct user invocation. Do not reconstruct missing material facts. -## Decision gate - -A decision qualifies only when it establishes or changes a system-wide important -constraint involving at least one of: - -- System boundaries or ownership. -- Public or cross-domain interfaces. -- Data models or persistence. -- Compatibility contracts. -- Security posture. -- Deployment or distribution strategy. -- A major dependency. -- A similarly durable constraint that is costly or risky to reverse. - -Routine implementation details, local refactors, naming and formatting choices, -temporary experiments, and easily reversible choices do not qualify. When the -request does not demonstrate the threshold, return `not_qualified` (or -`skipped` when the caller deliberately skips the gate); do not create an ADR -merely because context synchronization occurred. A nonqualifying or skipped -result is non-blocking, so the invoking synchronization phase continues -normally. Reserve `blocked` for missing, contradictory, or otherwise unsafe -decision input or history. +## Qualification handoff + +The invoking task context synchronization phase solely owns the decision +qualification threshold and decides whether this skill is invoked. Treat the +caller's gate result as authoritative; do not redefine, broaden, or independently +rerun that threshold here. + +Require the request to state why the caller qualified the decision and include +supporting evidence. If the request explicitly represents a nonqualifying gate +outcome, return `not_qualified` (or `skipped` when the caller deliberately skipped +the gate) without writing an ADR. If a claimed qualification is unsupported by +its supplied evidence, return `not_qualified`. Missing, contradictory, or +otherwise unsafe material input remains `blocked`. + +`not_qualified` and `skipped` are non-blocking to the invoking synchronization +phase. ## Workflow @@ -92,21 +86,10 @@ deterministic slug; never add an arbitrary counter and never overwrite a record. ### 4. Write the ADR -Create exactly one file using `references/adr-template.md` and these rules: - -- **Context** states the forces and constraint that made a decision necessary. -- **Decision** states one resulting choice, not a list of unrelated choices. -- **Rationale** explains why this path best satisfies the constraints. -- **Alternatives considered** names credible alternatives and why they were not - selected. -- **Compatibility and risks** states compatibility effects, migration concerns, - and material risks with mitigations. -- **Guardrails** records durable limits that keep the decision narrow. -- **Consequences** records positive and negative resulting constraints. -- **Follow-up** lists only established work or conditions; use `None.` when no - follow-up is established. -- **References** links the plan, relevant tasks, evidence, current-state context, - related ADRs, and any superseded ADR. +Read `references/adr-template.md` before writing. It is the sole authority for +the persisted ADR schema and section semantics. Populate that template from the +validated request and evidence; do not restate or invent a parallel section +contract here. Use repository-relative Markdown links where practical. Describe durable truth, not the implementation session. Do not edit current-state context; the invoking diff --git a/.claude/skills/sce-decision/references/adr-template.md b/.claude/skills/sce-decision/references/adr-template.md index 31891d448..8c2b06e77 100644 --- a/.claude/skills/sce-decision/references/adr-template.md +++ b/.claude/skills/sce-decision/references/adr-template.md @@ -1,7 +1,7 @@ # Decision: {concise decision title} Date: {YYYY-MM-DD} -Status: {Proposed|Accepted|Rejected|Deprecated|Superseded} +Status: {validated decision status} Plan: `{context/plans/plan-name.md}` Task: `{task-id or comma-separated task IDs}` Supersedes: `{context/decisions/YYYY-MM-DD-prior-decision.md}` @@ -14,7 +14,7 @@ Omit `Task` or `Supersedes` only when it does not apply. Do not omit `Plan`. ## Decision -{Exactly one durable system-wide choice.} +{Exactly one durable choice already qualified by task context synchronization.} ## Rationale diff --git a/.claude/skills/sce-next-task/references/context-sync.md b/.claude/skills/sce-next-task/references/context-sync.md index fb330bb6d..057043313 100644 --- a/.claude/skills/sce-next-task/references/context-sync.md +++ b/.claude/skills/sce-next-task/references/context-sync.md @@ -157,6 +157,10 @@ verified classification and explain the difference in the report. ## 3.5 Record qualifying architecture decisions +This subsection is the sole owner of decision qualification. The threshold below +decides whether `sce-decision` is invoked; the decision skill consumes that gate +result and must not restate or broaden it. + During this successful synchronization, determine whether the completed change establishes or changes a system-wide important constraint involving one or more of: diff --git a/.pi/skills/sce-decision/SKILL.md b/.pi/skills/sce-decision/SKILL.md index 543044c4d..789d792ba 100644 --- a/.pi/skills/sce-decision/SKILL.md +++ b/.pi/skills/sce-decision/SKILL.md @@ -1,17 +1,17 @@ --- name: sce-decision description: > - Write one immutable ADR for one qualifying system-wide decision + Write one immutable ADR for one decision already qualified by context synchronization --- # SCE Decision ## Purpose -Write exactly one architecture decision record for one qualifying system-wide -important decision during successful task context synchronization. Return -a deterministic internal handoff to the invoking synchronization phase. Do not -render an independent user-visible response. +Write exactly one architecture decision record for one decision already qualified +by successful task context synchronization. Return a deterministic internal +handoff to the invoking synchronization phase. Do not render an independent +user-visible response. ## Input @@ -28,28 +28,22 @@ synchronization. It must identify: Do not accept raw workflow arguments, ordinary phase state, multiple decisions, or direct user invocation. Do not reconstruct missing material facts. -## Decision gate - -A decision qualifies only when it establishes or changes a system-wide important -constraint involving at least one of: - -- System boundaries or ownership. -- Public or cross-domain interfaces. -- Data models or persistence. -- Compatibility contracts. -- Security posture. -- Deployment or distribution strategy. -- A major dependency. -- A similarly durable constraint that is costly or risky to reverse. - -Routine implementation details, local refactors, naming and formatting choices, -temporary experiments, and easily reversible choices do not qualify. When the -request does not demonstrate the threshold, return `not_qualified` (or -`skipped` when the caller deliberately skips the gate); do not create an ADR -merely because context synchronization occurred. A nonqualifying or skipped -result is non-blocking, so the invoking synchronization phase continues -normally. Reserve `blocked` for missing, contradictory, or otherwise unsafe -decision input or history. +## Qualification handoff + +The invoking task context synchronization phase solely owns the decision +qualification threshold and decides whether this skill is invoked. Treat the +caller's gate result as authoritative; do not redefine, broaden, or independently +rerun that threshold here. + +Require the request to state why the caller qualified the decision and include +supporting evidence. If the request explicitly represents a nonqualifying gate +outcome, return `not_qualified` (or `skipped` when the caller deliberately skipped +the gate) without writing an ADR. If a claimed qualification is unsupported by +its supplied evidence, return `not_qualified`. Missing, contradictory, or +otherwise unsafe material input remains `blocked`. + +`not_qualified` and `skipped` are non-blocking to the invoking synchronization +phase. ## Workflow @@ -91,21 +85,10 @@ deterministic slug; never add an arbitrary counter and never overwrite a record. ### 4. Write the ADR -Create exactly one file using `references/adr-template.md` and these rules: - -- **Context** states the forces and constraint that made a decision necessary. -- **Decision** states one resulting choice, not a list of unrelated choices. -- **Rationale** explains why this path best satisfies the constraints. -- **Alternatives considered** names credible alternatives and why they were not - selected. -- **Compatibility and risks** states compatibility effects, migration concerns, - and material risks with mitigations. -- **Guardrails** records durable limits that keep the decision narrow. -- **Consequences** records positive and negative resulting constraints. -- **Follow-up** lists only established work or conditions; use `None.` when no - follow-up is established. -- **References** links the plan, relevant tasks, evidence, current-state context, - related ADRs, and any superseded ADR. +Read `references/adr-template.md` before writing. It is the sole authority for +the persisted ADR schema and section semantics. Populate that template from the +validated request and evidence; do not restate or invent a parallel section +contract here. Use repository-relative Markdown links where practical. Describe durable truth, not the implementation session. Do not edit current-state context; the invoking diff --git a/.pi/skills/sce-decision/references/adr-template.md b/.pi/skills/sce-decision/references/adr-template.md index 31891d448..8c2b06e77 100644 --- a/.pi/skills/sce-decision/references/adr-template.md +++ b/.pi/skills/sce-decision/references/adr-template.md @@ -1,7 +1,7 @@ # Decision: {concise decision title} Date: {YYYY-MM-DD} -Status: {Proposed|Accepted|Rejected|Deprecated|Superseded} +Status: {validated decision status} Plan: `{context/plans/plan-name.md}` Task: `{task-id or comma-separated task IDs}` Supersedes: `{context/decisions/YYYY-MM-DD-prior-decision.md}` @@ -14,7 +14,7 @@ Omit `Task` or `Supersedes` only when it does not apply. Do not omit `Plan`. ## Decision -{Exactly one durable system-wide choice.} +{Exactly one durable choice already qualified by task context synchronization.} ## Rationale diff --git a/.pi/skills/sce-next-task/references/context-sync.md b/.pi/skills/sce-next-task/references/context-sync.md index fb330bb6d..057043313 100644 --- a/.pi/skills/sce-next-task/references/context-sync.md +++ b/.pi/skills/sce-next-task/references/context-sync.md @@ -157,6 +157,10 @@ verified classification and explain the difference in the report. ## 3.5 Record qualifying architecture decisions +This subsection is the sole owner of decision qualification. The threshold below +decides whether `sce-decision` is invoked; the decision skill consumes that gate +result and must not restate or broaden it. + During this successful synchronization, determine whether the completed change establishes or changes a system-wide important constraint involving one or more of: diff --git a/config/pkl/base/decision-skill.pkl b/config/pkl/base/decision-skill.pkl index a18192a8f..af32ce7e5 100644 --- a/config/pkl/base/decision-skill.pkl +++ b/config/pkl/base/decision-skill.pkl @@ -5,7 +5,7 @@ import "workflow-content.pkl" as model /// user-facing command or prompt routes to this skill. local SKILL_SLUG = "sce-decision" -local SKILL_DESCRIPTION = "Write one immutable ADR for one qualifying system-wide decision" +local SKILL_DESCRIPTION = "Write one immutable ADR for one decision already qualified by context synchronization" local skillText = (extraFrontmatterLines: String) -> """ --- @@ -18,10 +18,10 @@ description: > ## Purpose -Write exactly one architecture decision record for one qualifying system-wide -important decision during successful task context synchronization. Return -a deterministic internal handoff to the invoking synchronization phase. Do not -render an independent user-visible response. +Write exactly one architecture decision record for one decision already qualified +by successful task context synchronization. Return a deterministic internal +handoff to the invoking synchronization phase. Do not render an independent +user-visible response. ## Input @@ -38,28 +38,22 @@ synchronization. It must identify: Do not accept raw workflow arguments, ordinary phase state, multiple decisions, or direct user invocation. Do not reconstruct missing material facts. -## Decision gate - -A decision qualifies only when it establishes or changes a system-wide important -constraint involving at least one of: - -- System boundaries or ownership. -- Public or cross-domain interfaces. -- Data models or persistence. -- Compatibility contracts. -- Security posture. -- Deployment or distribution strategy. -- A major dependency. -- A similarly durable constraint that is costly or risky to reverse. - -Routine implementation details, local refactors, naming and formatting choices, -temporary experiments, and easily reversible choices do not qualify. When the -request does not demonstrate the threshold, return `not_qualified` (or -`skipped` when the caller deliberately skips the gate); do not create an ADR -merely because context synchronization occurred. A nonqualifying or skipped -result is non-blocking, so the invoking synchronization phase continues -normally. Reserve `blocked` for missing, contradictory, or otherwise unsafe -decision input or history. +## Qualification handoff + +The invoking task context synchronization phase solely owns the decision +qualification threshold and decides whether this skill is invoked. Treat the +caller's gate result as authoritative; do not redefine, broaden, or independently +rerun that threshold here. + +Require the request to state why the caller qualified the decision and include +supporting evidence. If the request explicitly represents a nonqualifying gate +outcome, return `not_qualified` (or `skipped` when the caller deliberately skipped +the gate) without writing an ADR. If a claimed qualification is unsupported by +its supplied evidence, return `not_qualified`. Missing, contradictory, or +otherwise unsafe material input remains `blocked`. + +`not_qualified` and `skipped` are non-blocking to the invoking synchronization +phase. ## Workflow @@ -101,21 +95,10 @@ deterministic slug; never add an arbitrary counter and never overwrite a record. ### 4. Write the ADR -Create exactly one file using `references/adr-template.md` and these rules: - -- **Context** states the forces and constraint that made a decision necessary. -- **Decision** states one resulting choice, not a list of unrelated choices. -- **Rationale** explains why this path best satisfies the constraints. -- **Alternatives considered** names credible alternatives and why they were not - selected. -- **Compatibility and risks** states compatibility effects, migration concerns, - and material risks with mitigations. -- **Guardrails** records durable limits that keep the decision narrow. -- **Consequences** records positive and negative resulting constraints. -- **Follow-up** lists only established work or conditions; use `None.` when no - follow-up is established. -- **References** links the plan, relevant tasks, evidence, current-state context, - related ADRs, and any superseded ADR. +Read `references/adr-template.md` before writing. It is the sole authority for +the persisted ADR schema and section semantics. Populate that template from the +validated request and evidence; do not restate or invent a parallel section +contract here. Use repository-relative Markdown links where practical. Describe durable truth, not the implementation session. Do not edit current-state context; the invoking @@ -163,7 +146,7 @@ local templateText = """ # Decision: {concise decision title} Date: {YYYY-MM-DD} -Status: {Proposed|Accepted|Rejected|Deprecated|Superseded} +Status: {validated decision status} Plan: `{context/plans/plan-name.md}` Task: `{task-id or comma-separated task IDs}` Supersedes: `{context/decisions/YYYY-MM-DD-prior-decision.md}` @@ -176,7 +159,7 @@ Omit `Task` or `Supersedes` only when it does not apply. Do not omit `Plan`. ## Decision -{Exactly one durable system-wide choice.} +{Exactly one durable choice already qualified by task context synchronization.} ## Rationale diff --git a/config/pkl/base/workflow-context-sync.pkl b/config/pkl/base/workflow-context-sync.pkl index 0e60d9f7c..88c230fb1 100644 --- a/config/pkl/base/workflow-context-sync.pkl +++ b/config/pkl/base/workflow-context-sync.pkl @@ -65,6 +65,10 @@ local skillText = (role: SyncRole, mode: workflow.WorkflowRenderMode) -> role.frontmatter.apply(mode) + "\n\n" + skillBody.apply(role, mode) local decisionGate = (evidenceSource: String, mode: workflow.WorkflowRenderMode) -> """ + This subsection is the sole owner of decision qualification. The threshold below + decides whether `sce-decision` is invoked; the decision skill consumes that gate + result and must not restate or broaden it. + During this successful synchronization, determine whether the completed change establishes or changes a system-wide important constraint involving one or more of: @@ -1275,6 +1279,10 @@ verified classification and explain the difference in the report. ## 3.5 Record qualifying architecture decisions +This subsection is the sole owner of decision qualification. The threshold below +decides whether `sce-decision` is invoked; the decision skill consumes that gate +result and must not restate or broaden it. + During this successful synchronization, determine whether the completed change establishes or changes a system-wide important constraint involving one or more of: diff --git a/config/pkl/renderers/generation-contract-check.pkl b/config/pkl/renderers/generation-contract-check.pkl index 9cdda173e..e6a3ecc1d 100644 --- a/config/pkl/renderers/generation-contract-check.pkl +++ b/config/pkl/renderers/generation-contract-check.pkl @@ -202,15 +202,7 @@ local expectedDecisionDocumentPaths = new Mapping { } local requiredDecisionSkillTokens = new Listing { - "qualifying system-wide" - "System boundaries or ownership" - "Public or cross-domain interfaces" - "Data models or persistence" - "Compatibility contracts" - "Security posture" - "Deployment or distribution strategy" - "major dependency" - "Routine implementation details" + "already qualified" "YYYY-MM-DD-.md" "`Proposed`" "`Accepted`" @@ -220,11 +212,18 @@ local requiredDecisionSkillTokens = new Listing { "otherwise default" "Never edit an ADR whose status is `Accepted`" "creates a new dated ADR" - "exactly one file" + "references/adr-template.md" + "exactly one ADR" "`written`" "`blocked`" } +local requiredDecisionOwnershipSkillTokens = new Listing { + "## Qualification handoff" + "Treat the caller's gate result as authoritative" + "sole authority for\nthe persisted ADR schema and section semantics" +} + local requiredDecisionWorkflowTokens = new Listing { "Record qualifying architecture decisions" "System boundaries or ownership" @@ -241,6 +240,42 @@ local requiredDecisionWorkflowTokens = new Listing { "On `blocked`" } +local requiredDecisionTemplateTokens = new Listing { + "## Context" + "## Decision" + "## Rationale" + "## Alternatives considered" + "## Compatibility and risks" + "## Guardrails" + "## Consequences" + "## Follow-up" + "## References" +} + +local forbiddenDecisionSkillGateTokens = new Listing { + "System boundaries or ownership" + "Public or cross-domain interfaces" + "Data models or persistence" + "Compatibility contracts" + "Security posture" + "Deployment or distribution strategy" + "A major dependency" + "Routine implementation details, local refactors" + "similarly durable constraint that is costly or risky to reverse" +} + +local forbiddenDecisionSkillTemplateRestatementTokens = new Listing { + "**Context** states" + "**Decision** states" + "**Rationale** explains" + "**Alternatives considered** names" + "**Compatibility and risks** states" + "**Guardrails** records" + "**Consequences** records" + "**Follow-up** lists" + "**References** links" +} + local requiredHandoverSkillTokens = new Listing { "selects **writer mode**" "selects **loader mode**" @@ -418,18 +453,6 @@ local requiredPhaseReferencesBySkill = new Mapping { } } -local requiredDecisionTemplateTokens = new Listing { - "## Context" - "## Decision" - "## Rationale" - "## Alternatives considered" - "## Compatibility and risks" - "## Guardrails" - "## Consequences" - "## Follow-up" - "## References" -} - local forbiddenWorkflowReferenceTokens = new Listing { "sce-context-load" "sce-plan-authoring" @@ -599,6 +622,42 @@ local assertDecisionContent = (documents: Mapping) -> ) "generated decision package content: complete" else throw("generated decision package is missing a required ADR rule or template section") +hidden assertDecisionGateTemplateOwnership = (artifacts: Mapping) -> + let (contexts = new Listing { + artifacts["config/.pi/skills/sce-next-task/references/context-sync.md"] + artifacts["config/.claude/skills/sce-next-task/references/context-sync.md"] + artifacts["config/.agents/skills/sce-next-task/references/context-sync.md"] + }) + let (skills = new Listing { + artifacts["config/.pi/skills/sce-decision/SKILL.md"] + artifacts["config/.claude/skills/sce-decision/SKILL.md"] + artifacts["config/.agents/skills/sce-decision/SKILL.md"] + }) + let (templates = new Listing { + artifacts["config/.pi/skills/sce-decision/references/adr-template.md"] + artifacts["config/.claude/skills/sce-decision/references/adr-template.md"] + artifacts["config/.agents/skills/sce-decision/references/adr-template.md"] + }) + if ( + contexts.every((text) -> text.contains("sole owner of decision qualification")) + && skills.every((text) -> + text.contains("## Qualification handoff") + && text.contains("caller's gate result as authoritative") + && text.contains("sole authority for") + && text.contains("persisted ADR schema and section semantics") + && !text.contains("## Decision gate") + && !text.contains("**Context** states") + && !text.contains("**Decision** states") + ) + && templates.every((text) -> + text.contains("Status: {validated decision status}") + && text.contains("## Context") + && text.contains("## Decision") + && text.contains("## Rationale") + && !text.contains("Proposed|Accepted|Rejected|Deprecated|Superseded") + ) + ) "sce-decision: context sync owns qualification and ADR template owns persisted section semantics" + else throw("decision qualification must be owned by tracked context-sync outputs while sce-decision consumes the gate and adr-template.md owns persisted ADR schema") local assertHandoverContent = (documents: Mapping) -> if ( documents.length == 4 @@ -1167,6 +1226,7 @@ contractChecks { ["opencode-decision-permission"] = assertOpenCodeDecisionPermission.apply(opencode.agents) ["decision-package-paths"] = assertDecisionDocumentPaths.apply(decisionSkillDocuments) ["decision-package-content"] = assertDecisionContent.apply(decisionSkillDocuments) + ["decision-gate-template-ownership"] = assertDecisionGateTemplateOwnership.apply(generatedArtifacts) ["handover-package-content"] = assertHandoverContent.apply(handoverSkillDocuments) ["handover-schema-completeness-ownership"] = assertHandoverSchemaCompletenessOwnership.apply(workflowDocuments) ["brownfield-package-content"] = assertBrownfieldContent.apply(brownfieldSkillDocuments) diff --git a/context/plans/compress-workflow-execution-preamble.md b/context/plans/compress-workflow-execution-preamble.md index 445d91870..99f9fca82 100644 --- a/context/plans/compress-workflow-execution-preamble.md +++ b/context/plans/compress-workflow-execution-preamble.md @@ -427,3 +427,28 @@ The two additional root edits replace existing text without increasing line coun - Verify: `pkl eval config/pkl/renderers/generation-contract-check.pkl`, `nix run .#pkl-check-generated`, targeted ownership checks, and `git diff --check`. - Context synchronization: synced. + + +## Follow-up: decision qualification and ADR-template ownership + +- [x] T10: `Deduplicate decision gate and ADR section semantics` (status:done) + - Scope: task context-sync decision qualification, the standalone `sce-decision` + package, `references/adr-template.md`, canonical Pkl, generated semantic checks, + tracked Pi/Claude/Codex mirrors, and the ownership table. + - Ownership after change: `decisionGate` in `workflow-context-sync.pkl` solely owns + the qualification threshold and invocation decision. `sce-decision/SKILL.md` + consumes the caller's gate result and owns ADR lifecycle/history/path/result + behavior. `references/adr-template.md` solely owns the persisted ADR schema and + section semantics. + - Behavior preserved: only successful task synchronization invokes `sce-decision`; + routine/reversible changes remain nonqualifying; one request still writes or + reuses at most one ADR; allowed status/default, immutability, supersession, + collision handling, nonblocking `not_qualified`/`skipped`, blocking unsafe input, + and internal result shapes remain unchanged. + - Result: the selected decision skill/template plus next-task context-sync documents + shrink by 13 Markdown lines per tracked target, 39 + across Pi/Claude/Codex. + - Verify: `pkl eval config/pkl/renderers/generation-contract-check.pkl`, + `nix run .#pkl-check-generated`, targeted ownership checks across all tracked + mirrors, and `git diff --check`. + - Context synchronization: synced. diff --git a/context/sce/dedup-ownership-table.md b/context/sce/dedup-ownership-table.md index 4d6d8833a..6dd351197 100644 --- a/context/sce/dedup-ownership-table.md +++ b/context/sce/dedup-ownership-table.md @@ -31,7 +31,9 @@ | Handover persisted schema and completeness validity | `references/handover-template.md` generated from `renderPersistedFormatBody` in `workflow-handover.pkl` | Writer composes and validates against this contract; loader validates against the same contract; `sce-handover/SKILL.md` owns routing, path checks, read/write boundaries, and terminal layout selection without restating required-section or content-validity rules | intentional/keep | | Compact workflow execution contract | `executionContract` in `workflow-content.pkl` | Inline in change-to-plan, next-task, commit, validate, and handover entrypoints on all four targets; no extra runtime read | shared rendering, preserved behavior | | Workflow routing | Six command documents in the workflow modules | Thin OpenCode Plan/Code agents | intentional/keep | -| Standalone ADR writing contract | `decision-skill.pkl` | Cross-target `sce-decision` package; successful task synchronization invokes it through the shared decision gate | intentional/keep | +| Decision qualification gate | `decisionGate` in `workflow-context-sync.pkl` | Successful task context synchronization decides qualification and invokes `sce-decision` once per qualifying decision; `sce-decision` consumes the caller's gate result without restating or broadening the threshold | intentional/keep | +| Standalone ADR lifecycle, history, path, and result contract | `sce-decision/SKILL.md` generated from `skillText` in `decision-skill.pkl` | Cross-target internal `sce-decision` package; consumes one already-qualified request, validates status/history/path safety, writes or reuses one ADR, and returns the internal result | intentional/keep | +| Persisted ADR schema and section semantics | `references/adr-template.md` generated from `templateText` in `decision-skill.pkl` | `sce-decision` reads and populates the template at the write boundary without restating the section schema or field semantics | intentional/keep | ## Guardrails