Skip to content

Commit 43e7eef

Browse files
docs(directors): refresh stale skill-bake prose left by worker skill mounting (#1000)
Worker mounts from #982 made six prose sites stale: workers now mount skill_search + use_skill scoped to optionalSkills instead of baking bodies. Correct the count (20 packages), drop the bake parenthetical, and reattach the orphaned identity JSDoc. No behavior change.
1 parent 5070087 commit 43e7eef

5 files changed

Lines changed: 14 additions & 13 deletions

File tree

docs/ARCHITECTURE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ The primary session identity is **Skywalker** (`buildChatRole` → `createSkywal
329329

330330
**Provider-conditional residuals.** Per-family additions layer on top of the shared block via the same `ModelFamilyPolicy` mechanism the directors use (`src/subagent/provider-family.ts`, `src/agent/model-family-policy.ts`) — additive lines, never prompt forks. **Grok** leaves get `buildGrokLeafAntiThrashNote` (gated by `shouldApplyGrokAntiThrash` / `applyGrokFinishBias`, withheld from orchestrators): a compact finish-bias reinforcement plus a one-line reminder to route file/web work through the dedicated tools rather than `run_shell`, motivated by observed tool-routing thrash on the same harness. **Kimi** intentionally has no residual yet — `detectModelFamily` already resolves the family so callers can branch on it, but the prompt seam is left unfilled pending eval characterization of Kimi's behavior, mirroring the provisional (permissive-default) policy in `model-family-policy.ts`.
331331

332-
`buildChatSystemPrompt` (TUI chat) assembles: base → core tool list → name-only skills listing → live `<env>` block → appended extensions. `buildSubAgentSystemPrompt` assembles the worker prompt without a skills listing (workers bake optional skill bodies; they do not mount `use_skill` / `skill_search`). Built-in catalog tools (including `skill_search`) are advertised on the primary wire and callable directly; MCP integrations are discovered via `tool_search` rather than being enumerated. Skills follow the same lazy principle: each discovered skill contributes only its name to the primary prompt. The model calls `skill_search` for descriptions when choosing, then `use_skill` to load a body. The operator can also invoke the same skill as `/<skill-name>` (see Skills below). Skills are discovered (and deduped by name, first-wins) from enabled plugin dirs, then `.agents`/`.claude`/`.codex/skills`, in that precedence. Corbits Code ships a bundled catalog via the first-party `corbits-skills` plugin (origin `repo`); project-local skills of the same name are shadowed by an enabled plugin skill.
332+
`buildChatSystemPrompt` (TUI chat) assembles: base → core tool list → name-only skills listing → live `<env>` block → appended extensions. `buildSubAgentSystemPrompt` assembles the worker prompt without a skills listing. Built-in catalog tools (including `skill_search`) are advertised on the primary wire and callable directly; MCP integrations are discovered via `tool_search` rather than being enumerated. Skills follow the same lazy principle: each discovered skill contributes only its name to the primary prompt. The model calls `skill_search` for descriptions when choosing, then `use_skill` to load a body. The operator can also invoke the same skill as `/<skill-name>` (see Skills below). Skills are discovered (and deduped by name, first-wins) from enabled plugin dirs, then `.agents`/`.claude`/`.codex/skills`, in that precedence. Corbits Code ships a bundled catalog via the first-party `corbits-skills` plugin (origin `repo`); project-local skills of the same name are shadowed by an enabled plugin skill.
333333

334334
**Overrides.** `loadSystemPromptOverrides` (`src/agent/context-extensions.ts`) resolves a project `SYSTEM.md` (repo root, then `.corbits/`) that **replaces** the static base block, and an `APPEND_SYSTEM.md` that is **appended** as an extension. These compose with `config.systemPromptExtensions` (profile config) and the auto-discovered `AGENTS.md`, all of which attach as appended sections after the base.
335335

docs/IMPLEMENTATION.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ docs/
157157

158158
### Closed director fleet
159159

160-
Sixteen packages under `src/agent/directors/<id>/` register in `DIRECTOR_REGISTRY` (`registry.ts`). Wire path:
160+
Twenty packages under `src/agent/directors/<id>/` register in `DIRECTOR_REGISTRY` (`registry.ts`). Wire path:
161161

162162
1. `spawn_agent(agent=…)` / `spawn_agent(intent=…)``resolveDirector` in `agent-fleet.ts` before tools and system prompt are built. Bare `spawn_agent` (neither field) and `intent=general` fail closed. After director resolution, `createSpawnAgentTool` fail-closes implement/review (and their default directors) without non-empty `success_criteria`.
163163
2. `packageToProfile` maps envelope (`tools.allow`/`deny`) to `AgentProfile.capabilities` and `spawn.maySpawn``orchestrator`. System prompts are prefixed with a stable identity block (`formatDirectorSystemPrompt`: agent id, model role, optional skills).
@@ -168,7 +168,7 @@ Sixteen packages under `src/agent/directors/<id>/` register in `DIRECTOR_REGISTR
168168
**Codex tool proxies.** When the active provider is Codex (`isCodexProviderName`), `createAgentToolset` and `runSubAgent` mount `apply_patch`, `shell`, and `update_plan` stringTools from `createCodexToolProxies`, all forwarding through the same posix `ToolRunner` seam (`runTool`) so permission plugins still apply. `apply_patch` parses the Codex envelope and forwards each op (`write_file` / `delete_file` / `read_file`). `shell` — the native Codex name is `shell`, not `exec_command` — normalizes Codex's `command` (string or `["bash","-lc",script]`-style argv array), `workdir`, and `timeout_ms` onto `run_shell`'s `{command, cwd?, timeout?}` and is gated by `allowShellFromCapabilities` (mirrors `allowDeleteFromCapabilities` against `run_shell`). `update_plan` maps Codex's `plan: [{step, status}]` onto `manage_tasks(action: "create")`; `pending`/`in_progress`/`completed` map to `todo`/`doing`/`done` — `manage_tasks`'s `cancelled` status has no Codex equivalent and is never produced by this proxy. Primary strips `apply_patch` after mount (Corbits DIY stays on `write_file` / `edit_file` / `delete_file`); `shell` and `update_plan` stay on primary (same classification as `run_shell` / `manage_tasks`). Build and docs worker allowlists (`BUILD_TOOLS` / `DOCS_TOOLS`) include `apply_patch` so Codex workers keep the proxy after the capability filter. `CORE_TOOL_NAMES` does not list it.
169169

170170
6. There is no static write-path declaration on packages or profiles (CL-6952 removed it — no shipped director ever set one). Instead, `agent-fleet.ts` tracks each running dispatch by cwd; a new mutating dispatch that lands on the same cwd as a live mutating peer (`pending_init`/`running`, and not a declared read-only `modelRole` of `explore`/`plan`/`review`/`test`) records at most one `concurrent-lane-overlap` entry per cwd wave in `intervention-log.ts` (class `conflict`). The wave flag clears when no live mutating writer remains for that cwd. Terminal-but-unsettled lanes (for example cancelled with `finishedAt` set while the run promise has not reached `finally`) are pruned from the map and do not warn. This is advisory only — it never blocks the spawn, since cwd overlap does not prove the two lanes touch the same files.
171-
7. Spawn effort: pin > package `modelRole` default (`defaultEffortForDirector`; intern=low; plan/review/orchestrator=high; implement/explore/docs/test=medium) > orchestrator/worker binary > parent inheritance. Optional skills are listed in the identity header for awareness; workers do not mount `use_skill` (guidance is baked into package system prompts). Primary mounts `use_skill` for its own skill list.
171+
7. Spawn effort: pin > package `modelRole` default (`defaultEffortForDirector`; intern=low; plan/review/orchestrator=high; implement/explore/docs/test=medium) > orchestrator/worker binary > parent inheritance. Optional skills are listed in the identity header for awareness; workers mount `skill_search` + `use_skill` scoped to the dispatch's `optionalSkills` and load bodies on demand (grok/kimi leaves omit `skill_search` and load brief-named skills straight through `use_skill`). Primary mounts `use_skill` for its own skill list.
172172

173173
Intent defaults: `intent=implement` → director `builder`; `explore``explorer`; `plan``counsel`; `review``critic`; general → error. Spawn: skywalker full fleet; all other directors, including greybeard, mount no fleet tools. Live `<env>` injects cwd, platform, arch, runtime, date, and git status on every chat and worker prompt.
174174

src/agent/directors/draper/package.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import { REVIEW_TOOLS } from "../tool-sets.js";
1212
*
1313
* Deviations from the original (deliberate Corbits translations):
1414
* 1. Brand references: the original loads the `brand-identity` skill and
15-
* agents-repo `references/*.md` paths. Workers do not mount use_skill,
15+
* agents-repo `references/*.md` paths. Skill bodies load on demand
16+
* scoped to the dispatch's optionalSkills, and Draper declares none,
1617
* so Draper loads only in-repo references relevant to the active
1718
* lenses (DESIGN.md, design tokens, brand docs already in the tree)
1819
* plus the mounted read/search/web tools.

src/agent/directors/identity.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,23 @@ import type { ModelRole } from "./types.js";
33
import type { ReasoningEffort } from "../../provider/reasoning-effort.js";
44

55
/**
6-
* Prefix every director system prompt with a stable identity block so the model
7-
* always sees agent id, model role, and optional skills — no ambiguity about which
8-
* package it is or how the parent should re-spawn it.
6+
* Worker skill-use rule: skills mount on every worker (scoped to the
7+
* dispatch's optionalSkills), so the worker searches only when the brief
8+
* names a skill or the task leaves its lane.
99
*
1010
* Skill bodies are never baked here. Workers (non-orchestrator) list skill
1111
* names only and load bodies on demand with skill_search + use_skill, scoped
1212
* to the dispatch's optionalSkills. Primary orchestrator (skywalker):
1313
* use_skill is mounted — list skill names only.
1414
*/
15-
/**
16-
* Worker skill-use rule: skills mount on every worker (scoped to the
17-
* dispatch's optionalSkills), so the worker searches only when the brief
18-
* names a skill or the task leaves its lane.
19-
*/
2015
export const WORKER_SKILL_SCOPING =
2116
"Skills are available; search only when the brief names a skill or the task is outside your lane. For a small, bounded edit, do not search skills.";
2217

18+
/**
19+
* Prefix every director system prompt with a stable identity block so the model
20+
* always sees agent id, model role, and optional skills — no ambiguity about which
21+
* package it is or how the parent should re-spawn it.
22+
*/
2323
export function formatDirectorSystemPrompt(pkg: DirectorPackage): string {
2424
const names = pkg.optionalSkills;
2525
const isPrimaryOrchestrator = pkg.tier === "orchestrator";

src/agent/directors/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export interface DirectorPackage {
102102
readonly description: string;
103103
/** Opinionated core prompt (prompt-first). */
104104
readonly systemPrompt: string;
105-
/** Optional skill names (ordered). Workers bake matching first-party bodies into the prompt; the primary orchestrator keeps them use_skill-loadable. */
105+
/** Optional skill names (ordered). Workers load matching bodies on demand with skill_search + use_skill, scoped to the dispatch's optionalSkills; the primary orchestrator keeps them use_skill-loadable. */
106106
readonly optionalSkills?: readonly string[];
107107
readonly tools?: ToolEnvelope;
108108
readonly spawn: SpawnRights;

0 commit comments

Comments
 (0)