refactor(architect): remove host-mode infrastructure and local-FS file paths #1142
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/agent-hooks!1142
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "code-lead/1133"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #1133
Summary
Retires the host-mode escape hatch that #1131 / #1132 left in place: the
HOST_MODE_TYPESallowlist, thehostModeConfigDirhelper, the local-FSattach-picker / spec-editor fallbacks, and the
git remote get-urlsubprocess that ran on every
/architect/configrequest. After this changethere is no non-containerised code path and no surface that touches
process.cwd()from the architect stack.Removals
webhook-config.ts—HOST_MODE_TYPES/isHostModeTypedeleted;container.enabled: falsenow failsloadWebhookConfigoutright witha clear migration hint.
agent-runner.ts—hostModeConfigDirdeleted;buildAgentEnvnolonger accepts the opt and always wires
CLAUDE_CONFIG_DIRto thein-container bind target. The
host_modebranch inrunAgentTask(dead since architect dispatch moved to
ArchitectAgentDispatch) isgone, and the unused
HostContainerLifecycleadapter + tests aredeleted.
domain/agent/architect.ts—getSelfRepo,resetSelfRepoCache,architectFilesRoot,resolveAllowlistedFile,FILE_ALLOWLIST_DIRS,FILE_ALLOWLIST_EXACTdeleted.http/handlers/architect.ts—node:fs/promisesimport removed; everyfile / spec handler routes through
createForgeAdapterForRepowith thearchitect token.
_architectForgeFactoryis the new module-level seamtests inject a fake
ForgePortthrough.main.ts—selfRepois resolved declaratively fromCLAUDE_HOOKS_SELF_REPOenv var →cfg.repos[0]and passed via therequest context (replaces the
git remote get-urlsubprocess).Tests + docs
handleArchitectFilesList/handleArchitectFileContent/handleArchitectSpecSavenow drivethrough the mock forge registry.
webhook-config/config-agent-types/onboardingfixturesflipped to
container.enabled: true, lifecycle: "hot"for thearchitect type.
docs/architect.mdupdated to reflect the containerised model — allreferences to
container.enabled: falseandcwd: process.cwd()aregone.
Test plan
just qa— 3333 tests pass, typecheck + Biome lint/format clean,sql-layer-check,paraglide-check,i18n-string-check,flow-schema-checkall green./architect/configreturnsself_repoderived fromcfg.repos[0]without forkinggit.the forge adapter; local-FS attach picker no longer enumerates the
host worktree.
Review — APPROVED ✅
CI: green (3333 tests pass, typecheck + Biome + all schema checks clean).
Overview
Complete removal of the host-mode escape hatch introduced in M18-4 / #165 and kept alive through #1131 / #1132. Every agent — including the architect singleton — now dispatches exclusively through a Docker container. The changes are systematic and consistent across all 23 affected files.
What's landed
webhook-config.tsHOST_MODE_TYPES+isHostModeTypedeleted;container.enabled=falsenow hard-fails with migration hintagent-runner.tshostModeConfigDirdeleted;buildAgentEnvalways setsCONTAINER_CLAUDE_CONFIG_DIR; host-mode branch inrunAgentTaskgonedomain/agent/architect.tsgetSelfRepo/resetSelfRepoCache(shelled out togit remote get-url),architectFilesRoot,resolveAllowlistedFile,FILE_ALLOWLIST_DIRS/EXACTall deletedhttp/handlers/architect.tsnode:fs/promisesimport gone; all three file/spec handlers route through_architectForgeFactory;selfRepocomes fromctx.selfRepohost-container-lifecycle.{ts,test.ts}main.tsselfReporesolved declaratively fromCLAUDE_HOOKS_SELF_REPO→cfg.repos[0]; no subprocesssections.tsxtier1NotAnthropicOnHostModenow keys onrole === "host"(previouslycontainer.enabled === false— always-false after this PR)container.enabled: true, lifecycle: "hot"docs/architect.mdCode quality observations (non-blocking)
1.
handleArchitectBreakdownPreviewbypasses the test seam (minor)The three file handlers (
handleArchitectFilesList,handleArchitectFileContent,handleArchitectSpecSave) all route through_architectForgeFactory.create, making them mockable in tests. ButhandleArchitectBreakdownPreviewstill callscreateForgeAdapterForRepodirectly:This leaves the forge read in the breakdown preview untestable via the mock seam. Not a behaviour bug, and the inline-content path is already well-tested. Worth aligning in a follow-up if
handleArchitectBreakdownPreviewever needs forge-path tests.2.
runArchitectTurnpassescontainerMode: falsebut the comment says "container mode" (cosmetic)buildAgentEnvnow always returnsCONTAINER_CLAUDE_CONFIG_DIRregardless ofcontainerMode, sofalseworks. But the comment says "container mode" while the argument isfalse. This is accurate for the shim vars (which are only set whencontainerMode=true, and the architect'sDockerExecClaudeAgentsets them itself), but it's confusing to read. A brief note thatfalseintentionally skips the duplicate shim-var injection would clarify the intent.3.
has_tracking_issue/modified_atfields are now consistently absent (non-regression)The old local-FS path for
handleArchitectFilesListcomputedhas_tracking_issue(regex scan) andmodified_at(fromstat.mtime). These were never present on the remote-repo path. Removing the self-repo branch makes the response shape uniform across all callers. Worth confirming no front-end code depends onhas_tracking_issue— a quick grep ofapps/webfor the field before merging wouldn't hurt.Security check
Path traversal protection in the new
handleArchitectFileContentis sound:normalize("specs/../../etc/passwd.md")→"../../etc/passwd.md", which failsstartsWith("specs/")before the..guard even fires. Belt-and-braces. ✅Summary
Clean refactoring, no dead code remaining, tests updated throughout, docs accurate. The three non-blocking notes above are housekeeping items — none affect correctness or security. Approving.