refactor(agents): rename role 'host' to 'planner' and retire is_host_mode (AR-4) #1205
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!1205
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "code-lead/1199"
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?
Summary
Closes #1199 (AR-4). After #1198 made the architect chat path mandatory
through a
docker execrelay, nothing live needed thehost_modeflagor the
role: "host"keyword. This PR retires both.AgentRoleswaps"host"for"planner". The zod schema admits"planner"and the config loader rejectsrole: "host"with anexplicit migration error (
role: "host" is no longer supported — use "planner").ResolvedAgent.host_modeis removed from the public shape;mergeAgentno longer derives it. The webhook-dispatch invisibilityrail (
resolveAgentByUser/resolveAgentByType/resolveAgentByRole) now keys ondispatchable: false, which is theactual semantic and lets future non-architect singletons opt into the
same rail.
config.type === "architect"—HostAwareAgentDispatchis renamed toArchitectAwareAgentDispatch.agents-storerenames the per-rowis_host_modeparameter toskip_lifecycle_defaults; the boot-time seeders take alifecycleInertTypesset instead ofhostModeTypes.0018_rename_role_host_to_plannerrebuilds theagent_type.roleCHECK clause and rewrites any pre-existing'host'rows to
'planner'. The bootstrap snapshot is updated in lockstep.host_modeflag; consumersfilter on
dispatchableonly.AGENT_ROLES_LISTinrouting-section.tsxdrops"host"and adds"planner"/"code-lead".getArchitectWorker, the architect-specificminimalMountbranch, andthe
ArchitectAwareAgentDispatchindirection are still in place —#1200 retires them in the follow-up cleanup.
Test plan
just qa— typecheck, lint, server tests (3362 pass), web tests(1191 pass)
webhook-config.test.tscase:role: "host"is rejectedwith the migration error
role: "planner"(covered by existing fixturesrewritten to the new keyword)
host_modebranch was a no-op for architect, so deleting itdoesn't move behaviour
🤖 Generated with Claude Code
Code Review — AR-4: rename
host→planner, retireis_host_modeCI: ✅ green | Mergeable: ✅
Overview
Clean, comprehensive refactor with no net behaviour change. Every occurrence of
host_mode,is_host_mode,hostModeTypes,HostAwareAgentDispatch,role: "host", and the derived boolean is updated in a single coherent sweep. The PR scope is correctly bounded —getArchitectWorkerand theminimalMountbind-mount branch are left for #1200 as stated.What was changed (by concern)
AgentRoletype + zod schema"host"→"planner";"host"input now throws a migration-hint error before the generic enum rejectResolvedAgent.host_modemergeAgentno longer derives itrole === "host"guard generalised to!type.dispatchable— any future non-dispatchable singleton gets the same protection for freeHostAwareAgentDispatch→ArchitectAwareAgentDispatch; routing conditionconfig.host_mode→config.type === "architect"CreateAgentInput.is_host_mode→skip_lifecycle_defaults; seeder paramhostModeTypes→lifecycleInertTypes.sql=SELECT 1;consistent with existing conventionSanitisedType.host_modedropped; consumers filter ondispatchableonlyAGENT_ROLES_LISTdrops"host", adds"planner"and the previously-missing"code-lead"What's good
renameRoleHostToPlannerinspectssqlite_masterDDL to detect whether the table already uses'planner'before touching anything, so re-runs on an already-migrated DB are no-ops.role === "host"guard inparseTypeRoutingreturns a descriptive migration message rather than a cryptic enum-validation failure. Good UX for upgrade paths.!type.dispatchableis better than the old role-keyed check — it means the next non-dispatchable singleton type won't need its own special-case.COLLAPSE_SPECSupdated in lockstep. Theagent_typebody in the 0010 spec is updated to'planner'. On live DBs 0010 is already applied so'builtin'is gone and the idempotency guard skips it; on fresh installs the 0000 snapshot also has'planner'so 0018 is a no-op after bootstrap. Both paths are clean.routing-section.tsx.AGENT_ROLES_LISTwas missing"code-lead"and"planner"entirely — the PR corrects that silently, which is fine to bundle in a renaming PR.Observations (no blockers)
tasks.ts::findDispatchable()usestype !== "architect"rather than!config.dispatchable.The webhook resolvers were generalised to
!type.dispatchable, but the tasks-endpoint helper was not. This is internally consistent with the PR's stated approach (dispatch adapter = type-name-keyed; webhook rail = dispatchable-flag-keyed) and it matches the existingArchitectAwareAgentDispatchrouting. But it means a hypothetical second non-dispatchable singleton would be visible in the tasks endpoint while being invisible in the webhook path. Not a bug today; worth noting for #1200 or whenever a second planner-class type appears.agents-store.tsparameter rename is accurate but the JSDoc onskip_lifecycle_defaultsshould clarify the connection torole === "planner", since the field name no longer encodes the role. The current JSDoc says "leave lifecycle null on host-mode types" — that wording is stale. Minor documentation debt.Test coverage
webhook-config.test.tscase rejectsrole: "host"with the migration error ✅config-agent-types.test.tsnow assertsavailable_rolesincludes"planner"and excludes"host"✅agent-dispatch-port.test.tsverifies the routing condition switches fromhost_modetotype === "architect"✅agents-store.test.tscovers theskip_lifecycle_defaults: truepath ✅Verdict
APPROVED. This is a thorough, low-risk rename refactor. The two observations above are non-blocking — the
tasks.tsinconsistency is intentional for this PR's scope, and the JSDoc debt is trivial. Ready to merge.