agentleFS
Hive-AcademyHive-Academy/PtahCode/.claude/skills/agent-lanes/SKILL.md

agent-lanes

Skill34 starsChanged 11 days agoMITView on GitHub

Contract for background CLI agent lanes via the ptah_agent_* tools. Use when a task spawns or resumes a lane, or checks, messages, recovers or verifies one, even if it never names a tool, orchestration or tribunal. Load before any ptah_agent_spawn. This is the mechanic orchestration and tribunal load for lane work, not a substitute for the engineering workflow or for a multi-vendor panel.

2 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

12 rules. About 0 are common, 3 are distinctive, and 9 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 9

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Read each row's Limit state: never pick an AT LIMIT lane (spawn refuses it unless force: true).

    line 17
  2. Distinctive:

    Treat every provider as an ordinary ptah-cli row.

    line 32
  3. Very specific:

    When a Routing: system reminder is present, reuse its taskType, depth and executor suggestions.

    line 61
  4. Very specific:

    Report before exiting: call ptah_agent_report once before the final message, naming what was produced, the absolute path of every file …

    line 78
  5. Very specific:

    Git: never commit, push or run history-changing git — unless the workflow gives the lane its own throwaway worktree and says so.

    line 82
  6. Very specific:

    Preserve list: when replacing, consolidating or deleting an existing surface, list what it can do today (or pass parity-inventory.md in …

    line 94
  7. Very specific:

    Every lane receives PTAH_LANE_POLICY (libs/backend/cli-agent-runtime/src/lib/cli-agents/cli-adapters/cli-adapter.utils.ts) on that CLI's …

    line 103
  8. Very specific:

    When the work calls for a role, pass it as the role parameter — never paste a role template into task.

    line 110
  9. Very specific:

    Do not poll in a loop: When a lane reaches a terminal status, Ptah records one <agent-lane-completed> signal per lane turn into the session …

    line 122
  10. Distinctive:

    Do not start review of a deliverable while a queued message for that lane is pending.

    line 151
  11. Very specific:

    Shipping code: Use an independent code reviewer from a different family than the implementer, regardless of execution side.

    line 210
  12. Distinctive:

    Every spawn, resume, message turn and review round is a real paid call.

    line 260

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Agent Lanes

A lane is one background agent started with ptah_agent_spawn: an installed system CLI or a configured ptah-cli provider. This skill is the one place lane mechanics are written. Workflows (orchestration, tribunal) decide what a lane does; this decides how to run it. Skill and workflow authors: write and trim prompts against the prompt-authoring rubric in skill-creator.

1. Discover

No ptah_agent_* tools in this session → do the work natively and say so. Otherwise call ptah_agent_list before choosing. Its rows are the only lanes that exist on this machine now. Read each row's Limit state: never pick an AT LIMIT lane (spawn refuses it unless force: true); treat "unknown (…)" as unverified, not as room. The cli enum on the ptah_agent_spawn schema lists adapters this build ships, not what is installed.

| Agent        | Type     | Status        | Family     | Capabilities                                              |
| ------------ | -------- | ------------- | ---------- | --------------------------------------------------------- |
| <cli row>    | cli      | installed     | <family>   | messaging: <reported capability>                          |
| <provider>   | ptah-cli | available     | <family>   | provider: <family>, ptahCliId: <listed id>, messaging: …  |

That sample is one machine's output at one moment — yours will differ.

  • Type: cli + installed → spawnable with cli. Any other status (not installed, disabled) → skip.
  • Type: ptah-cli + available → spawnable with ptahCliId.
  • Family = the cli value, or the provider: token of a ptah-cli row. Families matter for review.
  • Treat every provider as an ordinary ptah-cli row; none is privileged or excluded.
  • The user named a lane that is not listed → say which one is missing and offer the listed alternatives. Never substitute silently.
  • The live list, not an example, determines what can be spawned.

2. Address

ParamUse
taskRequired. The self-contained prompt (§3).
cliA system CLI from an installed row. Omit for the user's default CLI.
ptahCliIdA ptah-cli row's id. When set, cli is ignored.
modelRaw model id. For a ptah-cli lane it overrides the tier mapping. Read ids from that lane's own model list; never invent one.
modelTieropus / sonnet / haiku, ptah-cli lanes only; the provider maps the tier to a model.
permission, networkOptional requested lane policies. Check the manifest first; unsupported combinations return UNSUPPORTED_LANE_POLICY before launch. no-reliable-source means no verified mapping.
roleName of a role generated for this workspace. ptah_agent_list lists the valid names. The spawn result reports roleDelivery and roleChannel.
workingDirectoryInside the workspace. A worktree path when lanes edit the same files in parallel.
taskFolder, filesWhere the lane writes deliverables; what it should read.
taskKindGate 0.1 chosen row's taskKind: plan, implement, review, research, tests or docs.
routingSourceGate 0.1 chosen row's source: model, ranking or pin.
deliverablesThe files the lane MUST write. Relative to taskFolder when set, else to workingDirectory. Pass it whenever the lane owes you a file — it is what makes the completion signal (§4) able to say the work was actually done.
timeoutInactivity window in milliseconds: the lane is stopped after this long with no output. Default one hour, no maximum; 0 disables it. Pass a value well under an hour (20 min, 1200000, is a good default); a lane that needs more than that is too big — split it.
resume_session_idOnly per §5.

A user-pinned spawn args line (lane, model) is passed through unchanged. Before a lane spawn, the orchestrator may call ptah_route_decide as described at orchestration Gate 0.1. Pass taskKind and routingSource from its chosen row on ptah_agent_spawn; omit them when no routed row exists. If ptah_route_decide is not listed, skip it silently. ptah_agent_spawn rejects any key not listed here — pass only the documented parameters. When a Routing: system reminder is present, reuse its taskType, depth and executor suggestions; do not repeat host pre-flight routing. Gate 0.1 still applies.

3. Task contract

A lane shares none of your context and cannot ask the user anything. Every task carries:

  1. Objective and acceptance criteria, restated in full.
  2. Inputs as absolute paths (prior artifacts, files, conventions to follow).
  3. Scope: files it may touch; "do not modify anything else".
  4. Deliverable: **Deliverable**: <absolute path> — write the output there with a file tool. Pass the same path in the deliverables parameter; the lane is then told to write it AND the completion signal checks it. Tell the lane to write the file early as a skeleton (headings or a stub) and fill it in as it goes, so any stop leaves usable output. When the workflow reads the answer with ptah_agent_read instead (a panel answer), give the exact answer structure in place of a path.
  5. Reply: WROTE: <absolute path> plus a one-line headline, nothing else — when there is a deliverable file.
  6. Report before exiting: call ptah_agent_report once before the final message, naming what was produced, the absolute path of every file written, and anything it could not do. A lane that exits silently still produces a completion signal, but the signal lists files — only the lane can say what it decided and what it left undone.
  7. Git: never commit, push or run history-changing git — unless the workflow gives the lane its own throwaway worktree and says so. Never run git commands that discard working-tree changes (restore, checkout -- <path>, stash, reset, clean); a change the lane did not make belongs to another writer — report it, never revert it.
  8. Decide, then ask the spawner: settle open points from the code, the inputs, project docs and web search, and list each under ## Decisions in the deliverable (decision, options, evidence, reversible). A point still open, or user-reserved (orchestration checkpoints.md § User-reserved decisions), goes to you through ptah_agent_report with options and a recommendation; the lane continues with the work that does not depend on it. If the report is not delivered, or nothing is left to do without the answer, it writes the questions under ## Clarifications Needed in the deliverable and stops. You answer with ptah_agent_message (branch on mode, §7) after running the decision ladder.
  9. Preserve list: when replacing, consolidating or deleting an existing surface, list what it can do today (or pass parity-inventory.md in files). Every item stays, moves, or is listed under ## Proposed Removals for user approval — never removed silently.
  10. UI deliverables (HTML, components, styles): the lane loads the matching design skill (for example impeccable, ui-ux-designer, angular-frontend-patterns) with its own skill mechanism, renders the output, and checks it with ptah_browser_navigate (a file:// URL inside the workspace is allowed) and ptah_browser_screenshot. The report states what it checked. If those browser tools are absent from the lane's tool list, say so.

Every lane receives PTAH_LANE_POLICY (libs/backend/cli-agent-runtime/src/lib/cli-agents/cli-adapters/cli-adapter.utils.ts) on that CLI's strongest channel (canary Lane policy id: …). Do not repeat its tool table in task.

Say the output format ("markdown table", "numbered defects with file:line"). A lane that is not told where to write dumps its answer into the reply and skips the file.

When the work calls for a role, pass it as the role parameter — never paste a role template into task. Spawning without role is valid when the workspace has no roles generated.

4. Run

spawn   ptah_agent_spawn({ task, deliverables, cli | ptahCliId, … })  → agentId
wait    <agent-lane-completed> arrives in this session when the lane ends
read    ptah_agent_read({ agentId })                     then Read the deliverable file
stop    ptah_agent_stop({ agentId })                     for a lane you no longer need

Do not poll in a loop. When a lane reaches a terminal status, Ptah records one <agent-lane-completed> signal per lane turn into the session that spawned it. Spawn, get on with your own work, and act when it arrives. The signal carries the agent id, lane, terminal status, exit code, duration, report count, CLI Session ID when available, and one line per declared deliverable.

Act on its verdict, never on the exit code alone:

verdictMeaningDo this
deliveredCompleted (or stopped by Ptah) and every declared deliverable exists and is non-emptyRead the files and verify the content (§6)
no-deliverableEnded WITHOUT writing every declared deliverableTreat the task as not done. Read the output, then resume per §5 naming the missing paths. Never report the lane as complete
failedTerminal failure, timeout, a lane you stopped, or a usage-limit/auth stop without a completion claimRecover per §5
unverifiedCompleted (or stopped by Ptah), but nothing was declared, so nothing was checkedRead the output and verify it. Declare deliverables next time

A stopped lane carries stopReason, including repeat-call, usage-limit, or auth when detected, plus a reset time when known. A usage-limit stop without a completion claim has verdict failed even if a skeleton deliverable exists.

The <agent-lane-completed> signal is the wake. Completion and report envelopes may remain pending in a bounded in-memory store until parent activity or session-id resolution drains them. Retries use stable IDs and are idempotent after a successful send. After the signal arrives, read status and output with ptah_agent_status({ agentId }) and ptah_agent_read({ agentId }), then verify the declared deliverables' contents. A missing or empty file is not complete. If push is unavailable (for example, no live spawning session, no parent session, or no chat runtime), make one status/read check. If it reports running, continue other independent work and re-check with at most 5 status checks per lane, at least 60 s apart. Do not use a tight loop, timer, or watcher. If the fifth check still reports running, stop waiting: tell the user the lane is still running (include its agent ID and lane) and end the turn, or, if it has clearly exceeded its expected duration, use ptah_agent_stop and recover per §5 as a non-limit timeout, never as a usage limit. For a verdict other than delivered, read the output and recover per §5.

A message queued with ptah_agent_message runs as a new turn after the preceding turn settles and can change the deliverable again. A later signal from the same agent supersedes an earlier one. Do not start review of a deliverable while a queued message for that lane is pending; wait for that turn's signal, then read and verify the final file.

Status is one of running, completed, failed, timeout, stopped.

  • Concurrency: at most 3 lanes in flight by default. Wider only when the workflow allows it and the user agreed to the added cost. Queue the rest and spawn as slots free.
  • Parallel lanes must be independent and file-disjoint, or each gets its own worktree.

5. Recover

Classify terminal evidence as quota/usage-limit, auth, crash, timeout, bad/missing output, or unknown. After a possible limit failure, read that lane's ptah_agent_list row and its own output. The readable limit signal is the row's AT LIMIT state with a reset time or reset unknown, together with the lane's output. Never infer a limit from timeout, capacity, or a missing deliverable.

On a confirmed limit, record the lane ID (cli or ptahCliId), family, cause, and row's reset time or reset unknown in this run's context.md. Key exhaustion by lane, not agentId: a resumed lane gets a new agent ID. Do not force-spawn. Choose fallback in this order: other family same capability → same family other provider/model → subagent with a Subagent reason. Skip a known-reset lane until its limit clears. For reset unknown, skip that lane for the rest of this run; re-check with ptah_agent_list only at the next Gate 0.1 or on user request. A fresh list row with confirmed room overrides the exhausted entry.

For a non-limit failure, resume once when ptah_agent_status supplies a CLI Session ID and there is useful work to continue: spawn on the same lane with resume_session_id and a specific continuation task. Otherwise respawn once with a narrower, self-contained task; an ephemeral adapter needs the context restated. Name missing deliverables and missed items explicitly. After two non-limit failures on that lane, choose the next eligible lane, then a subagent with a Subagent reason if no lane is eligible. Report the fallback, cause, and reset time or reset unknown when a limit was involved. Never silently replace a user pin: disclose that its lane is unavailable and get direction before using another executor.

6. Verify and revise

Lane output is evidence, not proof.

OutputBefore you use it
Research, surveys, summariesSpot-check claims against the code
Scaffolding, stubsRead it in full — only the files the lane edited
Decision artifacts (spec, design, plan)A proposal, not a decision. Diff every rule against the user's request; tag rules user-requested / project-rule / lane-proposed, and list only lane-proposed rules under ## Lane-introduced constraints. Project rules keep their project-rule tag and cite their source where they appear; do not list them as lane-introduced. A Document gates review (below) runs first; then orchestration Gate 1, 1.7 or 2 approves the artifact before any lane builds from it — the reviewer in lane-review mode, the user in user mode or on escalation.
Code that deletes, replaces or consolidates a surfaceCheck the supplied preserve list or parity-inventory.md item by item; a missing, unapproved capability blocks the batch. Proposed removals require explicit user approval before the batch is accepted.
UI codeTypecheck/test/lint are not proof. Require visual-reviewer screenshots in dark + light themes, compared with the approved prototype (or — for a UI change with no added/redesigned surface and so no prototype — before/after screenshots of the affected screen, the "before" taken from the base commit before the fix lands) and shown to the user before merge.
Code that will shipIndependent review by a different family under Shipping code (below), recorded in code-logic-review.md under the code-review role's own verdict contract. Write-path trace: when persisted settings/config/storage writes change, trace each write to its runtime reader (key, scope, value format, side effects such as env vars); confirm behaviour is unchanged or intended.
  • Document gates: Decision artifacts (task-description.md, design-spec.md + prototype/, implementation-plan.md) use an independent opposite-execution-side reviewer. Side means in-process (orchestrator or subagent) versus CLI lane. The author never reviews its own work; an in-process author uses a CLI lane and a CLI author uses an in-process reviewer. If the opposite side is unavailable, lanes are disabled at Gate 0.1, or the user pins a same-side reviewer, disclose the reason and use an independent same-side reviewer, preferring another family unless pinned. Never silently replace a pinned reviewer. Document reviews write <artifact-stem>-review.md (APPROVED / REVISE); an existing eligible review is not duplicated. An approving opposite-side review passes Gate 1/1.7/2 in lane-review mode; a same-side review goes to the user rather than approving the gate. REVISE at the cap goes to the user; a proposed removal goes to the user. Keep the document verdict and orchestration agent-catalog.md / checkpoints.md § Approval mode protocol. If no independent reviewer can run, report the blocker; never claim a review.
  • Shipping code: Use an independent code reviewer from a different family than the implementer, regardless of execution side; keep the code-logic-review.md verdict contract. Family is the lane's cli value or ptah-cli provider token (§1), or the in-process model family. The Review family record names the actual reviewer family alongside the implementer family. The author never reviews its own work. A same-family review requires a specific reason and a weaker-evidence label. An in-process subagent reviewing code by an in-process subagent of the same family also requires both. If no eligible lane can review, use an independent subagent only with the same specific reason and weaker-evidence label. Never silently replace a pinned reviewer; if no independent reviewer can run, report the blocker and never claim a review.
  • Defects go back to the original lane (resume per §5) as a numbered list, each with file:line. Drop any defect without a location before relaying it.
  • Revise cap: at most 2 revise rounds (author/reviewer revision pairs) after the initial review; announce it first. At exhaustion, a document goes to the user with every open item, in either approval mode. For code, report the open defects or make ONE bounded correction, then have the changed code independently reviewed; if that review finds defects, report them and stop — never reset the cap or claim completion.
  • Code checks are the project's typecheck, tests and lint; UI also needs rendered evidence. A lane's PASS is an opinion; run them — scoped to the projects the lane changed (npx nx run-many -t typecheck,test,lint -p <project>), never workspace-wide. Tail or filter the output; never paste a full log into the thread.

7. Talk to a live lane

ptah_agent_message({ agentId, message, delivery: 'queue' | 'now' | 'steer' }) returns a receipt ID and the planned mode. Default queue waits for the next turn; an idle live lane may start-turn. now steers when the effective handle supports it. Otherwise interrupt and resume requires allowPartialTurnLoss: true after previewing the loss. Legacy steer requires live steering. Always branch on mode:

modeMeaning
steerInjected into the turn in flight
start-turnStarted a turn on an idle live lane
queue-next-turnHeld and delivered as the next turn
interrupt-resumeThe turn in flight was aborted and its partial work discarded
unsupportedNothing delivered; detail says why — fall back to §5

ptah_agent_list shows potential support from adapter manifests; a live lane resolves effective capabilities from its handle. Read the row and preview before Send. An accepted receipt is not settled: ptah_agent_message_status({ agentId, messageId }) returns accepted, started, settled, failed, expired, or interrupted-undelivered. Only receipt metadata survives a host restart; queued bodies live in memory. Missing or aged IDs return expired, and nonterminal receipts fail on restart. Do not interrupt a lane mid-edit to add a minor note. On a ptah-cli lane the message is echoed into that lane's own output, which is how you confirm it arrived. A lane's ptah_agent_report can return delivered: false; a report is attribution, not authentication — verify its claims against files and tests. The same rule applies to the completion signal: it is evidence a file exists, never evidence the content is right. OpenCode binds a lane to its own session; session-mismatch means it refused another conversation's events. Treat it as a failed lane and inspect the output before any resume.

The lane does not need this section, or a Ptah tool table, repeated in its task. Child-side sources of truth:

  • PTAH_LANE_POLICY (libs/backend/cli-agent-runtime/src/lib/cli-agents/cli-adapters/cli-adapter.utils.ts), on each CLI's strongest channel (canary Lane policy id: …).
  • TWO_WAY_MESSAGING_GUIDANCE (same file), only when that spawn has an MCP port and an agent id. Branch on the returned mode. Do not treat a messaging mode as available.
  • renderLaneCompletionContract (libs/backend/cli-agent-runtime/src/lib/cli-agents/lane-reporting-contract.ts), on every lane.

This section and the parent-side guidance in ptah-core-prompt.ts must agree with those three. ptah_agent_list is still what says whether a mode exists on this run.

8. Cost

Every spawn, resume, message turn and review round is a real paid call. Before spending, announce the lanes, the number of rounds and the resulting call count — including required document reviews: one initial review per artifact plus up to two author/reviewer pairs.

Inside a lane, cost ≈ requests × context: every tool call is one request that resends the whole thread, so a lane's bill grows with its call count times its accumulated context. Measured over 7 days of Codex lanes: 68 requests per session at an average 115k-token context, 29% of them polling, and 1.23 billion input tokens in total.

  • There is no tool-call ceiling. The vendor CLIs manage their own context, and a call count says little about cost (most of the input is cheap cache reads). Ptah stops a lane only when it repeats one identical call in a loop (laneRepeatCallStopAt, default 20). Do not state a call budget in task.
  • Bound cost by scope instead: split work by files and deliverables, not by call count. One lane per batch-sized scope; a larger phase is several sequential lanes, each with its own file list.
  • Give the lane its file list up front (files plus absolute paths in task) so it edits instead of exploring. Exploration is the calls you pay for twice — once to search, once as context.
  • A lane whose context balloons from a log or a whole-file read pays that context on every call after; the scoped-verification and tail rules in §6 apply inside the lane too.

9. Agent sessions (ptah_session_*)

A child session is a chat session in its own git worktree on a new branch. It opens as a tab in the user's window, and the user can read and type in that tab as well. It is not a CLI lane: it has no process to resume (§5), and it never exits, it goes idle. Use a lane for a bounded task on a vendor CLI; use a child session when the work needs the full chat runtime, slash commands such as /orchestrate TASK_…, or a branch the user can open and review.

ToolUse
ptah_session_start({ task, branch, … })Create the worktree and branch, open the tab, run task
ptah_session_send({ sessionId, message, mode? })Steer. queue (default), steer (interrupts the turn in flight), if-idle (refused as busy otherwise)
ptah_session_status({ sessionId? })State of one or all of your children
ptah_session_read({ sessionId, tailKiB? })Tail of the child's transcript (default 32 KiB, max 256)
ptah_session_stop({ sessionId })Stop it; tab, transcript, worktree and branch remain
  • Messaging first. Steer with ptah_session_send; use ptah_session_read to inspect. Do not poll ptah_session_status while a completion turn is due: one is pushed into your session each time a child settles, as <agent-lane-completed … cli="ptah-session" …>, with a verdict of delivered, no-deliverable, unverified or failed. Verify the deliverables yourself; a file existing is not proof its content is right.
  • Call ptah_session_status after a resume. Children keep running while you are not live and a completion that arrived then is held, not lost. Every ptah_session_* result ends with those held completions under "Held while this session was not live". A child's ptah_agent_report while you are not live is refused and counted, not queued.
  • Permissions. There is no permission, path or parent argument. The child starts at your session's autopilot level as it is at ptah_session_start. In full autopilot (YOLO) it runs without prompts. At any other level, file edits inside the worktree and allowlisted Bash commands run without asking; anything else waits in the child's tab for the user, then is denied (ptah_session_status shows awaiting-permission with the denial time). Plan mode is not inherited: a planning parent's child starts at Ask.
  • Limits. At most 3 live children per host by default, depth 1 (a child cannot start sessions). An idle child still holds its slot until ptah_session_stop. A refusal is returned as text with a code (cap-reached, depth-exceeded, branch-exists, …); act on it, do not retry blindly.
  • The user owns the result. The worktree and the branch remain after the child ends. Never merge, push or clean up on the user's behalf.
  • Hosts. Child sessions need the chat runtime and the Ptah MCP server. In a host without the session spawner the tools fail with an error that says so.
  • Reports. A child reports with ptah_agent_report; it arrives as <agent-report … cli="ptah-session">, the same envelope a lane's report uses.

Settings, limits and the full tool reference: the "Agent Sessions" page in the Ptah docs.

Requires

  • skill-creator — the prompt-authoring rubric this skill points authors to. If it is not installed, tell the user to enable it; do not improvise a rubric.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.