Skip to content

feat: ship the typed solver with exact optimization and a shared-build test matrix - #3

Draft
Marcus-Rise wants to merge 7 commits into
mainfrom
feat/matrix-astar-benchmarks
Draft

Marcus-Rise wants to merge 7 commits into
mainfrom
feat/matrix-astar-benchmarks

Conversation

@Marcus-Rise

@Marcus-Rise Marcus-Rise commented Sep 7, 2026 •

Copy link
Copy Markdown
Owner

The restored library branch is ready for review against main. This PR makes the solver minimize grouped actions first, then unit shifts among equal-action solutions, and separates verification from release delivery.

  • Share one strict TypeScript core between src/index.ts and src/cli.ts. The public contract remains solveLock(state, links, config?) with a documented createSolverConfig(overrides?) factory.
  • Build four self-contained library/browser files plus one standalone Node CLI, with declarations and no runtime dependencies.
  • Keep source flat, tests and benchmarks under tests/, and maintained documentation under wiki/. Generated reports, snapshots, coverage, traces and builds are CI artifacts.
  • Remove .github/scripts and its wrapper-only tests. pnpm build invokes Vite and TypeScript directly; CI and publication commands stay in two flat YAML workflows.
  • CI builds and benchmarks once, then tests the same archive in six matrix rows: Node 22/24/26 and Chromium/Firefox/WebKit. The browser rows use Node 24 to drive tests. Release publishes a canary only after the entire main-push CI succeeds; stable publication remains a manual dispatch selecting a successful main CI run.
  • Keep build/release jobs short: use the runner's official GitHub CLI, native run/artifact queries and standard publication commands. Remove manual CLI installation, custom run traversal, duplicate runtime assets, repeated release-file validation, checksum assets and the CDN polling gate.
  • Canonical artifacts are named by SHA within their CI run. Native failed-job reruns reuse the successful build; full build reruns overwrite its artifacts through the official Action.
  • Compare benchmarks only with a saved report for the exact target SHA. The latest successful CI run for that SHA supplies the report. Missing or expired evidence is explicitly skipped; no target checkout, rebuild, registry or release fallback.
  • Repack only version metadata for release. Tested runtime bytes are preserved. Publication uses direct npm pack, npm publish and gh release create commands. Release notes include npm/CDN links and the benchmark report.

The A* queue and relaxation now compare both costs. The matrix certificate and dense/sparse BFS fallback honor the same ordering. An equal-action route with fewer shifts can improve the predecessor before the result is finalized. Domain validation, intermediate-position bounds and search budgets remain enforced. The proof, complexity and limits are documented in the algorithm Wiki.

The reported regression is fixed:

Lock Actions before / after Unit shifts before Unit shifts after
lock-011 9 / 9 41 37
lock-018 14 / 14 49 45
lock-019 14 / 14 43 41
All 45 483 / 483 1723 1713

These before/after values compare the saved pre-fix solver with the final built module. No lock increased its actions, shifts, distinct plates or switches. All 45 final (actions, shifts) pairs were also checked against an independently implemented exhaustive solver. Focused regression tests and an independent exhaustive oracle for small state spaces are maintained in the test suite. Minimum distinct-plate count is not an API guarantee.

CI passed on the exact head, c6662611494f2b2181329b16dc212f5e9b84be7f:

  • 237 Node tests in each of the Node 22/24/26 rows; 42 tests of the deleted infrastructure wrappers were removed. Source coverage is unchanged. The installed archive and CLI pass in every row.
  • 543 tests in real Chromium, Firefox and WebKit; 13 distribution tests; 24 static-browser/Worker consumers and 24 installed-package browser consumers.
  • Coverage: 96.20% statements, 92.38% branches, 100% functions, 96.01% lines; the minimum is 80% for each metric.
  • Lint, strict type checking, all five bundles and the 45-lock benchmark passed.
  • Canary and stable preparation were additionally exercised locally with npm 12.0.2; only version metadata changes, and packaged runtime bytes stay identical.

The current main SHA a87e739a22ccc4215d6d9b14fa06b0738171cb60 has no saved report matching the new artifact contract, so this CI run skipped historical comparison. That skip is not evidence of equivalence; the regression result above comes from the separate pre-fix and independent-oracle checks. Future runs compare with available exact-SHA reports. Historical timing/RSS ratios remain informational because machines and runtime conditions may differ.

