| name | pharaoh-release |
| description | Use when preparing a release, generating changelogs from requirements, or summarizing requirement changes for version management |
Output invariant
This skill's visible output is the full release report (changelog plus release summary) as defined in Step 7. The report is mandatory. Every invocation MUST emit the complete report. The session-state update is internal bookkeeping. The skill is self-terminating. No interactive prompt at the end of the turn.
Failure modes:
- Ending the turn with a "save these release artifacts?" prompt instead of the report -> REGRESSION. Emit the full report and end the turn.
- Returning a brief summary instead of the full changelog and release summary -> REGRESSION.
File-save behaviour is controlled by an input flag (save_artifacts), not an interactive prompt. See Step 7.2 below.
pharaoh-release
Generate release artifacts from sphinx-needs changes. This skill identifies which
requirements, specifications, implementations, and test cases changed between
releases, produces structured changelogs and release notes, and computes
traceability coverage metrics suitable for safety-critical audit trails. In
enforcing mode, release is gated by prior verification (and optionally MECE
analysis).
When to Use
- Preparing a release and need a changelog of requirement-level changes.
- Summarizing what needs were added, modified, or removed since the last release or tag.
- Producing traceability coverage metrics for compliance or audit documentation.
- Generating release notes that include requirement impact chains.
Input
save_artifacts (optional, default none): one of none | changelog | release_notes | both. Controls whether the skill writes the rendered changelog/release-notes artifacts to disk in addition to emitting them in the turn output. Pass explicitly when calling non-interactively. Defaults to none so a bare invocation never silently writes files.
Prerequisites
This skill has workflow gates. Follow the strictness check in Step 1 before
proceeding to the release process.
Process
Execute the following steps in order.
Step 1: Strictness Check
Follow the decision flow defined in skills/shared/strictness.md, Section 5.
1a. Read strictness configuration
- Look for
pharaoh.toml in the workspace root.
- Read
[pharaoh] to determine the strictness level ("advisory" or "enforcing").
- Read
[pharaoh.workflow] for the gate settings:
require_verification (default: true)
require_mece_on_release (default: false)
- If
pharaoh.toml does not exist, treat strictness as "advisory".
1b. Advisory mode
If strictness = "advisory":
- Proceed directly to Step 2 without blocking.
- After the release output is complete (Step 6), check whether prerequisites were
skipped and show relevant tips (at most one per missing prerequisite):
| Missing prerequisite | Tip |
|---|
| no review skill run | Tip: Consider running the appropriate review skill (e.g. pharaoh:req-review) to validate implementations before release. |
pharaoh:mece not run | Tip: Consider running pharaoh:mece to check for gaps before release. |
Do not show a tip if the corresponding workflow gate is disabled in pharaoh.toml
(e.g., do not show the MECE tip if require_mece_on_release = false).
1c. Enforcing mode
If strictness = "enforcing":
- Read
.pharaoh/session.json (see skills/shared/strictness.md, Section 4).
- Check verification gate (if
require_verification = true):
- Check MECE gate (if
require_mece_on_release = true):
- If any gate fails, stop. Do not proceed to Step 2.
- If all gates pass, proceed to Step 2.
1d. User bypass
If the user explicitly requests to skip a gate check (e.g., "proceed anyway" or
"skip the check"), respect the request. Log a warning:
Warning: Skipping verification gate at user request. Workflow compliance is not guaranteed.
Proceed with Step 2. Do not update session state to indicate the prerequisite was met.
Step 2: Get Project Data
Follow the instructions in skills/shared/data-access.md to:
- Detect the project structure (find
ubproject.toml, conf.py, source directories).
- Read the project configuration (need types, extra_links, ID settings).
- Determine the data access tier (ubc CLI > ubCode MCP > raw file parsing).
- Build the needs index with all needs and their attributes.
- Build the link graph with all relationships in both directions.
- Detect sphinx-codelinks configuration.
- Read
pharaoh.toml for traceability requirements (required_links).
After completing data access, present the detection summary before proceeding:
Project: <name> (<config source>)
Types: <list of directive names>
Links: <list of link type names>
Data source: <tier used>
Needs found: <count>
Strictness: <advisory|enforcing>
If detection fails (no project found, no needs in source files), report the issue
and ask the user for guidance. Do not proceed with empty data.
Step 3: Determine Release Scope
Identify which version this release covers and what to compare against.
3a. Get version identifier from user
Ask the user for the release version if not already provided:
What version is this release?
- Enter a version string (e.g., v1.2.0)
- Or type "since last release" to auto-detect from the latest git tag
If the user provides a version string, record it as the release version.
3b. Find the comparison baseline
Determine the baseline to compare against:
If the user said "since last release" or provided no baseline:
- Run
git tag --sort=-v:refname to list tags in reverse version order.
- Take the most recent tag as the baseline.
- If no tags exist, use the initial commit as the baseline.
- Confirm with the user:
Comparing against: <tag> (<date>)
Proceed? [yes/no]
If the user provided a specific baseline (a tag, branch, or commit):
- Verify the reference exists with
git rev-parse <ref>.
- If it does not exist, report the error and ask for a valid reference.
3c. Determine changed files
Use git to find which documentation files changed between the baseline and HEAD:
git diff --name-only <baseline>..HEAD -- <source_directories>
Filter to only RST and MD files (the files that can contain need directives).
Record the list of changed files.
If ubc diff is available (the ubc CLI was detected and supports the diff
subcommand), prefer it for structural diff:
ubc diff <baseline>..HEAD --format json
This provides a precise need-level diff rather than file-level, which is more
accurate for detecting added, modified, and removed needs.
Step 4: Identify Changed Needs
Categorize every need change into one of three buckets: new, modified, or removed.
4a. Using ubc diff (Tier 1)
If ubc diff is available and returned JSON output in Step 3c, parse it directly.
The output provides need-level changes with before/after states. Map each entry to
the appropriate bucket.
4b. Using git diff with raw parsing (fallback)
If ubc diff is not available, analyze changes manually:
Find new needs:
- For each changed file, run
git diff <baseline>..HEAD -- <file>.
- In the diff output, look for added lines (prefixed with
+) that contain
need directives: .. <type>:: where <type> is one of the configured
directive names.
- For each added directive, parse the full need (title, ID, options) from the
current version of the file.
- Record as a new need.
Find removed needs:
- In the diff output, look for removed lines (prefixed with
-) that contain
need directives.
- Parse the full need from the old version (use
git show <baseline>:<file>
to read the old content).
- Verify the need ID no longer exists in the current needs index.
- Record as a removed need.
Find modified needs:
- For each need ID that appears in both the baseline and current versions of
changed files, compare the need's attributes:
- Title changed
- Status changed
- Content/body changed
- Options changed (tags, links, custom options)
- Link targets changed
- For each attribute that differs, record the old and new values.
- Record as a modified need with a list of changed attributes.
4c. Build the change summary
Organize all changes into a structured summary:
Changes detected:
New needs: <count> (<breakdown by type>)
Modified needs: <count> (<breakdown by type>)
Removed needs: <count> (<breakdown by type>)
Unchanged: <count>
For each modified need, also identify its impact chain: the set of needs
linked to it (upstream and downstream) that may be affected by the change. Use the
link graph built in Step 2 to trace one level in each direction.
Step 5: Generate Changelog
Build a structured changelog from the change summary.
5a. Changelog format
Use the following markdown template. Group changes by need type. Within each
group, sort by need ID.
## Release <version> - <date>
### Summary
- **<count>** new needs added
- **<count>** needs modified
- **<count>** needs removed
- **<total>** total needs in project
### New Requirements
- **REQ_004**: <title> [<status>]
<brief description or first sentence of content>
### New Specifications
- **SPEC_005**: <title> [<status>]
Linked to: REQ_004
### New Implementations
- (none)
### New Test Cases
- (none)
### Modified Requirements
- **REQ_001**: <title>
- <attribute>: <old value> -> <new value>
- Impact: <list of directly linked need IDs that may need review>
### Modified Specifications
- **SPEC_001**: <title>
- content: updated acceptance criteria
- Impact: IMPL_001, TEST_001
### Modified Implementations
- (none)
### Modified Test Cases
- (none)
### Removed Requirements
- (none)
### Removed Specifications
- (none)
### Removed Implementations
- (none)
### Removed Test Cases
- (none)
### Traceability Changes
- New links: <list of new link pairs, e.g., SPEC_005 -> REQ_004>
- Removed links: <list of removed link pairs>
- Modified links: <list of needs whose link targets changed>
### Verification Status
- All modified needs verified: <yes/no>
- Unverified needs: <list of IDs, or "none">
- MECE analysis: <passed / not run>
- Open MECE issues: <count, or "N/A">
Adapt the type sections to the project's configured types. If the project
defines custom types beyond the standard four (e.g., story, hazard,
constraint), generate sections for each type that has changes. Omit type
sections that have no changes in any category (no new, no modified, no removed).
5b. Changelog for custom need types
For each need type defined in the project configuration, generate the
corresponding "New", "Modified", and "Removed" sections only if that type has at
least one change. Use the type's title field from the configuration for the
section heading (e.g., "New Hazard Analyses" for a type with title = "Hazard Analysis").
5c. Verification status section
Populate the verification status from session state (.pharaoh/session.json):
Step 6: Generate Release Summary
Produce a high-level summary with coverage metrics.
6a. Needs inventory
Count all needs in the current project by type and status:
Needs Inventory
===============
Type Total draft approved implemented verified
Requirement 12 2 5 3 2
Specification 10 1 4 3 2
Implementation 8 0 2 4 2
Test Case 7 0 1 3 3
--------------------------------------------------------------
Total 37 3 12 13 9
Adapt the status columns to the project's actual status values. If the project
uses different statuses (e.g., open, in_progress, closed), use those instead.
6b. Traceability coverage metrics
Calculate coverage percentages based on required_links from pharaoh.toml:
For each required link chain (e.g., "req -> spec"):
- Count the number of source-type needs (e.g., all
req needs).
- Count how many have at least one link to a target-type need (e.g., linked to
at least one
spec).
- Calculate:
coverage = linked_count / total_count * 100
Present as:
Traceability Coverage
=====================
Chain Covered Total Coverage
req -> spec 10 12 83.3%
spec -> impl 8 10 80.0%
impl -> test 7 8 87.5%
Full chain (req->test) 6 12 50.0%
The "Full chain" row traces the complete path from top-level needs to leaf needs.
A source need is "fully covered" only if there is a complete path through all
intermediate types to the final type in the chain.
If required_links is not configured, skip this section and note:
Traceability coverage: Not configured.
Add [pharaoh.traceability] required_links to pharaoh.toml to enable coverage metrics.
6c. Open issues from MECE analysis
If pharaoh:mece was run in this session (check global.mece_checked in session
state), summarize any open issues that were identified:
- Orphaned needs (needs with no incoming or outgoing links)
- Gaps in required link chains
- Redundant or overlapping needs
- Inconsistent statuses (e.g., a
verified need linked to a draft specification)
If MECE was not run, note:
MECE Issues: Not available (pharaoh:mece has not been run this session).
6d. Codelinks summary
If sphinx-codelinks is enabled, include a code traceability summary:
Code Traceability
=================
Needs with code references: <count> / <total>
Code files referencing needs: <count>
Step 7: Output and Next Steps
The sub-steps below run in this fixed order: session-state update first
(internal bookkeeping), then artifact writes per the save_artifacts input
flag (silent side effects), and finally the visible release report. The
report is the LAST instruction in the skill so it is the last visible turn
content. The skill MUST end the turn after the report. No interactive
prompts.
7.1. Update session state (internal)
Run this BEFORE emitting any visible output. Update .pharaoh/session.json:
- Read the current session state (or create the initial structure).
- Set
global.last_release to the current ISO 8601 timestamp.
- Set
updated to the current ISO 8601 timestamp.
- Write the updated JSON back to
.pharaoh/session.json.
This is internal bookkeeping. It MUST NOT produce any visible turn output.
7.2. Write artifacts per save_artifacts input flag
Branch on the save_artifacts input value (default none):
none: do nothing. The output was already presented.
changelog: append the changelog entry to CHANGELOG.md (Option 1 logic below).
release_notes: write docs/releases/<version>.md (Option 2 logic below).
both: execute both branches in order.
Do NOT ask the user. Callers that want to choose interactively pass the flag explicitly.
changelog branch (append to CHANGELOG.md):
- Check if
CHANGELOG.md exists in the workspace root.
- If it exists, read its current content. Insert the new changelog entry at the top, after any existing header (e.g. after a
# Changelog line).
- If it does not exist, create it with a
# Changelog header followed by the new entry.
release_notes branch (write docs/releases/<version>.md):
- Create the
docs/releases/ directory if it does not exist.
- Write the full release notes (changelog plus release summary) to
docs/releases/<version>.md.
both branch: execute both branches in order.
7.3. Emit the release report (final visible output)
This sub-step is the LAST instruction in the skill and produces the LAST
visible turn content. After emitting the report, end the turn. Do not ask
follow-up questions.
Display the complete changelog (from Step 5) and release summary (from
Step 6) to the user in a single output. Append the tag suggestion below as
the final footer line of the report.
Tag suggestion footer (append at the end of the report):
Suggested next step:
git tag -a <version> -m "Release <version>"
(Run the tag command manually if desired. The skill does not run git tag
automatically.)
The skill MUST NOT execute git tag itself. The skill MUST NOT ask the
user whether to create the tag. The footer is informational only.
Key Constraints
-
Never run git tag or git push. The skill MUST NOT execute either
command. The release report includes a tag suggestion as a footer line so the
user can run it manually. The skill MUST NOT prompt the user about tagging.
-
File writes are gated by the save_artifacts input flag. The skill MUST
NOT prompt the user before writing CHANGELOG.md or docs/releases/<version>.md.
The flag is the contract. Default none means no files are written. When the
flag selects a write branch, perform the write without asking.
-
Include traceability metrics for safety-critical audit trails. The release
summary must always include the needs inventory and traceability coverage
metrics. These are essential for compliance in regulated industries (automotive,
aerospace, medical device).
-
Support both full release notes and incremental changelogs. The changelog
(Step 5) captures incremental changes for this release. The release summary
(Step 6) captures the full project state. Both are produced every time.
-
Adapt to project-specific types and statuses. Do not hardcode need types
(req, spec, impl, test) or status values (draft, approved). Read
the project configuration and use whatever types and statuses the project
defines. Generate changelog sections dynamically.
-
Handle missing git history gracefully. If the project is not a git
repository, or if there are no tags, report the limitation:
This workspace is not a git repository (or has no tags).
Cannot determine changes since last release automatically.
Please provide the set of changed need IDs manually, or specify two
file snapshots to compare.
Then allow the user to provide change information manually and proceed
with changelog generation from that input.
-
Handle empty releases. If no needs changed between the baseline and HEAD,
report:
No requirement changes detected between <baseline> and HEAD.
If documentation files changed but no need directives were affected,
this is a documentation-only release with no requirements impact.
Still offer to generate the release summary (Step 6) since the project
inventory and coverage metrics may be useful even without changes.
-
Respect the data access tier hierarchy. Always prefer ubc CLI (ubc diff)
for change detection when available. Fall back to git diff with raw parsing
only when ubc is not available. The structural diff from ubc is more precise
than text-based diff parsing.
-
Do not modify any need directives. This skill is read-only with respect to
documentation source files. It generates release artifacts and writes them to
dedicated output files (CHANGELOG.md, docs/releases/). It never modifies RST
or MD files containing need directives.