Skip to content

[Skill]: update code-agent — ticket-driven mode (plan-first, then execute) #73

@initializ-mk

Description

@initializ-mk

Skill name

code-agent (update — existing embedded skill)

Description

Update the existing code-agent skill to support ticket-driven mode — a flow where the agent is asked to implement a Linear ticket (or similar) end to end, with planning, file generation, and tests gated by a plan from the code-plan skill (#68 / merged via PR #69).

The current code-agent is built around an "EXECUTE — do NOT describe, plan, or ask" mantra. That is excellent for one-shot scaffolding requests like "build me a todo app" but is actively wrong for ticket-driven work, where reading the ticket, surveying the repo, and producing a plan are the first steps. This update adds a carve-out for ticket-driven mode without weakening the one-shot behaviour for direct user requests.

This is an update, not a rewrite. Tool surface stays identical — no new tools, no signature changes, no script edits.

Execution type

Script-backed (shell scripts in scripts/) — already so today, no change.

Category

developer — unchanged.

Requirements

No new requirements:

  • Binaries: bash, jq — unchanged
  • Env vars: none — unchanged
  • Egress: unchanged
  • timeout_hint: unchanged

Just add ticket-driven to tags.

Tool catalog

Tool Status
code_agent_scaffold, code_agent_write, code_agent_read, code_agent_edit, code_agent_run unchanged — all signatures and behaviours preserved
grep_search, glob_search, directory_tree unchanged
code_plan_create (from code-plan skill) referenced in the new Ticket-Driven Mode section. Not part of this skill — pointer only.

No new tools. No mode parameter added anywhere. Mode is inferred from conversation context.

File changes

Path Action Purpose
forge-skills/local/embedded/code-agent/SKILL.md edit Update tags, modify ABSOLUTE RULES 1/2/3/5 (rules 4/6/7 unchanged), add Ticket-Driven Mode section, add Ticket-Driven Implementation sub-flow, update Safety bullet, add code_plan_create pointer row to Tool Reference
forge-skills/local/embedded/code-agent/scripts/*.sh untouched
Framework templates / scaffolds untouched

Frontmatter change

tags:
  # existing tags preserved
  - ticket-driven

Do not change bins, egress_domains, timeout_hint, or trust_hints.

ABSOLUTE RULES — precise diff

Rules 4, 6, 7 unchanged. Rules 1, 2, 3, 5 modified with ticket-driven carve-outs:

1. **Every response MUST include tool calls OR a structured plan presentation.** A response with only chatty text is a failure. Either call tools, or present a `code_plan_create` result for user review. Never both ramble and stall.

2. **NEVER narrate intent without acting.** \"Let me patch that\" with no tool call is forbidden. Either call the tool, or in ticket-driven mode, call `code_plan_create` and present the plan.

3. **NEVER ask for confirmation on small, reversible actions.** Don't ask \"should I write this file?\" for routine writes. EXCEPTION: in ticket-driven mode, after `code_plan_create` returns `complexity: \"high\"` or non-empty `risks`, present the plan to the user and confirm before writing code. Confirmation on irreversible or contentious decisions is correct, not a violation.

4. **NEVER output code in markdown blocks.** You have file tools. Use them.  ← UNCHANGED

5. **Complete the user's request in as few turns as possible.** For direct user requests (\"build me a todo app\"), scaffold + write all files + run in ONE response. For ticket-driven mode (the task came from `linear_get_issue` or similar), the canonical sequence is: plan → present → confirm if needed → write → test → commit → push → PR. Each step in one turn; do not stall between them with chatter.

6. **ONE project per app...**  ← UNCHANGED

7. **NEVER scaffold over existing code...**  ← UNCHANGED

The framing is critical: the EXECUTE mantra is preserved for direct requests; the carve-out only applies when the LLM has evidence the task is ticket-driven.

New "Ticket-Driven Mode" section

Insert after the existing "Iteration Rules" section and before "Full-Stack Architecture":

## Ticket-Driven Mode

When the current task originated from an external tracker, the one-shot rules above relax in a specific way: **planning is required before code generation.**

### Trigger

You are in ticket-driven mode if ANY of the following is true:
- The conversation began with a `linear_*` or `github_get_issue` tool call returning a ticket.
- The user message contains a clear ticket identifier pattern like `ENG-123`, `BUG-456`, `#789` and asks you to implement it.
- The user paste includes ticket structure (title + description + acceptance criteria).

### Required sequence

1. **Understand the ticket.** Read the description, acceptance criteria, and any linked comments. Note any ambiguity.
2. **Generate a plan.** Call `code_plan_create` with the ticket body as `task` and the repo path as `repo_path`. Pass `ticket_id` for traceability.
3. **Present the plan.** Show the user `summary`, `files_to_create`/`files_to_modify` lists, and any `risks` or `open_questions`. Do NOT write code yet.
4. **Confirm if needed.**
   - If `complexity` is `low` and `risks` and `open_questions` are both empty: proceed without confirmation.
   - Otherwise: wait for user acknowledgment.
   - If the ticket has `open_questions` you cannot resolve from the description, post a comment on the originating ticket (via the appropriate skill) and stop. Do not guess.
5. **Implement.** Use `code_agent_write` and `code_agent_edit` to create/modify only the files listed in the plan. Do not silently add files outside the plan.
6. **Test.** If the repo has a test runner, run the tests. Iterate until they pass or until you can clearly explain a failure.
7. **Commit and PR.** Use the `github` skill — `github_commit``github_push``github_create_pr` with `ticket_id` set so the back-link is added automatically.
8. **Close the loop.** Post a comment on the ticket with the PR URL via the originating tracker's skill.

### Plan adherence

The plan is a contract. If, during implementation, you discover the plan was wrong, **regenerate the plan** rather than silently drifting. Tell the user: \"The plan needs revision because X. Regenerating.\" Then call `code_plan_create` again with the same `task` plus a note about what was wrong.

If you find yourself writing files not in the plan, stop. Either expand the plan and re-present, or you are off-task.

### What this does NOT change

- Direct user requests (\"build a hello-world React app\") still follow the one-shot rules. Do NOT invoke `code_plan_create` for these.
- The framework conventions, full-stack architecture, and scaffold rules are unchanged.
- Tool signatures are unchanged.

Tool Reference table — add pointer row

Add a row at the top of the existing Tool Reference table:

Tool When to Use
code_plan_create (from code-plan skill) First step in ticket-driven mode. Generates a structured plan from a task description + repo. Skip for direct user requests.
code_agent_scaffold Bootstrap a NEW project only (never for existing projects)
... rest unchanged ...

Plus a one-line note below the table:

code_plan_create is from the code-plan skill — install it with forge skills add code-plan if it's not already enabled. In ticket-driven mode the code-plan skill is a hard prerequisite.

One-Shot Workflow — new "Ticket-Driven Implementation" sub-flow

Add a fourth sub-flow after the existing three (New Project / Existing Codebase / Modify Existing):

### Ticket-Driven Implementation

When the user asks you to implement a ticket (Linear, GitHub issue, etc.):
  1. linear_get_issue (or equivalent) → load ticket
  2. github_clone → clone repo, auto-creates feature branch
  3. code_plan_create → generate structured plan
  4. [present plan, confirm if needed]
  5. code_agent_read / directory_tree → orient in the repo (skip if plan covers it)
  6. code_agent_write / code_agent_edit → write the files listed in the plan
  7. code_agent_run → run tests / start server to verify (if applicable)
  8. github_status → review changes
  9. github_commit → commit with conventional message
  10. github_push → push branch
  11. github_create_pr → open PR with ticket back-link
  12. linear_add_comment → post PR URL back on the ticket

Do NOT scaffold a new project in this flow — the repo already exists. Do NOT call `code_agent_scaffold`.

Safety section — bullet fix

Replace the existing "Do not create git commits unless explicitly asked" bullet (which contradicts ticket-driven mode) with:

Do not create git commits unless the request requires them. Direct one-shot scaffolds typically do not commit. Ticket-driven flows always commit and PR — that's the whole point.

Use case (concrete)

User in Slack: "@Forge-Agent implement ENG-742"

  1. Agent → linear_get_issue {\"identifier\":\"ENG-742\"} — title, description, acceptance criteria
  2. Agent detects ticket-driven mode (trigger Add multi-module codebase with CI pipeline #1: conversation began with linear_*)
  3. Agent → github_clone with branch from github_branch_name_from_ticket (PR feat(skills/github): ticket-driven PR creation + branch-name helper (closes #70) #71)
  4. Agent → code_plan_create {\"repo_path\":\"workspace/<dir>\", \"task\":<ticket body>, \"ticket_id\":\"ENG-742\"}
  5. Agent presents summary + files_to_modify + risks to user
  6. User confirms (or risks/open_questions are empty → proceed automatically)
  7. Agent → code_agent_write / code_agent_edit for only the files in the plan
  8. Agent → code_agent_run to verify tests pass
  9. Agent → github_statusgithub_commitgithub_pushgithub_create_pr {\"ticket_id\":\"ENG-742\", \"ticket_url\":...} → auto-suffix + Tracks: footer (PR feat(skills/github): ticket-driven PR creation + branch-name helper (closes #70) #71)
  10. Agent → linear_add_comment {\"identifier\":\"ENG-742\", \"body\":\"PR opened: <url>\"} — one comment, per the linear skill's etiquette

Versus the SAME user saying "build me a todo app" → ticket-driven mode does NOT trigger; agent scaffolds and runs in one turn as today.

Security considerations

  • No new tools, no new env vars, no new egress domains.
  • The carve-out is purely a system-prompt change.
  • The new sequence references linear_add_comment and github_* tools — those skills retain their own guardrails (token redaction, branch safety, etc.).
  • Plan adherence is documented as a contract; the runtime does not enforce it (out of scope), but the LLM is told to regenerate the plan rather than drift silently.

Done criteria

  • Frontmatter tags includes ticket-driven
  • ABSOLUTE RULES 1/2/3/5 updated as documented; 4/6/7 unchanged verbatim
  • New "Ticket-Driven Mode" section present after Iteration Rules and before Full-Stack Architecture
  • New "Ticket-Driven Implementation" sub-flow in One-Shot Workflow
  • Safety bullet about commits updated
  • Tool Reference table has a code_plan_create pointer row + clarifying note that it's from a sibling skill
  • go test ./forge-skills/... passes — no script changes means TestEmbeddedRegistry_DiscoverAll (count 15 today) and TestEmbeddedRegistry_LoadContent still pass without modification
  • shellcheck clean on scripts/*.sh (no script changes, so this should be a no-op)
  • forge build against a test agent with code-agent enabled produces a system prompt containing "Ticket-Driven Mode" — verify via jq '.system_prompt' .forge-output/agent-spec.json | grep -c \"Ticket-Driven Mode\"1
  • Manual: an agent driven from Telegram with a Linear ticket triggers the plan-first flow; a direct "build me a todo app" request still scaffolds in one turn

Anti-patterns (do NOT do)

  • ❌ Delete any of the existing ABSOLUTE RULES — they are modified, not removed
  • ❌ Add a new tool to this skill — out of scope; new planning tools live in code-plan
  • ❌ Rename code_agent_* tools — breaking change
  • ❌ Pull code_plan_create into this skill — lives in code-plan; this skill just references it
  • ❌ Add a mode parameter to any tool — mode is inferred from conversation context, not passed explicitly
  • ❌ Revert the "execute, don't plan" mantra for direct requests — that's still correct for one-shots; the carve-out is only for ticket-driven mode
  • ❌ Add framework-specific planning logic — planning is framework-agnostic and lives in code-plan
  • ❌ Touch scaffold scripts, framework templates, or any code under scripts/
  • ❌ Remove path-traversal protections, Tailwind CDN convention, or any scaffold rules

Out of scope (deferred)

  • Adding new tools to code-agent
  • Changing framework support or adding new frameworks
  • Modifying scaffold templates or scripts
  • Implementing a "plan mode" toggle in forge.yaml
  • Adding telemetry around plan adherence
  • Cross-skill state sharing (conversation history is the only state)
  • Auto-detecting ticket-driven mode from message classification — the LLM infers it from context, as documented

Reference patterns

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions