* test(#3576): gate shipped reference citations on the canonical resolvable form Failing-first gate for #3576: a backticked bare references/<name>.md cite resolves from no install location (agents, workflows, and references all install where a bare relative references/ path is dead). The gate walks the runtime-loaded trees the issue prescribes, strips @~/ include tokens PER-TOKEN (a line-skip guard would miss a bare cite sharing a line with an include — the issue-named trap), pins the genuinely relative ../ href and canonical forms as non-offenders, and checks canonical cite targets exist. 43 offenders today across 19 files. * fix(#3576): repair all 43 dead references/ cites to the canonical resolvable form Every backticked bare references/<name>.md cite across the 19 shipped files rewritten to gsd-core/references/<name>.md — the form every required_reading block and @~/ include already uses, and the only form that resolves from any install location. All 20 cited targets verified to exist; the one genuinely relative href (plan-phase.md's ../references/mvp-concepts.md) is untouched (the repair is backtick-anchored). Growth acks: new fragment for the three first-time paths, #3206-pattern appends to the five fragments already naming the other grown files (two ack sources may never name the same path). execute-phase.md lands at 93,391/93,400 and gsd-executor.md at 49,150/49,152 — exactly the issue's projections; every repair fits. * fix(#3576): drop stale default.md growth ack (nested modes file is hash-attributed, not growth-ratcheted) Review finding: the emitted-attribution ratchet covers only top-level workflows/ + agents/ files; discuss-phase/modes/default.md's delta is source-attributed, so acknowledging its growth is a stale entry the differential lane fails on. * chore(#3576): add changeset fragment * chore(#3576): backfill changeset pr number --------- Co-authored-by: sim <sim@local>
92 lines
3.3 KiB
Markdown
92 lines
3.3 KiB
Markdown
# 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 `gsd-core/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
|