bigpowers 2.75.0 → 2.75.2

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/.pi/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bigpowers",
3
- "version": "2.75.0",
3
+ "version": "2.75.2",
4
4
  "description": "77 skills — 73 agent skills synthesizing 17 years of software engineering discipline into a prescriptive methodology for solo developers",
5
5
  "keywords": [
6
6
  "pi-package"
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [2.75.2](https://github.com/danielvm-git/bigpowers/compare/v2.75.1...v2.75.2) (2026-07-07)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **ci:** enforce blocking OKF validation and close bug audit gaps ([e502c62](https://github.com/danielvm-git/bigpowers/commit/e502c62583024df36bed086d8e44a871907632cd))
7
+
8
+ ## [2.75.1](https://github.com/danielvm-git/bigpowers/compare/v2.75.0...v2.75.1) (2026-07-07)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **ci:** improve python compatibility with Z timezones, release agent lock ([bd92144](https://github.com/danielvm-git/bigpowers/commit/bd92144d0d2dc6ceb2db3999af215c5863939924))
14
+
1
15
  # [2.75.0](https://github.com/danielvm-git/bigpowers/compare/v2.74.12...v2.75.0) (2026-07-07)
2
16
 
3
17
 
package/bin/bigspec CHANGED
@@ -1,2 +1,36 @@
1
1
  #!/usr/bin/env bash
2
- if [[ "$1" == "--with-wiki" ]]; then echo "wiki enabled"; fi
2
+ # story: e48s10
3
+ # bigspec — minimal project bootstrap helper
4
+
5
+ print_wiki_setup() {
6
+ cat <<'EOF'
7
+ Wiki publishing enabled.
8
+
9
+ 1. Create a GitHub Wiki for this repository (or use the .wiki.git remote).
10
+ 2. Configure CI secrets: WIKI_PAT (repo scope for wiki push).
11
+ 3. Set WIKI_REPO_URL to the wiki clone URL (e.g. https://github.com/org/repo.wiki.git).
12
+ 4. Dry-run locally: bash kernel/src/publish-to-wiki.sh --dry-run
13
+ 5. Publish on merge: .github/workflows/publish-wiki.yml (gates on validate-okf first).
14
+
15
+ See docs/references/okf.md for OKF bundle layout and CI integration.
16
+ EOF
17
+ }
18
+
19
+ case "${1:-}" in
20
+ init)
21
+ if [[ "${2:-}" == "--with-wiki" ]]; then
22
+ print_wiki_setup
23
+ exit 0
24
+ fi
25
+ echo "Usage: bigspec init [--with-wiki]"
26
+ exit 1
27
+ ;;
28
+ --with-wiki)
29
+ print_wiki_setup
30
+ exit 0
31
+ ;;
32
+ *)
33
+ echo "Usage: bigspec init [--with-wiki]"
34
+ exit 1
35
+ ;;
36
+ esac
@@ -3,23 +3,138 @@
3
3
  # publish-to-wiki.sh — publish OKF bundles to a .wiki.git repository
4
4
  set -euo pipefail
5
5
 
6
+ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
7
+ HEADER="$ROOT/kernel/templates/wiki/header.md"
8
+ EPICS_SRC="$ROOT/specs/epics-wiki"
9
+ ADR_SRC="$ROOT/specs/adr-wiki"
10
+
6
11
  usage() {
7
12
  echo "Usage: $0 [--dry-run]"
8
- echo "Publishes OKF concept bundles from specs/epics-wiki and specs/adr-wiki to the configured .wiki.git repository, rewriting links to wiki slug format."
13
+ echo "Publishes OKF concept bundles from specs/epics-wiki and specs/adr-wiki"
14
+ echo "to the configured wiki git repository, rewriting links to wiki slug format."
9
15
  exit 0
10
16
  }
11
17
 
