mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-13 23:40:48 +01:00
NEXT_SESSION_PROMPT.md: phased CI-green + 250-cap + gates + shell-coverage campaign
Rewritten as a 4-phase recurring driver per user request: (0) fix current
CI red state — found Pre-commit checks AND Python tests both failing with
an identical, pre-existing coverage gap (python_pkg/artgate/routes/vector.py:156,
99.98% total, rsvg-convert missing on the GitHub Actions runner) that
predates this session by at least a day; Shell tests was also red from
this session's own archive commit, already fixed in e48f253 and confirmed
green — (1) drive the 11 remaining over-cap files to zero, same
dead-code-check-in-first pattern as every prior split — (2) only then wire
check_file_length.sh into pre-commit as a hard gate, plus a CI-green check
(mechanism deliberately left as an open question for the user: check the
latest main run, or extend the pre-push ci-mirror hook) — (3) a new,
separately-scoped repo-wide 100% shell coverage gate, measured at 487 .sh
files against only 14 existing lib/tests/ directories, explicitly flagged
as needing its own user confirmation and ratchet-vs-hard-gate decision
before starting given the scale.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
This commit is contained in:
parent
e48f253b23
commit
eb46b365cf
@ -1,136 +1,245 @@
|
||||
# Next session: pick the next §3/§4 target — no split candidate is currently in scope
|
||||
# Next session: Phase-driven campaign — CI green → 250-cap zero → gates → shell coverage
|
||||
|
||||
> **Paste this whole file into a fresh Claude session opened in `~/testsAndMisc`.**
|
||||
> It is self-contained. Do not go looking for the previous session's context.
|
||||
|
||||
Over-cap: **11** (10 shell, 2 kotlin, 1 dart — `focus_owner`'s two Kotlin files
|
||||
count once regardless of listing style). Working tree clean, `main` in sync
|
||||
as of the `setup_hosts_guard.sh` archive commit (see §0).
|
||||
This file drives a **multi-session campaign** with four phases, run strictly
|
||||
in order. Do not skip ahead to a later phase while an earlier one is
|
||||
incomplete — re-check the phase's exit condition at the start of every
|
||||
session, even if this doc claims it's done, since state can drift between
|
||||
sessions.
|
||||
|
||||
**The user's request that created this campaign** (verbatim intent): make it
|
||||
true FOR SURE that all files are under the 250-line cap, then add a 100%
|
||||
shell test-coverage gate, then add a pre-commit rule that blocks commits when
|
||||
any file is over 250 lines AND checks that GitHub Actions is green on this
|
||||
repo.
|
||||
|
||||
Two standing decisions from the user, already made — do **not** re-litigate:
|
||||
|
||||
1. **100% line coverage on what you extract** — same bar every session so far
|
||||
has applied. Does not apply to archived/deleted code (no split happened).
|
||||
1. **100% line coverage on what you extract/write tests for** — same bar
|
||||
every prior split has used.
|
||||
2. **Split blind where there is no device.** Do not deploy to the phone, do
|
||||
not ask to. Prove splits with tests, hashes and real runs instead.
|
||||
|
||||
Three decisions made when this campaign was scoped (2026-08-18) — also do
|
||||
**not** re-litigate without asking first:
|
||||
|
||||
3. **This is a recurring driver, not a single mega-session.** One phase step
|
||||
per session (usually one file split, or one CI fix), same pace as every
|
||||
split so far. Update this file at the end of each session for the next.
|
||||
4. **CI must be fixed before any new gate is added.** A "must be green" gate
|
||||
is meaningless while CI is already red for unrelated reasons.
|
||||
5. **The new shell coverage gate is a NEW, separate requirement** covering
|
||||
every `.sh` file repo-wide (not just newly-split ones). This is Phase 3,
|
||||
explicitly the largest phase — do not conflate it with Phase 1's cap work.
|
||||
|
||||
---
|
||||
|
||||
## 0. What just happened (read this, don't repeat it)
|
||||
## Phase 0: Fix current CI red state — **STATUS: in progress, check first**
|
||||
|
||||
`setup_hosts_guard.sh` (576 lines) was this session's assigned split target.
|
||||
The dead-code check-in (per the §0 lesson from two sessions before this one)
|
||||
turned up evidence the file might be fully superseded — confirmed by
|
||||
inspecting live machine state: the legacy pacman hooks it installs were
|
||||
absent from `/etc/pacman.d/hooks/`, its systemd units were all `disabled`,
|
||||
and guard-lib's `/etc/guard-lib/targets/{hosts,nsswitch,resolved}.conf` were
|
||||
all already populated. The user confirmed: archive, don't split.
|
||||
Three workflows were found red on `main` as of 2026-08-18, discovered while
|
||||
scoping this campaign:
|
||||
|
||||
Scope grew past the one named file once the directory was surveyed: the
|
||||
**whole legacy hosts-guard subsystem** (17 files — `setup_hosts_guard.sh`,
|
||||
`enforce-hosts.sh`, `enforce-nsswitch.sh`, `enforce-resolved.sh`, 6 systemd
|
||||
units, `install_pacman_hooks.sh`, `pacman-hooks/*`, `psychological/*`, both
|
||||
READMEs) only existed to support the retired system, so it went to
|
||||
`testsAndMisc-archive` together via `git filter-repo` (same procedure as the
|
||||
plagiarism-tools and libre_translate archives). `plugins/nsswitch-plugin.sh`
|
||||
and `plugins/resolved-plugin.sh` were **kept** — they're guard-lib's live
|
||||
plugins, registered by absolute path in `/etc/guard-lib/targets/*.conf`.
|
||||
1. **`Pre-commit checks` AND `Python tests` workflows — same root cause,
|
||||
both persistent and predating this campaign.** Both fail with
|
||||
`FAIL Required test coverage of 100% not reached. Total coverage: 99.98%`
|
||||
(6565 lines/1 miss, 1630 branches/1 miss). The gap is
|
||||
`python_pkg/artgate/routes/vector.py:156` (95% coverage in CI). Root
|
||||
cause: CI logs show `SKIPPED python_pkg/artgate/tests/test_routes.py:124:
|
||||
rsvg-convert not installed` — the `ubuntu-latest` GitHub Actions runner
|
||||
lacks `rsvg-convert`, so a test that would cover line 156 doesn't run
|
||||
there, while it passes locally (and in the pre-push `ci-mirror` hook,
|
||||
confirmed — that hook passed on both of this session's pushes) where
|
||||
`rsvg-convert` is installed. **This predates this campaign by at least a
|
||||
day** — `Python tests` was already failing with the identical signature
|
||||
on 2026-08-17 commits (`vscode_optimizer: split...`,
|
||||
`transcribe_helpers: split...`, etc.), long before the hosts-guard
|
||||
archive started. **Not yet fixed** — pick this up first, it blocks BOTH
|
||||
workflows simultaneously since they share the same coverage command.
|
||||
Likely fix: add `rsvg-convert` (librsvg) to whichever GitHub Actions
|
||||
runner setup step precedes pytest in `.github/workflows/pre-commit.yml`
|
||||
and `.github/workflows/python-tests.yml`, OR make the skipped test's
|
||||
coverage line conditionally excludable when the tool is genuinely absent
|
||||
(ask the user which they'd rather have — installing the real dependency
|
||||
in CI is almost certainly correct here, but confirm before choosing an
|
||||
`# pragma: no cover`-style route given the no-suppressions rule).
|
||||
2. **`Shell tests` workflow** — was also red (this campaign's own earlier
|
||||
commit broke `test_hosts_guard_pacman_integration.sh` by archiving files
|
||||
it referenced). **Already fixed** this session, commit `e48f253`, and
|
||||
confirmed green on the very next push (`gh run view 32185366621` →
|
||||
`success`). Re-verify it's still green before trusting this note
|
||||
(`gh run list --limit 3`) — don't assume it stayed fixed if something
|
||||
else touched shell tests since.
|
||||
|
||||
`check_and_enable_services.sh`'s `check_hosts()` function was rewritten in
|
||||
the same commit (user confirmed this too) to check guard-lib state
|
||||
(`guardctl file-guard status <name>`) instead of the legacy systemd
|
||||
units/enforce-scripts it used to check and self-repair. Verified live:
|
||||
`sudo bash check_and_enable_services.sh --status` now reports the hosts
|
||||
service `ok` against the actual migrated machine, where the old code would
|
||||
have reported `error` (three units it expected enabled were `disabled` by
|
||||
design). `linux_configuration/.github/copilot-instructions.md` (always-loaded)
|
||||
and one comment in `hosts/install.sh` were also updated to stop naming the
|
||||
archived files.
|
||||
**Exit condition for Phase 0:** `gh run list --limit 5` shows the most
|
||||
recent run of `Pre-commit checks`, `Python tests`, AND `Shell tests` on
|
||||
`main` all as `success`. Do not proceed to Phase 1 until this is true. If a
|
||||
session starts and Phase 0 isn't done, finish it before touching anything
|
||||
else — don't let it linger while new work piles on top of a broken
|
||||
baseline.
|
||||
|
||||
**Lesson (now 3 for 4):** the check-in keeps changing scope, and this time it
|
||||
changed scope _twice_ — first archive-vs-split, then "just this file" vs
|
||||
"the whole dead subsystem." Keep surveying the directory (`grep -rl`, not
|
||||
just the named file) before proposing an archive's file list, and keep
|
||||
confirming scope growth with the user before executing it.
|
||||
## Phase 1: Drive the 250-line cap to zero
|
||||
|
||||
## 0.1 Known defect found but NOT fixed this session — flag again if touching guard-lib
|
||||
**Status as of 2026-08-18: 11 files over cap.** Re-run
|
||||
`bash meta/scripts/check_file_length.sh --all` at the start of every session
|
||||
in this phase — the exact list drifts as other work touches these files.
|
||||
|
||||
`/etc/guard-lib/targets/nsswitch.conf` and `.../resolved.conf` both have
|
||||
`PLUGIN=` pointing at the **repo checkout**
|
||||
(`/home/kuhy/testsAndMisc/linux_configuration/scripts/periodic_background/hosts/guard/plugins/*.sh`)
|
||||
instead of `/usr/local/share/guard-lib-plugins/`, which
|
||||
`migrate_hosts_guard_to_guard_lib.sh`'s own header warns against by name
|
||||
("pointing it at a repo checkout... silently breaks enforcement the day that
|
||||
directory moves"). `/usr/local/share/guard-lib-plugins/` does not exist on
|
||||
this machine at all — the migration's plugin-install step appears to have
|
||||
never run. Not fixed this session: it needs a sudo mutation of a live
|
||||
security-enforcement system plus `guardctl` re-registration, which the user
|
||||
was not asked to approve. If a future session touches guard-lib, nsswitch,
|
||||
resolved, or moves/renames this checkout, raise this first.
|
||||
```
|
||||
1734 linux_configuration/scripts/periodic_background/digital_wellbeing/setup_midnight_shutdown.sh
|
||||
1225 linux_configuration/scripts/periodic_background/check_and_enable_services.sh
|
||||
1017 linux_configuration/scripts/single_use/utils/generate_study_materials.sh
|
||||
929 linux_configuration/scripts/periodic_background/digital_wellbeing/pacman/pacman_wrapper.sh
|
||||
918 linux_configuration/scripts/periodic_background/digital_wellbeing/setup_night_lockdown.sh
|
||||
913 linux_configuration/scripts/periodic_background/hosts/install.sh
|
||||
705 linux_configuration/scripts/periodic_background/digital_wellbeing/block_compulsive_opening.sh
|
||||
564 focus_owner/android/app/src/main/kotlin/com/kuhy/focus_owner/EnforcementRunner.kt
|
||||
485 linux_configuration/scripts/periodic_background/digital_wellbeing/install_leechblock.sh
|
||||
415 focus_owner/android/app/src/main/kotlin/com/kuhy/focus_owner/DevicePolicyBridge.kt
|
||||
307 focus_owner/lib/status_page_state.dart
|
||||
```
|
||||
|
||||
## 1. This session's task: none pre-selected — ask the user
|
||||
|
||||
Every file currently over the 250-line cap is already on an explicit
|
||||
out-of-scope list from a prior session (§3 below, or the equivalent of the
|
||||
old §4). There is no unclaimed split candidate right now. Options, in
|
||||
roughly ascending order of friction:
|
||||
|
||||
- Re-run `bash meta/scripts/check_file_length.sh --all` fresh (files may have
|
||||
grown/shrunk since this doc was written) and see if a genuinely new
|
||||
candidate appeared.
|
||||
- Ask the user whether any §3/§4 file should be taken out of its hold (e.g.
|
||||
"is `install_leechblock.sh`/`block_compulsive_opening.sh` still deployed at
|
||||
`/usr/local/…`? still preferred by `pacman_wrapper.sh:831`?" — re-verify,
|
||||
don't assume the old note is still true).
|
||||
- Ask the user for a completely different task.
|
||||
|
||||
**Ask before picking** — do not silently start splitting a file that a prior
|
||||
session explicitly parked, and do not assume "no candidate" means "nothing to
|
||||
do here" without checking with the user first.
|
||||
|
||||
## 2. §3 — do not touch this session (unless the user lifts it)
|
||||
|
||||
`install_leechblock.sh` (485) and `block_compulsive_opening.sh` (705) are
|
||||
copied to `/usr/local/…`, and `pacman_wrapper.sh:831` prefers the deployed
|
||||
copy on **every pacman invocation**. Splitting them naively breaks every
|
||||
`pacman -S` on this machine. Re-verify this is still true (grep
|
||||
`pacman_wrapper.sh` for the deployed-copy preference) before assuming the old
|
||||
note still holds — a lot has changed guard-lib-side this session, worth the
|
||||
30-second re-check.
|
||||
**Two of these carry a live-deployment trap, handle last or very carefully:**
|
||||
`install_leechblock.sh` and `block_compulsive_opening.sh` are copied to
|
||||
`/usr/local/…`, and `pacman_wrapper.sh:831` prefers the deployed copy on
|
||||
**every pacman invocation**. Splitting them naively breaks every
|
||||
`pacman -S` on this machine. `pacman_wrapper.sh` itself carries the same
|
||||
trap (it IS the thing that prefers the deployed copies). Re-verify this is
|
||||
still true before assuming the old note holds — a lot changed guard-lib-side
|
||||
in the session that wrote this doc, worth the 30-second re-check
|
||||
(`grep -n "prefer\|deployed" pacman_wrapper.sh` near line 831).
|
||||
|
||||
You cannot run `sudo pacman -S` from the Bash tool — it deadlocks on
|
||||
`db.lck`. Hand the user a `! sudo pacman -S <pkg>` line plus the expected
|
||||
output if `pacman_wrapper.sh` ever needs live verification.
|
||||
|
||||
## 3. Out of scope until the user says otherwise
|
||||
The Kotlin and Dart files need a different verification stack —
|
||||
`focus_owner` gradle needs `JAVA_HOME=/usr/lib/jvm/java-21-openjdk` and
|
||||
`--rerun-tasks`; a plain `gradlew test` reports `UP-TO-DATE` and proves
|
||||
nothing.
|
||||
|
||||
`setup_midnight_shutdown.sh` (1734), `check_and_enable_services.sh` (1225,
|
||||
edited this session but not split — same out-of-scope reasoning as before),
|
||||
`generate_study_materials.sh` (1017), `pacman_wrapper.sh` (929),
|
||||
`setup_night_lockdown.sh` (918), `hosts/install.sh` (913, one comment edited
|
||||
this session), `EnforcementRunner.kt` (564), `DevicePolicyBridge.kt` (415),
|
||||
`status_page_state.dart` (307) — check `check_file_length.sh --all` for the
|
||||
current exact list before assuming this is still accurate, since files
|
||||
change size between sessions.
|
||||
**Before splitting ANY file in this list, run the dead-code check-in first**
|
||||
(ask the user: "do you still use this?"). This lesson has held 3 of the last
|
||||
4 sessions — files on this list have turned out to be fully superseded by
|
||||
something else (guard-lib replaced the entire hosts-guard subsystem this
|
||||
way). Don't assume a file needs splitting just because it's long; it might
|
||||
need archiving instead. When surveying a candidate for archival, survey its
|
||||
**whole directory and cross-references** (`grep -rl <name>` repo-wide), not
|
||||
just the named file — this has changed scope from "split one file" to
|
||||
"archive 17 files" once already.
|
||||
|
||||
`pacman_wrapper.sh` carries the same live-deployment trap as §2. The Kotlin
|
||||
and Dart files need a different verification stack — `focus_owner` gradle
|
||||
needs `JAVA_HOME=/usr/lib/jvm/java-21-openjdk` and `--rerun-tasks`; a plain
|
||||
`gradlew test` reports `UP-TO-DATE` and proves nothing.
|
||||
**Exit condition for Phase 1:**
|
||||
`bash meta/scripts/check_file_length.sh --all` exits 0 with no files listed.
|
||||
Do not proceed to Phase 2 until this is true.
|
||||
|
||||
## 4. Rules that will bite you (carried forward, still true)
|
||||
## Phase 2: Wire the file-length gate into pre-commit
|
||||
|
||||
- **Ask before large scope changes.** Three of the last four sessions have
|
||||
changed scope mid-session because the user volunteered new information, or
|
||||
a check-in (dead-code, or in this session's case a directory survey)
|
||||
surfaced something bigger than the named file. That is fine and expected —
|
||||
just don't assume silence means "keep going as originally scoped."
|
||||
**Do NOT do this until Phase 1's exit condition is met.** Wiring it early
|
||||
breaks every commit repo-wide, including unrelated ones, for as long as
|
||||
Phase 1 remains incomplete.
|
||||
|
||||
Once `check_file_length.sh --all` exits 0:
|
||||
|
||||
1. Add a `local` hook to `.pre-commit-config.yaml` that runs
|
||||
`bash meta/scripts/check_file_length.sh --all` and fails the commit
|
||||
(non-zero exit) if any file is found. Follow the existing local-hook
|
||||
pattern already in the file (see e.g. the `ai-evidence-contract` or
|
||||
`no-polling-antipatterns` hooks for the `language: system` +
|
||||
`pass_filenames: false` shape — this check is repo-wide, not
|
||||
per-file, since a file that grows past 250 lines without being staged
|
||||
this commit should still be caught).
|
||||
2. Also add the GitHub-Actions-green check here (see below) if it hasn't
|
||||
been added yet — the user asked for both in the same pre-commit rule,
|
||||
though they can land as two hooks in the same commit rather than one
|
||||
combined script if that's cleaner.
|
||||
3. **GitHub-Actions-green check, exact mechanism to decide with the user
|
||||
first (ask, don't assume):** a pre-commit hook cannot literally block a
|
||||
commit on "is CI green" for a commit that doesn't exist yet — CI runs
|
||||
AFTER a push, not before a commit. Two real options:
|
||||
- **(a) Check the LATEST run on `main` is green** before allowing a new
|
||||
commit — catches "you're building on top of a known-broken baseline"
|
||||
but not "did MY change break something," since that can only be known
|
||||
after pushing.
|
||||
- **(b) A pre-PUSH hook** (this repo already has a pre-push stage, see
|
||||
`ci-mirror`) that runs the equivalent of the CI workflows locally
|
||||
before allowing the push — closer to the actual guarantee wanted, and
|
||||
`ci-mirror` already does exactly this for the Python/pre-commit side.
|
||||
Extending it (or adding a sibling hook) to also run the `Shell tests`
|
||||
workflow's local-equivalent commands before push may be the more
|
||||
honest way to satisfy "checks GitHub workflow outputs green" than
|
||||
querying `gh run list` for a run that hasn't happened yet.
|
||||
|
||||
Ask the user which they want (or both) before implementing — this is a
|
||||
genuine design fork, not a mechanical step.
|
||||
|
||||
4. Verify by making a throwaway file exceed 250 lines and confirming the
|
||||
commit is actually blocked with a clear error message, then removing the
|
||||
throwaway file, before considering this phase done.
|
||||
|
||||
**Exit condition for Phase 2:** the new hook(s) exist in
|
||||
`.pre-commit-config.yaml`, `pre-commit run --files <touched>` fails when a
|
||||
file exceeds 250 lines (verified with a throwaway test), and the mechanism
|
||||
chosen for the CI-green check is documented in this doc's next revision.
|
||||
|
||||
## Phase 3: Repo-wide 100% shell coverage gate — **the largest phase, expect many sessions**
|
||||
|
||||
**Do NOT start this until Phase 1 AND Phase 2 are both done.** This is
|
||||
explicitly scoped as separate, much larger work — do not let it bleed into
|
||||
or block the 250-cap campaign.
|
||||
|
||||
**Scale, measured 2026-08-18:** 487 `.sh` files exist repo-wide (excluding
|
||||
`.venv/`, vendored, and build-output dirs) versus only 14 `lib/tests/`
|
||||
directories following the established split-and-test pattern. A genuinely
|
||||
repo-wide "100% line coverage, every shell script" gate would immediately
|
||||
demand test suites for on the order of 450+ currently-untested scripts. This
|
||||
is roughly an order of magnitude more work than Phase 1's 11 files. Re-count
|
||||
before starting (`find . -name '*.sh' -not -path '*/.venv/*' -not -path
|
||||
'*/node_modules/*' -not -path '*/testsAndMisc_builds/*' -not -path
|
||||
'*/testsAndMisc_binaries/*' -not -path '*/.git/*' | wc -l`), since Phase 1
|
||||
will have grown the tested-file count somewhat.
|
||||
|
||||
**Ask the user to confirm scope before starting Phase 3 at all** — 487
|
||||
files is a genuinely large body of future work and deserves an explicit
|
||||
"yes, still want this" check before a session starts writing hundreds of
|
||||
test files, not just a paste of an old plan. Also ask whether the gate
|
||||
should apply repo-wide from day one (blocking ANY commit touching an
|
||||
untested `.sh` file) or ratchet in incrementally (e.g. only newly-added or
|
||||
newly-modified files must be covered, with a frozen allowlist of
|
||||
pre-existing untested files that shrinks over time) — a hard repo-wide gate
|
||||
turned on immediately would block unrelated commits to any of the 450+
|
||||
untested files until every one of them gets a test suite, which could stall
|
||||
unrelated work for a long time. A ratcheting gate is the much more common
|
||||
pattern for retrofitting coverage onto an existing codebase and is worth
|
||||
raising as the recommended default, but it's the user's call.
|
||||
|
||||
Use `meta/scripts/shell_coverage.sh <test> <subject> [min]` (kcov wrapper)
|
||||
and the established `lib/tests/` + harness + PATH-shim pattern from every
|
||||
split so far (see Phase 1's testing-pattern reference below) — there is no
|
||||
reason for shell test infrastructure to differ between "coverage added
|
||||
because we split the file" and "coverage added because a new gate demands
|
||||
it."
|
||||
|
||||
**Exit condition for Phase 3:** every `.sh` file in the repo (or every file
|
||||
not on an explicitly agreed allowlist, if ratcheting was chosen) has a test
|
||||
suite reaching the agreed minimum coverage, and a pre-commit/CI gate enforces
|
||||
it going forward. Given the scale, expect this phase's "exit condition" to
|
||||
itself be revised into something more incremental once the user weighs in.
|
||||
|
||||
---
|
||||
|
||||
## Rules that will bite you (carried forward, still true)
|
||||
|
||||
- **Ask before large scope changes.** Repeatedly, a check-in or a directory
|
||||
survey has surfaced something bigger than the named task. That's expected —
|
||||
don't assume silence means "keep going as originally scoped."
|
||||
- **Survey the whole directory before scoping an archive, not just the named
|
||||
file.** `grep -rl <filename-stem>` across the repo, then `ls` the file's
|
||||
own directory — this session's file list grew from 1 to 17 files this way.
|
||||
own directory.
|
||||
- **No suppressions, ever.** No `# noqa`, no per-file-ignore added without
|
||||
asking every time, no shellcheck disable beyond what's already justified
|
||||
inline.
|
||||
inline. This applies to Phase 0's coverage gap too — don't reach for a
|
||||
coverage-exclude pragma without asking first; installing the missing
|
||||
dependency in CI is the more likely correct fix.
|
||||
- **A file must not assign a global it never reads** (SC2034). The hook runs
|
||||
`shellcheck` with **no `-x`**, but `.shellcheckrc`'s
|
||||
`external-sources=true` + `source-path=SCRIPTDIR` means a `source=`
|
||||
@ -143,37 +252,39 @@ needs `JAVA_HOME=/usr/lib/jvm/java-21-openjdk` and `--rerun-tasks`; a plain
|
||||
- **Every commit touching code needs evidence** in
|
||||
`docs/superpowers/evidence/<slug>-<date>.json`. Staging **≥4 code files
|
||||
also needs** a fresh `docs/superpowers/contracts/*.json`. Put the
|
||||
**measured** number in it, not a rounded-up one. This session's pair
|
||||
(`archive-setup-hosts-guard-2026-08-18.json` in both `evidence/` and
|
||||
`contracts/`) documents an archive-plus-live-script-fix, not a pure split —
|
||||
read it if the next task is another archive-vs-split judgment call.
|
||||
- **An archive does not need new tests.** The 100%-coverage standing decision
|
||||
binds code that gets _split_, not code that gets _deleted_. Neither this
|
||||
session's archive nor the two before it added tests for the archived code.
|
||||
**measured** number in it, not a rounded-up one.
|
||||
- **An archive does not need new tests.** The 100%-coverage standing
|
||||
decision binds code that gets _split_ or newly _written_, not code that
|
||||
gets _deleted_.
|
||||
- **A test file broken by an archive commit is a same-session bug, not a
|
||||
future TODO.** This campaign already hit this once
|
||||
(`test_hosts_guard_pacman_integration.sh`, fixed in `e48f253`) — `gh run
|
||||
list` after every push, not just `pre-commit run --files <staged>`
|
||||
locally, since CI-only test suites (like `linux_configuration/tests/*.sh`
|
||||
run directly by `shell-tests.yml`) aren't caught by pre-commit's
|
||||
file-scoped hooks.
|
||||
- Work directly on `main`. `git stash` and branch creation are blocked; use
|
||||
`git worktree add --detach` for a clean baseline (but NEVER `git filter-repo`
|
||||
inside a worktree — it shares the object store with the main repo and will
|
||||
corrupt it; always a throwaway `git clone` for that).
|
||||
- **Do not wire the file-length hook into pre-commit.** It lands last, once
|
||||
`check_file_length.sh --all` exits 0.
|
||||
`git worktree add --detach` for a clean baseline (but NEVER
|
||||
`git filter-repo` inside a worktree — it shares the object store with the
|
||||
main repo and will corrupt it; always a throwaway `git clone` for that).
|
||||
- Watch `jscpd` (fails above 2%). Measure in a **clean HEAD worktree**.
|
||||
- Cap pytest memory:
|
||||
`systemd-run --user --scope -p MemorySwapMax=0 -p MemoryMax=2G`.
|
||||
- **Never let a test allocate unbounded real memory.**
|
||||
|
||||
## 5. Tooling reference
|
||||
## Tooling reference
|
||||
|
||||
**`meta/scripts/check_file_length.sh --all`** — the 250-line gate. Run
|
||||
**before every commit**. Applies to test files too, not just the file you're
|
||||
splitting.
|
||||
**before every commit**. Applies to test files too, not just the file
|
||||
you're splitting.
|
||||
|
||||
**`meta/scripts/shell_coverage.sh <test> <subject> [min]`** — kcov wrapper,
|
||||
100% minimum. Hand it the test script **directly**; `bash script.sh`
|
||||
instruments the bash binary and silently reports 0/0.
|
||||
|
||||
**`meta/scripts/extract_shell_functions.py`** — moves functions
|
||||
brace-by-brace. **Never slice by line range**. Verify placement with `grep -c`
|
||||
on the anchor.
|
||||
brace-by-brace. **Never slice by line range**. Verify placement with
|
||||
`grep -c` on the anchor.
|
||||
|
||||
**`meta/scripts/verify_shell_split.sh <pre-split-rev> <old> <new>...`** —
|
||||
proves a split moved every function verbatim. For a **partial** split list
|
||||
@ -183,19 +294,19 @@ the old path among the new paths too.
|
||||
required.
|
||||
|
||||
**Archiving a dead file/subsystem** (no dedicated script — hand-run each
|
||||
time): clone to a scratch dir, `git filter-repo --force --path <each current
|
||||
path> --path <each historical path from `git log --all --follow
|
||||
time): clone to a scratch dir, `git filter-repo --force --path <each
|
||||
current path> --path <each historical path from `git log --all --follow
|
||||
--name-only`>`, clone `testsAndMisc-archive` separately, add the filtered
|
||||
clone as a remote, `git merge --allow-unrelated-histories`, remove stray
|
||||
remote-tracking branches and the remote, push, verify with `gh api
|
||||
repos/kuhyx/testsAndMisc-archive/contents/<dir>`, **then** `git rm` from
|
||||
`testsAndMisc`. Read `docs/superpowers/evidence/archive-setup-hosts-guard-2026-08-18.json`
|
||||
or `archive-plagiarism-tools-2026-08-18.json` for the full worked example.
|
||||
`testsAndMisc`. Read
|
||||
`docs/superpowers/evidence/archive-setup-hosts-guard-2026-08-18.json` for
|
||||
the full worked example.
|
||||
|
||||
## 6. Testing pattern to follow (for an actual split, if one gets picked)
|
||||
## Testing pattern to follow (Phase 1 splits and Phase 3 new coverage alike)
|
||||
|
||||
The established pattern for `single_use/`-adjacent shell scripts with no
|
||||
prior test coverage (used across three prior splits):
|
||||
The established pattern for shell scripts with no prior test coverage:
|
||||
|
||||
- A `lib/tests/` directory sibling to the split libs.
|
||||
- A `*_harness.sh` file (sourced, not executed) with `_t_pass`/`_t_fail`/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user