diff --git a/commands/gsd/import.md b/commands/gsd/import.md index e8fe2d2c1..0abcae4d8 100644 --- a/commands/gsd/import.md +++ b/commands/gsd/import.md @@ -25,6 +25,7 @@ Future: `--prd` mode for PRD extraction is planned for a follow-up PR. @~/.claude/get-shit-done/workflows/import.md @~/.claude/get-shit-done/references/ui-brand.md @~/.claude/get-shit-done/references/gate-prompts.md +@~/.claude/get-shit-done/references/doc-conflict-engine.md diff --git a/get-shit-done/references/doc-conflict-engine.md b/get-shit-done/references/doc-conflict-engine.md new file mode 100644 index 000000000..67dc685fd --- /dev/null +++ b/get-shit-done/references/doc-conflict-engine.md @@ -0,0 +1,91 @@ +# Doc Conflict Engine + +Shared conflict-detection contract for workflows that ingest external content into `.planning/` (e.g., `/gsd-import`, `/gsd-ingest-docs`). Defines the report format, severity semantics, and safety-gate behavior. The specific checks that populate each severity bucket are workflow-specific and defined by the calling workflow. + +--- + +## Severity Semantics + +- **[BLOCKER]** — Unsafe to proceed. The workflow MUST exit without writing any destination files. Used for contradictions of locked decisions, missing prerequisites, and impossible targets. +- **[WARNING]** — Ambiguous or partially overlapping. The workflow MUST surface the warning and obtain explicit user approval before writing. Never auto-approve. +- **[INFO]** — Informational only. No gate; no user prompt required. Included in the report for transparency. + +--- + +## Report Format + +Plain-text, never markdown tables (no `|---|`). The report is rendered to the user verbatim. + +``` +## Conflict Detection Report + +### BLOCKERS ({N}) + +[BLOCKER] {Short title} + Found: {what the incoming content says} + Expected: {what existing project context requires} + → {Specific action to resolve} + +### WARNINGS ({N}) + +[WARNING] {Short title} + Found: {what was detected} + Impact: {what could go wrong} + → {Suggested action} + +### INFO ({N}) + +[INFO] {Short title} + Note: {relevant information} +``` + +Every entry requires `Found:` plus one of `Expected:`/`Impact:`/`Note:` plus (for BLOCKER/WARNING) a `→` remediation line. + +--- + +## Safety Gate + +**If any [BLOCKER] exists:** + +Display: +``` +GSD > BLOCKED: {N} blockers must be resolved before {operation} can proceed. +``` + +Exit WITHOUT writing any destination files. The gate must hold regardless of WARNING/INFO counts. + +**If only WARNINGS and/or INFO (no blockers):** + +Render the full report, then prompt for approval via the `approve-revise-abort` or `yes-no` pattern from `references/gate-prompts.md`. Respect text mode (see the workflow's own text-mode handling). If the user aborts, exit cleanly with a cancellation message. + +**If the report is empty (no entries in any bucket):** + +Proceed silently or display `GSD > No conflicts detected.` Either is acceptable; workflows choose based on verbosity context. + +--- + +## Workflow Responsibilities + +Each workflow that consumes this contract must define: + +1. **Its own check list per bucket** — which conditions are BLOCKER vs WARNING vs INFO. These are domain-specific (plan ingestion checks are not doc ingestion checks). +2. **The loaded context** — what it reads (ROADMAP.md, PROJECT.md, REQUIREMENTS.md, CONTEXT.md, intel files) before running checks. +3. **The operation noun** — substituted into the BLOCKED banner (`import`, `ingest`, etc.). + +The workflow MUST NOT: + +- Introduce new severity levels beyond BLOCKER/WARNING/INFO +- Render the report as a markdown table +- Write any destination file when BLOCKERs exist +- Auto-approve past WARNINGs without user input + +--- + +## Anti-Patterns + +Do NOT: + +- Use markdown tables (`|---|`) in the conflict report — use plain-text labels as shown above +- Bypass the safety gate when BLOCKERs exist — no exceptions for "minor" blockers +- Fold WARNINGs into INFO to skip the approval prompt — if user input is needed, it is a WARNING +- Re-invent severity labels per workflow — the three-level taxonomy is fixed diff --git a/get-shit-done/workflows/import.md b/get-shit-done/workflows/import.md index 7f8a9ca85..5b5167d0f 100644 --- a/get-shit-done/workflows/import.md +++ b/get-shit-done/workflows/import.md @@ -107,7 +107,7 @@ Extract from the imported content: -Run conflict checks against the loaded project context. Output as a plain-text conflict report using [BLOCKER], [WARNING], and [INFO] labels. Do NOT use markdown tables (no `|---|` format). +Run conflict checks against the loaded project context. The report format, severity semantics, and safety-gate behavior are defined by `references/doc-conflict-engine.md` — read it and apply it here. Operation noun: `import`. ### BLOCKER checks (any one prevents import): @@ -128,45 +128,15 @@ Run conflict checks against the loaded project context. Output as a plain-text c - Plan uses a library not currently in the project tech stack → [INFO] - Plan adds a new phase to the ROADMAP.md structure → [INFO] -Display the full Conflict Detection Report: +Render the full Conflict Detection Report using the format in `references/doc-conflict-engine.md`. -``` -## Conflict Detection Report - -### BLOCKERS ({N}) - -[BLOCKER] {Short title} - Found: {what the imported plan says} - Expected: {what project context requires} - → {Specific action to resolve} - -### WARNINGS ({N}) - -[WARNING] {Short title} - Found: {what was detected} - Impact: {what could go wrong} - → {Suggested action} - -### INFO ({N}) - -[INFO] {Short title} - Note: {relevant information} -``` - -**If any [BLOCKER] exists:** - -Display: -``` -GSD > BLOCKED: {N} blockers must be resolved before import can proceed. -``` - -Exit WITHOUT writing any files. This is the safety gate — no PLAN.md is written when blockers exist. +**If any [BLOCKER] exists:** apply the safety gate from the reference — exit WITHOUT writing any files. No PLAN.md is written when blockers exist. **If only WARNINGS and/or INFO (no blockers):** - **Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available. -Ask via AskUserQuestion using the approve-revise-abort pattern: + +Ask via AskUserQuestion using the approve-revise-abort pattern (see `references/gate-prompts.md`): - question: "Review the warnings above. Proceed with import?" - header: "Approve?" - options: Approve | Abort @@ -267,7 +237,7 @@ Show: plan filename written, phase directory, validation result, next steps. ## Anti-Patterns Do NOT: -- Use markdown tables (`|---|`) in the conflict detection report — use plain-text [BLOCKER]/[WARNING]/[INFO] labels +- Violate the shared conflict-engine contract in `references/doc-conflict-engine.md` (no markdown tables, no new severity labels, no bypass of the BLOCKER gate) - Write PLAN.md files as `PLAN-01.md` or `plan-01.md` — always use `{NN}-{MM}-PLAN.md` - Use `pbr:plan-checker` or `pbr:planner` — use `gsd-plan-checker` and `gsd-planner` - Write `.planning/.active-skill` — this is a PBR pattern with no GSD equivalent