Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,32 @@ matching `## [X.Y.Z]` section (plus install instructions). Do not maintain
parallel copies under `docs/` or `scripts/notes/`. At cut time: rename
`## [Unreleased]` to `## [X.Y.Z] - YYYY-MM-DD`, then run the release script.

## [Unreleased]

Skywalker identity stays on the primary; workers get a job-shaped director prompt plus a thin overlay. Product write tools are mounted on Skywalker; slash actions stay optional.

### Directors

- **Skywalker can write files and chains specialists from a short roster.**
The primary prompt is identity plus a name/description list of the closed
fleet. Product write tools are mounted. Skywalker may do small work itself
or chain `task(agent=…)` in sequence or parallel. Slash actions stay
optional. The operator does not name a director.
- **Director prompts are job-shaped; identity is first.** Worker assembly
leads with the director body, then a thin harness, tools, env, and one
report contract. The Skywalker constitution is not prepended. `*Director`
suffixes, baked skill fiction, interview-the-operator, and the Web Crypto
eval scar are gone. Intern's model role is `intern` (effort low).
- **Workers mount use_skill and tool_search.** Skill bodies load on demand.
MCP tools stay dispatchable and are discovered via tool_search instead of
being stripped by the posix envelope.

### Plugins

- **Slash recipes are optional explicit actions.** Draper and emil are not
skills or slashes — Skywalker still dispatches them from chat. Ordinary
chat does not need a slash.

## [0.2.99] - 2026-08-21

Skywalker is the primary orchestrator over a closed director fleet: product write tools stay off the primary, and you cannot spawn Skywalker as a task leaf. Workers are not done until they return the four-heading report. First-party action skills ship as slashes; eval runners require an explicit provider/model pair; the style skill no longer refuses non-git folders.
Expand Down
16 changes: 8 additions & 8 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ Every shipped specialist is a **director package** — a prompt-first `DirectorP

| Director | Owns | Does not own |
|---|---|---|
| skywalker | Orchestrate only — classify, dispatch, track fleet, synthesize | Product tree edits; being the implementer/reviewer by default |
| skywalker | Do the work; chain specialists when isolation, parallel map, review, or a named lane pays | Catch-all worker; `task(agent="skywalker")` |

**Engineering directors**

Expand Down Expand Up @@ -299,16 +299,16 @@ Data-only agent plugins (`src/plugins/data-only-agent.ts`) synthesize `agentPlug

### System Prompt (`src/agent/prompts.ts`)

The primary session identity is **Skywalker** (`buildChatRole` → `createSkywalkerSystemPrompt`). Product name remains Corbits Code; when asked its name, the primary answers Skywalker. Role: orchestrate-only — classify, dispatch closed directors via `task`, track the fleet, synthesize. Product mutation tools (`write_file` / `edit_file` / `delete_file`) are **not mounted** on the primary session (structural never-implement for path tools). Residual mutation surfaces: `run_shell` remains (gated; shell file-writes denied by auto-shell policy), MCP tools added after the strip are not re-filtered by `PRIMARY_DENIED_PRODUCT_TOOLS`, and leaf `writePaths` only apply to path-keyed product tools. A frontier model already knows how to code; the static prompt carries harness-specific facts and the closed-fleet orchestration policy. The base is three individually-exported sections:
The primary session identity is **Skywalker** (`buildChatRole` → `createSkywalkerSystemPrompt`). Product name remains Corbits Code; when asked its name, the primary answers Skywalker. Role: do the work, and chain closed directors via `task` when isolation, parallel map, fresh-eyes review, or a named lane pays. Product mutation tools (`write_file` / `edit_file` / `delete_file`) are mounted on the primary session. Shell file-writes stay denied by auto-shell policy. Optional leaf `writePaths` still apply to path-keyed product tools when a profile sets them. A frontier model already knows how to code; the static prompt is a short roster plus harness facts. The base is three individually-exported sections:

