PRD Source Write: $ARGUMENTS
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.
Input contract
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.
Omitted means draft — the not-ready default. This matches the ticket-side build_ready contract
in ready-role-filing: on both sides of the pipeline, entering a queue is an explicit claim and
omission is the safe direction. (The ticket side reached that position by removing a per-vendor
legacy default; the PRD side never had one to remove.)
Workflow
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.)
- Any other value (including
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.
Rules
- Never bypass dispatch — a vendor-neutral caller calling a
*-write-prd skill directly defeats the
per-project source switch (exactly the tracker-write discipline, mirrored).
- Never drop or duplicate an existing managed
## Lisa Usage section. Writer-specific preservation
and fallback behavior belongs in the vendor writers and follows the lisa-lisa-usage-accounting contract.
- Never accept a source outside
{notion, confluence, github, linear}. jira and file fail loudly.
- Never mutate the spec between layers. The vendor writers define their own create/dedupe contract.
- Never drop, rename, or vendor-render
ideation_ledger_payload; it is a pass-through payload for
the configured writer.
- Never invent a PRD lifecycle role string — resolve every role from
config-resolution per vendor.
- Idempotency is the vendor writer's job (marker search before create); this shim only routes.
1---2name: lisa-prd-source-write3description: 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.4---56# PRD Source Write: $ARGUMENTS78Thin dispatcher. Resolves the configured PRD `source` and delegates to the matching vendor PRD9writer, which owns the concrete create/update, the lifecycle-role application, and the marker-based10dedupe. When the supplied PRD body already contains the canonical `## Lisa Usage` ledger, the11vendor writer must preserve that managed section on update instead of dropping it or reformatting it12ad hoc. This skill only routes — it never talks to a source API itself.1314See the `config-resolution` rule for the full configuration schema and the PRD lifecycle roles.1516## Input contract1718Callers pass a single structured spec:1920```yaml21operation: create_or_update # the only operation; create unless the marker already exists22title: "<PRD title>"23body: "<full PRD markdown — the entire spec>"24initial_role: draft | ready # default: draft. ready = picked up by lisa-intake's PRD scan25dedupe_key: "<stable-key>" # e.g. project-ideation's idea key26marker: "[lisa-project-ideation] idea=<stable-key>" # embedded in the PRD body for dedupe27origin: { tool: project-ideation | research | manual }28source_ref: "<optional existing PRD ref to force an update>"29ideation_ledger_payload: # optional; forwarded unchanged to the vendor writer30 selected_marker: "<same value as marker>"31 automation_id: "<Codex/Claude automation id or unavailable>"32 automation_memory_path: "<path or unavailable>"33 repo: "<org>/<repo or detected repo identity>"34 prd_ready: true|false35 persona_names: ["<derived persona name>"]36 persona_evidence_refs: ["<file/doc/table/release ref>"]37 selected_idea: "<selected idea title/key>"38 rejected_overlap_candidates: ["<issue refs/titles considered and rejected>"]39 expected_empirical_verification_artifact: "<artifact ref or unavailable>"40```4142`initial_role` semantics are uniform across vendors (the role STRINGS resolve per vendor from43`config-resolution`):4445- **`draft`** (default) → the PRD is created in the source's `draft` PRD role. It waits for a human46 (or a later `ready` promotion) before any intake claims it.47- **`ready`** → the PRD is created in the source's `ready` PRD role (`prd-ready`), so the PRD-side of48 `lisa-intake` / the `*-prd-intake` scanner auto-claims it on the next cycle.4950Omitted means `draft` — the not-ready default. This matches the ticket-side `build_ready` contract51in `ready-role-filing`: on both sides of the pipeline, entering a queue is an **explicit claim** and52omission is the safe direction. (The ticket side reached that position by removing a per-vendor53legacy default; the PRD side never had one to remove.)5455## Workflow56571. **Resolve the source.** Read `.lisa.config.local.json` first (if present), then58 `.lisa.config.json`. Local overrides global per key. Use `jq` — never hand-parse JSON.5960 ```bash61 local_source=$(jq -r '.source // empty' .lisa.config.local.json 2>/dev/null)62 global_source=$(jq -r '.source // empty' .lisa.config.json 2>/dev/null)63 source="${local_source:-${global_source}}"64 if [ -z "$source" ]; then65 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)." >&266 exit 167 fi68 ```69702. **Validate the value and dispatch** (pass the spec verbatim):7172 - `notion` → confirm `notion.workspaceId` and `notion.prdDatabaseId` are present, then invoke73 `lisa-notion-write-prd`.74 - `confluence` → confirm `atlassian.cloudId` and (`confluence.spaceKey` or75 `confluence.parents.draft`/`.ready`) are present, then invoke `lisa-confluence-write-prd`.76 - `github` → confirm `github.org` and `github.repo` are present, then invoke77 `lisa-github-write-prd`.78 - `linear` → confirm `linear.workspace` (and team for project placement) is present, then invoke79 `lisa-linear-write-prd`.80 - `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.)81 - Any other value (including `file`) → stop and report: `"Unknown PRD source '<value>'. Expected one of: notion, confluence, github, linear."`82833. **Surface the vendor writer's output unchanged.** It returns the created/reused PRD ref + URL,84 the applied role (`draft`/`ready`), the dedupe marker, and whether it was created or reused.85 Downstream callers (research, project-ideation) parse this — do not paraphrase.8687When `ideation_ledger_payload` is present, this shim still does not render or interpret it. Forward88the object verbatim to the selected vendor writer so source-specific rendering remains behind the89configured writer and the dispatch layer never bypasses source selection.9091## Rules9293- Never bypass dispatch — a vendor-neutral caller calling a `*-write-prd` skill directly defeats the94 per-project source switch (exactly the `tracker-write` discipline, mirrored).95- Never drop or duplicate an existing managed `## Lisa Usage` section. Writer-specific preservation96 and fallback behavior belongs in the vendor writers and follows the `lisa-lisa-usage-accounting` contract.97- Never accept a source outside `{notion, confluence, github, linear}`. `jira` and `file` fail loudly.98- Never mutate the spec between layers. The vendor writers define their own create/dedupe contract.99- Never drop, rename, or vendor-render `ideation_ledger_payload`; it is a pass-through payload for100 the configured writer.101- Never invent a PRD lifecycle role string — resolve every role from `config-resolution` per vendor.102- Idempotency is the vendor writer's job (marker search before create); this shim only routes.