prd-plugin

PRD Plugin is a method delivered as a plugin: it installs a disciplined product-development workflow (idea → PRD → architecture → plan → implementation → evidence) into any repo that a host AI coding agent works in, and enforces that discipline with stable IDs, a JSON state store, cross-host hooks, and a verification gate. This document is chunked by heading for shared-knowledge indexing — each section is written to be read correctly on its own, with no surrounding context.

1. What this repo is

PRD Plugin (prd-plugin on npm) is a method-as-a-plugin for host AI coding agents — primarily Claude Code, with parity support for OpenAI Codex and opencode. It gives an agent a repeatable way to turn an idea into a requirement, a requirement into architecture and an implementation plan, and code into verified, evidence-backed work — with every artifact carrying a stable ID so the chain is traceable and no record can be silently invented. It solves the problem that agents drift, hallucinate "done", skip verification, and lose the thread across sessions and compactions; the plugin replaces recollection with on-disk state, skills the agent must consult, and hooks that run checks it cannot forget.

This repository is the hub (the source of truth), located at D:\Projects\prd-plugin / github.com/markusuk1/prd-plugin. It authors the skills, templates, scripts, MCP server, and hooks, and publishes them to npm. Downstream repos consume the plugin by running npx prd-install, which lays down a .prd_plugin/ tree (method docs, state store, ID registry, hooks, config) plus host-specific skill mirrors. The hub is edited with the same method it ships (it dogfoods itself: its own work is tracked as REQ-*/TRK-*/EV-* records under .prd_plugin/state/).

What it is not. It is not a library or framework you import at runtime — nothing in a downstream app links against it. It is not an orchestrator: it does not spawn or manage subagents; the host agent runs the method itself and may manage its own parallelism. It is not project-specific — the skills and schema are domain-agnostic. And it is not a replacement for the host agent's own tools; it is a governance and memory layer on top of whatever agent is driving.

2. Capability map

Everything PRD Plugin provides, and where it lives in this repo. Counts are as of version 0.15.0.

