# Lisa Implement

> This skill should be used for any non-trivial request — features, bugs, stories, epics, spikes, or multi-step tasks. It accepts a ticket URL (Jira, Linear, GitHub), a file path containing a spec, or a plain-text prompt. It assembles an agent team, breaks the work into structured tasks, and manages the full lifecycle from research through implementation, code review, deploy, and empirical verification.

- Skill: `codyswanngt/lisa-implement` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add codyswanngt/lisa-implement`
- Raw SKILL.md: https://api.skillmd.com/api/skills/codyswanngt/lisa-implement/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: codyswanngt (https://skillmd.com/u/codyswanngt)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/codyswanngt/lisa-implement

---


# Implement: $ARGUMENTS

## Routing: `executionEnv` (check this first)

Before anything else — before team orchestration, before reading the input — check `$ARGUMENTS` for an `executionEnv=` parameter.

| Value | What you do |
| --- | --- |
| absent, or `executionEnv=local` | Nothing changes. Continue to team orchestration below. |
| `executionEnv=<surface>` | Invoke `lisa-remote-dispatch` with `$ARGUMENTS`, report what it returns, and **stop**. |

This check comes first because dispatching is the whole job in that case: the remote runs this identical skill from this identical repository, so forming a team locally would duplicate the work you are about to send away.

**Routing only.** `executionEnv` changes *where* the work happens and nothing about *what* happens. Do not vary the lifecycle, the gates, the review obligations, or the evidence requirements based on it. If a behaviour genuinely must differ, encode it here as an explicit branch — never as an unstated assumption in the dispatcher.

`lisa-remote-dispatch` rejects an unknown surface rather than falling back to local. Do not catch that and continue: a silently ignored `executionEnv` runs work locally while the operator believes it went remote, and nothing downstream contradicts that belief.

Dispatch is fire-and-record. It returns a task identifier and exits without polling; that identifier and the recorded ledger entry are the deliverable. Do not wait for the remote task, and do not report the work as complete — report it as dispatched.

## Orchestration: agent team

Implement is a **team-first** flow. Bug, Build, Improve, and Investigate-Only all compose multiple specialists (Reproduce → debug → fix → review → verify). Single-agent mode is not permitted based on task complexity — the only exception is when no team creation or subagent delegation tool is available in the current runtime (see no-team fallback in the paragraph below).

You are "inside an agent team" only if you are yourself a spawned teammate or subagent — you were spawned into a team context, or your context names a team lead you report to. A lead/root session that has previously spawned subagents is still the lead: prior `Agent` calls in the session (e.g., an Intake cycle's bounded scan helpers) do NOT make this a nested flow, and the lead retains full authority to create this flow's team.

If you are NOT inside an agent team by that definition, the very first thing you do is establish team orchestration.

Use the team tool for the current runtime:

- Claude (Claude Code >= 2.1.178, implicit-team model): there is no `TeamCreate` tool — the team forms automatically the moment you spawn your first teammate with the `Agent` tool. That first `Agent` spawn MUST be the bounded **input-resolver** described under "Resolve the input" below — never a builder/implementer that does the whole task inline. Spawning one fat worker satisfies the team-first gate but collapses the flow into the 1-agent ad-hoc fix this skill forbids, and it skips the Roster Decision, which MUST be recorded before any lifecycle, research, implementation, review, or verification specialist is spawned. (On older Claude Code that still exposes `TeamCreate`, that explicit path also works: load it via `ToolSearch` with `query: "select:TeamCreate"`, create the team, then spawn the input-resolver.)
- Codex: do not call `TeamCreate`; Codex does not expose that Claude tool. Use `tool_search` with a query like `multi-agent tools` to load `multi_agent_v1`, then use `multi_agent_v1.spawn_agent` for teammate delegation. Treat the first successful `spawn_agent` call as establishing team orchestration.
- Other runtimes: use the current runtime's tool-discovery mechanism to discover and call the appropriate multi-agent/team tool.

If no team creation or subagent delegation tool is available, explicitly state that team orchestration is unavailable in this runtime, continue as the lead agent, and preserve the workflow's review, verification, and task-tracking obligations locally.

Your only permitted first move is establishing orchestration by spawning the bounded **input-resolver** teammate (Claude: `Agent`; Codex: `multi_agent_v1.spawn_agent`), or declaring the no-team fallback. The initial Claude `Agent` spawn is the only pre-team exception, and for Implement it must be the bounded input-resolver rather than a builder. Apart from that single spawn, do NOT call any of: a second `Agent`/`spawn_agent` for any worker, `TaskCreate`, `Skill` (including `lisa-tracker-read`, `lisa-jira-read-ticket`, `lisa-github-read-issue`), MCP tools (Atlassian / Linear / GitHub / Notion), `Read`, `Write`, `Edit`, `Bash`, `Grep`, `Glob` — until the input-resolver has returned and the Roster Decision has been recorded. Reading the ticket, exploring the code, fetching context — every one of those is a task for the team, not for the lead session before orchestration exists. Doing them inline, or spawning a single worker that does the whole build, is the exact bypass path that produces a 1-agent ad-hoc fix instead of a real team flow.

Note that `lisa-intake` dispatching this skill is NOT the nested case: Intake is a thin dispatcher that creates no team of its own and invokes this skill via the Skill tool in the lead session precisely so this preamble fires — treat an Intake dispatch exactly like a direct invocation and run the full team-first flow above.

If you ARE already inside an agent team by the definition above (you are a teammate that was handed this skill via the Skill tool from within another flow's team), do NOT create a second team — many harnesses reject double-creates — and do NOT collapse the nested flow into a single inline worker. A nested team-first flow must still bring in the specialists it requires by adding them to the existing team, not by doing the work itself:

- **Claude:** teams are flat and only the lead can add named teammates, so do NOT call `Agent` with a `name` from a teammate (the harness rejects it: *"Teammates cannot spawn other teammates — the team roster is flat"*). Send the team lead a message naming the specialist teammate(s) this flow needs, their task assignments, and completion criteria, then coordinate through the shared task list until they finish. An anonymous subagent (`Agent` with `name` omitted) is permitted only for bounded one-shot work whose result returns directly to you — it is not a substitute for the required lifecycle specialists.
- **Codex:** do NOT call `TeamCreate`. If the lead/root agent is addressable (you were given its id/handle), send it a request to `multi_agent_v1.spawn_agent` the specialist agent(s), including each agent's prompt, ownership, and expected result. If no lead handle exists but `spawn_agent` is available to you, spawn only the bounded specialist agent(s) this flow needs, `wait_agent` for their results, and relay those results upward to the parent/lead.

Treat the first successful lead-spawn request (or, on the Codex fallback, the first specialist spawn) as preserving team orchestration. Never satisfy a team-first lifecycle flow by doing all the work inline.

## Resolve the input (first task assigned to the team)

$ARGUMENTS is either a URL/key for an existing work item, a pointer to a file containing the request, or the request in text format. Every form must resolve to exactly one live, claimed tracker leaf and a verified worktree binding before the lead may begin durable work.

The team lead does NOT read the input directly. The first task on the team's plan is "resolve the input" — assigned to a bounded input-resolver teammate, which then:

The input-resolver invokes `lisa-track $ARGUMENTS` and owns its complete resolve -> claim -> bind transaction:

- **Explicit ticket:** call `lisa-tracker-read` against the configured tracker and require a live open/unresolved current-project leaf. **Mismatch guard:** if the ticket format/project does not match the configured tracker (for example, a GitHub URL when `tracker` is `jira`), stop — never auto-translate vendors or trust pasted/stale ticket text. The read captures comments, graph, and metadata, not just the description.
- **Specification file:** read the entire file without offset or limit, preserve it as the resolved input, and follow the plain-text resolution path below.
- **Plain text or file contents:** search the configured project conservatively for open leaves describing the same outcome. Live-validate every candidate through `lisa-tracker-read`; reuse only exactly one high-confidence match. When there is no unique match (zero or ambiguous candidates), synthesize one complete single-repository leaf and invoke `lisa-tracker-write` exactly once with `build_ready: true`, then live-read its canonical returned ref. Never create a thin placeholder, hierarchy, or container.
- **Claim:** invoke `lisa-tracker-claim <canonical-ref>` and require the provider skill's post-read verified `claimed|reused` result. A failed or inaccessible claim blocks the flow.
- **Bind before durable work:** only after the verified claim, run:

  ```bash
  node scripts/lisa-work-item.mjs link <canonical-ref>
  ```

  Require a successful readback of that worktree-local binding. On detached HEAD, `branch: null` is the expected pending binding; after branch creation the mandatory `attach-branch` step below must replace it before any commit. Tracker or binding failure stops the flow; never continue untracked.
- Return the full resolved work-item context plus `tracker_provider`, canonical `work_item_ref`, resolution outcome, claim outcome, and verified binding to the team lead, who then proceeds to roster selection.

The input resolver may perform these tracker and local-binding operations before the Roster Decision because they are the mandatory gate that establishes what work the team is allowed to do. No project source, documentation, plan artifact, branch, or task may be created or changed before this transaction succeeds. Read-only discussion/orientation outside an Implement flow remains exempt per the `tracked-work` rule.

The input resolver is the only teammate that may be spawned before the Roster Decision exists. After it returns the resolved input, do not spawn any lifecycle, research, implementation, review, verification, or learning teammate until the Roster Decision has been recorded.

**Rejection evidence in the claim handoff.** When this flow was dispatched from a build-intake claim that classified the item as a `rejection-reclaim` (per the `rejection-detection` rule), the context bundle carries a **rejection evidence summary** (what was rejected, the defect the QA comment named, the approach named as wrong). The plan MUST explicitly address that rejection evidence and MUST NOT re-propose the specific approach the rejection named as wrong — a bounced item must come back fixed, not re-bounced. `lisa-implement` cannot fetch this itself (it never sees the claim); it consumes what the handoff carries. Absence of rejection evidence never blocks — plan and implement normally.

## Select the agent roster

Before spawning any teammate beyond the bounded input resolver, record a **Roster Decision** artifact. It must enumerate every agent or specialist type exposed by the current runtime's delegation tool and record one line per type:

```text
INCLUDE|EXCLUDE - <agent type> - <one-sentence reason>
```

Review all available agent types listed in the current runtime's delegation options. In Claude, this includes the Task tool's `subagent_type` options: built-in agents such as `Explore` and `general-purpose`, custom agents from `.claude/agents/`, and plugin agents from enabled plugins. In Codex, Cursor, Copilot, agy, OpenCode, or another runtime, use that runtime's tool-discovery and delegation surfaces to enumerate the equivalent available specialists. If the runtime exposes no specialist list, record that explicitly in the Roster Decision and justify the fallback agent type you will use.

Persist the Roster Decision where the flow can be audited later. Prefer task-list metadata `metadata.roster` when a task list exists; otherwise write `${LISA_PROJECT_DIR:-${CLAUDE_PROJECT_DIR:-.}}/.lisa/roster/<work-item-slug>.md` or post the Roster Decision in the plan/tracker artifact the flow is already updating. The later verification/evidence step must reference the recorded artifact; absence of the artifact is a workflow failure.

`<work-item-slug>` is this flow's work-item reference with every character outside `[A-Za-z0-9._-]` replaced by `-` — `SE-490` stays `SE-490`, `CodySwannGT/lisa#3395` becomes `CodySwannGT-lisa-3395`. **One file per work item, never a shared one.** The path used to be the single `.lisa/roster.md`, and two flows running concurrently in one repository both wrote it: the first time each created it, the merge was add/add, which has no common ancestor for git to three-way, so resolution was a coin flip that silently discarded the other flow's roster. Because the file reads as scratch, that discard looked harmless and got done without thought — while the surviving roster belonged to a different flow than the one being audited. A per-work-item path cannot collide, and it matches the per-flow `.lisa/plan-<id>.md` artifacts already written alongside it.

Rosters stay **trackable** — they are the auditable record of who was on a flow, not runtime scratch, which is why `.lisa/` ignores specific runtime filenames rather than the whole directory (CodySwannGT/lisa#1607). Do not add `.lisa/roster/` to `.gitignore`. A repository that already carries a committed `.lisa/roster.md` from before this change keeps it; leave it alone rather than migrating or deleting it, and write this flow's roster to the per-work-item path.

Inclusion is the default. You MUST justify excluding an agent. Every team must include the Explore agent, or the runtime's nearest read-only search/research equivalent; if no equivalent exists, record that gap in the Roster Decision.

Do not spawn a teammate whose agent type is not included in the recorded Roster Decision. `general-purpose` is a fallback, not a default: using it requires an explicit INCLUDE line explaining why no more specific specialist fits or why the runtime exposes no specialist type. If the task changes enough that a different specialist is needed, update the Roster Decision before spawning that teammate.

When deciding the agents to use, consider:
* Before any task is implemented, the agent team must explore the codebase for relevant research (documentation, code, git history, etc) and update each task's `metadata.relevant_documentation` with the findings.
* Each task must be reviewed by the team to make sure their verification passes.
* Each task must have their learnings captured to the ledger by the learner subagent.
* When the work item prescribes an **existing** test as a red-before-green control ("that test must go red once this lands"), the `control-reachability` rule binds the team. Read the item's `[CONTROL: <test-identifier> | reaches: <input-or-field>]` declaration (gate S20) and confirm the named input is in that test's fixture. If the control does not move when the change lands, **do not act on the stopping rule until the cause is established**: the change had no effect (revisit the change) or the fixture never reached the changed path (fix or extend the control — never revert). Prove reachability by execution — a temporary `throw` in the changed block under that one test, or coverage scoped to it — never by reading the fixture. A named control with no reachability declaration is an unvalidated control; treat it as a triage finding, not a pass.

Using the general-purpose agent in Team Lead session, Determine the name of this plan

Using the general-purpose agent in Team Lead session, **determine the base branch from the ticket's target environment, then sync the working branch onto the latest of it before any work** — so implementation always builds on current target-environment code:

1. **Resolve the target environment with durable provenance.** The `## Target Backend Environment` value has this exact grammar: a human-confirmed value is either a bare configured key or `Confirmed: <env>`; automated evidence writes `Inferred: <env> — evidence: <title|body|reproduction|hostname>`; an automated fallback writes `Assumption: <env> — remote default branch <branch>` when the branch maps uniquely, or `Assumption: remote default branch <branch>` when it does not. Human confirmation replaces an automated annotation with the bare configured key or `Confirmed: <env>`. For a legacy bare value created before this grammar, use managed draft markers and current ticket content only — provider edit history is not required or assumed. A managed marker proves automation and requires rewriting to `Inferred:` or `Assumption:`; without a marker provenance is unknown, so the value may be used only when no conflicting evidence exists, and a conflict **stops for confirmation**.
   - A human-confirmed value wins. Otherwise a validated `Inferred:` value is next.
   - Otherwise inspect the human-authored title, body, and reproduction steps for exactly one unambiguous signal: an exact `deploy.branches` key as a complete token, or that key as a complete label in a URL hostname (`staging.<domain>`, `gql.staging.*`). Exclude the entire `Target Backend Environment` section and all other machine-authored metadata/draft blocks from this evidence scan so an `Inferred:` or `Assumption:` annotation can never validate or conflict with itself. Clear evidence may supersede only an `Assumption:` value, never a human-confirmed value.
   - The only normalization is built-in `prod` ↔ `production`, and only when exactly one of those keys exists in `deploy.branches`; normalize to that configured key. No other aliases exist.
   - Never infer from arbitrary branch text, URL paths or query strings, or substrings inside other words or hostname labels. Multiple conflicting signals after normalization **stop** the flow. If there are no signals, resolve the remote default branch (`gh repo view --json defaultBranchRef -q .defaultBranchRef.name`, or `git remote set-head origin -a` then `origin/HEAD`). When it reverse-maps uniquely, write the env-bearing `Assumption:` form; when the reverse-map is not unique, write the branch-only form and continue on the remote default without inventing an environment or blocking solely for that ambiguity. Record the fallback assumption in the plan/tracker artifact.
2. **Map the resolved environment to a base branch** through `.lisa.config.json` `deploy.branches` — the forward direction of the env-keyed `done` resolution. The selected exact configured key must map uniquely, and the mapped branch must exist on the remote. A missing/ambiguous mapping or remote branch **stops** the flow; never guess or silently fall back.
   - **Reconcile the ticket's `## Branch Plan` (`derived-branch-plan` rule).** The rendered plan is derived output, never input: **recompute** it here from current config and the remote — the mapping you just resolved — and compare. Four arms, no fifth:
     - **Match** → proceed.
     - **Legacy (no plan)** → derive it, **write the assumption onto the ticket as a comment**, then proceed. Visible prose plus a dedupe marker, e.g. ``Branch plan derived for this item: branch from `main`, PR into `main` (Target Backend Environment: production via .lisa.config.json deploy.branches).`` followed by `<!-- [lisa-branch-plan] key=<work-item-ref>::<branch> -->` (marker-dedupe on `<work-item-ref>::<branch>`, so a re-claim adds no duplicate; where a vendor cannot host an HTML comment the visible line alone carries it). **No silent guess** — if the comment cannot be written, that is a stop, because proceeding would make the inference invisible.
     - **Conflict with a human-confirmed environment, or with an existing open PR's base** → **stop under the existing confirmation rules** below. A branch plan never overrides the environment and never supplies the confirmation itself.
     - **Stale (config changed since the plan was rendered)** → current config wins: re-render the section onto the ticket, record the change, and never follow the stale plan. Staleness is output falling behind its input, not a conflict to escalate.
   - Exempt work carries no plan and needs none: `runtime_behavior_change = false` (doc-only / config-only / type-only) and containers have no environment to derive from, so **absence of a plan is correct** — never demand or invent one. Read the flag off the item rather than assuming it: `## Target Backend Environment` is rendered on every leaf and carries the declaration (`derived-branch-plan`) — an exact configured environment key means `true`, `None — no runtime behavior change: <doc-only|config-only|type-only>` or `None — container: state rolls up from children` means `false`. An **absent** section is *underivable*, not exempt: derive the flag from the change under implementation, write the declaration onto the item beside the `[lisa-branch-plan]` legacy comment, and proceed. Never read absence as `false` — that is the assumption that made S8/S11/S14/S19 undecidable on a live item.
3. **Establish the feature branch off the latest base, conflict-free:**
   - `git fetch origin`.
   - Already on a feature branch with an **open PR** → reuse it. If the PR's base ≠ the resolved base branch, surface the mismatch and re-target only with confirmation — the ticket's environment is the source of truth.
   - Already on a feature branch with **no open PR** → reuse it; its PR base will be the resolved base branch (do not ask the human — the environment determines it).
   - On an **environment / default branch** → check out a feature branch named for this plan (with the work-item ref prefix, per the linkage rules below) **from `origin/<base>`**.
   - **Sync the feature branch onto the latest `origin/<base>` and resolve any merge conflicts BEFORE starting work.** Both sync lanes are sanctioned in a bound worktree: **rebase** (`git rebase origin/<base>` — the commit hooks validate mid-rebase picks against the rebase head-name, so a work-item binding never wedges a rebase) and **merge** (`git merge origin/<base>` — push validation exempts commits already reachable from the remote default branch, while branch-authored commits stay strictly validated; the exemption needs the local `origin/HEAD` symref, so if a hand-added remote fails push validation on foreign commits, run `git remote set-head origin -a` first). Prefer rebase for a linear history; use merge when rewriting pushed history is undesirable. If a rebase goes wrong before anyone has resolved conflicts, `git rebase --abort` is a safe, allowed recovery; once conflict resolutions exist, the safety net blocks abort to protect them — finish resolving and `git rebase --continue` instead. If the conflicts cannot be resolved cleanly and safely, create a fix task for the agent team (with the conflicting file list and current merge state) and resolve it before implementation begins — never start work on stale or conflicted code.
4. **The PR targets the resolved base branch** — carry it as `target_branch=<base>` into `lisa-git-submit-pr` (Verify flow). `git-submit-pr` always uses a non-closing GitHub issue reference so merge cannot front-run the deploy, remote verification, health check, and terminal `done` label. For a bug fixed on a non-integration environment branch, the current flow is not done until the fix is merged and verified there, then forward cherry-picked down to the integration branch via a linked follow-up.

Every Implement run now has a tracker work item. Preserve its canonical identifier for development linkage unconditionally:

- Capture `tracker_provider` and `work_item_ref` from the tracked input before creating or reusing a branch. Examples: `github` + `CodySwannGT/lisa#614`, `linear` + `ENG-123`, `jira` + `ENG-123`. Missing linkage is a workflow failure, never an optional/no-ticket mode.
- If a new branch is needed and the provider can link branches by identifier, include the identifier in the branch name before the human-readable slug. Linear and JIRA integrations commonly link from branch names; GitHub issue linkage is PR-body driven, but including the issue number in the branch name is still useful. Keep branch names URL-safe, for example `codex/ENG-123-add-checkout-copy` or `codex/614-add-checkout-copy`.
- After the feature branch exists, run `node scripts/lisa-work-item.mjs attach-branch` so the worktree-local binding records the actual branch without treating the branch name as authority.
- Pass the work-item ref and target branch to `lisa-git-submit-pr` when opening or updating the PR, for example `work_item_ref=CodySwannGT/lisa#614 target_branch=<base resolved from the ticket's environment above>` (not hardcoded `main`). The PR workflow owns provider-specific body text and must use non-closing references until terminal native closure after verification.
- After `lisa-git-submit-pr` returns a PR URL, ensure the reverse backlink is present on the source work item by running `lisa-tracker-sync <work_item_ref> pr-ready pr_url=<url> tracker_provider=<provider>`. The sync path must prefer native provider linkage and fall back to one managed `[lisa-pr-link]` comment when native linkage is unavailable or cannot be verified.
- If the provider has no native branch or PR development-linkage surface, the managed `[lisa-pr-link]` fallback is required; never continue without proven ticket-side linkage.

Using the general-purpose agent in Team Lead session, Determine which flow applies:
1. Research -- needs a PRD (no specification exists)
2. Plan -- needs decomposition (specification exists but no work items)
3. Implement -- has a well-defined work item
4. Verify -- has code ready to ship

If Implement, determine the work type:
1. Build (feature, story, task)
2. Fix (bug -- mandatory Reproduce sub-flow before investigation)
3. Improve (refactoring, optimization, coverage improvement)
4. Investigate Only (spike -- no code changes, just findings)

Run the readiness gate check for the selected flow as defined in the `intent-routing` rule (loaded via the lisa plugin). If the gate fails, stop and report what is missing.

IF it is a Fix (bug), execute the Reproduce sub-flow FIRST:
1. Write a failing test that demonstrates the bug (preferred)
2. If a failing test is not possible, write a minimal reproduction script
3. Verify the reproduction is reliable (consistent failure)
4. The reproduction MUST succeed before any investigation or fix attempt begins
5. Examples of reproduction methods:
   1. Write a simple API client and call the offending API
   2. Start the server on localhost and use the Playwright CLI or Chrome DevTools

For any Fix flow, and for any Build flow that changes user-visible behavior, regression coverage is a required deliverable at the highest practical observation level for the reported surface. If the project has a browser, device, or end-to-end harness for that platform (for example Playwright, Maestro, Detox, Cypress, or an equivalent runtime), the task plan and definition of done MUST include a deterministic regression spec against the reported surface, using mocked or seeded data where needed. This is alongside unit or integration coverage, not a substitute for it. For **frontend work** the deliverable is defined by the `bdd-e2e-coverage` rule and has two halves, both landing in this PR: the Gherkin scenario (stable ID, required platforms) added or updated in the project's behavior contract, and aligned automation in the project's configured runner for **every** platform that scenario requires — no runner substitutes for another, because they guard different platforms of the same behavior. The coverage gate must pass and the matrix and burndown be regenerated before the item is done. Cite the rule; do not restate its scenario, waiver, or bootstrap mechanics here.

For work that adds or changes a **UI surface**, the `design-source-of-truth` rule adds a second non-demotable deliverable landing in this same PR: every UI surface the change touches declares where its design came from. Figma is the source of truth, so **prefer sync-back** — if the surface is not in Figma yet and the tool-access preflight proved Figma access, reflect it there and cite the node with `DESIGN-SOURCE: <figma-url>`. Only when the surface genuinely does not belong in the design source (debug affordance, dev-only playground, internal tooling) does it carry the exception marker `DESIGN-SOURCE: none — not in Figma`, ideally with a trailing reason. `scripts/design-source-gate.mjs` decides this deterministically and fails closed on anything it cannot resolve; a FAIL blocks the item exactly as a failing coverage gate does. Host design-system rules (`figma-design-system`, `design-system`, `use-the-design-library`, or the project's equivalent) stay authoritative about *what* to build — this obligation is only about declaring the source. Cite the rule; do not restate its marker grammar, host-precedence, or bootstrap mechanics here.

The `design-value-binding` rule adds a second, orthogonal obligation on the same surfaces: **values come from design variables where a variable system exists.** That contract asks whether the values are *bound*, not whether the source is *declared* — a surface can cite a valid design node and still paint a literal no variable backs. Resolve the regime per axis, block only on the five objectively checkable conditions, and record every value derived in an untyped axis on the work item. `/lisa:design:intake` runs it. Cite the rule; do not restate its conditions, config schema, or comment grammar here.

For work that adds or changes **persistent state**, the `reset-seed-coverage` rule adds a third non-demotable deliverable landing in this same PR: every entity the item introduces or changes is classified in the project's state contract (`fixture-owned` / `preserve` / `derived-rebuild` / `forbidden`) with a reason and an owner, anything `fixture-owned` declares its ownership predicate and is actually swept, and the state-classification check passes. Writing a flow that creates a record and deletes it only on its happy path does NOT satisfy this — that is the leak, not the coverage. Cite the rule; do not restate its policy, waiver, or bootstrap mechanics here.

The team lead may not waive, defer, demote, or phrase this regression spec as "optional", "if cheap", "nice to have", or equivalent. The only permitted exits are:

1. The project genuinely has no end-to-end harness for the affected platform; record the checked locations and that absence in the task metadata, PR, and work-item evidence.
2. A genuine technical blocker prevents adding or executing the spec in this PR; before merge, create a linked build-ready follow-up ticket, reference it from the PR and source work item, and keep the current item blocked or explicitly non-terminal until that follow-up is accepted.

Completion evidence for the regression spec must prove execution, not mere existence. A green CI run is insufficient unless the PR evidence includes a CI log line, reporter output, or equivalent record naming the new spec and showing that it ran and passed. Guard explicitly against `test.skip`, suite-level environment gates, shard filters, and "0 tests" passes.

**Observe the new spec green at least once BEFORE you ship it — ordering matters.** A spec that has never been seen passing anywhere is not regression coverage; it is an untested artifact, and shipping it can break a gate that the current branch does not even run (a spec skipped on the integration branch may be a required gate on the release branch, where it fails for the next author instead of for you). Run it locally first. Only fall back to CI execution proof when local execution is genuinely impossible, and treat that impossibility as a finding to record, not a step to skip.

Two traps make a local run lie, so check both before trusting or blaming a local result:

- **The run may not be testing your code.** Browser harnesses commonly point at a deployed environment unless a CI-only flag is set (for example a Playwright config that defines `webServer` only when `process.env.CI` is set, so a local run silently exercises the deployed app rather than the working tree). A "local pass" obtained this way is a statement about deployed code, and a local failure may be the deployed code failing, not your change. Confirm which artifact is under test before drawing any conclusion.
- **A red local run may not be your spec.** Before concluding that a new spec is broken, run a **known-good sibling spec, unmodified, in the same mode as a control**. If the control also fails, the surface is not exercisable in that environment and the result says nothing about your spec. If the control passes and yours fails, the defect is yours. Running the control is cheap and is the only reliable way to separate "my spec is wrong" from "this harness cannot run here" — asserting either without it produces confident, wrong conclusions in both directions.

When the control shows the surface is not locally exercisable, that is exit 2 below (a genuine technical blocker): ship the spec only with a linked follow-up that names it as unproven and carries the obligation to confirm it, and say plainly in the PR that the spec has never been observed green. Do not describe an unproven spec as regression coverage.

If the required regression spec is still in flight on an auto-merge-enabled PR, pause auto-merge or use an equivalent merge gate until the spec commit is pushed and its execution proof is available. The flow must not allow the PR to merge before this non-demotable deliverable is satisfied or formally blocked through the linked follow-up path above.

Using the general-purpose agent in Team Lead session, determine how you will know that the task is fully complete. Write this as an **effective completion condition** — one an independent verifier could confirm from observed output alone, not from your assertion that it works. A strong condition has:

- **One measurable end state** — a status code, an exit code, a row count, an observable UI state, an empty queue. Not "it looks right" or "the code is correct".
- **A stated proof command that surfaces the evidence** — exactly how the running system is exercised so the result is observable (e.g. `curl … returns 200 with {…}`, "the Playwright run reaches the dashboard", "`SELECT … ` returns the new row"). Quality gates (test/typecheck/lint) do NOT count — they are prerequisites.
- **Constraints that must hold** — anything that must not change on the way there (e.g. "no other endpoint's response changes", "no migration is dropped").

This condition is the contract the Verify flow proves and records in the verification verdict (below); it is what the completion gate checks before the flow may stop.

1. Examples
   1. Direct deploy the changes to dev and then Write a simple API client and call the offending API
   2. Start the server on localhost and then Use the Playwright CLI or Chrome DevTools

Using the general-purpose agent in Team Lead session, run the **tool access preflight** per the `tool-access-gate` rule (loaded via the lisa plugin) before any implementation task is created or started:

1. Enumerate every external tool or system this flow will need — for the implementation itself, for the proof command, and for remote verification (AWS CLI/CloudWatch, Figma, Jam, Sentry, SonarCloud, PostHog, device/browser harnesses, databases, deploy targets, trackers, …). Derive the list from the resolved work item (a linked Figma file, Jam capture, or Sentry issue implies that tool), the acceptance criteria, the testing requirements, and the completion condition above.
2. Prove access to each with its cheapest read-only probe, routing through the matching `*-access` skill where one exists (`integration-access-layer` rule). Tool presence on PATH is not access; a probe failure counts only after exhausting the documented credential sources (project e2e config/fixtures, `.lisa.config.local.json` / env vars, documented work-item credentials).
3. Record the enumeration and probe results in the plan artifact and in each task's `metadata.required_access`.
4. If any required tool fails its probe, do NOT start implementation — follow the break-out protocol in the `tool-access-gate` rule: post an "Access Needed" comment on the work item (plain-English summary, the exact credential/role/env var to grant, the probe that must pass), transition the item to the configured blocked state with the `human_needed` marker, write the verification verdict with `status: "blocked"`, and stop. Working around missing access — substituting weaker verification, mocking the inaccessible system, guessing at tool contents, or narrowing scope — is never permitted, for any tool.

The same gate applies **continuously**: if a tool requirement surfaces mid-flow (e.g. verification turns out to need CloudWatch log capture the runtime cannot authenticate to), probe it the moment it is discovered, record the new tool and probe result in the plan artifact and the affected tasks' `metadata.required_access` before continuing, and break out identically on failure.

Using the general-purpose agent in Team Lead session, create tasks needed to complete the request.

Every task MUST include this JSON metadata block. Do NOT omit `skills` (use `[]` if none), `learnings` (use `[]` if none), `required_access` (use `[]` if the task needs no external tool) or `verification`.

```json
{
  "plan": "<plan-name>",
  "type": "spike|bug|task|epic|story",
  "acceptance_criteria": ["..."],
  "relevant_documentation": "",
  "testing_requirements": ["..."],
  "skills": ["..."],
  "learnings": [{ "kind": "mistake", "note": "one line", "evidence": "optional ref" }],
  "required_access": [
    { "tool": "<external tool/system this task or its verification needs>", "probe": "<the read-only command or *-access check that proves access>", "status": "pass|fail" }
  ],
  "verification": {
    "type": "ui-recording|api-test|cli-test|database-check|manual-check|documentation",
    "command": "the proof command — must run the actual system and surface its result in the transcript (NOT test/typecheck/lint, those are quality gates). Phrase it so an independent verifier sees the evidence, e.g. `curl -s localhost:3000/health` not `check that health works`",
    "expected": "the single measurable end state that proves success — observable system behavior (status code, response body, row count, UI state), not a subjective judgement"
  }
}
```

The `learnings` array is task-end MLD telemetry (Mistakes / Learnings / Desires) — a low-trust self-report for the harness builder, never instructions for a later agent. Each entry is either a plain string (treated as kind `learning` for backward compatibility with older flows) or an object, exactly like the example entry in the block above: a `kind` of `mistake`, `learning`, or `desire`; a one-line `note`; and an optional `evidence` pointer. A `mistake` is an error in the agent's own trajectory, a `learning` is an environment fact discovered the hard way, a `desire` is context or tooling the agent wished it had. Keep each to one line — no essays. `mistake`/`learning` entries are ledger candidates; `desire` entries are tooling-gap candidates that the learner (#1731) records for the gardener's human-gated tooling-gap lane.

Before any task is implemented, the agent team must explore the codebase for relevant research (documentation, code, git history, etc) and update each task's `metadata.relevant_documentation` with the findings.

For Fix tasks and user-visible Build tasks, `testing_requirements` must include the highest-practical-observation regression requirement above, including the selected harness or the recorded absence/blocker path. The completion condition must include the

…(truncated)
