AgentSkillsCN

wo/guard

在任何 WO 操作之前,强制执行故障封闭的不变性原则。

SKILL.md
--- frontmatter
name: wo/guard
description: Enforce fail-closed invariants before any WO action
enforcement: require

WO Guard - Fail-Closed Invariant Gate

Principle: Skills are not advice; they are doors with keys.

Overview

This skill enforces fail-closed checks before any WO action. It is the gatekeeper that prevents agents from "doing whatever they want."

Without this skill, all other WO skills are just literature.

When to Use

CheckpointWhen
PRE-TAKEBefore running ctx_wo_take.py
POST-TAKEAfter ctx_wo_take.py completes
PRE-COMMITBefore committing changes in worktree
PRE-FINISHBefore running ctx_wo_finish.py
POST-FINISHAfter ctx_wo_finish.py completes

Invariant Checks

PRE-TAKE Checks

CheckCommandExpected
No locks from OTHER WOsls _ctx/jobs/running/*.lockNo locks for WOs != target WO
System healthyctx_wo_take.py --statusNo errors
WO exists in pendingcat _ctx/jobs/pending/WO-XXXX.yamlValid YAML

Note: Locks from the SAME WO are OK if WO is already running (re-taking).

POST-TAKE Checks

CheckCommandExpected
In worktreegit worktree list --porcelainCurrent dir matches WO worktree
Correct branchgit branch --show-currentfeat/wo-WO-XXXX
YAML moved to runningcat _ctx/jobs/running/WO-XXXX.yamlstatus: running
Lock existstest -f _ctx/jobs/running/WO-XXXX.lockExit 0

PRE-COMMIT Checks

CheckCommandExpected
In correct worktreegit worktree list --porcelainWorktree matches WO
WO is runningCheck YAML status fieldrunning
Lock is validCheck lock filePID alive, age < TTL
Files in scopegit diff --name-onlyAll in scope.allow

PRE-FINISH Checks

CheckCommandExpected
In correct worktreegit worktree list --porcelainWorktree matches WO
Correct branchgit branch --show-currentfeat/wo-WO-XXXX
Lock existstest -f _ctx/jobs/running/WO-XXXX.lockExit 0
Session markers (BOTH)grep "\[WO-XXXX\]" session.mdintent: AND result: present
Repo cleangit status --porcelainEmpty
Verify commands passRun commands from WO YAMLAll PASS

Note: PRE-FINISH does NOT check verdict.json (that's generated by finish).

POST-FINISH Checks

CheckCommandExpected
Verdict existstest -f _ctx/handoff/WO-XXXX/verdict.jsonExit 0
Verdict PASScat verdict.json"result": "PASS"
All DoD artifactsls _ctx/handoff/WO-XXXX/5 files present
WO moved to donecat _ctx/jobs/done/WO-XXXX.yamlstatus: done

SCHEMA VALIDATION Check (PRE-COMMIT)

CheckCommandExpected
DoD schemas validctx_backlog_validate.pyNo WO_INVALID_SCHEMA
WO schemas validctx_backlog_validate.pyNo errors

If schema validation fails:

  1. STOP - Do not commit
  2. Run wo/repair Issue 7: "Reconcile Falls with WO_INVALID_SCHEMA"
  3. Fix schemas before proceeding

Worktree Check (Deterministic)

DO NOT use fragile string matching like git rev-parse --show-toplevel | grep ".worktrees".

USE the porcelain format:

bash
# Get worktree info
git worktree list --porcelain

# Verify current worktree matches WO
git worktree list --porcelain | grep -A2 "worktree $(pwd)" | grep "branch feat/wo-WO-XXXX"

Lock TTL Validation

DO NOT use hardcoded "1 hour" rule.

The TTL is configurable:

  • Environment variable: WO_LOCK_TTL_SEC (default: 86400 = 24h)
  • Checker function: scripts/helpers.pycheck_lock_age()

Process:

bash
# Check lock age via Python
uv run python -c "
from scripts.helpers import check_lock_age
from pathlib import Path
result = check_lock_age(Path('_ctx/jobs/running/WO-XXXX.lock'))
print(f'Lock valid: {result}')
"

Failure Response

When any guard check fails:

  1. STOP immediately
  2. DIAGNOSE: Run wo/status for snapshot
  3. SUGGEST: Point user to wo/repair
  4. DO NOT PROCEED until guard passes

Example failure output:

code
⛔ GUARD FAILED: PRE-COMMIT

Check: Correct worktree
  Expected: worktree for WO-XXXX
  Actual: main repo

ACTION: You are in the wrong directory.
  Run: cd .worktrees/WO-XXXX
  Then: Re-run guard

DO NOT COMMIT until guard passes.

Resources

  • scripts/ctx_wo_take.py - Take script with status check
  • scripts/helpers.py - Lock age validation
  • scripts/ctx_reconcile_state.py - State reconciliation
  • _ctx/jobs/running/*.lock - Lock files

Quick Reference

bash
# Pre-take guard (WO-XXXX is target)
ls _ctx/jobs/running/*.lock | grep -v "WO-XXXX.lock" # Should be empty or stale

# Post-take guard
git worktree list --porcelain | grep -A2 "$(pwd)" | grep "branch feat/wo-WO-XXXX"

# Pre-commit guard
git diff --name-only | while read f; do grep -q "$f" _ctx/jobs/running/WO-XXXX.yaml || exit 1; done

# Pre-finish guard
git status --porcelain && \
grep "\[WO-XXXX\] intent:" _ctx/session.md && \
grep "\[WO-XXXX\] result:" _ctx/session.md

Required Output

After running guard, always output:

code
GUARD_CHECKPOINT=<PRE-TAKE|POST-TAKE|PRE-COMMIT|PRE-FINISH|POST-FINISH>
GUARD_RESULT=<PASS|FAIL>
ACTIVE_WO=<WO-XXXX|none>
CWD=<current directory>
BRANCH=<current branch|none>
STATE=<pending|running|done|failed|none>
NEXT_ALLOWED=[<list of allowed actions>]