4.7 KiB
4.7 KiB
id, title, status, wave, plan, spec, depends_on
| id | title | status | wave | plan | spec | depends_on | ||||
|---|---|---|---|---|---|---|---|---|---|---|
| 06-review-blockers | Close admission review blockers | done | 4 | plan.md | ../../specs/platform/requirements/git-subprocess-admission.md |
|
Task 06: Close Admission Review Blockers
Root Cause
The first migration audited the old subproc.Git() accessor but not every raw
exec.Command*(..., "git", ...) invocation. The scheduler also treated a
cancel-versus-release interleaving as a successful grant, and fresh status used
the background-only polling helper for its final porcelain command.
Acceptance
- Every production Git command starts through an explicitly classified shared helper; a repository guard rejects raw Git execution outside tests and the approved command-construction seam.
- A waiter canceled at the grant boundary returns
ErrAdmissionCanceled(and the context error), starts no command, and leaves the round-robin cursor and slot accounting correct. - Every subprocess in a fresh interactive status observation is admitted as
GitInteractive; polling commands remainGitBackgroundand retainGIT_OPTIONAL_LOCKS=0.
Verification
cd apps/backend && go test ./internal/common/subproc -run 'Test(ClassAdmission|GitAdmission|Throttle|RawGit|FreshStatus)' -count=1
cd apps/backend && go test -race ./internal/common/subproc -run 'Test(ClassAdmission|GitAdmission|Throttle|RawGit|FreshStatus)' -count=1
cd apps/backend && go test ./internal/agentctl/server/process -run 'Test(.*FreshStatus|.*Admission|.*Poll)' -count=1
cd apps/backend && go test -race ./internal/agentctl/server/process -run 'Test(.*FreshStatus|.*Admission|.*Poll)' -count=1
cd apps/backend && go test ./internal/agent/runtime/lifecycle ./internal/backendapp ./internal/agentctl/server/api -run 'Test.*(Git|Admission|Materialize|Worktree)' -count=1
cd apps/backend && rg -n 'exec\.(Command|CommandContext)\([^\n]*"git"|exec\.LookPath\("git"\)|\b(unix|syscall)\.Exec\(' . --glob '*.go' --glob '!*_test.go'
Files
apps/backend/internal/common/subproc/admission.goapps/backend/internal/common/subproc/admission_test.goapps/backend/internal/common/subproc/raw_git_audit_test.goapps/backend/internal/agentctl/server/process/workspace_git_cmd.goapps/backend/internal/agentctl/server/process/workspace_git_status.goapps/backend/cmd/agentctl/github_cli_shim.goapps/backend/cmd/mock-agent/scenarios.go- direct Git call sites identified by the repository audit
- this task's sibling tests and the shared command helpers
Results
- Migrated remaining production Git construction paths (task services, local repository initialization, worktree helpers, agentctl materialization, and lifecycle helpers) to the shared command seam and classified runners.
- Added a repository AST guard that rejects raw Git command construction,
executable lookup, and direct
unix/syscall.Execoutside thesubprocseam. - Made cancellation win both queue-head dispatch and the post-grant select boundary; canceled grants release their slot before returning the context error.
- Split lock suppression from scheduling class so fresh status remains
GitInteractivewhile background polling remainsGitBackground. - Added deterministic cancellation/release and fresh-status class-attribution regression tests.
Validation:
go test ./internal/common/subproc ./internal/task/gitinit ./internal/task/service -run 'TestProductionGitCommandsUseTheAdmissionSeam|TestClassAdmissionCancellationWinsReleaseBoundary|TestClassAdmissionCancellationDoesNotAdvanceQueue|TestPerformFreshBranch|TestInitializeLocalRepository' -count=1 # pass
go test -race ./internal/common/subproc -count=1 # 32 tests pass
go test ./internal/agentctl/server/process ./internal/common/subproc ./internal/task/service ./internal/task/gitinit ./internal/backendapp ./internal/agent/runtime/lifecycle ./internal/agentctl/server/api ./internal/worktree ./internal/repoclone ./internal/office/configloader ./internal/office/skills ./internal/office/testharness ./internal/orchestrator/executor -count=1 # pass
go test ./cmd/agentctl ./cmd/mock-agent -count=1 # 259 tests pass
go test -run '^$' ./... # compile pass
make -C apps/backend build # pass
The repository-wide go test -tags fts5 ./... reached 10,254 passing tests,
29 skips, and one pre-existing failure in
TestTaskEventBroadcaster_NoDuplicateSubscriptions (62 subscriptions versus
61). The isolated websocket test reproduces the same failure outside this
change's scope (go test -tags fts5 ./internal/gateway/websocket -run TestTaskEventBroadcaster_NoDuplicateSubscriptions -count=1).