12
- if [[ "${1:-}" == "--help" ]]; then
18
+ wiki_slug_from_file() {
19
+ local base
20
+ base="$(basename "$1")"
21
+ base="${base%.okf.md}"
22
+ base="${base%.md}"
23
+ echo "$base"
24
+ }
25
+
26
+ rewrite_links() {
27
+ sed -E \
28
+ -e 's/\]\(([^)]*)\.okf\.md\)/](\1)/g' \
29
+ -e 's/\]\(([^)]*)\.md\)/](\1)/g' \
30
+ -e 's/\]\(specs\/[^)]+\/([^/)]+)\)/](\1)/g'
31
+ }
32
+
33
+ stage_bundle() {
34
+ local src="$1" section="$2" dest_root="$3"
35
+ local slug dest_dir dest_file
36
+ slug="$(wiki_slug_from_file "$src")"
37
+ dest_dir="$dest_root/$section"
38
+ dest_file="$dest_dir/${slug}.md"
39
+ mkdir -p "$dest_dir"
40
+ {
41
+ if [[ -f "$HEADER" ]]; then cat "$HEADER"; echo ""; fi
42
+ rewrite_links < "$src"
43
+ } > "$dest_file"
44
+ echo "$section/$slug.md"
45
+ }
46
+
47
+ collect_sources() {
48
+ local dir="$1"
49
+ if [[ -d "$dir" ]]; then
50
+ find "$dir" -maxdepth 1 -name '*.okf.md' -type f | sort
51
+ fi
52
+ }
53
+
54
+ publish_bundles() {
55
+ local dest_root="$1"
56
+ local -a pages=()
57
+ local src
58
+
59
+ rm -rf "$dest_root"
60
+ mkdir -p "$dest_root"
61
+
62
+ while IFS= read -r src; do
63
+ [[ -n "$src" ]] || continue
64
+ pages+=("$(stage_bundle "$src" "Epics" "$dest_root")")
65
+ done < <(collect_sources "$EPICS_SRC")
66
+
67
+ while IFS= read -r src; do
68
+ [[ -n "$src" ]] || continue
69
+ pages+=("$(stage_bundle "$src" "ADRs" "$dest_root")")
70
+ done < <(collect_sources "$ADR_SRC")
71
+
72
+ if [[ -f "$ROOT/kernel/templates/wiki/_Sidebar.md" ]]; then
73
+ cp "$ROOT/kernel/templates/wiki/_Sidebar.md" "$dest_root/_Sidebar.md"
74
+ pages+=("_Sidebar.md")
75
+ fi
76
+
77
+ printf '%s\n' "${pages[@]}"
78
+ }
79
+
80
+ push_to_wiki() {
81
+ local staged_root="$1"
82
+ local wiki_repo="${WIKI_REPO_URL:-}"
83
+ local work_dir="${WIKI_WORK_DIR:-}"
84
+
85
+ if [[ -z "$wiki_repo" ]]; then
86
+ echo "publish-to-wiki: WIKI_REPO_URL is not set — cannot push" >&2
87
+ return 1
88
+ fi
89
+
90
+ if [[ -z "$work_dir" ]]; then
91
+ work_dir="$(mktemp -d)"
92
+ trap 'rm -rf "$work_dir"' EXIT
93
+ fi
94
+
95
+ if [[ -d "$work_dir/.git" ]]; then
96
+ git -C "$work_dir" pull --rebase origin master 2>/dev/null || git -C "$work_dir" pull --rebase origin main
97
+ else
98
+ git clone "$wiki_repo" "$work_dir"
99
+ fi
100
+
101
+ rsync -a --delete "$staged_root/" "$work_dir/"
102
+ git -C "$work_dir" add -A
103
+ if git -C "$work_dir" diff --cached --quiet; then
104
+ echo "publish-to-wiki: no wiki changes to push"
105
+ return 0
106
+ fi
107
+ git -C "$work_dir" -c user.name="bigpowers-bot" -c user.email="bot@bigpowers.local" \
108
+ commit -m "chore(wiki): sync OKF bundles from main"
109
+ git -C "$work_dir" push origin HEAD
110
+ }
111
+
112
+ if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
13
113
  usage
14
114
  fi
15
115
 
16
116
  DRY_RUN=0
17
117
  if [[ "${1:-}" == "--dry-run" ]]; then
18
118
  DRY_RUN=1
19
- echo "[Dry Run] Would publish OKF bundles to wiki."
119
+ fi
120
+
121
+ STAGING="$(mktemp -d)"
122
+ trap 'rm -rf "$STAGING"' EXIT
123
+
124
+ mapfile -t PAGES < <(publish_bundles "$STAGING")
125
+ PAGE_COUNT="${#PAGES[@]}"
126
+
127
+ if [[ "$PAGE_COUNT" -eq 0 ]]; then
128
+ echo "publish-to-wiki: no OKF bundles found under specs/epics-wiki or specs/adr-wiki" >&2
129
+ exit 1
130
+ fi
131
+
132
+ echo "publish-to-wiki: pages: $PAGE_COUNT"
133
+ printf ' - %s\n' "${PAGES[@]}"
134
+
135
+ if [[ "$DRY_RUN" -eq 1 ]]; then
136
+ echo "publish-to-wiki: dry-run complete (staged under $STAGING)"
20
137
  exit 0
21
138
  fi
22
139
 
23
- # Logic to map OKF kinds to wiki sections, render markdown, rewrite relative links, and push
24
- echo "publish-to-wiki: Rewriting links and publishing to wiki..."
25
- exit 0
140
+ push_to_wiki "$STAGING"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bigpowers",
3
- "version": "2.75.0",
3
+ "version": "2.75.2",
4
4
  "description": "73 agent skills synthesizing 17 years of software engineering discipline into a prescriptive methodology for solo developers",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -23,7 +23,8 @@ if not d or 'locks' not in d:
23
23
 
24
24
  stale = []
25
25
  for lock in d['locks']:
26
- locked_at = datetime.datetime.fromisoformat(lock.get('locked_at', '1970-01-01T00:00:00Z'))
26
+ locked_at_str = lock.get('locked_at', '1970-01-01T00:00:00Z').replace('Z', '+00:00')
27
+ locked_at = datetime.datetime.fromisoformat(locked_at_str)
27
28
  if locked_at.tzinfo is None:
28
29
  locked_at = locked_at.replace(tzinfo=datetime.timezone.utc)
29
30
  age_hours = (now - locked_at).total_seconds() / 3600
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bash
2
+ # story: e48s01
2
3
  # story: e45s01 e45s06
3
4
  # generate-adr-wiki.sh — emit OKF concept bundles from specs/adr/*.md
4
5
  set -euo pipefail
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bash
2
+ # story: e48s01
2
3
  # story: e45s01 e45s06
3
4
  # generate-epics-wiki.sh — emit OKF concept bundles from specs/epics/*/epic.yaml
4
5
  set -euo pipefail
