130 lines
6.6 KiB
Markdown
130 lines
6.6 KiB
Markdown
# ADR 0002: Prove reuse of Rayforge and BalorMK before building an app
|
|
|
|
- Status: Proposed
|
|
- Date: 2026-10-17
|
|
|
|
## Context
|
|
|
|
The initial roadmap assumed that The Pirate Ray would define its own offline
|
|
application core and would later research the JCZ protocol. Ecosystem research
|
|
found two MIT-licensed projects that substantially change that assumption:
|
|
|
|
- Rayforge already implements most of the desired cross-platform desktop
|
|
product and has an addon/driver architecture, LightBurn import, simulation,
|
|
material recipes, pre-flight validation, and MOPA-relevant operation fields.
|
|
- MeerK40t's BalorMK already implements the EZCAD2-compatible JCZ controller
|
|
protocol, MOPA pulse width, a mock connection, and the exact USB VID/PID
|
|
independently observed in our installer evidence.
|
|
|
|
Creating another editor, geometry stack and controller implementation would
|
|
duplicate large, safety-relevant bodies of work and permanently increase the
|
|
maintenance burden.
|
|
|
|
## Proposed decision
|
|
|
|
Do not begin independent desktop product implementation. First run three
|
|
offline, version-pinned proofs:
|
|
|
|
1. evaluate stock MeerK40t with BalorMK's mock controller as the shortest
|
|
route to a usable product;
|
|
2. prove that an external Rayforge addon can register a binary no-device
|
|
driver and survive packaging on Windows;
|
|
3. translate one synthetic Rayforge operation stream to JCZ/Balor commands and
|
|
compare it with a BalorMK mock trace.
|
|
|
|
If the proofs pass, prefer one of these outcomes in order:
|
|
|
|
1. use and contribute to MeerK40t if its full application is adequate;
|
|
2. implement and upstream a Rayforge JCZ/Balor addon, adapting the narrowest
|
|
practical layer from BalorMK;
|
|
3. extract a small maintained controller library shared by either application.
|
|
|
|
An independent desktop application requires a later ADR showing concrete,
|
|
tested gaps in both existing applications.
|
|
|
|
No copied upstream source enters this repository until the project license is
|
|
chosen and exact commit-level copyright/license attribution is recorded.
|
|
|
|
## Proof obligations
|
|
|
|
- All experiments are mock/no-I/O and cannot enumerate or open USB devices.
|
|
- Frequency and pulse-width units and defaults survive end-to-end.
|
|
- Galvo coordinates, correction, timing, list buffering, framing, cancel and
|
|
status semantics fit the host abstraction or their required extensions are
|
|
explicit.
|
|
- The adapter emits deterministic traces suitable for golden tests.
|
|
- Hardware transport is optional, disabled by default, and separated from
|
|
encoding.
|
|
- Machine/source/lens/profile mismatch fails closed.
|
|
- Windows driver switching is excluded from automatic setup.
|
|
- Upstream contribution feasibility and API stability are assessed before a
|
|
permanent fork is accepted.
|
|
|
|
## Consequences if accepted
|
|
|
|
- The project becomes an integration, validation and safety effort rather
|
|
than a general CAD application effort.
|
|
- M1 is shortened to ecosystem validation and a JCZ vertical slice.
|
|
- Protocol capture is a fallback used only for unresolved behavior, not the
|
|
first discovery method.
|
|
- The eventual public repository may primarily contain an addon, machine
|
|
profiles, tests, fixtures and documentation.
|
|
- Project license selection becomes a prerequisite for adapted code. MIT is
|
|
the simplest compatibility candidate, but this ADR does not select it.
|
|
|
|
## Rejection criteria
|
|
|
|
Reject the proposed Rayforge route if the addon seam cannot support a binary
|
|
galvo driver without maintaining invasive core changes, or if the operation
|
|
model loses required galvo/MOPA semantics. Reject the stock MeerK40t route if
|
|
the tested application cannot provide a safe and maintainable workshop
|
|
workflow. Record evidence before choosing a standalone app.
|
|
|
|
## Research basis
|
|
|
|
See [Open-source landscape](../research/open-source-landscape.md) for the
|
|
candidate matrix, inspected commits, risks and detailed spike plan.
|
|
|
|
Subsequent offline evidence:
|
|
|
|
- [MeerK40t mock MOPA spike](../research/meerk40t-mock-mopa-spike.md):
|
|
deterministic controller-level frequency, pulse-width and square encoding;
|
|
- [MeerK40t hatch cut-plan and mock-spooler spike](../research/meerk40t-hatch-cutplan-spike.md):
|
|
stock planning and spooling preserve a synthetic hatch and MOPA settings on
|
|
forced mock transport;
|
|
- [Rayforge addon spike](../research/rayforge-addon-spike.md): external binary
|
|
driver load and lifecycle are viable, with a documented registry API gap.
|
|
- [Rayforge-to-JCZ equivalence spike](../research/rayforge-jcz-equivalence-spike.md):
|
|
the required MOPA and geometry semantics survive a real Rayforge `Ops`
|
|
stream and match the pinned BalorMK mock trace.
|
|
- [JCZ negative cases](../research/rayforge-jcz-negative-cases.md): the encoder
|
|
boundary rejects profile mismatch, invalid values, out-of-field geometry and
|
|
unsupported commands without a transport.
|
|
- [JCZ 12-byte record spike](../research/rayforge-jcz-packet-spike.md): the
|
|
external encoder deterministically packs controller-shaped command records
|
|
matching the pinned BalorMK mock values, while retaining no transport.
|
|
- [Synthetic LightBurn MOPA import spike](../research/rayforge-lightburn-mopa-import-spike.md):
|
|
geometry and common settings survive, but frequency is not mapped to the
|
|
workflow and pulse-width representation still lacks fixture evidence.
|
|
- [Graphical workflow model spike](../research/rayforge-graphical-workflow-spike.md):
|
|
Rayforge's generated settings contract exposes frequency and pulse width,
|
|
preserves them through step serialization and supplies preview Ops without
|
|
transport; packaged GTK interaction remains untested.
|
|
- [LightBurn-to-Rayforge UX capability map](../research/lightburn-rayforge-ux-capability-map.md):
|
|
the casual-maker workflow maps mostly to existing Rayforge product seams;
|
|
the remaining UX gaps are narrow, testable extensions rather than evidence
|
|
for a separate desktop application.
|
|
- [Rayforge layer visibility and output spike](../research/rayforge-layer-model-spike.md):
|
|
canvas visibility and job participation are already independent serialized
|
|
states; LightBurn-style layer Output is a narrow aggregate UI concern, not a
|
|
new pipeline or document-model requirement.
|
|
- [M1 no-device acceptance checkpoint](../research/m1-no-device-acceptance.md):
|
|
the public regression suite and leak guard now form one transport-free gate
|
|
over addon lifecycle, workflow, layers, recipes, encoding, negative cases,
|
|
cancellation/recovery and synthetic imports. The packaged Windows GUI and a
|
|
known-working private project remain external gates.
|
|
|
|
These results satisfy the current model, buffering and no-device integration
|
|
proofs. They do not yet satisfy the packaged human-interaction or real-project
|
|
import obligations, so this ADR remains proposed.
|
|
|