# Root Cause Analysis: RECORDING_INTEGRITY Missing from execute.md Template

**Date**: 2026-03-07
**Analyst**: Rex (nw-troubleshooter)
**Severity**: HIGH -- DES validation will always reject prompts built from the execute.md template
**Status**: Root causes identified, fix proposed

---

## Problem Statement

The DES hook system requires 9 mandatory sections in every agent prompt, including `RECORDING_INTEGRITY` (section 7 of 9). The `execute.md` template -- the canonical source from which orchestrators build DES prompts -- does not contain a `# RECORDING_INTEGRITY` section header.

**Impact**: Any orchestrator that constructs a DES prompt by filling the execute.md template verbatim will produce a prompt that fails DES pre-invocation validation. The validator emits:

```
MISSING: Mandatory section 'RECORDING_INTEGRITY' not found
FIX: Add RECORDING_INTEGRITY section with valid skip prefixes
     (NOT_APPLICABLE, BLOCKED_BY_DEPENDENCY, APPROVED_SKIP, CHECKPOINT_PENDING)
     and anti-fraud rules. See ~/.claude/commands/nw/execute.md
```

The recovery guidance itself is circular -- it tells users to "See ~/.claude/commands/nw/execute.md" for a section that does not exist in that file.

**Scope**: Affects `/nw:execute` and `/nw:deliver` (which delegates to execute.md).

---

## Evidence Summary

| Source | Finding |
|--------|---------|
| `src/des/application/validator.py:61` | `RECORDING_INTEGRITY` listed in `MANDATORY_SECTIONS` |
| `src/des/application/validator.py:74-78` | Recovery guidance references `~/.claude/commands/nw/execute.md` |
| `src/des/application/prompt_validator.py:43` | Lists `RECORDING_INTEGRITY` as section 7 of 9 |
| `nWave/tasks/nw/execute.md` (full file) | No `# RECORDING_INTEGRITY` header exists anywhere |
| `nWave/tasks/nw/execute.md:91-117` | Template jumps from `# OUTCOME_RECORDING` to `# BOUNDARY_RULES` |
| `tests/des/conftest.py:143-146` | Test fixtures include `RECORDING_INTEGRITY` content (tests pass) |
| `src/des/application/orchestrator.py:604-612` | Comment lists 8 sections, omits `RECORDING_INTEGRITY` |
| Commit `0bc132fd` | Claims to update execute.md in message but file is not in changeset |

---

## Toyota 5 Whys Analysis

### Branch A: Missing Section in Template

**WHY 1A**: The execute.md template does not contain a `# RECORDING_INTEGRITY` section header.
[Evidence: `grep -n "RECORDING_INTEGRITY" nWave/tasks/nw/execute.md` returns zero matches. The template (lines 47-127) contains 9 section headers but uses `SKILL_LOADING` as one of them, not `RECORDING_INTEGRITY`.]

**WHY 2A**: The commit that introduced `RECORDING_INTEGRITY` as the 9th mandatory section (`0bc132fd`) did not include execute.md in its changeset.
[Evidence: `git diff 0bc132fd^..0bc132fd --name-only` lists 16 files; `nWave/tasks/nw/execute.md` is not among them. The commit message claims "execute.md: add skip prefixes, when-to-skip rules, anti-fraud rules" but this change was never applied to the file.]

**WHY 3A**: The commit message was written aspirationally (describing intended changes) rather than reflecting actual file changes. No automated check catches a discrepancy between commit message and actual changeset.
[Evidence: The commit message bullet "execute.md: add skip prefixes, when-to-skip rules, anti-fraud rules" does not correspond to any diff in the commit. The validator source code and test fixtures were updated, but the template file was overlooked.]

**WHY 4A**: The development process relied on manual completeness checking. There was no automated test that validates the execute.md template against the validator's `MANDATORY_SECTIONS` list, nor a CI check that verifies the template itself passes validation.
[Evidence: No test file in `tests/` loads `nWave/tasks/nw/execute.md` and runs it through `MandatorySectionChecker.validate()`. Test fixtures in `tests/des/conftest.py` hand-craft prompts that include all 9 sections, never sourcing from the actual template.]

