Author the canonical 3-tier domain → capability → feature catalog (features.yaml) from enriched-capabilities.yaml using the 5-point status vocabulary (planned | development | rollout | released | cleanup). Use this skill whenever product-keeper needs to materialise features.yaml during specify Stage 4b — after enrich-capabilities and before generate-intent-epics — or when any product-configuration workflow references authoring, updating, or regenerating the product feature catalog at .garura/product/scope/features.yaml. Emits a decision-manifest for inferred statuses so the orchestrator can drive the tiered surfacing flow.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Author the canonical 3-tier domain → capability → feature catalog (features.yaml) from enriched-capabilities.yaml using the 5-point status vocabulary (planned | development | rollout | released | cleanup). Use this skill whenever product-keeper needs to materialise features.yaml during specify Stage 4b — after enrich-capabilities and before generate-intent-epics — or when any product-configuration workflow references authoring, updating, or regenerating the product feature catalog at .garura/product/scope/features.yaml. Emits a decision-manifest for inferred statuses so the orchestrator can drive the tiered surfacing flow.
user-invocable
false
model
sonnet
allowed-tools
Read, Write, Grep, Glob
deprecated
true
deprecated_note
#434 ProductOS realignment — superseded by the command model; retained for Phase E reference, not installed
manage-features
Decision Surfacing Discipline (DSD): This skill emits a decision-manifest.yaml alongside its primary artifact. Every inferred status assignment or taxonomy inference is recorded with tier and grounding source. The orchestrator drives the tiered surfacing flow after this skill completes.
Model-invocable skill that produces the canonical feature catalog. Called by product-keeper during specify Stage 4b — between enrich-capabilities (Stage 4) and generate-intent-epics (Stage 5).
Purpose
generate-intent-epics needs a stable feature catalog to cross-check epic KB IDs against declared product features. Before this skill existed, the Stage-4 enriched record went directly to Stage 5 and the feature catalog was either reconstructed ad-hoc or hand-authored post-run. This skill closes that gap by materialising features.yaml at a well-known path with a well-known schema.
Input
Receive from product-keeper:
enriched_capabilities_path (path, required) — .garura/product/scope/garura:enriched-capabilities.yaml from Stage 4.
project_profile_path (path, required) — the frozen project profile YAML. Drives two decisions: (a) greenfield vs brownfield default-status logic, (b) reading any feature-status overrides the user declared.
stm_output_base (path, required) — base path for writes. features.yaml is written to {stm_output_base}/scope/features.yaml; the decision manifest goes to {stm_output_base}/scope/decision-manifest-manage-features.yaml.
ltm_rules_feature_catalog_path (path, required) — path to core/components/memory/standards/rules/feature-catalog.md (LTM). The skill loads this file first and enforces every rule in it against its output. When ltm_context is present in the calling contract, resolve via ltm_context.core_base; never hardcode source-repo paths.
Output
Return to caller:
features_path — absolute path to the written features.yaml.
features_count — integer count of feature entries written across all domains and capabilities.
decision_manifest_path — absolute path to the decision manifest.
decisions_recorded — integer count of decision entries. Must be ≥ 1 when any status was inferred (F3 fires otherwise).
Process
0. Load the feature-catalog rules
Read ltm_rules_feature_catalog_path (typically core/components/memory/standards/rules/feature-catalog.md). This file is the source of truth for how the catalog is authored — 3-tier hierarchy, ID regex, naming, 5-point status enum, required fields, summary counters, decision-manifest obligations. The narrative in this SKILL.md is a faithful summary; if the rules file and this SKILL.md ever drift, the rules file wins. Load it first so every downstream step applies its rules.
1. Load inputs
Read enriched-capabilities.yaml. Extract:
Domain slugs from each enriched capability's KB provenance header (domain field).
Capability slugs, their features, and each feature's feature_id, name, and supplemental fields the enrich step surfaced (notes, evidence references, gap items).
Read project-profile.yaml. Extract:
project_type — greenfield or brownfield. Absent → treat as greenfield.
Optional feature_status_overrides — a feature_id → status map for brownfield projects.
2. Build the 3-tier hierarchy
Group features by domain → capability → feature. Never flatten. The output shape:
summary:domains:<int>capabilities:<int>features_total:<int>features_planned:<int>features_development:<int>features_rollout:<int>features_released:<int>features_cleanup:<int>domains:-slug:<domain-slug>status:<freeform—NOT5-point>rollup_notes:>
<prose summary from enriched record, or blank>
capabilities:-slug:<capability-slug>status:<5-pointvocab>rollup_notes:>
<prose>
features:-id:<PREFIX-Fnnn>name:<nounphrase,3–10words>status:<5-pointvocab>notes:>
<prose>
# optional:evidence: [<pathorurl>, ...]
gap_items: [<string>, ...]
target_milestone:<versionstring>
3. Assign per-feature status
Apply per feature in order:
If project_profile.feature_status_overrides[feature_id] exists and is a valid 5-point value → use it. Pass-through, no decision entry.
Else if project_type == "brownfield" → planned (inferred — record decision at tier=mid, grounding_source=brownfield-default).
Else (greenfield) → planned (inferred — record decision at tier=high, grounding_source=greenfield-default).
Rollup to capability- and domain-level:
Capability status. Compute from its features using this precedence: if any feature is released → released; else if any is rollout → rollout; else if any is development → development; else if any is cleanup → cleanup; else planned.
Domain status. Leave freeform. If the enriched record or project profile supplies a domain-level rollup string (e.g., applied-and-evolving), pass it through verbatim. Do not coerce to the 5-point enum — C4 forbids it.
4. Write features.yaml
Write to {stm_output_base}/scope/features.yaml. Include a header comment block with:
Generation timestamp and play invocation context.
Status vocabulary reference (the 5-point enum).
A note that domain-level status is freeform and not validated.
Compute and populate the summary block counters from the per-feature status assignments.
5. Write the decision manifest
Write {stm_output_base}/scope/decision-manifest-manage-features.yaml. Each entry:
Record an entry only when a status was inferred — not when it was passed through from an override. F3 fires if any inference occurred and the manifest is empty.
R1 — Feature ID regex.^[A-Z]{2,4}-F\d{3}$. PREFIX (2–4 uppercase letters) must match the domain-slug abbreviation from the KB provenance header (e.g., Agentic Methodology → AM, Engineering Observability → EO, AI Governance → AG, Work Intelligence → WI, Engineering Experience → EE). IDs not matching the regex are not written.
R2 — Name format. Feature name is a noun phrase of 3–10 words. Verb phrases, imperative phrases, and single nouns are invalid. Example: Profile-Based Auto-Triage (valid). Triage users (invalid).
R3 — Required fields. Every feature entry carries id, name, status, notes. Optional: evidence, gap_items, target_milestone. Missing or null on any required field is a structural violation.
R4 — Domain mapping. Nest each capability under its canonical domain per the KB provenance header. Do not arbitrarily relocate capabilities across domains.
R5 — 3-tier shape.domains[].capabilities[].features[] is mandatory. Features must not appear at the domain or top level; capabilities must not appear at the feature level. Flattening is a structural violation.
Constraints
C1 — No invented IDs. Feature IDs are copied verbatim from the enriched record's feature_id field. Assigning an ID that does not appear in enriched-capabilities.yaml is a structural violation.
C2 — Default-status rule. Greenfield default is planned. Brownfield uses user-declared overrides where present; unresolved entries fall back to planned.
C3 — Per-feature and per-capability status enum. Values must belong to the 5-point enum: planned | development | rollout | released | cleanup. Any other value is rejected.
C4 — Domain-level status is freeform. Not validated against the 5-point enum. Strings like applied-and-evolving pass through unchanged. Coercing domain status into the 5-point vocab is a violation.
C5 — Not user-invocable. Model-invocable only, called by product-keeper during /specify Stage 4b. Direct user invocation is a protocol violation.
Failure Conditions
F1 — Missing artifact.features.yaml is absent or empty after the skill completes. Unconditional failure.
F2 — Bad status value. Any feature or capability entry carries a status outside the 5-point enum. Domain-level status is exempt.
F3 — Missing manifest when inference occurred. The decision manifest is absent or empty when at least one status was inferred (i.e., not passed through from an override).
Success Scenarios
S1 — Greenfield. Enriched record holds 23 capabilities / 85 features across 5 domains. Project profile has no pre-existing feature statuses. Every feature receives planned. Manifest records 85 entries at tier=high, grounding_source=greenfield-default. features_count=85, decisions_recorded=85.
S2 — Brownfield. Project profile declares overrides for 30 features (20 released, 10 rollout); the rest have no declared status. The 30 pass through verbatim (no manifest entries). The remaining features receive planned with manifest entries at tier=mid, grounding_source=brownfield-default. Both features_path and decision_manifest_path are present and non-empty.
References
Canonical example data: .garura/product/scope/features.yaml (the dogfooded Garura feature catalog — matches this schema).
Intent source (source of truth): core/components/skills/manage-features/reference/intent.yaml. Change behaviour there, not in SKILL.md.