bigpowers 2.66.0 → 2.67.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.fix_regex.sh +16 -0
- package/.hermes-verify-sed-fix.py +53 -0
- package/.pi/package.json +2 -2
- package/.pi/prompts/build-epic.md +8 -0
- package/.pi/prompts/gate-trace.md +2 -1
- package/.pi/prompts/kickoff-branch.md +19 -0
- package/.pi/prompts/maintain-wiki.md +63 -0
- package/.pi/prompts/plan-tests.md +1 -1
- package/.pi/prompts/release-branch.md +17 -13
- package/.pi/prompts/verify-work.md +9 -5
- package/.pi/skills/build-epic/SKILL.md +8 -0
- package/.pi/skills/gate-trace/SKILL.md +2 -1
- package/.pi/skills/kickoff-branch/SKILL.md +19 -0
- package/.pi/skills/maintain-wiki/SKILL.md +65 -0
- package/.pi/skills/plan-tests/SKILL.md +1 -1
- package/.pi/skills/release-branch/SKILL.md +17 -13
- package/.pi/skills/verify-work/SKILL.md +9 -5
- package/CHANGELOG.md +20 -0
- package/README.md +1 -1
- package/SKILL-INDEX.md +1 -1
- package/_test_e28s01.sh +2 -0
- package/hermes-verify-sed-fix.py +30 -0
- package/package.json +1 -1
- package/scripts/build-skill-graph.sh +151 -183
- package/scripts/check-spec-drift.sh +121 -0
- package/scripts/check-spec-version-gap.sh +143 -0
- package/scripts/decompose-conventions.sh +147 -0
- package/scripts/generate-agent-guide.sh +89 -0
- package/scripts/hermes-verify-e39s02.sh +28 -0
- package/scripts/lib/python-env.sh +44 -0
- package/scripts/migrate-version.sh +721 -0
- package/scripts/okf-post-sync.sh +163 -0
- package/scripts/validate-okf.sh +18 -0
- package/skills/build-epic/SKILL.md +8 -0
- package/skills/gate-trace/SKILL.md +2 -1
- package/skills/kickoff-branch/SKILL.md +19 -0
- package/skills/maintain-wiki/SKILL.md +66 -0
- package/skills/plan-tests/SKILL.md +1 -1
- package/skills/release-branch/SKILL.md +17 -13
- package/skills/verify-work/SKILL.md +9 -5
- package/skills-lock.json +11 -6
- package/tests/fixtures/v1.x-project/CLAUDE.md +4 -0
- package/tests/fixtures/v1.x-project/CONVENTIONS.md +4 -0
- package/tests/fixtures/v2.0.0-project/CLAUDE.md +4 -0
- package/tests/fixtures/v2.0.0-project/CONVENTIONS.md +3 -0
- package/tests/fixtures/v2.20-project/CLAUDE.md +4 -0
- package/tests/fixtures/v2.20-project/CONVENTIONS.md +4 -0
- package/tests/run-golden-migrate-version.sh +155 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# story: e39s04
|
|
3
|
+
# okf-post-sync.sh — Post-processing pipeline for OKF skills-wiki generation.
|
|
4
|
+
# Called by sync-skills.sh --okf after concept files are rendered.
|
|
5
|
+
# Steps: cross-references from skill-graph.json → index.md → validate-okf.sh
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
9
|
+
GRAPH_JSON="$REPO_ROOT/specs/skill-graph.json"
|
|
10
|
+
OKF_WIKI_SKILLS="$REPO_ROOT/specs/skills-wiki/skills"
|
|
11
|
+
OKF_WIKI_DIR="$REPO_ROOT/specs/skills-wiki"
|
|
12
|
+
OKF_INDEX="$OKF_WIKI_DIR/index.md"
|
|
13
|
+
|
|
14
|
+
# ── Step 1: Run build-skill-graph.sh for cross-references ──────────
|
|
15
|
+
echo ""
|
|
16
|
+
echo "--- OKF post-sync ---"
|
|
17
|
+
echo "Step 1: Cross-references from skill graph..."
|
|
18
|
+
|
|
19
|
+
if [[ -x "$REPO_ROOT/scripts/build-skill-graph.sh" ]]; then
|
|
20
|
+
bash "$REPO_ROOT/scripts/build-skill-graph.sh" --json || {
|
|
21
|
+
echo " WARNING: build-skill-graph.sh --json failed; cross-references will be fallback" >&2
|
|
22
|
+
}
|
|
23
|
+
else
|
|
24
|
+
echo " WARNING: build-skill-graph.sh not found" >&2
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# ── Step 2: Add cross-references from skill-graph.json ─────────────
|
|
28
|
+
echo "Step 2: Adding cross-references to OKF concepts..."
|
|
29
|
+
|
|
30
|
+
if [[ -f "$GRAPH_JSON" ]] && command -v python3 &>/dev/null; then
|
|
31
|
+
python3 "$REPO_ROOT/scripts/okf-add-references.py" "$GRAPH_JSON" "$OKF_WIKI_SKILLS"
|
|
32
|
+
else
|
|
33
|
+
echo " Adding fallback references..."
|
|
34
|
+
for f in "$OKF_WIKI_SKILLS"/*.md; do
|
|
35
|
+
[[ -f "$f" ]] || continue
|
|
36
|
+
python3 -c "
|
|
37
|
+
import re
|
|
38
|
+
c = open('$f').read()
|
|
39
|
+
c = re.sub(r'references:\s*\[\]', 'references:\n - concept: skills-wiki\n type: belongs_to', c)
|
|
40
|
+
open('$f','w').write(c)
|
|
41
|
+
" 2>/dev/null || true
|
|
42
|
+
done
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# ── Step 3: Generate index.md with progressive disclosure ──────────
|
|
46
|
+
echo "Step 3: Generating index.md..."
|
|
47
|
+
|
|
48
|
+
python3 - "$OKF_WIKI_SKILLS" "$OKF_INDEX" <<'PYEOF'
|
|
49
|
+
import re, sys
|
|
50
|
+
from pathlib import Path
|
|
51
|
+
from collections import defaultdict
|
|
52
|
+
|
|
53
|
+
wiki_skills = Path(sys.argv[1])
|
|
54
|
+
index_path = Path(sys.argv[2])
|
|
55
|
+
|
|
56
|
+
concepts = []
|
|
57
|
+
for f in sorted(wiki_skills.glob("*.md")):
|
|
58
|
+
content = f.read_text()
|
|
59
|
+
fm_match = re.search(r'^---\n(.*?)\n---', content, re.DOTALL)
|
|
60
|
+
if not fm_match:
|
|
61
|
+
continue
|
|
62
|
+
fm_text = fm_match.group(1)
|
|
63
|
+
name = title = phase = model = effort = description = ""
|
|
64
|
+
for line in fm_text.split('\n'):
|
|
65
|
+
line = line.strip()
|
|
66
|
+
if line.startswith('name:'): name = line.split(':', 1)[1].strip()
|
|
67
|
+
elif line.startswith('title:'): title = line.split(':', 1)[1].strip().strip('"')
|
|
68
|
+
elif line.startswith('phase:'): phase = line.split(':', 1)[1].strip()
|
|
69
|
+
elif line.startswith('model:'): model = line.split(':', 1)[1].strip()
|
|
70
|
+
elif line.startswith('effort:'): effort = line.split(':', 1)[1].strip()
|
|
71
|
+
elif line.startswith('description:'): description = line.split(':', 1)[1].strip().strip('"')
|
|
72
|
+
if not name:
|
|
73
|
+
continue
|
|
74
|
+
concepts.append({
|
|
75
|
+
"name": name,
|
|
76
|
+
"title": title or name.replace('-', ' ').title(),
|
|
77
|
+
"phase": phase or "utility",
|
|
78
|
+
"model": model,
|
|
79
|
+
"effort": effort,
|
|
80
|
+
"description": (description[:120] + "...") if len(description) > 120 else description,
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
phases = defaultdict(list)
|
|
84
|
+
for c in concepts:
|
|
85
|
+
phases[c["phase"]].append(c)
|
|
86
|
+
|
|
87
|
+
total = len(concepts)
|
|
88
|
+
cp = phases.get("critical-path", [])
|
|
89
|
+
util = phases.get("utility", [])
|
|
90
|
+
|
|
91
|
+
with open(index_path, "w") as out:
|
|
92
|
+
out.write(f"""---
|
|
93
|
+
okf_kind: concept
|
|
94
|
+
type: Index
|
|
95
|
+
id: skills-wiki
|
|
96
|
+
title: "BigPowers Skills Wiki"
|
|
97
|
+
category: skills
|
|
98
|
+
description: "Progressive-disclosure index of {total} bigpowers skills ({len(cp)} critical-path, {len(util)} utility) — auto-generated by sync-skills.sh --okf (e39s04)."
|
|
99
|
+
references:
|
|
100
|
+
- concept: bigpowers
|
|
101
|
+
type: belongs_to
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
# BigPowers Skills Wiki
|
|
105
|
+
|
|
106
|
+
**{total} skills** ({len(cp)} critical-path, {len(util)} utility)
|
|
107
|
+
|
|
108
|
+
> Auto-generated by sync-skills.sh --okf (e39s04). Source of truth: skills/*/SKILL.md files.
|
|
109
|
+
|
|
110
|
+
## Critical-Path Skills ({len(cp)})
|
|
111
|
+
|
|
112
|
+
These skills form the bigpowers core development loop.
|
|
113
|
+
|
|
114
|
+
| Skill | Model | Effort | Description |
|
|
115
|
+
|-------|-------|--------|-------------|
|
|
116
|
+
""")
|
|
117
|
+
for c in cp:
|
|
118
|
+
out.write(f"| [{c['title']}](skills/{c['name']}.md) | {c['model']} | {c['effort']} | {c['description']} |\n")
|
|
119
|
+
|
|
120
|
+
out.write(f"""
|
|
121
|
+
## Utility Skills ({len(util)})
|
|
122
|
+
|
|
123
|
+
Supporting skills for specialised workflows.
|
|
124
|
+
|
|
125
|
+
| Skill | Model | Effort | Description |
|
|
126
|
+
|-------|-------|--------|-------------|
|
|
127
|
+
""")
|
|
128
|
+
for c in util:
|
|
129
|
+
out.write(f"| [{c['title']}](skills/{c['name']}.md) | {c['model']} | {c['effort']} | {c['description']} |\n")
|
|
130
|
+
|
|
131
|
+
out.write(f"""
|
|
132
|
+
## Quick Reference
|
|
133
|
+
|
|
134
|
+
- **Total skills:** {total}
|
|
135
|
+
- **Critical-path:** {len(cp)}
|
|
136
|
+
- **Utility:** {len(util)}
|
|
137
|
+
- **Format:** OKF concept bundles (okf_kind: concept)
|
|
138
|
+
- **Validation:** `bash scripts/validate-okf.sh --dir specs/skills-wiki/skills`
|
|
139
|
+
""")
|
|
140
|
+
|
|
141
|
+
print(f" index.md written: {total} skills ({len(cp)} critical-path, {len(util)} utility)")
|
|
142
|
+
PYEOF
|
|
143
|
+
|
|
144
|
+
# ── Step 4: Validate OKF conformance ───────────────────────────────
|
|
145
|
+
echo "Step 4: Validating OKF conformance..."
|
|
146
|
+
|
|
147
|
+
VALIDATE_SCRIPT="$REPO_ROOT/scripts/validate-okf.sh"
|
|
148
|
+
if [[ -x "$VALIDATE_SCRIPT" ]]; then
|
|
149
|
+
if bash "$VALIDATE_SCRIPT" --dir "$OKF_WIKI_SKILLS" 2>&1; then
|
|
150
|
+
echo " OKF validation: PASSED"
|
|
151
|
+
else
|
|
152
|
+
OKF_EXIT=$?
|
|
153
|
+
echo " OKF validation: exit code $OKF_EXIT (non-zero — see output above)" >&2
|
|
154
|
+
fi
|
|
155
|
+
else
|
|
156
|
+
echo " WARNING: validate-okf.sh not found; skipping validation" >&2
|
|
157
|
+
fi
|
|
158
|
+
|
|
159
|
+
OKF_COUNT=$(find "$OKF_WIKI_SKILLS" -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
|
|
160
|
+
echo ""
|
|
161
|
+
echo "okf-post-sync: $OKF_COUNT OKF concepts generated"
|
|
162
|
+
echo " → specs/skills-wiki/skills/ ($OKF_COUNT .md files)"
|
|
163
|
+
echo " → specs/skills-wiki/index.md (progressive-disclosure index)"
|
package/scripts/validate-okf.sh
CHANGED
|
@@ -292,6 +292,24 @@ validate_bundle() {
|
|
|
292
292
|
EXIT_CODE=1
|
|
293
293
|
return
|
|
294
294
|
}
|
|
295
|
+
|
|
296
|
+
# ── OKF v0.1 Generic Frontmatter Conformance (e39s10) ──
|
|
297
|
+
# Check required 'type' field
|
|
298
|
+
local fm_type
|
|
299
|
+
fm_type="$(echo "$fm" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('type',''))" 2>/dev/null)"
|
|
300
|
+
if [ -z "$fm_type" ]; then
|
|
301
|
+
printf "${RED}FAIL${NC} %s: OKF v0.1 — missing required 'type' field\n" "$name"
|
|
302
|
+
EXIT_CODE=1
|
|
303
|
+
return
|
|
304
|
+
fi
|
|
305
|
+
|
|
306
|
+
# Reserved filenames: index.md must have type: Index
|
|
307
|
+
if [ "$name" = "index.md" ] && [ "$fm_type" != "Index" ]; then
|
|
308
|
+
printf "${RED}FAIL${NC} %s: OKF v0.1 — index.md must have type: Index (got '%s')\n" "$name" "$fm_type"
|
|
309
|
+
EXIT_CODE=1
|
|
310
|
+
return
|
|
311
|
+
fi
|
|
312
|
+
|
|
295
313
|
local kind
|
|
296
314
|
kind="$(echo "$fm" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('okf_kind',''))" 2>/dev/null)"
|
|
297
315
|
case "$kind" in
|
|
@@ -43,6 +43,14 @@ Orchestrates the **build** flow for a single epic: survey → plan tasks → kic
|
|
|
43
43
|
8. On story complete, set `execution-status.yaml` story key to `done`; run `bash scripts/sync-status-from-epics.sh`.
|
|
44
44
|
9. **Traceability refresh:** Before step 8 (release-branch), run `bash scripts/trace-stories.sh` to regenerate `specs/traceability-matrix.json`, `specs/TRACEABILITY_LATEST.md`, and the `specs/codebase-wiki/` OKF bundle. Surface dark/orphan/stale findings for the just-built epic in your verify summary. If `scripts/trace-stories.sh` is missing or fails, note "trace skipped" and continue — trace failure must be visible, not silent (blocking is gate-trace's job, e38s06).
|
|
45
45
|
|
|
46
|
+
9b. **OKF wiki refresh (e39s08):** Before step 8, run maintain-wiki INGEST to refresh the OKF wiki bundle:
|
|
47
|
+
```bash
|
|
48
|
+
bash scripts/decompose-conventions.sh
|
|
49
|
+
bash scripts/generate-agent-guide.sh
|
|
50
|
+
```
|
|
51
|
+
If any script is missing or fails, note "OKF wiki refresh skipped" and continue.
|
|
52
|
+
This is non-blocking — stale concepts are caught by LINT in verify-work Phase 3.
|
|
53
|
+
|
|
46
54
|
### Step 6 — audit-code gate (non-optional)
|
|
47
55
|
|
|
48
56
|
After step 5 (verify-work) completes successfully, step 6 runs `audit-code` automatically in `--gate` mode:
|
|
@@ -37,7 +37,8 @@ TEA-inspired: if trace links rely on heuristics rather than explicit tags, confi
|
|
|
37
37
|
3. Read `specs/traceability-matrix.json` and `specs/blind-spots.json`.
|
|
38
38
|
4. Apply decision rules R1–R5 in order (first match wins).
|
|
39
39
|
5. Apply oracle confidence downgrade based on the heuristic link ratio from the matrix's `oracle_stats`.
|
|
40
|
-
6.
|
|
40
|
+
6. **Drift check (e39s03):** If `specs/drift-report.json` exists and has suspect links, mark verdict as CONCERNS with note: "Drift detected — some implementing files are newer than their specs. Run scripts/check-spec-drift.sh for details."
|
|
41
|
+
7. Output verdict + rationale to stdout.
|
|
41
42
|
7. Update `specs/execution-status.yaml` with gate-trace result.
|
|
42
43
|
|
|
43
44
|
## Verdict Semantics
|
|
@@ -95,6 +95,25 @@ git checkout -b <task-slug>
|
|
|
95
95
|
|
|
96
96
|
### 4. Verify clean baseline
|
|
97
97
|
|
|
98
|
+
> **HARD GATE (e39s02):** Acquire story lock in `specs/agent-locks.yaml` before running tests.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
LOCK="specs/agent-locks.yaml"; STORY="<story-id>"
|
|
102
|
+
if [ -f "$LOCK" ]; then
|
|
103
|
+
python3 -c "
|
|
104
|
+
import yaml,sys,datetime
|
|
105
|
+
d=yaml.safe_load(open('$LOCK'))or{'locks':[]}
|
|
106
|
+
for l in d['locks']:
|
|
107
|
+
if l['story_id']=='$STORY':print(f'LOCKED by {l[\"locked_by\"]} at {l[\"locked_at\"]}');sys.exit(1)
|
|
108
|
+
d['locks'].append({'story_id':'$STORY','locked_by':'agent: build-epic','locked_at':datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ'),'files_touched':[]})
|
|
109
|
+
yaml.dump(d,open('$LOCK','w'),default_flow_style=False)
|
|
110
|
+
print(f'LOCK ACQUIRED: $STORY')
|
|
111
|
+
"
|
|
112
|
+
fi
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
If locked: abort. If unlocked: entry added, proceed.
|
|
116
|
+
|
|
98
117
|
Run the full test suite and confirm it passes before writing any code:
|
|
99
118
|
|
|
100
119
|
```bash
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: maintain-wiki
|
|
3
|
+
model: haiku
|
|
4
|
+
effort: light
|
|
5
|
+
description: "Agent-maintained OKF wiki — INGEST source docs, LINT for issues, QUERY across concept pages. Run as part of build-epic Step 8 and verify-work Phase 3."
|
|
6
|
+
# story: e39s07
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Maintain Wiki
|
|
10
|
+
|
|
11
|
+
Three operations for keeping the OKF wiki bundle consistent with its source docs.
|
|
12
|
+
|
|
13
|
+
## INGEST
|
|
14
|
+
|
|
15
|
+
Read source doc (CLAUDE.md, CONVENTIONS.md, or SKILL.md) and write/update OKF concept pages:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Regenerate skills-wiki from SKILL.md files
|
|
19
|
+
bash scripts/sync-skills.sh --okf
|
|
20
|
+
|
|
21
|
+
# Regenerate conventions-wiki from CONVENTIONS.md
|
|
22
|
+
bash scripts/decompose-conventions.sh
|
|
23
|
+
|
|
24
|
+
# Regenerate agent-guide from CLAUDE.md
|
|
25
|
+
bash scripts/generate-agent-guide.sh
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## LINT
|
|
29
|
+
|
|
30
|
+
Check for common OKF issues:
|
|
31
|
+
|
|
32
|
+
1. **Stale concepts** — source file mtime vs concept page mtime. If source is newer, concept is stale.
|
|
33
|
+
2. **Orphan concepts** — concept page exists but source doc section no longer exists.
|
|
34
|
+
3. **Missing cross-references** — skill concept pages with no `enforced_by` or `references` links.
|
|
35
|
+
4. **Contradictions** — two concept pages that make opposite claims about the same topic.
|
|
36
|
+
5. **Broken links** — internal OKF links that point to non-existent concept pages.
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Quick stale check: compare source vs concept mtimes
|
|
40
|
+
for page in specs/skills-wiki/skills/*.md; do
|
|
41
|
+
skill=$(basename "$page" .md)
|
|
42
|
+
source="skills/$skill/SKILL.md"
|
|
43
|
+
if [ -f "$source" ] && [ "$page" -ot "$source" ]; then
|
|
44
|
+
echo "STALE: $skill (SKILL.md newer than concept page)"
|
|
45
|
+
fi
|
|
46
|
+
done
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## QUERY
|
|
50
|
+
|
|
51
|
+
Search across OKF concept pages to answer questions:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Find all concepts about a topic
|
|
55
|
+
grep -rl "topic" specs/skills-wiki/ specs/conventions-wiki/ specs/agent-guide/
|
|
56
|
+
|
|
57
|
+
# Trace a convention → enforcing skills
|
|
58
|
+
grep -A1 "enforced_by" specs/conventions-wiki/*.md
|
|
59
|
+
|
|
60
|
+
# Find skill by description keyword
|
|
61
|
+
grep -ril "keyword" specs/skills-wiki/skills/*.md
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Verify
|
|
65
|
+
|
|
66
|
+
→ verify: `test -d specs/skills-wiki && test -d specs/conventions-wiki && test -d specs/agent-guide && echo "OKF wiki present" || echo "FAIL"`
|
|
@@ -34,7 +34,7 @@ Bridges the gap between slicing and planning by systematically designing the tes
|
|
|
34
34
|
|
|
35
35
|
## Verify
|
|
36
36
|
|
|
37
|
-
→ verify: `
|
|
37
|
+
→ verify: `ls specs/tech-architecture/*-TEST_PLAN_LATEST.md 2>/dev/null | head -1 && echo OK || echo "SKIP: no test plan yet — EPIC not set or not generated"`
|
|
38
38
|
|
|
39
39
|
## Handoff
|
|
40
40
|
|
|
@@ -13,7 +13,6 @@ description: Make the merge/PR/keep/discard decision for a feature branch, verif
|
|
|
13
13
|
Finalize a completed feature branch: verify coverage gates, integrate onto `main`, and clean up the worktree.
|
|
14
14
|
|
|
15
15
|
## Additional modes
|
|
16
|
-
|
|
17
16
|
- `--hotfix`: Cherry-pick to main + tag. Skip PR in solo.
|
|
18
17
|
- `--squash-state`: Squash `chore(state):` commits before merge.
|
|
19
18
|
|
|
@@ -76,9 +75,7 @@ bash scripts/land-branch.sh <task-slug> "feat(scope): description"
|
|
|
76
75
|
|
|
77
76
|
### 6. Create PR (team-pr only)
|
|
78
77
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
### 7. Merge (team-pr only)
|
|
78
|
+
Create the pull request, then merge via `gh`:
|
|
82
79
|
|
|
83
80
|
```bash
|
|
84
81
|
gh pr merge --squash --delete-branch
|
|
@@ -94,22 +91,32 @@ gh pr merge --squash --delete-branch
|
|
|
94
91
|
mv specs/epics/eNN-slug specs/epics/archive/
|
|
95
92
|
```
|
|
96
93
|
|
|
97
|
-
### 7b. CI verification
|
|
94
|
+
### 7b. CI verification & agent lock release (e39s02)
|
|
98
95
|
|
|
99
96
|
> **HARD GATE** — Do NOT declare success until CI completes. A push that fails CI is a regression, not a release.
|
|
100
97
|
|
|
101
|
-
After push
|
|
98
|
+
After push, run CI polling:
|
|
102
99
|
|
|
103
100
|
```bash
|
|
104
101
|
bash scripts/wait-for-ci.sh --timeout 600 --interval 30
|
|
105
102
|
```
|
|
106
103
|
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
Then release the story lock:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
LOCK="specs/agent-locks.yaml"; STORY="<story-id>"
|
|
108
|
+
[ -f "$LOCK" ] && python3 -c "
|
|
109
|
+
import yaml
|
|
110
|
+
d=yaml.safe_load(open('$LOCK'))
|
|
111
|
+
if d:d['locks']=[l for l in d['locks'] if l.get('story_id')!='$STORY']
|
|
112
|
+
yaml.dump(d,open('$LOCK','w'),default_flow_style=False)
|
|
113
|
+
print(f'LOCK RELEASED: $STORY')
|
|
114
|
+
"||echo "No lock for $STORY — idempotent"
|
|
115
|
+
```
|
|
109
116
|
|
|
110
117
|
- [ ] CI workflow passes after push (wait-for-ci.sh exit 0)
|
|
111
118
|
- [ ] `release.ci_verified: true` documented in state.yaml
|
|
112
|
-
- On failure: `handoff.next_skill = fix-bug` with
|
|
119
|
+
- On failure: `handoff.next_skill = fix-bug` with CI failure URL
|
|
113
120
|
|
|
114
121
|
### 8. Clean up worktree
|
|
115
122
|
|
|
@@ -130,16 +137,13 @@ bash scripts/record-cycle-time.sh append \
|
|
|
130
137
|
--file specs/metrics/cycle-times.yaml
|
|
131
138
|
```
|
|
132
139
|
|
|
133
|
-
This replaces the previous hand-arithmetic approach (story_end minus story_start).
|
|
134
|
-
See [REFERENCE.md](REFERENCE.md) for the git-hours model and field definitions.
|
|
135
|
-
|
|
136
140
|
### 9. Return to main
|
|
137
141
|
|
|
138
142
|
```bash
|
|
139
143
|
git checkout main && git status && pwd
|
|
140
144
|
```
|
|
141
145
|
|
|
142
|
-
Report: "Branch released.
|
|
146
|
+
Report: "Branch released."
|
|
143
147
|
|
|
144
148
|
## Verify
|
|
145
149
|
|
|
@@ -109,6 +109,13 @@ phases:
|
|
|
109
109
|
closed: true
|
|
110
110
|
```
|
|
111
111
|
|
|
112
|
+
### 5b. OKF wiki LINT (e39s08)
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
for p in specs/skills-wiki/skills/*.md; do s="skills/$(basename "$p" .md)/SKILL.md"; [ -f "$s" ]&&[ "$p" -ot "$s" ]&&echo "STALE: $p"; done
|
|
116
|
+
for p in specs/conventions-wiki/*.md; do [ "$(basename "$p")" = "index.md" ]&&continue; grep -q "$(basename "$p" .md)" CONVENTIONS.md||echo "ORPHAN: $p"; done
|
|
117
|
+
```
|
|
118
|
+
|
|
112
119
|
> **HARD GATE** — Verification evidence MUST be persisted before marking the story done. No evidence = not verified.
|
|
113
120
|
|
|
114
121
|
## --cli mode
|
|
@@ -132,15 +139,12 @@ BINARY=$(grep '^BIN\s*=' Makefile 2>/dev/null | awk '{print $3}')
|
|
|
132
139
|
3. Happy-path: run documented example command from README.md → assert non-empty output
|
|
133
140
|
4. Edge case: `$BINARY --invalid-flag` → assert exit code ≠ 0 and error message printed
|
|
134
141
|
|
|
135
|
-
No "stop server"
|
|
142
|
+
No "stop server" / "clear caches" in `--cli` mode. Steps 3–6 still run unchanged.
|
|
136
143
|
|
|
137
144
|
## Verify
|
|
138
145
|
|
|
139
146
|
→ verify: `find specs/verifications -maxdepth 1 -name '*-verify.yaml' 2>/dev/null | head -1 | grep -q . && echo "Evidence persisted" || echo "No evidence yet"`
|
|
140
147
|
|
|
141
|
-
See [REFERENCE.md](REFERENCE.md) for cold-start and gaps template.
|
|
142
|
-
|
|
143
148
|
## Handoff
|
|
144
|
-
|
|
145
|
-
Gate: READY -> next: audit-code
|
|
149
|
+
READY -> next: audit-code
|
|
146
150
|
Writes: state.yaml handoff.next_skill = audit-code
|
package/skills-lock.json
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"build-epic": {
|
|
25
25
|
"description": "Eight-step epic build cycle — reads state.yaml, execution-status.yaml, and one epic capsule; updates status via bp-yaml-set or direct edit. Resume mode runs one step per invocation. Use instead of ad-hoc execute-plan for release work.",
|
|
26
|
-
"sha256": "
|
|
26
|
+
"sha256": "230ac9d30cae1a63",
|
|
27
27
|
"path": "skills/build-epicSKILL.md"
|
|
28
28
|
},
|
|
29
29
|
"change-request": {
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
},
|
|
129
129
|
"gate-trace": {
|
|
130
130
|
"description": "\"Deterministic traceability quality gate — reads coverage matrix + blind-spot data, applies decision rules with oracle confidence downgrade, emits PASS/CONCERNS/FAIL/WAIVED verdict. Use before release-branch to gate merges on traceability.\"# story: e38s06",
|
|
131
|
-
"sha256": "
|
|
131
|
+
"sha256": "81deb2549867386b",
|
|
132
132
|
"path": "skills/gate-traceSKILL.md"
|
|
133
133
|
},
|
|
134
134
|
"grill-me": {
|
|
@@ -163,9 +163,14 @@
|
|
|
163
163
|
},
|
|
164
164
|
"kickoff-branch": {
|
|
165
165
|
"description": "Create a git worktree and feature branch, then verify a clean test baseline before any code is written. Use when starting a new feature or task, when user wants to work in isolation from main, or mentions \"start a branch\" or \"new worktree\".",
|
|
166
|
-
"sha256": "
|
|
166
|
+
"sha256": "928d87bae8cc4ddf",
|
|
167
167
|
"path": "skills/kickoff-branchSKILL.md"
|
|
168
168
|
},
|
|
169
|
+
"maintain-wiki": {
|
|
170
|
+
"description": "\"Agent-maintained OKF wiki — INGEST source docs, LINT for issues, QUERY across concept pages. Run as part of build-epic Step 8 and verify-work Phase 3.\"# story: e39s07",
|
|
171
|
+
"sha256": "c54c6170db6fe3f9",
|
|
172
|
+
"path": "skills/maintain-wikiSKILL.md"
|
|
173
|
+
},
|
|
169
174
|
"map-codebase": {
|
|
170
175
|
"description": "\"Derives the tech-stack doc from scratch by scanning the codebase — analyzes stack, architecture, and gray areas (error handling, API shapes) and persists findings into specs/tech-architecture/tech-stack.md. Run when the tech doc doesn't exist yet; use survey-context to consume it once it does.\"",
|
|
171
176
|
"sha256": "cfd8a71a3cdb63af",
|
|
@@ -203,7 +208,7 @@
|
|
|
203
208
|
},
|
|
204
209
|
"plan-tests": {
|
|
205
210
|
"description": "\"Design a risk-scaled test architecture for an epic before implementation begins. Produces prioritized scenarios, test level distribution, and fixture plans based on TEA and bigpowers principles.\"",
|
|
206
|
-
"sha256": "
|
|
211
|
+
"sha256": "ed22b3feb985eabb",
|
|
207
212
|
"path": "skills/plan-testsSKILL.md"
|
|
208
213
|
},
|
|
209
214
|
"plan-work": {
|
|
@@ -223,7 +228,7 @@
|
|
|
223
228
|
},
|
|
224
229
|
"release-branch": {
|
|
225
230
|
"description": "Make the merge/PR/keep/discard decision for a feature branch, verify coverage gates, create the PR with gh, and clean up the worktree. Use when a feature is done and ready to ship, or when user says \"release\", \"merge\", or \"open a PR\".",
|
|
226
|
-
"sha256": "
|
|
231
|
+
"sha256": "73a9aebff3fb4dc0",
|
|
227
232
|
"path": "skills/release-branchSKILL.md"
|
|
228
233
|
},
|
|
229
234
|
"request-review": {
|
|
@@ -348,7 +353,7 @@
|
|
|
348
353
|
},
|
|
349
354
|
"verify-work": {
|
|
350
355
|
"description": "Multi-phase UAT gate — cold-start smoke, build, typecheck, lint, tests, step-by-step manual verification, gaps-closure loop. Use after execute-plan or develop-tdd, before audit-code.",
|
|
351
|
-
"sha256": "
|
|
356
|
+
"sha256": "300e5a7c7695e33f",
|
|
352
357
|
"path": "skills/verify-workSKILL.md"
|
|
353
358
|
},
|
|
354
359
|
"visual-dashboard": {
|