CapabilityWhat it doesWhere
Workflow skills (29)Markdown skill files the host agent invokes to run each stage of the method (router, planning, TDD, debugging, verification, decision ledger, wiki, session close, …). The primary interface an agent touches.skills/<name>/SKILL.md
State store & ID registryPer-repo JSON files holding all durable records (requests, tracking, decisions, evidence, health, changelog) plus a monotonic ID registry so IDs never collide or get invented..prd_plugin/state/*.json, .prd_plugin/ids/registry.json
MCP server (35 tools)A Model Context Protocol server exposing bounded canonical and DBR discovery, duplicate-safe ordinary record management, config-enforced branch-first parallel tracking, guarded goal/request/evidence/decision/change workflows, unified configuration management, reflection-bank CRUD, and persistent deterministic workflow operations.mcp/server.cjs
Slash commands (13)Host slash commands that wrap the scripts (/prd-status, /prd-new, /prd-track, /prd-report, /prd-drift, /prd-config, /prd-reflections, /prd-workflow, /prd-autonomy, /prd-graph, /prd-hooks, /prd-version, /prd-close).commands/*.md
Deterministic workflow authorityA strict catalog and allowlisted action engine turns bounded mechanics, policy, validation, state, evidence, lifecycle, and release work into resumable WFR-* runs with stable plans, receipts, postconditions, idempotency, retry safety, cancellation, and hash-bound judgment requests. AI-Collab executes only the explicit external judgment contract; it cannot write canonical state directly.scripts/prd_workflows.py, .prd_plugin/workflows.json, .prd_plugin/state/workflow-runs.json
Cross-host hooksShared hook scripts wired into all three hosts (Claude via settings.json, Codex via hooks.json 5 events, OpenCode via a JS plugin) — session nudge, gate on commit, drift on Stop, and optional bounded reflection questions on Stop..prd_plugin/hooks/, .claude/hooks/, .codex/hooks.json, .opencode/plugins/prd-hooks.js
Stop reflectionsAn off-by-default, categorized question bank whose categories and questions can be individually edited or activated; one local session marker prevents recursive Stop loops and reflection answers never become canonical project state automatically..prd_plugin/config.json, .prd_plugin/hooks/prd_reflection.py, scripts/prd_reflections.py
The gateA single composable validator that blocks a commit / flags a session when state is inconsistent: duplicate IDs, version markers out of sync, implemented-without-graduation, tier violations, and more. Reads the config policy flags.scripts/prd_gate.py
Drift monitorRuns the validator suite, snapshots results to JSONL, emits a compact drift-event feed, and (optionally) a cheap on-Stop check. Detects when docs, state, the wiki, or the ingest manual have drifted from the code, and (for fork-consumer repos) when a newer fork version is available.scripts/drift_monitor.py, scripts/ingest_manual_drift.py, scripts/fork_version_check.py
LLM wikiA compounding, navigable knowledge base (Karpathy-style) the agent queries before re-deriving a fact and ingests into as work closes; with backfill and drift detection.wiki/, scripts/prd_wiki_backfill.py
Version checkCompares the installed plugin version against npm (TTL-cached, fail-open, cross-platform) and surfaces "update available" in-session.scripts/prd_version_check.py
Config togglesA typed registry of on/off and value knobs (autonomy tier, tracking branches, drift monitoring, version check, wiki, gate) readable and settable as a JSON contract so external apps can toggle features.scripts/prd_config.py, .prd_plugin/config.json
Delegated reportingAn off-by-default control plane for bounded non-deterministic prose: PRD Plugin builds source-referenced bundles and validates results; AI-Collab resolves and executes the configured fast-capable model profile.scripts/prd_reporting.py, reporting.delegation config, utcp.json
AI-Collab Substrate adapterAn off-by-default, versioned projection contract with observe and coordinate modes. AI-Collab mirrors canonical records and graph edges while every project-truth mutation remains behind PRD MCP.scripts/prd_substrate.py, integrations.substrate config, utcp.json
Request intake & auto-submitTurns a bug/change proposal into a REQ-* record; downstream plugin-bug reports self-submit upstream rather than relying on the agent to remember.skills/project-request-intake/, skills/project-local-integration/
InstallerThe npx prd-install entrypoint: copies the skeleton into a target repo, mirrors skills per host, refreshes plugin files with --force while preserving state, and idempotently maintains a bounded root .gitignore block without replacing project-owned rules.scripts/prd_install.py, index.js

3. Interfaces — how to call it

PRD Plugin is driven five ways: the install CLI, MCP tools, host slash commands, the Python scripts directly, and a UTCP tool surface. The UTCP manual (utcp.json, generated by scripts/prd_tools.py --utcp-manual) describes a set of read-only observe/recall tools (status, tracking, decisions, evidence, wiki, drift, gate, reporting) as cli call templates that run this repo's own scripts. A UTCP host such as the AI-Collab hub mounts the manual with a cli provider and bridges it to MCP — so the tools are defined and owned here, not re-implemented downstream. Writes are deliberately excluded: they stay on the validated MCP/script path (branch-first parallel tracking, serialized canonical promotion, and the consent floor).

3.1 Install CLI

The npm package's bin runs the installer. Invoked in a target repo:

npx prd-install [target-dir]        # first-time install into a repo (default: cwd)
npx prd-install . --force           # refresh plugin files, PRESERVE .prd_plugin/state + config.json
npx prd-install . --force --yes     # DESTRUCTIVE reset request; interactive confirmation required
npx prd-install . --host codex      # choose host wiring (claude | codex | opencode)

--force is the update path: it re-lays hooks, skills, scripts, and templates but never overwrites .prd_plugin/state/, .prd_plugin/ids/, .prd_plugin/local/, or .prd_plugin/config.json (the state-protected set), and never overwrites a downstream README.md. The report labels each file copied, skipped, or preserved.

Every install also creates or refreshes the lines between # BEGIN PRD Plugin managed ignores and # END PRD Plugin managed ignores in the repo-root .gitignore. It preserves surrounding lines and line-ending style; malformed markers or a non-UTF-8 file are reported and left untouched. The block ignores runtime/transport state, reports, local command adapters, secrets, caches, logs, temporary files, and OS metadata while leaving committed state, tracking branches, drift exports, evidence, MCP configuration, and the shipped Codex environment trackable.

3.2 MCP tools

Exposed by mcp/server.cjs over the Model Context Protocol. Read tools are side-effect-free; write tools allocate IDs from the registry and append to the state store under the owner-token lock. The thirty-five tools:

ToolKindPurpose
prd_statusreadSummarize state: requests, active tracking, DBR branches, open health, stale items, skills used.
prd_findreadReturn compact bounded canonical or DBR records filtered by kind, status, link, or text.
prd_getreadReturn one exact full canonical or DBR record by ID.
prd_createwriteCreate ordinary TRK/REQ/HLT state with allocation inside the locked write.
prd_updatewriteUpdate only kind-specific mutable fields and valid lifecycle states.
prd_linkwriteVerify and symmetrically link two existing record-backed IDs.
prd_open_tracking_branchwriteBefore fan-out, the lead allocates one assigned DBR tracking file without changing canonical TRK state.
prd_update_tracking_branchwriteA worker records progress only in its assigned branch file and allocates no IDs.
prd_promote_tracking_branchwriteAfter worker merges, the lead serially applies a conflict-checked, idempotent branch promotion to canonical TRK state.
prd_next_idwriteConsume the next globally unused embedded planning ID; ordinary record creation allocates internally.
prd_open_goalwriteOpen a tracking goal (TRK-*) with summary and links.
prd_update_goalwriteUpdate a tracking goal's status/summary/links.
prd_close_goalwriteClose a tracking goal and record the outcome.
prd_file_requestwriteFile a REQ-* (bug/change/feature) with severity, risk, and provenance.
prd_record_evidencewriteAppend an EV-* evidence record backing a completion claim.
prd_record_decisionwriteAppend a DEC-* decision with rationale, options, consequences, provenance.
prd_log_changewriteAppend a CHG-* changelog record.
prd_validatereadRun the consistency/gate checks and return findings.
prd_reflection_listreadList categories and questions with configured and effective activation; optional category and enabled filters are bounded and side-effect-free.
prd_reflection_createwriteCreate a unique category or atomically allocate a collision-free RFQ-* question under the shared state lock.
prd_reflection_updatewriteRename or activate a category; edit, activate, deactivate, or move a question while rejecting normalized duplicates.
prd_reflection_deletewriteDelete a question or an empty category; deleting a non-empty category requires explicit cascade: true.
prd_config_listreadList and filter the complete persistent setting catalog with current/default values, ownership, activation, latency, and dependency metadata.
prd_config_getreadDescribe one configured setting or explain its effective state and blocking dependencies.
prd_config_setwriteAtomically set, enable, or disable one operator-mutable setting after type and policy validation.
prd_config_profileread/writeList, show, diff, dry-run/apply, save, or delete built-in and custom latency profiles.
prd_workflow_listreadList shipped workflows, step counts, judgment boundaries, and effective enablement.
prd_workflow_actionsreadList the code-owned action allowlist with determinism, mutation, and idempotency metadata.
prd_workflow_auditreadAudit catalog schema, provenance, inputs, actions, postconditions, and duplicates.
prd_workflow_planreadValidate inputs and return a stable dry-run plan without executing or allocating.
prd_workflow_runwriteAllocate and start a persistent run whose completion requires every postcondition.
prd_workflow_statusreadRead steps, receipts, attempts, pending judgment, and terminal outcome for one run.
prd_workflow_resumewriteValidate a hash-bound judgment result and resume deterministic execution.
prd_workflow_cancelwriteCancel a non-terminal run with an auditable reason.
prd_workflow_retrywriteRetry a safely retryable failure within policy; outcome-unknown mutations remain blocked.

3.3 Slash commands

Thin host-command wrappers over the scripts (files under commands/):

CommandDoes
/prd-statusPrint the state summary (wraps prd_status.py).
/prd-newStart a new piece of tracked work.
/prd-trackOpen/update a tracking goal.
/prd-reportGenerate deterministic reports and optionally delegate source-validated summary prose to AI-Collab under the configured fallback.
/prd-driftRun the drift monitor and show findings.
/prd-configGet/set/list config toggles, including delegated reporting and the Substrate adapter switch, mode, and capabilities (wraps prd_config.py).
/prd-reflectionsList and manage reflection categories/questions through the validated CRUD script or MCP tools.
/prd-workflowList, audit, plan, run, inspect, resume, cancel, or safely retry persistent deterministic workflows.
/prd-autonomyShow or set the autonomy tier.
/prd-graphRender the traceability graph.
/prd-hooksInspect/repair host hook wiring.
/prd-versionCheck installed vs npm-latest plugin version.
/prd-closeRun the session-close flow (user-invoked).

3.4 Scripts

The Python scripts under scripts/ are the real implementation; commands, hooks, and MCP tools all call into them. Stdlib-only, cross-platform.

ScriptRole
prd_gate.pyThe composite verification gate; also set-autonomy <level>.
prd_status.pyHuman-readable state summary.
prd_config.pyUnified setting catalog and profile manager: list/get/describe/set/enable/disable, effective-state explanation, audit/inventory, and built-in/custom profile CRUD with atomic writes.
prd_reflections.pyValidated reflection-bank list/create/update/delete CLI with atomic config writes and duplicate-safe RFQ-* allocation.
prd_reporting.pyProvider-neutral delegated-reporting control plane: effective policy, deterministic sanitized bundles, fallback decisions, and strict result validation. It makes no model call and writes no project state.
prd_substrate.pyVersioned read-only handshake, complete canonical-record snapshot, and repo-qualified graph export consumed by the AI-Collab adapter.
prd_workflows.pyStrict workflow catalog validator and execution authority with persistent WFR-* state, receipts, postconditions, resumable judgment boundaries, idempotency, and retry/cancel safety.
workflow_chml_audit.pyDeterministic C/H/M/L completeness audit across engine, catalog, config, interfaces, lifecycle hooks, installer, skills, docs, and release wiring.
drift_monitor.pyValidator suite runner, snapshots, drift-event feed, on-Stop check.
prd_version_check.pynpm-vs-installed version check (cached, fail-open).
prd_wiki_backfill.pyWiki build/backfill and --drift detection.
ingest_manual_drift.pySource-path-aware drift detection for this manual (--drift): flags when a cited file changed since the manual's commit stamp, or it is unstamped / non-conformant.
fork_version_check.pyGeneric fork/upstream version drift check (--drift): polls a configured JSON URL (static manifest or a node /v1/status) and compares to a local marker; inert unless the repo is a configured fork consumer.
prd_tools.pyThe UTCP tool surface: read-only observe/recall tools over a repo's method state, plus --utcp-manual discovery. The tools a UTCP host (AI-Collab hub) mounts and bridges to MCP.
state_consistency_check.pyRequired default downstream runtime for cross-record and tracking-branch integrity; prd_gate.py fails if it is unavailable.
release_check.pyVersion markers and release-ledger consistency, compared with the prior v* release tag by default (or HEAD~1 before the first tag).
gap_audit.pyCoverage/gap audit against a target version.
prd_self_audit.pyRule/state/downstream-template audit. Registry counters are monotonic allocation cursors rather than continuity ledgers; explicitly guarded hub-helper references are allowed while unguarded downstream commands remain findings.

3.5 Reflection CRUD example

The CLI and MCP CRUD tools operate on the same .prd_plugin/config.json#reflection store and use the same local lock as canonical state writes. They require local repository write access but no network authentication. Invalid IDs, duplicate normalized text/category names, unknown targets, and non-empty category deletion without an explicit cascade return an error without partially editing the bank. Real read output at commit c5bab8c:

$ python scripts/prd_reflections.py list --json --category harness_friction
{
  "enabled": false,
  "on_stop": true,
  "max_questions_per_stop": 5,
  "categories": [
    {
      "id": "harness_friction",
      "name": "Harness friction",
      "enabled": true,
      "question_count": 2
    }
  ],
  "questions": [
    {
      "id": "RFQ-004",
      "text": "What harness friction points made this work more difficult?",
      "enabled": true,
      "category_id": "harness_friction",
      "category_name": "Harness friction",
      "effective_enabled": false
    },
    {
      "id": "RFQ-005",
      "text": "What up to three changes would most improve friction in the harness?",
      "enabled": true,
      "category_id": "harness_friction",
      "category_name": "Harness friction",
      "effective_enabled": false
    }
  ]
}

3.6 Worked example

Running the status script in this repo prints the current state summary. Real output at commit f7d182d:

$ python scripts/prd_status.py
# PRD Plugin Status

Autonomy: `autonomous`

## Requests
- accepted: 1
- deferred: 1
- implemented: 54
- proposed: 3
- rejected: 1

## Active tracking (1)
- TRK-063

## Open health findings (1)
- HLT-001

## Stale items
- 1

## Skills used this repo
- project-decision-policy: 1
- project-request-intake: 1
- project-test-driven-implementation: 1
- project-verification-before-completion: 1

Architecture — how the pieces fit

PRD Plugin has four structural layers: the skill mirrors, the per-repo state store, the MCP server, and the host hooks — all authored once in the hub and projected outward by the installer. This section reads on its own; it describes how a change made in the hub reaches a downstream agent.

Skill delivery: one canonical set, seven mirrors

The 29 skills are authored in skills/<name>/SKILL.md. Because each host discovers skills from a different directory, the canonical set is copied byte-identically into per-host mirrors: hub-level .agents/skills, .opencode/skill, and .claude/skills, plus three skeleton copies under templates/repo-skeleton/ that ship downstream. Parity tests assert the mirrors are identical. Two skills (project-verification-before-completion, project-prd-plugin-setup) have adapted skeleton variants that strip hub-only scripts — a blanket copy would clobber them, so those two are excluded from the byte-identical sweep.

State store: branch-first parallel writes, serialized promotion

Every durable record lives in .prd_plugin/state/*.json (requests.json, tracking.json, decisions.json, evidence, health.json, changelog). IDs are allocated only from .prd_plugin/ids/registry.json, which holds a next counter per type — this is what makes "no inventing records" enforceable: a referenced ID that was never allocated is a gate failure. Before parallel fan-out, the lead pre-allocates one DBR tracking branch per worker and commits the distinct files under .prd_plugin/state/tracking-branches/. It launches workers with PRD_WORKER_SESSION=1, PRD_TRACKING_BRANCH_ID, and PRD_TRACKING_BRANCH_OWNER. When tracking.branching.require_for_parallel_agents is true, the MCP dispatcher rejects every canonical state/registry write and any branch assignment mismatch. Workers update only their assigned files, allocate no IDs, and leave non-TRK closeout requests as notes for the lead. After worktree merges, the lead promotes branches serially; canonical state and registry allocation therefore remain single-authority and duplicate-safe.

Hooks: shared scripts, thin per-host wiring

Hook logic is host-neutral and lives once in .prd_plugin/hooks/ (byte-identical to .claude/hooks/). Each host wires the same scripts differently: Claude Code via .claude/settings.json; Codex via .codex/hooks.json across all five events (SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, Stop) with the same payload shape and exit-2 block semantics as Claude; opencode via a JavaScript plugin (.opencode/plugins/prd-hooks.js) mapping session.idle to Stop-like behavior and tool.execute.before to PreToolUse. opencode's session.idle is non-blocking, so opencode alone cannot enforce run-until-done; the gate and CI are the portable backstop.

The gate: composition, not reimplementation

prd_gate.py composes the existing validators (state_consistency_check, release_check) and adds checks seeded by real past failures (duplicate IDs, version markers out of sync including already-published-on-npm, implemented-without-graduated_to, stranded outbox, autonomy-tier violations). It reads the config policy flags that would otherwise be dormant, so the gate is where advisory policy becomes enforced. state_consistency_check.py is installed by default beside the downstream gate; a missing validator is itself an error rather than a silent skip.

Recipes — common tasks end to end

Copy-pasteable paths for the things operators and agents do most. Each recipe stands alone.

Install PRD Plugin into a repo

cd my-repo
npx prd-install .            # also creates/merges the managed root .gitignore block
python .prd_plugin/scripts/prd_status.py   # confirm the state store is live

Update the plugin without losing state

npm update prd-plugin
npx prd-install . --force    # refreshes hooks/skills/scripts/templates; preserves state + config

Turn on drift detection with an on-Stop check

python scripts/prd_config.py set drift.monitoring.enabled true
python scripts/prd_config.py set drift.monitoring.on_stop true
python scripts/drift_monitor.py            # run it now

Turn on Stop reflections and inspect the question bank

python scripts/prd_config.py set reflection.enabled true
python scripts/prd_reflections.py list --json
python scripts/prd_reflections.py update question RFQ-005 --disabled

The first eligible Stop asks the active questions and writes only a hashed local session marker. The immediately following Stop consumes that marker and allows completion, preventing an infinite reflection loop.

Enable the AI-Collab Substrate adapter in observe mode

python .prd_plugin/scripts/prd_config.py set integrations.substrate.enabled true
python .prd_plugin/scripts/prd_config.py set integrations.substrate.mode observe
python .prd_plugin/scripts/prd_substrate.py handshake --repo-root .

Use coordinate only with the additional capability names the runtime needs. Substrate remains a derived mirror; writes still use PRD MCP.

Check for a newer plugin version

python scripts/prd_version_check.py        # npm-vs-installed, cached, fail-open

Plan and run a deterministic workflow

python scripts/prd_workflows.py --repo-root . audit --json
python scripts/prd_workflows.py --repo-root . plan engineering.verify --inputs '{}'
python scripts/prd_workflows.py --repo-root . run engineering.verify --inputs '{}'

Use the equivalent prd_workflow_* MCP tools from an agent. If a run reaches waiting_judgment, AI-Collab receives only the declared, source-hashed request and result schema; deterministic validation must accept the result before the run can continue.

Build or query the LLM wiki

python scripts/prd_wiki_backfill.py        # build/backfill articles
python scripts/prd_wiki_backfill.py --drift --format json   # detect stale/unstamped/missing articles

File a request (bug/change/feature)

Invoke the project-request-intake skill (or the prd_file_request MCP tool). It allocates the next REQ-* from the registry and appends to requests.json with severity, risk, and provenance — never a hand-typed ID.

4. Operations — run, deploy, configure

PRD Plugin runs as files in a repo, not a service; "operating" it means installing/updating it, setting config knobs, and running its release ceremony in the hub. There is nothing to stand up on a server.

Stand it up

One command in a target repo: npx prd-install .. Update with npm update prd-plugin && npx prd-install . --force (state- and config-preserving). Never add --yes to an update: it requests a destructive reset, is refused in non-interactive sessions, and requires the exact interactive phrase RESET PRD STATE. The hub itself needs Python 3 (stdlib only) and Node for the MCP server and installer.

Configuration knobs and defaults

Managed by scripts/prd_config.py and stored in .prd_plugin/config.json. The unified catalog covers every shipped persistent setting and reports type, owner, mutability, activation, dependencies, and latency. inventory also reports environment, installer, host-wiring, specialized-CRUD, and invocation-only controls. Validated writes are atomic and formatting-preserving; lean, balanced, and thorough profiles can be previewed before apply and never auto-enable external integrations. Core runtime hook controls include:

KeyDefaultControls
hooks.enabledtrueMaster switch for all host hook behavior.
hooks.nudge.on_user_prompttruePer-prompt routing nudge and its TTL-gated update checks.
hooks.session_report.enabledtrueConfigured Stop reporting work.
hooks.skill_log.enabledtrueHigh-frequency post-tool skill logging.
hooks.workflow.enabledtruePermit lifecycle events to dispatch the configured deterministic start/stop workflows.
workflows.enabledtrueMaster switch for workflow planning and execution.
workflows.enabled_workflow_idsshipped catalogExplicit workflow allowlist for this use case/profile.
workflows.allow_state_mutationstruePermit only allowlisted MCP mutation actions from workflows.
workflows.judgment.executorai-collabExternal runtime responsible for declared non-deterministic judgment requests.
workflows.judgment.profilefast-capableConfigurable AI-Collab model profile for source-backed judgment.
workflows.judgment.fallbackfailExternal-runtime fallback policy; the deterministic engine never silently substitutes an LLM.
automation.autonomy_levelautonomousHow much the agent decides vs. asks; the ship-consent tier.
automation.autonomous_run_until_donetrueThe Stop guard keeps working toward the active goal in autonomous.
automation.autonomous_continue_cap25Max consecutive auto-continues per session before allowing a stop.
automation.precommit_gatetrueBlock git commit when the gate has error-severity findings.
automation.graph_auto_refreshfalseRegenerate the traceability graph on Stop.
automation.version_check.enabledtrueAuto-check npm for a newer plugin version (cached, fail-open).
automation.version_check.ttl_hours1How long the version-check result is cached before re-querying npm.
drift.monitoring.enabledfalseThe drift monitor (validators + snapshots/events).
drift.monitoring.on_stopfalseRun a cheap drift check on every Stop and surface a summary.
drift.monitoring.export.enabledfalseAlso append drift events to a committed/shared feed.
drift.monitoring.export.path.prd_plugin/drift/events.jsonlWhere the exported (committed) drift-event feed is written.
reflection.enabledfalseMaster switch for categorized reflection questions when the host reaches Stop/idle.
reflection.on_stoptruePermit the reflection hook to run on Stop when the master switch is enabled.
reflection.max_questions_per_stop5Bound the number of effectively active questions included in one reflection pass (1–50).
integrations.substrate.enabledfalseMaster switch for the AI-Collab Substrate adapter.
integrations.substrate.modeoffSelect inert, read-only observe, or capability-gated coordinate behavior.
integrations.substrate.capabilitiesrecords, graph, eventsExplicit allowlist; coordinate-only functions are unavailable unless named.
knowledge.llm_wiki.enabledtrueThe LLM wiki (query-before-re-derive, ingest-on-close, backfill).

python scripts/prd_config.py inventory --json and list --json are machine contracts. Agents use the equivalent prd_config_list, prd_config_get, prd_config_set, and prd_config_profile MCP tools. Each host event launches one dispatcher process, which checks these switches before importing disabled behavior.

Autonomy tiers

Three tiers set by automation.autonomy_level (change via python scripts/prd_gate.py set-autonomy <level>): guided and key_decision require explicit consent before push/merge/publish; autonomous makes the tier itself the standing consent — the agent ships the work end-to-end (commit, push, merge to the work's own main, tag, publish) provided the gate is green, and never ships red. What never unlocks in any tier: committing/exposing secrets, force-push or history destruction, editing an unrelated repo, or irreversible external spend. Local commits on a work branch never need consent in any tier.

Release ceremony (hub only)

Cutting a version bumps every version marker (the marker set plus package.json and index.js), adds entries to the releases ledgers, graduates the driving REQ-* to implemented with a graduated_to, appends CHG-*/EV-*, and updates the registry counters — then runs the full gate green before merge/tag/publish to npm. In this hub the remote v* tag push is the publication action: .github/workflows/npm-publish.yml checks out the tag, runs tests and package verification, and publishes to npm. Agents must not run npm publish locally or treat missing local npm credentials as a release blocker. After a successful tag push, treat the release as published unless the owner reports otherwise. Only then inspect or rerun the GitHub Actions Publish to npm workflow to distinguish workflow failure from registry lag.

