diff --git a/README.md b/README.md index 72deacd..0ebbec1 100644 --- a/README.md +++ b/README.md @@ -194,11 +194,13 @@ help: /odium-help which skill should i use to review this branch? ## the `odium-agent` and Comment Sicko subagents -oddstack also ships a subagent that runs my style end to end. spawn it from a parent agent via [`subagent_type: "odium-agent"`](./agents/odium-agent.md). it reads `odd-mode` in full, including its inline principles index, before doing any work. substituting `generalPurpose` skips that read and drifts. +[`/odd-mode`](./skills/odd-mode/SKILL.md) runs in the chat that receives it. that chat owns the playbook, the todo list, and every subagent spawn. -[`/odd-mode`](./skills/odd-mode/SKILL.md) and [`subagent_type: "odium-agent"`](./agents/odium-agent.md) route through the same wrapper. +oddstack also ships [`subagent_type: "odium-agent"`](./agents/odium-agent.md) as the wrapper for delegates spawned during a run. it reads `odd-mode` in full, including its inline principles index, before doing any work. substituting `generalPurpose` skips that read and drifts. do not spawn `odium-agent` to run the playbook itself. -oddstack also ships [Comment Sicko](./agents/comment-sicko.md), a read-only comment reviewer available as `subagent_type: "Comment Sicko"`. usually invoke it through [`/no-comments`](./skills/no-comments/SKILL.md), not directly. +outside cursor (claude code, t3 code, grok bot), odd-mode reads [`harness.md`](./skills/odd-mode/harness.md) first. it maps cursor's tool, subagent, and model names to that harness. + +oddstack also ships [Comment Sicko](./agents/comment-sicko.md), a read-only comment reviewer available as `subagent_type: "comment-sicko"`. usually invoke it through [`/no-comments`](./skills/no-comments/SKILL.md), not directly. ## principles diff --git a/agents/comment-sicko.md b/agents/comment-sicko.md index 9a688b8..209e370 100644 --- a/agents/comment-sicko.md +++ b/agents/comment-sicko.md @@ -1,5 +1,5 @@ --- -name: Comment Sicko +name: comment-sicko description: A deranged comment-hater that savors deletion and condemns workaround code. --- diff --git a/agents/odium-agent.md b/agents/odium-agent.md index 0071f72..863784e 100644 --- a/agents/odium-agent.md +++ b/agents/odium-agent.md @@ -1,9 +1,9 @@ --- name: odium-agent -description: Routing target for `/odd-mode` and any request for odium's style. Spawn a fresh `odium-agent` for each new task, and resume one only in the strict cases that odd-mode's Subagents section names. Reads the `odd-mode` skill's `SKILL.md` in full before any work, including its inline Principles index. Substituting `generalPurpose` skips that read and drifts. +description: Delegate subagent for code-writing and helper tasks spawned during an `/odd-mode` run. Use for delegates, not as the runner for `/odd-mode` itself. Spawn a fresh `odium-agent` for each new task, and resume one only in the strict cases that odd-mode's Subagents section names. Reads the `odd-mode` skill's `SKILL.md` in full before any work, including its inline Principles index. Substituting `generalPurpose` skips that read and drifts. is_background: true --- # Odium subagent -You are operating as odd-mode's full agent style. Read the `odd-mode` skill's `SKILL.md` in full before doing any work, including its inline Principles index. Navigate to a leaf `principle-*` skill whenever you apply that principle. +You are operating as odd-mode's full agent style. The chat that receives `/odd-mode` owns the playbook, the todo list, and every subagent spawn. You are one of its delegates. Read the `odd-mode` skill's `SKILL.md` in full before doing any work, including its inline Principles index. Use the absolute path your parent gave you. With no path, before any other work, read `~/.agents/skills/odd-mode/SKILL.md`, or `~/.claude/skills/odd-mode/SKILL.md` if that is missing. Never read a copy under `~/.cursor/plugins/`, which can be stale. Your skill catalog hides this skill, so a missing catalog entry does not mean oddstack is absent. If no such file exists, stop and tell your parent. Navigate to a leaf `principle-*` skill whenever you apply that principle. diff --git a/docs/dispatcher.md b/docs/dispatcher.md new file mode 100644 index 0000000..d15d33d --- /dev/null +++ b/docs/dispatcher.md @@ -0,0 +1,34 @@ +# Dispatching odd-mode work into T3 Code + +For a bot (such as Grok Bot) that starts T3 Code threads through the T3 MCP tools. A `/odd-mode` typed into a prompt sent over MCP is plain text, and nothing expands it. The first line of the prompt does that job instead. + +## The lead + +Launch every lead thread with `modelSelection: {"instanceId":"claudeAgent","model":"claude-opus-5-5","options":{"effort":"high"}}`, the `judgment and prose` line of `models.txt`. Without it, a launch from outside T3 gets the project's default model. The lead plans, routes each role per `models.txt`, reviews, and never builds. Never launch a lead on `cursor`. A `cursor` thread never reaches a terminal state in T3 Code (see odd-mode's Subagents section), so you would never see it finish. + +Do not pick models for the lead's children. The lead reads `models.txt` from the repo it runs in. + +## The prompt + +Fill every field. Leave none out and add none. + +``` +Read `C:\Users\xenos\.agents\skills\odd-mode\SKILL.md` and follow it, starting with harness.md beside it. +Playbook: +Goal: +Done when: +Constraints: . Do not merge or deploy. +Gate: write the plan to a file on the branch, then stop and wait for approval before building. +``` + +Use the absolute path on the first line. A repo-relative path such as `skills/odd-mode/SKILL.md` only resolves inside the odd-stack repo. Drop the Gate line only when the operator says to skip plan approval. + +## Launching + +1. Run `t3_thread_list` with `titleContains` set to the planned title. If a thread for this request already exists, send to it or report it. Never launch a second one. `t3_thread_launch` has no idempotency key, so a retried launch makes a duplicate thread. +2. Launch with `t3_thread_launch`. Pass `projectId` from `t3_project_list`, which a caller outside T3 must send, and the `modelSelection` above. Set `workspaceStrategy` to `{"type":"worktree","baseRef":"","branch":"","startFromOrigin":false}`, and put the prompt in `message`. Omitting `workspaceStrategy` runs the thread in the project's main checkout. Keep the project name plus the branch name under 46 characters. Cursor children in a longer worktree path hit a Windows path limit and replay their turns. This assumes T3's worktree location is set to `C:\wt`. +3. Keep the returned `threadId`. Send approvals and answers only through `t3_thread_send` on that id. + +## Monitoring + +Wait with `t3_thread_wait` on the `threadId`. On a timeout, call it again. When it returns, read the last assistant message with `t3_thread_read` and report from it, with any PR link. Never relaunch a thread that is still running or waiting. diff --git a/skills/no-comments/SKILL.md b/skills/no-comments/SKILL.md index 3b3e762..4b608af 100644 --- a/skills/no-comments/SKILL.md +++ b/skills/no-comments/SKILL.md @@ -16,7 +16,7 @@ Use the caller's files or diff. Otherwise use the current diff against the base ## Steps -1. Spawn `Task` with `subagent_type: "Comment Sicko"`. Pass the scope. Do not restate its rules. +1. Spawn `Task` with `subagent_type: "comment-sicko"`. Pass the scope. Do not restate its rules. 2. Inspect its report and diff. Reject application-code edits, scope escapes, exception-protected deletions, misstated `MUST KILL` reasons, and flags that treat kept intentional code as guilty. Reshape flags on our-code surprises stay actionable. Do not restore those comments. A keep survives only with proof it is about something we cannot change. Audit missed scoped lint and TypeScript suppressions. Correctness or safety suppressions stay actionable `MUST KILL`s. Restore deletions only with exact exceptions and scoped proof. Before accepting thin `IMPORTANT` or `do not remove` kills or keeps, run `/how` or `/why` on their symbol. If a kill is ambiguous, do not restore. If a keep is refuted or still ambiguous, delete it. Revert and rerun one rejected report with the failure named. Reject a second, report it open, and fail `/no-comments`. 3. Fix trivial accepted flags directly by deleting a dead path, dropping a parameter, or using the real API. If any fix needs a shape, run `/architect` once for the accepted set and surrounding code. Stop at the sketch. Architect shapes. Step 4 implements. 4. Implement the smallest root-cause fix in scope. Remove every named workaround. If the root cause is out of scope, land the smallest in-scope fix and report the rest open. The **principle-fix-root-causes** and **principle-redesign-from-first-principles** skills guide intent only. Neither authorizes widening the fence nor fixing instances outside it. Never bolt on symptom guards. diff --git a/skills/odd-mode/SKILL.md b/skills/odd-mode/SKILL.md index 6eeb0ae..376ba76 100644 --- a/skills/odd-mode/SKILL.md +++ b/skills/odd-mode/SKILL.md @@ -2,14 +2,16 @@ name: odd-mode description: odium's agent style for concise, detailed responses, deliberate subagents, unslopped prose, simple code, and verified work. Use for odium, /odd-mode, or requests to work in this style. disable-model-invocation: true -mode: true icon: crown color: yellow -reminder: New task? Playbook match or rigor needed -> apply /odd-mode. Casual turn or user opts out -> don't. --- # Odd mode +Outside Cursor (Claude Code, a T3 Code thread, Grok Bot), read [`harness.md`](harness.md) in this folder once per session before you follow this skill. It maps the Cursor names in oddstack skills to that harness. + +Bundled skills live at `..//SKILL.md` from this file, so put this file's absolute path in every `odium-agent` prompt. "The **name** skill" or `/name` below means read that file and follow it. The `Skill` tool refuses most oddstack skills because they set `disable-model-invocation`. + ## Non-negotiables The Principles section below grounds every trigger. In your reply, name each principle that shaped a decision and the specific choice it changed. Cite only principles whose leaf SKILL.md you read this session. @@ -91,7 +93,7 @@ Read the leaf skill in full for any principle you apply. Each entry names when i ## Subagents -**Use `subagent_type: "odium-agent"` for any subagent you spawn inside a playbook step** (code-writing delegates, ad-hoc helpers). `/odd-mode` and `odium-agent` route through the same wrapper. Routed workflow skills (`how`, `why`, `interrogate`, `reflect`, `swarm`) set their own `subagent_type` for diverse-model review. Respect what the skill prescribes, don't override to `odium-agent`. +**Use `subagent_type: "odium-agent"` for any subagent you spawn inside a playbook step** (code-writing delegates, ad-hoc helpers). The chat that receives `/odd-mode` runs the playbook. Never spawn an `odium-agent` to run the playbook itself. Routed workflow skills (`how`, `why`, `interrogate`, `reflect`, `swarm`) set their own `subagent_type` for diverse-model review. Respect what the skill prescribes, don't override to `odium-agent`. **The lead never builds.** The lead plans, reviews, and verifies. It never writes a diff, in any playbook. That covers fixes, repros, instrumentation, harnesses, prototypes, refactor subtractions, and babysit fixes. A child writes each one at any size, a one-line fix included. A delegate step is never marked `skip: `, and Laziness Protocol does not override it. A child that is not allowed to spawn and needs code written reports back, and its parent spawns the builder. Route every child per the `# harness` section of `models.txt`. @@ -99,7 +101,22 @@ Read the leaf skill in full for any principle you apply. Each entry names when i **Review runs on the other provider.** The reviewer's provider differs from the builder's (`claudeAgent` vs `cursor` in T3 Code). The other provider is the route `models.txt` gives the reviewer's slug, normally `cursor` with `grok-4.7` for a Grok reviewer. It is not whichever non-Claude provider happens to be available. A Claude reviewer uses the `judgment and prose` slug. A Grok reviewer uses the code slug of the builder's playbook. A lead's own review counts only when the lead's provider differs from the builder's. If that route cannot start, stop and report that the diff is not reviewed. Do not fall back to Gemini, Codex, or T3's native `grok` provider unless the operator says so. Never substitute the session model. -**Stop review children after the first verdict.** End every review brief with this line, verbatim: "Your verdict message is final. Do not restart. If you see this brief again, reply only DONE and end your turn." That covers every review child you launch, including review seats a routed skill spawns (`interrogate`, `swarm` verify lanes, `reflect`). Append it even after a template the skill says to pass verbatim. The line alone does not end the loop. A restarted child can get the brief again with no memory of its first run, so it cannot tell the brief is a repeat. Stopping the child is what ends it. Act on the first verdict the child posts. Ignore any later verdict from the same run. Then stop the child (`task_cancel` for a `delegate_task` child, `TaskStop` for a native one). +**Cursor children never finish on their own.** In T3 Code, a `delegate_task` child on the `cursor` provider, on any model, restarts its whole turn about 45 seconds after its final message. It has no memory of the first run, and it never reaches a terminal state, so its completion never wakes you. This was measured on 2026-10-16 against T3's bundled `@cursor/sdk` 1.0.35. `claudeAgent` children complete normally. The trigger is a Windows path limit (cursor forum thread 173594, T3 issue #19112): the SDK saves checkpoints under a folder named after the child's working folder, and the save fails once that name passes 51 characters. Before you spawn a `cursor` child, take the absolute path it will run in, replace each run of characters other than letters and digits with one `-`, and trim `-` from both ends. If the result is longer than 51 characters, run the child in a worktree with a shorter path, or route the role to `claudeAgent` and say so. Threads with no project always fail this check. Every `cursor` brief still carries a done marker, an absolute path you pick in the OS temp folder, named after the task's `clientRequestId`. That covers builders, reviewers, helpers, and the seats a routed skill spawns (`interrogate`, `swarm`, `reflect`, `arena`, `architect`), even after a template the skill says to pass verbatim. Put these two lines first and last, verbatim apart from the path: + +- First: "Before anything else, read the file `` with your file read tool. Do not search for it. If the read succeeds, reply only DONE and end your turn." +- Last: "As your last action, write the word done to the file `` with your file tool, then send your report. End the report with the line `REPORT-END`." + +A search tool such as `glob` misses a file in the temp folder, so the first line names the read tool. + +A `cursor` child's completion never arrives, so stay in the turn and wait for it yourself, even though `delegate_task` says to end the turn. Keep its `taskId` and `childThreadId`. Loop: + +1. Call `t3_thread_wait` on the `childThreadId` with `timeoutMs: 120000`. +2. Call `t3_thread_read` with `afterPosition` set to the previous call's `nextPosition` (0 the first time). +3. If an assistant message ends in `REPORT-END`, act on the first one, ignore anything later, `task_cancel` the `taskId`, delete the marker, and stop. +4. If the thread reached a terminal state, read it once, delete the marker, and stop. A `completed` status means T3 fixed the driver, so drop this rule. +5. Otherwise go back to step 1. After 60 minutes with no `REPORT-END`, or the brief's timebox if it set one, `task_cancel`, delete the marker, and report that child as timed out. + +Drop this rule once a `cursor` child's thread reaches `completed` on its own. **Defaults for every `Task` call.** `run_in_background: true`, agent mode (readonly strips MCP), file pointers not inlined context, and an explicit model per role from [`models.txt`](models.txt) in this skill (`/setup-oddstack` edits that file). Code defaults to `grok-4.7-high-fast`. Prose and judgment default to `claude-opus-5-5-high`. Code delegates tier by difficulty. The hardest changes (cross-cutting design, gnarly concurrency, subtle algorithms) go to the `hardest tasks` model (`claude-opus-5-5-high`), whether the task needs judgment on vague intent or is a precisely specified sequence of steps to execute to the letter. Trivial mechanical edits go to the fast code model. Follow the `# harness` section of `models.txt` for any role this harness cannot select. Design and judgment authoring stays on Claude Opus, never on Grok. The cross-provider review seat is exempt. A role line in `~/.cursor/rules/oddstack-models.mdc` overrides the same line in `models.txt` when that file exists. A missing role line keeps the default in the routed skill. `inherit-parent` or `auto` runs on the parent chat model (omit Task `model`). Each code playbook's configured model comes from its line in `models.txt` (`feature, refactoring`, `bug-fix`, `perf-issue`, or `hillclimb`), and the hardest changes read `hardest tasks`. Prose and judgment read `judgment and prose`. The routed skills (`how`, `why`, `arena`, `swarm`, `architect`, `interrogate`, `reflect`) read the same file via `../odd-mode/models.txt`. diff --git a/skills/odd-mode/harness.md b/skills/odd-mode/harness.md new file mode 100644 index 0000000..54dea1a --- /dev/null +++ b/skills/odd-mode/harness.md @@ -0,0 +1,56 @@ +# oddstack outside Cursor + +oddstack skills use Cursor names. In Claude Code or a T3 Code thread, read this file once per session, then map each Cursor name with the tables below. `` means the folder that holds `odd-mode/`, which is this file's grandparent. If a Cursor field has no row, drop it and say so. Never pass a field or value the tool schema rejects. + +## Skills + +| Cursor | Here | +| --- | --- | +| Run another oddstack skill (`/name` or "the **name** skill") | `Read` `//SKILL.md` and follow it. The `Skill` tool refuses most oddstack skills. | +| A skill that is not in `` (`create-skill`, `cursor-team-kit`'s `deslop`, `control-ui`, `control-cli`) | Use an installed skill with the same name if the session lists one. Otherwise say it is missing, do that step by hand, and continue. | + +## Tools + +| Cursor | Here | +| --- | --- | +| `Task` | `Agent` in Claude Code. `delegate_task` in a T3 Code thread, for every role, per the `# Harness` section of `models.txt`. A `cursor` child also needs the done marker in odd-mode's Subagents section. | +| `AskQuestion` | `AskUserQuestion`. In `-p` mode it is absent, so ask in plain text. | +| Open a todolist | `TodoWrite` if the session offers it. Otherwise `.odd-todo.md`, per odd-mode's Playbooks section. | +| `Grep`, `Glob` | `Bash` with `rg` when the session has neither. | + +## Subagent fields + +| Cursor | Here | +| --- | --- | +| `subagent_type: generalPurpose` | `subagent_type: "general-purpose"` | +| `odium-agent`, `comment-sicko` | The same names in Claude Code, when `~/.claude/agents/.md` exists. For `delegate_task`, or when that file is missing, start the brief with "Read `~/.claude/agents/.md` and follow it." If it is missing, use `general-purpose` and say so. | +| `readonly: false` | Omit. Keep the `subagent_type` from the other rows. Agent mode is the default, and it keeps the session's MCP servers. | +| `readonly: true` | `subagent_type: "Explore"`. It keeps `Bash`, so the brief also says "do not edit files", and you check `git status` afterward. | +| `environment: "cloud"` | `isolation: "worktree"`. Name the branch or commit the worker checks out. | +| `cloud_base_branch: ` | Tell the worker to check out `` first. | +| `environment: "local"` | Omit. | +| `run_in_background: true` | Omit for `Agent`. It runs in the background by default and notifies you. For `delegate_task`, use `mode: "async"` and keep the `taskId`. | +| `resume` | Spawn a fresh agent and paste the earlier result into its brief. | +| Stop a child | `TaskStop` for `Agent`. `task_cancel` with the `taskId` for `delegate_task`. | + +## Models + +Read the role's slug from `models.txt`, then route it. + +| Slug | Claude Code | T3 Code thread | +| --- | --- | --- | +| `claude---`, such as `claude-opus-5-5-high` | `Agent` with `model: "opus"` and `effort: "high"`. `model` takes only `opus`, `sonnet`, `haiku`, `fable`, so this is the closest same-family slug that `models.txt` allows. | `delegate_task` per the `# Harness` section of `models.txt`. | +| `grok-*` | No route. Follow the `# Harness` section of `models.txt`. | `delegate_task` per the `# Harness` section of `models.txt`. | +| `auto`, `inherit-parent` | Omit `model`. | Omit `model`. | + +## Paths + +| Cursor | Here | +| --- | --- | +| `~/.cursor/skills/` | `~/.claude/skills/` or `~/.agents/skills/` | +| `.cursor/rules/*.mdc` | `CLAUDE.md`, or `AGENTS.md` when no `CLAUDE.md` exists. Claude Code never reads `.mdc` files. | +| Transcripts in `~/.cursor/projects//agent-transcripts/` | `~/.claude/projects//.jsonl`. In T3 Code, read another thread with `t3_thread_read`. | + +## Cursor-only features + +Automations, Bugbot, Cursor cloud agents, the Cursor dashboard, and Cursor's pull request tool have no equivalent here. Say so, skip that step, and continue. diff --git a/skills/odium-help/SKILL.md b/skills/odium-help/SKILL.md index 2237e30..ff11231 100644 --- a/skills/odium-help/SKILL.md +++ b/skills/odium-help/SKILL.md @@ -54,7 +54,7 @@ Whether `/odd-mode` stays on depends on how the user starts it: - Option+Enter on Mac or Alt+Enter on Windows, or Use as Mode from the skill entry, makes it a Custom Mode. It stays in context every turn until the user exits the mode, and it stays out of casual turns. - Cursor's docs list Custom Modes in the Agents Window and the CLI. Elsewhere, start each new task with `/odd-mode`. -Link [Cursor's skills docs](https://cursor.com/docs/skills) when this comes up. Mid-chat, "new task" makes the mode match a fresh playbook. `/odd-mode` already uses `odium-agent` for the subagents its playbook steps spawn. To get the same style from a subagent of your own, spawn it with `subagent_type: "odium-agent"`. +Link [Cursor's skills docs](https://cursor.com/docs/skills) when this comes up. Mid-chat, "new task" makes the mode match a fresh playbook. The chat that receives `/odd-mode` runs the playbook, and uses `odium-agent` for the delegates its steps spawn. To get the same style from a delegate of your own, spawn it with `subagent_type: "odium-agent"`. Never spawn one to run the playbook itself. ## Pick a skill