Skip to content

release: 0.2.0 — mdBook contract parity for the build path - #28

Merged
AlexMikhalev merged 3 commits into
mainfrom
release/0.2.0
Aug 12, 2026
Merged

release: 0.2.0 — mdBook contract parity for the build path#28
AlexMikhalev merged 3 commits into
mainfrom
release/0.2.0

Conversation

@AlexMikhalev

Copy link
Copy Markdown
Contributor

Version bump, changelog, README scope note, and the Phase 4/5 reports.

Why 0.2.0 and not 1.0.0

Validation was conditional. Five of six Phase 1 success criteria are met and evidenced against terraphim-ai's real 129-file book; the sixth ({{#include}}) is deliberately unmet, closed on evidence that no book md-book builds uses it. md-book serve has 0% test coverage. "Major" would claim a completeness that is not there.

Evidence

CI 19/19 green — Linux, macOS, Windows × stable/beta/nightly, six feature combinations, security audit
Tests 168 (90 unit, 46 integration, 12 e2e, 4 structure, 16 conformance)
Coverage 86.0% lines, 84.7% regions
Accessibility 0 axe violations on chapter, index and 404 pages
Real corpus 129-file book builds to 59 pages in SUMMARY order

What validation caught that verification could not

Three of four validation defects trace to design omissions, not implementation:

  • The landing page had no navigation at all — one link, the logo. A README-backed index skips the card grid and the template never included the sidebar. Every test passed throughout, because the design never said the index needs navigation.
  • The logo link had no accessible name (serious, WCAG 2.4.4/4.1.2).
  • The TOC component left content outside any landmark.

Known limitations, stated in the README

{{#include}}, {{#playground}}, {{#rustdoc_include}}, {{#title}} unimplemented; mathjax-support parses but does nothing; serve untested.

Reports

  • docs/plans/mdbook-parity-verification-report.md — traceability, coverage, defect register (15 defects with origin phases)
  • docs/plans/mdbook-parity-validation-report.md — success criteria, NFRs, E2E scenarios, conditions

Minor, not major, per the Phase 5 validation decision: the build path is
correct, tested and validated against a real 129-file book, but
{{#include}} is deliberately absent and `serve` has no test coverage, so
"major" would claim a completeness that is not there.

Adds the verification and validation reports, and states the {{#include}}
limitation in the README rather than leaving migrating users to discover it.
@github-actions

Copy link
Copy Markdown

📊 Performance Benchmark Results

Benchmark Time
pagefind_init/pages/100 1.928 ms
pagefind_init/pages/500 10.438 ms
Raw Results
{
  "timestamp": "2026-08-11T18:35:06+00:00",
  "benchmarks": [
    {
      "benchmark_name": "pagefind_init/pages/100",
      "mean": {
        "estimate": 1927600
      },
      "unit": "ns"
    },
    {
      "benchmark_name": "pagefind_init/pages/500",
      "mean": {
        "estimate": 10438000
      },
      "unit": "ns"
    }
  ]
}

@github-actions

Copy link
Copy Markdown

🚀 Deployment Preview

Your changes have been deployed to Cloudflare Pages!

🔗 Preview URL: https://preview-28.md-book.pages.dev

The deployment will be updated automatically when you push new changes to this PR.

Clears the first validation condition: server.rs goes from 0% to 86.7%
coverage. `book_routes` and `resolve_bind_addr` are extracted so behaviour
can be exercised with warp::test rather than by binding ports.

Writing those tests immediately found why the condition mattered: the
catch-all `fs::file` fallback matched *every* path, including
/live-reload, so the websocket upgrade was never reached. Live reload has
silently never worked — the browser asked for a socket and got index.html.
The reload route now precedes the file fallback, and a test performs the
handshake and asserts a rebuild pushes "reload".

Using the tool found a second gap: `serve -p 8080` was rejected because
only `--port` existed. mdBook documents `-p`, so the short flag is added.

On the second condition: UBS still cannot scan Rust. `ubs doctor` verifies
js, python, cpp and golang and fails only on rust, with a stable hash
across independent fetches — three distinct digests between the installer's
pin, what upstream serves now, and the July cache. It fetches modules from
an unpinned `master` while pinning digests in a released installer, so any
upstream edit breaks verification by construction. Upstream's problem; the
integrity check was not disabled. Substitute analysis with ast-grep and
clippy is recorded in the validation report: zero unsafe blocks, zero
panic!/todo!/unimplemented!, and seven unwrap/expect in production code,
each verified guarded.
server.rs coverage 0% -> 86.7% closes the last open module boundary, taking
totals to 87.1% lines and 174 tests. The UBS section now records the
diagnosis (unpinned upstream branch vs pinned installer digest) and the
substitute ast-grep/clippy analysis rather than just noting the tool failed.
@AlexMikhalev

Copy link
Copy Markdown
Contributor Author

Both validation conditions are now cleared, pushed to this branch.

serve coverage: 0% → 86.7%. book_routes and resolve_bind_addr are extracted so behaviour can be exercised with warp::test instead of by binding ports.

Writing those tests immediately found why the condition mattered: the catch-all fs::file fallback matched every path, including /live-reload, so the websocket upgrade was never reached — live reload has silently never worked, the browser asking for a socket and receiving index.html. Route order corrected; a test now performs the handshake and asserts a rebuild pushes reload. Using the tool also showed serve -p 8080 was rejected because only --port existed, unlike mdBook; short flag added.

UBS diagnosed, not bypassed. ubs doctor verifies js, python, cpp and golang, failing only on rust. Three distinct digests: installer pin 5c0df5f4…, upstream now 08e99d1e…, July cache 26249823…, with the served hash stable across fetches — so not corruption in transit. ubs fetches modules from an unpinned master while pinning digests in a released installer, so any upstream edit breaks verification by construction. Upstream's problem; the integrity check was not disabled.

Substitute analysis run directly with ast-grep and clippy: 0 unsafe blocks, 0 panic!/todo!/unimplemented!, 7 unwrap()/expect() in production code — each verified guarded by a surrounding invariant.

Totals now: 174 tests, 87.1% line coverage, 9/9 module boundaries.

@github-actions

Copy link
Copy Markdown

📊 Performance Benchmark Results

Benchmark Time
pagefind_init/pages/50 2.293 ms
pagefind_init/pages/100 4.453 ms
pagefind_init/pages/500 24.821 ms
Raw Results
{
  "timestamp": "2026-08-12T09:57:46+00:00",
  "benchmarks": [
    {
      "benchmark_name": "pagefind_init/pages/50",
      "mean": {
        "estimate": 2292700
      },
      "unit": "ns"
    },
    {
      "benchmark_name": "pagefind_init/pages/100",
      "mean": {
        "estimate": 4453400
      },
      "unit": "ns"
    },
    {
      "benchmark_name": "pagefind_init/pages/500",
      "mean": {
        "estimate": 24821000
      },
      "unit": "ns"
    }
  ]
}

@github-actions

Copy link
Copy Markdown

🚀 Deployment Preview

Your changes have been deployed to Cloudflare Pages!

🔗 Preview URL: https://preview-28.md-book.pages.dev

The deployment will be updated automatically when you push new changes to this PR.

@AlexMikhalev
AlexMikhalev merged commit 643439e into main Aug 12, 2026
23 checks passed
@AlexMikhalev
AlexMikhalev deleted the release/0.2.0 branch August 12, 2026 10:05
AlexMikhalev added a commit to terraphim/terraphim-ai that referenced this pull request Aug 12, 2026
Requires md-book 0.2.0, merged as terraphim/md-book#28. The workflow clones md-book from main, so it picks this up on the next docs build: 574 pages in path order becomes 59 in SUMMARY order.
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