5. Design decisions & re-open triggers

The load-bearing decisions behind PRD Plugin's shape, and what would make each worth revisiting. These are the choices a newcomer most often questions.

DecisionWhyRe-open when
Tiered consent floor with a never-unlock setSome actions (secrets, history destruction, unrelated repos, external spend) must stay blocked regardless of tier.A new class of irreversible action appears that the floor does not name.
Stable IDs from a single registry; no invented recordsTraceability and grounding depend on IDs that were actually allocated; the gate can then reject phantom references.Never for the core; only to add a new record type (extend the registry, not bypass it).
One canonical skill set, byte-identical mirrorsEach host discovers skills from a different path; identical mirrors keep behavior consistent and testable.Hosts converge on a single shared skills location, or a host needs genuinely divergent skill content beyond the two adapted variants.
Host-neutral hook scripts, thin per-host wiringWrite the check once; only the tiny wiring differs per host, so parity is cheap to maintain.A host's hook model diverges enough that shared scripts no longer fit.
Stop reflections are opt-in and recursion-boundedReflection can improve behaviour and expose harness friction, but enabling it silently on every downstream upgrade would interrupt existing workflows. A local one-pass marker makes the feature useful without creating an endless Stop/re-prompt cycle.Hosts provide a portable native reflection lifecycle with equivalent recursion protection and explicit persistence semantics.
Substrate is a derived runtime, not project truthPRD Plugin retains schemas, IDs, locking, source references, and validation; AI-Collab can index and coordinate without creating a second writer or exposing local state.A future substrate can prove equivalent canonical allocation, locking, validation, and audit guarantees.
Deterministic authority below explicit judgmentBounded mechanics are more reliable, faster, auditable, and cheaper as validated workflows. Irreducible judgment is isolated in source-hashed, schema-bound requests executed by AI-Collab, while canonical mutations remain deterministic.A currently judgment-bound decision gains a complete deterministic policy, or the external runtime cannot honor the request/hash/schema contract.
opencode cannot enforce run-until-donesession.idle is non-blocking, so the Stop guard can't hold opencode in the loop; accepted as a host limitation.opencode adds a blocking idle/stop hook — then wire run-until-done there too.
Complexity/confidence ratings, never time estimatesTime estimates from an agent are false precision; complexity + confidence + risk carry the real signal.Never — this is a hard method rule.
LLM wiki separate from the state storeState records durable facts/records (IDs, decisions); the wiki holds durable knowledge queried before re-derivation. Different lifecycles.The two collapse into one representation without losing the query-before-re-derive workflow.
Generate/merge downstream .gitignore in the installer, not the skeletonnpm packing excludes files named .gitignore; a skeleton file silently fails to reach npm consumers. A marked installer-owned block is package-safe, upgradeable, idempotent, and preserves project rules.npm gains a reliable way to transport dot-ignore files, or downstream repositories adopt another shared ignore mechanism.

6. Verification — how claims are proven

Every claim in this manual is backed by a test, a script, or a reproducible command. PRD Plugin holds itself to the same grounding rule it ships: verify before claiming done, cite real output.

Test suite

The hub carries a stdlib unittest suite. Release-wide verification for version 0.15.0 runs the complete discovered suite:

$ python -m unittest discover -s tests
...
OK

Included are data-driven parity tests that assert the seven skill mirrors are byte-identical (except the two adapted skeleton variants), Windows-console-safety tests that reject non-ASCII in Python source (a real past crash class), and installer tests that assert --force preserves state/config while refreshing plugin files. The installer suite also invokes git check-ignore --no-index to prove generated/runtime paths are ignored while committed PRD Plugin truth stays trackable.

The five gates

Before any release the following must be green, and the same checks compose into prd_gate.py for commit-time enforcement:

python -m unittest discover -s tests                 # unit + parity + safety
python scripts/state_consistency_check.py --repo-root .   # cross-record integrity -> ok
python scripts/release_check.py                      # version markers / ledger
python scripts/gap_audit.py --target-version 0.15.0  # coverage gaps
python scripts/workflow_chml_audit.py --repo-root . --format json  # C/H/M/L -> 0
python scripts/prd_gate.py                           # composite gate (reads policy flags)

Drift detection

The drift monitor re-runs the validators and flags when documentation, state, the wiki, or this ingest manual have fallen behind the code. Wiki drift is measured by commit-stamp staleness; ingest-manual drift is source-path-aware — it flags precisely when a file the manual cites has changed since the manual's commit stamp (silent for unrelated churn), and immediately if the manual becomes unstamped or non-conformant. A repo that consumes an external fork can also enable a fork-version check that polls a configured source (a static manifest or a node /v1/status) and surfaces a newer fork version on Stop — inert unless configured. It writes snapshots and a compact drift-event feed and can run a cheap subset on every Stop.

Evidence records

Completion claims in this repo are backed by EV-* records in the state store, linked from the REQ-*/TRK-* that drove the work. A claim of "done" with no evidence record and no reproduction command does not pass the method — and this manual follows that rule: its counts (29 skills, 35 MCP tools, 13 commands, version 0.15.0) were each captured by running the command shown, not recalled.