Skip to content

Commit f190a3d

Browse files
committed
Add Lexicon skill owning director prompt drift and size
1 parent bf79cc0 commit f190a3d

6 files changed

Lines changed: 175 additions & 8 deletions

File tree

docs/ARCHITECTURE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ Corbits Code **ships a bundled catalog** as the first-party data-only plugin `pl
428428

429429
`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.
430430

431-
Primary is Skywalker. Bundled skill bodies are **how-to playbooks** (steps, done-definition) — not director personas and not fleet routers. Identity and who-does-what live on director system prompts. Default slashes: `/implement`, `/plan`, `/refactor`, `/review`, `/pull-request-review`, `/create-issue`, `/scribe`, `/interview`, `/ast-grep`. `/review` is how to review a branch (base, scope, signal); `/pull-request-review` is worktree checkout then the review skill; `/scribe` is how to maintain PRODUCT / ARCHITECTURE / IMPLEMENTATION; `/implement` is the per-commit greybeard → implement → gate → critic loop and does not steal planning from `/plan`; substantial Builder work consumes a counsel / `/plan` plan first; `/plan` authors an eng change plan and does not implement or file tickets; `/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`. The less-is-more quality bar (`idiot-proof`) is baked into builder and critic; it is not a slash. There is no first-party dispatch skill — Skywalker orchestrates natively. Draper and emil are closed directors via `spawn_agent(agent=…)`, not slashes. There is no catch-all worker. The operator types the slash; the primary follows the playbook.
431+
Primary is Skywalker. Bundled skill bodies are **how-to playbooks** (steps, done-definition) — not director personas and not fleet routers. Identity and who-does-what live on director system prompts. Default slashes: `/implement`, `/plan`, `/refactor`, `/review`, `/pull-request-review`, `/create-issue`, `/scribe`, `/interview`, `/ast-grep`, `/lexicon`. `/review` is how to review a branch (base, scope, signal); `/pull-request-review` is worktree checkout then the review skill; `/scribe` is how to maintain PRODUCT / ARCHITECTURE / IMPLEMENTATION; `/implement` is the per-commit greybeard → implement → gate → critic loop and does not steal planning from `/plan`; substantial Builder work consumes a counsel / `/plan` plan first; `/plan` authors an eng change plan and does not implement or file tickets; `/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`; `/lexicon` owns director-prompt drift and size against the agents repo at a pinned commit. The less-is-more quality bar (`idiot-proof`) is baked into builder and critic; it is not a slash. There is no first-party dispatch skill — Skywalker orchestrates natively. Draper and emil are closed directors via `spawn_agent(agent=…)`, not slashes. There is no catch-all worker. The operator types the slash; the primary follows the playbook.
432432

433433
#### Discovery and precedence
434434

docs/PRODUCT.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ That distinction sets priority.
2020

2121
**The harness is core and cannot be swapped in later**, because everything runs inside it. Fleet events waking the director, continuous dispatch while capacity is free, unprompted reporting, aggregated health, a bound grounded in real cost rather than a turn count. This is the part no one can hand us and the part a competitor cannot copy from a directory of prompts.
2222

23-
**Agent personas and skills are content.** They define who gets dispatched and to what standard. They are valuable, they are swappable, and they ship as the first-party `corbits-skills` plugin — on by default, disable-able in `/plugins`. The default action set (`/implement`, `/plan`, `/refactor`, `/review`, `/pull-request-review`, `/create-issue`, `/scribe`, `/interview`, `/ast-grep`) is not an optional install and not something an operator has to discover.
23+
**Agent personas and skills are content.** They define who gets dispatched and to what standard. They are valuable, they are swappable, and they ship as the first-party `corbits-skills` plugin — on by default, disable-able in `/plugins`. The default action set (`/implement`, `/plan`, `/refactor`, `/review`, `/pull-request-review`, `/create-issue`, `/scribe`, `/interview`, `/ast-grep`, `/lexicon`) is not an optional install and not something an operator has to discover.
2424

2525
**Distribution is packaging for content**, and content is not the constraint. A catalog and an install surface matter eventually; they do not gate anything the product is actually judged on.
2626

@@ -107,7 +107,7 @@ the file path and parse details.
107107

108108
The TUI has an extensible slash-command framework. Built-ins include `/help` (shortcut + command overlay), `/model` (models-only picker for connected accounts; **Alt+A** or `/connect` adds a provider), `/settings`, `/permissions`, `/plugins`, `/clear`, `/new`, `/mcp` (enable, disable, or remove servers), and `/yolo` (persists as the user-global skip-permissions default; `--dangerously-skip-permissions` still forces this process; secret-guard and authz still apply; `/yolo [on|off|toggle]`, bare `/yolo` toggles), plus a `/<name>` command per available workflow. When a session starts with the persisted default already on, the TUI shows a startup notice ("Permission prompts are disabled by your saved default…") so the silent machine-wide default is never invisible; `corbits exec` prints the equivalent warning to stderr. Plugins can register additional commands.
109109

110-
**Default skills** exist out of the gate as first-party slash **actions**, not director names: `/implement`, `/plan`, `/refactor`, `/review`, `/pull-request-review`, `/create-issue`, `/scribe`, `/interview`, `/ast-grep`. Each one is a how-to playbook — the slash sends the skill body to the primary, which follows the steps. Skills do not assign identity or route the fleet; that stays on director system prompts. `/review` is how to review a branch; `/scribe` is how to maintain PRODUCT / ARCHITECTURE / IMPLEMENTATION; `/implement` is the per-commit review/build/critique loop — it does not steal planning from `/plan`. Substantial Builder work consumes a counsel / `/plan` plan first; tiny parent-DIY stays plan-optional. `/plan` authors an eng change plan (files, AC, non-goals, risks, ordered steps) and does not implement. `/create-issue` remains the tracker command: Linear MCP when available; otherwise it `ask_operator`s for the platform (GitHub etc.) and persists `Preferred issue tracker` in `.corbits/MEMORY.md` (GitHub via `gh issue create`). There is no first-party dispatch skill — Skywalker orchestrates natively. `git-rebase`, `linear-issue-workflow`, `style`, `philosophy`, `native-integration`, `typescript`, `ponytail`, and `opsh` stay `use_skill` only (`user-invocable: false`). Bake-only bars such as `idiot-proof` and `native-runtime` are not slashes and are not listed for `use_skill`. Draper and emil are not slashes; they remain closed directors via `spawn_agent(agent=…)`. There is no catch-all worker. Slash names are also available to the model via `skill_search` (descriptions) then `use_skill` (body). Disable the catalog in `/plugins` (`corbits-skills`) if you want them gone.
110+
**Default skills** exist out of the gate as first-party slash **actions**, not director names: `/implement`, `/plan`, `/refactor`, `/review`, `/pull-request-review`, `/create-issue`, `/scribe`, `/interview`, `/ast-grep`, `/lexicon`. Each one is a how-to playbook — the slash sends the skill body to the primary, which follows the steps. Skills do not assign identity or route the fleet; that stays on director system prompts. `/review` is how to review a branch; `/scribe` is how to maintain PRODUCT / ARCHITECTURE / IMPLEMENTATION; `/implement` is the per-commit review/build/critique loop — it does not steal planning from `/plan`. Substantial Builder work consumes a counsel / `/plan` plan first; tiny parent-DIY stays plan-optional. `/plan` authors an eng change plan (files, AC, non-goals, risks, ordered steps) and does not implement. `/create-issue` remains the tracker command: Linear MCP when available; otherwise it `ask_operator`s for the platform (GitHub etc.) and persists `Preferred issue tracker` in `.corbits/MEMORY.md` (GitHub via `gh issue create`). `/lexicon` owns director-prompt drift and size against the agents repo at a pinned commit. There is no first-party dispatch skill — Skywalker orchestrates natively. `git-rebase`, `linear-issue-workflow`, `style`, `philosophy`, `native-integration`, `typescript`, `ponytail`, and `opsh` stay `use_skill` only (`user-invocable: false`). Bake-only bars such as `idiot-proof` and `native-runtime` are not slashes and are not listed for `use_skill`. Draper and emil are not slashes; they remain closed directors via `spawn_agent(agent=…)`. There is no catch-all worker. Slash names are also available to the model via `skill_search` (descriptions) then `use_skill` (body). Disable the catalog in `/plugins` (`corbits-skills`) if you want them gone.
111111

112112
Providers are **models-first**: there is no standalone `/login` command. `/model` opens a **models-only list** (Recent, Favorites, then connected provider/model rows) — type-to-filter owns printable keys, so Connect is never a bare letter. **Alt+A** or `/connect` opens a dedicated add-provider selector over every first-class kind (OpenAI dual-path ChatGPT OAuth or API key, xAI, OpenCode Zen, Anthropic, Google, OpenCode Go, Z.AI Coding Plan, Ollama, Custom), each annotated with its live account count and never filtered out for “already connected.” **Alt+F** toggles favorite on the highlighted model. **Alt+D** persists the highlighted pair as the default without switching the live session. Advanced provider drill-down (edit/delete/tiers) stays on the advanced surface, not a bare printable key while the model list is filtering. OAuth providers open their existing browser login with a named account step so multiple accounts per kind coexist (`codex/work`, …). API-key providers use the same named-instance step before the key (auth-only form: instance name + key + fixed catalog base URL), so personal and team keys land as distinct catalog rows (`openai/default`, `anthropic/work`, …); reusing a name re-keys that instance after confirm. Custom remains a free-form single endpoint (full manual form). Successful connect refreshes the catalog and reopens the model list focused on the new account’s default model. OpenCode Go lists models from the live `/zen/go/v1/models` catalog (packaged seed on fetch failure), routes each by its protocol metadata (chat completions, OpenAI responses, or Anthropic messages) and can show subscription usage in the status bar when active (rolling 5h / weekly / monthly windows when the usage API responds; omitted on auth or network failure). When Go returns a quota or rate-limit error — including some HTTP 400 responses that carry limit payloads — Corbits classifies them so quota aborts cleanly and short provider rate limits remain retryable. On a free-tier or subscription quota hit, wait for the window to reset or use OpenCode Zen free models.
113113

@@ -155,7 +155,7 @@ Capabilities beyond the core toolset are opt-in plugins, enabled per workspace t
155155

156156
## Multi-agent (fleet agents)
157157

158-
The primary session is always **orchestrator** (single-agent mode is gone). Its identity is **Skywalker** (product name remains Corbits Code; when asked its name, answer Skywalker): classify work, DIY tiny/single-file/one-route product edits, dispatch a **closed fleet of 16 directors** for substantial work, track the fleet, and synthesize. Product mutation tools (`write_file` / `edit_file` / `delete_file`) are mounted on the primary (CORE / `SKYWALKER_TOOLS`) — path tools are the DIY surface; spawn remains the default for substantial, multi-file, parallel, or specialist work. Shell file-writes stay denied. MCP tools are not re-filtered by a product-write deny list (that list is gone). There is no static per-package write-path declaration (CL-6952 removed it — no shipped director ever set one). A concurrent dispatch landing on the same working directory as another still-running lane is recorded as a `conflict` intervention, not blocked. Operator slash recipes (`/implement`, `/plan`, `/refactor`, `/review`, `/pull-request-review`, `/create-issue`, `/scribe`, `/interview`, `/ast-grep`) tell Skywalker which directors to spawn for substantial work; tiny/bounded edits may run on the primary.
158+
The primary session is always **orchestrator** (single-agent mode is gone). Its identity is **Skywalker** (product name remains Corbits Code; when asked its name, answer Skywalker): classify work, DIY tiny/single-file/one-route product edits, dispatch a **closed fleet of 16 directors** for substantial work, track the fleet, and synthesize. Product mutation tools (`write_file` / `edit_file` / `delete_file`) are mounted on the primary (CORE / `SKYWALKER_TOOLS`) — path tools are the DIY surface; spawn remains the default for substantial, multi-file, parallel, or specialist work. Shell file-writes stay denied. MCP tools are not re-filtered by a product-write deny list (that list is gone). There is no static per-package write-path declaration (CL-6952 removed it — no shipped director ever set one). A concurrent dispatch landing on the same working directory as another still-running lane is recorded as a `conflict` intervention, not blocked. Operator slash recipes (`/implement`, `/plan`, `/refactor`, `/review`, `/pull-request-review`, `/create-issue`, `/scribe`, `/interview`, `/ast-grep`, `/lexicon`) tell Skywalker which directors to spawn for substantial work; tiny/bounded edits may run on the primary.
159159

160160
| Lane | Directors |
161161
| --------- | -------------------------------------------------------------------------------------- |

