Files
msd-core/gsd-core/references/doc-conflict-engine.md
Tom Boucher ec7e49a64c fix(#3576): repair all 43 dead references/ cites and gate the canonical resolvable form (#3596)
* 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>
2026-08-17 15:24:24 -04:00

3.3 KiB

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