From 6362cef699d10f4af3a7e00224adc4777b82075c Mon Sep 17 00:00:00 2001 From: cproudlock Date: Thu, 16 Jul 2026 16:35:17 -0400 Subject: [PATCH] printedparts docs: record the open-write kiosk decision; defer the dashboard widget The kiosk take endpoint is the product's first unauthenticated mutation; spell out the acceptance criteria (decrement-only, badge attributed, bounded, physically rate-limited) so future open-write endpoints meet the same bar. The dashboard-widget milestone is marked optional: get_dashboard_widgets predates the ADR-010 data-only renderers and needs a core component to render. --- docs/PLUGIN-LAB-PRINTEDPARTS.md | 6 +++++- docs/proposals/printedparts-plugin.md | 18 ++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/docs/PLUGIN-LAB-PRINTEDPARTS.md b/docs/PLUGIN-LAB-PRINTEDPARTS.md index d6f863f..8d56a13 100644 --- a/docs/PLUGIN-LAB-PRINTEDPARTS.md +++ b/docs/PLUGIN-LAB-PRINTEDPARTS.md @@ -166,7 +166,11 @@ Build 2. Stock report includes the reconcile check: flag rows where cached `quantityonhand` != SUM(ledger). Should always be empty; if not, you have a non-atomic write path - find it. -3. `get_dashboard_widgets()` -> low-stock count. +3. OPTIONAL/deferred: `get_dashboard_widgets()` -> low-stock count. Caveat: + this hook predates the ADR-010 data-only renderers - the widget names a + frontend component that must already exist in core, so a plugin widget + only renders if you also add that component. Reports are the primary + monitoring surface; skip the widget unless you want the extra credit. 4. Nice-to-have if time: burn rate (avg weekly takes over trailing 4 weeks + weeks-to-empty). Plain SQL over the ledger. diff --git a/docs/proposals/printedparts-plugin.md b/docs/proposals/printedparts-plugin.md index 267dbaf..bdcc798 100644 --- a/docs/proposals/printedparts-plugin.md +++ b/docs/proposals/printedparts-plugin.md @@ -187,8 +187,22 @@ default_enabled false (site opts in - USB precedent). - Cached quantity vs ledger drift: single-commit writes + a reconcile query in the stock report (flags items where cache != ledger sum). -- Unauthenticated kiosk take: accepted (matches shopfloor kiosk posture); - it is decrement-only, fully attributed, and rate-limited by physics. + +### Decision: the kiosk take endpoint is an unauthenticated WRITE + +This is the first open mutation in the product - every existing kiosk +endpoint (notifications, employees, shopfloor) is a read, and the closest +write (USB checkout) is JWT + permission gated. Accepted deliberately, on +these grounds, and any future open-write endpoint must meet the same bar: + +1. Decrement-only: it can reduce stock of an active item, nothing else - no + catalog edits, no restocks, no reads it does not already expose. +2. Fully attributed: it refuses to act without a badge that resolves per the + site policy; every action lands in the ledger with SSO + name + time. +3. Bounded blast radius: worst case is stock counts driven low, which the + ledger makes visible and reversible (adjust with reason). +4. Physically rate-limited: it exists for a touch screen on the shop floor; + there is nothing to enumerate and nothing returned worth scraping. - 1x0.5in QR marginal: default to CODE128 barcode. - Not an Asset: no floor-map plotting or warranty for items. If a site later wants bins on the floor map, revisit via get_map_overlays (ADR-010).