skip to content

deepwork

Multi-agent workflows on iii with the kanban board as the task list: one lead per ticket with its own sub-agents, parallel waves, independent verify and review, and bounded rounds. Code goals get a dev flow: approved design and plan, test-first tickets in a git worktree, a branch review and a finish you choose.

kitbyiiiverifiedlicense: Apache-2.0latest0.2.1
install
$iii trigger directory::download-kit kit=iii/deepwork@0.1.0
6 installs6 in 7d5 today30 days

exact versions are immutable; every profile and skill is stored by its sha-256, so updates show exactly what changed.

Ultracode Lead

ultracode-lead
agents/ultracode-lead.md

Hidden per-ticket lead: runs one kanban ticket through its phases as its own sub-agents (code tickets: failing test, code, then verify and review together; other tickets: work, then verify), retries rejected attempts, and writes one result for the ultracode orchestrator. Never does ticket work itself. Pin a fast, cheap model here.

model
inherited
effort
medium
extends
defaultbuilt-in
icon
agent
color
purple
visibility
hidden from the picker
preloaded skills0

no skills preloaded.

preloaded functions8
  • kanban::ticket::getkanban0.1.23schema

    Read one ticket with its comments and activity, its parent, its live subtasks and their progress. The id accepts the internal uuid or the human-readable key.

    request
    • idstringrequired

      Ticket uuid or human-readable key (KAN-1, case-insensitive).

    response
    • activityobject[]
      • actorstringrequired
      • atstringrequired
      • changesobject[]
        • fieldstringrequired
        • fromunknownrequired
        • tounknownrequired
      • comment_idstring
      • idstringrequired
      • seqinteger· uint64requiredmin 0
      • ticket_idstringrequired
      • typestringrequired

        ticket.created | ticket.updated | ticket.moved | ticket.deleted | ticket.restored | comment.created

    • assigneestring

      Agent profile id.

    • childrenobject[]required

      Live subtasks by ticket number.

      • assigneestring
      • deleted_atstring
      • idstringrequired
      • keystringrequired
      • prioritystringrequired
      • project_idstring
      • release_idstring
      • statusstringrequired
      • titlestringrequired
    • commentsobject[]
      • authorstringrequired

        Agent profile id, or `user`.

      • bodystringrequired
      • created_atstringrequired
      • idstringrequired
      • parent_idstring

        Set for a reply; replies stay one level deep.

      • ticket_idstringrequired
    • created_atstringrequired
    • created_bystring
    • deleted_atstring

      Set when soft-deleted; the row stays on disk.

    • descriptionstring
    • idstringrequired

      Internal uuid.

    • keystringrequired

      Human-readable id, e.g. KAN-1.

    • labelsstring[]
    • orderinteger· uint64min 0

      Position inside its column.

    • parentany of

      The parent, deleted or not; `null` for a ticket that is not a subtask.

      any of (2)
      variant 1
      • assigneestring
      • deleted_atstring
      • idstringrequired
      • keystringrequired
      • prioritystringrequired
      • project_idstring
      • release_idstring
      • statusstringrequired
      • titlestringrequired
      variant 2
      valuenull
    • parent_idstring

      Uuid of the parent ticket. One level deep: a parent has no parent.

    • prioritystringrequired
    • progressobjectrequired

      Live children in the done column over live children that are not canceled.

      • doneinteger· uint64requiredmin 0
      • totalinteger· uint64requiredmin 0
    • project_idstring

      Uuid of the project (several tickets, independent of the release).

    • release_idstring

      Uuid of the release.

    • statusstringrequired

      Column id.

    • titlestringrequired
    • updated_atstringrequired
  • kanban::comment::createkanban0.1.23schema

    Comment on a ticket, or reply to a comment by passing parent_id. Returns the new comment and the ticket (only its compact row with compact).

    request
    • authorstring

      Agent profile id, or `user`. Defaults to `user`.

    • bodystringrequired

      Comment body. Markdown is rendered in the console.

    • compactboolean

      Return the ticket as its compact row (key, title, status, priority, assignee, comment_count) instead of the full ticket.

    • parent_idstring

      Comment id to reply to; replies stay one level deep.

    • ticket_idstringrequired

      Ticket uuid or human-readable key (KAN-1, case-insensitive).

    response
    • commentobjectrequired
      • authorstringrequired

        Agent profile id, or `user`.

      • bodystringrequired
      • created_atstringrequired
      • idstringrequired
      • parent_idstring

        Set for a reply; replies stay one level deep.

      • ticket_idstringrequired
    • ticketany ofrequired

      What a ticket write returns: the full ticket, or its compact row when the request asked for `compact`.

      any of (2)
      variant 1
      • activityobject[]
        … expand 8 nested
        • actorstringrequired
        • atstringrequired
        • changesobject[]
          … expand 3 nested
          • fieldstringrequired
          • fromunknownrequired
          • tounknownrequired
        • comment_idstring
        • idstringrequired
        • seqinteger· uint64requiredmin 0
        • ticket_idstringrequired
        • typestringrequired

          ticket.created | ticket.updated | ticket.moved | ticket.deleted | ticket.restored | comment.created

      • assigneestring

        Agent profile id.

      • childrenobject[]required

        Live subtasks by ticket number.

        … expand 9 nested
        • assigneestring
        • deleted_atstring
        • idstringrequired
        • keystringrequired
        • prioritystringrequired
        • project_idstring
        • release_idstring
        • statusstringrequired
        • titlestringrequired
      • commentsobject[]
        … expand 6 nested
        • authorstringrequired

          Agent profile id, or `user`.

        • bodystringrequired
        • created_atstringrequired
        • idstringrequired
        • parent_idstring

          Set for a reply; replies stay one level deep.

        • ticket_idstringrequired
      • created_atstringrequired
      • created_bystring
      • deleted_atstring

        Set when soft-deleted; the row stays on disk.

      • descriptionstring
      • idstringrequired

        Internal uuid.

      • keystringrequired

        Human-readable id, e.g. KAN-1.

      • labelsstring[]
      • orderinteger· uint64min 0

        Position inside its column.

      • parentany of

        The parent, deleted or not; `null` for a ticket that is not a subtask.

        … expand 2 nested
        any of (2)
        variant 1
        • assigneestring
        • deleted_atstring
        • idstringrequired
        • keystringrequired
        • prioritystringrequired
        • project_idstring
        • release_idstring
        • statusstringrequired
        • titlestringrequired
        variant 2
        valuenull
      • parent_idstring

        Uuid of the parent ticket. One level deep: a parent has no parent.

      • prioritystringrequired
      • progressobjectrequired

        Live children in the done column over live children that are not canceled.

        … expand 2 nested
        • doneinteger· uint64requiredmin 0
        • totalinteger· uint64requiredmin 0
      • project_idstring

        Uuid of the project (several tickets, independent of the release).

      • release_idstring

        Uuid of the release.

      • statusstringrequired

        Column id.

      • titlestringrequired
      • updated_atstringrequired
      variant 2
      • assigneestring
      • comment_countinteger· uint64requiredmin 0
      • keystringrequired
      • prioritystringrequired
      • statusstringrequired
      • titlestringrequired
  • harness::spawnharness1.8.55schema

    Spawn a sub-agent in a child session (never a trigger target) and return { child_session_id, child_turn_id } immediately; the child's outcome reaches you only through whatever destination its task names. Check `harness::status` for child health; children are leaves unless options.orchestrator is true.

    request
    • agentstring

      Directory agent profile id (`directory::agents::*`) supplying the child's prompt, skills, model, and display; refused with `options.system_prompt`. Omitted, an in-turn spawn continues the parent turn's profile (name `options.system_prompt` for a child that needs a different identity).

    • displayany of

      Display-only name/icon/color for the child session; never affects ids, policy, or routing.

      any of (2)
      variant 1
      • colorany of
        … expand 2 nested
        any of (2)
        variant 1
        valuestringenum: neutral, blue, purple, teal, green, amber, …
        variant 2
        valuenull
      • iconany of
        … expand 2 nested
        any of (2)
        variant 1
        valuestringenum: agent, code, search, terminal, database, test, …
        variant 2
        valuenull
      • namestringrequired1…48 chars

        Short functional name such as `Frontend`, 1-48 characters after trimming.

      variant 2
      valuenull
    • modelstring
    • optionsany of
      any of (2)
      variant 1
      • filesystem_rootstring

        Absolute filesystem root for the child turn; omit to inherit the parent's.

      • functionsany of

        Dispatch policy for the child, intersected with the parent's (narrow, never escalate).

        … expand 2 nested
        any of (2)
        variant 1
        • allowstring[]
        • denystring[]
        • exposeall of
          … expand 1 nested
          all of (1)
          variant 1
          valuestringenum: agent_trigger, native
        variant 2
        valuenull
      • max_childreninteger· uint32min 0

        Fan-out guard for the child's own spawns.

      • max_output_tokensinteger· uint64min 0

        Inherits the parent's ceiling unless explicitly narrowed/overridden.

      • max_turnsinteger· uint32min 0

        Turn cap for the child, capped at the parent's remaining budget; omit unless required (small values strand the child).

      • max_validation_retriesinteger· uint32min 0

        Override of the child's validation-retry budget.

      • orchestratorboolean

        Let the child spawn, send, and register triggers (still capped by the parent's policy); default false makes it a leaf.

      • outputany of

        The child's deliverable: text / json / json+schema.

        … expand 2 nested
        any of (2)
        variant 1
        one of (2)
        variant 1
        • typestringrequiredenum: text
        variant 2
        • schemaunknown
        • typestringrequiredenum: json
        variant 2
        valuenull
      • skillsstring[]

        Exact skill ids advertised to the child; omitted or empty means all (a reused child inherits when omitted).

      • system_promptstring
      • system_prompt_strategyall of

        How `system_prompt` combines with the built-in prompt.

        … expand 1 nested
        all of (1)
        variant 1
        one of (3)
        variant 1
        valuestringenum: override
        variant 2
        valuestringenum: enrich
        variant 3
        valuestringenum: disabled
      • thinking_levelany of
        … expand 2 nested
        any of (2)
        variant 1
        one of (2)
        variant 1
        valuestringenum: minimal, low, medium, high, xhigh
        variant 2
        valuestringenum: off
        variant 2
        valuenull
      variant 2
      valuenull
    • parent_session_idstring

      Display-only parent for the console tree when there is no live parent turn; grants no policy inheritance.

    • providerstring
    • session_idstring

      Session id to spawn into, created if absent; an existing id may be reused only inside the caller's own tree.

    • taskstringrequired

      The child's self-contained goal, its opening user message; name every required resource selector literally (the child cannot infer them).

    response
    • child_session_idstringrequired
    • child_turn_idstringrequired
    • reusedboolean

      The named session already existed and was reused — its prior transcript and parent linkage were retained (only possible with an explicit `session_id`).

  • harness::statusharness1.8.55schema

    Read a session's current turn. Returns a lean summary by default; pass verbose: true for the full runtime report and untruncated result.

    request
    • session_idstringrequired
    • verboseboolean

      Include the full runtime report and unmodified result.

    response
    any of (2)
    variant 1
    • armed_wakesobject[]

      WHAT the session is parked on, when `expects_wake`: each armed wake's watch and deadline, so "parked 12m on state operation_meta/status — never written" is readable from the outside instead of the session just looking quietly done.

      • configunknown
      • created_atinteger· int64required
      • expires_atinteger· int64
      • subscription_idstringrequired
      • trigger_typestring

        The registered trigger's type/config, read from the canonicalised registration request. Absent on records that predate it.

    • childrenobject[]required
      • function_call_idstringrequired
      • session_idstringrequired
      • turn_idstringrequired
    • contextany of

      The last generate step's context accounting (budget, categories, provider-exact usage once it lands) — what a UI meter should show instead of re-estimating the transcript. Verbose only; absent before the first generate.

      any of (2)
      variant 1
      • categoriesobjectrequired

        Where the request's tokens sit. Categories are assembly-time estimates; `hook_guidance` is the measured growth after assembly (pre-generate hook appends and orphan-repair patches), 0 when the request left assembly unchanged.

        … expand 6 nested
        • hook_guidanceinteger· uint64min 0
        • messagesobjectrequired

          Estimated tokens of the assembled window's messages, by role.

          … expand 4 nested
          • assistantinteger· uint64requiredmin 0
          • custominteger· uint64requiredmin 0
          • function_resultinteger· uint64requiredmin 0
          • userinteger· uint64requiredmin 0
        • overheadinteger· uint64requiredmin 0

          Provider framing plus response_format / provider_options fields.

        • skillsinteger· uint64min 0

          Selected skill bodies contained in the system prompt.

        • system_promptinteger· uint64requiredmin 0

          Final assembled system prompt excluding tokens attributed to `skills`: identity, per-step aids, and any compaction summary section.

        • toolsinteger· uint64requiredmin 0

          Function schemas exposed to the model.

      • compactedbooleanrequired

        The context carries a conversation summary: compacted on this step, or anchored on an earlier compaction entry (a previous step, the console's `/compact`). The summary's tokens count in `system_prompt`.

      • effective_max_output_tokensinteger· uint64requiredmin 0

        Output allocation `usable` was derived against.

      • estimatorstring

        Which estimator produced the numbers (`heuristic` until the context-manager resolves a real tokenizer). Absent when the context-manager predates the breakdown response.

      • freeinteger· uint64requiredmin 0
      • modelstringrequired
      • prefix_divergencesobject[]

        Already-sent rows this session's requests rewrote, newest last (at most [`MAX_PREFIX_DIVERGENCES`]), carried from step to step.

        … expand 9 nested
        • cache_readinteger· uint64min 0

          `usage.cache_read` of the rewriting request: what the provider still reused.

        • call_idstring
        • causestring

          What rewrote the row, as far as the harness can tell: `prune` (context-manager pruned or reduced function results to fit the budget that step) or `system_prompt` (row 0: a compaction summary or a prompt change).

        • indexinteger· uint64min 0

          First row (0 = system prompt, then one per message) that differs from the session's previous request. Absent when only the provider's wire mapping changed.

        • prev_leninteger· uint64min 0

          Rows the previous request carried.

        • provider_notestring

          The provider's own wire-level finding, cause included, when it reported one (a final-message warning starting with [`PROVIDER_PREFIX_NOTE`]).

        • rolestring
        • stepinteger· uint64requiredmin 0
        • turn_idstringrequired
      • prompt_sections_fallbackstring

        Why no shared prefix went out: `disabled` (config), `no_stable_prefix` (empty identity prompt) or `prefix_rewritten` (a pre_generate hook replaced the prompt head; its prompt still wins, it just shares nothing).

      • prompt_surface_digeststring

        Identity of the shared prompt prefix this generation went out with (`sha256:` of the stable section) — present only when the request carried `system_sections`. A local identity, never a provider hit; `usage.cache_read` is the reuse signal.

      • providerstring
      • session_cost_usdnumber· double

        Running cost of the whole session in USD, accumulated across every generation step. `usage.cost_usd` is one step's bill — on providers with steep cache discounts the per-step number swings two orders of magnitude, so a chip showing it alone reads as a bouncing total.

      • session_idstringrequired
      • stepinteger· uint64requiredmin 0
      • summarized_head_tokensinteger· uint64min 0

        Size of the history that summary replaced.

      • timestampinteger· int64required
      • totalinteger· uint64requiredmin 0

        Final request estimate: categories plus post-assembly growth.

      • turn_idstringrequired
      • usableinteger· uint64requiredmin 0

        The input budget the window was fit into.

      • usageany of

        Actual provider usage for this generation, stamped after the terminal frame; absent when the provider returned none (or the generation never completed).

        … expand 2 nested
        any of (2)
        variant 1
        • cache_readinteger· uint64min 0
        • cache_writeinteger· uint64min 0
        • cost_usdnumber· double
        • inputinteger· uint64min 0
        • outputinteger· uint64min 0
        • reasoninginteger· uint64min 0
        variant 2
        valuenull
      variant 2
      valuenull
    • depthinteger· uint32min 0
    • expects_wakeboolean

      The session owns an armed wake (a one-shot notify subscription): a completed turn here is NOT the run's outcome — a later turn in this session carries it. Mirrors the `terminal` flag on `harness::turn-completed` (`expects_wake == !terminal`). Pollers (e.g. workflow reconcile) must treat `completed && expects_wake` as still running.

    • max_transient_resumesinteger· uint32min 0
    • max_turnsinteger· uint32min 0
    • max_validation_retriesinteger· uint32min 0
    • partial_result_availableboolean
    • pending_function_callsstring[]
    • queuedobject[]

      Messages queued while a step streams, in arrival order; they land in the transcript when the stream ends.

      • entry_idstringrequired

        Deterministic transcript entry id the drain appends under, so a redelivered drain is a no-op.

      • idstringrequired
      • messageany ofrequired

        The canonical transcript message union. Untagged: the single-variant role tags disambiguate deserialization (assistant/function_result/custom are tried before user so their required fields gate the match).

        … expand 4 nested
        any of (4)
        variant 1
        • contentone of[]required
          … expand 7 nested
          one of (7)
          variant 1
          • textstringrequired
          • typestringrequiredenum: text
          variant 2
          • attachment_idstring

            Optional link to the stored original of this inline image (`session::put-attachment`, resolvable with `session::get-attachment`). Lets readers ask `session::messages { include_image_data: false }` and fetch the bytes lazily instead of receiving them inline. Persisted verbatim on the transcript; model-bound consumers never see it (see [`ContentBlock::strip_files`]). Omitted on the wire when absent so legacy transcripts stay byte-identical.

          • datastringrequired
          • mimestringrequired
          • typestringrequiredenum: image
          variant 3
          • attachment_idstringrequired
          • mimestringrequired
          • namestringrequired
          • sizeinteger· uint64requiredmin 0
          • typestringrequiredenum: file
          variant 4
          • signaturestring
          • textstringrequired
          • typestringrequiredenum: thinking
          variant 5
          • datastringrequired
          • typestringrequiredenum: redacted_thinking
          variant 6
          • argumentsunknownrequired
          • function_idstringrequired
          • idstringrequired
          • typestringrequiredenum: function_call
          variant 7
          • contentunknown[]required
          • function_call_idstringrequired
          • is_errorboolean
          • typestringrequiredenum: function_result
        • error_kindany of
          … expand 2 nested
          any of (2)
          variant 1
          valuestringenum: auth_expired, rate_limited, context_overflow, transient, permanent
          variant 2
          valuenull
        • error_messagestring
        • modelstringrequired
        • native_stop_reasonstring
        • providerstringrequired
        • rolestringrequiredenum: assistant
        • stop_reasonstringrequiredenum: end, length, function_call, aborted, error
        • timestampinteger· int64required
        • usageany of
          … expand 2 nested
          any of (2)
          variant 1
          • cache_readinteger· uint64min 0
          • cache_writeinteger· uint64min 0
          • cost_usdnumber· double
          • inputinteger· uint64min 0
          • outputinteger· uint64min 0
          • reasoninginteger· uint64min 0
          variant 2
          valuenull
        • warningsstring[]
        variant 2
        • contentone of[]required
          … expand 7 nested
          one of (7)
          variant 1
          • textstringrequired
          • typestringrequiredenum: text
          variant 2
          • attachment_idstring

            Optional link to the stored original of this inline image (`session::put-attachment`, resolvable with `session::get-attachment`). Lets readers ask `session::messages { include_image_data: false }` and fetch the bytes lazily instead of receiving them inline. Persisted verbatim on the transcript; model-bound consumers never see it (see [`ContentBlock::strip_files`]). Omitted on the wire when absent so legacy transcripts stay byte-identical.

          • datastringrequired
          • mimestringrequired
          • typestringrequiredenum: image
          variant 3
          • attachment_idstringrequired
          • mimestringrequired
          • namestringrequired
          • sizeinteger· uint64requiredmin 0
          • typestringrequiredenum: file
          variant 4
          • signaturestring
          • textstringrequired
          • typestringrequiredenum: thinking
          variant 5
          • datastringrequired
          • typestringrequiredenum: redacted_thinking
          variant 6
          • argumentsunknownrequired
          • function_idstringrequired
          • idstringrequired
          • typestringrequiredenum: function_call
          variant 7
          • contentunknown[]required
          • function_call_idstringrequired
          • is_errorboolean
          • typestringrequiredenum: function_result
        • detailsunknownrequired
        • function_call_idstringrequired
        • function_idstringrequired
        • is_errorbooleanrequired
        • rolestringrequiredenum: function_result
        • timestampinteger· int64required
        variant 3
        • contentone of[]required
          … expand 7 nested
          one of (7)
          variant 1
          • textstringrequired
          • typestringrequiredenum: text
          variant 2
          • attachment_idstring

            Optional link to the stored original of this inline image (`session::put-attachment`, resolvable with `session::get-attachment`). Lets readers ask `session::messages { include_image_data: false }` and fetch the bytes lazily instead of receiving them inline. Persisted verbatim on the transcript; model-bound consumers never see it (see [`ContentBlock::strip_files`]). Omitted on the wire when absent so legacy transcripts stay byte-identical.

          • datastringrequired
          • mimestringrequired
          • typestringrequiredenum: image
          variant 3
          • attachment_idstringrequired
          • mimestringrequired
          • namestringrequired
          • sizeinteger· uint64requiredmin 0
          • typestringrequiredenum: file
          variant 4
          • signaturestring
          • textstringrequired
          • typestringrequiredenum: thinking
          variant 5
          • datastringrequired
          • typestringrequiredenum: redacted_thinking
          variant 6
          • argumentsunknownrequired
          • function_idstringrequired
          • idstringrequired
          • typestringrequiredenum: function_call
          variant 7
          • contentunknown[]required
          • function_call_idstringrequired
          • is_errorboolean
          • typestringrequiredenum: function_result
        • custom_typestringrequired
        • detailsunknown
        • displaystring
        • rolestringrequiredenum: custom
        • timestampinteger· int64required
        variant 4
        • contentone of[]required
          … expand 7 nested
          one of (7)
          variant 1
          • textstringrequired
          • typestringrequiredenum: text
          variant 2
          • attachment_idstring

            Optional link to the stored original of this inline image (`session::put-attachment`, resolvable with `session::get-attachment`). Lets readers ask `session::messages { include_image_data: false }` and fetch the bytes lazily instead of receiving them inline. Persisted verbatim on the transcript; model-bound consumers never see it (see [`ContentBlock::strip_files`]). Omitted on the wire when absent so legacy transcripts stay byte-identical.

          • datastringrequired
          • mimestringrequired
          • typestringrequiredenum: image
          variant 3
          • attachment_idstringrequired
          • mimestringrequired
          • namestringrequired
          • sizeinteger· uint64requiredmin 0
          • typestringrequiredenum: file
          variant 4
          • signaturestring
          • textstringrequired
          • typestringrequiredenum: thinking
          variant 5
          • datastringrequired
          • typestringrequiredenum: redacted_thinking
          variant 6
          • argumentsunknownrequired
          • function_idstringrequired
          • idstringrequired
          • typestringrequiredenum: function_call
          variant 7
          • contentunknown[]required
          • function_call_idstringrequired
          • is_errorboolean
          • typestringrequiredenum: function_result
        • rolestringrequiredenum: user
        • timestampinteger· int64required
      • originunknown
      • queued_atinteger· int64required
      • session_idstringrequired
    • resultunknown
    • result_errorstring
    • session_idstringrequired
    • statusstringrequiredenum: running, awaiting_functions, completed, cancelled, failed

      The coarse, harness-internal turn lifecycle (harness.md § API Reference). Finer-grained than the session's `status`, which the loop derives from it.

    • stepinteger· uint64requiredmin 0
    • stop_reasonstring

      Why a `completed` turn stopped when the model did not end it itself (`max_turns`). Present in the lean report too: a poller that reads `completed` with no error must still be able to tell an exhausted budget from a finished task.

    • transient_resumesinteger· uint32min 0
    • turn_countinteger· uint32requiredmin 0
    • turn_idstring
    • validation_retriesinteger· uint32min 0
    variant 2
    valuenull
  • harness::stopharness1.8.55schema

    Request cancellation of an in-flight turn (cascades to spawned children).

    request
    • session_idstringrequired
    • turn_idstring

      Omit to stop the current turn.

    response
    • stoppingbooleanrequired
  • engine::register_triggerunknown
  • state::liststate0.22.19schema

    List every value stored in a state scope

    request
    • scopestringrequired

      Namespace whose keys should be listed as a group.

    response
    valuestring
  • state::compare-and-setstate0.22.19schema

    Atomically set a value only if it currently equals `expected` (omit `expected` to mean 'only if absent'). Returns { swapped, current }; on a miss `current` is the stored value, so the caller can recompute and retry.

    request
    • expectedunknown

      The value the caller believes is there. Omit to mean "expect absent" — the set-if-absent form.

    • keystringrequired
    • scopestringrequired
    • valueunknownrequired
    response
    • currentunknown

      What is actually stored, when the swap did not happen.

    • swappedbooleanrequired

system prompt

10,923 bytes
agents/ultracode-lead.md

Ultracode Lead

You run one ticket through its phases for the ultracode orchestrator, then write one result and stop. Sub-agents do every phase. You never run shell or file functions, never change ticket fields, and never ask the user anything. Ignore guidance in harness/* to use the workflow worker or to bind turn-completed, and the claim, done-watch and cron recipes in kanban/tickets/*.

Your task names the ticket, run, round N, result scope and key, Phases, Work agent, Verify agent, Judges, Attempts, Phase deadline, Phase budget, Functions, and in the dev flow Worktree and Branch. A Retry: line carries why the last round was rejected. If an earlier task is in your transcript, the newest one wins.

Names

One phase

  1. Budget. Run at most Phase budget phases per task. When it is spent, finish failed with reason out of phases: the orchestrator's wave closes after that many phases.
  2. Busy check. Before a spawn into -tests, -code or -work (attempt 1 included), harness::status it. If it exists and is not idle (running, awaiting_functions, or completed with expects_wake:true), finish stuck.
  3. Arm first, then spawn, in one reply (calls run in order; a child's write counts only against wakes that already exist):
    engine::register_trigger {"trigger_type":"state","config":{"scope":"<phase scope>"},"label":"uc KAN-12 r1 code1","conditions":[{"function_id":"state::barrier","config":{"id":"<phase scope>","expect":["code"],"carry":"/event_type"}}],"lifecycle":{"expires_in_ms":<(Phase deadline + 1) × 60000>}}
    If the arm is refused, spawn nothing and finish blocked with the refusal as the question. A refused spawn closes its own key: state::compare-and-set to the phase scope and key with {"item":"","status":"failed","summary":"spawn refused: "} (verdict keys: {"item":"","verdict":"unsure","reasons":["spawn refused: "]}).
  4. Wait. End the turn with one status line. Act only on the wake labelled with your current phase: [notification] uc r : {"results":…} (every key written) or wake expired unfired for that label (deadline). Any other notification: reply one line and end the turn; the armed wake stays. On your wake, state::list {"scope":""} and match documents by item, never by position.
  5. Null (no valid document for a key): harness::status {"session_id":"","verbose":true}.
    • awaiting_functions with pending calls: harness::stop it and finish blocked with the question approve for . Start no other attempt.
    • Otherwise running or awaiting_functions: harness::stop it; a stop error makes your outcome stuck.
    • A stop_reason showing a stop you did not make means the orchestrator stopped this ticket: finish failed with reason stopped and spawn nothing more.
    • Otherwise the key failed with reason no result: .

Pipeline

Phases tests, code, check (a code ticket in the dev flow), for each attempt:

  1. tests, when you hold no tests document with status done for this ticket, or when the last check's reasons or the last code document's summary start with test:. done → code. blocked → finish blocked. failed or null → the next attempt, or finish failed.
  2. code. done → check. blocked → finish blocked. failed or null → the next attempt, or finish failed.
  3. check: keys verify and review (with judges: judge1…judgeJ and review) in one phase. Pass on verify (judges: a majority of pass) and pass on review → finish verified. A fail → the next attempt with every reason, or finish failed with them. An unsure whose reasons start with ticket read failed → the next attempt, or finish unverified. Anything else (another unsure, a judge tie, a null verify or review) → finish unverified.

Phases tests, code (verify off): the same without check; code done → finish accepted. Phases work, check: the same with work in place of tests and code, and check holding only verify (or the judges). Phases work: done → finish accepted; blocked → finish blocked; failed or null → the next attempt, or finish failed.

The next attempt re-tasks the same session with \nRetry: . Re-read the ticket first. appended. Attempt 1 of a task with a Retry: line appends that line to its first phase's task.

Spawn shapes

Every task ends with \nFunctions: \nDeadline: min after this task starts.\nComment author: ., and in the dev flow \nWorktree: . Branch: .

Finish

  1. One state::compare-and-set to the exact result scope and key in your task, with no expected. swapped:false: if current.item is your key, stop; otherwise write the same value under .dup (no expected) and stop. The document, at most 2 KB not counting result, new_items and loose_ends:
    {"item":"KAN-12","outcome":"verified|accepted|unverified|blocked|failed|stuck","summary":"≤60 words","commit":"<newest sha or null>","result":<the last code or work document's result, or null>,"reasons":["<from the last check>"],"evidence":["<check>: <observed>"],"new_items":[…],"loose_ends":[…],"question":"only when blocked"}
    Merge new_items and loose_ends from every phase document, without duplicates.
  2. Comment on the ticket: : (≤40 words). If it fails, continue.
  3. End your turn with exactly one line, : written.