Skip to content

Commit f2ecee0

Browse files
committed
fix: dedupe AGENTS.md rules, pin gstack, bump CI actions, drop Claude-only wording
AGENTS.md stated the error-handling policy twice, in wording that did not quite agree: one version banned exceptions in hot paths, the other preferred return codes in critical code. Both nuances are now folded into the single §Error handling statement, and the Senior-reflexes copy points at it. Same treatment for 'comments = WHY only' (stated in two sections) and for naming. Not merged: 'one authoritative source (DRY)' in Engineering discipline and 'at the third copy, centralize' in Refactoring discipline. On inspection those are complementary — a principle and its actionable trigger — not a duplicate. gstack now installs at a pinned, verified commit (394db326f2d3, v1.71.0.0 — cloned and inspected: setup script present, 61 skills). Upstream publishes no tags and moves daily, so tracking the default branch meant two people installing a week apart got different environments. Pass --gstack-ref main to opt back into tracking. CI actions were three majors behind (checkout@v4, setup-python@v5, setup-node@v4) and GitHub was already forcing them onto Node 24 with a deprecation warning. Bumped to v7 across both workflows, runtime to Node 22. Two 'In Claude Code:' comments became CLI-neutral: the skills now install into every agent root, so the instruction was wrong, not just narrow.
1 parent 2c2c5bc commit f2ecee0

6 files changed

Lines changed: 66 additions & 52 deletions

File tree

.github/workflows/anti-debt-ci.yml

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ jobs:
1313
name: Validate JSON schemas
1414
runs-on: ubuntu-latest
1515
steps:
16-
- uses: actions/checkout@v4
16+
- uses: actions/checkout@v7
1717
- name: Setup Python
18-
uses: actions/setup-python@v5
18+
uses: actions/setup-python@v7
1919
with:
2020
python-version: '3.11'
2121
- name: Install pyyaml
@@ -53,9 +53,9 @@ jobs:
5353
name: Test Critic Engine
5454
runs-on: ubuntu-latest
5555
steps:
56-
- uses: actions/checkout@v4
56+
- uses: actions/checkout@v7
5757
- name: Setup Python
58-
uses: actions/setup-python@v5
58+
uses: actions/setup-python@v7
5959
with:
6060
python-version: '3.11'
6161
- name: Run critic tests
@@ -70,9 +70,9 @@ jobs:
7070
name: Test Python tools syntax
7171
runs-on: ubuntu-latest
7272
steps:
73-
- uses: actions/checkout@v4
73+
- uses: actions/checkout@v7
7474
- name: Setup Python
75-
uses: actions/setup-python@v5
75+
uses: actions/setup-python@v7
7676
with:
7777
python-version: '3.11'
7878
- name: "Syntax check (all Python: tools, kg, skills)"
@@ -92,9 +92,9 @@ jobs:
9292
name: Test scan quality (corpus)
9393
runs-on: ubuntu-latest
9494
steps:
95-
- uses: actions/checkout@v4
95+
- uses: actions/checkout@v7
9696
- name: Setup Python
97-
uses: actions/setup-python@v5
97+
uses: actions/setup-python@v7
9898
with:
9999
python-version: '3.11'
100100
- name: Install ruff
@@ -108,9 +108,9 @@ jobs:
108108
name: Test Layer 0 (Knowledge Graph)
109109
runs-on: ubuntu-latest
110110
steps:
111-
- uses: actions/checkout@v4
111+
- uses: actions/checkout@v7
112112
- name: Setup Python
113-
uses: actions/setup-python@v5
113+
uses: actions/setup-python@v7
114114
with:
115115
python-version: '3.11'
116116
- name: Run Layer 0 tests
@@ -132,9 +132,9 @@ jobs:
132132
name: Test Layer 1+2 (static analysis + critic V2)
133133
runs-on: ubuntu-latest
134134
steps:
135-
- uses: actions/checkout@v4
135+
- uses: actions/checkout@v7
136136
- name: Setup Python
137-
uses: actions/setup-python@v5
137+
uses: actions/setup-python@v7
138138
with:
139139
python-version: '3.11'
140140
- name: Run Layer 1+2 tests
@@ -145,9 +145,9 @@ jobs:
145145
name: Test adapters validation
146146
runs-on: ubuntu-latest
147147
steps:
148-
- uses: actions/checkout@v4
148+
- uses: actions/checkout@v7
149149
- name: Setup Python
150-
uses: actions/setup-python@v5
150+
uses: actions/setup-python@v7
151151
with:
152152
python-version: '3.11'
153153
- name: Run adapter tests
@@ -158,9 +158,9 @@ jobs:
158158
name: Test Layer 3 (V1.2 skills)
159159
runs-on: ubuntu-latest
160160
steps:
161-
- uses: actions/checkout@v4
161+
- uses: actions/checkout@v7
162162
- name: Setup Python
163-
uses: actions/setup-python@v5
163+
uses: actions/setup-python@v7
164164
with:
165165
python-version: '3.11'
166166
- name: Run Layer 3 V1.2 tests
@@ -171,9 +171,9 @@ jobs:
171171
name: Test Layer 4+6+7 (orchestration, calibration, dashboard)
172172
runs-on: ubuntu-latest
173173
steps:
174-
- uses: actions/checkout@v4
174+
- uses: actions/checkout@v7
175175
- name: Setup Python
176-
uses: actions/setup-python@v5
176+
uses: actions/setup-python@v7
177177
with:
178178
python-version: '3.11'
179179
- name: Run Layer 4+6+7 tests
@@ -184,9 +184,9 @@ jobs:
184184
name: Test LLM-as-judge (structural, no API)
185185
runs-on: ubuntu-latest
186186
steps:
187-
- uses: actions/checkout@v4
187+
- uses: actions/checkout@v7
188188
- name: Setup Python
189-
uses: actions/setup-python@v5
189+
uses: actions/setup-python@v7
190190
with:
191191
python-version: '3.11'
192192
- name: Run LLM judge tests
@@ -197,9 +197,9 @@ jobs:
197197
name: Test production mining tool
198198
runs-on: ubuntu-latest
199199
steps:
200-
- uses: actions/checkout@v4
200+
- uses: actions/checkout@v7
201201
- name: Setup Python
202-
uses: actions/setup-python@v5
202+
uses: actions/setup-python@v7
203203
with:
204204
python-version: '3.11'
205205
- name: Validate production_mining.py syntax and imports
@@ -213,9 +213,9 @@ jobs:
213213
name: Test dashboard end-to-end
214214
runs-on: ubuntu-latest
215215
steps:
216-
- uses: actions/checkout@v4
216+
- uses: actions/checkout@v7
217217
- name: Setup Python
218-
uses: actions/setup-python@v5
218+
uses: actions/setup-python@v7
219219
with:
220220
python-version: '3.11'
221221
- name: Run scan_periodic + dashboard

.github/workflows/ci.yml

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ jobs:
1818
- python-version: "3.8"
1919
continue-on-error: true # 3.8 EOL oct 2024 — kept for backward-compat claim
2020
steps:
21-
- uses: actions/checkout@v4
21+
- uses: actions/checkout@v7
2222
- name: Set up Python ${{ matrix.python-version }}
23-
uses: actions/setup-python@v5
23+
uses: actions/setup-python@v7
2424
with:
2525
python-version: ${{ matrix.python-version }}
2626
- name: Run test suite (stdlib unittest — zero dependencies)
@@ -30,8 +30,8 @@ jobs:
3030
name: Conventions declared == conventions enforced
3131
runs-on: ubuntu-latest
3232
steps:
33-
- uses: actions/checkout@v4
34-
- uses: actions/setup-python@v5
33+
- uses: actions/checkout@v7
34+
- uses: actions/setup-python@v7
3535
with:
3636
python-version: "3.11"
3737
- name: AGENTS.md and conventions.json must agree
@@ -49,10 +49,10 @@ jobs:
4949
name: LOC budget gate
5050
runs-on: ubuntu-latest
5151
steps:
52-
- uses: actions/checkout@v4
53-
- uses: actions/setup-node@v4
52+
- uses: actions/checkout@v7
53+
- uses: actions/setup-node@v7
5454
with:
55-
node-version: "20"
55+
node-version: "22"
5656
- name: Enforce the stack's own LOC rule on its own sources
5757
# Uses the same run_gate.js the PreToolUse hook uses, reading the same
5858
# conventions.json — one implementation, so CI and the hook can never
@@ -72,8 +72,8 @@ jobs:
7272
matrix:
7373
os: [ubuntu-latest, macos-latest, windows-latest]
7474
steps:
75-
- uses: actions/checkout@v4
76-
- uses: actions/setup-python@v5
75+
- uses: actions/checkout@v7
76+
- uses: actions/setup-python@v7
7777
with:
7878
python-version: "3.11"
7979

@@ -136,8 +136,8 @@ jobs:
136136
matrix:
137137
os: [ubuntu-latest, windows-latest]
138138
steps:
139-
- uses: actions/checkout@v4
140-
- uses: actions/setup-python@v5
139+
- uses: actions/checkout@v7
140+
- uses: actions/setup-python@v7
141141
with:
142142
python-version: "3.11"
143143

@@ -229,10 +229,10 @@ jobs:
229229
matrix:
230230
os: [ubuntu-latest, macos-latest, windows-latest]
231231
steps:
232-
- uses: actions/checkout@v4
233-
- uses: actions/setup-node@v4
232+
- uses: actions/checkout@v7
233+
- uses: actions/setup-node@v7
234234
with:
235-
node-version: "20"
235+
node-version: "22"
236236

237237
- name: LOC gate — pass, warn and block tiers
238238
shell: bash

AGENTS.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,23 @@ Own the result beyond the edit — local changes have system-level consequences.
2626

2727
## Error handling
2828

29+
This is the single statement of the error-handling policy. Other sections point
30+
here rather than restating it.
31+
2932
- Never swallow errors silently: no empty `catch {}`, no ignored `Result`, no `_ =`
30-
- **Rust**: `?`, `map_err()`, or `anyhow::bail!``unwrap()` only with `// SAFETY: [proven reason]`
31-
- **C++**: `std::optional`/`std::expected` over exceptions in hot paths; never `catch(...) {}`
32-
- At system boundaries (I/O, HTTP, user input, external parsing): always handle explicitly
33+
- **Rust**: `?`, `map_err()`, or `anyhow::bail!``unwrap()`/`expect()` forbidden in production code except on a proven invariant carrying `// SAFETY: [reason]`
34+
- **C++**: return codes or `std::optional`/`std::expected` over exceptions in hot paths and critical code; never `catch(...) {}`
35+
- At system boundaries (I/O, HTTP, network, user input, external parsing): always handle explicitly
3336
- Internal trusted boundaries may `assert`/`debug_assert` in debug, panic in Rust
3437

3538
---
3639

3740
## Naming & comments
3841

3942
- **Language**: English everywhere — code, comments, commits, PR descriptions. One language per repo.
40-
- **Names**: explicit over short — `processAudioFrame()` > `process()`, `userEmailAddress` > `email`
43+
- **Names**: explicit over short — `processAudioFrame()` > `process()`, `userEmailAddress` > `email`. One term per concept across the codebase.
4144
- **No cryptic abbreviations**: `idx→index`, `cnt→count`, `mgr→manager` (exceptions: `ptr`, `id`, `num`)
42-
- **Comments**: WHY only — hidden constraint, subtle invariant, workaround for a specific bug. Never describe WHAT the code does.
45+
- **Comments**: WHY only — hidden constraint, subtle invariant, workaround for a specific bug. Never describe WHAT the code does, and never to explain confusing code: simplify the code instead. (One exception, in §Senior reflexes: public interface contracts.)
4346
- **Dead code**: delete immediately, never comment out. `git log -S "functionName"` recovers any deleted code.
4447

4548
---
@@ -81,9 +84,8 @@ Own the result beyond the edit — local changes have system-level consequences.
8184
<!-- Distilled from Clean Code — Robert C. Martin -->
8285

8386
- Preserve behavior, write for the next reader, leave touched code cleaner within scope.
84-
- Precise names with one term per concept; split boolean flags and mixed abstraction levels out of functions.
87+
- Split boolean flags and mixed abstraction levels out of functions. (Naming itself: see §Naming & comments.)
8588
- Separate commands from queries. No hidden side effects.
86-
- Comments only for rationale or contracts — never to explain confusing code (simplify the code instead).
8789
- When touching code: remove the smell most likely to make the next change risky or unclear.
8890

