Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
"Bash(git push -f *)",
"Bash(sudo *)",
"Read(**/.env)",
"Read(**/.env.*)"
"Read(**/.env.local)",
"Read(**/.env.*.local)",
"Read(**/.env.production)"
]
}
}
4 changes: 2 additions & 2 deletions .claude/workflow.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
".claude/skills/gc/SKILL.md": "abfb7282d3000eb30b872df8313a17aa2c60a54e5951034c0bdfaa3da59bde71",
".claude/skills/handoff/SKILL.md": "1289ffc479b7761066212b576d1a22c8c134e3aeed7bff5945642acc439a3eab",
".claude/skills/parallel-work/SKILL.md": "94fbb922cf88fc005fd8cfa033c1c3559adbfde04fd759ca5f3c696f2afd9afe",
".claude/workflow/check.py": "c3e23ff58df8e13365d69c85a5a54d1bfbc9557f08d745e426426715e09d6220",
".claude/workflow/check.py": "f2e69f3c29d75e116ed3812bc3a33af7129a82c8d32b17d8782d8d4aed7ce29a",
".claude/workflow/gc.py": "30b0191f1171a1fe9d5f6bf10579a8eaa8a06db49da9a8437376df5bebb70af4",
"docs/plans/_template.md": "9178c6a0a9807241ecd8d5624f9e07f94f6b5181e4a2290f44fd49f0c8b08d3f"
},
"kit": "c9485b3 2026-11-06",
"kit": "9a00ece 2026-11-06",
"level": "full"
}
16 changes: 13 additions & 3 deletions .claude/workflow/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
- Every path-scoped rule in .claude/rules/ has a strict `paths:` header whose fixed prefixes exist
(a header that fails to parse makes the rule load in every session instead).
- docs/decisions.md, if present: under its byte budget, lines within the length limit, each theme
heading names an existing detail file; every detail entry opens with a status line; every index
line is claimed by an entry marked `live, indexed`, and every claim names an index line.
heading names an existing detail file, each detail file under its own budget when one is set
(entries that no longer apply move to docs/decisions/archive/, which is not checked); every
detail entry opens with a status line; every index line is claimed by an entry marked
`live, indexed`, and every claim names an index line.
- docs/plans/README.md, if present: its "Active plans" list agrees with each dated plan's
`Status:` line (a closed plan is not listed; an open one is).
"""
Expand All @@ -33,6 +35,7 @@
"claude_md_max_bytes": 14336,
"decisions_index_max_bytes": 20000,
"decisions_line_max_chars": 250,
"decisions_theme_max_bytes": 0, # 0 = no cap; new repositories are seeded with 40960
}
STATUS = re.compile(
r"^\*\*Status:\*\* (live, indexed|live, not indexed|superseded by \d{4}-\d{2}-\d{2}"
Expand Down Expand Up @@ -144,7 +147,14 @@ def check_decisions(root: Path, cfg: dict, r: Report) -> None:
if not detail.exists():
r.fail("decisions", f"theme heading names {file}, which does not exist")
continue
lines = detail.read_text(encoding="utf-8-sig").split("\n")
text = detail.read_text(encoding="utf-8-sig")
cap = cfg.get("decisions_theme_max_bytes") or 0
if cap and len(text.encode()) > cap:
size = len(text.encode())
r.fail("decisions", f"{file} is {size} bytes, over {cap}: move superseded, withdrawn "
f"and record entries to docs/decisions/archive/{file}, which "
"nothing loads or checks")
lines = text.split("\n")
claims: list[tuple[int, str]] = []
for i, line in enumerate(lines):
h = HEADING.match(line)
Expand Down
Loading