From pharaoh
Records canonical decisions, facts, or preferences in shared Papyrus workspace with automatic deduplication on (type, canonical_name). Returns action and papyrus_id for multi-agent coordination and ADR capture.
How this skill is triggered — by the user, by Claude, or both
Slash command
/pharaoh:pharaoh-decision-recordThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Invoke from any authoring or multi-agent coordination workflow that needs to record a canonical named item (architecture decision, domain fact, style preference) in a way that survives concurrent writers without duplication. Typical callers: `pharaoh-req-from-code` (when a type or concept is first surfaced), `pharaoh-decide` chains, multi-agent reverse-engineering fan-out.
Invoke from any authoring or multi-agent coordination workflow that needs to record a canonical named item (architecture decision, domain fact, style preference) in a way that survives concurrent writers without duplication. Typical callers: pharaoh-req-from-code (when a type or concept is first surfaced), pharaoh-decide chains, multi-agent reverse-engineering fan-out.
Do NOT invoke for informational or non-canonical observations, and do NOT invoke when pharaoh-finding-record is a better fit (audit-finding category + subject_id tuple).
{type: "dec"|"fact"|"pref", canonical_name: str, body: str, tags?: list[str], reporter_id: str}. Output: {action: "wrote"|"duplicate"|"error", papyrus_id: str, dup_of?: str, message?: str}.(type, canonical_name) must produce exactly 1 "wrote" + 1 "duplicate"; measured via fixture.type: one of dec (decision), fact (domain fact), pref (preference). Controls the Papyrus need type.canonical_name: canonical identifier for the subject. Style (snake_case, CamelCase, etc.) MUST match the frozen vocabulary if one exists for the project. If the caller is unsure, it MUST first invoke pharaoh-context-gather and reuse an existing canonical before coining a new one.body: 1-3 sentence description. Stored verbatim as the Papyrus need body.tags: optional list of free-form tags.reporter_id: caller identifier (e.g. req-from-code:health_monitor.cpp). Stored in the Papyrus need source field for traceability.Exactly one single-line JSON object, no prose:
{"action": "wrote", "papyrus_id": "FACT_HealthMonitor"}
or:
{"action": "duplicate", "papyrus_id": "FACT_HealthMonitor", "dup_of": "FACT_HealthMonitor"}
or, on subprocess failure:
{"action": "error", "papyrus_id": "FACT_HealthMonitor", "message": "<stderr-first-line>"}
papyrus_id = uppercase(type) + "_" + sanitize(canonical_name)
sanitize replaces non-alphanumeric characters with underscores, collapses consecutive underscores, strips leading/trailing underscores. Case is PRESERVED (do not lowercase).
Examples:
("fact", "HealthMonitor") → FACT_HealthMonitor("fact", "heartbeat_timeout") → FACT_heartbeat_timeout("dec", "use thread pool for monitors") → DEC_use_thread_pool_for_monitorspapyrus addpapyrus --workspace .papyrus add <papyrus_need_type> \
"<canonical_name>" \
--id <papyrus_id> \
--body "<body>" \
--tags "canonical:<canonical_name>,<joined_tags>" \
--source "<reporter_id>" \
--scope local
The <papyrus_need_type> argument maps as: dec → decision, fact → fact, pref → preference.
{"action": "wrote", "papyrus_id": "<id>"}."already exists" → emit {"action": "duplicate", "papyrus_id": "<id>", "dup_of": "<id>"}.{"action": "error", "papyrus_id": "<id>", "message": "<stderr-first-line>"} and return; the caller must not retry.No surrounding prose. Emit exactly one JSON object per invocation.
(type, canonical_name). Body and tag differences do NOT suppress dedup — first writer wins and sets canonical body.reporter_id difference does NOT suppress dedup — two callers arriving at the same concept from different files still collapse to one record.papyrus_id are serialized by the Papyrus FileLock; only one succeeds, the others get "duplicate".FACT_HealthMonitor and FACT_healthmonitor do NOT dedup. The caller is responsible for consistent casing (via pharaoh-context-gather lookup before coining).papyrus binary missing → emit {"action": "error", "message": "papyrus CLI not found"}..papyrus/ workspace missing → emit {"action": "error", "message": "no .papyrus/ workspace in cwd"}.{"action": "error", "message": "<stderr-first-line>"}.pharaoh-finding-recordpharaoh-finding-record is the audit-specialized sibling: it constrains category to a known enum and derives IDs from (category, subject_id). pharaoh-decision-record accepts any (type, canonical_name) pair. Existing Phase 4b audit fan-out continues to use pharaoh-finding-record; Phase 4c's reverse-engineering fan-out uses pharaoh-decision-record.
A future cleanup may reimplement pharaoh-finding-record as a thin wrapper over pharaoh-decision-record; that refactor is out of scope for Phase 4c.
After emitting the artefact, invoke pharaoh-decision-review on it. Pass the emitted artefact (or its need_id) as target. Attach the returned review JSON to the skill's output under the key review. If the review emits any axis with score: 0 or severity: critical, return a non-success status with the review findings verbatim and do NOT finalize the artefact — the caller must regenerate (via pharaoh-decision-regenerate if available, or by re-invoking this skill with the findings as input).
See shared/self-review-invariant.md for the rationale and enforcement mechanism. Coverage is mechanically enforced by pharaoh-self-review-coverage-check in pharaoh-quality-gate.
Each caller invokes this skill once per canonical subject surfaced. The orchestrator or harness then reads the final Papyrus workspace via papyrus recall for the aggregated vocabulary.
npx claudepluginhub useblocks/pharaoh --plugin pharaohRecords design decisions as traceable sphinx-needs 'decision' directives with alternatives, rationale, and links to requirements. Use for documenting choices with full traceability in Sphinx projects.
Generates a complete Decision Record (ADR/PDR/TDR/BDR/ODR) from planning context and existing documentation, producing a canonical file with rationale, status, and metadata.
Records significant architectural decisions like database choices, frameworks, or core patterns in docs/decisions.md. Activates on major decisions, explicit requests, or proactively at session ends.