Restore the docs signpost and fix the bench lockfile - #116
Merged
Conversation
The blueprint lists docs/README.md as a file both repositories carry, and describes exactly what it prevents: someone starting a second documentation tree in the main repository. That is what happened here. docs/ holds three real documents and nothing that says where the rest lives, so a reader who opens the directory has no reason to think there is a site at all. The file names both directions. The per-language API reference is on backtest.wickra.org, one page per language surface, and the Rust API is on docs.rs. What stays here is what a release can change and what the repository owns: the spec reference beside its JSON schema, the cookbook beside the strategies it explains, the microstructure guide beside the engine that implements it. It also states the rule that keeps it a signpost. A page about calling the library from a language belongs on the site; a page about what the engine accepts belongs beside the code. A second tree drifts from the first, and nobody notices, because both look maintained.
bench.yml has failed for at least three consecutive nights -- 2026-08-28, -29 and -30 -- and nobody saw it, because it only runs on a schedule and nothing watches a scheduled workflow. The error was the same each time: ERROR: In --require-hashes mode, all requirements must have their versions pinned with ==. These do not: pexpect>4.6 (from ipython==9.16.1) The lock was compiled on Windows. ipython requires pexpect only where sys_platform != "win32", so that branch was never taken and pexpect never entered the file. On the ubuntu runner pip needs it, finds it unpinned, and --require-hashes refuses the whole install -- so not one benchmark ran. --python-platform linux fixes it at the source, and update-lockfiles.sh now says why, because the next person to regenerate this on a laptop would otherwise undo it. bench.yml runs on ubuntu and nothing else, so the lock is built for ubuntu and nothing else. The diff is the whole story: +pexpect, +ptyprocess, and the Windows-only colorama and tzdata drop out of a file that only ever installs on Linux. No other version moved -- uv keeps the existing pins as preferences. The two ci-dev locks are deliberately left alone. They install on all three runner operating systems, so resolving them for one would be the same mistake in reverse; measured rather than assumed -- they carry no platform-conditional requirement, which is why they have been green on all three all along. Verified: the dependency closure is complete (21 via-sources, all pinned) and all 61 packages carry hashes.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
kingchenc
added a commit
that referenced
this pull request
Aug 30, 2026
Version-strings only, which is the point: a bump that carries nothing else has a CI run that is unambiguous, and a failure in it can only come from the bump. **Do not merge this yet** — merging it is the last reversible step. The tag that follows publishes to six registries and cannot be taken back. ## What moved Produced by `bump_version.py`, not by hand — 20 touchpoints across eight languages, each with an expected hit count, so a manifest that quietly stops matching is a failure rather than a silent skip: | | | |---|---| | `Cargo.toml` | 3 | | `bindings/node/package.json` | 7 (version + six `optionalDependencies`) | | `bindings/node/npm/<rid>/package.json` | 6 × 1 | | `bindings/node/index.js` | 52 (the napi loader's version literal) | | `bindings/node/package-lock.json` | 19, one third-party entry left alone | | `bindings/python/pyproject.toml`, `bindings/java/pom.xml`, `Wickra.Backtest.csproj`, `bindings/r/DESCRIPTION` | 1 each | | `examples/java/pom.xml` | 2 (its own version and the dependency) | | `SECURITY.md` | 3 | | `CITATION.cff` | version **and** `date-released` | | `Cargo.lock` | refreshed by `cargo build`, never edited | `CITATION.cff` is new to that list. It became a version touchpoint in #115 when it grew `version:` and `date-released:`, and the bump tool had not followed — so this bump would have left the citation naming 0.1.0 while every manifest said 0.1.1, with nothing downstream to catch it, since GitHub's citation box and Zenodo read that file and no build does. Fixed in the tooling repo, along with `date-released`, which no replacement finds because it is not a version: left alone it names the day of the previous release beside the new version, and a reader cannot tell which of the two is stale. ## Changelog `[0.1.1]` collects what #115 landed — the publish gate, the ref guard, the split `wasm-build`, CodeQL over the four compiled bindings, actionlint, CodSpeed, semver, the container smoke job, the C golden test, the schema check — and two entries that #116 should have written and did not: - the `docs/` signpost under **Added** - the cross-library benchmark under a new **Fixed** section, which had been red for three consecutive nights without anyone noticing ## Verification `cargo fmt`, `cargo test --workspace --all-features` (21 suites), `cargo clippy -D warnings`, `cargo deny`, `actionlint` with shellcheck, and all six check scripts: green. `check_version_sync.py` agrees across 18 declarations at 0.1.1. The diff outside `CHANGELOG.md` and the two lockfiles contains no line that is not a version string — checked, not assumed. Line endings are unchanged: `git ls-files --eol` reports 285 index entries as `i/lf` and none as CRLF. ## What is still unproven, and will be until the tag `release.yml` runs on `push: tags: ["v*"]` and nothing else, so five things land in it for the first time on this release: the `gate` job, its ref guard, the split `wasm-build`, the `go build`/`go test` inside `go-mirror`, and provenance extended to the nupkg, the jar and the C ABI archives. Each is built so that failing **blocks** rather than half-publishes — the gate sits before the first irreversible step rather than after it, and refuses to open unless this exact commit has a green `ci.yml` and nothing red. That is the argument for merging it, not against; but it is worth naming before the tag rather than after. ## After merge Note the merge SHA. The tag is set on that SHA explicitly — `git tag -s v0.1.1 <merge-sha>` — because `git tag` without a ref captures the local `HEAD`, which is not necessarily the merge commit. **Only after explicit go-ahead.**
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.
Two gaps that came out of holding the tree against the blueprint path by path
rather than against the checker, which could see neither of them.
The signpost in
docs/Section 01 lists
docs/README.mdas a file both repositories carry, and sayswhat it prevents: someone starting a second documentation tree in the main
repository. That is what happened here.
docs/holds three real documents andnothing that says where the rest lives, so a reader who opens the directory has
no reason to think a site exists at all.
The blueprint even anticipated it — the row reads "In
wickra-backtestliegendaneben drei echte Dokumente" — and
check_blueprint.pystill reported the rootinventory complete, because
docs/README.mdwas missing from itsROOTlist.Fixed on the tooling side too, so the next repo cannot hide the same gap.
The new file names both directions. The per-language API reference is on
backtest.wickra.org, one page per language surface; the Rust API is on docs.rs.
What stays here is what a release can change and what this repository owns: the
spec reference beside its JSON schema, the cookbook beside the strategies it
explains, the microstructure guide beside the engine implementing it. It closes
with the rule that keeps it a signpost — a page about calling the library from a
language belongs on the site, a page about what the engine accepts belongs
beside the code.
Site URLs verified against the site's own
.vitepress/config.ts(cleanUrls: true, links of the form/api/rust) rather than guessed.bench.ymlhas been red for three nights2026-08-28, -29 and -30, all with the same error, and nobody saw it because the
workflow only runs on a schedule and nothing watches a scheduled workflow:
The lock was compiled on Windows.
ipythonrequirespexpectonly wheresys_platform != "win32", so that branch was never taken andpexpectneverentered the file. On the ubuntu runner pip needs it, finds it unpinned, and
--require-hashesrefuses the entire install — so not one benchmark ran on anyof those nights.
--python-platform linuxfixes it at the source, andupdate-lockfiles.shnowcarries the reason, because the next person regenerating this on a laptop would
otherwise undo it silently.
bench.ymlruns on ubuntu and nothing else, so thelock is built for ubuntu and nothing else.
The diff is the whole story:
+pexpect,+ptyprocess, and the Windows-onlycoloramaandtzdatadrop out of a file that only ever installs on Linux. Noother version moved — uv keeps existing pins as preferences.
The two
ci-devlocks are deliberately untouched. They install on all threerunner operating systems, so resolving them for one would be the same mistake in
reverse. Measured rather than assumed: neither carries a platform-conditional
requirement, which is why both have been green on all three all along.
Verification
viasources, every onepinned — and all 61 packages carry hashes.
actionlint(with shellcheck),check_readme_links,check_version_sync,check_example_specs,check_license_copies: green.against
wickrastays at 88/88 with every conditional check still firingthere, so nothing was weakened to reach it.
Not attempted, and named rather than left implied: the R vignette,
r/data,data-raw, the nodeharness.js/dts-header.d.tspolish,gen_golden_test.pyand the extra example scenarios. All are marked wickra-only in the blueprint,
and §08 says the matrix is filled as needed rather than in full. Writing them
here would be inventing product content, not closing a gap.