canary-lab
Use when the user wants Canary Lab to take a product repo end to end — "test this app", "onboard this repo", "run a flight", "evaluate what I just built" — through the flight pipeline (start_flight / get_flight / respond_flight_checkpoint over MCP). One conducted pipeline continues a configured suite or takes bare repo(s) to a green, covered, healed run and publishes a downloadable Report; Parallel setup continues as Canary-owned background work. Use a focused skill only when the user asks for that single capability without asking for a Flight or /canary-lab.
- License 许可
- MIT
- 最近更新
- 2026-11-12
- Stars
- ★ 4
- Forks
- 0
01 前言 Front Matter
- name
- canary-lab
- type
- skill
- description
- Use when the user wants Canary Lab to take a product repo end to end — "test this app", "onboard this repo", "run a flight", "evaluate what I just built" — through the flight pipeline (start_flight / get_flight / respond_flight_checkpoint over MCP). One conducted pipeline continues a configured suite or takes bare repo(s) to a green, covered, healed run and publishes a downloadable Report; Parallel setup continues as Canary-owned background work. Use a focused skill only when the user asks for that single capability without asking for a Flight or /canary-lab.
03 SKILL.md 正文
Canary Lab — Flight
An explicit request for a Flight or /canary-lab always means this pipeline. Do
not reinterpret its desired outcome (for example, "drive coverage to 100%") as
permission to substitute focused author, run, or coverage workflows. For an
existing configured suite, call start_flight(feature, coverage_target); Canary
reads durable stage evidence and continues non-destructively from the first
stage that does not meet the requested target.
User input through MCP 2.0
Use the native Canary connector in the requesting chat so SDK 2.0 elicitation
(input_required) reaches the human there. Do not substitute a shell MCP client,
answer a form yourself, or recreate the question in chat. Existing explicit
instructions and autopilot choices still apply without another ask.
Form decisions have one shared record. The native form links to the same approval
in Canary Notifications, also surfaced above the Flight page. On needs-input
with approvalId and reviewUrl, show that link and call wait_for_approval with
the ID; repeat on still_waiting. The human answers once in either surface.
A browser answer resolves the server decision; some clients keep their native
form visible until the human dismisses it. Dismissal then returns the stored
result. Client decline/cancel alone does not represent a human decision.
Without an approvalId, leave needs-input pending after decline/cancel, stale
input, or an unfinished UI action; do not automatically retry or repeat the
question. Setup/reconnection can use chat while MCP is unavailable. Never collect
passwords, API keys, or access tokens in chat or form elicitation; use the returned
Canary UI URL for secret entry.
MCP Invocation
Read coverageUpdate in related tool replies: it is the suite's current
freshness, revision, owner and next required action. Canary's UI must update
without a manual refresh. Stale/unavailable/updating coverage is historical,
not current; an old passing run cannot hide a newer failure. While actively
monitoring the suite, use wait_for_feature_change(feature, afterRevision, timeout_ms:30000); omit the revision to catch up after reconnecting. Tool replies
deliver this into the agent's context; an idle host is not promised an unsolicited
wake-up. Respect active owners and launch permissions. Resume from the earliest
invalid stage, reuse valid prior stages, and re-read the ledger after recovery.
Setup and the plugin expose one public Canary Lab MCP tool: exec (usually
rendered as mcp__Canary_Lab__exec). Every
Canary Lab tool name below is the exact command value, not a separate public
tool. For a feature-scoped command, replace both placeholders in this shape:
{"command":"<exact_tool_name>","arguments":{"feature":"<feature_name>"}}
This is the envelope shape, not every command's complete schema. Add the
fields that command declares inside arguments; call describe_tool when a
field is uncertain.
Never invent a wrapper verb such as learn or call, embed JSON in a command
string, or turn arguments into flags. Keep fields such as confirm: true inside
arguments. Use list_tools, search_tools, or describe_tool as the
command when discovery is needed. A deliberately selected focused or full
profile still exposes atomic tools for debugging; the setup-installed path is
compact + exec.
The server computes every stage verdict. Start the flight with stage_producer: "external" — the default for any MCP caller, so you get it even without passing it — so this client does every THINKING
step: scout, docs, PRD summary, spec and coverage authoring and mapping,
run healing, and localized evaluation export. The server still handles similarity,
scaffolding, environment capture, the test run, Parallel setup. Pass stage_producer: "internal"
instead only when the user wants a hands-off flight, or when this client cannot do the
work (no file tools, no subagents, permission refused) — and note a single step can
degrade on its own by answering run-internally on its checkpoint, so a whole flight
rarely needs to be internal. See Doing the stage work yourself below. The flight is Canary Lab's
front door: one command/tool takes
one or more bare product repos to a green, healed, covered run that ends in
an evaluation export. These tools arrive via the Canary Lab MCP server. If
this client is already connected (the plugin connects with compact), skip
this step. To configure the same connection manually: npx canary-lab mcp --profile compact.
Workspace Bootstrap
Before calling Canary Lab MCP tools, make sure the workspace and UI server are available.
- Find the LIVE server first: read
~/.canary-lab/active-servers.json. It recordsprojectRoot,portandpidfor every UI that registered. A stopped server's entry LINGERS — the file is only rewritten when the next server registers — so an entry is a candidate, not proof: the health check in step 4 is what confirms it. One entry → that is your server and itsport; several → take the one whoseprojectRootis the workspace the user means. Do NOT start from a guessed port. - Only when nothing live serves the workspace you want, fall back to the user-level registry at
~/.canary-lab/workspaces.json(Windows: resolve from the home directory, e.g.%USERPROFILE%\.canary-lab\workspaces.json). Exactly one workspace → use it. Multiple → ask which, listing eachnameandpath. - If the registry is missing or empty, ask the user to run
npx canary-lab setupfrom the Canary Lab workspace. - Check the MCP health endpoint on the port you found in step 1. Only if no live entry gave you one, read
portfrom the workspace'scanary-lab.config.json(fallback7421). Thencurl -s http://127.0.0.1:<port>/mcp/health— success is a JSON response. If it does not respond, runnpx canary-lab mcp doctorto discover the active URL. - A healthy response does not settle the question on its own — VERIFY
projectRootagainst the workspace you intended. A stale UI left behind by a demo or a tarball smoke test answers a port just as convincingly as the right one, and that is exactly how a flight ends up running in someone's throwaway workspace instead of theirs.projectRootmatches → continue, and tell the user which workspace you are in. It names a DIFFERENT workspace → this is the wrong server: go back to step 1, do not adopt it. It is under a temp directory (/tmp,/private/var/folders,%TEMP%) → never auto-select it; those are throwaway demo workspaces that vanish, so use one only when the user names it explicitly. Only when the user wants a workspace no live server is serving does anything need starting or stopping. - If the health check fails, start
npx canary-lab uifrom the selected workspace in a visible long-running terminal when the host supports that; if this client cannot run long-lived commands, ask the user to runnpx canary-lab uifrom the workspace and confirm when it's up. The port comes fromcanary-lab.config.json(default7421); do not pass--port(it was removed). - Resolve this skill's ARGUMENTS against that workspace before calling any tool. A bare name —
flight-app— is a directory in the workspace root (<workspace>/flight-app); it is not a suite name and not a repo to hunt for elsewhere on the machine. The Getting Started guide emits exactly that shape, with the intent string quoted beside it, so pass the resolved path asrepoPathsand that string asdescription. An absolute path is used as given. If the named directory is not in the workspace, say so and ask — never substitute a similarly-named repo from somewhere else, and never invent the intent. - A healthy
/mcp/healthmeans the server is live. On the setup-installedcompactprofile, atomic names such asget_feature_coverageare deliberately absent fromtools/list; onlyexecis public. Callexecwith{"command":"list_tools","arguments":{}}before concluding the connection is missing. Only an unknown-tool error forexecmeans this session is not connected — ask the user to runnpx canary-lab setup --forceand reconnect/restart the client, then retry. Never drive/mcpwith a hand-written HTTP/JSON-RPC client (curl included; the health check above is the only direct HTTP use): a custom client bypasses client detection and reconnect handling.
Flight (end-to-end pipeline)
If start_flight returns type: "getting_started_busy", a Getting Started demo already owns the workspace. Follow the returned active target (a run, Flight, coverage job, draft, portify, or export) in its current owner; do not start another workflow.
start_flight(repoPaths, description)runs ONE background pipeline from bare repo(s) to a green, covered, healed run that publishes a downloadable Report before Parallel setup (similarity → scout → scaffold → env → docs → PRD → Tests & coverage → Test run → Auto-repair → Report → Parallel setup). Large apps therefore produce both harness evidence and the Report without first waiting for port-injection work. Report completion ends the foreground user journey: as soon asget_flightexposeslinks.evaluationZip, tell the user and end your turn while Canary continues Parallel setup as persistent background work. The server conducts every stage and computes every verdict — you only approve checkpoints; do not run the stages yourself or start a separate run/coverage pass alongside an active flight. A flight started withstage_producer: "external"— the default for any MCP caller, so you get it even without passing it — instead asks you to execute the thinking steps — scout / docs / prd-summary / specs↔coverage / the run's heal loop / a localized export — in-band viaexternal-workcheckpoints (see Doing the stage work yourself). Pass a stablesession_idand usefulconversation_nameso the UI identifies this external agent session; use the client's real session id when available. Passexternal_session_urlonly when it opens this exact conversation. Do not passclient_kind— the MCP bridge detects Claude/Codex from the connection. A Parallel setup workflow already started independently from the Flight page is adopted when the conductor reaches that stage; the Flight never starts a duplicate.- Follow with
get_flight(flightId)and do what itsnext:field says. On a humanwaiting-for-approvalcheckpoint with no answer yet, callrespond_flight_checkpoint(flightId)without a choice to request elicitation. It applies the answer to the reviewed checkpoint. For an already-authorized response, call it withchoice(one ofcheckpoint.options),values(a missing-env KEY→value map), ordata({ configSource }for config-approval — the feature is already scaffolded, so this writes through to its REAL on-disk feature.config.cjs;redraftre-runs the repo scan). Under autopilot (the default) the terminalexport-modecheckpoint answers itself —rawfor an internal flight,localizedfor one started withstage_producer: "external"(the rewrite is thinking, so an external flight does it externally by default; the localized rewrite then arrives as anexternal-workhand-off). A flight started withautopilot: falseparks there to pickraw(fast report) vslocalized(agent-rewritten reasoning) either way. A checkpoint payload over the inline budget is omitted from the tool result — review it in the web UI flight view, then respond here. Anexternal-workpayload is the exception: it degrades topromptPath(pluspromptOmitted: true) rather than being dropped, because the payload IS the task —Readthat file for the full prompt. - Autopilot is ON by default: checkpoints with a safe default answer themselves (config-approval→approve, prd-source→continue when requirement docs already exist and collect-repo-docs when none do, coverage-stuck→accept-partial, portify-gate→run, portify-apply→apply, run-failed→export-as-is, export-mode→raw — or localized when the flight's stage producer is external), each logged
[autopilot]on its stage. The flight still parks onsimilarity-choiceandmissing-env(no safe default) and on any RE-parked checkpoint — including aprd-sourcewhose collector came back empty. A stage you explicitly RE-ENTER (from_stage/redo) always parks its FIRST checkpoint even under autopilot — choosing to re-run a step IS the intent to answer it differently. Start withautopilot: falsewhen you plan to distill THIS conversation into requirement docs at theprd-sourcestop: add them withwrite_feature_doc— distilled from this conversation (content) or linking a local file (link_path, symlinked so the user's original stays live) — then respondcontinue. Write the docs FIRST:continueonly appears incheckpoint.optionsonce requirement docs exist on disk, so answering it on a doc-less park is rejected rather than accepted empty. Or have Canary's agent gather the docs guided by the flight's frozen intent: respondcollect-repo-docs(copies in repo docs relevant to the intent) orinfer-from-diff(derives requirements from the branch diff vs base) — an optionalfeedbackstring on respond_flight_checkpoint rides a retry into the agent's prompt. If the checkpoint'sdata.lastAttemptis present, a previous gather already came back EMPTY (outcome:empty|no-output|no-diff, with the agent's ownreason) — do NOT simply repeat that same choice; the material is not in these repos. Supply the docs yourself, or re-run the agent only withfeedbacknaming what it missed, or after the user points the flight at different repos. A parkedportify-gateis the Parallel setup ask after Report and BEFORE any Portify agent/double-boot cost:runstarts the portify workflow (declared native port injection or a sibling feature's saved overlay is verified first — the agent only runs if verification fails),skipkeeps the feature serial and the flight continues. A parkedportify-applyis a verified-diff review:applysaves the overlay (nothing lands in the product repos — runs apply it into throwaway per-run worktrees),reviseREQUIRESfeedback: "<what to change>"and re-runs the agent + double-boot re-verify (the checkpoint re-parks with the new diff),canceldiscards the edits and SKIPS the stage — the flight continues without Parallel setup (the feature stays serial; a later flight can retry). - ONE flight record per feature — never a silent second manifest. Re-calling
start_flightfollows an active flight and resumes a paused one from its first open stage; a settled one requiresredo: true(restart from stage 1) orfrom_stage: "<stage>"(jump to a chosen stage — prerequisites are checked and a rejection names the missing artifact, e.g. no specs yet). An explicit restart resets only affected stage artifacts. Tests & coverage and Test run keep Parallel setup while resetting their downstream run and current Report stage.from_stage: "portify"resets Parallel setup but keeps the run and downloadable Report.from_stage: "evaluation-export"builds a new Report and keeps completed archives in history. A fullredo: trueresets all stages. Plain resume (no flag) never wipes; warn the user before any otherredo/from_stagewhen they may still want a step's artifacts. The CLI equivalents are--redoand--from-stage <key>.fresh: trueskips resuming a paused flight and starts over instead.yolo: trueskips every checkpoint except missing env secrets (export defaults to raw — localized, delivered as anexternal-workhand-off, when the stage producer is external: yolo skips asks, never work delivery);autopilot: falseparks at every checkpoint instead of self-answering the safe ones.agent: "claude" | "codex"picks which CLI conducts the flight's stage agents — sticky per record (jump/continue reuse the stored one; onlyredo: truemay change it; the run stage's auto-heal follows the workspace heal setting instead). - A flight's repos and intent are frozen against MID-PIPELINE re-entry. On
from_stage/ resume, OMITrepoPathsanddescription— the stored values are reused; passing DIFFERENT ones is rejected withtype: "flight_frozen". A full restart (redo: true) discards every stage's evidence and artifacts, so THERE new values are accepted: pass newrepoPaths/descriptionto start fresh and they replace the stored ones (omit them to reuse). Deleting a flight (web UI only — no tool or CLI flag) remains for removing the record itself, not for changing inputs. Whenever you re-enter a stage BECAUSE something was wrong, passfeedback: "<what went wrong>"alongsideredo/from_stage— it is appended to the ENTRY stage's agent prompt. Without it the re-run has no idea the last attempt was rejected and produces the same thing again. - A flight parked
status: "paused",pauseReason: "queued"is waiting its turn behind another flight on the same repo(s) (a broad intent split into per-feature flights runs them sequentially). It starts automatically when that repo frees — narrate it as queued, not stuck, and do NOT ask the user to resume it. Only if they want it started early, re-callingstart_flightresumes it now. (stage-failedandrestartare the pauses a re-call picks up.pauseReason: "user"is different in kind: the user pressed Stop and Canary stopped that flight's live work — spawned agents, its run, a portify workflow, an export. Do NOT resume it unprompted; report it as stopped and let them ask. If you were midexternal-workfor it, discard that result rather than submitting it.) - When the user says stop, stop it — do not just stop polling.
pause_flight(flightId)is the resumable stop: it ends the flight's live work (the stage's spawned agent, its test run including a repair in progress, a portify workflow, an export) and returns only once that work is actually stopped, keeping every stage's evidence — a laterstart_flighton the same repos resumes from the first open stage.abort_flight(flightId, confirm: true)is terminal: same teardown, no resume, and a queued sibling on the same repo(s) may start once the repos free. Prefer pause unless they want the flight abandoned. A verified portify review awaiting an answer survives a pause deliberately. Abandoning a flight by simply ceasing toget_flightleaves the whole pipeline running.stop_flight_agent(flightId, confirm: true)is the narrow option: it kills only the agent the CURRENT stage is running. Be honest with the user about what that does — the flight is waiting on that stage, so the attempt FAILS and the flight parksstage-failed; it does not carry on. What it buys over a pause is that the test run and the export are left alone, the stage keeps its error instead of resetting to not-started, and a queued sibling flight on the same repo(s) is released. Reach for it when one agent is misbehaving and everything else should stay up; reach forpause_flightwhen the user wants the flight held. - As soon as
links.evaluationZipappears — including while status is stillrunningon Parallel setup — point the user at opening the Report (video playback where the tests drive a browser, plus the per-test reasoning inevaluation.html) and end your turn. Reviewing that export IS the core Canary Lab loop, not an optional extra. Canary owns Parallel setup as persistent background work; do not keep polling merely to hold the conversation open. The Flight page stays live, and a laterget_flightcan check it when the user asks.
A flight can be STARTED from the CLI (npx canary-lab flight <repo...> "<what to test>"), the web UI (Flights pill), or this MCP surface — one store, so progress shows everywhere. But a flight is driven by whoever started it: one you start over MCP defaults to stage_producer: "external", and the web UI is then read-only for it. Its Respond, Pause, Continue and autopilot controls are disabled and point back at you; Abort stays live for when this session dies. During an external-work hand-off the UI also offers Request takeover: that does not race you with a local agent — it records the request and waits for you to release this one step. A returned, signed URL-mode elicitation is the narrow exception: it enables input only for that exact checkpoint, without transferring ownership. Never send the user to ordinary disabled controls; pause and resume still belong to the driver.
Doing the stage work yourself
Only relevant when the flight was started with stage_producer: "external"
(sticky per record, like agent; a GUI-started flight is always internal
because there is no client to hand work to). Six steps then park on an
external-work checkpoint instead of spawning Canary's own CLI: scout
(survey the repos, draft the feature config), docs (gather or infer the
requirement docs — request elicitation first; see the docs bullet below), prd-summary (distill the docs into testable
requirements), specs↔coverage (author the spec files, then map them
onto the requirements — authoring followed by mapping of changed or previously unexamined tests: the
mapping park asks for { mappings[], unmappable[] } and every test in its
pinned roster must appear in one of them, exactly like
submit_external_coverage), run/heal (the flight
starts the run in external-heal mode UNCLAIMED and parks: claim_heal with
your OWN session id, loop wait_for_heal_task, fix APP code — never weaken a
test — signal_run after each fix, and respond submit once the run is
terminal; a failed run is a valid terminal answer and Canary reads the verdict
from the run record itself — never abort_run to escape), and
evaluation-export
(only when the mode is localized — the default for an external flight;
answer with { slots: [...] } or the full { cases: [...] } envelope the
prompt describes, and Canary renders the final evaluation.html itself, status
preserved).
-
Boot verification overlaps docs and requirement preparation after scaffold. Tests wait for both. Only one checkpoint is answerable; pause and abort stop both owners.
-
A docs collector also returns `{ requirements[], variantDimension? } in that handoff, as its prompt specifies. Canary pins this draft to the accepted docs and validates it in the summary stage; a separate summary handoff is needed only when the draft is missing, invalid, or stale.
-
Mapping reuses previously examined test/requirement pairs, including unmappable answers, while their source, helpers, configuration and requirements stay unchanged. Account for every test in the supplied roster; do not add omitted tests. Coverage is still recomputed from real tags and test evidence.
-
checkpoint.data.promptis the task, rendered exactly as Canary's own agent would have received it — fan-out rule included. Split the reading across your own subagents where the prompt says to. If the payload was oversized,Readcheckpoint.data.promptPathinstead. -
A Flight created before Parallel setup became server-owned may still expose
external-workwithcheckpoint.data.stage: "portify"after its Report exists. Do not perform that legacy hand-off. Release it immediately withchoice: "run-internally", tell the user wherelinks.evaluationZipis, and end your turn while Canary continues it in the background. -
The
docshand-off: discover authorized documents before asking. Search the flight's repositories and explicit user references, using the frozen intent as the relevance filter. Read contents; use clearly relevant, compatible sources automatically and preserve prior source choices. Never choose by a confidence percentage or infer requirements from code/tests without authorization.respond_flight_checkpoint(flightId)returns discovery instructions when no documents exist. Returndocument_resolution: {status: "resolved", searched, sources: [{path, sha256, reason}]}to validate/import selected sources. Missing material uses{status: "missing", searched, reason}; ambiguity/conflicts use that status plussearched,question, andcandidates: [{label, sources}](1–5 for ambiguity, 2–5 for conflicts). Pass this withoutchoiceto elicit only the unresolved issue through MCP 2.0. A collector's recorded empty search already establishes that discovery ran. Followdocument_source: "form"or"upload"when the user chooses to supply material. Only unsupported clients ask the focused question in chat. Use only the selected documents, write the current handoff's required output, and submit with itshandOffId. Never start a separate coverage job. If the user already choseinfer-from-diff, follow that authorized handoff directly. -
Do the work with your own tools, writing to the real paths the prompt names. Then release it:
respond_flight_checkpoint(flightId, choice: "submit", data: <the shape the prompt asks for>, token: checkpoint.data.handOffId). -
Pass
token, and re-check before you submit.checkpoint.data.handOffIdidentifies the hand-off you were given. These steps run for many minutes and nothing can interrupt you mid-turn, so re-callget_flight(flightId)between fan-out rounds, roughly every 10 minutes, and always immediately before submitting. If the status is no longerwaiting-for-approval, or thehandOffIdhas changed, the user stopped or re-asked this step: discard your result, do not submit, and tell them. A submit carrying a superseded id is discarded server-side and the step re-parks withdata.lastRejection: "stale_submission"— work you did after that point was never going to count. -
A takeover request means stop and release, never submit. If a re-check carries
checkpoint.data.takeoverRequestedAt, or a submit returnstype: "takeover_requested", stop this work plus any subagents/processes you started. Tell the user which files you already changed if they need to review them, then acknowledge withrespond_flight_checkpoint(flightId, choice: "run-internally"). Canary starts its local agent only after that acknowledgement. The UI can force takeover if this session is gone; a later response from you is then rejected. -
A parked hand-off has no deadline — so do NOT end your turn while one is open unless elicitation returned
needs-input. The flight advances only when you submit: nothing polls it, no timeout rescues it, and a status update to the user is not progress. Keep working through the submit, then follow the flight to its next stage. A read that finds a hand-off with no client contact for 45+ minutes carrieshandOffIdle— that is a step somebody took and abandoned; it is still answerable against the samehandOffId, so pick it up or tell the user the flight is stalled. If you must stop, say so in the same breath and tell them the flight stays parked until they re-invoke this skill. -
A
type: "flight_stopped"result means the flight is no longer waiting on you. Discard what you were about to submit, do not retry it, and do not resume the flight yourself — say it was stopped and let the user decide. Files you already wrote stay on disk; if they resume, a fresh hand-off arrives with a new id. -
Canary re-validates independently, and its check is the verdict — the drafted config must parse, the requirement doc must exist on disk, the submitted requirements are reconciled and re-read from the written summary, the specs must compile, and a mapping must account for every roster test before Canary's own tag-writer writes the tags and recomputes the ledger. Reporting success for work that did not land on disk re-parks or fails the stage; it never passes. This is the same bar Canary's own agent is held to, so there is nothing extra asked of you here.
-
Can't do a step — no file tools, permission refused, wrong machine? Answer
choice: "run-internally"and Canary's local agent takes that one step. The flight continues either way; nothing is lost. -
The server-owned stages (similarity, scaffold, env, the run's own Playwright execution, a
rawexport, Parallel setup) stay Canary's. Under an external flight only the heal loop is driven with thecanary-lab-runtools FROM the flight's own hand-off checkpoint.
Follow loop
Until the Report exists, re-call get_flight(flightId) while status is
running (wait ~20s between calls). Once links.evaluationZip appears,
surface it and end the foreground turn; Parallel setup does not need
this conversation held open. Before then, stop states are done, failed,
paused (when pauseReason is not queued). On waiting-for-approval,
respond to the checkpoint instead of waiting.
| Status | Action |
|---|---|
running + links.evaluationZip |
Tell the user the Report is ready, explain Parallel setup continues in Canary's background, and end your turn. Do not poll merely to hold it open. |
running |
Wait ~20s, re-call get_flight. |
waiting-for-approval |
Respond via respond_flight_checkpoint. |
waiting-for-approval + checkpoint.data.takeoverRequestedAt |
Stop external work and release with choice: "run-internally"; do not submit. |
paused, pauseReason: "queued" |
Narrate as waiting — do NOT resume it. |
paused + attention.state: "resolved" |
The earlier failure is historical and current evidence satisfies that stage. Describe remaining work; do not resume automatically. |
paused + attention.state: "unavailable" |
Current evidence could not be verified. Re-read get_flight before recommending recovery. |
paused, other pauseReason |
Re-call start_flight (OMIT repoPaths + description) to resume. |
paused + remedy in the result |
A stage is blocked by uncommitted repo changes. Help the user clean each listed repo — git stash push -u (undoable) or commit — then start_flight resumes and the stage retries. |
done |
Point the user at links.evaluationZip. |
failed |
Report the failure; a re-call to start_flight resumes from the failed stage. |
Guardrails
- On
from_stage/ resume: OMITrepoPathsanddescription— frozen against mid-pipeline re-entry. Onredo: trueyou MAY pass new ones: a full restart replaces the stored inputs. Bothredoandfrom_stagewipe the re-entered steps' on-disk artifacts (user-added docs included) — resume never does. start_flightacceptssession_id,conversation_name, andexternal_session_urlfor Activity provenance. Keep the same values on resume/redo/jump. The other Flight tools do not take them.- The flight conducts run/heal/coverage/portify itself. While a flight is active, do not drive those stages with the focused skills — answer the flight's checkpoints instead.
- Only when the user asks for one capability on its own, without asking for a Flight or
/canary-lab, use the matching focused skill:canary-lab-run,canary-lab-verify,canary-lab-author,canary-lab-coverage,canary-lab-portify,canary-lab-export.
Broken document links are repaired before source discovery: the owning command elicits the moved file's new path on the Canary server. On document-relinked, retry that command with the same arguments. Keep the symlink and existing baseline; never omit the missing source or create recovery copies. Cancel/decline leaves work pending. Unsupported clients use Relink in the returned Canary UI.
04 同仓库更多 Skills
off-by-one
暂无简介
multi-failure-cascade
暂无简介
broken-delete-contract
暂无简介
canary-lab
Use when the user wants Canary Lab to take a product repo end to end — "test this app", "onboard this repo", "run a flight", "evaluate what I just built" — through the flight pipeline (start_flight / get_flight / respond_flight_checkpoint over MCP). One conducted pipeline continues a configured suite or takes bare repo(s) to a green, covered, healed run and publishes a downloadable Report; Parallel setup continues as Canary-owned background work. Use a focused skill only when the user asks for that single capability without asking for a Flight or /canary-lab.
canary-lab-verify
Use when verifying a Canary Lab feature against a RUNNING target — a deployed environment ("verify checkout on staging", "run the saved verify config", "check the deployed app") or a locally booted app ("verify a running app") — through the verify MCP tools (list/get/create/update_verification_config, boot_services, execute_verification, get_verification_result). No heal loop. For run + heal use canary-lab-run; for end-to-end onboarding use canary-lab (flight).
canary-lab-run
Use when running or healing an EXISTING Canary Lab feature locally — "run <feature>", "fix the failing run", "rerun 7cvh", "drive the heal loop" — through the repair MCP tools (start_run, wait_for_heal_task, signal_run, get_heal_context, pause_run, cancel_heal, abort_run). Fix failing runs by editing app/service code, not tests. For end-to-end onboarding of a new repo use canary-lab (flight); for deployed-environment checks use canary-lab-verify.