@@ -265,7 +265,7 @@ okf_scan_dir() {
265
265
  validate_bundle "$f"
266
266
  count=$((count + 1))
267
267
  fi
268
- done < <(find "$dir" -maxdepth 1 -name '*.md' -print0 2>/dev/null || true)
268
+ done < <(find "$dir" -maxdepth 1 \( -name '*.okf.md' -o -name 'registry.okf.md' \) -print0 2>/dev/null || true)
269
269
  if [ "$count" -eq 0 ]; then
270
270
  printf "${YELLOW}SKIP${NC} no OKF bundles found in %s\n" "$dir"
271
271
  fi
@@ -77,6 +77,7 @@ for e in entries:
77
77
  bundle = f"""---
78
78
  okf_kind: concept
79
79
  okf_version: "0.1"
80
+ type: Bug
80
81
  id: "{bug_id}"
81
82
  title: "{title_escaped}"
82
83
  category: bug
@@ -82,7 +82,7 @@ OKF_FLAG=""
82
82
  [[ "$OKF_MODE" -eq 1 ]] && OKF_FLAG="--okf"
83
83
 
84
84
  # Run srp-engine.py --all to process all skills in Python
85
- python3 "$REPO_ROOT/scripts/lib/srp-engine.py" --all $OKF_FLAG
85
+ "$PYTHON" "$REPO_ROOT/scripts/lib/srp-engine.py" --all $OKF_FLAG
86
86
 
87
87
  # Count generated skills
88
88
  skill_count=$(find "$CURSOR_RULES" -maxdepth 1 -name "*.mdc" | wc -l | tr -d ' ')
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env bash
2
+ # story: BUG-001
3
+ # Regression test: epic.yaml status matches execution-status.yaml for completed epics
4
+ set -euo pipefail
5
+
6
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7
+ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
8
+ EXEC_STATUS="$REPO_ROOT/specs/execution-status.yaml"
9
+ EPICS_ROOT="$REPO_ROOT/specs/epics"
10
+
11
+ if [[ ! -f "$EXEC_STATUS" ]]; then
12
+ echo "FAIL: missing $EXEC_STATUS"
13
+ exit 1
14
+ fi
15
+
16
+ FAILURES=0
17
+
18
+ while IFS= read -r line; do
19
+ [[ "$line" =~ ^[[:space:]]*(e[0-9]+):[[:space:]]*done[[:space:]]*$ ]] || continue
20
+ epic_id="${BASH_REMATCH[1]}"
21
+
22
+ # e37 is redesigned as Reach — execution-status may say done while capsule stays planned
23
+ [[ "$epic_id" == "e37" ]] && continue
24
+
25
+ epic_yaml=""
26
+ for candidate in \
27
+ "$EPICS_ROOT/$epic_id"*/epic.yaml \
28
+ "$EPICS_ROOT/archive/$epic_id"*/epic.yaml; do
29
+ if [[ -f "$candidate" ]]; then
30
+ epic_yaml="$candidate"
31
+ break
32
+ fi
33
+ done
34
+
35
+ if [[ -z "$epic_yaml" ]]; then
36
+ echo "WARN: no epic.yaml found for $epic_id (execution-status: done)"
37
+ continue
38
+ fi
39
+
40
+ yaml_status="$(grep -m1 '^status:' "$epic_yaml" | sed 's/^status:[[:space:]]*//' | tr -d '"')"
41
+ if [[ "$yaml_status" != "done" ]]; then
42
+ echo "FAIL: $epic_id epic.yaml status='$yaml_status' but execution-status.yaml says done ($epic_yaml)"
43
+ FAILURES=$((FAILURES + 1))
44
+ fi
45
+ done < "$EXEC_STATUS"
46
+
47
+ if [[ "$FAILURES" -gt 0 ]]; then
48
+ echo "FAIL: $FAILURES epic status drift(s)"
49
+ exit 1
50
+ fi
51
+
52
+ echo "PASS: epic.yaml status aligned with execution-status for completed epics"
53
+ exit 0
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env bash
2
+ # story: e48s01
3
+ # story: e48s03
4
+ # Regression tests for OKF bundle generators (e48 audit gap closure)
5
+ set -euo pipefail
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
9
+
10
+ echo "=== OKF generator regression tests ==="
11
+
12
+ require_min_count() {
13
+ local dir="$1" min="$2" label="$3"
14
+ local count
15
+ count="$(find "$dir" -maxdepth 1 -name '*.okf.md' -type f 2>/dev/null | wc -l | tr -d ' ')"
16
+ if [[ "$count" -lt "$min" ]]; then
17
+ echo "FAIL: expected at least $min $label bundles in $dir, got $count"
18
+ exit 1
19
+ fi
20
+ echo " $label: $count bundles"
21
+ }
22
+
23
+ echo "→ generate-epics-wiki.sh"
24
+ bash "$REPO_ROOT/scripts/generate-epics-wiki.sh" >/dev/null
25
+ require_min_count "$REPO_ROOT/specs/epics-wiki" 1 "epic"
26
+ bash "$REPO_ROOT/scripts/validate-okf.sh" --dir "$REPO_ROOT/specs/epics-wiki"
27
+
28
+ if ! grep -q '^tier:' "$REPO_ROOT/specs/epics-wiki/e48.okf.md"; then
29
+ echo "FAIL: e48.okf.md missing tier: field (e48s06)"
30
+ exit 1
31
+ fi
32
+
33
+ echo "→ generate-adr-wiki.sh"
34
+ bash "$REPO_ROOT/scripts/generate-adr-wiki.sh" >/dev/null
35
+ require_min_count "$REPO_ROOT/specs/adr-wiki" 1 "adr"
36
+ bash "$REPO_ROOT/scripts/validate-okf.sh" --dir "$REPO_ROOT/specs/adr-wiki"
37
+
38
+ echo "→ sync-bugs-registry.sh"
39
+ bash "$REPO_ROOT/scripts/sync-bugs-registry.sh" >/dev/null
40
+ require_min_count "$REPO_ROOT/specs/bugs" 1 "bug"
41
+ bash "$REPO_ROOT/scripts/validate-okf.sh" --dir "$REPO_ROOT/specs/bugs"
42
+
43
+ echo "→ publish-to-wiki.sh --dry-run"
44
+ OUTPUT="$(bash "$REPO_ROOT/kernel/src/publish-to-wiki.sh" --dry-run)"
45
+ if [[ "$OUTPUT" != *"pages:"* ]]; then
46
+ echo "FAIL: publish-to-wiki dry-run missing page manifest"
47
+ echo "$OUTPUT"
48
+ exit 1
49
+ fi
50
+
51
+ echo "PASS: OKF generators and publish-to-wiki dry-run"
52
+ exit 0