plugins/lisa-agy/skills/prd-source-write/SKILL.md
Vendor-neutral wrapper for creating (or idempotently updating) a PRD in the configured PRD source. The PRD-side sibling of lisa:tracker-write. Resolves `source` from .lisa.config.local.json first (then .lisa.config.json — local overrides global) and dispatches to lisa:notion-write-prd, lisa:confluence-write-prd, lisa:github-write-prd, or lisa:linear-write-prd. Callers (notably lisa:research) MUST invoke this skill instead of a vendor PRD writer directly — that is what makes the PRD source switchable per project. Accepts an `initial_role` of `draft` (default) or `ready` so a freshly created PRD either waits for human promotion or is immediately picked up by lisa:intake; and a stable dedupe marker so re-runs reference the existing PRD instead of creating a duplicate. The PRD lives in the source — there is no separate document artifact.
npx skillsauth add codyswanngt/lisa prd-source-writeInstall 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.
Thin dispatcher. Resolves the configured PRD source and delegates to the matching vendor PRD
writer, which owns the concrete create/update, the lifecycle-role application, and the marker-based
dedupe. When the supplied PRD body already contains the canonical ## Lisa Usage ledger, the
vendor writer must preserve that managed section on update instead of dropping it or reformatting it
ad hoc. This skill only routes — it never talks to a source API itself.
See the config-resolution rule for the full configuration schema and the PRD lifecycle roles.
Callers pass a single structured spec:
operation: create_or_update # the only operation; create unless the marker already exists
title: "<PRD title>"
body: "<full PRD markdown — the entire spec>"
initial_role: draft | ready # default: draft. ready = picked up by lisa:intake's PRD scan
dedupe_key: "<stable-key>" # e.g. project-ideation's idea key
marker: "[lisa-project-ideation] idea=<stable-key>" # embedded in the PRD body for dedupe
origin: { tool: project-ideation | research | manual }
source_ref: "<optional existing PRD ref to force an update>"
ideation_ledger_payload: # optional; forwarded unchanged to the vendor writer
selected_marker: "<same value as marker>"
automation_id: "<Codex/Claude automation id or unavailable>"
automation_memory_path: "<path or unavailable>"
repo: "<org>/<repo or detected repo identity>"
prd_ready: true|false
persona_names: ["<derived persona name>"]
persona_evidence_refs: ["<file/doc/table/release ref>"]
selected_idea: "<selected idea title/key>"
rejected_overlap_candidates: ["<issue refs/titles considered and rejected>"]
expected_empirical_verification_artifact: "<artifact ref or unavailable>"
initial_role semantics are uniform across vendors (the role STRINGS resolve per vendor from
config-resolution):
draft (default) → the PRD is created in the source's draft PRD role. It waits for a human
(or a later ready promotion) before any intake claims it.ready → the PRD is created in the source's ready PRD role (prd-ready), so the PRD-side of
lisa:intake / the *-prd-intake scanner auto-claims it on the next cycle.There is no "omitted = legacy behavior" mode (unlike the ticket-side build_ready): there was no
prior PRD-source-write behavior to preserve, so omitted means draft.
Resolve the source. Read .lisa.config.local.json first (if present), then
.lisa.config.json. Local overrides global per key. Use jq — never hand-parse JSON.
local_source=$(jq -r '.source // empty' .lisa.config.local.json 2>/dev/null)
global_source=$(jq -r '.source // empty' .lisa.config.json 2>/dev/null)
source="${local_source:-${global_source}}"
if [ -z "$source" ]; then
echo "Error: 'source' is not set in .lisa.config.json. A PRD source (notion / confluence / github / linear) is required to create a PRD. Run /lisa:setup:notion (or :confluence, :github, :linear)." >&2
exit 1
fi
Validate the value and dispatch (pass the spec verbatim):
notion → confirm notion.workspaceId and notion.prdDatabaseId are present, then invoke
lisa:notion-write-prd.confluence → confirm atlassian.cloudId and (confluence.spaceKey or
confluence.parents.draft/.ready) are present, then invoke lisa:confluence-write-prd.github → confirm github.org and github.repo are present, then invoke
lisa:github-write-prd.linear → confirm linear.workspace (and team for project placement) is present, then invoke
lisa:linear-write-prd.jira → stop and fail loudly: "source=jira is not a supported PRD source — config-resolution defines no JIRA PRD lifecycle roles. Use notion / confluence / github / linear, or set source accordingly." (JIRA is a destination tracker, not a PRD source.)file) → stop and report: "Unknown PRD source '<value>'. Expected one of: notion, confluence, github, linear."Surface the vendor writer's output unchanged. It returns the created/reused PRD ref + URL,
the applied role (draft/ready), the dedupe marker, and whether it was created or reused.
Downstream callers (research, project-ideation) parse this — do not paraphrase.
When ideation_ledger_payload is present, this shim still does not render or interpret it. Forward
the object verbatim to the selected vendor writer so source-specific rendering remains behind the
configured writer and the dispatch layer never bypasses source selection.
*-write-prd skill directly defeats the
per-project source switch (exactly the tracker-write discipline, mirrored).## Lisa Usage section. Writer-specific preservation
and fallback behavior belongs in the vendor writers and follows the usage-accounting contract.{notion, confluence, github, linear}. jira and file fail loudly.ideation_ledger_payload; it is a pass-through payload for
the configured writer.config-resolution per vendor.documentation
Onboard a user to the project via its LLM Wiki. Interviews the user about themselves in relation to the project, captures that to project-scoped memory only, then gives a guided tour of what the project is and sample questions they can ask. Use when someone is new to the project or asks to be onboarded. Read-mostly — it does not open PRs or write PII into the wiki.
documentation
Migrate an existing, hand-rolled wiki implementation onto the lisa-wiki kernel — phased and compatibility-first, with a strict no-loss guarantee. Use when adopting lisa-wiki in a repo that already has its own wiki/, ingest skills, docs, or roles. Renaming things into the canonical shape is fine; losing functionality or data is not. Ends by running /doctor.
development
Health-check the LLM Wiki. Reports orphan pages, contradictions, stale claims, broken internal links, missing index/log coverage, structure-manifest violations, and secret/tenant leaks. Use periodically or before hardening a wiki. Read-only — it reports findings, it does not fix them.
testing
Ingest source material into the LLM Wiki. With an argument (URL, file path, or prompt) it ingests that one source; with no argument it runs a full ingest across every enabled non-external-write source. Routes to the right connector, then runs the ordered pipeline (source note → synthesis → index → log → verify → state → commit/PR). Use whenever new knowledge should enter the wiki.