WO Finish - DoD Validation and Closure
Overview
Complete a WO with full Definition of Done validation and artifact generation.
When to Use
- •Work is complete and committed
- •Ready to close WO and record SHA
Prerequisites
- •Git status clean - All changes committed
- •Tests passing - All verify commands pass
- •Session markers present - BOTH
[WO-XXXX] intent:AND[WO-XXXX] result: - •Scope respected - No files outside
scope.allow
Process
Step 0: Run Guard PRE-FINISH (REQUIRED)
This is NOT optional. Always run guard first.
# Verify in worktree git worktree list --porcelain | grep -A2 "$(pwd)" | grep "branch feat/wo-WO-XXXX" # Verify clean git status --porcelain # Verify BOTH markers exist (guard requires both) grep "\[WO-XXXX\] intent:" _ctx/session.md grep "\[WO-XXXX\] result:" _ctx/session.md
If ANY check fails → STOP → fix → retry
Note: PRE-FINISH does NOT check verdict.json (that's generated by finish).
Step 1: Run Verify Commands
# Check WO's verify commands grep -A 5 "verify:" _ctx/jobs/running/WO-XXXX.yaml # Run each command uv run pytest tests/unit/test_xxx.py uv run ruff check src/
Step 2: Log Session Result (if not done)
# If you haven't logged result yet trifecta session append --segment . \ --summary "[WO-XXXX] result: <what was completed>"
Both markers are REQUIRED:
- •
[WO-XXXX] intent:- logged when you took the WO - •
[WO-XXXX] result:- logged before finish
Step 3: Execute Finish
uv run python scripts/ctx_wo_finish.py WO-XXXX --result done
Step 4: Verify Artifacts (POST-FINISH)
Check _ctx/handoff/WO-XXXX/ for 5 required artifacts:
| Artifact | Purpose |
|---|---|
tests.log | pytest output |
lint.log | ruff output |
diff.patch | git diff vs merge-base |
handoff.md | Summary from WO metadata |
verdict.json | Validation verdict |
Step 5: Run Guard POST-FINISH
# Verify verdict exists and is PASS cat _ctx/handoff/WO-XXXX/verdict.json | grep '"result": "PASS"' # Verify WO moved to done cat _ctx/jobs/done/WO-XXXX.yaml | grep "status: done"
DoD Artifacts
All 5 artifacts are required:
# Verify all exist ls -la _ctx/handoff/WO-XXXX/ # Check verdict cat _ctx/handoff/WO-XXXX/verdict.json | jq '.verdict' # Should be "PASS"
Emergency Bypass Protocol
--skip-dod and --skip-verification are valid ONLY for emergencies.
Fail-Closed Rule
IF --skip-* is requested AND _ctx/incidents/INCIDENT-WO-XXXX-YYYY-MM-DD.md does not exist THEN STOP - DO NOT PROCEED
You CANNOT bypass without an INCIDENT NOTE.
INCIDENT NOTE Required
Before using bypass, create incident document:
# INCIDENT-WO-XXXX-YYYY-MM-DD ## Motivo [Why bypass is needed] ## Impacto [What is being skipped, risks assumed] ## Plan de Remediación [Actions to regularize later] ## Autorización [Who approved - even if it's you]
Save in: _ctx/incidents/INCIDENT-WO-XXXX-YYYY-MM-DD.md
Bypass Activation Methods
Method 1: Commit message marker (commit-msg hook)
git commit -m "fix: [emergency] schema fixes for legacy WOs"
Method 2: Environment variable (pre-commit hook)
TRIFECTA_HOOKS_DISABLE=1 \ TRIFECTA_WO_BYPASS_REASON="Schema fixes for legacy WOs" \ git commit -m "feat: ..."
Method 3: File marker
echo "Schema fixes" > .trifecta_hooks_bypass git commit -m "feat: ..." rm .trifecta_hooks_bypass
Note: The hook check_pending_commit_msg_bypass() reads from the pending commit file, not git log. This means [emergency] in commit message NOW works for new commits.
Bypass Commands
# 1. Create incident note FIRST mkdir -p _ctx/incidents cat > _ctx/incidents/INCIDENT-WO-XXXX-$(date +%Y-%m-%d).md << 'EOF' # INCIDENT-WO-XXXX ## Motivo [reason] ## Impacto [impact] ## Plan de Remediación [remediation] ## Autorización [who] EOF # 2. Verify note exists BEFORE bypass test -f _ctx/incidents/INCIDENT-WO-XXXX-*.md && echo "OK" # 3. Then bypass uv run python scripts/ctx_wo_finish.py WO-XXXX --result done --skip-dod
Follow-up Required
After bypass:
- •Create follow-up WO in backlog
- •Or register in
_ctx/backlog/backlog.yamlas debt
Bypass Output
BYPASS_USED=true INCIDENT_NOTE=_ctx/incidents/INCIDENT-WO-XXXX-2026-02-22.md FOLLOWUP_REQUIRED=true
Hook: validate_wo_metadata_update()
The hook validates that only allowed keys are modified in WOs in done/ or failed/:
Allowed Keys
- •
closed_at,closed_by,verified_at,verified_at_sha - •
evidence,result,x_governance_notes
Blocked Modifications
If you try to modify required_flow, scope, title, etc. in a done/failed WO:
[hooks] BLOCKED: disallowed key 'required_flow' modified in _ctx/jobs/done/WO-XXXX.yaml
When This Matters
Legacy WO schema fixes (like adding required_flow) require bypass because:
- •These are already-closed WOs
- •The modifications are for schema compliance, not content changes
- •Standard workflow uses
ctx_wo_finish.pywhich only modifies allowed keys
Solution: Use bypass activation method (see above) with INCIDENT NOTE explaining "Schema compliance fix for legacy WO"
Cleanup (Optional)
After successful finish, you may clean up:
# Remove worktree (optional) git worktree remove .worktrees/WO-XXXX # Prune stale worktrees git worktree prune
Common Mistakes
| Mistake | Why Bad | Fix |
|---|---|---|
| Skipping guard | Allows invalid state | Always run PRE-FINISH guard |
| Missing intent marker | Guard fails | [WO-XXXX] intent: logged at take |
| Missing result marker | Guard fails | Add [WO-XXXX] result: before finish |
| Uncommitted changes | Fails finish | Commit first |
| Bypass without incident note | Audit gap | Create INCIDENT NOTE first |
Resources
- •
scripts/ctx_wo_finish.py- Main finish script - •
_ctx/dod/DOD-DEFAULT.yaml- DoD definition - •
_ctx/handoff/- Artifact examples - •
docs/backlog/WORKFLOW.md- Full workflow
Quick Reference
# Guard PRE-FINISH (REQUIRED) git status --porcelain && \ grep "\[WO-XXXX\] intent:" _ctx/session.md && \ grep "\[WO-XXXX\] result:" _ctx/session.md # Run verify uv run pytest tests/ uv run ruff check src/ # Finish uv run python scripts/ctx_wo_finish.py WO-XXXX --result done # Guard POST-FINISH ls _ctx/handoff/WO-XXXX/ cat _ctx/handoff/WO-XXXX/verdict.json
Required Output
After finish completes:
ACTIVE_WO=none CWD=/path/.worktrees/WO-XXXX BRANCH=feat/wo-WO-XXXX STATE=done NEXT_ALLOWED=["cleanup worktree","return to main","start new WO"] ARTIFACTS=_ctx/handoff/WO-XXXX/ VERDICT=PASS
Bypass Output
BYPASS_USED=true INCIDENT_NOTE=_ctx/incidents/INCIDENT-WO-XXXX-YYYY-MM-DD.md FOLLOWUP_REQUIRED=true ACTIVE_WO=none STATE=done