plugins/corbits-skills/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
"name": "Corbits Skills",
44
"kind": "command",
55
"defaultEnabled": true,
6-
"description": "Default operator skills and slash commands (implement, refactor, review, pull-request-review, create-issue, scribe, interview, ast-grep, plan)."
6+
"description": "Default operator skills and slash commands (implement, refactor, review, pull-request-review, create-issue, scribe, interview, ast-grep, plan, lexicon)."
77
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
---
2+
name: lexicon
3+
description: Diff director prompts against the agents repo at a pinned commit, report assembled prompt sizes, and file Linear issues for drift
4+
argument-hint: "[--pin <commit>] [--file-issues]"
5+
---
6+
7+
# Lexicon
8+
9+
Own prompt drift and size for the director prompts mirrored from the
10+
agents repo. Diff each same-name director prompt against the agents
11+
checkout at a pinned commit, report assembled prompt sizes, and file
12+
Linear issues for drift.
13+
14+
## What this is not
15+
16+
- Not a director. There is no `lexicon` director package, no
17+
`src/agent/directors/lexicon/` module, and no Skywalker
18+
classification route. Never call `spawn_agent(agent="lexicon")`
19+
this skill runs as a `/lexicon` slash playbook on the primary only.
20+
- Not a fleet router. It does not assign identity or dispatch workers.
21+
- Not ponytail. That skill stays untouched.
22+
23+
## Step 1: Pin the agents commit
24+
25+
All comparisons in one run use a single pinned commit of the agents
26+
checkout — never float mid-run.
27+
28+
1. Resolve the checkout (default `/Users/thegreataxios/abklabs/agents`;
29+
accept an operator override path).
30+
2. Record the pin: `git -C <checkout> rev-parse HEAD`.
31+
3. Read every agents-side file with `git show <pin>:<path>` so local
32+
working-tree edits cannot skew the diff.
33+
34+
## Step 2: Match same-name prompts
35+
36+
- Director side: the closed `DIRECTOR_IDS` set in
37+
`src/agent/directors/types.ts`; each prompt lives in
38+
`src/agent/directors/<id>/package.ts` as `systemPrompt`.
39+
- Agents side: `plugins/*/agents/*.md` files in the checkout, matched
40+
by file basename — `<id>.md` matches director `<id>` exactly.
41+
- Near-misses are not diffs: `critique.md` is not `critic`, and
42+
`marketing-intern.md` is not `intern`. List them as unmatched, do
43+
not force a comparison.
44+
45+
## Step 3: Diff same-name pairs
46+
47+
For each matched pair, compare the director `systemPrompt` against the
48+
agents file body at the pin. Report per director: in sync, or drifted
49+
with the drifted sections quoted on both sides. Note the ported-from
50+
commit recorded in the package comment (e.g. gaasbot's `@ 6e16b6c`)
51+
when it disagrees with the pin — a stale port marker is itself drift.
52+
53+
## Step 4: Report assembled prompt sizes
54+
55+
Reuse the canonical helper in `src/agent/prompt-sizes.ts` — do not
56+
hand-roll a new measurement:
57+
58+
- `directorPromptSizeTable()` for the full per-director x per-family
59+
table (default assembly vs Grok, pinned env).
60+
- `formatPromptSizeTable(rows)` to render it as markdown.
61+
62+
Include the rendered table in the report. Sizes move only when real
63+
prompt changes land; the env and provider inputs stay pinned.
64+
65+
## Step 5: File Linear issues for drift
66+
67+
Follow the `linear-issue-workflow` skill conventions. File one issue
68+
per drifted director (never one mega-issue across directors), using
69+
the mounted Linear MCP tools as they appear in the toolset — do not
70+
invent a Linear REST client. Each issue carries the pinned agents
71+
commit, the quoted drift from Step 3, and the size-table row from
72+
Step 4. Without `--file-issues`, report the drift and stop — do not
73+
file. Without mounted Linear MCP tools, stop and tell the operator
74+
to enable Linear MCP.
75+
76+
## Report
77+
78+
Per director: match status (matched / unmatched with reason), sync
79+
status at the pin, size rows, and the filed issue id or why nothing
80+
was filed.

tests/unit/corbits-skills-catalog.test.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const SKILL_DIRS = [
2828
"opsh",
2929
"plan",
3030
"idiot-proof",
31+
"lexicon",
3132
] as const;
3233

3334
/** use_skill listing + resolve; not slash. No disable-model-invocation. */
@@ -58,6 +59,7 @@ const SLASH_SKILLS = [
5859
"interview",
5960
"ast-grep",
6061
"plan",
62+
"lexicon",
6163
] as const;
6264

6365
const BANNED_TOKENS = ["TaskCreate", "@greybeard", 'intent="general"'] as const;
@@ -96,8 +98,8 @@ test("corbits-skills plugin has no agents directory", () => {
9698
expect(existsSync(join(pluginRoot, "agents"))).toBe(false);
9799
});
98100

99-
test("corbits-skills catalog lists 20 skills with name and description", async () => {
100-
expect(SKILL_DIRS).toHaveLength(20);
101+
test("corbits-skills catalog lists 21 skills with name and description", async () => {
102+
expect(SKILL_DIRS).toHaveLength(21);
101103
const entries = await readdir(join(pluginRoot, "skills"), {
102104
withFileTypes: true,
103105
});
@@ -218,7 +220,7 @@ test("Corbits-only skills do not contain GaaS tool names", async () => {
218220
}
219221
});
220222

221-
test("loadSkillCommands lists exactly the nine slash actions", async () => {
223+
test("loadSkillCommands lists exactly the ten slash actions", async () => {
222224
const cmds = await loadSkillCommands(
223225
join(import.meta.dirname, "../../plugins/corbits-skills"),
224226
);
@@ -231,6 +233,7 @@ test("loadSkillCommands lists exactly the nine slash actions", async () => {
231233
"create-issue",
232234
"implement",
233235
"interview",
236+
"lexicon",
234237
"plan",
235238
"pull-request-review",
236239
"refactor",

0 commit comments

Comments
 (0)