- `buildChatRole` — Skywalker primary identity (orchestrate; do not implement product work by default).
- `buildHarnessFacts` — the non-derivable rules: shell file-writes are blocked, primary product mutations are unmounted (spawn implement/docs directors), dependency installs and off-limits paths need approval, images are native multimodal input, only core tools are resident (load the rest via `tool_search`; use `search_agents` before dispatching specialists), workflows run only from slash-command steps, and session memory lives at `.corbits/MEMORY.md`.
- `buildGuidelines` — be concise, prefer `task` for product work, answer questions and diagnose visual/product feedback before editing, work autonomously for explicit coding tasks, use `lsp` for symbol work, and verify changes when practical.
- `buildPromptDisciplineBlock` — a shared, prohibition-form section appended exactly once to every built prompt (chat and sub-agent, every provider family). Primary vs leaf wording differs for product writes: leaves are told to use `read_file`/`edit_file`/`write_file`; Skywalker is told product writes are unmounted and durable edits go through directors. Shared rules: never `cat`/`sed`/heredoc/`echo` for file work, no setting or exporting environment variables (recurring needs belong in project settings), `web_fetch`/`web_search` instead of `curl`/`wget`/hand-rolled queries, one operation per `run_shell` call, turn semantics (a tool-less reply is the final answer, no repeat searches, stop and change approach after three failed attempts, batch independent reads in parallel), and TTY output rules (short bold headers, one-line bullets, backticks for paths/commands, no wide tables).
- `buildChatRole` — Skywalker primary identity (may edit; may chain the closed fleet).
- `buildHarnessFacts` — the non-derivable rules: shell file-writes are blocked, product writes go through `write_file`/`edit_file`/`delete_file`, dependency installs and off-limits paths need approval, images are native multimodal input, only core tools are resident (load the rest via `tool_search`; use `search_agents` before dispatching specialists), workflows run only from slash-command steps, and session memory lives at `.corbits/MEMORY.md`.
- `buildGuidelines` — be concise, prefer doing small work yourself and chain `task(agent=…)` when it pays, answer questions and diagnose visual/product feedback before editing, work autonomously for explicit coding tasks, use `lsp` for symbol work, and verify changes when practical.
- `buildPromptDisciplineBlock` — prohibition-form section on the **primary** chat prompt only. File work uses `read_file`/`edit_file`/`write_file`; never `cat`/`sed`/heredoc/`echo`. Shared rules: no setting or exporting environment variables, `web_fetch`/`web_search` instead of `curl`/`wget`, one operation per `run_shell`, turn semantics, TTY output rules.

**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`.

`buildChatSystemPrompt` (TUI chat) and `buildSubAgentSystemPrompt` assemble: base → core tool list → lazy skills listing → live `<env>` block → appended extensions. Built-in catalog tools and MCP integrations load dynamically via `tool_search` rather than being enumerated. Skills follow the same lazy principle pi-style: each discovered skill contributes only its name + one-line description to the prompt, and the model pulls a skill's full instructions into context on demand by calling `use_skill`. 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.
`buildChatSystemPrompt` (TUI chat) assembles: Skywalker identity → harness → guidelines → discipline → tools → skills → `<env>`. `buildSubAgentSystemPrompt` leads with the director identity, then a thin worker harness, skills, the mounted tool list, `<env>`, one report contract, and a short spawn appendix. Workers mount `use_skill` and `tool_search`; MCP tools stay dispatchable and are discovered rather than dumped into the prompt. Skills follow the same lazy principle: name + one-line description in the prompt, full body on `use_skill`. 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.

**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.

Expand Down Expand Up @@ -403,7 +403,7 @@ Corbits Code **ships a bundled catalog** as the first-party data-only plugin `pl

`discoverRepoPlugins` locates `plugins/` next to the source root, at `dist/plugins`, or at `dirname(execPath)/plugins`. It never scans the session cwd for the bundled catalog.