8991
---
@@ -224,7 +226,7 @@ The rules above are the always-on core. The reflexes below are the full senior p
224226

225227
### Safety & static analysis
226228

227-
- **Error handling policy**never swallow silently. Rust: `unwrap()`/`expect()` forbidden in prod except a proven invariant with `// SAFETY:`; prefer `?`/`map_err()`. C++: prefer return codes / `std::optional`/`std::expected` in critical code; never empty `catch(...)`. Errors at system boundaries (I/O, network, user parsing) always handled explicitly.
229+
- **Error handling policy**see §Error handling above. It is stated once, there.
228230
- **RAII (C++)** — no naked `new`/`delete`; `make_unique`/`make_shared`/stack. FFI opaque handles wrapped in a RAII type immediately (no naked handle circulating).
229231
- **`using namespace` banned at file scope** — in headers (0 exceptions, fully qualify) and production `.cpp` (function scope or explicit alias `namespace fs = std::filesystem;` only).
230232
- **Sanitizers** in dedicated CI builds: ASan (use-after-free, overflow) + UBSan (signed overflow, null deref) can combine; TSan (data races) separate build; MSan (uninit reads). Rust FFI modules: `cargo miri test` (nightly) catches UB at the `extern "C"` boundary that C++ sanitizers miss.

PORTABILITY.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ python3 scripts/validate_conventions.py # → all thresholds a
136136
# Anti-debt runs through an agent path (Claude example):
137137
python3 ~/.claude/skills/anti-debt/skills/debt-scan/tools/scan_code.py .
138138

139-
# AI-docs stack in a project:
140-
# In Claude Code: /verify-ai-docs → OPERATIONAL
139+
# AI-docs stack in a project — in any agent that loaded the skills:
140+
# /verify-ai-docs → OPERATIONAL
141141
```
142142

143143
A correct transfer means: each agent loads `AGENTS.md` (Layer 1), the anti-debt

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,9 @@ cp tools/ai_docs/config.sh.example your-project/tools/ai_docs/config.sh
368368
# 5. Generate all AI_SUMMARY.md files
369369
python tools/ai_docs/generate_all.py
370370

371-
# 6. Verify the full stack
372-
# In Claude Code: /verify-ai-docs
371+
# 6. Verify the full stack — in any agent that loaded the skills
372+
# (Claude Code, Codex, OpenCode, Cursor):
373+
# /verify-ai-docs
373374
```
374375

375376
### For a new machine / new contributor

install.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ def first_party_skills() -> list[Path]:
6565

6666
GSTACK_URL = "https://github.com/garrytan/gstack.git"
6767

68+
# gstack publishes no git tags — versions live only in commit messages, and the
69+
# default branch moves daily. Tracking it means two students installing a week
70+
# apart get different environments, which is unusable for teaching.
71+
#
72+
# So the default is a commit that was cloned and inspected before being written
73+
# here (setup script present, 61 SKILL.md files, self-described v1.71.0.0).
74+
# Override with --gstack-ref, or set this to None to track the default branch.
75+
# When you move it, verify the new commit the same way and say so here.
76+
GSTACK_DEFAULT_REF = "394db326f2d3" # v1.71.0.0 — verified 2026-08-27
77+
6878

6979
class Installer:
7080
def __init__(self, project_root: Path, dry_run: bool) -> None:
@@ -289,8 +299,9 @@ def parse_args() -> argparse.Namespace:
289299
gstack.add_argument("--with-gstack", dest="gstack", action="store_const", const="yes",
290300
help="install gstack (third-party code from GitHub)")
291301
gstack.add_argument("--skip-gstack", dest="gstack", action="store_const", const="no")
292-
parser.add_argument("--gstack-ref", default=None,
293-
help="commit or tag to pin gstack to (reproducible installs)")
302+
parser.add_argument("--gstack-ref", default=GSTACK_DEFAULT_REF,
303+
help=f"commit to pin gstack to (default: {GSTACK_DEFAULT_REF}); "
304+
"pass 'main' to track the default branch instead")
294305
parser.add_argument("--dry-run", action="store_true", help="show actions, change nothing")
295306
parser.set_defaults(gstack="no")
296307
return parser.parse_args()

0 commit comments

Comments
 (0)