release: 0.17.0 — Markers that were trusted to be numbers - #328
Merged
Conversation
Co-Authored-By: Max <noreply>
fdaviddpt
added a commit
that referenced
this pull request
Aug 8, 2026
…e sweep (#336) * fix(#326,#332): bound the marker's range, not just its syntax — and let a check do the sweep #326 — the four cooldown guards validate SYNTAX and not RANGE. A digits-only marker ahead of now is accepted, makes ELAPSED negative, and a negative ELAPSED is -lt any cooldown, so the gate takes its `exit 0` — which sits ABOVE the line that rewrites the marker. The self-heal the last three releases rest on is unreachable on exactly the path that needs it: no save, no compression, no git backup, permanently and mutely, until the wall clock catches up. Three states, not two. Out of range now PROCEEDS, resets the marker at the point of rejection where the reset is reachable, and says so once in hook-errors.log via a new report_error() in log.sh. A silent clamp would trade a mute stuck throttle for a mute wrong value. post-tool-hook.sh is deliberately asymmetrical: it declines the cooldown it cannot substantiate and does nothing else — no rewrite (the marker is save-session.sh's), no diagnostic (one per tool call), no added spawn or read (#299/#330). The source comment at save-session.sh:155 asserted the opposite and is corrected here. That comment, not the CHANGELOG, is why the issue was reopened: PR #328 closed it by referencing it. #332 — twelve remaining sites read a case-guarded value into $(( )) with no 10#, not the seven the issue lists. The five extra were found by tests/test_arith_base_lint_332.py, which sweeps scripts/ and hooks.d/ for the shape mechanically and is the part that prevents a sixth issue. ShellCheck does not flag it (koalaman/shellcheck#2679). No shared helper: a helper a new author does not know about cannot stop them writing the sixteenth site. tests/test_ndc_day_boundary.py was suppressing NDC by writing a marker 34,000 years in the future — #326's defect used as an off switch. Switched to _suppress_ndc, the brake the product documents (#159). Targeted RED verified before the fix at all four sites; full suite 1545 passed, 43 skipped. Windows unverified — CI is the authority. Co-Authored-By: Max <noreply> * review(#336): a fifth site the issue never named, and a lint that would have cried wolf Findings from the /code-review pass on PR #336, fixed in the same run. FIFTH SITE (#326). hooks.d/before_session_start/50-git-restore.sh reads `started=` through the same digits-only case. A value ahead of now makes _age negative, so _fetch_health answers "in-flight" — the one state meaning "wait, something is already running" — about nothing, and _spawn_fetch takes its early return so the only writers of the record never run. Same geometry as the four sites #326 enumerates, and not on its list. The harm is worse than a wrong label: the caller then prints "already up to date with origin/main" off refs no fetch refreshed, which is exactly what _fetch_health's own header forbids. Now answers "abandoned" and spawns a real fetch that rewrites the record. _fetch_health stays pure — its stdout is the verdict, read through $( ) — so the diagnostic goes in _spawn_fetch. LINT COULD NOT BE TRUSTED AS A GATE (#332). `case "$1" in` captures the guarded name as the bare string "1", and the matcher did not require the $ sigil, so every `$(( x + 1 ))` in a file guarding a positional parameter was a finding. lib-lock.sh guards two, so the next ordinary arithmetic there would have failed CI for no reason. Numeric names now require the sigil. ITS OWN FIXTURE WAS NOT THE SHAPE IT CLAIMED. `''` inside a single-quoted Python literal closes it and opens another, so the planted guard had silently become `case "$LAST" in |*[!0-9]*)`. A self-test whose fixture is not what it plants still goes green, and green here is supposed to mean "looked, found none". Pinned by a test. STALE LINE-NUMBER CITATIONS. Six comments this PR added cited line numbers; three were already wrong at commit time. All replaced with construct names. A PR that exists because a comment outlived the truth should not add more. Targeted RED verified before each fix — including catching that the first draft of the restore tests passed vacuously, because a doubled backslash put a literal \\n in the state file and the digits-only guard rejected it for the wrong reason. Full suite 1551 passed, 43 skipped. Windows unverified. Co-Authored-By: Max <noreply>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Manifest 0.16.0 → 0.17.0 and the CHANGELOG section for the release. No code.
Ships #322 (the two cooldown markers
save-session.shfed to$(( )), reported and fixed by @jmossie82) and #320 (the auth-marker scan's blind spot).The intro states plainly what this release does not fix: #326 (the guards check syntax, not range — a future-dated marker sticks the throttle on, and the rewrite is unreachable on that path) and #327 (
10#landed insave-session.shonly). Both predate this release, both arefails-to-preserve, neither blocks it — but the previous CHANGELOG wording asserted a self-heal property that is only true for the syntax-error case, so that claim is now scoped rather than left to mislead whoever reads it next.Release-gate audit of
v0.16.0..main: nodestroys, nodiscloses. Findings filed as #326/#327.Local suite not run — this is a manifest field and markdown, and there is no version-drift test in this repo (swept:
.claude-plugin/plugin.jsonis the only file carrying the version). CI is the authority.