plugins/lisa-copilot/skills/lisa-linear-evidence/SKILL.md
Uploads text evidence to the GitHub `pr-assets` release, updates the PR description, posts a comment on the originating Linear Issue with code blocks, and transitions the Issue from the configured `claimed` label to the configured `review` label. Reusable by any skill that captures evidence and generates evidence/comment.txt + evidence/code-blocks.md. Linear counterpart of lisa-jira-evidence and lisa-github-evidence.
npx skillsauth add codyswanngt/lisa lisa-linear-evidenceInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Post verification evidence to a Linear Issue and transition it from the configured claimed build label to the configured review build label. This skill is the destination of the lisa-tracker-evidence shim when tracker = "linear".
$ARGUMENTS is the Linear Issue identifier (e.g. ENG-123) and the path to the evidence directory. Caller passes both: <IDENTIFIER> <evidence-dir>.
Resolve every lifecycle role through the shared resolver — never an inlined read_role helper. Twelve skills used to inline their own and produced eleven different implementations, which is how the vendors drifted apart on this exact contract.
resolve() { # role, intent -> value on stdout; empty when an optional role is unset
node "${CLAUDE_PLUGIN_ROOT}/scripts/resolve-lifecycle-role.mjs" \
--role "$1" --vendor linear --intent "${2:-read}"
}
CLAIMED=$(resolve claimed write) || {
echo "ERROR: failed to resolve the required Linear claimed role" >&2
exit 1
}
[ -n "$CLAIMED" ] || {
echo "ERROR: the required Linear claimed role resolved empty" >&2
exit 1
}
REVIEW=$(resolve review write) || {
echo "ERROR: failed to resolve the optional Linear review role" >&2
exit 1
}
review is OPTIONAL and has no default. An empty REVIEW means the project does not run an agent review step, and this skill skips the transition entirely, leaving the Issue in claimed — the same behaviour lisa-jira-evidence/scripts/post-evidence.sh has always had. Do not substitute In Review, and do not fall back to a state resolved by type or board position: a fallback may inform a read but must never supply a write target (config-resolution, R2). Resolving a state nobody configured is how agents reach human-only review lanes.
Reads linear.workspace, linear.teamKey, and linear.workflow.* from .lisa.config.json (with .local override).
<evidence-dir>)The caller must produce:
evidence/comment.txt — the human-readable comment body posted on the Linear Issue.evidence/code-blocks.md — fenced code blocks (test outputs, command output, log excerpts) appended to the comment.evidence/files/ (optional) — any text files that should be uploaded to the GitHub pr-assets release for permalink-style references.If any of these are missing, stop and report.
Before posting or updating anything, check the evidence body (comment.md, and comment.txt where this skill uses it):
## Not established heading. That heading is never omitted and never blank — when nothing is outstanding it still renders None outstanding — reviewed; otherwise it names, in plain operator language, what the verification did not prove.not_established_reviewed: true (the list may be empty; the flag may never be omitted).## Artifact identity heading carrying values, not placeholders — the repository, the head_sha the verification observed, the environment, and per artifact its sha256 digest and captured_at. Refuse to post a body whose identity heading is absent or unpopulated, or whose recorded artifact_head_sha disagrees with the verdict's artifact.head_sha — report the evidence id and both SHAs. Definition: the claim-evidence-mapping rule.If either is missing, refuse to post: stop and report the missing Not-established review to the caller instead of publishing. Composing the body is lisa-tracker-evidence's job (see its UI Evidence Checklist); this skill only refuses to publish one that omits the section. The section is defined by the claim-evidence-mapping rule and generalizes lisa-improve-harness's required, never-empty Known limits field.
$ARGUMENTS.lisa-linear-access operation: get-issue to confirm it exists and capture its current state, label set, and Project membership.If evidence/files/ is non-empty, upload each text file to the GitHub pr-assets release on the current repo via gh release upload. The release is the permalink store — keeps the Linear comment lightweight while preserving large outputs.
For each uploaded file, capture the public release URL.
If a PR is open on the current branch (gh pr view --json url,number,body 2>/dev/null), append an "Evidence" section to its description with:
https://linear.app/<workspace>/issue/<IDENTIFIER>).evidence/comment.txt).If no PR is open, skip this phase.
Call lisa-linear-access operation: save-comment({issueId: <id>, body: <body>}) where <body> is:
[<comment.txt contents verbatim>]
<details>
<summary>Evidence</summary>
[<code-blocks.md contents verbatim>]
</details>
[<bullet list of uploaded evidence file URLs, if any>]
Linear comments support markdown including <details> collapsibles, fenced code, and links — preserve the formatting.
If $REVIEW is empty, skip this phase entirely — post the evidence comment and leave the Issue in $CLAIMED. Report it plainly (No linear.workflow.review configured; leaving <ID> in its current (claimed) state) so the skip is visible rather than silent. This is a supported configuration, not a failure.
When $REVIEW is non-empty, update labels via lisa-linear-access operation: save-issue to remove $CLAIMED and add $REVIEW. Resolve label IDs first via lisa-linear-access operation: list-issue-labels (create the label via create_issue_label if it doesn't exist on the team).
The native Linear state field is updated to $REVIEW only when the resolver returned it from config. Never resolve the state by searching the team for something review-shaped: on a board with more than one review-ish state that picks by position, not by intent, and the states most likely to be found that way are the human-only ones a project deliberately kept out of its config.
Return:
lisa-linear-write-issue.review is configured. An empty $REVIEW is the one sanctioned skip (Phase 5): post the evidence comment, leave the Issue in $CLAIMED, and report the skip. Whenever $REVIEW is non-empty, the configured native state transition is mandatory.lisa-linear-access operation: save-comment fails, retry once. If it fails again, surface the error — don't pretend the comment was posted.development
Prepare a machine — a fresh laptop or a throwaway container — to run coding agents, before any repository exists. Detects which of Lisa's supported agents (Claude Code, Codex, Cursor, OpenCode, Antigravity, Copilot) are already installed, asks which credential manager the machine uses (Bitwarden, 1Password, Doppler, Vault, AWS, or none), and installs only what is missing, each by its vendor's own preferred method. Idempotent, headless by default, and emits a Dockerfile for a spin-up/spin-down environment. Run it on a new machine, in a container, or before cloning anything.
tools
Provision and verify a remote execution environment for a host project — Codex Cloud today, other remote surfaces as they are added. Generates a repository-owned setup script that installs the declared toolchain, materializes secrets through lisa-secrets-access, and runs the project's own hook. Provisions by API where one exists, by driving the vendor console where one does not, and by emitting exact config otherwise — then proves the result with the same read-back regardless of which tier did the work. Use before dispatching any work with executionEnv.
tools
Bring a developer's machine in line with the toolchain the project declares. Reports every tool in remoteEnv.tools that is missing, outdated, or unpinned for this platform, and installs the missing ones into ~/.local/bin from the same pinned, checksummed entries the remote surfaces use — but only when asked. Same manifest, same pins, same installers as lisa-setup-remote-env; what differs is consent and that the pin is a floor rather than an equality. Run it on a fresh checkout, after a manifest change, or when a tool fails at the moment of use.
tools
Route one unit of work to a remote execution surface. Reads the executionEnv parameter (local by default, codex-cloud or claude-web today), verifies the environment is provisioned and bound to this repository, submits a thin skill invocation, records the task identifier to .lisa/remote-dispatch.json, and exits without polling. Routing only — the remote runs the identical skill from the identical repository. Composable and inline: other skills invoke it via the Skill tool rather than users calling it directly.