Merge pull request #1595 from davesienkowski/feat/1592-plan-drift-precheck

feat(#1592): add plan:pre codebase-drift pre-check before planner runs
This commit is contained in:
Tom Boucher
2026-06-23 10:56:29 -04:00
committed by GitHub
10 changed files with 251 additions and 7 deletions

View File

@@ -645,7 +645,7 @@ const capabilities = {
"role": "feature",
"version": "1.6.0-rc.2",
"title": "Drift detection gates",
"description": "Post-execution drift detection gates that run after each wave completes. Provides two gates at execute:wave:post: a blocking schema drift gate (detects schema files changed without a database push) and a non-blocking codebase drift gate (detects structural additions not reflected in STRUCTURE.md).",
"description": "Drift detection gates for the planning loop. At execute:wave:post: a blocking schema drift gate (detects schema files changed without a database push) and a non-blocking codebase drift gate (detects structural additions not reflected in STRUCTURE.md). At plan:pre: a non-blocking, warn-only codebase drift gate (gated on workflow.plan_drift_precheck) that flags a stale codebase map before planning, so plans are authored against a fresh STRUCTURE.md instead of discovering drift mid-execution.",
"tier": "full",
"requires": [],
"engines": {
@@ -679,6 +679,11 @@ const capabilities = {
"type": "boolean",
"default": true,
"description": "Enable the drift gates at execute:wave:post. When enabled, the schema drift gate blocks verification if schema-relevant files changed during execution but no database push command was executed; the codebase drift gate (non-blocking) warns when structural additions exceed the drift_threshold."
},
"workflow.plan_drift_precheck": {
"type": "boolean",
"default": true,
"description": "Enable the non-blocking codebase drift pre-check at plan:pre, before /gsd:plan-phase spawns the planner. When enabled, a stale STRUCTURE.md (structural additions exceeding drift_threshold) is surfaced up front as a warn-only advisory pointing to /gsd:map-codebase; it never blocks planning and never spawns the mapper agent. Separate from schema_drift_gate so autonomous/CI runs can silence the plan-time advisory while keeping the execute:wave:post gates enabled."
}
},
"steps": [],
@@ -701,6 +706,15 @@ const capabilities = {
"when": "workflow.schema_drift_gate",
"blocking": false,
"onError": "skip"
},
{
"point": "plan:pre",
"check": {
"query": "verify.codebase-drift"
},
"when": "workflow.plan_drift_precheck",
"blocking": false,
"onError": "skip"
}
]
},
@@ -2228,6 +2242,16 @@ const byLoopPoint = {
}
],
"gates": [
{
"capId": "drift",
"point": "plan:pre",
"check": {
"query": "verify.codebase-drift"
},
"when": "workflow.plan_drift_precheck",
"blocking": false,
"onError": "skip"
},
{
"capId": "ui",
"point": "plan:pre",
@@ -2480,6 +2504,7 @@ const configKeys = {
"workflow.drift_threshold": "drift",
"workflow.drift_action": "drift",
"workflow.schema_drift_gate": "drift",
"workflow.plan_drift_precheck": "drift",
"workflow.post_planning_gaps": "gap-analysis",
"graphify.enabled": "graphify",
"intel.enabled": "intel",
@@ -2553,6 +2578,12 @@ const configSchema = {
"default": true,
"description": "Enable the drift gates at execute:wave:post. When enabled, the schema drift gate blocks verification if schema-relevant files changed during execution but no database push command was executed; the codebase drift gate (non-blocking) warns when structural additions exceed the drift_threshold."
},
"workflow.plan_drift_precheck": {
"owner": "drift",
"type": "boolean",
"default": true,
"description": "Enable the non-blocking codebase drift pre-check at plan:pre, before /gsd:plan-phase spawns the planner. When enabled, a stale STRUCTURE.md (structural additions exceeding drift_threshold) is surfaced up front as a warn-only advisory pointing to /gsd:map-codebase; it never blocks planning and never spawns the mapper agent. Separate from schema_drift_gate so autonomous/CI runs can silence the plan-time advisory while keeping the execute:wave:post gates enabled."
},
"workflow.post_planning_gaps": {
"owner": "gap-analysis",
"type": "boolean",

View File

@@ -693,6 +693,21 @@ Also available:
**Exit the plan-phase workflow. Do not continue.**
## 5.65. Codebase Map Freshness Pre-Check (drift plan:pre gate)
If `activeHooks` (from `PLAN_PRE_HOOKS_JSON`, §5.6) has a `kind == "gate"`, `capId == "drift"`,
`check.query == "verify.codebase-drift"` entry (`workflow.plan_drift_precheck` on), run the same check the
execute gate uses; otherwise skip to step 6:
```bash
DRIFT=$(gsd_run verify codebase-drift 2>/dev/null || echo '{"skipped":true}')
```
This gate is **non-blocking** and **never blocks, never spawns** the mapper at plan time. If `skipped` or
`action_required` is false, continue silently to step 6. If `action_required` is true, print `message`
verbatim (it ends with a `/gsd:map-codebase` pointer) and continue — planning proceeds whether or not the
map is refreshed first. (`drift_action: auto-remap` stays at `execute:wave:post`.)
## 6. Check Existing Plans
```bash