# Plotter Plan โ€” ink-signature station for no-login CMS filings Goal: turn the (already-built) ink-signature pipeline into a reliable physical station that draws an **original wet-ink signature** on each printed CMS form so the Standard (no-login) filing path can be mailed and accepted. The CR-10 V2 is the motion system; this plan covers the retrofit, calibration, the software/hardware integration that remains, validation, and the operational runbook. Status legend: โœ… done ยท ๐Ÿ”ฒ to do ยท โณ blocked on hardware --- ## 0. What already exists (software, hardware-independent) - โœ… `signature_vector` capture end-to-end (migration 090, signing page, API). - โœ… `ink_signature_plotter.py` โ€” fit-to-box, PDF-pt โ†’ bed-mm, G-code (Z pen or M280 servo/BLTouch), SVG preview, `render_signature_on_pdf` digital twin, gated serial sender. - โœ… `ink_signature_cli.py` โ€” load record โ†’ gcode + preview, `--test-box`, `--plot`. - โœ… `test_ink_signature.py` 30/30; signature anchor verified inside the CMS-10114 Section 4A cell. - โœ… `docs/ink-signature-plotter.md` โ€” retrofit + interpretive-risk writeup. The remaining work is hardware + a few integration/safety pieces. --- ## 1. Hardware retrofit (CR-10 V2) 1. ๐Ÿ”ฒ **Pen holder.** Print a spring-loaded CR-10/Ender X-carriage pen holder (Printables/Thingiverse). Spring = even contact pressure. Print it before converting (you still have the hotend). - BOM: printed bracket, 1 compression spring (~8โ€“12mm), 2โ€“3ร— M3 screws, a smooth **gel/rollerball** pen (wet ink, hand-written look). 2. ๐Ÿ”ฒ **Mount + cable management.** Attach beside the hotend; make sure the pen tip is the lowest point and the bed can still home. 3. ๐Ÿ”ฒ **Pen-up/down method โ€” pick one:** - *Z mode (default, simplest):* pen fixed; G-code lifts/drops Z. Spring forgives over-press. No firmware change. - *Servo/BLTouch mode (optional):* actuate pen with a servo or repurpose the BLTouch; `--servo-pen` emits `M280`. Faster, no Z lash, more build effort. - **Decision:** start Z mode; revisit servo only if Z lift is too slow. 4. ๐Ÿ”ฒ **Paper jig.** Tape an L-shaped corner stop to the bed (front-left) so a US-Letter sheet always sits at the same `(jig_x_mm, jig_y_mm)`. This is the single most important accuracy factor. 5. ๐Ÿ”ฒ **Pen-touch Z reference.** Either set `pen_down_mm` by hand, or use the BLTouch to probe a fixed point on the jig for a repeatable touch height. Reversibility: nothing here is permanent; swap the hotend back to print anytime. --- ## 2. First-light calibration (uses --test-box) 1. ๐Ÿ”ฒ Connect: CR-10 enumerates as CH340 `/dev/ttyUSB0` @ 115200. Confirm with `ls -l /dev/ttyUSB*` and a manual `G28` via pronterface/printrun. 2. ๐Ÿ”ฒ Dry-run inspect: `ink_signature_cli.py --order --doc cms10114 --test-box` โ†’ review the `_testbox.gcode` + `_preview.svg`. 3. ๐Ÿ”ฒ Plot the box on a **blank** sheet in the jig: `--test-box --plot --home --port /dev/ttyUSB0`. 4. ๐Ÿ”ฒ Print a real (unsigned) CMS-10114 cert page, lay it in the jig, plot the test box again, and confirm the rectangle frames the Section 4A signing cell. 5. ๐Ÿ”ฒ Tune `--jig-x/--jig-y` (position) and `--pen-down` (ink without digging in) until the box lands on the line. **Record the final values** as the station defaults. 6. ๐Ÿ”ฒ Bake the calibrated defaults into `PlotterConfig` (or a small `plotter_config.json` the CLI/worker reads), so operators don't pass flags. Acceptance: the plotted rectangle sits within ~1mm of the cell, repeatably, across 3 reloads of the sheet. --- ## 3. Software/integration still to build 1. ๐Ÿ”ฒ **Persisted station config.** `scripts/workers/services/plotter_config.json` (jig offset, pen heights, feeds, port) loaded by `PlotterConfig.from_file()`. Keeps calibration out of code + flags. 2. ๐Ÿ”ฒ **Anchor scaling parity test.** A test that plots/previews against a page whose `page_w/page_h` differ from the authored size, asserting the strokes still land in the cell (the stamper already scales; add the matching ink test). 3. ๐Ÿ”ฒ **Signature-quality guard.** Reject/flag vectors that are too few points, near-empty bbox, or a single dot (someone tapped instead of signing) before they reach the pen. Add to `ink_signature_plotter` + a unit test. 4. ๐Ÿ”ฒ **855 anchors for ink.** `cms855_pdf_filler` only has the 855I signature rect today; add 855B/O/A signature rects so org filings can also be plotted (currently human-placed). Mirror the CMS-10114 anchor approach. 5. ๐Ÿ”ฒ **Batch integration.** Teach `daily_paper_batch.py` to, for each signed filing in a batch: (a) print the filled form, (b) call the plotter to ink the signature, (c) include it in the per-agency envelope. Sequencing + a per-sheet "plotted โœ“" status column so a crash doesn't double-sign or skip. 6. ๐Ÿ”ฒ **Plot audit trail.** Store the emitted G-code hash + a post-plot photo (if a camera is added) on the esign/batch record for traceability. 7. ๐Ÿ”ฒ **Operator safety.** `--plot` already gated; add a hard env guard (`INK_PLOTTER_ENABLED=1`) so a stray `--plot` on a dev box can't move a machine, and a `--confirm` prompt for live runs. --- ## 4. Validation (build verifiable criteria) - ๐Ÿ”ฒ **Geometry (done, extend):** keep `test_ink_signature.py` green; add the page-scale parity + quality-guard tests above. - ๐Ÿ”ฒ **Physical accuracy:** a calibration card โ€” plot a 10mm grid + the test box, measure with calipers, assert โ‰ค1mm error. Document the measured numbers. - ๐Ÿ”ฒ **Legibility:** plot 5 real captured signatures, scan, eyeball that each is recognizably the signer's mark (not mangled by resampling). Tune `min_segment_mm` / feeds if jagged. - ๐Ÿ”ฒ **Ink originality sanity:** confirm under magnification the line is continuous wet ink (not dotty), since "deemed not original" is the failure mode we're guarding against. - ๐Ÿ”ฒ **End-to-end dry run:** one fake order โ†’ form printed โ†’ signature plotted โ†’ batched โ†’ addressed envelope, with nothing actually mailed. --- ## 5. Go-live policy (interpretive risk) CMS does not explicitly bless/ban autopen for the 855/10114. Therefore: 1. ๐Ÿ”ฒ **Two paths, choose per filing:** - *Plotter (fast):* default for low-stakes changes (e.g. address/contact NPPES updates) where a re-file is cheap. - *True wet-signature mail-out (safe):* a printed packet to the provider (cover sheet with a signing arrow + return envelope) for high-stakes filings (enrollment, reactivation) until acceptance is proven. 2. ๐Ÿ”ฒ **Pilot:** run a handful of real plotter-signed filings, track acceptance vs rejection at the MAC/Enumerator. If clean, widen the plotter default. 3. ๐Ÿ”ฒ **Kill switch:** if any rejection cites the signature, fall back to wet-sig mail-out for that service and log it. Note: never expose any of this (plotter, paper, ink, MAC, Enumerator) in client-facing copy โ€” same rule as the rest of the no-login model. --- ## 6. Operational runbook (once calibrated) ``` # Daily, per signed Standard filing (or via daily_paper_batch once wired): 1. Print the filled, unsigned form (form printer, plain paper). 2. Lay the cert page in the jig on the CR-10. 3. Plot the signature: INK_PLOTTER_ENABLED=1 python scripts/workers/ink_signature_cli.py \ --order CO-XXXX --doc cms10114 --plot --home --confirm 4. Verify the ink landed on the line; reassemble the form pages. 5. Hand to the daily batch -> per-agency Priority Mail envelope. ``` --- ## 7. Sequence (what to do, in order) 1. Print + mount the spring pen holder; tape the jig. (ยง1) 2. Calibrate with `--test-box`; record jig/pen values. (ยง2) 3. Add persisted `plotter_config.json` + load it. (ยง3.1) 4. Add quality guard + page-scale parity tests. (ยง3.2โ€“3.3) 5. Physical accuracy + legibility validation. (ยง4) 6. Wire into `daily_paper_batch` with per-sheet plotted status. (ยง3.5) 7. Add env/confirm safety guards. (ยง3.7) 8. Pilot live filings under the go-live policy; widen or fall back. (ยง5) 9. (Later) 855B/O/A anchors so org filings can be plotted too. (ยง3.4) --- ## Dependencies / risks - โณ Everything in ยง1โ€“2 is blocked on the pen holder + jig (cheap, fast). - Risk: jig drift โ†’ signature off the line. Mitigate with a fixed, screwed-down jig and a per-session `--test-box` check. - Risk: pen dry-out / skipping โ†’ illegible mark. Mitigate with gel/rollerball + legibility validation + a "prime the pen" pre-stroke. - Risk: CMS deems plotted signature "not original." Mitigate with the two-path go-live policy + pilot.