**WHY 5A**: **ROOT CAUSE A** -- The template (execute.md) and the validator (validator.py) have no shared single source of truth and no automated cross-validation. They evolved independently with manual synchronization, creating an undetected drift.

**SOLUTION A**:
- *Immediate mitigation*: Add `# RECORDING_INTEGRITY` section to execute.md template between `# OUTCOME_RECORDING` and `# BOUNDARY_RULES` with the content defined in test fixtures.
- *Permanent fix*: Add a CI test that loads execute.md, extracts the DES template block, and runs it through `MandatorySectionChecker.validate()` to catch section drift.

---

### Branch B: Circular Recovery Guidance

**WHY 1B**: When validation fails due to missing `RECORDING_INTEGRITY`, the recovery guidance tells users: "See ~/.claude/commands/nw/execute.md" -- but that file does not contain the section.
[Evidence: `src/des/application/validator.py:77` contains the string `"and anti-fraud rules. See ~/.claude/commands/nw/execute.md"`.]

**WHY 2B**: The recovery guidance was written assuming the execute.md template would be updated in the same commit. Since the template was not updated, the guidance points to a non-existent section.
[Evidence: Same commit `0bc132fd` -- the guidance was added to `validator.py` in this commit, referencing a change to `execute.md` that was never made.]

**WHY 3B**: Recovery guidance content is a hardcoded string in the validator, not a generated reference validated against actual file content.
[Evidence: `RECOVERY_GUIDANCE_MAP` in `validator.py:67-81` contains static strings with no mechanism to verify that referenced files actually contain the referenced content.]

**WHY 4B**: No test validates that recovery guidance references are resolvable (i.e., that referenced files and sections actually exist).
[Evidence: `tests/installer/unit/test_template_validator.py` tests that guidance is *generated* but never that guidance *references* are valid.]

**WHY 5B**: **ROOT CAUSE B** -- Recovery guidance references are not validated against actual content, allowing dead references to be committed and shipped.

**SOLUTION B**:
- *Immediate mitigation*: Once execute.md is fixed (Solution A), the reference becomes valid.
- *Permanent fix*: Either remove file references from guidance (make guidance self-contained) or add a test that validates all `See ...` references in recovery guidance map resolve to actual content.

---

### Branch C: Stale Orchestrator Comment

**WHY 1C**: The `render_full_prompt` method in `orchestrator.py` lists only 8 sections in its comment block and omits `RECORDING_INTEGRITY`.
[Evidence: `orchestrator.py:604-612` lists DES_METADATA, AGENT_IDENTITY, TASK_CONTEXT, TDD_8_PHASES, QUALITY_GATES, OUTCOME_RECORDING, BOUNDARY_RULES, TIMEOUT_INSTRUCTION. Also uses stale name `TDD_8_PHASES` instead of `TDD_PHASES`.]

**WHY 2C**: The comment was written before `RECORDING_INTEGRITY` was introduced and was not updated in commit `0bc132fd`.
[Evidence: The comment still references `TDD_8_PHASES` (from the 8-phase schema era, pre-v4.0). Both the section count and the phase name are stale.]

**WHY 3C**: Comments are not validated by any automated tool. They are documentation, not executable code, so drift is invisible to CI.
[Evidence: No linting rule or test validates comment content against the `MANDATORY_SECTIONS` constant.]

**WHY 4C**: The comment serves as the only documentation of "which sections render_full_prompt should assemble." Without it being executable, it becomes stale silently.
[Evidence: The method only renders 2 of the 9 sections (BOUNDARY_RULES and TIMEOUT_INSTRUCTION), with a note "For now, return minimal prompt...to satisfy tests." The comment was aspirational, describing a future complete implementation.]

**WHY 5C**: **ROOT CAUSE C** -- `render_full_prompt` was designed as a partial implementation with aspirational comments. The method was never completed to render all sections, and the comments drifted with no mechanism to catch the drift.

**SOLUTION C**:
- *Immediate mitigation*: Update comment to list all 9 sections including `RECORDING_INTEGRITY`, rename `TDD_8_PHASES` to `TDD_PHASES`.
- *Permanent fix*: Either complete `render_full_prompt` to render all 9 sections, or refactor the comment into a reference to `MandatorySectionChecker.MANDATORY_SECTIONS` so there is one source of truth.

---

## Cross-Validation

| Root Cause | Forward Trace | Symptoms Explained |
|------------|--------------|-------------------|
| A: Template/validator no shared source of truth | execute.md missing RECORDING_INTEGRITY -> orchestrators build incomplete prompts -> DES validation rejects them | Primary symptom (validation failure) |
| B: Unvalidated recovery guidance references | Guidance says "See execute.md" -> user checks execute.md -> section not found -> confusion | Secondary symptom (misleading error message) |
| C: Stale orchestrator comments | Developer reads comment listing 8 sections -> does not realize 9 are required -> builds incomplete prompt | Contributing factor (compounds root cause A) |

- Root Cause A + B: Consistent -- both stem from incomplete commit `0bc132fd` that updated validator but not template.
- Root Cause A + C: Consistent -- both show the pattern of aspirational documentation not backed by automation.
- All symptoms explained: Yes. The validation failure, circular guidance, and stale comment all trace to the same incomplete change propagation.

---

## Proposed Fix

### Immediate Mitigation (P0 -- restore correct behavior)

Add the missing `# RECORDING_INTEGRITY` section to `nWave/tasks/nw/execute.md`. Insert between `# OUTCOME_RECORDING` (ends at line 116) and `# BOUNDARY_RULES` (starts at line 118):

```markdown
# RECORDING_INTEGRITY
Valid Skip Prefixes: NOT_APPLICABLE, BLOCKED_BY_DEPENDENCY, APPROVED_SKIP, CHECKPOINT_PENDING
Anti-Fraud Rules:
- NEVER write EXECUTED for phases not actually performed
- NEVER invent timestamps -- DES CLI enforces real UTC timestamps
- DES audits all entries and detects integrity violations at finalize
```

Content sourced from `tests/des/conftest.py:143-146` (canonical test fixture).

### Permanent Fix (P1 -- prevent recurrence)

1. **Cross-validation test**: Add a test that loads `nWave/tasks/nw/execute.md`, extracts the DES template block (between the triple-backtick fences), and runs it through `MandatorySectionChecker.validate()`. This test fails if any mandatory section is missing from the template.

2. **Stale comment cleanup**: Update `orchestrator.py:604-612` comment to reference `MandatorySectionChecker.MANDATORY_SECTIONS` instead of maintaining a hardcoded list.

3. **Recovery guidance validation** (optional P2): Add a test that checks all `"See ..."` references in `RECOVERY_GUIDANCE_MAP` resolve to actual file content.

---

## Files Referenced

| File | Role |
|------|------|
| `/mnt/c/Repositories/Projects/nWave-dev/nWave/tasks/nw/execute.md` | Template missing `# RECORDING_INTEGRITY` |
| `/mnt/c/Repositories/Projects/nWave-dev/src/des/application/validator.py` | Defines 9 mandatory sections including `RECORDING_INTEGRITY` |
| `/mnt/c/Repositories/Projects/nWave-dev/src/des/application/prompt_validator.py` | Facade over validator, lists 9 sections |
| `/mnt/c/Repositories/Projects/nWave-dev/src/des/application/orchestrator.py` | `render_full_prompt` with stale 8-section comment |
| `/mnt/c/Repositories/Projects/nWave-dev/tests/des/conftest.py` | Test fixtures with correct `RECORDING_INTEGRITY` content |
| `/mnt/c/Repositories/Projects/nWave-dev/docs/architecture/design/deterministic-execution-system-design.md` | Design doc lists 8 sections (pre-RECORDING_INTEGRITY) |

## Commit Trail

| Commit | Description | Relevance |
|--------|-------------|-----------|
| `0bc132fd` | "add RECORDING_INTEGRITY as 9th mandatory section" | Added section to validator and tests but NOT to execute.md despite claiming to |
| `ef7cb960` | "optimize TDD cycle from 7-phase to 5-phase (schema v4.0)" | Modified execute.md (renamed TDD_7_PHASES to TDD_PHASES) but did not add RECORDING_INTEGRITY |