Primary is Skywalker. Bundled skill bodies that are operator slashes are **action** recipes that tell it to `task(agent="<director>")` — there is no catch-all worker. Default slashes: `/implement`, `/plan`, `/refactor`, `/review`, `/pull-request-review`, `/create-issue`, `/scribe`, `/interview`, `/ast-grep`. `/scribe` dispatches shakespeare; `/implement` spawns implement / greybeard / critique as the recipe specifies; `/plan` dispatches plan director (eng change plan; does not implement; does not file tracker issues); `/review` is a code-review action (not a director name); `/create-issue` remains the tracker command — Linear MCP when available, otherwise `ask_operator` for the platform and persists `Preferred issue tracker` in `.corbits/MEMORY.md`. Dispatch is `use_skill` only, not a default slash. Draper and emil are closed directors via `task(agent=…)`, not slashes. The operator types the slash; Skywalker reads the body and dispatches.
Primary is Skywalker. Ordinary chat is enough: Skywalker may do the work or `task(agent=…)` a closed director — the operator does not name one. Bundled skill bodies that are operator slashes are **optional explicit recipes** that pin a chain (`task(agent="<director>")`) when someone wants that crutch; there is no catch-all worker. Default slashes: `/implement`, `/plan`, `/refactor`, `/review`, `/pull-request-review`, `/create-issue`, `/scribe`, `/interview`, `/ast-grep`. `/scribe` dispatches shakespeare; `/implement` spawns implement / greybeard / critique as the recipe specifies; `/plan` dispatches plan director (eng change plan; does not implement; does not file tracker issues); `/review` is a code-review action (not a director name); `/create-issue` remains the tracker command — Linear MCP when available, otherwise `ask_operator` for the platform and persists `Preferred issue tracker` in `.corbits/MEMORY.md`. Dispatch is `use_skill` only, not a default slash. Draper, emil, bruckheimer, gaasbot, testsmith, and brand-reviewer have no slash; Skywalker still dispatches them from chat.

#### Discovery and precedence

Expand Down
2 changes: 1 addition & 1 deletion docs/IMPLEMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ Sixteen packages under `src/agent/directors/<id>/` register in `DIRECTOR_REGISTR
2. `packageToProfile` maps envelope (`tools.allow`/`deny`) to `AgentProfile.capabilities`, `spawn.maySpawn` → `orchestrator`, and optional `writePaths`. System prompts are prefixed with a stable identity block (`formatDirectorSystemPrompt`: agent id, model role, optional skills).
3. Nested spawn: packages with `spawn.allowlist` forward that list into nested `task` (`spawnAllowlist` on nestedDispatch). Off-list `agent` is refused. `task(agent=skywalker)` is refused (primary is not a spawned worker). Primary omits the list so plugin profiles stay reachable.
4. `directorProfiles()` is the spawn catalog (`default-agents.ts`) — closed set minus skywalker; plugin agent profiles still load and can override by id.
5. Primary chat role is Skywalker: `buildChatRole()` → `createSkywalkerSystemPrompt()`. Product mutation tools are stripped from the primary toolset and from CORE/CATALOG ads (`PRIMARY_DENIED_PRODUCT_TOOLS`) — never-implement is structural for path tools. Residual: `run_shell` stays on primary; MCP tools loaded later are not re-stripped by that deny list; optional `writePaths` (when a profile sets it) only gate path-keyed product tools.
5. Primary chat role is Skywalker: `buildChatRole()` → `createSkywalkerSystemPrompt()`. Product mutation tools are mounted and advertised on CORE (`write_file` / `edit_file` / `delete_file`). Skywalker may do the work or chain `task(agent=…)`. Optional `writePaths` (when a profile sets it) only gate path-keyed product tools.
6. Shipped directors omit `writePaths`. The optional field is still enforced in the permission gate via ALS identity (`identity-context.ts` + `write-path-policy.ts`) when a plugin/custom profile sets it.
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.

Expand Down
Loading
Loading