Skip to content
This repository was archived by the owner on Apr 5, 2026. It is now read-only.

Commit 7f6bc04

Browse files
HerbHallclaude
andauthored
docs(rules): ingest AP#136-137 + KG#62,123,163,164 from issues #418-426 (#427)
AP#136: Go interface extension requires updating all test mocks AP#137: Hardcoded count assertions break when adding features KG#62: +Python binary-mode CRLF -- find() returns -1, content[:-1] silently corrupts KG#123: +Gitea force-push 'stale info' (fetch first); +semantic-release EGITNOPERMISSION via Cloudflare Tunnel; KG#161 updated (resolved in Samverk #38) KG#163: semantic-release/git incompatible with branch protection requiring PR status checks KG#164: Gitea act_runner actcache grows unboundedly, causes ENOSPC Also update status.md: Samverk URL (github→gitea), pattern counts (119→123), queued section. Closes #418, #419, #422, #423, #424, #425, #426 Co-authored-by: Claude <noreply@anthropic.com>
1 parent d61b209 commit 7f6bc04

3 files changed

Lines changed: 59 additions & 9 deletions

File tree

.samverk/status.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
phase: execution
3-
updated: 2026-03-17T21:00:00Z
3+
updated: 2026-03-17T22:00:00Z
44
updated_by: claude-code
55
managed_by: samverk
66
---
@@ -15,7 +15,7 @@ Active maintenance and execution. AI tooling methodology, Claude Code configurat
1515
## What Is Running
1616

1717
- Symlinked rules loaded by all Claude Code sessions via ~/.claude/
18-
- 25 skills, 7 agents, 11 rules files, 119 active patterns (AP: 66, KG: 53)
18+
- 25 skills, 7 agents, 11 rules files, 123 active patterns (AP: 68, KG: 55)
1919
- 3 Claude Code hooks (SessionStart, SessionStop, SubagentVerify) + 3 git hooks (pre-push, pre-commit, commit-msg)
2020
- Credentials migrated to PowerShell SecretStore vault (HomeLabVault)
2121

@@ -25,10 +25,11 @@ None.
2525

2626
## Queued
2727

28-
None. 0 open issues as of 2026-03-17.
28+
- **Issue ingestion** (#418, #419, #422-#426): 7 autolearn patterns from Samverk/Synapset sessions — in this PR
2929

3030
## Recently Completed
3131

32+
- **KG#156 correction** (2026-03-17): CI validator scope (PR #420)
3233
- **KG#162 ingestion** (2026-03-17): GitHub issues-disabled API quirk (PR #417)
3334
- **Rules compaction** (2026-03-17): KG 63->52 entries, AP 72->66 entries (39.8k/38.6k -> 35.1k/35.9k), Synapset SYN#595-602
3435
- **KG#160-161 ingestion** (2026-03-17): Gitea tunnel auth + Samverk MCP init gating
@@ -44,7 +45,7 @@ None. 0 open issues as of 2026-03-17.
4445
## Related Projects
4546

4647
- **Synapset** (gitea:samverk-admin/synapset) — Vector memory MCP server, DevKit is primary consumer
47-
- **Samverk** (github:HerbHall/samverk) — Project lifecycle manager
48+
- **Samverk** (gitea:samverk/samverk) — Project lifecycle manager
4849

4950
## Start Here (Cold Start Protocol)
5051

claude/rules/autolearn-patterns.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
description: Learned patterns from past sessions. Read when encountering similar situations.
33
tier: 2
4-
entry_count: 66
4+
entry_count: 68
55
last_updated: "2026-03-17"
66
---
77

@@ -690,3 +690,19 @@ MUI Popper needs `anchorEl` during render. `useRef` + `ref.current` triggers Rea
690690
**Category:** process-pattern
691691
**Context:** Issue spec said "call into existing `dispatcher.Claim()`" but no such public method existed, and the caller and callee were in separate processes. A 2-minute codebase check would have caught both problems.
692692
**Fix:** Before writing implementation specs that reference internal methods, verify: (1) the method exists and is exported, (2) the caller and callee are in the same process. Extends AP#47 (check existing assets before scoping) and AP#83 (sprint scope reduction via exploration).
693+
694+
## 136. Go Interface Extension Requires Updating All Test Mocks
695+
696+
**Added:** 2026-03-17 | **Source:** Samverk | **Status:** active
697+
698+
**Category:** correction
699+
**Context:** Adding a method to a Go interface requires updating ALL structs implementing it, including private test mocks. The compiler catches missing methods, but if a mock adds the new method stub without calling it in any test, golangci-lint's `unused` linter fails.
700+
**Fix:** Before submitting a PR that extends a Go interface, grep for all types implementing it. Ensure every mock (1) adds the new method and (2) exercises it in at least one test case.
701+
702+
## 137. Hardcoded Count Assertions Break When Adding Features
703+
704+
**Added:** 2026-03-17 | **Source:** Samverk | **Status:** active
705+
706+
**Category:** gotcha
707+
**Context:** Tests asserting exact counts (e.g., `len(tools) != 41`) fail whenever a new item is added. Common in tool-discovery tests, route-registration tests, and enum exhaustiveness checks.
708+
**Fix:** Before creating a PR that adds tools/routes/handlers, search for `len(...) != N` or `assert.Equal(t, N, len(...))` patterns and update the expected count. For non-correctness counts, prefer `>= N` over exact equality.

claude/rules/known-gotchas.md

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
description: Known gotchas and platform-specific issues. Read when debugging unexpected behavior.
33
tier: 2
4-
entry_count: 53
4+
entry_count: 55
55
last_updated: "2026-03-17"
66
---
77

@@ -230,6 +230,7 @@ Windows CRLF (`\r\n`) causes silent failures across multiple tools. Three known
230230
- **Bash grep in CI:** `\r\n` in Windows-committed files causes trailing `\r` in grep output, breaking comparisons. Fix: `tr -d '\r' < "$file" > "$clean_file"`.
231231
- **Claude Code Edit tool:** `old_string` matching fails silently on CRLF files. Workaround: use Write tool for new files, or Python binary-mode (`open('file', 'rb')`).
232232
- **GitHub API body fields:** `gh api` returns `\r\n` in `body` field on Windows. Python regex fails silently. Fix: `body = body.replace("\r\n", "\n")` before parsing.
233+
- **Python binary-mode file manipulation:** `open(f, 'rb').read()` then `content.find(b'...\n')` returns -1 on CRLF files -- endings are `\r\n`. Using -1 as a slice index (`content[:-1]`) silently corrupts the file with no error. Fix: use `b'...\r\n'` in binary-mode searches.
233234

234235
**Universal fix:** Normalize `\r\n` to `\n` before any string processing on Windows.
235236

@@ -521,10 +522,25 @@ Windows CRLF (`\r\n`) causes silent failures across multiple tools. Three known
521522
**Issue:** Gitea REST API calls via the Cloudflare tunnel URL fail with "token is required" because the tunnel strips the `Authorization` header.
522523
**Fix:** Use the internal URL (e.g., `http://192.168.1.160:3000`) for all Gitea API calls. Token extraction: `printf 'protocol=https\nhost=gitea.example.com\n' | git credential fill | grep password`
523524

524-
### Samverk MCP handler init gated on GitHub env vars (was KG#161)
525+
### Samverk MCP handler init gated on GitHub env vars (was KG#161, resolved)
525526

526-
**Issue:** Samverk MCP handler init is gated on `GITHUB_TOKEN + SAMVERK_GITHUB_OWNER + SAMVERK_GITHUB_REPO` all being set. If any is missing, all MCP routes and server.yaml projects are skipped -- even Gitea-only projects.
527-
**Fix:** Set env vars to a non-colliding bootstrap project (e.g., `herbhall/devkit`) to keep the handler alive when migrating to Gitea. Proper fix: decouple Gitea project registry from GitHub init gate.
527+
**Issue:** Samverk MCP handler init was gated on `GITHUB_TOKEN + SAMVERK_GITHUB_OWNER + SAMVERK_GITHUB_REPO` all being set. If any was missing, all MCP routes and server.yaml projects were skipped.
528+
**Fix:** Resolved in Samverk refactor/38 -- MCP handler and server.yaml projects now initialize unconditionally. GitHub env vars only needed for GitHub-hosted projects.
529+
530+
### Force-push rejected with 'stale info' -- fetch first
531+
532+
**Issue:** `git push --force` or `--force-with-lease` to Gitea fails with "stale info" when the local remote-tracking ref is stale or missing (e.g., branch was created remotely via a PR or prior push from another worktree).
533+
**Fix:** `git fetch gitea <branch>` first, then force-push. The fetch creates the tracking ref. Occurs every time rebasing a branch originally created by a Gitea PR. Different from GitHub, which allows force-push with stale refs.
534+
535+
### semantic-release EGITNOPERMISSION via Cloudflare Tunnel -- needs second url.insteadOf
536+
537+
**Issue:** semantic-release uses `repositoryUrl` for both release notes link generation AND the git push target. If `repositoryUrl` points to the public Cloudflare Tunnel URL and Cloudflare strips `Authorization` headers, the tag push fails with `EGITNOPERMISSION`.
538+
**Fix:** Add a second `url.insteadOf` rule in CI that rewrites the public URL to authenticated localhost -- the first rule covering `localhost:3000` is not enough alone:
539+
540+
```yaml
541+
git config --global url."http://user:${TOKEN}@localhost:3000/".insteadOf "http://localhost:3000/"
542+
git config --global url."http://user:${TOKEN}@localhost:3000/".insteadOf "https://gitea.herbhall.net/"
543+
```
528544

529545
## 125. go:embed Cache Misses Embedded File Changes
530546

@@ -619,3 +635,20 @@ Windows CRLF (`\r\n`) causes silent failures across multiple tools. Three known
619635
**Issue:** When `has_issues=false` on a GitHub repo, individual issue GETs return 410 and PATCH on regular issues returns 403. However, PRs (which share the `/issues` endpoint) can still be closed via PATCH even with issues disabled.
620636
**Fix:** To close regular issues when issues are disabled: (1) re-enable: `GITHUB_TOKEN= gh api repos/OWNER/REPO -X PATCH -f has_issues=true`, (2) close the issues, (3) re-disable. The `GITHUB_TOKEN=` prefix clears any fine-grained PAT that lacks repo settings scope.
621637
**See also:** KG#120 (fine-grained PAT shadows gh CLI OAuth)
638+
639+
## 163. semantic-release/git Incompatible With Branch Protection Requiring PR Status Checks
640+
641+
**Added:** 2026-03-17 | **Source:** Synapset | **Status:** active
642+
643+
**Platform:** Gitea / GitHub Actions
644+
**Issue:** `@semantic-release/git` and `@semantic-release/changelog` push commits directly to the default branch. Branch protection requiring `(pull_request)` status checks always rejects these -- direct commits can never have a `pull_request` CI context. Error: "Protected branch update failed: changes must be made through a pull request".
645+
**Fix:** Remove `@semantic-release/git` and `@semantic-release/changelog` from the plugin chain. Keep: `@semantic-release/commit-analyzer`, `@semantic-release/release-notes-generator`, and the release plugin. Semantic-release still creates the git tag and platform release without the direct-commit plugins.
646+
647+
## 164. Gitea act_runner actcache Grows Unboundedly, Causes ENOSPC
648+
649+
**Added:** 2026-03-17 | **Source:** Synapset | **Status:** active
650+
651+
**Platform:** Gitea Actions (act_runner / Linux)
652+
**Issue:** act_runner caches workflow artifacts at `/home/git/.cache/actcache/cache/`. No built-in eviction. Can consume 20+ GB on a 40GB disk, causing ENOSPC in all running CI workflows.
653+
**Fix:** (1) Immediate cleanup: `rm -rf /home/git/.cache/actcache/cache/*`. (2) Daily pruning cron (run as `git` user): `0 3 * * * find /home/git/.cache/actcache/cache -mindepth 1 -maxdepth 1 -mtime +7 -exec rm -rf {} +`. (3) Disk alert at >80% usage via `logger`.
654+
**Infrastructure note:** `proxmox.herbhall.net` resolves to the dns-proxy LXC, NOT the Proxmox host. Actual Proxmox host is `192.168.1.203`. `pct resize` and `pvesm` are only available on the Proxmox host itself.

0 commit comments

Comments
 (0)