Skip to content

EmbeddedEra app (home.embeddedera.com/app)

The one screen the business runs from. Code: ~/assistant (main = production, assistant.service), built on branch cockpit in ~/assistant-sandbox. Tabler "Workshop" shell, vendored MIT libraries, engines (InvenTree, Kanboard, Metabase, the vault) stay behind it. Started 2026-10-01; history of decisions in plex-server Log until this note took over.

Rules (owner)

  • Every task starts in the app: find it, see its status and do the common actions here; deep work (editing a Google Doc/Sheet, accounting, specialist admin) opens the specialist tool. Build only shop-specific workflows and glue; link or index what a maintained tool already does (owner, 2026-10-04 — replaces "every click stays inside"; see company-operating-system-strategy, app-everything-in-app).
  • The menu lists things; actions live on the page of the thing they change.
  • Prefer a proven MIT library, vendored, over hand-written UI (prefer-mit-libraries).
  • Preview → confirm → undo for every write; sandbox ERP for testing; production only through the app.
  • No UI change ships unless app-ui-check passes. It runs real WebKit (iPhone 13 + iPhone SE, the Safari engine) in the official Playwright Docker image against a throwaway server with every API mocked, opens every sheet/dialog/menu, scrolls it to the end and fails if any part is off screen (also with the keyboard-sized viewport), and checks every route scrolls to its last element with no sideways scroll. Source: tests/ui/ in the repo (README there); command ~/.local/bin/app-ui-check [worktree]. Add a scenario for every new sheet and a route for every new page. Smart gate (2026-10-13): app-ui-check <worktree> --since <rev> runs only what the changed files need (~/.local/bin/app-test-scope: server code only → none, a lazy view module → its scenarios on all 4 device runs, anything shared → full) and skips entirely when the exact clean tree already passed the full gate (~/.local/state/app-ui-check/passed). app-release uses it against production main and runs the speed check only for full-scope changes. Add a line to app-test-scope's case list for every new view module. Never sudo apt for browsers; the image is the way.
  • Overlays (sheets, lock, photo viewer) are <dialog> frames appended to <body> and pinned to visualViewport by JS; the page behind is locked with overflow:hidden on <html>, never position:fixed on <body>. No transform/filter/backdrop-filter on any ancestor of a fixed element (.app-top, .fade-in).
  • Releases: every deploy goes through ~/.local/bin/app-release "What's-new line" … — tests + app-ui-check (WebKit iPhone gate) must pass; CalVer YYYY.MM.N; VERSION + CHANGELOG.md (plain-English What's new, shown in Settings → About); git tag vYYYY.MM.N (rollback: git -C ~/assistant reset --hard v<prev> + restart). First version v2026.10.1 (2026-10-02).
  • The one outside alert: Healthchecks.io dead-man (hc-ping.com, DEADMAN_URL in /etc/rescue-kit.conf) — emails if the server goes silent.

Overview · SELL Invoices, Customers, Marketing · MAKE Parts (Minimums tab), Assemblies & BOMs, Build orders, Stock, Purchase orders · MONEY Margins · SYSTEM Workflows (Jobs), People & access (admin). Top-right: profile.

Assistant behind the app (chat / admin) — moved from memory 2026-10-19

  • Addresses: chat https://chat.embeddedera.com · admin https://admin.embeddedera.com (Administration department, owner addresses only) · sandbox app https://chat-sandbox.embeddedera.com/app (Cloudflare Access sign-in; the old http://chat-sandbox.lan has no sign-in and returns 401, corrected 2026-11-11; banner, production actions refused) · sandbox ERP http://sandbox.lan (password printed by erp-sandbox up).
  • Code: ~/assistant (main = production, assistant.service on 127.0.0.1:8200) and worktree ~/assistant-sandbox (branch sandbox, assistant-sandbox.service on 172.18.0.1:8201, sandbox ERP); templates/plugins in ~/erp-config (branch sandbox too). Rule: code is branched, data snapshotted, nothing tested on production (sandbox-workflow). Config ~/.config/assistant/env (+ env.sandbox), people ~/.config/assistant/people.yml (owned by onboard), departments ~/Notes/roles/departments.yml, skills ~/Notes/skills/<dept>/SKILL.md, SOP index ~/.local/state/assistant/sops.json (built by sop-index, run by sop-deploy).
  • Guarantees live in code, not prompts: identity = verified Access JWT (two audiences); the model sees only our five in-process tools (built-ins removed + disallow list + PreToolUse deny hook); department-scoped ERP token (Sales: 403 on delete, proven); prices from the price list; nothing written until /confirm; the page renders only action / question / guide / standard line; 500-char cap; sqlite tables turns, admin_actions, jobs, secrets, emails, backed up nightly. Model Haiku. Red-team suite assistant-test (17 cases, daily 06:40 against the sandbox, ntfy on failure).
  • Admin page cards: assistant per department (on/off), sandbox (up/reset/down), canaries, backups, access lists, services, sign-ins (Cloudflare Access audit log), people (add / edit name / change departments / reactivate / remove / reset NAS password / send welcome), recent turns. Onboarding emails via Resend from hello@; the NAS password only through a gated one-time link.
  • Guide mode: "How do I..." returns a card from sops.json (number, title, owner, version, purpose, link, computed "I can do this for you"); other-department SOPs give a referral to the owner, never steps.
  • Skills live (2026-09-12): sales, purchasing, engineering, production, admin, each with its own ERP user and token (all 403 on delete), guided multi-field forms (forms.py), feedback capture with admin triage, demo sandbox with expiring guest invitations (one-time email codes, sandbox gates only).
  • Lessons: the Agent SDK offers the full built-in tool roster regardless of allowed_tools; test only with throwaway accounts (an agent test once deactivated a real user; repaired with onboard update; details in roles-and-skills Log 2026-09-12). erp-backup had an R2 pagination bug that made "latest" stale, fixed.
  • Reporting: Metabase is the published reporting system, https://reports.embeddedera.com behind Cloudflare Access; stable paths /management and /quality; Grafana only on localhost:3000. Navigation preference (Angel 2026-09-21) is in reporting.

HANDOFF 2026-11-02 — Reports: Website + Code & GitHub (start a new chat: "read the handoff in ~/Notes/projects/embeddedera-app.md and continue")

  • Built, committed on cockpit (~/assistant-sandbox), NOT released: fcc156e Code & GitHub reports (admin; code_activity.py: open/closed PR GraphQL searches for org:EmbeddedEra user:angelEmbeddedEra, local git state of every repo/worktree under /home/angel except Notes, 5-min cache; external row links open a new tab via openRow in app.js). e86dd4a Website reports (sales+admin; site_reports.py reads marketing.sqlite: Clarity page_ rows -> Website pages, site cta_clicks -> Clicks toward contact, form_ -> Form drop-off; tiles grouped by server group).
  • Checks passed: full pytest 3053 passed; app-ui-check --since fcc156e 1829 passed 0 failed (earlier full run 1813 passed, 4 notes flakes passed on retry). Live data check: 5 open PRs, 18 merged in 7 d, 34 unmerged server folders; 10 Clarity pages (dead clicks on /, /services/, /contact/, /faq/).
  • Done 2026-11-02: released v2026.11.2 (owner asked in chat); site PR #15 merged (915faee) and deployed. PageSpeed key was already set (daily scores since 2026-10-02), nothing to do.
  • Collector (ops-scripts, pushed): 30346d1 Clarity share fix + per-page rows; 9da8dac site clicks/form funnel, Bing backlinks, Meta not_connected while social is paused. Details: site-measurement.
  • Next: after release, open #reports on the phone: Website + Code & GitHub groups show; tile counts should match the numbers above. After #15 is live, confirm cta_clicks/form_starts rows appear in marketing.sqlite the next morning (08:05 run). Known limit: Done this week has no GitHub commit counts (contributions API returns 0 for this account); it shows server commits + merged PRs.

Open

  • Sync two KiCad descriptions to the ERP (SOP-008 audit, 2026-10-06): symbols EE-C-0065 / EE-C-0067 now say "PROGRAMMING PADS, NOT POPULATED, ..." but the ERP parts still say "PROGRAMING HEADER" (ERP write, Engineering with an ERP token; kicad-erp-sync audit lists the mismatch). Also decide whether to add 2.54 mm STM32 SWD and Microchip ICSP programming-pad symbols, deleted as unused (footprint ProgramingSocket_1x05_P2.54mm_Vertical is still in the library, no symbol).
  • Label tape EE-K-0004 mm → m after build BO-0001 is finished: stock 23838 mm → 23.838 m and per-board BOM qty 27 mm → 0.027 m (EE-A-0002/0004/0005), in one step; BO-0001 holds 567 of 729 mm. EE-K-0005 stays mL (owner).
  • Push notifications: deploy and migrate off ntfy (built on branch cockpit in ~/assistant-sandbox: notify_push.py, static/sw.js, ~/.local/bin/notify; pywebpush 2.5.0 is MPL-2.0, server-side only; VAPID keys in ~/.config/assistant/vapid.env, CLI secret in ~/.config/assistant/notify.secret, both 0600). After the branch is merged and assistant.service restarted: (1) add cron 30 7 * * * cron-run push-summary notify summary (the 7:30 one-liner); (2) install on the iPhone: Safari to the app, Share, Add to Home Screen, open it from the icon, Profile, Notifications, Turn on for this device, Send test.
  • Wired to push (ntfy kept alongside for now): cron-run failures (kind jobs, critical for backup/snapraid/smart/disk/precious/rescue/restic names); jobs-index findings transitions (jobs); parts newly below minimum and Paul Shop below target (stock, via notify scan run from jobs-index, every 15 min with cockpit-index); Kanboard task newly assigned or moved to Review (tasks, via notify kanboard, same run); invoice payment recorded, reminder sent, call task created (invoices); daily summary (needs the cron line above).
  • Still ntfy only: Scrutiny, smartd (smartd-ntfy.sh), snapraid-alert@ OnFailure, rescue-watchdog, history-backup, tasks-digest-alert and the shared unit alert (systemd failures), surfaces-check, postiz-scheduler-watchdog, cron-watch (the "job stopped running" page), uptime-kuma. Each can call notify --kind system --critical --title ... --url '#jobs'; move one at a time, then delete its ntfy line. Healthchecks.io dead-man stays.
  • Ship: iPhone scroll fix, bottom sheets scroll, stock location bar overlap, long-press text selection, New customer, job detail (Run/Pause/Fix/Retire), kicad-check as "findings", tester-report-sync fix (helper in progress).
  • Remove/edit menus (⋯, long-press, right-click) over the committed lifecycle API (assistant 1941dd1): PO delete/cancel/edit (owner's stray LCSC PO-0002 → delete), build cancel, part obsolete, stock scrap, customer/supplier archive.
  • Profile menu (top right): name, areas (read-only), notifications per kind + quiet hours + this device, app lock, theme, sign out.
  • SYSTEM → People & access (admin only): people list/detail with departments as ticks, "what they can see" computed from departments.yml, devices, welcome / NAS reset / deactivate; Add person (reuses onboard); Roles matrix (department × permission); sign-ins & activity. Then retire admin.embeddedera.com (backups/services/canaries fold into Workflows).
  • Notifications: Web Push from the home-screen app (iOS 16.4+, Android, desktop), per-user and per-kind settings, quiet hours, badge = Needs-you count; owner gets everything, Yara her tasks + Sell. Then move every ntfy alert into it and retire ntfy; keep Healthchecks.io as the only external alert.
  • App lock with Face ID / fingerprint (WebAuthn passkeys, SimpleWebAuthn MIT + py_webauthn), optional per person, can be required for Money. Also: add a Google passkey to both Google accounts for biometric sign-in (owner step).
  • Pictures: part/assembly thumbnails in lists, photo on detail, proxied from the ERP; "Add photo" from phone camera clears needs-photo.
  • Tasks in-app (board columns, create/move/comment/assign, mine) over Kanboard's API; storage can move to open.md later without changing the screen.
  • Projects + SOPs in-app: render vault project notes (status, to-dos, decisions, log; tick to-dos, add log lines) and SOPs; wikilinks become in-app routes.
  • Workflows page: 35 workflows by area from Notes/_system/workflows/ with Mermaid diagrams (MIT) and the keep/pause/retire review (retire maint-badblocks/drill/dedupe, pause pod-pins; fix precious-verify cron OR, erp-output-clean every minute, add cron-run to 3 unwrapped jobs).
  • Remaining forms: finish build, new PO from shortages, receive delivery, ship + invoice Paul from Paul Shop (consumes consignment stock).
  • Invoice reminders: switch ~/.config/assistant/invoice-reminders.mode to live when the owner says "turn reminders on" (first send would be Mon 2026-10-12, SO-0001 courtesy).
  • Prices: 46 parts unpriced (2 PCBs, 4 consumables, 40 components) → margins overstated.
  • Assistant: add Angel's wife from the People card as sales,finance once she has a Google account (Finance skill blocked on the accounting decision). Guided forms (multi-turn field collection) and the Engineering "part from a number/datasheet" skill are designed in roles-and-skills but not built. WhatsApp deferred (phase 5 there).

Log

  • 2026-11-11: Phone bottom tab bar built on cockpit (9b9d393, NOT released): below 992px the top hamburger row goes; bottom bar = Overview, Tasks, Chat, Parts (Invoices if sell-only), Menu (opens the full menu above the bar). Desktop sidebar unchanged. CSS budget 25→26 KiB gzip. Full app-ui-check 1833/1834 (1 desktop 3D board-highlight flake, passed 3/3 alone); pytest 3052 passed (node-dependent asset test can't run here: no node). Tab picks are one line in renderNav if Angel wants different ones.
  • 2026-10-06: Parts clean-up rehearsed end to end on the sandbox (descriptions/units, 33 MPNs, 11 merges, 30 archives all verified); production writes NOT applied (permission classifier blocked the run). No record lock was active (the owner's bulk-edit check-out was already cancelled 06:31). See the Open item.
  • 2026-10-02: Note created; roadmap consolidated from the session (order above, owner approved "plan to incorporate all this while keeping the organization").
  • 2026-10-02: LIVE (assistant 21614ef): iPhone scroll fix, scrollable sheets, stock bar stacking, New customer, job detail + controls (Run/Pause/Resume/Retire/Fix), findings severity. tester-report-sync fixed (sync_tester_reports.py lost exec bit); restored exec bits on 4 more erp-config files — cause unknown.
  • 2026-10-02: LIVE (assistant 8265299): ⋯/long-press/right-click action menus (delete/cancel/edit PO, obsolete part, scrap, archive), profile menu (top right), in-app post sheets; People & access API committed (UI next).
  • 2026-10-02: People & access LIVE (assistant 2652bda). Notifications (Web Push) in progress.
  • 2026-10-02: Web Push built on the cockpit branch (notify_push.py, sw.js, notify CLI); not deployed. See Open.
  • 2026-10-02: Notifications LIVE (assistant fc00bc6; ops 5482aaf). Assistant venv dependency added: pywebpush 2.5.0 (MPL-2.0) — no requirements file exists, so record it here; rebuilds of ~/.local/share/assistant-venv must reinstall it. VAPID keys ~/.config/assistant/vapid.env, CLI secret notify.secret (0600). Daily summary cron 07:30 (push-summary). ntfy kept in parallel.
  • 2026-10-02: App lock (optional passkey/biometric gate) built on the cockpit branch (applock.py, not deployed). Assistant venv dependencies added: webauthn 3.0.1 (py_webauthn, BSD-3; pulls cbor2, pyOpenSSL, pyasn1) — no requirements file, so rebuilds of ~/.local/share/assistant-venv must reinstall it (uv pip install --python <venv>/bin/python webauthn). Browser side vendored: @simplewebauthn/browser 14.0.0 (MIT) in static/vendor/simplewebauthn/. Env: APPLOCK_RP_ID (home.embeddedera.com), APPLOCK_ORIGINS (https://home.embeddedera.com), APPLOCK_COOKIE_SECURE; secret ~/.config/assistant/applock.secret (0600, auto-created). WebAuthn needs a secure context: the sandbox on http://chat-sandbox.lan cannot register a passkey; test on http://localhost (RP ID localhost) or over https.
  • 2026-10-02: Assistant venv dependencies added for in-app Tasks + Projects/SOPs (branch cockpit: tasks_api.py, docs_api.py): markdown-it-py 4.2.0, mdit-py-plugins, nh3 0.3.7 (all MIT; installed with uv pip into ~/.local/share/assistant-venv). No requirements file exists, so a rebuilt venv must reinstall them.
  • 2026-10-02: LIVE (assistant a7e3afd): app lock (opt-in), images API, tasks API, docs API (screens next).
  • 2026-10-02: LIVE (assistant c6ce8ab): WORK section — Tasks board (Kanboard engine, SortableJS), Projects + How-to in-app, part pictures + camera upload; in-app link rewriting for tasks/SOP/notebook. Workflows page in progress.
  • 2026-10-02: LIVE (assistant 2a1a064): System → Workflows (35 workflows, Mermaid diagrams, Review tab). Owner asked for a Tabler consistency pass using its demo layouts (settings, users, activity, tasks, invoice, uptime, logs, steps, prose, datagrid, empty, auth-lock…) — in progress.
  • 2026-10-02: iPhone bug (Profile sheet below the screen). Fixed app-wide: overlays pinned to visualViewport, body-fixed scroll lock removed, backdrop-filter on the top bar removed (it made the phone search results position against the bar), page fade-in is opacity only. Permanent gate app-ui-check added (real WebKit in Docker, tests/ui/). Profile/notifications/app lock became a Settings page (#settings) and the avatar a Tabler dropdown.
  • 2026-10-02: Tabler consistency pass on branch cockpit (not deployed): one page-header on every page, Settings page + avatar dropdown, empty/error states, datagrid facts, table/pager (datatables look), invoice layout, tasks card-sm board, users table + activity feeds, tracking bars + steps for jobs/workflows, timelines (unit, project log), search-results groups, prose typography, form-selectgroup filters, widgets on Overview/Marketing. app-ui-check green (134 checks, WebKit iPhone 13 + SE).

  • 2026-10-02: LIVE (assistant 8580f54): Tabler consistency pass on every screen; overlays rebuilt as

    on sized from visualViewport (iOS sheet fix, cause not reproducible in WebKit — structural). app-ui-check (WebKit iPhone 13 + SE in Docker ee-ui-check image, 134 checks) is now the UI gate. Found: today's note not on website → Story 404 (investigating).

  • 2026-10-02: PO delete fails (400): ERP_TOKEN_ADMIN in ~/.config/assistant/env is the assistant-engineering user's token (purchase_order view only) — also the cause of earlier admin 403s on sales-order metadata; and no ERP group has purchase_order delete (Purchasing has view/add/change). Needs owner OK: create a real admin service user/token + grant Purchasing delete on POs. Sortable columns + gate repair + card overflow:clip (sticky header overlap in Chrome) in progress.
  • 2026-10-02: ERP permission change (owner: 'yes fix'): Purchasing group ruleset purchase_order can_delete=true (ruleset 74). Did NOT create an Owner-level admin token (chat assistant also uses ERP_TOKEN_ADMIN, which deliberately is the engineering service user); lifecycle actions now use each kind's department token. Backup 2026-10-02_1247 before the change.
  • 2026-10-02: LIVE (assistant 0eae0cc): sortable columns everywhere, sticky-header overlap fix (card overflow:clip), UI gate repaired (blocks service worker; 146 checks). Team chat API committed (5be3854); chat screens in progress (Tabler chat layout, MIT emoji picker).
  • 2026-10-02: LIVE (assistant 5430794): app is Home (/, /home → /app; old page /oldhome), team chat (DMs, department channels, emoji, files, SSE, push), notification bell inbox. Known: DM read ticks only ✓✓ after a live read event (API lacks other member's last_read); search hits don't scroll to message.
  • 2026-10-02: Home is the plain address home.embeddedera.com/ (no /app, no /home, no forwarding; owner). SW scope '/', manifest start_url '/'. Notifications must be re-enabled once per device. /oldhome kept.
  • 2026-10-02: Owner: tasks hard to close → simplifying to Done / Cancel (reason) / Delete (admin or creator) with checkbox, swipe, Undo, 'Done this week'; SOP-017 to be updated (owner overrides 'register sets Done'). Home-screen install at plain address confirmed working by owner.
  • 2026-10-02: Owner approved 3 task stages: To do → Doing → Done + Someday (old Backlog, hidden); List default everywhere; Kanboard columns migrated by kanboard-3stages (Backlog→Someday, Ready→To do, WIP→Doing, Review merged into Doing); task attachments + comments-with-files.
  • 2026-10-02: Tasks simplification: code done in sandbox (Done/Cancel/Delete+undo, attachments, review mode, List default) — safety check blocked the live Kanboard column migration + ops-script edits; waiting for owner's explicit 'go ahead with the task board migration'. Must update task-verify run_reopen_check (~line 590; reopens tasks closed without 'Verified') before Done ships, plus onboard (re-adds Review), now-build, tasks-digest, stock.py Backlog fallback.
  • 2026-10-02: Task board migrated (owner: 'yes'): all 9 projects → Someday / To do / Doing / Done, task counts unchanged (ops 4ece391, kanboard-3stages); task-verify timer disabled; intake close-out + stock confirm now mark Done (assistant 533afc8); SOP-017 v3.0 (Done/Cancel/Delete, no Review) deployed; sop-audit closed-unverified retired (ops b56c612). Backup 2026-10-02_1513 before.
  • 2026-10-02: LIVE (assistant f149211): simplified Tasks (List default, Done/Cancel/Delete + Undo, swipe, attachments, Someday review, quick-add, + button).
  • 2026-10-02: BUG fixed: tests used the production assistant DB (app loads ASSISTANT_DB via env setdefault) and pushed real notifications (286 fake 'Reminder sent' bell items, removed; backup /tmp/claude-1000/assistant.sqlite.pre-inbox-clean). conftest now pins a temp DB + stubs webpush; tests assert both. App auto-reloads after deploys (/app/api/version) — stale home-screen copy caused 'Close task' 404.
  • 2026-10-02: Owner: one way into the account (top-right avatar only, drop left 'Profile & settings'); remove Old Home (/oldhome) entirely; richer My account (photo shown everywhere, job title, phone, timezone, email signature, devices). Backend in progress; screens after part-edit work.
  • 2026-10-02: Released v2026.10.2 (02f1773): Parts: edit cost (price breaks, price paid), manufacturer and MPN, suppliers, and part details;My account: profile photo, job title, phone, time zone, email signature, your devices;Only your picture in the top right opens your account; Old Home removed;About page with version and What's new;Marketing: post previews show their pictures;Fixed: tests can no longer send you notifications; the app reloads itself after an update
  • 2026-10-02: Faster releases: pytest-xdist 3.8.0 (MIT) added to the assistant venv (record: no requirements file); app-release runs tests once with -n 4 (~1 min) and app-ui-check runs 3 device containers in parallel (~3.5 min); total ~5 min vs ~12. Pushed ops-scripts (12 commits) + erp-config (1).
  • 2026-10-02: Released v2026.10.3 (50e72f9): Fixed: the social artwork job stopped failing on four already-published notes, and now says why if anything fails
  • 2026-10-02: content-review-prep fixed (v2026.10.3): it re-prepared notes owned by the daily pipeline whose published source was edited → 409 'Future package source changed' every run; now skips notes with daily-source.json and reports reasons. UI gate Someday desktop check fixed (race).
  • 2026-10-02: Owner approved: 7 components set purchaseable=true in production ERP (were false, blocking suppliers/price breaks): EE-C-0098 (pk106), 0185 (203), 0186 (204), 0187 (205), 0188 (206), 0192 (210), 0194 (212). Undo = PATCH purchaseable false on those pks. Root cause of how they got false not yet traced (likely KiCad sync/creation path) — check kicad-erp-sync defaults.
  • 2026-10-02: Released v2026.10.4 (ee600fb): Parts: Price I paid works on every part with stock; parts marked not purchased say so and offer Mark as purchased;Seven components that were wrongly marked not purchased are fixed (EE-C-0098, 0185–0188, 0192, 0194)
  • 2026-10-03: content-buffer-fill crashed (rc=1) when Claude's capacity reading had reset_at null; now treated as unknown (ops 69a9547). Reserve after yesterday's refill: 4 of 7 ready days, 4 new notes in preparation.
  • 2026-10-03: Task 293 remaining: reserve refilling (4/7 ready days, buffer-fill fixed 2026-10-02/03); Story link verification 'not confirmed' (IG: no in-app browser host; FB: viewer not showing own Story) — helper diagnosing/fixing in story-publisher; then 7 consecutive verified days; due date to move accordingly.
  • 2026-10-03: Released v2026.10.5 (7bd29ed): Content: a late release now hands its Stories to the publisher and spaces them 20 minutes apart
  • 2026-10-03: Released v2026.10.6 (69ea681): Oddly: go-live no longer stalls when an approved listing is being restored; one failing design never blocks the others
  • 2026-10-03: Oddly pod-publish/pod-golive failed all day (rc=1): the 07:30 audit's snapshot restore republished the approved dog design (pets-gentle-watercolor…) and set restore_etsy:, then golive's attribution PATCH hit the approved-listing guard every tick and the crash blocked every other design. Fixed in assistant v2026.10.6: golive skips approved listings (the restore re-applies their Etsy fields) and isolates per-design failures. Calavera design went live 17:35. Open: dog restores still pending_publish (desk_mat, ornament); mug restore failed with Etsy 400 deleting image 8616930756 — next audit retries.
  • 2026-10-04: Released v2026.10.7 (1496b8d): Settings: a simple vertical list on phones instead of sideways tabs; every pane scrolls to the bottom;Menu: scrolls on its own, the page behind stays put and keeps its place;Marketing, parts, builds, tasks, stock: nothing cut off or sliding sideways; Overview tiles line up
  • 2026-10-04: Label/printing plan written by Codex (gpt-6-astra, web search + read-only whole-disk, write limited to the plan): label-printing-plan — proposal, reuses existing labels.py/zebra.py + InvenTree templates; phase 1 = one shelf + part labels.
  • 2026-10-04: Released v2026.10.8 (55714c7): Labels: Print label on any part, and Print location label / Print bin labels for a whole shelf in Stock — with a preview first
  • 2026-10-04: Released v2026.10.9 (610f2af): Labels: stock labels, and Print received labels on a purchase order;Paper: Print invoice, packing slip and work order to the shop's letter printer, with a preview first
  • 2026-10-04: Released v2026.10.10 (d62b4b7): Social posts: every picture must be new and show the note's own subject; repeats and generic pictures are stopped before posting
  • 2026-10-04: Released v2026.10.11 (b9d23e6): Social posts: the picture check also guards the hand-run Story step
  • 2026-10-04: Notes editing plan written by Codex (web search, read-only, one file): app-notes-editing-plan — proposal. Its finding fixed now: notes-sync exited on a clean index without pushing commits left by an earlier failed push (ops-scripts).
  • 2026-10-04: Codex plans: app-notes-editing-plan updated with owner decisions (WYSIWYG Milkdown, private+share/contribute, PDF/print/external link, iOS/Android/desktop, SharePoint-style version history) — pilot 8–11 days; new app-speed-plan (eager ~2.1 MB uncompressed; quick wins 4–8 h).
  • 2026-10-04: Released v2026.10.12 (fe040f3): Faster: the app downloads a third of what it used to, and reopening it is near-instant
  • 2026-10-04: Released v2026.10.13 (aabe2e6): Notes (pilot, owner only): My notes with a Word-style editor, drafts that save themselves, numbered versions with history and restore, and Edit on projects
  • 2026-10-04: v2026.10.12 speed phase 1 (eager 2.17 MB -> 0.83 MB, warm reopen 0 B ~0.2 s; app-release now has a speed budget gate). v2026.10.13 notes pilot (Codex-built): NOTES_EDITING=1 for adiaz@embeddedera.com only, isolated vault clone ~/.local/state/assistant/notes-vault (syncs via GitHub; maintenance via scripts/notes-sync-locked), Milkdown/Crepe editor, drafts, numbered versions/restore, project Edit; notebook-build privacy patch installed (ops). Next slices: sharing/contributing + compare, external share/PDF/print, SOP proposals.
  • 2026-10-04: Released v2026.10.14 (688b02b): Documents (not switched on yet): link Google Docs/Sheets to parts, builds, orders and customers, open them in Google, and publish a numbered PDF back into the app and the ERP
  • 2026-10-04: v2026.10.14 Documents (Codex-built; 2390 tests, 850 UI checks) released OFF behind DOCUMENTS_GOOGLE; owner setup: google-documents-setup. Rule changed to 'every task starts in the app' (company-operating-system-strategy decisions 1-3 adopted).
  • 2026-10-04: Released v2026.10.15 (25b6d62): Documents: connecting Google returns to the app, and the first New document walks you through allowing the template and folder
  • 2026-10-04: Released v2026.10.16 (70b57d2): Documents: Google's file picker opens on top, not behind the menu
  • 2026-10-04: Released v2026.10.17 (2e24d6c): Documents: allow all your templates in one pick
  • 2026-10-04: Released v2026.10.18 (1293057): Documents: its own tab next to Overview, BOM, Cost, Stock, Used in and Builds — everywhere;New documents fill in the part number, name, description, revision and BOM from the ERP; documents get a number and letter revisions (Rev A, B…) written into the document when you publish; Refresh from ERP
  • 2026-10-04: Released v2026.10.19 (caf6f0b): Documents: simpler New document — the one-time Google access step only appears if it's needed
  • 2026-10-04: Released v2026.10.20 (1cb4195): Photos: add a part's photo by pasting a picture link (or a product page), pasting an image, or the camera — always renamed to the part number
  • 2026-10-05: Released v2026.10.21 (e4c3230): Documents: Draft → Release Rev A/B/C with a change note; drafts stamped DRAFT; released files are frozen, attached to the ERP and locked in Google Drive;Machine files too: link pick-and-place programs, oven profiles and repo files and release them the same way; builds show exactly which revisions they were built with
  • 2026-10-05: Released v2026.10.22 (9714448): Documents: Undo a release for 10 minutes; admins can Withdraw a released revision (kept in history in red, earlier revision becomes current again, builds flagged); reissue an old machine-file revision
  • 2026-10-05: Released v2026.10.23 (9025af0): Suppliers: a Suppliers list in the menu and a New supplier form (address, contact, duplicate check), supplier page with parts supplied, purchase orders and documents
  • 2026-10-05: v2026.10.22 Undo/Withdraw for released controlled files (SOP-000 v2.2); v2026.10.23 Suppliers (list, New supplier, supplier page) — owner: 'it seems I cannot add vendors'. Both Codex-built, gated by Claude.
  • 2026-10-05: Released v2026.10.24 (256a3f3): Reports: new Reports menu — part health (with a badge on every part), assembly shortages, component risk, reorder list, unpaid invoices and margins; every row opens the part where it needs fixing; CSV export;Faster: rarely used screens (Reports, Marketing, admin pages) load only when opened — the app's main file is 19% smaller
  • 2026-10-05: Released v2026.10.25 (53818be): BOM in Google Sheets: Edit in Sheets checks the BOM out (everyone else read-only), Import changes shows exactly what changes, applies all-or-nothing with Undo;Parts in Google Sheets: edit a filtered set of parts (up to 500) the same way; new rows become new parts with the next part number
  • 2026-10-05: Released v2026.10.26 (085748a): Equipment: a list of shop machines (pick-and-place, oven, 3D printer, printers, tester) with their released programs and profiles, maintenance due dates and alerts;Check file: confirm the file on a machine is exactly the released revision
  • 2026-10-05: Released v2026.10.24 Reports (Sonnet) + lazy views (Sonnet; app.js gzip 135.8→110.2 KB), v2026.10.25 BOM+Parts Sheets round trip with check-out lock (Codex), v2026.10.26? Equipment + Check file (Sonnet). app-ui-check now retries failed scenarios once alone (FLAKY). Follow-up: external ERP writers (kicad-erp-sync etc.) must honour the check-out lock.
  • 2026-10-05: Owner decision: hide part Name in the app; show part number (IPN) + description everywhere (lists, search, titles, BOM/PO/stock/builds/reports, labels). ERP Name field kept untouched (KiCad library sync may key on it); search still matches names; new parts get a name auto-filled. Descriptions become the visible label — polish via AI-proposed review sheet later.
  • 2026-10-05: Released v2026.10.27 (f28488e): Parts now show as part number + description everywhere (lists, search, BOMs, orders, stock, reports, labels); names are hidden but still searchable
  • 2026-10-06: Released v2026.10.28 (774039d): Parts bulk edit is simpler: one card shows the two steps (edit in the Sheet, then Review and save)
  • 2026-10-06: Released v2026.10.29 (e96a61b): Buttons now show a spinner while they work, and a bar runs across the top when something takes a moment
  • 2026-10-06: Released v2026.10.30 (cc47470): Photo library: one picture per package (like Resistor 0603), applied to many parts at once;Units are now only pcs, m and g
  • 2026-10-06: Released v2026.10.31 (3d74cef): Jobs: a failed scheduled job is re-run once or twice when the failure looks temporary, and you are alerted only if that does not fix it;Jobs: every failure is logged as an incident and shown on the job page
  • 2026-10-06: Released v2026.10.32 (31c2ed0): Jobs: scheduled systemd timers are covered by failure handling too
  • 2026-10-06: Released v2026.10.33 (5d3352e): Jobs: failure alerts show the real cause line for systemd timers

  • 2026-10-06: Parts clean-up APPLIED to production by the owner (apply.py A engineering key, B/C/E purchasing key): 392 description/unit changes, 33 manufacturer parts + 6 maker companies, 11 merges, archive incl. Dashcam Drive + EE-P-0001-A; verify.py 690 checks 0 problems; manufacturer parts 128→161. Snapshot + changelog-prod-*.csv kept in ~/precious/erp-cleanup-2026-10-06/ (rollback source).

  • 2026-10-06: ERP_TOKEN_ADMIN fixed (owner request): new ERP user assistant-admin (not staff/superuser) in new group Administration = view/add/change/delete on part_category, part, bom, stock_location, stock, build, purchase_order, sales_order, return_order, transfer_order, no admin ruleset; token (1-year expiry, expires 2027-10-06) in ~/.config/assistant/env (backup env.bak-20261006-admin-token, 0600); company create/delete proven. Consumers: app.py admin token_role, adminchat reads, forms company create. scripts/invoice-bank-snippet.py needs staff (report snippet 403) so run it with the Owner token. lifecycle.py comment about ERP_TOKEN_ADMIN being the engineering user is now stale; lifecycle still uses department tokens by choice. Sandbox untouched (erp-sandbox rewrites all five keys with its own Owner token).- 2026-10-08: Released v2026.10.34 (3c8d7d9): Social posts that fail review are now revised and re-reviewed automatically (up to 3 tries, then one alert);Fixed: ESD and bring-up notes no longer get the USB power-meter picture
  • 2026-10-08: Released v2026.10.35 (6cf0375): Content writer, reviewer and revise step now run on the monthly API credits with a per-job budget (no more stalls when Claude is busy)
  • 2026-10-08: Released v2026.10.36 (7c1cd44): Job alerts now include a likely cause and how to fix it;Fixed: jobs that run every few minutes no longer page on a single hiccup;Post images get quick automatic checks before the paid review;API credits log shows cost per run and per passed result, by model
  • 2026-10-13: Released v2026.10.37 (e3cfc7f): Make › Boards: schematic, PCB, live 3D model and interactive BOM for each board, with Choose boards to pick which ones show
  • 2026-10-13: Released v2026.10.38 (77a5bf0): Boards: the interactive BOM remembers your Sourced and Placed ticks, fits a phone (list on top, one side of the board) and follows the app's light or dark theme;Boards: Full screen on the BOM now opens inside the app, with a Close button
  • 2026-10-13: Released v2026.10.39 (66d31ac): Fixed: build-order previews and BOM stock now count accepted substitute parts, so a line covered by an alternate (e.g. a 1% resistor for a 5% one) no longer shows a false shortage
  • 2026-10-21: Investigated "New build order does nothing": it is the unbuilt coming-next stub; BO-0002 "32 parts short" is an unallocated count with no allocate action in the app. Plan and handoff in Open.
  • 2026-10-21: Released v2026.10.40 (42a306a): You can now start a build order from Build orders;Build orders now allocate stock automatically when created, and an Allocate stock button with Undo handles the rest

  • 2026-10-21: Build orders: New build order sheet (assembly, quantity, date, batch, review, Confirm) creates, issues and auto-allocates; Allocate stock with Undo on any open order. Review fixes: a 5xx on create is parked as unknown (never re-posted), Undo refuses if the ERP was still allocating. Not done: daily write cap/audit log on Allocate stock confirm (same as stock moves); "New purchase order" is still the coming-next stub. SOP-006 v2.1.

  • 2026-10-21: Decided: no Issue button in the app. New build orders issue themselves at creation; the chat assistant can still issue a Pending order (build_issue). The Allocate stock button stays: allocation runs once at creation, so stock received later or freed by a cancelled order is not picked up until someone clicks it. Possible later improvement: allocate automatically on goods receipt.

  • 2026-10-21: Released v2026.10.41 (2183570): Production tests now fill several open build orders one after another
  • 2026-10-21: Tester API (v2026.10.41) now fills several open build orders for one product oldest first (a slot per output of any state); it used to need exactly one. BO-0002, 0003, 0005 (9 boards each) fill in that order and each auto-closes when clean. SOP-006 2.2.
  • 2026-10-24: reconcile-gaps commit 1206659: seven-day missed-release check (floor 2026-10-24); failed/cooldown/alerted drafts excluded from research reserve, reported as stuck_note_slugs. Focused tests 64 passed. Full suite in network-disabled bwrap with live home hidden: 2991 passed, 18 skipped, 14 failed (13 hidden department data/read-only asset store dependencies; one unchanged desk-mat pricing assertion, 3599 vs 3000). No deployment. Work stayed local because the available helper route cannot enforce SOP-025 tool confinement.
  • 2026-11-01: Store tab built (cockpit 6c041d5 + 0700a56; merged production main into cockpit). Local check at 375/1440, light/dark: no overflow, no console errors. NOT released: app-release refused for Claude (production deploy) and the full suite has 2 failures that are already on production main and unrelated: test_content_approval::test_new_approval_schedules_each_platform_at_snapshotted_time (409 schedule in the past, date-dependent) and test_fastshop_drive::test_price_lands_in_the_band_but_never_below_margin_or_floor (desk_mat 3599 != 3000).
  • 2026-11-01: Fixed the 2 stale tests on cockpit (38d94af): content schedule test now uses 2099-12-01 (fixed 2026-11-01 date went past); desk_mat price test expects 3599 (owner $35.99 floor 2026-10-24). Release dry run passes: 3032 tests, UI gate 56/0, would ship v2026.11.1. Owner runs app-release (refused for Claude).
  • 2026-11-01: Released v2026.11.1 (846650c): Marketing: new Store tab shows store orders, revenue, units, the shop funnel and where orders came from
  • 2026-11-02: Released v2026.11.2 (1ec6d0e): Reports: new Website group — pages where visitors hit dead clicks, rage clicks or quick exits (from Microsoft Clarity), clicks toward Contact/Quote/Book, and form drop-off;Reports: new Code & GitHub group (admin) — pull requests waiting, merged this week, work not merged yet on the server, and what was done this week
  • 2026-11-02: v2026.11.2 released (Reports: Website + Code & GitHub; tests 3053, UI gate 1829/0, speed 6/0). Site PR #15 merged + deployed. PageSpeed to-do was stale: key present, scores stored daily.

Task #351 — surfaces-check recovery, 2026-11-04

Yesterday’s eight gate findings all had synthetic HTTP status 0 (no HTTP response), incorrectly described as served without login. Corrected classification in ~/.local/bin commit 5486af8: network errors, HTTP 5xx and unexpected responses remain failures with accurate diagnostics; a real unauthenticated HTTP 200 still fails. Existing bounded retry unchanged. Six offline regression tests pass and fail against the previous checker. Real systemctl --user start surfaces-check.service completed 06:22:19 Eastern with Result=success / ExecMainStatus=0: eight gates 403 challenged, Home/Chat render, all scripts parse, 31 API tiles. Exact historical network subtype is not recoverable because the old checker discarded its error detail. Task #351 closed with verification. - 2026-11-06: Released v2026.11.3 (6bee106): Reports › Website › Visitors by company: company networks that visited the site, with pages, time and forms; tap one to see its visitors - 2026-11-07: Boards part picking built on cockpit (assistant 1223c8a, not released): click a part in the schematic or PCB (KiCanvas) → lit orange in the 3D model, camera turns to it, label "R49 · 10k"; click a part in 3D → selected in the schematic; the BOM row follows; × clears everywhere. Schematic/PCB tabs show the 3D beside the drawing (above it on a phone). Owner chose part-level only, no pins (pins = pad rings from .kicad_pcb + net, possible later). Kept model-viewer (spike: reaching its three.js scene works on pinned 4.3.1; recheck on upgrade) instead of three.js. KiCanvas's select event fires on its internal viewer object, not the DOM: hooked through shadow roots. Gate: tests/ui/board_highlight.py (two-part fixture board, real KiCanvas + model-viewer, WebKit + Chromium), wired into app-ui-check under the board term. - 2026-11-08: Released v2026.11.4 (3a4c9b5): Boards: click a part in the schematic, PCB or 3D and it lights up in the other views;Boards: one-screen workspace on a computer, with a single 3D beside the drawing tabs;Boards: drawings in KiCad's own colors, with the layer picker in the sidebar - 2026-11-08: Boards part picking shipped in v2026.11.4 (owner approved, handoff removed). KiCanvas facts: embed ignores theme attr (seed localStorage kc:prefs:theme before import); it clears the selection after load (reselect); selection is white (override selection_color). Bottom/top of a 3D part = body direction from its origin, not origin height. - 2026-11-11: Released v2026.11.5 (2909c98): Phone: the menu is now a bar along the bottom (Overview, Tasks, Chat, Parts or Invoices, and Menu for everything else); on a computer it stays on the left