Spec reviewed: none; repo-wide code audit Review date: 2026-04-03 Verdict: BLOCK
Repo-wide audit of the server entrypoint, HTTP/API layer, workflow managers, state machines, orchestrators, and dashboard wiring found one critical defect and five major defects that can break real workflows. The highest-risk problems are a path-traversal bug in codedoc feature names, workspace override wiring that is only partially implemented, a broken default no-config startup path for the main spec workflow, and restart/gate flows that strand code-review and codedoc runs.
The binary wiring is broadly present from cmd/specworkflow/main.go, and the codebase has substantial unit coverage, but the integration edges between HTTP, persistence, and the UI are not reliable enough to pass a production review.
| Metric | Value |
|---|---|
| Files reviewed | 21 key runtime/test files |
| Wiring gaps | 4 partial/dead wiring paths |
| Tests passing | 3 packages pass / 1 package fails |
| Severity | Count |
|---|---|
| CRITICAL | 1 |
| MAJOR | 5 |
| MINOR | 1 |
| OBSERVATION | 1 |
| Total | 8 |
No package-level placeholder implementations were found in the runtime path reviewed.
No fully unwired internal packages were found from the binary entrypoint; main.go wires the spec, code-review, and codedoc managers into the HTTP server.
| Component | What's Connected | What's Missing |
|---|---|---|
workspace_dir for codedoc |
UI sends a workspace_dir field |
cdStartRequest has no such field, so the override is silently dropped |
workspace_dir for spec/code review |
APIs accept overrides and store some state under the override | source-doc copying and child runner working directories still use the manager default workspace, mixing two workspaces in one run |
| codedoc gate comments | UI renders comment boxes and API struct has comment |
the browser never sends the comment and the handler never uses it |
| persisted CR/CD gate state | status endpoints can read gate state from disk | gate endpoints require an in-memory orchestrator, so restarted workflows are not actually resumable from the dashboard |
- Lens: Security
- Files:
- Issue:
HandleCDStartonly checks thatfeature_nameis non-empty; it never validates or sanitizes it.NewCodedocOrchestratorthen buildsfeatureDir := filepath.Join(cfg.WorkspaceDir, "codedoc", cfg.FeatureName), andpersistState()writesworkflow-state.jsonthere. A request body withfeature_name: "../../tmp/pwn"can escape the intendedworkspace/codedoc/subtree. - Impact: A caller can create or overwrite files outside the codedoc workspace namespace. Follow-up operations such as reset/rewind then act on that escaped directory, which is both a correctness bug and a filesystem safety bug.
- Fix: Apply the same feature-name validation used by the spec workflow and code-review workflow before constructing paths.
- Lens: Correctness
- Files:
- Issue: The UI exposes a generic workspace override, but the back end wires it inconsistently. Spec workflows resolve/copy source docs from
manager.workspaceDirbefore applying the override, then still create the Claude runner withmanager.workspaceDirinstead of the chosenwsDir. Code review acceptsworkspace_dirfor artefacts, but the runners were already constructed inmainagainst the default workspace. Codedoc is worse: the UI sendsworkspace_dir, butcdStartRequesthas noWorkspaceDirfield at all. - Impact: Overridden runs can read source docs from one workspace, persist state in another, and execute child agents from a third working directory. This breaks isolation and makes resume/debugging unreliable.
- Fix: Thread the effective workspace through request structs, source-doc discovery/copy, runner construction, and disk-state lookup consistently for all three workflows.
- Lens: Correctness
- Files:
- Issue:
maindocuments--configas optional, andDefaultConfig()leavesSkillPathsempty.loadSkillsFromConfig()then returns an emptySkillCache, but prompt generation immediately requiresspec-template.mdand other skill files viaGetSkillContent(). In practice the workflow starts and then fails in discovery withunknown skill file: "spec-template.md". - Impact: A default server boot looks healthy, but the first spec workflow fails at runtime unless an external config has already wired skill directories. That is a broken out-of-box path, not just a test harness issue.
- Fix: Either make
--configtruly required at process startup, or derive sane default skill paths and validate them before accepting workflow requests.
- Lens: Correctness
- Files:
- Issue: Both status endpoints can reconstruct CR/CD state from disk when there is no in-memory orchestrator, so the dashboard continues showing gate panels after restart. But the corresponding gate POST handlers immediately 404 if
manager.getOrchestrator(featureName)returnsnil. The browser only posts to/gate; it never calls the CR/CD/resumeendpoints. - Impact: After a restart, a code review or codedoc run can appear actionable in the UI but be impossible to advance. That strands workflows at scope/fixes/draft/final gates until someone uses ad hoc API calls or restarts the run.
- Fix: Mirror the spec workflow’s auto-resume-from-disk behavior in CR/CD gate handlers, and add explicit frontend resume handling for CR/CD workflows.
- Lens: Error Handling
- Files:
- Issue:
HandleCDStartinserts the orchestrator into memory, launchesRunWorkflow()in a goroutine, and returns202 Acceptedimmediately.NewCodedocOrchestratordoes not persist the initial state, so there is no durableworkflow-state.jsonuntil the background goroutine gets far enough to transition and persist. The current test suite already exposes this timing hole. - Impact: A process crash or fast follow-up request can observe a “started” workflow with no recoverable state on disk. This also makes cleanup/race behavior flaky, as shown by the failing API test run.
- Fix: Persist the initial codedoc state synchronously before returning success, or block until the first durable transition has completed.
[MAJ-005] CR/CD start handlers do not protect persisted workflows from duplicate starts after restart
- Lens: Correctness
- Files:
- Issue: Code-review and codedoc starts only reject duplicate feature names that are still present in the in-memory manager map. They do not check on-disk persisted state the way spec workflows do. After a server restart, starting the same feature again can recreate the orchestrator and overwrite or fork existing artefacts.
- Impact: Operators can accidentally clobber a paused review/documentation run instead of resuming it, leading to lost audit history and ambiguous workspace contents.
- Fix: Add the same persisted-state conflict detection/resume behavior used by
HandleStartWorkflow.
- Lens: Overcomplexity
- Files:
- Issue: The dashboard renders three codedoc comment textareas, and the request struct includes
comment, butsubmitCDGate()only sends{action}and the handler never propagatesreq.Commentto the orchestrator or persistence. - Impact: Reviewers are shown a comment box that has no effect. That is dead wiring and misleading UX.
- Fix: Either send/persist the comment end-to-end or remove the unused UI/control surface.
- Lens: Correctness
- Files:
- Suggestion: The server does successfully wire the three workflow families, WebSocket streaming, logs, metrics, and spec endpoints from a single binary. The main problems are integration edges and restart semantics, not missing top-level registration.
Command run:
go test ./internal/api/... ./internal/codereview/... ./internal/codedoc/... ./internal/specworkflow/...Summary:
| Status | Count |
|---|---|
| PASS | 3 packages |
| FAIL | 1 package |
| SKIP | 0 observed |
| Test | File | Failure Reason |
|---|---|---|
TestCodedocHandlers_Gate_ScopeConfirm |
codedoc_handlers_test.go |
go test fails in internal/api with codedoc background-workflow cleanup races and missing early persistence (TempDir RemoveAll cleanup: ... directory not empty) |
Package results:
FAIL github.com/foundry-zero/adversarial-spec-system/internal/apiok github.com/foundry-zero/adversarial-spec-system/internal/codereviewok github.com/foundry-zero/adversarial-spec-system/internal/codedocok github.com/foundry-zero/adversarial-spec-system/internal/specworkflow
The repository is blocked by correctness issues at workflow boundaries, not by isolated implementation mistakes. The codedoc start path has a real filesystem-safety bug, the restart/gate paths for CR/CD are not actually operable from the dashboard, and workspace overrides are not wired consistently enough to trust isolation or persistence.
The system also advertises execution modes that do not work as described: default no-config startup fails at runtime for spec workflows, and codedoc comments/workspace overrides are exposed in the UI without an end-to-end implementation behind them. These issues can cause workflows to fail, become stranded, or write artefacts in the wrong place.
- Fix
CRIT-001by validating/sanitizing codedocfeature_namebefore any path construction. - Fix
MAJ-001by threading the effective workspace through source-doc discovery, disk lookups, and runner creation for spec, code-review, and codedoc flows. - Fix
MAJ-002by making skill-path configuration mandatory or providing working defaults. - Fix
MAJ-003by auto-resuming CR/CD gate workflows from persisted state and wiring the frontend to use those paths. - Fix
MAJ-004by persisting codedoc state synchronously before returning202 Accepted. - Fix
MAJ-005by checking persisted CR/CD state before allowing a new start for the same feature. - Fix
MIN-001by either removing codedoc gate comments or actually persisting them.
After fixing, re-run: /grill-code /Users/nixlim/Sync/PROJECTS/foundry_zero/adversarial_spec_system