From dec78e89cc24f5258cabfbdfb0f7b2d4d4b3fc76 Mon Sep 17 00:00:00 2001 From: "basquin-bot[bot]" <307641014+basquin-bot[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 11:53:03 -0400 Subject: [PATCH 1/5] =?UTF-8?q?fix(dd045):=20item=202=20=E2=80=94=20a=20tr?= =?UTF-8?q?acked=20pointer=20file=20for=20the=20run=20of=20record?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bench-results/RUN-OF-RECORD is a tracked pointer FILE (not a symlink — this checkout has core.symlinks=false, on which a tracked symlink materialises as a plain-text file naming its target rather than resolving) holding one non-comment line naming the current run-of-record directory. scripts/check-citations.py's resolve() now substitutes a cited bench-results/RUN-OF-RECORD/... prefix with the directory the pointer names before matching it against the tracked tree (resolve_run_of_record()), reusing the existing FAILED/DEAD-PATH reporting path rather than adding a parallel one. A dangling, missing, or malformed (0 or 2+ non-comment-line) pointer is never a silent pass or a guess: each was proven empirically to produce exit=1 with a DEAD PATH finding naming the reason, and restoring the pointer returned exit=0 again every time. Repointed all 14 occurrences across the 5 files that named verify-20260730T215842Z (counted with grep -o | wc -l, not grep -c, per the lesson 16da079 shipped) to bench-results/RUN-OF-RECORD/; check-citations.py's disposition counts are byte-identical before and after. Removed the now-moot "proposed, not yet built" allowlist exemption for the pointer path. scripts/verify-dd043-pr3.sh was not touched and does not write this file — promoting a run stays a deliberate, manual edit in the same commit that adds the new run directory, per the pointer file's own comment header. Closes DD-045 item 2 in TODO.md and docs/ROADMAP.md, describing what was actually delivered. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01LHBLwqfM1acog2bHRS8WCb --- TODO.md | 32 +++++++--- bench-results/RUN-OF-RECORD | 14 +++++ .../README.md | 4 +- docs/ROADMAP.md | 32 ++++++---- .../2026-07-26-dd043-pr3-maven-injector.md | 2 +- ...26-07-24-native-reactive-targets-design.md | 4 +- scripts/check-citations-allowlist.txt | 1 - scripts/check-citations.py | 58 +++++++++++++++++++ 8 files changed, 121 insertions(+), 26 deletions(-) create mode 100644 bench-results/RUN-OF-RECORD diff --git a/TODO.md b/TODO.md index 3e8b5a1..398a2fb 100644 --- a/TODO.md +++ b/TODO.md @@ -1184,12 +1184,28 @@ the feature held in every one, and almost every finding was in the machinery tha but is gitignored — the citation resolved for its author and was dead on every fresh clone (fixed in the same pass that added this entry). Evidence for the scale that motivated building it: `bench-results/dd043-pr3-citation-audit-2026-07-30/`. -- [ ] **2 — a stable pointer to the run of record.** Timestamped `verify-/` names mean each new - run stales every citation to the previous one at once: **10, 10, 13 and 18** occurrences had to be - repointed by the four supersession commits, each figure read out of that commit's own message - (`16da079`, `865ba35`, `1c3ce88`, `572282a`) and counted as occurrences rather than matching lines - — `16da079` records `grep -c` reporting eight where there were ten. Add - `bench-results/RUN-OF-RECORD` and cite that. +- [x] **2 — a stable pointer to the run of record. Delivered.** Timestamped `verify-/` names meant + each new run staled every citation to the previous one at once: **10, 10, 13 and 18** occurrences + had to be repointed by the four supersession commits, each figure read out of that commit's own + message (`16da079`, `865ba35`, `1c3ce88`, `572282a`) and counted as occurrences rather than + matching lines — `16da079` records `grep -c` reporting eight where there were ten. Added + `bench-results/RUN-OF-RECORD`, a tracked pointer **file** — not a symlink: this checkout has + `core.symlinks=false`, on which a tracked symlink materialises as a plain-text file containing its + target path rather than resolving. Format: `#`-comment and blank lines ignored, then exactly one + line naming a `bench-results/` subdirectory by name only. `scripts/check-citations.py`'s + `resolve()` substitutes a cited `bench-results/RUN-OF-RECORD/...` prefix with the directory the + pointer names before matching the tracked tree (`resolve_run_of_record()`), reusing the existing + FAILED/DEAD-PATH reporting path rather than adding a parallel one. Repointed all **14** occurrences + across the **5** files that named `verify-20260730T215842Z` (counted with `grep -o … | wc -l`, not + `grep -c`, per the lesson above) to `bench-results/RUN-OF-RECORD/`; `python3 + scripts/check-citations.py`'s disposition counts are byte-identical before and after the repoint, + both runs exit 0. The three failure modes a resolver like this must never silently pass were each + proven empirically, not asserted: a pointer naming an untracked directory, a missing pointer file, + and a pointer with 0 or 2 non-comment lines each produced a `DEAD PATH` finding and `exit=1`; + restoring the pointer returned `exit=0` again every time. `scripts/verify-dd043-pr3.sh` was not + touched and does not write this file — promoting a run to run-of-record stays a deliberate, manual + edit made in the same commit that adds the new run directory, stated in the pointer file's own + comment header. - [ ] **3 — mutation-test the harness, not only the guards.** The script proves each of the injector's 8 guards fails when neutered; nothing proves the script's own rows do. Also: the guards stage mutates tracked source in place, so a commit during a run is unsafe — one was observed @@ -1259,7 +1275,7 @@ were recorded nowhere — the same evaporation that #95 had to go back and fix. committed unexercised (the native mutex was held, and the `guards` stage mutates source a running build was compiling). **Resolved 2026-07-30**: both stages ran end-to-end in the run of record, stamped `20260730T215842Z` and made against `b980e1f` on a clean tree. All four figures come from - `bench-results/verify-20260730T215842Z/RESULTS.md`, read by label rather than by line number because + `bench-results/RUN-OF-RECORD/RESULTS.md`, read by label rather than by line number because that header gains lines: its title line carries the stamp, its `Commit:` line the SHA and `tree clean at run start`, its `Stages run:` line `unit jar guards jvm native`, and the line after that **27 passed, 0 failed, 0 skipped** — including the `jvm:build`, `jvm:banner`, `native:build` and @@ -1274,7 +1290,7 @@ were recorded nowhere — the same evaporation that #95 had to go back and fix. `## What a pass here does and does not establish` heading, which states what a pass does and does not establish. (Cited by heading with no line range at all: the range given here was off by one at both ends, and a limitations list that gains a bullet invalidates any range.) Do not re-run the - native stage on the strength of this entry; check `bench-results/verify-20260730T215842Z/` first. + native stage on the strength of this entry; check `bench-results/RUN-OF-RECORD/` first. (An earlier run, `verify-20260729T153141Z`, was **deleted** in `8cadf8a` — its B1 and B2 checks could not fail, so it certified nothing. Do not cite it; it is not in the tree.) - [ ] **A repo-wide line-citation audit (PR #103 round 7) found 135 wrong citations out of 547 diff --git a/bench-results/RUN-OF-RECORD b/bench-results/RUN-OF-RECORD new file mode 100644 index 0000000..b2e2855 --- /dev/null +++ b/bench-results/RUN-OF-RECORD @@ -0,0 +1,14 @@ +# bench-results/RUN-OF-RECORD — the certified run of record for DD-043 PR-3. +# +# scripts/check-citations.py resolves any cited path beginning +# `bench-results/RUN-OF-RECORD/` against the directory named on the single non-comment line +# below, so citations do not go stale every time evidence is regenerated (DD-045 item 2). +# Format: exactly one non-comment, non-blank line, naming a bench-results/ subdirectory by +# name only — no `bench-results/` prefix, no trailing slash. Zero or more than one such line +# is a malformed pointer and the checker fails loudly rather than guessing. +# +# Promoting a run to run-of-record is a DELIBERATE, MANUAL step: scripts/verify-dd043-pr3.sh +# never writes this file, so an ad hoc local run cannot silently become the cited evidence. +# Whoever certifies a new run edits the line below to name it, in the SAME COMMIT that adds +# the new bench-results/verify-/ directory — never as a follow-up commit. +verify-20260730T215842Z diff --git a/bench-results/dd043-pr3-restvillains-2026-07-26/README.md b/bench-results/dd043-pr3-restvillains-2026-07-26/README.md index 1219f95..6651484 100644 --- a/bench-results/dd043-pr3-restvillains-2026-07-26/README.md +++ b/bench-results/dd043-pr3-restvillains-2026-07-26/README.md @@ -14,7 +14,7 @@ is established separately, by `scripts/verify-dd043-pr3.sh`'s `jvm` stage — di the build (the preflight `git -C "$app" status --porcelain -- .`, whose non-zero `rc` `skip`s the whole stage as UNMEASURED) and `jvm:zero-edits` after it (`git status --porcelain=v2 --branch -- .` into `jvm-target-status-after.txt`), graded in -`bench-results/verify-20260730T215842Z/RESULTS.md`'s `jvm:zero-edits` row. All three are cited by +`bench-results/RUN-OF-RECORD/RESULTS.md`'s `jvm:zero-edits` row. All three are cited by command text and row key, not by line: the script's line numbers went stale twice while this very citation was being fixed, and any added guard row renumbers that table. The run *directory* is the part that still has to be re-checked by hand — the previous name here was superseded and deleted while this @@ -32,7 +32,7 @@ by the Quarkus bootstrap resolver on its own. **JVM mode only — the native cel | 2 | Startup banner lists `basquin` under `Installed features` | `app-startup.log:25`, extracted to `banner.txt` | | 3 | The boundary works, not just loads: driven request returns a cost line, not `miss` | `result-poll.txt`: `X-Basquin-Req: pr3-accept-1` → `/__basquin/result?id=pr3-accept-1` → `787,-684,9|0||` | | 4 | `basquin-quarkus-deployment` fetched from the injected repo | `http-access.log` (4 GETs for it, all `200`); `build.log:31-36` (`Downloaded from basquin-injected`) | -| 5 | App tree pristine, checked once, post-hoc | `pristine-proof.txt:6,11`: a single `git status --porcelain`, empty, taken after `clean package` and after the app container ran. The before-**and**-after property (not merely after) is established by the verify run, not this artifact — in `scripts/verify-dd043-pr3.sh`, the preflight `git -C "$app" status --porcelain -- .` (before; a non-zero `rc` `skip`s the stage as UNMEASURED) and `git status --porcelain=v2 --branch -- .` into `jvm-target-status-after.txt` (after). Each is that file's only occurrence, so it is cited by command text, not by a line number that edits keep invalidating. Graded `PASS` at `bench-results/verify-20260730T215842Z/RESULTS.md`'s `jvm:zero-edits` row (row key, not line — an added guard row renumbers the table), against the same clone commit `c9b46d74…` this directory used (that run's `jvm-target-status-after.txt:1`) | +| 5 | App tree pristine, checked once, post-hoc | `pristine-proof.txt:6,11`: a single `git status --porcelain`, empty, taken after `clean package` and after the app container ran. The before-**and**-after property (not merely after) is established by the verify run, not this artifact — in `scripts/verify-dd043-pr3.sh`, the preflight `git -C "$app" status --porcelain -- .` (before; a non-zero `rc` `skip`s the stage as UNMEASURED) and `git status --porcelain=v2 --branch -- .` into `jvm-target-status-after.txt` (after). Each is that file's only occurrence, so it is cited by command text, not by a line number that edits keep invalidating. Graded `PASS` at `bench-results/RUN-OF-RECORD/RESULTS.md`'s `jvm:zero-edits` row (row key, not line — an added guard row renumbers the table), against the same clone commit `c9b46d74…` this directory used (that run's `jvm-target-status-after.txt:1`) | Build wall time 01:03 min (`build.log`, `Total time`). On check 3's numbers: 787 ms elapsed is a first-hit (Hibernate/Agroal warmup) figure, the −684 KB heap delta is the reactive-path GC-in-window diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 87428bb..fa47395 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -45,7 +45,7 @@ work, not cleanup of this thread. | **DD-043** | Native + reactive targets — build-time instrumentation of a GraalVM-native Quarkus app | **Phase 0 done, gate PASSED** — **merged** as [#98](https://github.com/ianp94/basquin/pull/98) (2026-07-24). All four spikes resolved; S1 REFUTED as specified then CONFIRMED via S1b; 8 spec amendments forced, none voiding a section, plus a round-2 fix pass from the whole-branch review (spec ledger, "Round 2"). **PR-1 (#100), PR-2 (#102) merged; PR-3 open as [#103](https://github.com/ianp94/basquin/pull/103)** — build-time injection with zero edits to the target's tree, both halves of §5.2 passed (JVM on `rest-villains`, native on the fixture), 390 tests -(`bench-results/verify-20260730T215842Z/suite-counts.txt:1`). +(`bench-results/RUN-OF-RECORD/suite-counts.txt:1`). §8.1 **resolved**: Apicurio's server has no native build on the 3.x line, so row 5 needs a substitute — ranked Debezium Server (Quarkus 3.33.1.1) > Eclipse Hono HTTP adapter (3.27.4.1, reactive, heavier infra) > Apicurio 2.6.x, the last only behind a compatibility spike since `basquin-quarkus` is pinned to @@ -99,7 +99,7 @@ extraction; scope under "Open PRs" below). Four threads are ready to pick up, in Spec §5.2's two-artifact bar passed both halves — JVM on the real `rest-villains` app (`bench-results/dd043-pr3-restvillains-2026-07-26/`) and native on the Phase-0 fixture (`bench-results/dd043-pr3-native-2026-07-26/`). 390 tests, 0 failures — that count comes from the - run of record, not from either acceptance directory: `bench-results/verify-20260730T215842Z/` + run of record, not from either acceptance directory: `bench-results/RUN-OF-RECORD/` (`suite-counts.txt:1` reads `390 0`; `RESULTS.md:10`). **Both acceptances are single-module, and no multi-module Maven reactor was ever built end-to-end @@ -111,7 +111,7 @@ extraction; scope under "Open PRs" below). Four threads are ready to pick up, in targets are multi-module" (`docs/superpowers/specs/2026-07-24-native-reactive-targets-design.md`, the paragraph beginning "The injector must construct a fresh `Dependency` per `MavenProject`"). The run of record's own "What a pass here does and does not establish" section - (`bench-results/verify-20260730T215842Z/RESULTS.md`) omits this gap; that file is fixed evidence and + (`bench-results/RUN-OF-RECORD/RESULTS.md`) omits this gap; that file is fixed evidence and cannot be amended, so it is recorded here and in the spec instead. **What a fresh agent most needs to know about this branch.** Two mechanisms fail *silently* if @@ -166,7 +166,7 @@ extraction; scope under "Open PRs" below). Four threads are ready to pick up, in `declaration-usability`, `sibling-scope`, `sibling-version` — seven, matching the seven `throw new MavenExecutionException` sites in `BasquinInjector.java`), plus `skip` for the operator opt-out, each proven able to fail when its own branch is neutered. All eight PASS in - `bench-results/verify-20260730T215842Z/RESULTS.md` as one `guards: