From ffbff9805c6422f09449cb70f9dbfa24f10a9960 Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 21 Oct 2026 09:57:05 +0200 Subject: [PATCH] docs: keep project status and links current --- README.md | 3 +- docs/CODEX_HANDOFF.md | 4 +-- .../rayforge-jcz-equivalence-spike.md | 8 +++-- docs/research/rayforge-jcz-packet-spike.md | 8 +++-- docs/roadmap.md | 9 ++--- docs/status/phase-0.md | 6 ++-- tests/test_document_links.py | 33 +++++++++++++++++++ 7 files changed, 55 insertions(+), 16 deletions(-) create mode 100644 tests/test_document_links.py diff --git a/README.md b/README.md index 4230353..4486a8f 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,8 @@ We do not need to begin with a blank-sheet LightBurn clone: The leading route is therefore either to use and improve MeerK40t directly or to build a Rayforge JCZ/Balor addon using the narrowest practical layer from -BalorMK. This remains a proposed decision until the offline proofs in +BalorMK. This remains a proposed decision until the packaged interaction and +real-project gates in [ADR 0002](docs/adr/0002-reuse-rayforge-and-balormk.md) have passed. ## Next steps diff --git a/docs/CODEX_HANDOFF.md b/docs/CODEX_HANDOFF.md index e857947..729c04e 100644 --- a/docs/CODEX_HANDOFF.md +++ b/docs/CODEX_HANDOFF.md @@ -7,8 +7,8 @@ ## Verified checkpoint -The public repository currently passes 83 unit tests and the public-repository -guard. The offline Rayforge/MeerK40t evidence covers addon lifecycle, MOPA +The complete public unit-test suite and public-repository guard pass at this +checkpoint. The offline Rayforge/MeerK40t evidence covers addon lifecycle, MOPA settings and units, layer and recipe semantics, JCZ record/list encoding, negative cases, cancellation/recovery and synthetic LightBurn imports. diff --git a/docs/research/rayforge-jcz-equivalence-spike.md b/docs/research/rayforge-jcz-equivalence-spike.md index b404563..f60efc1 100644 --- a/docs/research/rayforge-jcz-equivalence-spike.md +++ b/docs/research/rayforge-jcz-equivalence-spike.md @@ -59,6 +59,8 @@ production adapter must not infer the unit from a driver-specific comment. Spike C passes at the semantic boundary. The result supports a Rayforge JCZ addon architecture. A follow-up spike now covers transport-free 12-byte -command records, but ADR 0002 remains proposed until complete list behavior, -addon packaging in a complete Windows build, and the remaining stock -MeerK40t workflow assessment are addressed. +command records. At this checkpoint, list behavior, full Windows packaging and +the remaining stock MeerK40t workflow assessment were still open. Later +offline progress is summarized by the +[M1 no-device acceptance checkpoint](m1-no-device-acceptance.md); ADR 0002 +remains proposed because its external gates are still open. diff --git a/docs/research/rayforge-jcz-packet-spike.md b/docs/research/rayforge-jcz-packet-spike.md index 98acfda..ec6ba80 100644 --- a/docs/research/rayforge-jcz-packet-spike.md +++ b/docs/research/rayforge-jcz-packet-spike.md @@ -49,6 +49,8 @@ operations continue to fail closed. The result advances the Rayforge addon route beyond semantic JSON traces: the same operation model can produce deterministic controller-shaped records at a -narrow encoder boundary. ADR 0002 remains proposed because stock application -workflow coverage, complete packet/list behavior, packaging in a full Windows -build and the remaining safety proof obligations are still open. +narrow encoder boundary. At this checkpoint, stock application workflow +coverage, complete list behavior and full Windows packaging were still open. +Later offline progress is summarized by the +[M1 no-device acceptance checkpoint](m1-no-device-acceptance.md); ADR 0002 +remains proposed because its external gates are still open. diff --git a/docs/roadmap.md b/docs/roadmap.md index 466860e..269198e 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1,6 +1,6 @@ # Product and research roadmap -Last updated: 2026-10-19 +Last updated: 2026-10-21 ## Destination @@ -164,9 +164,10 @@ unknown, so the job still deliberately fails the JCZ encoding gate. A private known-working `.lbrn2` fixture is required before implementing the missing MOPA mapping. -The architecture decision remains proposed until these spikes produce -evidence. An independent app requires a documented gap analysis showing why -neither existing platform can be extended responsibly. +The architecture decision remains proposed until the packaged Windows +interaction and known-working private-project gates produce evidence. An +independent app requires a documented gap analysis showing why neither +existing platform can be extended responsibly. Exit criteria: a representative JPT job survives import/planning, MOPA parameters and units, validation and deterministic mock encoding; the chosen diff --git a/docs/status/phase-0.md b/docs/status/phase-0.md index 577d2ca..45b41de 100644 --- a/docs/status/phase-0.md +++ b/docs/status/phase-0.md @@ -1,6 +1,6 @@ # Phase 0 status -Last updated: 2026-10-20 +Last updated: 2026-10-21 ## Completed @@ -75,8 +75,8 @@ evidence for: - independent layer visibility/output state and ordered serialization; - material-recipe matching plus a fail-closed PirateRay provenance and exact machine/source/lens/correction compatibility gate; -- one consolidated no-device acceptance report that reruns all 83 public - tests and the leak guard, then hashes the regression evidence; +- one consolidated no-device acceptance report that reruns the complete + public test suite and leak guard, then hashes the regression evidence; - a non-executing Windows artifact verifier that checks portable paths, archive safety, sizes, hashes, the pinned Rayforge revision and every packaged addon source while retaining the manual GUI gate; diff --git a/tests/test_document_links.py b/tests/test_document_links.py new file mode 100644 index 0000000..c102949 --- /dev/null +++ b/tests/test_document_links.py @@ -0,0 +1,33 @@ +import re +import unittest +from pathlib import Path +from urllib.parse import unquote + + +ROOT = Path(__file__).resolve().parents[1] +MARKDOWN_LINK = re.compile(r"!?\[[^\]]*\]\(([^)]+)\)") + + +class DocumentLinkTests(unittest.TestCase): + def test_relative_markdown_links_resolve_inside_repository(self): + documents = [ROOT / "README.md", *sorted((ROOT / "docs").rglob("*.md"))] + failures = [] + for document in documents: + text = document.read_text(encoding="utf-8") + for match in MARKDOWN_LINK.finditer(text): + target = match.group(1).strip().strip("<>").split("#", 1)[0] + if not target or "://" in target or target.startswith(("mailto:", "#")): + continue + path = (document.parent / unquote(target)).resolve() + try: + path.relative_to(ROOT) + except ValueError: + failures.append(f"{document.relative_to(ROOT)} -> outside repository: {target}") + continue + if not path.exists(): + failures.append(f"{document.relative_to(ROOT)} -> missing: {target}") + self.assertEqual(failures, [], "\n".join(failures)) + + +if __name__ == "__main__": + unittest.main()