Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
9afbdcd
docs(research): RR-004 — non-extrusion toolpath coverage (CNC/laser/p…
sobechestnut-dev Jul 29, 2026
b401308
docs(design): DD-012 — non-extrusion toolpath & modal tool-state [Acc…
sobechestnut-dev Jul 29, 2026
1029580
feat: non-extrusion Cut classification + tool-state modal (DD-012 pha…
sobechestnut-dev Jul 29, 2026
8fec7c3
feat: opt-in modal tool-power channel — ModalChannel mechanism (DD-01…
sobechestnut-dev Jul 29, 2026
11f317d
feat: modal motion continuation — bare coord lines repeat last G0-G3 …
sobechestnut-dev Jul 29, 2026
b2053be
feat: canned drilling cycle expansion — G81/G82/G83 (DD-012 phase 2, …
sobechestnut-dev Jul 29, 2026
13fd5c6
feat: non-extrusion dialect families + validation tiers (DD-012 phase…
sobechestnut-dev Jul 29, 2026
5f59b77
feat: non-extrusion color modes — power + cut-vs-rapid (DD-012 phase …
sobechestnut-dev Jul 29, 2026
7d6c1d7
docs: non-extrusion (CNC/laser) compatibility matrix + support tiers …
sobechestnut-dev Jul 29, 2026
b84bea9
feat: lexer handles multi-command lines, N line numbers, bare S/F (#1…
sobechestnut-dev Jul 29, 2026
b010c6a
feat(demo): STL export of the rendered toolpath (closes #152) (#257)
sobechestnut-dev Jul 29, 2026
3f06e5b
feat: evidence-based non-extrusion detection — recognize header-less …
sobechestnut-dev Jul 30, 2026
969c194
docs: checkpoint status — #188 closed, #189 phases 1–5 + real-file wo…
sobechestnut-dev Jul 30, 2026
879b60a
fix: G0 rapids classify as Travel, not Cut (#189) (#260)
sobechestnut-dev Jul 30, 2026
c7b8b7f
docs: cite CNC/laser spec authorities in RR-004 + DD-012 (#189) (#261)
sobechestnut-dev Jul 30, 2026
3e244ae
feat(dialects): promote grbl-laser to validated on hardware evidence …
sobechestnut-dev Jul 30, 2026
88873bd
docs(dd): DD-017 RS274NGC parametric programs — Proposed (#189 phase …
sobechestnut-dev Jul 31, 2026
4f48b0f
release: version packages (lockstep) (#249)
github-actions[bot] Jul 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,13 @@ over one shared, framework-neutral engine.
plates, WebGL context-loss recovery.
- **A low-resource Canvas 2D renderer** — an optional `renderer: '2d'` layer view for constrained
environments, with adjacent "ghost" layers and its own progress mapping (no WebGL required).
- **Rich toolpath coloring** — by feature type, move speed, object, or per-layer height, plus
toggleable wipe/seam moves; time-based scrub with a print-time estimate; and a source-line ↔
segment debugger mapping.
- **Rich toolpath coloring** — by feature type, move speed, object, per-layer height, or (for
non-extrusion) tool power and cut-vs-rapid, plus toggleable wipe/seam moves; time-based scrub with a
print-time estimate; and a source-line ↔ segment debugger mapping.
- **Non-extrusion toolpaths — CNC / laser / plotter** *(experimental)* — cut/burn/draw moves classified
as `Cut`, a modal `toolPower` (laser power / spindle RPM) channel, canned drilling-cycle expansion
(`G81`/`G82`/`G83`), and controller recognition (GRBL laser/mill, LinuxCNC) — all honesty-**tiered**:
reported `inferred` until confirmed on real hardware, never fabricated.
- **Honest live progress** (for printer telemetry) — a normalized `ProgressObservation` contract
mapped onto the toolpath with tiered confidence: a precise cut + marker when the source position
is known, an uncertainty band when it is approximated, stale-signal handling, and user scrub
Expand Down
5 changes: 3 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ See also [`../PROJECT_SETUP.md`](../PROJECT_SETUP.md) for the local environment
Provenance of inherited vs. Chestnut code, the exact founding baseline, and the branch mapping are
tracked in [`UPSTREAM_PROVENANCE.md`](UPSTREAM_PROVENANCE.md).

## Current state (updated 2026-07-27 — v0.3.0 in preparation; E0–E11 complete; renderer/viz backlog (#177–#185) shipped; binary G-code (`.bgcode`, #188/DD-011) code-complete)
## Current state (updated 2026-07-29 — v0.3.0 shipped to npm; v0.4.0 in prep; #188 bgcode closed; #189 CNC/laser phases 1–5 built + real-file lexer/detection; #152 STL export done)

| Epic | Status | Gate |
|---|---|---|
Expand All @@ -56,7 +56,8 @@ tracked in [`UPSTREAM_PROVENANCE.md`](UPSTREAM_PROVENANCE.md).
| Renderer color/viz backlog (#177–#185) | **Closed** (2026-07-27) | Additive capability-gated modes over already-parsed IR channels (DD-009 pattern, no new DD). **All shipped:** color-by-speed (#177), color-by-object (#178), color-by-layer-height (#179); seam/wipe move visibility (#182 → [DD-016](design/DD-016-annotation-derived-move-kinds.md)); filled build-plate surface (#185); filament/time metadata (#183) with time-based scrub + print-time estimate (#181); source-line ↔ segment debugger surface (#184). Advanced modal-channel color research (#180) recorded as [RR-002](research/RR-002-modal-state-color-channels.md) |
| **E11** Documentation, SDK Reference & Published Manual (#197) | **Closed/Accepted** (2026-07-25) | [DD-013](design/DD-013-documentation-sdk-reference-and-published-manual.md) **Accepted** (D1–D7 as recommended). Completed E7/DD-008's docs ambit. **All four phases shipped:** typedoc API reference over the ten packages (#198), GitHub Pages + Chestnut Labs theme (#199), SDK manual — getting-started/guides/concepts (#200), accuracy gate + `eslint-plugin-tsdoc` + version stamp (#201). **Live: [chestnutlabs.github.io/gcode-preview](https://chestnutlabs.github.io/gcode-preview/)** (manual at `/`, API at `/api/`), auto-redeployed on merge/release. No package/IR/renderer change. Deferred: flip the `notDocumented` doc-coverage check to error once the 55 TSDoc-syntax gaps are filled |
| **E8** Low-Resource Layer Mode (#9) | **Closed/Accepted** (2026-07-26) | [DD-014](design/DD-014-low-resource-layer-renderer.md) **Accepted** (D1–D5 as recommended; D6 build-now on the standing AnyBridge evidence). **All four §14 phases shipped** — #212 two new lockstep pkgs (`gcode-colors` shared ColorMode subsystem + `gcode-renderer-2d` Canvas 2D `LayerView2D`, no `three`/framework; renderer-three refactored onto the shared colorer) → **12 packages**; #213 adjacent "ghost" layers over a stable model frame; #214 **`renderer: '2d' \| '3d'` prop** through core + all 4 adapters (the 3D renderer is **loaded on demand** so a 2D-only bundle never ships Three.js) + 2D live-progress "cut"; #215 capability-honesty disclosures (non-planar/CNC via `renderer-unsupported`) + **§8 low-resource budget verified on a real device** (redraw ~0.2 ms median, ≤ 3.6 ms @ 6× CPU throttle vs the 16 ms budget; ~0 MB heap growth over 870 renders — no per-layer geometry) ([report](../tools/benchmark/results/e8-2d-lowresource-benchmark-2026-07-26.md)). §15 acceptance criteria met. Roadmap note (DD-008 §4.8): pure-Node GPU-less still rendering is a related deferred capability |
| **Binary G-code (`.bgcode`) decode** (#188) | **Code-complete** — phase 6 (security sign-off) pending | [DD-011](design/DD-011-binary-gcode-decode-adapter.md) **Accepted** (D1–D7; D4 amended — metadata/thumbnails in-scope), preceded by [RR-003](research/RR-003-bgcode-licensing-and-format-audit.md) licensing/format audit. **Phases 0–5 merged** (#231–#239) — new 13th lockstep pkg `@chestnutlabs/gcode-bgcode` decodes Prusa `.bgcode` → plain G-code through the pipeline; all four codecs (None / DEFLATE-zlib / heatshrink w11+w12 / MeatPack) validated against real Prusa files (21 MB XL — 856/856 block-CRC pass; cube golden-equivalence byte-identical); MeatPack (MIT) + heatshrink (ISC) clean-room ports, no AGPL; adversarial fuzz + §7 review + decode benchmark done. **Remaining: maintainer signs off [SECURITY-REVIEW-DD-011-bgcode.md](design/SECURITY-REVIEW-DD-011-bgcode.md) → close #188.** Targets `v0.3.0` |
| **Binary G-code (`.bgcode`) decode** (#188) | **Closed/Accepted** (2026-07-28) | [DD-011](design/DD-011-binary-gcode-decode-adapter.md) **Accepted**, preceded by [RR-003](research/RR-003-bgcode-licensing-and-format-audit.md). New 13th lockstep pkg `@chestnutlabs/gcode-bgcode` decodes Prusa `.bgcode` → plain G-code (None / DEFLATE-zlib / heatshrink w11+w12 / MeatPack; MeatPack MIT + heatshrink ISC clean-room, no AGPL); validated against real Prusa files (21 MB XL 856/856 CRC; cube golden byte-identical); [§7 security review](design/SECURITY-REVIEW-DD-011-bgcode.md) **signed off**. **Shipped in `v0.3.0`.** |
| **Non-extrusion toolpath — CNC / laser / plotter** (#189) | **Phases 1–5 built + merged; documented; experimental tier** | [DD-012](design/DD-012-non-extrusion-toolpath-and-modal-tool-state.md) **Accepted** (D1–D8), preceded by [RR-004](research/RR-004-non-extrusion-toolpath-coverage.md). **Phases 1–5 (#248–#255):** `MoveKind.Cut` + opt-in `ModalChannel`/`toolPower`; modal-motion + canned cycles (`G81`/`G82`/`G83`); GRBL-laser/GRBL-mill/LinuxCNC dialects + **validation tiers** (experimental → claims `inferred`); color-by-power + cut-vs-rapid; [compatibility matrix](compatibility/dialects-and-containers.md#dialects-non-extrusion--cnc--laser--plotter-dd-012-189) + support docs. **Real-file work:** lexer handles multi-command lines / `N`-numbers / bare-`S` (#256 — real LinuxCNC/TinyG now parse); evidence-based detection (#258, 0/6→3/6 real samples); [STL export](../tools/demo) (#152, #257). All FDM-byte-identical. **Remaining:** phase 6 — hardware validation → promote tiers to `validated`; larger gaps (LinuxCNC O-word subroutines/params/expressions). Rides the next lockstep release (`v0.4.0`). |
| #152 STL export | Open, gated | Follows the **#118** chrome/showcase product decision, not an architecture DD (DD-009 §3) |

Shipped so far: `packages/toolpath-core` (SoA `ToolpathIR`, capability model), `packages/gcode-parser`
Expand Down
26 changes: 26 additions & 0 deletions docs/compatibility/dialects-and-containers.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,28 @@ annotation) · **unsupported** (generic parse only — geometry always works; me
| Marlin | **full** (`;FLAVOR:Marlin`; `gcode_flavor` tail) | **full** (`M486 S<idx>`/`S-1` → `objects: known`) | composes (proven: Cura+Marlin) | `dialect-cura-style` | 2026-07-23 |
| RepRap-style | **full** (`;FLAVOR:RepRap`; `gcode_flavor` tail) | — | detection-only | `dialect-reprap-style` | 2026-07-23 |

## Dialects (non-extrusion — CNC / laser / plotter, DD-012 #189)

Non-extrusion controllers. Each declares a **validation tier** (DD-012 D6): until a controller is
confirmed on real hardware, its non-extrusion claims are reported **`inferred`** (experimental), never
`known` — the tier *is* the honesty mechanism. Geometry (positions, arcs, drilled holes) always parses
regardless of tier; the tier governs only how much to trust the *semantic* classification. The
underlying capabilities are in [Cross-cutting coverage](#cross-cutting-coverage) below.

| Controller | Detection | Machine class | Validation tier | Non-extrusion claims | Fixtures | Evidence date |
|---|---|---|---|---|---|---|
| GRBL laser | LightBurn header / `$32=1` laser mode / `M4`+`S`, no extrusion | laser | **experimental** | `cutMoves` · `toolPower` (laser power) · `cannedCycles` — reported **`inferred`** until hardware-validated | synthetic | 2026-07-28 |
| GRBL mill | `Grbl` banner + `M3` spindle, no extrusion | mill | **experimental** | `cutMoves` · `toolPower` (spindle RPM) · `cannedCycles` — **`inferred`** | synthetic | 2026-07-28 |
| LinuxCNC / EMC | `LinuxCNC`/`EMC` header / `%`-program + `M3` | mill | **experimental** | as above — **`inferred`** | synthetic | 2026-07-28 |
| Marlin-laser / Mach / Smoothieware | _reserved_ | laser/mill | _pending_ | generic parse only until added | — | — |
| Pen plotters (servo `M280` / Z-lift) | _reserved_ | plotter | _pending_ | generic parse only until added | — | — |

Each dialect adds provenance to `metadata.raw` (`cnc.controller`, `cnc.machineClass`,
`cnc.toolPowerLabel`, `cnc.validationTier`) and emits a `cnc-dialect-experimental` disclosure warning.
A one-line `tier: 'validated'` flip per controller promotes its claims to `known` once a real-hardware
run confirms them (DD-012 §8/§15). **DSP lasers (`.rd`) and galvo (`.ezd`) are out of scope** — those
are proprietary binary formats, not G-code.

## Containers

| Container | Discovery | Plates | Machine metadata | Integrity checks | Security review | Fixtures | Evidence date |
Expand All @@ -42,6 +64,10 @@ annotation) · **unsupported** (generic parse only — geometry always works; me
| Multi-tool / AMS / IDEX | core `tool` channel (T commands) + adapter `filament_type/colour` → `ir.tools` material/color | **full** (`dialect-multitool-ams`, 2026-07-23) |
| Arc moves (G2/G3) | core parser (golden-gated) | **full** since E2 |
| Per-file build plate in the viewer | `metadata.machine` → `setBuildVolume` (DD-005 §4.2) | mechanism shipped (phase 1); data arrives phases 2–3 |
| Non-extrusion move classification (`Cut`) | core parser: a no-`E` move while a tool is engaged (`M3`/`M4`, `M5` off) → `MoveKind.Cut` (DD-012 D2, #189) | **full** mechanism (`cutMoves: 'known'`); a per-dialect experimental tier reports it `inferred` |
| Tool-power channel (`toolPower`) | opt-in `ModalChannel` — the modal `S` while engaged, requested via `ParseOptions.modalChannels` (DD-012 D3) | **full** mechanism; `NaN` when the tool is off, never a fabricated 0; consumed by the `power` color mode |
| Canned drilling cycles | parser expands `G81`/`G82`/`G83` (+ `G80`, `G98`/`G99`, and modal bare-`X`/`Y` repeat) to real geometry (DD-012 D5) | **full** for `G81`/`G82`/`G83` incl. `G83` peck; `G84`–`G89` `unavailable` (disclosed) |
| Modal motion continuation | a coordinate-only line repeats the last `G0`–`G3` motion mode — the CNC/LinuxCNC form (DD-012 phase 2) | **full** since #189; FDM unaffected (slicers always emit the `G` word) |

## Live progress tiers (DD-006, E5)

Expand Down
62 changes: 62 additions & 0 deletions docs/design/DD-012-hardware-validation-log.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# DD-012 — Hardware validation log (#189)

**Purpose.** DD-012 D6/D8 make every non-extrusion dialect ship **`experimental`** (claims reported
`inferred`) until its classification is confirmed on a real machine, at which point it is promoted to
**`validated`** (claims report `known`, the `cnc-dialect-experimental` warning drops). This file is the
**acceptance evidence** behind each promotion: one entry per hardware run, recording what was observed
against what the physical machine did. A tier flip in
[`packages/gcode-dialects/src/cnc.ts`](../../packages/gcode-dialects/src/cnc.ts) must cite an entry here.

**Provenance.** We record the run's *observations* (move counts, power range, verdicts) and the file
**name only** — never the user's design file or its geometry (RR-004 §6 governance). The files are the
maintainer's own jobs on the maintainer's own hardware.

**What a pass validates.** The `experimental` tier downgrades exactly three capabilities — `cutMoves`,
`toolPower`, `cannedCycles`. A run validates a controller by confirming, against the physical result,
the claims the file actually exercises: machine-class detection, the Cut-vs-rapid split, the `toolPower`
(`S`) channel, and (where present) canned-cycle geometry. The check is performed with the in-repo
**validation harness** (`tools/demo/validate.html`), which lists each claim for ✓/✗ marking and exports
the report pasted below.

---

## Runs

### grbl-laser — VALIDATED — 2026-07-29

- **Controller / dialect:** GRBL / LightBurn → `grbl-laser` (machine class **laser**)
- **Machine:** maintainer's diode laser
- **File:** `laser-diode-test1.gc` (name only; not committed)
- **Tool:** [`tools/demo/validate.html`](../../tools/demo/validate.html) harness export

| Observed | Value |
| --- | --- |
| Moves | 5822 cut · 339 rapid · 6161 total |
| Tool power (`S`) | 0–1000 over the 5822 cutting moves (full ramp; exercises the `toolPower` channel end to end) |
| Envelope | 356.0 × 566.0 × 0.0 mm (planar) |
| Geometry | fill + offset-fill patterns |

**Findings (maintainer, against the physical cut):**

| Claim | Verdict | Note |
| --- | --- | --- |
| Machine class correct | ✓ matches | detected `laser` |
| Cut-vs-rapid split correct | ✓ matches | holds across fill + offset-fill |
| Tool-power ramp correct | ✓ matches | 0–1000 `S` tracked real laser behavior |
| Work envelope matches part | ✓ matches | off-bed by design (placed off-bed in the source software) |
| Overall path shape matches | ✓ matches | — |
| Canned/drilling cycles | n/a | a laser has no `G81`–`G83` |

**Decision:** all exercised claims ✓ against real hardware → **`grbl-laser` promoted
`experimental` → `validated`** ([`cnc.ts`](../../packages/gcode-dialects/src/cnc.ts)). Scope is
per-controller: this run validates GRBL/LightBurn **laser** classification only. `grbl-mill` and
`linuxcnc` remain `experimental` pending a run on the partner CNC.

---

## Pending

| Dialect | Tier | Needs |
| --- | --- | --- |
| `grbl-mill` | experimental | a real GRBL-mill / router run (spindle `M3`, Z-plunge, ideally a `G81` drill) |
| `linuxcnc` | experimental | a real LinuxCNC run (canned-cycle geometry + `toolPower` against the machine) |
Loading
Loading