The benchmark artifact contains the complete JSON report, commands, raw samples, environment and Markdown table. The build artifact contains the tested package (including all five runtime files) and the same JSON/Markdown evidence. Downloaded artifact digests, report source identity and packaged file hashes were verified. All six matrix rows verified the same npm archive SHA256: b1517f701ee7cdf221fe284014b1c9b501007721715e488a1795ab494788a8dd.

All 45 locks from the final CI report

Node 24.19.0, Linux x64, AMD EPYC 7763; two warmups and seven measured solves per lock. Timings cover the solver call only, excluding cloning and independent validation.

Lock Actions Distinct plates Unit shifts Switches Median ms p95 ms
lock-001 17 6 57 16 5.767 9.435
lock-002 9 5 31 8 0.129 0.214
lock-003 5 4 15 4 0.060 0.082
lock-004 14 5 60 13 0.383 0.395
lock-005 11 6 41 10 0.359 0.754
lock-006 9 5 30 8 0.140 0.153
lock-007 9 6 28 8 0.237 0.260
lock-008 5 4 16 4 0.033 0.035
lock-009 17 6 72 16 3.163 3.796
lock-010 7 5 25 6 31.396 41.904
lock-011 9 6 37 8 0.143 0.229
lock-012 23 5 68 22 2.195 2.436
lock-013 20 6 75 19 9.622 12.181
lock-014 9 7 38 8 0.118 0.145
lock-015 7 5 31 6 0.118 2.546
lock-016 11 5 44 10 0.523 0.781
lock-017 13 6 52 12 0.742 1.292
lock-018 14 6 45 13 9.271 13.218
lock-019 14 5 41 13 2.212 2.269
lock-020 12 6 56 11 0.056 0.092
lock-021 11 6 35 10 2.177 5.691
lock-022 8 6 23 7 0.123 0.165
lock-023 16 6 48 15 7.207 15.880
lock-024 8 5 29 7 0.320 0.365
lock-025 14 5 44 13 1.021 1.034
lock-026 9 5 37 8 0.082 0.122
lock-027 8 5 36 7 0.082 0.110
lock-028 11 6 43 10 0.726 0.751
lock-029 20 6 48 19 11.863 14.151
lock-030 10 6 41 9 0.186 0.211
lock-031 9 5 30 8 0.148 0.193
lock-032 9 6 31 8 0.102 0.151
lock-033 10 5 31 9 0.273 0.298
lock-034 8 6 33 7 0.087 0.099
lock-035 10 6 40 9 0.098 0.179
lock-036 8 5 27 7 0.075 0.106
lock-037 11 6 40 10 0.218 1.836
lock-038 8 6 21 7 0.306 0.338
lock-039 8 6 25 7 0.098 0.117
lock-040 13 5 46 12 1.093 1.190
lock-041 9 5 36 8 0.032 0.048
lock-042 4 3 20 3 0.014 0.044
lock-043 5 5 13 4 0.015 0.017
lock-044 11 6 41 10 0.309 0.336
lock-045 10 5 33 9 0.538 0.670

Totals: 483 actions, 1713 unit shifts, 438 switches, and 245 distinct plates summed per lock. Whole-catalog process peak RSS: median 120,549,376 bytes across three fresh processes. This includes Node, loading and validation; it is not solver-only allocation or browser memory.

Reproduce with Node 24.19.0:

npm install --global --ignore-scripts npm@12.0.2 pnpm@12.3.4
pnpm install --frozen-lockfile
pnpm exec playwright install --with-deps chromium firefox webkit
pnpm test
pnpm benchmark

To compare a downloaded report for a known exact target SHA:

pnpm benchmark --baseline-report /path/to/benchmark.json --baseline-sha <target-sha>

Release setup and the manual stable command are documented in the release Wiki. The PR remains a draft targeting main; no merge or npm publication has been performed.

…CLI (#2)

The minimum-action solver becomes a reusable TypeScript package with a
small public contract, shared library/CLI core and verified browser/Node
distribution.

This revision addresses readability across every source file and the
GitHub delivery tooling. Search orchestration, matrix row operations,
predecessor storage, input validation and publication steps now have
named responsibilities. Domain bounds, storage units and sentinels are
explicit; deeply nested operations are split into short functions
without changing search order or adding dependencies. Oxlint limits
nesting to three levels in `src/` and `.github/scripts/`.

- Keep ten flat `src/*.ts` files and two build entries: `index.ts` and
`cli.ts`.
- Export `solveLock(state, links, config?)` and
`createSolverConfig(overrides?)`; preserve readonly tuple typing,
immutable defaults and CLI `--config`.
- Build four self-contained browser/library files and one standalone CLI
with Vite; keep strict TypeScript 7 and the coverage gate.
- Keep tests under `tests/` and maintained documentation under `wiki/`.
Generate reports, snapshots, coverage and traces only as artifacts.
- Use one `release.yml` workflow with three jobs: readonly verification,
npm delivery and GitHub release. Main verification/build runs once. The
same tested archive passes between jobs; publication uses trusted main
tooling and separate permissions.
- Preserve actual PR-base / preceding-release comparisons, source and
file identity checks, explicit performance acceptance, canaries and
recovery from partial publication.

Local tests and the full benchmark completed before workflow YAML
changes. An independent reviewer examined all ten source files, all
seven delivery scripts and the workflow data flow; findings were
resolved without adding reviewer reports to the repository.

| Local verification | Result |
| --- | --- |
| Node source tests | 277 passed on Node 24 and Node 26 |
| Distribution / real-browser tests | 13 / 528 passed |
| Static / installed browser consumers | 24 / 24 passed |
| Same installed archive | Node 22.23.2, 24.19.0 and 26.8.1; CLI exits
0/1/2, exports and types |
| Coverage: statements / branches / functions / lines | 96.44% / 92.72%
/ 100% / 96.26% |
| All 45 exact command paths | Unchanged from the pre-refactor
implementation |
| 45-input quality vs PR target | 483 actions, 245 distinct-plate
totals, 1,723 unit shifts, 438 switches; unchanged |
| Local timing / memory | Inconclusive / inconclusive; raw calibration
and bounded repeats retained |

Reproduce from the repository root:

```sh
pnpm install --frozen-lockfile
pnpm exec playwright install --with-deps chromium firefox webkit
pnpm test
pnpm verify:package --node /path/to/node22 --node /path/to/node26
git worktree add --detach ../gothic-lock-solver-base 3cbbeed
pnpm benchmark --baseline-module ../gothic-lock-solver-base/src/index.mjs --baseline-format legacy --output-dir artifacts/benchmark
```

The benchmark compares the separately checked-out target source, not a
candidate-owned expected snapshot. Inconclusive performance does not
certify the absence of a regression and is not silently accepted for
publication.

[Hosted CI on
b66d3d8](https://github.com/Marcus-Rise/gothic-lock-solver/actions/runs/34130127903)
passed on its first attempt. Verification completed; the npm/GitHub
publication jobs were skipped for this PR.

[Verification
artifacts](https://github.com/Marcus-Rise/gothic-lock-solver/actions/runs/34130127903/artifacts/10021794594)
contain the five builds, one archive tested in Node 22/24/26, coverage,
real-browser reports, the baseline snapshot and the complete 45-input
benchmark with calibration and bounded repeats. The downloaded artifact,
report hashes, module hashes, source SHA and archive SHA were checked.

Hosted quality remains A/U/C/switches = **483/245/1723/438**. Timing and
memory both remain **inconclusive**. Sums of per-lock medians were
**60.685 ms** for the candidate and **55.259 ms** for the target; these
descriptive sums are not whole-workload latency or proof of a speedup.
The report identifies candidate
`b66d3d8d371b2d7f17d85bf6bed9186006eab87c` and separately checked-out
target `3cbbeedbb409a2d8ffa5b00c778cfcb0b07c0ec6`.

This PR remains a draft. The reference branch and history are preserved.
No package publication, GitHub release or merge is part of this
revision.
@Marcus-Rise Marcus-Rise changed the title feat: integrate exact TypeScript solver and verified distribution into main feat: ship the typed solver with exact action/shift optimization and simple CI Sep 7, 2026
@Marcus-Rise Marcus-Rise changed the title feat: ship the typed solver with exact action/shift optimization and simple CI feat: ship the typed solver with exact optimization and a shared-build test matrix Sep 8, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant