Skip to content

fix: complete security, concurrency, architecture, and test hardening - #307

Closed
Patel230 wants to merge 4 commits into
mainfrom
fix/complete-hardening
Closed

Patel230 wants to merge 4 commits into
mainfrom
fix/complete-hardening

Conversation

@Patel230

Copy link
Copy Markdown
Contributor

Second hardening pass completing the earlier review. Two commits:

Security

  • validatePathAllowed fails closed without a ToolContext; tests attach a permissive context.
  • Delete the dead, bypassable BoundaryChecker.
  • Wrap MCP/remote tool output as untrusted external content.
  • Bound HTTP clients (stt, media); safewrite uses crypto/rand + O_EXCL; hook URL validation now actually rejects loopback; plugin index reads capped.
  • Git invocations hardened via internal/gitcmd (diff.external, fsmonitor, pager, editor, system config).

Concurrency

  • Cancellable tool-event sends; cmd.Wait race fixed; lastAutoCommitHash mutex; daemon review subprocess tracking.
  • jobs cancel-status snapshot under lock; nil Done guard.
  • Bounded exec timeouts (git context, spec tools, watcher); watcher worker pool.
  • Idempotent Stop for filewatcher/cron; RunWaterfall snapshots handlers under lock.
  • AutoCommit errors logged; AssertWritable returns an error; SessionPreparations honors a context.

Architecture

  • Move IsSensitivePath/ResolvePath to internal/pathsafe; drop the config → tool edge.
  • Consolidate byte-unsafe truncate copies onto rune-safe textutil.
  • Delete dead types.ChatClient and cmd/markdown_renderer.go.

Tests / CI

  • Real bug fix: spec.extractDescription always returned empty (body excludes the header), so every ADDED/MODIFIED requirement failed SHALL/MUST validation. Spec coverage 2.4% → 24.3% + fuzz target + benchmarks.
  • Deterministic ContextDecay clock; un-skipped flaky/provider tests; removed the blanket CI -skip.
  • Golden test restores globals; make update-golden; testutil.Eventually/Never.
  • CI: per-package coverage floors, FuzzParseDeltaSpec, non-mutating fmt-check, real fuzz gate.

Verified locally: go vet, golangci-lint (0 issues), full go test ./..., -race on changed packages, make boundaries, coverage 68.0%.

Security:
- validatePathAllowed now fails closed without a ToolContext; tests attach a
  permissive test context.
- Delete the dead, bypassable BoundaryChecker (no production callers).
- Wrap MCP/remote tool output as untrusted external content.
- Bound HTTP clients in stt/media; safewrite uses crypto/rand + O_EXCL;
  hooks URL validation now actually rejects loopback; plugin index reads are
  capped.

Concurrency:
- jobs: snapshot cancel status under lock; guard nil Done.
- git context, spec tools, watcher: bounded exec timeouts.
- planning prompt: context-aware prompt + ctx timeout.
- watcher: bounded fireChange workers.
- filewatcher/cron: idempotent Stop (no double-close panic).
- event bus RunWaterfall: snapshot handlers under lock.
- AutoCommit errors logged; AssertWritable returns an error; SessionPreparations
  load/wait honor a context.

Architecture:
- Move IsSensitivePath/ResolvePath into internal/pathsafe; drop config->tool.
- Consolidate byte-unsafe truncate copies onto textutil (rune-safe).
- Delete dead types.ChatClient and the dead markdown_renderer.
- Fix a real bug in spec extractDescription: the requirement body excludes
  the header, so descriptions were always empty and every ADDED/MODIFIED
  requirement failed SHALL/MUST validation.
- Add spec tests (parse/validate/apply/DAG/config) lifting coverage from
  2.4% to 24.3%, plus a fuzz target and benchmarks.
- Make ContextDecay clock injectable; rewrite the timing-flaky decay tests
  deterministically.
- Un-skip TestParallelExecution, TestIntegration_FullSessionFlow, and the two
  config-apply tests; remove the blanket CI -skip.
- Golden test restores rootCmd globals; add make update-golden.
- Add testutil.Eventually/Never.
- CI: per-package coverage floors, FuzzParseDeltaSpec target, version fixture
  aligned to 0.0.1.
applyRename built a regexp with regexp.MustCompile from an unescaped
requirement name; a name containing invalid UTF-8 (or a bad pattern) panicked
the whole process. Use regexp.Compile and fall back to leaving the content
unchanged, and ReplaceAllLiteralString so $$ in the new name is not treated as
a group reference. Found by the new FuzzParseDeltaSpec target.
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