fix(ultraplan-local): Bug 3 — wire frontmatter consistency check into /ultracontinue Phase 1.5

Step 8 of v3.4.1 plan.

commands/ultracontinue-local.md:
- New Phase 1.5 between Phase 1 and Phase 2 — runs the
  next-session-prompt-validator in --consistency mode when both candidates
  exist (plugin-root + project-dir). Refuses on producer mismatch with
  fresh candidates, downgrades stale candidate to a warning, downgrades
  >24h wall-clock drift to a soft warning.
- Anti-substitution rule applies — paths emitted as concrete tokens, not
  template placeholders.

lib/validators/next-session-prompt-validator.mjs:
- Sharpen NEXT_SESSION_PROMPT_PRODUCER_MISMATCH error message to include
  the literal "produced_by" field name so consumers (and operators) can
  trace the disagreement back to the YAML key.

tests/commands/ultracontinue.test.mjs:
- Test (Bug 3 prose) — Phase 1.5 header present, references validator,
  appears between Phase 1 and Phase 2 in document order.
- Test (Bug 3 e) — tmp project dir with state file + two prompt files
  with mismatched producers, both fresh relative to state.updated_at;
  CLI consistency mode exits non-zero, JSON stdout surfaces
  NEXT_SESSION_PROMPT_PRODUCER_MISMATCH with both paths and the
  "produced_by" token in the message.

Tests 346 -> 348 (+2).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-05-04 17:39:42 +02:00
commit 37108ae899
3 changed files with 125 additions and 1 deletions

View file

@ -122,7 +122,7 @@ export function validateNextSessionPromptConsistency(a, b, opts = {}) {
if (producerMismatch && bothFresh) {
errors.push(issue(
'NEXT_SESSION_PROMPT_PRODUCER_MISMATCH',
`Producers disagree: "${aFm.produced_by}" (${a.path}) vs "${bFm.produced_by}" (${b.path})`,
`Frontmatter "produced_by" disagrees: "${aFm.produced_by}" (${a.path}) vs "${bFm.produced_by}" (${b.path})`,
'One file is stale or producers wrote conflicting frontmatter. Resolve manually.',
));
} else if (producerMismatch && (aStale || bStale)) {