Skip to content

fix: harden planner, conflict path parsing, and post-merge fixer wiring#85

Merged
tzone85 merged 1 commit into
mainfrom
fix/audit-hardening-port
Jun 24, 2026
Merged

fix: harden planner, conflict path parsing, and post-merge fixer wiring#85
tzone85 merged 1 commit into
mainfrom
fix/audit-hardening-port

Conversation

@tzone85

@tzone85 tzone85 commented Jun 24, 2026

Copy link
Copy Markdown
Owner

Summary

Three robustness fixes ported from internal audit findings, each developed test-first (failing test first, then implementation).

Fix Area Files
Reject empty plan / empty-id / empty-title stories before emitting REQ_PLANNED / STORY_CREATED internal/engine/planner.go planner_validation_test.go
ConflictedFiles uses git status --porcelain -z + NUL-delimited parsing (raw paths, not octal-escaped quotepath) internal/git/conflict.go conflict_quotepath_test.go
Wire post-merge integration-build fixer (NewTechLeadFixer + WithMonTechLeadFixer) into runResume internal/cli/resume.go resume_wiring_test.go

Why these matter

  • Planner guard: an empty story array from the LLM previously emitted REQ_PLANNED with zero stories, stranding the requirement forever. A blank {} story got an auto-assigned ID and dispatched an agent against nothing.
  • Conflict path quoting: default --porcelain octal-escapes paths with spaces / non-ASCII (e.g. résumé draft.txt), so the escaped string flowed into SniffBinary/StageFiles and the conflict resolver silently failed.
  • Dead fixer wire: the post-merge build-validation feature and monitor logic existed and were unit-tested, but runResume never attached the fixer, so the stage never ran in production. The new source-scan test guards the wire.

Test plan

  • go build -o /tmp/nxd ./cmd/nxd
  • go vet ./...
  • go test ./... -count=1 — all packages pass
  • golangci-lint run ./... — 0 issues

Three robustness fixes, each TDD'd (failing test first):

- planner: reject empty story lists and stories with empty id/title before
  emitting REQ_PLANNED/STORY_CREATED, so a requirement can't be stranded
  with nothing to dispatch.
- git: ConflictedFiles uses `git status --porcelain -z` and parses
  NUL-delimited records, returning raw paths instead of octal-escaped
  quotepath form. Fixes conflict handling for filenames with spaces or
  non-ASCII characters.
- cli/resume: wire the post-merge integration-build fixer
  (NewTechLeadFixer + WithMonTechLeadFixer). The feature and monitor logic
  existed but the option was never passed, so the stage never ran.

Green gate: go build, go vet, go test ./... (all pass), golangci-lint 0 issues.
@tzone85 tzone85 merged commit b6d4c9d into main Jun 24, 2026
10 checks passed
@tzone85 tzone85 deleted the fix/audit-hardening-port branch June 24, 2026 09:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant