embeddedera-site¶
The EmbeddedEra web presence: embeddedera.com (registrar Squarespace ex-Google Domains, DNS at Google nameservers, site on WordPress.com, mail on Google Workspace), its subdomains, and the eventual static site + store page.
Repo: ~/embeddedera-site → github.com/angelEmbeddedEra/embeddedera-site (private) — the step-by-step guides live there (docs/01…05); to-dos live here.
Pick up here (read this first in a new session)¶
State on 2026-10-15 (release cc1b188, rollback target 72d47ac). Live: service-page template src/pages/services/[slug].astro with /services/pcb-design (wave 1 next: firmware, SMT, test fixtures, R&D, obsolete parts); site search (MiniSearch, Ctrl/Cmd+K, scripts/search-index.mjs); privacy page without product names; master lists in src/lib/facts.ts (chip families, connectivity, SMT limits, test checks, PCB deliverables, service names, platforms, CAD formats, …) — add or change a fact there, never in copy; scripts/check-repeats.mjs warns on repeated lists (allow-list scripts/check-repeats.allow.json). Owner copy rules: no ownership claims, no lead time, no layer counts/turnaround/minimums, KiCad only, privacy names no products or tools (Clarity once).
What it is. embeddedera.com IS the Astro 5 + Tailwind v4 static site on Cloudflare Pages (cutover 2026-09-11 ~07:30 ET), with Pages Functions for the two /api/* endpoints. WordPress.com is no longer served; cancel the plan after 2026-09-18.
Where the code is (on the Plex box).
- Repo: github.com/angelEmbeddedEra/embeddedera-site (private). Two local checkouts of the same repo:
- ~/embeddedera-site — branch main = PRODUCTION (what embeddedera.com serves). Only receives merges from the dev branch. Tag v1-mirror = the old WordPress-mirror version.
- ~/embeddedera-site-notes — branch notes-queue = DEV; all new work happens here (git worktree). 17 pages EN+ES, 12 services in 5 families, quote/contact forms, uploads.
- Key files: src/i18n/{en,es}.ts (ALL copy, both languages), src/site.ts (business facts, socials, nav, WEB3FORMS_KEY, BOOKING_URL, SERVICES), src/pages/*.astro (EN) + src/pages/es/*.astro (thin wrappers), src/layouts/Base.astro (SEO, JSON-LD, hreflang), src/lib/quote-form.ts (form logic), functions/api/{upload.ts,file/[key].ts} (R2 uploads), public/{_headers,_redirects,_routes.json,robots.txt,llms.txt}, scripts/{deploy.sh,llms.mjs,og.mjs,icons.mjs}, docs/*.md (guides + spanish-review.md).
Previews / hosting.
- PRODUCTION: Pages project embeddedera-apple, production branch main, custom domains embeddedera.com + www (DNS: proxied CNAMEs to embeddedera-apple.pages.dev; the old WordPress A records 192.0.78.24/25 were deleted). R2 binding UPLOADS + secret UPLOAD_SECRET.
- DEV preview: Pages project embeddedera-site, production branch notes-queue → https://embeddedera-site.pages.dev (same R2 binding/secret, shares the uploads bucket).
- LAN preview of main: user unit site-preview.service → http://site.lan (NPM proxy host).
- REVERT (if ever needed): delete the two CNAMEs and re-create A embeddedera.com → 192.0.78.24 and 192.0.78.25 (proxied), CNAME www → embeddedera.com; WordPress.com must still be active.
How to build and deploy.
Since 2026-10-12, a push deploys (GitHub Actions .github/workflows/deploy.yml, both branches): push notes-queue → dev preview, push main → production + IndexNow. Works from any machine (the Mac included); repo secrets CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID, INDEXNOW_KEY. Actions → Deploy → Run workflow previews any branch on the dev project. publish-note and weekly-research now pull --rebase before committing/deploying so a Mac push is never rolled back. The manual commands below still work from the server.
cd ~/embeddedera-site-notes && source ~/.nvm/nvm.sh
npm run build && npx astro check && npm run check:functions
set -a; . ~/.config/cloudflare/env; set +a
bash scripts/deploy.sh embeddedera-site notes-queue # DEV preview (from ~/embeddedera-site-notes)
# release: cd ~/embeddedera-site && git merge notes-queue && git push && npm ci && bash scripts/deploy.sh embeddedera-apple main # PRODUCTION
wrangler inside the repo root (its autoconfig rewrites astro.config); never wrangler deploy (that is Workers, not Pages).
Services and where their keys live (all 0600, also in Vaultwarden):
- Cloudflare API token claude-plex (Pages, DNS, Access, Analytics read, Email Routing rules, Bot Mgmt, R2): ~/.config/cloudflare/env (+ CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_ZONE_ID, UPLOAD_SECRET).
- Web3Forms access key (forms → email to hello@; free plan = browser submissions only, no autoresponder): ~/.config/web3forms/env; the key is also public in site.ts by design.
- R2 bucket embeddedera-uploads (ENAM, 90-day auto-delete). hCaptcha via Web3Forms' shared sitekey (no account).
- cal.com: https://cal.com/embeddedera/20-minute-call (account adiaz@). Uptime Kuma: monitor #11, login in ~/.config/credentials/kuma.txt, client venv ~/.local/share/kuma-venv.
- Email: hello@ (public), alerts@ (machines), plus purchasing/sales/info/marketing/billing/socialmedia — all Workspace aliases on adiaz@. Gmail label EmbeddedEra/Leads. Claude's connectors: Gmail = adiaz@ (Workspace; verified 2026-09-11 — the [EE-] emails are there), Google Calendar = angelgdo7@gmail.com (the training calendar).
- Google Business Profile (verification pending), Bing Places, Cloudflare Web Analytics (auto-inject after cutover), DMARC p=none, AI-crawler blocking OFF on the zone.
How the work gets done. Orchestrator session + one Sonnet builder at a time (general-purpose agent, model: sonnet; the worker/scout agent types are not visible to the Agent tool in these sessions). Brief → builder edits the worktree without committing → I build/check, commit, push, deploy, verify with curl. Copy changes go in BOTH dictionaries. Apple-style rules: one idea per screen, big type, our dark palette (bg #0b0d10, copper #c8813f), no cards, pill + "›" links, "we" voice (About uses "I"), no pricing, no equipment brands, no client names, no board counts.
Decisions on file: website-stack (Astro + Pages, own components, no theme), Real Cow product parked, pricing off the site for now, standards line pending research, WordPress content mirrored then superseded.
The record set to recreate on Cloudflare (inventory 2026-09-10)¶
| Type | Name | Value | Proxy |
|---|---|---|---|
| A | @ |
192.0.78.24 | DNS only (WordPress.com terminates TLS) |
| A | @ |
192.0.78.25 | DNS only |
| CNAME | www |
embeddedera.com | DNS only |
| MX | @ |
1 aspmx.l.google.com · 5 alt1.aspmx.l.google.com · 5 alt2.aspmx.l.google.com · 10 alt3.aspmx.l.google.com · 10 alt4.aspmx.l.google.com | — |
| TXT | @ |
v=spf1 include:_spf.google.com ~all |
— |
| TXT | google._domainkey |
v=DKIM1; k=rsa; p=MIIBIjAN… (copy the full value from the current DNS panel — long) |
— |
| TXT | www |
same SPF (harmless duplicate) | — |
Not present today: DMARC (_dmarc), AAAA, CAA. Add _dmarc TXT "v=DMARC1; p=none; rua=mailto:adiaz@embeddedera.com" after the move — observe-only, no risk. |
Planned subdomains¶
tesla→ Cloudflare Pages projecttesla-key(Tesla Fleet API public key host)store→ the store (eBay store link now; own shop later)angelor root → portfolio when published
Gotchas¶
- Mail is the only thing that breaks on a bad migration: the five MX + SPF + DKIM must be present on Cloudflare BEFORE the nameservers change. Cloudflare's import scan usually finds them; verify each against this table.
- Keep the WordPress.com A records "DNS only" (grey cloud) at first; turn the proxy on later only if WordPress.com's SSL keeps working.
- Changing nameservers ≠ transferring the registrar. The domain stays registered at Squarespace; only DNS hosting moves.
Handoff 2026-10-29: Work / case studies (read this to continue)¶
Done. /work is LIVE with only the kitchen panel case study (main d03bad5, Deploy success, EN + /es). Other 4 studies are draft: true in src/content/work/.
In progress. Branch cow-visuals (worktree ~/embeddedera-site-work, commits 69ca3dd + 6e4fbc2, pushed 2026-10-29, draft PR https://github.com/angelEmbeddedEra/embeddedera-site/pull/13, NOT merged), off main d03bad5. Adds to livestock-robot-controls.md: link/failsafe SVG, ACK dot chart (85.9 -> 97.0 vs 99.5 gate), test-station LED strip, pick-and-place video (1.2 MB), and "It started on an 8-bit PIC" paragraph (PIC18F46K22, from ~/Cow_Robot_Board/hardware/Robot-Cow-004B/production/Robot_Cow_2024-01-14_*/bom.csv, U2), period now "2024 – present". Removed the link to /work/universal-tester/ (draft). The study is still draft: true on the branch; previews are built by flipping it to false uncommitted, npm run build, copying dist+functions to a temp dir, npx wrangler pages deploy dist --project-name embeddedera-site --branch cow-visuals, then reverting. Preview: https://cow-visuals.embeddedera-site.pages.dev/work/livestock-robot-controls/
Checks passed. npm run build (check-seo etc.) rc 0 with the study un-drafted; preview 200 + noindex; phone width 390 no horizontal scroll.
Gotchas. scripts/deploy.sh hung once in astro build (19 min, ~0% CPU); wrap builds in timeout 450. notes-queue is ~189 behind main: branch from main.
Open questions for the owner.
1. Ownership wording in the cow study ("our own pick-and-place line", "equipment we own") vs the no-ownership-claims rule.
2. OK to describe the client as "Equine training equipment manufacturer"?
3. Use a KiCad board render (module label blurred)? Not used yet: page says board files stay with the client.
4. Was the remote also PIC18 at first? Only the robot controller BOM was found.
5. Diagram text is small on phones: make diagrams open full size on tap (cow + kitchen panel).
6. Kitchen panel: confirm lights by room, round thermostat dial, timer rings, 5" nightstand panel.
Next action. Owner answers 1–2 (and 3 if wanted) -> apply copy fixes on cow-visuals, set draft: false, build, push cow-visuals:main (fast-forward; fetch main first), watch the Deploy run, curl production /work/livestock-robot-controls/.
Open¶
- Browser circuit simulator for /tools/ (owner asked 2026-11-11): plan and decisions in circuit-sim; next is the phase 0 spike.
- Gerber viewer ranking (market brief 2026-11-09): /tools/gerber-viewer/ has 85 impressions at position 44.5 and 1 click in Search Console; improve page copy and internal links. Source: projects/market-brief/site-data-2026-11-09.md
- Spanish thermistor page (market brief 2026-11-09): /es/tools/thermistor/ is at position 9.1 with 12 impressions, 1 click; tune the Spanish title and text to hold page 1. Do it together with the existing Spanish-read to-do for this page. Source: projects/market-brief/site-data-2026-11-09.md
- Check /quote/ dead clicks (market brief 2026-11-09): Clarity shows dead clicks in 50% of sessions, last 3 days, only 2 sessions; find what visitors click that does nothing. Source: projects/market-brief/site-data-2026-11-09.md
- Visitor insights (live 2026-11-06, PR #16): confirm
/api/admin/visitorloads behind Access on embeddedera.com and a real inquiry email showsvisitor_history(site-measurement rows 17-18). App Reports page for companies: later. - Lead attribution (market-brief outcome tracking, 2026-11-02): add
from=<note slug>to each note's offer link (/quote/, /bom-check/) and store it on /api/lead + bom-check sonote-outcomescan count leads per note. Until then outcomes = Search Console clicks/impressions only. Script: ~/.local/bin/note-outcomes; ledger: Notes/projects/market-brief/outcomes.md. - New tool (market brief 2026-11-02): I²C pull-up calculator — R range from bus capacitance, rise time (100k/400k/1M mode) and Vdd/sink current, using shared src/lib/calc.ts + schematic.css, EN+ES. Pairs with the backlog worked-example note "sizing an I2C pull-up". Context: already in the ranked next-tools queue (2026-09-30 log). Sources: NXP UM10204 I²C spec; TI SLVA689.
- Review branch
design-skills(Mac worktree ~/embeddedera-site-design, commit 80d0ac0): design pass from the Impeccable + Emil Kowalski skills; push +gh workflow run deploy.yml --ref design-skillsfor a preview, then merge into notes-queue if approved. - Owner: decide whether to publish the other 4 case studies (draft: true in src/content/work/; boost-gauge, cricket, universal-tester, livestock-robot-controls = anonymised client work). Before any goes live: UT body quotes board counts (53/28, no-board-counts rule), livestock says "our own pick-and-place line" (ownership-claim rule). Kitchen-panel copy still names features to confirm (lights by room, round thermostat dial, timer rings, 5" nightstand panel). Next after that: link each service page to its case study (HMI -> kitchen panel).
- Trace Rush follow-ups: (1) cleanup done by owner 2026-10-26; (2) links LIVE 2026-10-26 (main 8ff8e56, run 40360667398 success; footer Game/Juego + /tools/ 'Need a break?'; local worktree/branch removed, remote branch game-links left); (3) native Spanish read of the
playblock in src/i18n/es.ts; (4) owner tries it on iPhone Safari. - Seasonal themes — HANDOFF 2026-10-26: LIVE on embeddedera.com (PR #10 merged, fc36a27; production e2e passed). Files: src/lib/seasons.ts (table: dates/rules, accent, icon, fx, greeting EN/ES), src/lib/season-boot.js (inlined in via ?raw in Base.astro), src/lib/season-scene.ts (home hero canvas), public/season-icons.svg, Nav.astro (icon + .season-strip), index.astro (greeting + canvas), SEASONS_ENABLED in src/site.ts. Checks:
node scripts/seasons.test.mjs;PW_EXECUTABLE=/usr/bin/google-chrome uv run --with playwright python scripts/seasons.shots.py <base>. Preview any theme:?season=<id>,?season=off. Open: (1) owner to give shop-closure dates if a 'closed' line is wanted (not built; would be a field in seasons.ts + line under the greeting); (2) icon tweaks on request; (3) notes-queue does not have this yet — it arrives on the next notes-queue↔main merge; (4) cleanup:git worktree remove ~/embeddedera-site-seasonsand delete branch seasonal-themes. Next action: none required; wait for owner feedback after seeing Halloween live. - Eugene 5th/6th emails (2026-10-27 18:36 + 19:41, thread 1a166e861b5ef8f7): (1) REGRESSION: commit 01f46cb (released 10-23) changed searchPairs' dedupe key from mantissa pair to ratio, so equal-ratio pairs vanish (op-amp non-inv gain 2.5, E24, 10k-100k: 7 exact pairs before, 1 now; same on divider without load/Max error, regulator with bias 0). Fix: collapse only same-mantissa decade copies, keep the clamp case working; his case into calc.test vs brute force; e2e divider/regulator/opamp. (2) Op-amp Max error field like the divider. Then reply with mail-draft (unsent) on his 19:41 message: say yes, we changed it on the 23rd.
- New tool (Eugene 10-27): three-resistor ratio finder — standard R1,R2,R3 for target R1:R2 and R1:R3, peak ratio error, any series; modes: two-resistor ratio (his item a), switchable two-attenuation divider (change-over R2a/R2b, or parallel add-on with A2<A1). Acceptance: R1/R2=0.6941236, R1/R3=2.6537024, E96+E24 → 39k/56.2k/14.7k at 0.025 %.
- New tool (Eugene 10-27): divider with offset / Y level shifter — inputs Vin min/max, Vref, Vout min/max; outputs ideal R1:R2, R1:R3, Vref_min, currents in R1/R2/R3 at both Vin ends; verify mode (R1,R2,R3,Vin,Vref → Vout + currents); hands ratios to the 3-resistor finder. Math (checked against his example): a=ΔVout/ΔVin, b=Vout_min−a·Vin_min, R1/R2=(1−a−b/Vref)/a, R1/R3=b/(a·Vref), Vref_min=b/(1−a) (=3.247 V for ±10 V→0.2-4.8 V).
- Cleanup (blocked by the permission classifier 2026-10-23):
git worktree remove ~/embeddedera-site-sort ~/embeddedera-site-regv2, delete local branches tool-sort-tables, tool-regulator-v2 (both merged), check ~/embeddedera-site-dividersort (tool-divider-sort, released earlier) before deleting. Preview aliases tool-regulator-v2 / tool-sort-tables remain on Pages (harmless). - Thermistor calculator (free browser tool): Beta vs Steinhart-Hart, divider and ADC error, self-heating; pairs with the 2026-10-22 thermistor note. Picked in market brief meeting 2026-10-22. Sources: https://www.analog.com/en/analog-dialogue/articles/thermistor-temperature-sensing-system-part-2.html · https://news.ycombinator.com/item?id=49950653 · https://www.eevblog.com/forum/beginners/little-more-accurate-ntc-measurement/msg4192198/
- Free browser tool: Web Serial / WebUSB device flasher and configurator (no installer). Picked 2026-10-19 market brief. Context: backlog note "Browser-based device tools"; radar saw a WebUSB thermal camera https://hackaday.com/2026/10/15/a-thermal-camera-that-uses-webusb/ ; pair with the note, link from /tools/. Check for an existing MIT library first (esptool-js, WebUSB DFU) per hard rule 1.
- Spanish read of /es/tools/thermistor/ and /es/tools/thermocouple/ (Sonnet translation, live since 2026-10-16). Also check the "≈0.2 °C per 1 % R error" thermistor pitfall line (derived 0.01·T²/B, no datasheet source) and the misplaced impedance lines in public/_redirects (a /tools/led-resistor line in the /es block).
- Marketing/Google audit 2026-10-26 — ranked list, evidence and owner/Claude split in embeddedera-site/seo-audit-2026-10-26 (replaces the 2026-10-15 plan; its items 3 NDA, 4 case studies, 5 About photo/LinkedIn, 6 geo/founder and 8 Manufactured in NC + LinkedIn page were still undone on 10-26). Owner: (a) Search Console Request indexing for /services/pcb-design/ (not indexed) and /services/ (last crawl 2026-07-19); (b) DONE 10-26 GOOGLE_API_KEY back — owner saves it in Vaultwarden; (c) GBP booking link → /book/ + ask 3–5 clients for reviews; (d) free listings: Manufactured in NC, Thomasnet, LinkedIn company page, Clutch, Apple Business Connect; (e) decide case studies without client names, About photo, NDA line, Cloudflare email obfuscation, social resume; (f) test-subscribe to the newsletter. Claude (one branch + preview, owner says merge): service + Book-a-call links on every tool/note with cta_click, lazy captcha on /quote/ (LCP 10 s), ES→EN link fix, breadcrumbs on services/notes, immutable /_astro cache, image sizes, /shop/ noindex, /sitemap.xml redirect, llms.txt slashes, /book/ contrast; then a clean PageSpeed re-test. Claude items 1–8 RELEASED 2026-10-26 (PR #11, main 1559c00, production checked). Left for owner: (a)–(f) above, plus Search Console Request indexing for the 8 /services/
/ pages; PageSpeed re-test once GOOGLE_API_KEY is back. - Ship /tools/impedance (picked in brief meeting 2026-10-15): already built on branch
tool-impedance(commit 97cf17c, worktree ~/embeddedera-site-impedance), pushed, not merged or deployed. Next: owner looks at the preview, then merge to main (a push deploys). Add a note link back from a 90 Ω USB answer. Source: https://forum.kicad.info/t/diferential-pair-impedance-setup/72023 - New free tool: coin-cell pulse budget calculator (picked in brief meeting 2026-10-15): inputs are the radio's peak current and burst length, the cell (CR2032 etc.) internal resistance against temperature and age, and the brownout threshold. Outputs are the voltage sag, the reservoir capacitor needed (C = I·t/ΔV, plus cap ESR) and the battery life with pulse derating. Look for an existing MIT calculator before writing one. Sources: https://hubble.com/community/guides/designing-ble-products-for-coin-cell-operation-from-chip-selection-to-power-budget/ · https://devzone.nordicsemi.com/f/nordic-q-a/58176/low-power-beacon/235820 . Pairs with the sleep-current note.
- Site search, second engine (only when triggered): search is MiniSearch (typo-tolerant, in-browser, branch
site-search, 2026-10-15). Add Pagefind as a separate 'More in articles' section (do not merge rankings) when the MiniSearch index passes ~150 KB gzipped per language (~1,000+ notes) OR the zero-result log shows searches for words that exist deep inside notes. Server option beyond that: self-hosted Meilisearch. - Google Business Profile — VERIFIED. Done 2026-10-15 in the owner's Chrome (Browser 2 Linux): description rewritten to the Clayton rule (approved), categories + Engineering consultant + Electronics manufacturer (pending review), home address hidden (now 'No location; deliveries and home services only', 7 service areas kept, live), service 'Existing design takeover' added (pending, up to 1 day); booking link cal.com and website/socials were already set; hours stay 'open with no main hours' (owner), no public phone (owner). Still open: photos (6 watermarked shop photos + logo + cover) — the GBP photo uploader is a cross-origin iframe the Chrome file_upload tool cannot reach (first attempt dropped the files into Google's search box, nothing submitted); owner uploads from the phone. Review link: https://g.page/r/CRHQxPFIjBm9EBM/review (capital I; verified it resolves to place 0xbd198c48f1c4d011). Review request to Paul Hale saved as a Gmail draft (own words, no ghostwritten review: Google prohibits business-written reviews). Profile URL in sameAs DONE 2026-10-15 (GOOGLE_BUSINESS_PROFILE in src/site.ts, structured data only). Owner uploaded the shop photos + logo 2026-10-15. cal.com bio + location fixed to Clayton 2026-10-15 (verified on cal.com/embeddedera); Paul Hale review request sent by the owner 2026-10-15. cal.com conflict checking: adiaz@embeddedera.com and angelgdo7@gmail.com primary calendars ON; Family/Bee/Birthdays/Alquiler/F1 OFF; owner's other work calendar not yet connected (address unknown).
- LinkedIn company page: owner decides/creates (needs personal admin account); Claude writes About text, adds to SOCIALS in src/site.ts.
- Apple Business Connect listing (free) after the Google Profile is verified.
- Owner/lawyer: review https://embeddedera.com/terms/ ('Free online tools' section, drafted 2026-09-30).
- STM32 flasher is LIVE but still untested on real hardware (owner chose go-live 2026-10-10). Next time an STM32 board with DFU is on the bench (e.g. Black Pill: hold BOOT0, tap reset; Windows needs Zadig WinUSB once), flash a bundled MicroPython fixture in Chrome/Edge and confirm flash + verify + run; any failure → unlist again (tools.ts listed:false, noindex prop, sitemap filter).
- PARKED (owner, 2026-09-30): signed EmbeddedEra firmware package
.eefw(manifest with exact part/DEV_ID, flash size, product, version, per-image SHA-256, Ed25519 signature;ee-packCLI; flashers accept only .eefw in production mode) and the device-side fix for wrong-firmware bricks over ST ROM DFU (own bootloader: MCUboot + TinyUSB/Zephyr USB DFU, hardware-ID + signature check before erase, A/B slots with rollback, WRP on the bootloader, own USB PID; later disable ROM boot entry via nBOOT0/nSWBOOT0, RDP1). Trigger: a customer again flashes the wrong image, or a product with field updates. Plan written in the 2026-09-30 session.
See ~/Notes/tasks.md — this section is now generated from the task register.
Measurement questions and their sources: site-measurement.
Booking — LIVE since 2026-10-23 11:50 (was: handoff)¶
Read this, then continue. PR #6 (angelEmbeddedEra/embeddedera-site, branch feat/booking, worktree ~/embeddedera-site-booking) replaces cal.com. Plan/handoff in the repo: docs/booking-handoff.md, README › Booking.
Done and verified on preview (https://feat-booking.embeddedera-site.pages.dev): public booking, Calendar event + Meet, confirmation + invite (Gmail Primary), alert to adiaz@, reschedule, cancel, admin page behind Access, private link 20/40/60, 40-min booking. All test bookings cancelled.
Infra in place: Google OAuth = project EmbeddedEra Documents (197835953119), refresh token ~/.config/google/booking.env; Turnstile widget keys ~/.config/cloudflare/booking-turnstile.env; per-env keys ~/.config/cloudflare/booking-secrets.env; D1 ee-bookings (live, f2bcb0e2…) + ee-bookings-preview (22fa0f8b…); Pages vars set on embeddedera-apple production + embeddedera-site preview; Access apps "Booking admin (/admin, /api/admin)" (live, embeddedera.com first) and "Booking admin preview" (feat-booking host first). Calendars in BOTH DBs: Work (Google primary, write) + "Afex calendar", "Personal" (angelgdo7 secret iCal), "Family" (secret iCal) — all ICS, encrypted; Google free/busy sharing of angelgdo7 never worked (notFound), secret iCal used instead. Token claude-plex now has Turnstile Edit.
Open, in order:
- [x] After go-live: cal.com event types all hidden 2026-10-26 (owner; 20-minute-call + secret links answer "page could not be found"). GBP booking link → /book/ DONE 2026-10-26 (owner); task #142 text → embeddedera.com/book DONE 2026-10-26.
- [ ] Owner: add booking-secrets.env, booking-turnstile.env, google/booking.env to Vaultwarden.
- [ ] Optional: revoke preview private link "Angel test"; Gmail display name for adiaz@ if customers should see "EmbeddedEra"; Outlook Afex publish → "busy only"; ee-meet: keep event description in calendar.json (CalendarPrompt in frontend/src-tauri/src/calendar/mod.rs) + html-unescape <.
- [ ] HANDOFF 2026-10-24 — contact/booking/inbox plan, phase 1 (booking speed). Read this, then continue.
- Plan (owner "go" 2026-10-24): (1) booking speed, (2) Contact page = hub (Book a call / Message / Quote tabs, calendar inline reusing SlotPicker + BookingForm, copper "Book a call" button in NAV, /book/ stays, ES too; response-time line: keep the existing common.quoteResponseTime unless owner gives a promise), (3) one inbox: every entry point sends one [EE-…] email to hello@, Gmail label = source, app page "Inquiries" (~/assistant, sandbox branch first, SOP-031) shows it live with needs-reply derived from the thread, no new DB; fix the Gmail filter that labels GitHub ee-meet CI mail as Leads, (4) cleanup: clicks/ (no reader) drop or add to marketing-snapshot; triage 7 unmerged branches (assembly-quote, design-takeover, diagrams, feat/pid-simulator, service-pages-2, tool-check-visuals, tool-stm32-visual) with preview links.
- Phase 1 state: PR #9 (draft) https://github.com/angelEmbeddedEra/embeddedera-site/pull/9, branch perf/booking-speed, worktree ~/embeddedera-site-bookfast, preview https://perf-booking-speed.embeddedera-site.pages.dev . Files: migrations/bookings/0002_busy_cache.sql, functions/_lib/booking/{availability,db}.ts, functions/api/book/slots.ts (MAX_RANGE 15 d for DST), functions/api/admin/booking/calendars/index.ts, src/scripts/booking/{picker,book,api}.ts, scripts/booking-cache.test.mjs, scripts/booking-handlers.test.mjs.
- Checks passed: all 13 scripts/booking-*.test.mjs, check:functions, astro check 0 errors, build; browser EN+ES week nav, no console errors. Perf (scratchpad script, copy kept at ~/Notes/projects/embeddedera-site/bookperf.py; run uv run -q --with playwright python bookperf.py <base> 5): warm 0.57 s / slow 1.35 s; cold (>1 h rows) 1.76–2.23 s → warmer required.
- Warmer: ~/.local/bin/booking-warm, crontab line installed 2026-10-24 (every 5 min via cron-run), currently pointed at the PREVIEW; backup crontab.bak-20261024. Map card row added (schedules.md). Switched to https://embeddedera.com 2026-10-24 at merge (ba206cf).
- DONE 2026-10-24 08:1x: owner ran the live migration, verified busy_cache exists on ee-bookings; warmer first scheduled run 08:15 rc=0. Was: (a) owner runs the live migration (auto-mode blocked Claude): cd ~ && set -a && . ~/.config/cloudflare/env && set +a && npx -y wrangler@4 d1 execute ee-bookings --remote --file=$HOME/embeddedera-site-bookfast/migrations/bookings/0002_busy_cache.sql — verify with SELECT name FROM sqlite_master WHERE name='busy_cache' on ee-bookings (f2bcb0e2…); (b) test booking + reschedule + cancel on the preview must be done by the OWNER (Turnstile verification; Claude may not solve it) — owner approved the test 2026-10-24; (c) then owner says "merge": mark PR ready, merge, switch warmer to embeddedera.com, re-run bookperf on embeddedera.com, check live busy_cache ages stay <10 min over an hour, then phase 2.
- [ ] Idea (owner 2026-10-23): book with other people, e.g. Yara (later, owner 2026-10-23): /book/<host>/ pages + per-host private links. Design in chat 2026-10-23: hosts table (slug, name, email, calendar id, hours); free/busy + events via the existing adiaz@ token if the host is a Workspace user (domain free/busy; event on the host calendar needs a service account with domain-wide delegation via GAM or the host signing in once); host gets the alert email. Decide after go-live.
Log¶
- 2026-11-08 Booking time-zone clarity + reminders LIVE. Owner: add 15-min reminder, then merge. PR #18 merged (88a5184), deploy green; migration 0003 applied to ee-bookings first. 12-hour EN+ES, friendly zone with current time, host time on the form, emails 30 and 15 min before (POST /api/book/remind, run by ~/.local/bin/booking-warm every 5 min;
reminder_sent_at= latest send). Checked: all booking tests, astro check, check:functions, build; live /book + /es/book in browser (Chicago, NY), /api/book/remind 200 sent 0, booking-warm exit 0. First real reminder email not yet observed; check at the next booked call. - 2026-11-06 19:06 Booking hours narrowed by owner (admin page): Mon 11:00-13:00, Tue + Thu 13:00-16:00 ET, Wed/Fri/weekends off; limit 2 per day (perDay); min notice kept 24 h (1440, not the suggested 48 h); buffers 15/15, horizon 30 d unchanged. Verified live /api/book/slots: only Mon/Tue/Thu in those windows; Mon Nov 9 shows none (3 already booked > cap). Reason: leads booked without a conversation and stacked on one day.
- 2026-11-06: Visitor insights built (company field, company from email domain, page history per inquiry, network company, time on page, privacy EN/ES). PR #16 draft, see site-measurement.
- 2026-10-31: Merged design polish (items 1-5 only: mobile tap targets/no iOS zoom, contrast, hover gating + press feedback, no-JS reveal, centred case studies) to main via PR #14; production deploy run 41193371369 succeeded and verified live.
design-v2stays as the test branch (canvas pages, skills). - 2026-10-31: Case-study pages were pinned left (narrow column inside the full-width container, also on production). Centred the column on
design-v2(preview only). - 2026-10-31: Angel preferred the preview without GSAP. Reverted on
design-v2; the GSAP version is kept on branchgsap-test. - 2026-10-31: GSAP 3.15 added to the home page on
design-v2as a test only (no merge): split headline, scroll-scrubbed hero photo, count-up specs, unmasking capability photos, drawn steps line. Added to /licenses (GSAP standard no-charge license). - 2026-10-31:
design-skillsandcanvaswere cut from stale notes-queue (no search/seasons). Rebuilt both on current main asdesign-v2(preview design-v2.embeddedera-site.pages.dev). Code changes go to main via PR, not notes-queue. GSAP: hold until a direction needs scroll timelines. Testing stays Playwright Python + browser pane; playwright-cli not needed. - 2026-10-31: Built
canvasbranch with three no-rules home-page prototypes (A Datasheet, B Bench, C Signal) at canvas.embeddedera-site.pages.dev/canvas/, noindex, not linked. Waiting on Angel to pick a direction. - 2026-10-30: Picked Impeccable (pbakaus, Apache-2.0) as the site's design skill plus 4 of Emil Kowalski's (review-animations, break-ui, mobile-native, find-animation-opportunities); vendored in
.claude/skills/on branch design-skills. Brand guide overrides Impeccable's bans on eyebrows and the system font. Fixes: iOS form zoom (14px fields), 24px tap targets, schematic footer contrast 2.96->AA, motion easing/hover gating. - 2026-10-29 22:14-22:19 Owner asked for an SEO/GEO prompt to help a friend at LHG Industries rank like our site, asked whether showing the cow controls shares too much, and (having RealCow's permission to use their page) a permission-request page built from realcowtraining.com/videos to share. No note holds the outcome. TODO: record where the prompt and permission page were saved.
- 2026-10-30 Livestock/RealCow study, trust+ranking pass on cow-visuals: closing CTA on every work page (Book a call / Get a quote / service links, data-cta for tracking, EN+ES strings), optional
faq(visible + FAQPage) andservicesfields, BreadcrumbList; study got 4 FAQs, 4 service links, "from our shop in Clayton, about half an hour away". astro check 0 errors, check-seo/check-geo PASS. AT MERGE: link the study from /services/firmware, smt-assembly, test-fixtures, pcb-design and the home featured work (can't before: draft page = broken link); ask Paul for a quote + backlink. Owner inputs still missing: Paul quote, real numbers (units shipped, years in the field), remote-in-hand / arena photo of our hardware. - 2026-10-30 Owner: share preview should show the RealCow photo, not pick-and-place -> realcow-arena.jpg (1200x630 from RealCow_305 on LHG's site, thin blurred side fill) is now heroImage + og:image; work template passes heroAlt as imageAlt. Gotcha: og:image is absolute to embeddedera.com, so a shared preview link shows no image; for the shareable preview I built once with SITE set to the preview origin (uncommitted, check-seo fails on that build by design) and redeployed. Commit pushed on cow-visuals.
- 2026-10-30 Owner: removed "used with permission" (caption) and the top line now reads "Built with RealCow Training and LHG Industries"; exact chip (PIC18F46K22, PIC18F tag) removed, now "8-bit chip"; pick-and-place clip got an original synthesized country-style music bed (numpy, no license needed), unmuted. Commit pushed on cow-visuals.
- 2026-10-30 Owner: the labelled board gave away "our recipe" -> replaced with "What the controls do for the rider" (6 outcomes, no parts/layout), board render removed from the repo; RealCow clips now play with sound. cow-visuals pushed; preview redeployed. Lesson: case studies show outcomes, not board layout or part choices.
- 2026-10-30 Owner got permission to use RealCow's videos page; built the shareable version on cow-visuals: 2 arena clips from realcowtraining.com/videos (credited), "Shown with permission from RealCow Training and LHG Industries" line (new
partnersfield), Article JSON-LD with partners asmentions, board image capped at 700 px; removed the unmet 99.5% gate (text + chart), the pairing-gesture detail, board-revision counts and the pairing-record weakness. Quote slot left as an HTML comment for Paul. Still draft: true; preview https://cow-visuals.embeddedera-site.pages.dev/work/livestock-robot-controls/ (noindex). Waiting on Paul/RealCow OK. - 2026-10-29 22:10 Owner: the livestock case study should show that we work with LHG Industries and RealCow (overrides "no client names" for this study only; not the LHG visual style). Branch cow-visuals 7a90f32: title/summary/client name LHG + RealCow (EN/ES), new "Who we build it with" section linking realcowtraining.com and lhgindustries.com, labelled controller-board render (STM32G0B1 board, 9 numbered parts). Still draft: true; preview https://cow-visuals.embeddedera-site.pages.dev/work/livestock-robot-controls/ . Open: owner confirms the RealCow→LHG→EmbeddedEra chain wording and that Paul (LHG) is OK being named.
- 2026-10-26: Owner hid all cal.com event types; checked: cal.com/embeddedera lists none, /20-minute-call and /secret show "could not be found". Booking now only via /book/.
- 2026-10-26: Owner switched the GBP booking link to /book/; Claude updated Kanboard #142 (business cards) title + verify line from cal.com to embeddedera.com/book.
- 2026-10-26: GOOGLE_API_KEY restored in ~/.config/google/env (new key "EmbeddedEra PageSpeed", project embeddedera-documents, restricted to PageSpeed Insights API; NOT yet in Vaultwarden — bw CLI unauthenticated, owner to save). PSI mobile after release: /quote/ 91, LCP 3.3 s (audit ~10 s).
- 2026-10-26: Post-release perf, local Lighthouse 12.8.2 mobile (PSI keyless quota exhausted, GOOGLE_API_KEY still absent — not in env, Vaultwarden CLI unauthenticated): /quote/ 98, LCP 1.8 s (audit: ~10 s), TBT 60 ms; / 88, LCP 2.5 s, TBT 350 ms; /services/ 94, LCP 2.9 s; CLS 0 on all three.
- 2026-10-26: RELEASED SEO audit fixes (PR #11 → main 1559c00, deploy success). Production: pages 200, /sitemap.xml 301, /_astro immutable, Book + breadcrumbs, captcha lazy on 6 form pages. Worktree/branch removed. Found: play.e2e.py 404 check expects one /play/ link but the footer link (8ff8e56) makes two — test is stale, game checks pass.
- 2026-10-26 Trace Rush links RELEASED: footer 'Game'/'Juego' on every page + 'Need a break?' line at the end of /tools/ (main 8ff8e56, deploy run 40360667398 success; live /tools/ and /es/tools/ carry 2 links each). Owner asked next for more game ideas tied to the site.
- 2026-10-26 RELEASED Trace Rush (owner asked for a video game; recommended a PCB trace-routing snake, alternates pick-and-place catch / fix-the-board puzzle). /play/ + /es/play/, link from 404. main fast-forward 7de2931→f952101, deploy run 40358996552 success; production: /play/ /es/play/ 200,
scripts/play.e2e.py https://embeddedera.com0 failures. Files: src/lib/trace-game.ts (rules, unit test scripts/trace-game.test.mjs), trace-game-ui.ts (canvas/input), src/pages/play.astro,playblock in i18n. No new deps. No PR (gh pr create blocked by auto-mode; owner said merge directly). - 2026-10-26: Owner said deploy the SEO preview myself; deployed via Actions (local deploy.sh lacks CLOUDFLARE_API_TOKEN). Awaiting owner "merge" on PR #11.
- 2026-10-26: SEO audit fixes 1–8 built and merged into seo-audit-fixes (draft PR #11); battery-life CTA moved from /quote/ to /services/firmware/ (owner to confirm); preview deploy blocked for Claude by the auto-mode classifier, owner runs it.
- 2026-10-26 Marketing/Google audit (embeddedera-site/seo-audit-2026-10-26): Google 28 d 1,612 impr / 36 clicks / pos 21, weekly impressions doubling; service queries now show at pos 40–90 (zero on 10-15); 0 local queries; /services/pcb-design/ not indexed by Google or Bing; Bing index 9 → 54 of 152 (re-check done), Bing sees 0 backlinks; only 4 of 56 tools/notes link a service page, 0 link /book/; /quote/ LCP ~10 s (hCaptcha 971 KB). Bing SubmitUrlBatch for 16 service/contact URLs done. Technical basics clean on all 152 pages.
- 2026-10-26: Seasonal themes Idea 2 chosen by owner over Idea 1 (quieter); holidays swap the accent, base seasons on, Muertos + Pi Day in. PR #10.
- 2026-10-26 Booking month calendar LIVE. Owner: "Merge". PR #12 merged (7de2931, main had moved: seasonal-themes PR #10, no booking files touched, merge CLEAN); Deploy run 40347601915 green. Live checks on embeddedera.com: /book/ desktop + phone + /es/book/ no page errors, no horizontal scroll, choosing a time opens the form with the right time; /book/manage/ 200. Owner did not make a preview test booking first (backend unchanged; picker only).
- 2026-10-26 Booking picker follow-ups (owner): times "taking a lot of space" → compact grid (2 across beside the calendar, 4 on phone); "the next seems off" → Next step removed, tapping a time selects it and opens the form (Cal.com style, same as the old live page). Preview redeployed and re-checked desktop/phone/ES.
- 2026-10-26 10:50 Booking picker → month calendar + time list (owner asked for calendar style, then "simple and familiar"; chose Calendly-style month view over a week time-grid). Mockups ~/claude-remote/booking-{calendar,month}-mockup.html. Built on feat/booking-month (only SlotPicker.astro, picker.ts, strings.ts); month loads in ≤14-day windows, first matches prefetch; Next button confirms time. astro check 0 errors, 13 booking tests pass, preview checked desktop/phone/ES. PR not opened (blocked). Preview DB shows 8:00 AM slots (preview settings differ from live; not this change).
- 2026-10-24 08:50 Phase 1 LIVE. Owner tested book/reschedule/cancel on the preview 08:34–08:37 (verified: preview D1 bk_xtsrlo4vlkxtdjqb7nfc cancelled; Gmail alert + confirmation + new-time + cancelled emails). Owner "go ahead and merge" → PR #9 merged ba206cf, Deploy run 40094765396 success. Warmer crontab now https://embeddedera.com (backup ~/crontab.bak-20261024b), first manual run rc=0. Live bookperf (5 fresh browsers, 2 rounds): median to first slot 0.98 / 1.04 s unthrottled, 1.66 / 1.30 s Slow 4G+4×CPU (was 1.6 / 1.9 s before). Live slots API 0.17–0.25 s. Single-run request trace: live 0.51 s vs preview 0.75 s, same order of requests; Clarity/CF beacon are not on the critical path → the median gap vs the preview (0.57 s) is run noise, not a regression. Remaining: live busy_cache ages <10 min over an hour (check ~09:50), then phase 2.
- 2026-10-24 08:25 Phase 1 check (new chat from handoff): PR #9 open/draft/mergeable, no CI checks attached; preview busy_cache ages 1.1 min (warmer cron rc=0 at 08:15, 08:20); no owner test booking on the preview yet (latest preview bookings are 10-23, pre-PR). Waiting on owner: test booking + reschedule + cancel on https://perf-booking-speed.embeddedera-site.pages.dev/book/ , then "merge".
- 2026-10-24 Contact/booking/inbox plan approved (owner "go") and phase 1 (booking speed) on preview. Raw data: ~2 real inquiries since 09-11 (Gabor, Blossman); 30-day RUM ≈ 2,560 page loads, /contact 70, /quote 20; GitHub CI mail for ee-meet carries the Leads label (to fix in phase 3). Plan: (1) speed, (2) Contact page as hub with inline booking + "Book a call" in nav, /book/ stays, (3) one inbox = Gmail label fed by every entry point + app "Inquiries" page, no new DB, (4) cleanup clicks/ + 7 unmerged branches. Phase 1 = PR #9 (branch perf/booking-speed, worktree ~/embeddedera-site-bookfast, preview https://perf-booking-speed.embeddedera-site.pages.dev): D1
busy_cache(stale-while-revalidate 5 min / 1 h, create+reschedule stay live), one 14-day slots request in parallel with config. Measured (Playwright, 5 fresh browsers): median to first slot 1.6 s → 0.57 s; Slow 4G+4×CPU 1.9 s → 1.35 s (worst 2.4 → 1.42) WITH a warm cache; cold cache (rows >1 h) 1.76–2.23 s ≈ baseline, so a 5-min warmer~/.local/bin/booking-warm(written, tested on preview, cron not installed yet: needs owner OK) is part of the fix. Migration 0002 applied to ee-bookings-preview only; apply to ee-bookings before merging (auto-mode blocked the prod D1 write). Cold cost measured: Afex ICS 0.6–1.1 s, Personal 730 KB/1,187 events, token+freeBusy 0.4 s; parsing ≤0.1 s. - 2026-10-23 12:45 PR #7 merged (72c8efc, owner "merge everything"), deploy green, /book/ + /es/book/ 200, slots ok. Task #142 lives in the assistant production DB (tasks-export reads ASSISTANT_DB) — not edited directly; owner changes the text on the admin Tasks card.
- 2026-10-23 12:30 cal.com follow-ups: business cards (~/design/business-cards: preview.html, card-trim.html, card-print.html, ideas/build.py) now say BOOK embeddedera.com/book; print PDF + preview.png rebuilt with headless Chrome, same fonts, only that line differs (pixel diff). PR #7 (comment + handoff doc, no visible change) open, merge blocked by permission check → owner merges. Task #142 text + GBP link + cal.com event still owner/next chat.
- 2026-10-23 12:10 cal.com audit. Live site clean: 149 sitemap pages + llms.txt/robots/RSS/CSP, zero cal.com; home, contact, FAQ, quote, 8 services link /book/ (EN) and /es/book/ (ES). Repo: only a stale comment in src/site.ts ("Cal.com booking link") and docs/booking-handoff.md still says "Live: no" — fix in the next site commit. Outside the site: brand/README.md updated; draft business cards (~/design/business-cards: preview.html, card-trim.html, card-print.html, the print PDF) still print cal.com/embeddedera; task #142 text (yrosado) still says cal.com — change via the task register. Owner: cal.com event type off, GBP booking link.
- 2026-10-23 11:50 Booking LIVE. PR #6 merged (3376b9f, owner: "do the whole pull request and finish end to end"); README Access fix 011d801 included; PR #5 had already been merged (plan doc). Production deploy run 39980771814 green. Live checks: /book/ + /es/book/ 200, config has Turnstile, slots ok (213 / 14 days, Afex 10:15-11:15 Oct 27 blocked), /admin and /api/admin redirect to Access, no cal.com links left on home/contact/es; Book buttons -> /book/, /es/book/. Left for owner: disable cal.com event type, GBP booking link -> https://embeddedera.com/book/, 3 key files to Vaultwarden.
- 2026-10-23 09:40 Personal (angelgdo7, 1,184 events) and Family (23 events) added as encrypted ICS busy calendars to live + preview booking DBs; preview slots API ok with all 4 calendars (212 slots / 14 days). Only go-live step left: owner says "merge".
- 2026-10-23 06:05 Booking (PR #6) Google setup done. OAuth client = project EmbeddedEra Documents (197835953119, the
~/.config/google/envclient), redirecthttp://127.0.0.1:53682/callbackadded by owner. Refresh token for adiaz@ (calendar.events, calendar.freebusy, calendar.readonly, gmail.send) in~/.config/google/booking.env(0600); verified: freeBusy OK, Gmail API enabled (scope error, not SERVICE_DISABLED). Cloudflare token scopes (Pages, D1, Access) OK, Turnstile not permitted (needs widget from owner or token widened). Next: bookings-db.sh, secrets on both Pages projects, Access app, preview deploy. - 2026-10-23 06:40 Booking setup, part 2. Turnstile widget "EmbeddedEra Booking" (embeddedera.com + embeddedera-site.pages.dev, managed) created; keys
~/.config/cloudflare/booking-turnstile.env(0600);claude-plextoken now has Turnstile Edit. D1ee-bookings(f2bcb0e2…, prod on embeddedera-apple) +ee-bookings-preview(22fa0f8b…, preview on embeddedera-site) created, 0001_init applied, bound as BOOKINGS. Access app + Pages secrets + preview deploy blocked by the auto-mode permission check → owner runsbash ~/embeddedera-site-booking/.booking-finish.sh(Access app on all six hosts incl. *.pages.dev, secrets per env, Deploy workflow on feat/booking). - 2026-10-23 06:50 Booking on PREVIEW https://feat-booking.embeddedera-site.pages.dev/book/ (run 39939890036 green). Owner ran
.booking-finish.sh: Access app "Booking admin" (12 destinations, owner only), all 9 booking vars on embeddedera-apple production + embeddedera-site preview (UPLOAD_SECRET kept). Checked: /book/ + /es/book/ 200, /api/book/config has Turnstile key, /api/book/slots returns a week of slots (D1 + Google free/busy), /admin and /api/admin redirect to Access on preview and on embeddedera-apple.pages.dev. Next: owner test booking (invite, Meet, emails, reschedule, cancel, admin, private link), then merge PR #6, close PR #5. - 2026-10-23 06:55 Booking preview test: booking, Calendar event + Meet, confirmation (Gmail Primary), invite, alert, reschedule, cancel all verified (D1 + Calendar + Sent). Admin sign-in looped: one Access app spanning embeddedera.com + *.pages.dev finishes login on its FIRST destination host (callback went to embeddedera.com/cdn-cgi/access/authorized for a feat-booking login). Fix: separate preview app, live app keeps embeddedera.com first; owner runs
bash ~/embeddedera-site-booking/.booking-access-fix.sh. Lesson: one Access app per site/host family when the app has several hostnames. -
2026-10-23 09:05 Afex calendar added as ICS busy calendar "Afex calendar" (Outlook published feed of the afexsystems.com work calendar; URL encrypted with each env SETTINGS_KEY, same as the admin page) in BOTH
ee-bookings(live) andee-bookings-preview. Verified: site parser reads 5 busy blocks / 14 days; preview Mon Oct 27 shows no slots 10:00–11:20 around the Afex 10:15–11:15 meeting. Private links + 40-min booking also verified (2 test bookings Oct 26 9:20, Oct 30 14:20, to cancel). Personal Gmail free/busy share still notFound — Personal calendar removed from preview list. -
2026-10-18 USB-C note requeued for 2026-10-25 (first free queue day; 10-19..10-24 taken, due_date is UNIQUE). Queue row was
uncertain, whichapprove()refuses by design, so I moved it tomissedwith a note_queue_history row (evidence: refusal before any copy, no production file, live 404, draft hash unchanged), then usedapprove()with actorassistant:sonnet:requeue-after-failed-release. Social stays paused, so it releases as website-only unless resumed. - 2026-10-18 RESOLVED: root cause of the recurring website-release refusals = the build writes each note's OG card (
public/og/notes/<slug>.png) untracked and nothing committed it, so the next morning's clean-tree guard refused (only sessions committed the cards by hand).publish-note releasenow commits the OG card beforegit push(backuppublish-note.bak.20261018; syntax-checked, first live proof = the 10-19 07:00 release, checkgit statusstays clean). 10-18 crystal-oscillator note released on time (verified), ESD note live since 10-17 22:00 (ledger reconciled to verified by the engine). USB-C note (10-17 slot) skipped: late release is same-day only and social is paused; draft stays in notes-queue asuncertainand can be re-scheduled as a future day if wanted. - 2026-10-17 22:05 UPDATE: deploy + push done (embeddedera-apple 94d2fe83, main == origin); ESD note live (200). USB-C note still 404: its 10-17 website attempt is
uncertainin the ledger. The supported route (daily_runtime.py --late-release) also re-times FB/IG stages and runs story-handoff, which conflicts with the 10-16 social pause, and its Story deadline is 20:00 (past). Needs an owner decision (see next line), andrecord_not_publishedfor the USB-C attempt only; do NOT mark ESD as not published (it is live). - 2026-10-17 HANDOFF (website notes stalled since 10-15): 10-16 release died because
thermocouple-converterwas not installed in production node_modules (installed 10-16 17:07,npm run buildnow passes); 10-17 release refused by publish-note's clean-tree guard (untracked OG png). I committed the OG card (18b5ffc);mainis 2 commits ahead of origin (ESD notec9ee444+ OG card) and NOT deployed: the auto-mode classifier deniedscripts/deploy.sh embeddedera-apple maintwice. Next action: run deploy +git push origin main(or add a Bash permission rule for scripts/deploy.sh), then per SOP-018 "Late release of a missed day":record_not_publishedfor the ESD and USB-C website attempts (bothuncertainin the daily ledger), thennote_queue.py late-release why-a-usb-c-board-works-on-usb-a-but-not-c-to-c. Social stays paused (~/.config/social-paused). Open question: same HTTPError/ValueError website failures recur since 09-29; add a build/clean-tree preflight before the 07:00 release. - 2026-10-16: RELEASED /tools/thermistor/ and /tools/thermocouple/ (+/es) at owner request ("Publish"): main fast-forwarded 1e87685 → 65b01b5, Actions Deploy success, all four pages 200, in sitemap, both cards on /tools/, linked first from /services/sensor-integration/. Rollback target 1e87685.
- 2026-10-16: Temperature calculators started (branch
tool-temperature, worktree ~/embeddedera-site-temperature, math commit 6be0f96): /tools/thermistor (Beta + Steinhart-Hart 3-point fit, divider, ratiometric ADC, best fixed R = sqrt(R(Tlow)R(Thigh)), self-heating) and /tools/thermocouple (NIST ITS-90, CJC in volts, naive-sum error shown). Library choice:thermocouple-converter1.1.0 (MIT, pinned) matches NIST to <0.07 °C; the other npmthermocoupledrops the type K exponential term (3.987 mV at 100 °C vs NIST 4.096 = 2.7 °C error) — never use it. Range clamped (the library extrapolates). Thermistor test data: Vishay NTCLE100E3103 table (doc 29049): S-H worst 0.21 °C, Beta 3977 worst 2.99 °C at −40 °C. - 2026-10-15: RELEASED /services/sensor-integration/ and /services/hmi-displays/ (+/es), main 0683b7b, deploy success, linked from /services/. Owner edit before release: no photos and no past-work proof, capabilities only (memory service-pages-capabilities-only). Proof block in [slug].astro now optional. Spanish not native-reviewed.
- 2026-10-15 ~21:03Z RELEASED heard-ai (owner pushed main e220960 -> beb56dc; Deploy run 38806753093 green). Live check: 'An AI assistant' choice (value
ai) on /contact/, /es/contact/ and /quote/. - 2026-10-15 Bing had only 9 of 101 pages indexed (Bing Webmaster API GetCrawlStats, InIndex=9 flat Oct 1-8). This matters more than llms.txt: Copilot and ChatGPT search answer from Bing's index. IndexNow on deploy only sends pages changed in that push, so older pages were never pushed. Submitted all 101 sitemap URLs with SubmitUrlBatch (quota 10,000/day, returned OK). Our view: llms.txt is fine as is; no major AI provider says it reads it.
- 2026-10-15: branch
heard-ai(beb56dc, worktree ~/embeddedera-site-heardai), pushed, not merged: the contact/quote "How did you hear about us?" list gets 'An AI assistant (ChatGPT, Copilot, Gemini…)' (EN/ES, keyai), and the referrer categories gain chatgpt, perplexity, copilot, gemini and claude (gemini is checked before google). usage + utm tests and the build pass. Release = merge to main. - 2026-10-15 Barry Rowton (Blossman Gas) says he found us by asking an AI (owner, from Barry). Matches the 10-14 traffic evidence: his PC visit was a direct hit on /contact with no referrer, which is what a link clicked in an AI chat app (ChatGPT app, Copilot in Edge) usually looks like. The google.com visits from an iPhone the evening before may have been Google AI Overviews / AI Mode, since those also send google.com as the referrer. So the first paying-scale lead came through an AI answer, not the site's ranked pages. Still unknown: which AI and what he asked; ask him. Use this before changing the AI/GEO plan (the 10-15 audit said AI answers follow classic rank and Bing). The lead-source form ("How did you hear about us?") should offer an "AI assistant (ChatGPT, Copilot, Gemini…)" choice.
- 2026-10-15: Tool card visuals released (main 658338a, deploy success; another session then pushed e220960 on top): STM32 flasher (board, BOOT0, USB DFU, 0x08000000), BOM risk check (BOM.csv risk rows), assembly readiness (GBR/BOM/CPL → ready/fix/confirm). Verified live on /tools/.
- 2026-10-15: Impedance tool figure released (main db693ba): own PCB cross-section on the tools card and as the live #sch panel (Copy image works), card title "PCB trace impedance" / "Impedancia de pistas PCB"; screenshots checked against neighbouring cards.
- 2026-10-15: RELEASED impedance calculator to production at owner request ("place the calculator online"): main e30222a..cc10ba3 → 46fcaac (tool-impedance rebased, build/check-seo/all tests pass), Actions success; live https://embeddedera.com/tools/impedance/ + /es. 2-D field solver with solder mask, within ~1% of OSH Park published values. Open: owner read of the Spanish copy; trapezoidal etch not modelled.
- 2026-10-15: Impedance tool on preview: https://tool-impedance.embeddedera-site.pages.dev/tools/impedance/ (branch tool-impedance 97cf17c, from the 2026-10-15 market brief). Open before release: compare against JLCPCB's impedance calculator, review the Spanish copy.
- 2026-09-19: Continued storefront planning in embeddedera-store: confirmed stocked plus kits/made-to-order, US and international, and shared multichannel inventory. Added proposed architecture, reservation/error handling, shipping/payment defaults, operations and sandbox launch gates. No deployment.
- 2026-09-19: Angel selected WooCommerce as the storefront planning direction, with InvenTree-controlled inventory, easy listing creation/editing, public checkout/payments, cart reminders, minimal recurring service fees, and extensibility for custom features. Planning only; no deployment authorized by this decision. Remaining decisions include product types, shipping regions, stock reservations and connector feasibility, fulfillment, payment/accounting reconciliation, email delivery, hosting, and returns.
- 2026-09-18 01:41: Quote intake now requires one of three canonical engagement types in English and Spanish, with custom development preselected and client-side allow-list validation. Verified on the development deployment, then cherry-picked to
mainand deployed to production (embeddedera-apple, deploymentee04cb79). The InvenTree proposal now fails closed with aPROPOSAL BLOCKEDpage unless the sales-order description contains one exactEngagement type: <value>marker; sandbox-generated PDFs proved both blocked and licensed-design paths before production template revision 24 was installed. Source commits: site1069b4f, ERPc97e89a. - 2026-09-11 17:05: Google API key stored (
GOOGLE_API_KEYin~/.config/google/env, projectembeddedera, restricted to PageSpeed/Search Console/Sheets/Drive/YouTube/Custom Search). First audit of the live site: mobile performance 97→99, desktop 100, accessibility 100, SEO 100, best practices 92→100; LCP 2.0 s mobile / 0.4 s desktop, CLS 0, TBT 0. The audit found a real bug: our CSP blocked Cloudflare's Web Analytics beacon, so no analytics had been recorded since cutover. Fixed (script-src+connect-srcallowstatic.cloudflareinsights.com), deployed to production, console errors now zero and the beacon loads (it is injected at the edge only for browser user agents, socurlwithout a UA shows nothing — not a fault). - 2026-09-11 17:00: Service-account key creation is blocked by the Workspace org policy
iam.disableServiceAccountKeyCreation(Google "secure by default"). Decision: leave the policy alone. It only blocked the Search Console automation, which is a convenience; revisit with a one-time OAuth consent or a monthly CSV export when that work actually starts. - 2026-09-11 14:45: Engineering notes section added on
apple-style(collectionnotes, /notes index + article pages, Article JSON-LD, footer + home links, llms.txt section, Spanish index that says articles are English). First article "When your microcontroller goes end-of-life" (1,421 words). Worker also fixed the ES toggle 404 on article pages and a UTC date-shift bug. On the dev preview only — not yet promoted to production. - 2026-09-11 13:30:
quote-draftsroutine live — prompt~/.claude/routines/quote-drafts.md, wrapper~/.local/bin/quote-drafts, cron*/30 7-19 * * 1-5. Reads[EE-threads with the Gmail connector, writes a REPLY DRAFT with the 1-3 missing questions per request type, labels the thread EmbeddedEra/Leads. Send tools are explicitly disallowed; it can only draft. First run skipped all six self-tests correctly. Log~/.claude/routines/quote-drafts.log, ntfy on error. - 2026-09-11 13:05: Lunch session — filters and cal.com done; Google Cloud left half-done across three projects (see Open). PageSpeed audit still blocked until one project has the API + an unrestricted key.
- 2026-09-11 12:10: Gmail filters created (alerts@ → Notifications/skip inbox; [EE- → EmbeddedEra/Leads, starred, important). cal.com now checks angelgdo7 for conflicts. PageSpeed API key in progress (GCP project
embeddederaunder the Workspace org). - 2026-09-11 09:35: State at end of the morning session — LIVE on Cloudflare Pages; dev branch
apple-style(preview embeddedera-site.pages.dev), prodmain(project embeddedera-apple). Done today: forms + attachments + captcha, Spanish, R&D + CAD services, AI-discoverability files, security headers, redirects, Search Console sitemap, Kuma monitor, alerts@ alias + billing alerts, lunch checklist event. Waiting on Angel: lunch list (Gmail filters, cal.com conflict calendar, send the two drafts, PageSpeed key, LinkedIn), Spanish review replies, testimonial, affiliate sign-ups, photo shoot 2026-09-19, WordPress cancel after 2026-09-18. - 2026-09-11 09:30: Bing — Angel is letting Bing Places' automatic sync from Google handle it; no separate Bing Webmaster setup.
- 2026-09-11 09:25: Search Console — Domain property was already verified (WordPress.com era); sitemap
https://embeddedera.com/sitemap-index.xmlsubmitted; indexing requested for /, /services/, /es/. Google still shows the old WordPress snippet + favicon until recrawl. - 2026-09-11 07:30: CUTOVER.
apple-stylemerged intomain(tagv1-mirrormarks the old mirror),embeddedera-appleproduction branch set tomain, custom domains attached, DNS switched (A records deleted, proxied CNAMEs to the project).embeddedera-siteproject repurposed as the DEV preview forapple-style(same R2 binding). Workflow from now: work onapple-style→ dev preview → merge tomain→ deploy production. - 2026-09-11 07:10: R&D positioning live (Home screen "Your outsourced R&D department.", service "Hardware R&D and Product Development" first under Design, FAQ, titles/descriptions/knowsAbout). 12 services. Gmail: label EmbeddedEra/Leads created; drafts for the Spanish review (friend) and the testimonial (client) in Angel's Drafts.
- 2026-09-11 06:35: Angel added the Workspace alias alerts@embeddedera.com and three Cloudflare usage-billing notifications (R2 storage, Class A, Class B) to it. Rule: hello@ for humans/leads, alerts@ for machines.
- 2026-09-11 06:20: File attachments live on /quote (both languages): Pages Functions
functions/api/upload.ts+functions/api/file/key.ts, R2 bucketembeddedera-uploads(ENAM, 90-day auto-delete, free tier 10 GB), bindingUPLOADS, secretUPLOAD_SECRET(in~/.config/cloudflare/env), HMAC-signed download links in the Web3Forms email. Tested: upload 200, signed download 200, tampered token 404, .exe 415, bad id 400. Deploy now viascripts/deploy.sh <project> <branch>(stages dist+functions; wrangler must run inside the stage). Gotcha: first bucket needs R2 enabled in the dashboard (Angel did, card on file, free tier). Billing alert must be set in the dashboard (token can't). - 2026-09-11 06:00: Uptime Kuma monitor #11
embeddedera.com(HTTP, 60 s, ntfy "Ntfy IPhone") added via theuptime-kuma-apiclient in~/.local/share/kuma-venv; Kuma admin login in~/.config/credentials/kuma.txt(the~/.config/kuma/dir ended up root-owned from the sudo reset — Angel tosudo chown -R angel:angel ~/.config/kuma). - 2026-09-11 03:00: Spanish site live on the preview under /es/ (18 pages, Astro built-in i18n, dictionaries
src/i18n/{en,es}.ts, hreflang/canonical per language, ES⇄EN toggle, forms localized with alanguagefield; English text byte-identical after the extraction). Intake forms fixed (hidden required fields blocked submit) and hCaptcha added; booking link on the site; conformal coating added. Audit: 0 broken links/anchors across 9 EN pages, structure consistent; small wording fixes queued. - 2026-09-11 00:15: Web3Forms key in
~/.config/web3forms/env(free plan: browser submissions only). Intake forms (/quote, six request types, request IDs) being built. cal.com booking link: https://cal.com/embeddedera/20-minute-call (free personal plan, Google Calendar connected). Google Business Profile created by Angel (verification pending). - 2026-09-10 23:55: Site says EmbeddedEra LLC, founded April 2024; lead time "as fast as four weeks… depending on parts availability" on Home, Services and FAQ. Pricing and standards lines drafted, waiting on Angel. Photo shoot on the calendar Sat 2026-09-19 13:00.
- 2026-09-10 23:40: Workspace aliases exist on adiaz@: purchasing, sales, socialmedia, info, marketing, billing, hello (added tonight). Site now shows hello@ as the public address. Cloudflare Web Analytics added in the dashboard with automatic setup (injects once the domain is proxied through Pages).
- 2026-09-10 23:30: Token extended (Analytics read, Email Routing Rules, Bot Management). AI-crawler blocking set to
disabledon the zone via API (wasonly_on_ad_pages). Email Routing rejected as the hello@ route: it replaces MX and would break Workspace mail → Workspace alias instead. Web Analytics creation needs a permission API tokens can't carry → dashboard step. - 2026-09-10 23:25: Five families / eleven services on
apple-style(added Software → "Apps and Software for Hardware Products"; Design → "Enclosures, Fixtures and Mechanical Parts"; third capability "Enclosures and fixtures, made here", text-only; no machine brands on the site by Angel's instruction). /privacy, touch icons, web manifest. Live preview 659c698. - 2026-09-10 23:10: DMARC
_dmarcTXT (p=none, rua=adiaz@) added via API. Email Routing and Web Analytics need token permissions the current token lacks → to-do. Security headers (public/_headers) and old-WordPress-URL redirects (public/_redirects) added; robots allows for AI crawlers, llms.txt/llms-full.txt (build script), /faq with FAQPage schema, definitional paragraph on About. - 2026-09-10 22:50: Consolidation done on
apple-style(headline "From schematic to tested board.", one voice, four service families Design/Firmware/Build and test/Redesign, specs strip, location folded into contact). Platforms broadened (STM32, ESP32, Nordic nRF, Microchip, TI, Arduino; BLE/Wi-Fi/Ethernet/CAN/USB/RS-485/radio). Nine services now, incl. "Reverse Engineering and Legacy Boards". Live preview https://embeddedera-apple.pages.dev. Rule 4 (prefer API-key services) added to global rules. - 2026-09-10 22:00: Apple-style is the chosen direction. Credibility pass done (first-person About, capabilities, how-it-works, quote checklist, OG image), Real Cow parked, images remapped to the right sections, board counts removed. Seven services now incl. "Obsolete Parts and Board Redesign" (own landing page /obsolete-parts-redesign) and "Automated Test Fixtures and 100% Production Testing"; "Universal Tester" name gone from live pages. JSON-LD ProfessionalService + search titles/descriptions + footer keyword line. Latest
apple-style971be2e → https://embeddedera-apple.pages.dev. - 2026-09-10 21:00: Two candidate looks side by side.
main(mirror of WordPress, dark, cards) → https://embeddedera-site.pages.dev. Branchapple-style(one idea per screen, big type, same copy/images/colors; worktree~/embeddedera-site-apple) → its own Pages project embeddedera-apple at https://embeddedera-apple.pages.dev because branch-alias URLs on a new project have no TLS cert for a while (handshake alert 40). Angel picks; the loser's branch stays in git. - 2026-09-10 20:30: v1 = mirror of the live WordPress pages (Home/Services/About/Contact, WP copy verbatim, dark theme). Case studies, Tools, Docs parked in
src/_parked/for phase 2. Deployed by direct upload to Pages projectembeddedera-site→ https://embeddedera-site.pages.dev (all 4 pages 200). Cloudflare API tokenclaude-plex(Pages:Edit, Zone DNS:Edit, Access:Edit on embeddedera.com) in~/.config/cloudflare/envwith account/zone ids. Gotcha: runningwranglerinside the repo auto-added the Workers adapter + wrangler.jsonc — reverted; always runwrangler pages deployfrom outside the repo. LAN preview: user unitsite-preview.service→ http://site.lan via NPM. - 2026-09-10 19:30: Phase 4 started. Stack decided (website-stack): Astro 5 + Tailwind v4 from the portfolio's own components, Cloudflare Pages. WordPress copy scraped (home/services/about — thin), logo recovered, portfolio cloned to
~/portfolio-sitefor media. Worker (Sonnet) building in~/embeddedera-site. The Real Cow flasher + configurator (EmbeddedEra org) → own subdomains later. - 2026-09-10 12:50: Angel switched nameservers at account.squarespace.com (domain is Squarespace-registered, resold via Google Workspace — that panel, not admin.google.com, is where nameservers live). A first attempt in May 2026 had stalled at this exact step and Cloudflare deleted the zone after 30 days. Cloudflare account nameservers: alexis + love.
- 2026-09-10: inventory taken from public DNS; no changes made. Repo
embeddedera-sitecreated with the five phase guides; this note renamed from embeddedera-domain to match.
2026-09-19 — Public Shop entry¶
At Angel’s explicit choice, English/Spanish header and footer Shop links lead to public coming-soon pages until launch, with contact links and no gated-store destination. Commit2fc9bbf built28pages and passed Astro/TypeScript and375/1440px checks. Preview verified then main fast-forwarded/pushed; production deployment660ca01a completed and https://embeddedera.com/shop/ plus /es/shop/ independently verified. Isolated worktree embeddedera-site-store avoided publishing apple-style drafts. Main merged back into local apple-style as eb2f060 (Terms draft preserved); Astro check0errors/0warnings; draft branch not published.
- 2026-10-14 Where the first two real inquiries came from (Cloudflare Web Analytics minute data + Search Console). Gabor Kadas (EE-20261013-1746-JY4H, Pacific time): US Mac/Safari landed on
/from google.com 00:44Z, /contact 00:44, form 00:46Z. Barry Rowton (EE-20261009-0703-QPLT, Central time): only visit on his Windows/Edge PC was a direct hit on /contact 12:00Z Oct 9 (no referrer); likely the US iPhone that came from google.com to/at 23:46Z and 00:27Z the evening before (Search Console shows home-page Google clicks on those dates). Neither had a utm first-touch, so neither came through our tagged social links. Home-page queries are anonymized by Google (rare, specific searches). What changed: Google impressions ~15/day -> ~50/day from 2026-10-06 (tools pages: resistor codes, battery life, ES calculators); the site is about a month past cutover, so Google is starting to rank it. Gap: the form records source only for utm-tagged arrivals; referrer and landing page of untagged visits are lost. Barry reported our replies landing in his Gmail Promotions tab. - 2026-10-14 Why replies to Barry hit Gmail Promotions. Not authentication: SPF (google), DKIM (google._domainkey) and DMARC p=none all present; the first reply was 3.5 KB plain text, no links/images. Likely causes: (1) the reply subject is the Web3Forms notification's,
Re: [EE-…] General inquiry from Barry Rowton, i.e. a first email that starts with Re:, a bracketed ticket ID and the recipient's own name, the shape of help-desk/bulk mail; (2) no sending history with this recipient (the domain itself is not new: it predates the 2026-09-10 cutover, WordPress.com era); Resend DKIM for hello@ newsletters is present; (3) the follow-up carried a cal.com booking link and a 452 KB attachment. Fix proposed: form subject that reads like a person wrote it, ticket ID moved into the body, first reply without links; ask the contact to reply/star; later DMARC p=quarantine after reading rua reports. - 2026-10-14 Lead source capture on PREVIEW (branch
lead-source@e70cc1f, worktree~/embeddedera-site-leads, https://lead-source.embeddedera-apple.pages.dev; main untouched). Untagged arrivals now store referrer host + landing path (90-day first touch, host only); optional "How did you hear about us?" (EN/ES); form subject "Your project inquiry to EmbeddedEra – {name}" with request ID in the body;site/form_submit {form, source, heard}to /api/ev; privacy page EN/ES updated. Tests: utm.test, usage.test, build, utm.e2e pass. Not verified end to end: a real submit (email text, D1 write). Left out:tools/assembly-checkform still has the old "[EE-…] … from name" subject and no source capture. Built by a Sonnet worker, verified by primary. - 2026-10-14 17:12 RELEASED lead-source to production (owner: "yes for everything"): main fast-forwarded 195a20f -> eb63b6f (e70cc1f + assembly-check follow-up eb63b6f: visitor_source/utm/referrer on the SMT assembly quote, subject "Your SMT assembly request to EmbeddedEra – {name}", form_submit form=assembly).
scripts/deploy.sh embeddedera-apple main(needs~/.config/cloudflare/envsourced or wrangler fails non-interactively), cache purged, IndexNow 200. Live check: /contact, /es/contact, /quote carry heard_about; all pages 200. End-to-end test inquiry pending: the forms use hCaptcha, so the owner submits it. - 2026-10-14 Microsoft Clarity built, inert, on PREVIEW (branch
clarity@726bcc5 from lead-source, worktree~/embeddedera-site-clarity, https://clarity.embeddedera-apple.pages.dev). Loads only whenCLARITY_PROJECT_IDinsrc/site.tsis set. EEA/UK/CH (32 codes, from/cdn-cgi/traceloc, fail closed) get an Accept/Decline banner and ConsentV2 after Accept; everyone else gets Clarity plus a footer "Don't record my visits" (reuses the usage opt-out, so it also stops flasher stats). DNT/GPC respected. Forms and inputsdata-clarity-mask. Privacy section EN/ES renders only once an ID is set; bump the privacy effective date at go-live. CSP adds *.clarity.ms + c.bing.com;worker-src blob:unverified. Masking left at dashboard default Balanced (Strict would blank page text in heatmaps). Waiting on: owner creates the Clarity project and sends the Project ID (+ a Data Export API token for marketing-snapshot). - 2026-10-14 17:20 End-to-end test passed (owner's test inquiry EE-20261014-1720-JCOO from a Google search on his phone): email subject "Your project inquiry to EmbeddedEra – Angel Diaz", body carries
source : google (www.google.com) (landed /)andheard_about : Google or other search; D1ee-usagegotsite/form_submit {form:contact, source:www.google.com, heard:search}(US, mobile). That D1 row is a test: exclude it when counting inquiries. - 2026-10-14 18:20 Microsoft Clarity LIVE (project
yxstuvbmyv, owner account): main fast-forwarded eb63b6f -> 6e24cc9 (726bcc5 integration + 6e24cc9 ID and privacy effective date 2026-10-14), deployed, cache purged. Verified in a real browser on embeddedera.com/contact: tag + clarity.js load, data posts toe.clarity.ms/collect, no CSP errors (soworker-src blob:was not needed), no banner for a US visitor, footer opt-out shown, all 14 inputs + form carrydata-clarity-mask. Pi-hole had to allowclarity.microsoft.comandwww.clarity.msfor the dashboard to show "New project". Project created by the owner on his phone; industry B2B Services. API token not yet made (optional, for marketing-snapshot). - 2026-10-14 Clarity excludes development.
src/lib/clarity.tsRECORD_HOSTS= embeddedera.com + www only, so *.pages.dev previews, localhost and astro preview never record (e142188, released; preview verified: zero clarity.ms requests). Home public IP 207.49.173.70 (residential, may change) to be added by the owner in Clarity > Settings > IP blocking (dashboard-only, no API). Owner's own devices: use the footer "Don't record my visits" once per browser (also stops flasher usage stats on that browser). Note: the browser checks on 2026-10-14 ~18:20 (preview + /contact) were recorded in Clarity as test sessions. - 2026-10-15 Why we don't rank for the work we sell (evidence). Search Console 90 d: 644 impressions, 14 clicks, avg pos 17; impressions come from notes and tools (kicad autorouter, webusb flasher, resistor codes); zero service-intent queries rank (only "pcb assembly quotes" at pos 77). /services/ last crawled 2026-07-19 (pre-cutover); /quote/ unknown to Google; sitemap has no
<lastmod>. Site audit (Explore agent, spot-checked): only one service sub-page (/services/pcb-design/); firmware, assembly, fixtures, prototyping are anchors on /services/; no page for taking over an existing design (the Blossman buyer) or for design-partner-under-NDA (the AttendeeMatch buyer); home H1 is a slogan; /about/ has no photo, résumé or LinkedIn; 4 case studies parked in src/_parked/pages/work; 7 of 29 notes have no service/quote link; schema lacks geo/telephone/priceRange, founder is bare; location reads Clayton (true principal office, site.ts LOCATION) vs Raleigh in copy, state it as based in Clayton, serving Raleigh/Triangle. Off-site (scout, partly unverified): Google Business Profile still unverified since 2026-09-11; free Manufactured in NC (NC State/NCMEP) listing; Thomasnet PCB designers; takeover/legacy-rescue and NDA-partner queries have no strong agency page = opportunity; llms.txt has little value (Mueller, Ahrefs); AI answers follow classic rank and Bing. Plan and to-dos in Open. - 2026-10-15 Location rule + sitemap dates, RELEASED (main cc10ba3): everywhere reads "Clayton, NC, serving Raleigh and the Triangle" (owner's rule; Raleigh only as an area served; EN+ES copy, titles, FAQ, llms.txt header, areaServed, og.png). Titles/descriptions kept inside check-seo limits (home: "PCB Design & Firmware, Clayton NC near Raleigh | EmbeddedEra"). Sitemap
<lastmod>= newest git commit of the page template + its dictionary (notes: the note file). Gotcha: production deploy from~/embeddedera-sitefailed untilnpm ci(minisearch missing in that checkout's node_modules); the live site stayed on the old build meanwhile. Owner to do: Search Console > URL inspection > Request indexing for /services/ and /quote/. - 2026-10-15 Search Console "Request indexing" done in the owner's Chrome (with his go): /services/ (was indexed, last crawl 2026-07-19) and /quote/ ("Discovered - currently not indexed", found only via the sitemap, no referring page seen; 12 live pages do link it, Google just had not re-crawled them). Both "added to a priority crawl queue". Check in a few days with URL inspection (API:
searchconsole.googleapis.com/v1/urlInspection/index:inspect). Direct links of the form/search-console/inspect?...&id=<url>404; use the top search box. - 2026-10-15 Collision avoided: a second session started takeover + firmware pages from main on a branch named
service-pageswithout re-reading this note's State line, which already listed firmware on service-pages-2 and owner copy rules (no ownership claims, facts in src/lib/facts.ts). Stopped before any commit/push/deploy; worktree removed. Rule: before site work, read the State line at the top of this note andgit branch -afor live branches. - 2026-10-15 Design takeover page on PREVIEW: branch
design-takeover(ef5fa82, on top of service-pages-2, worktree ~/embeddedera-site-takeover), https://design-takeover.embeddedera-site.pages.dev/services/design-takeover/ (+/es). Built by a Sonnet worker, every claim reviewed by primary: softened 'we design for safety products' -> 'working alongside your certification lab', 'test every unit' -> 'test them' (prototypes), per-milestone promise -> 'we document as we go and hand it over'; no ownership claims; facts reused from facts.ts. Gates pass (99 pages, check-repeats 0). Phone 375 px OK. Not done: quote engagement type (ENGAGEMENT_TYPES are the Terms clause 9 ownership types; a takeover is a project kind, not one of those). Spanish not native-reviewed. Release needs a rebase: service-pages-2 and design-takeover predate the 2026-10-15 Clayton wording (footer keyword line still says Raleigh) and main's impedance commits; rebase onto main, rebuild, then release both together. Also fixed live (044f124, auto-deployed by GitHub Actions on push): template prints{LOCATION}. {c.location}, so c.location must NOT repeat the city; reverted to 'Serving Raleigh and the Triangle. Ships nationwide.' - 2026-10-15 ~13:55 RELEASED service pages (owner: "publish"): firmware, smt-assembly, test-fixtures, rd-product-development (other session's ecae44f) + design-takeover (53f0742, a72a242 softened claims), cherry-picked onto main as 63789af/611e306/a72a242; GitHub Actions deployed (push to main deploys). Then e220960: /services/ hub STRUCT had 12 rows for 13 dictionary entries so design-takeover was silently dropped and test-fixtures had no onward link; fixed + build now throws if the lists differ. Live check: all 5 pages 200 with H1 (EN+ES), in sitemap, hub links all six service pages. check-repeats 24 warnings is pre-existing on main (none added). Concurrent sessions push to main: always
git pull --rebasebefore pushing (a push was rejected once, correctly). - 2026-10-15 Search Console "Request indexing" (owner's go, server Chrome = Browser 2 Linux) for the 5 new service pages: design-takeover, firmware, smt-assembly, test-fixtures, rd-product-development. All were "URL is unknown to Google"; each confirmed "added to a priority crawl queue". 7 requests used today (incl. /services/, /quote/). Check index status in a few days via the URL Inspection API.
2026-09-24 — the site said Raleigh; the company is in Clayton¶
The NC filings put the principal office at 1001 Ridge Drive, Clayton, NC 27520-9664 (Johnston County), SOSID 2827835. Raleigh is the registered agent's address — ZenBusiness, 1001 Wade Ave, Wake County — which is almost certainly how it propagated into the site and the internal notes.
Changed only the two places the site states where the business is: the schema.org PostalAddress.addressLocality, which is machine-readable and was asserting the wrong city to search engines, and the LOCATION constant shown on about, quote and obsolete-parts-redesign. areaServed stays Raleigh — that is true, it is the metro we sell into. Address kept to locality only: the principal office is residential and does not belong in public structured data.
Deployed to production as c66a496, cherry-picked onto main rather than merged. A merge would have shipped 37 commits from apple-style, including about twenty unpublished weekly engineering notes and a "Terms of sale and limited warranty page, for review" — none of which had been approved for publication. Those 37 are still waiting on that branch and are worth a deliberate release decision.
The live domain served the old copy for a few minutes after deploy; POST /zones/<id>/purge_cache for the three affected URLs fixed it. Verified after: addressLocality is Clayton and all three pages show Clayton, with /, /about/, /services/ and /contact/ all 200.
Left alone deliberately: "Raleigh" still appears roughly ten times in src/i18n/{en,es}.ts — page titles, meta descriptions, service copy. That is SEO positioning and changing it has search consequences, so it is Angel's call. Two of those are closer to factual claims than positioning and are worth a look: "built and verified on our own line in Raleigh, North Carolina" and "everything built and tested in Raleigh" — the line is in Clayton, and "in the Raleigh area" would fix both without losing the search term.
- 2026-09-30: Note offers built on branch note-offers (worktree ~/embeddedera-site-offers, from main, NOT merged): per-note offer frontmatter (internal href only, schema-validated), tag→service fallback map (src/lib/offers.ts), ::offer mid-note marker, offers on all 17 notes, /api/click beacon → R2 clicks/<note>/<kind>/ tallied by scripts/note-clicks.sh (no reader data; privacy page updated EN+ES). Preview https://note-offers.embeddedera-site.pages.dev. Dev Pages project embeddedera-site preview environment now has the UPLOADS R2 binding (it had none, so /api/ 500'd on preview aliases). Pipeline: weekly-research.md prompt + wrapper gate now require offer; reviewer check offer_matches_note on assistant branch note-offers-review (worktree ~/assistant-note-offers, unmerged).
- 2026-09-30: Owner: notes must earn. Built on site branches (preview only): note-offers (per-note offer frontmatter + tag→page map for all 17 notes, related notes + inline cross-links, private click beacon /api/click → R2), bom-check (free BOM risk check, lead-gated: first/last/work email, separate unticked newsletter consent; ≤50 unique MPNs/request, cache-first, ≤400 distributor calls/day; verdict-only output until Digi-Key/Mouser display terms are confirmed; TrustedParts API adapter stub pending owner key), assembly-check (browser-side Gerber/BOM/CPL readiness check, lead-gated, 'send files for a quote'). Affiliate links deprioritised: own services convert better for a small site. Next tools ranked: ESP32 flasher on esptool-js with a production serial/label mode, battery-life and MSL bake calculators (open, optional 'email me the result').
- 2026-09-30: Free BOM risk check built on branch bom-check (worktree ~/embeddedera-site-bom, from note-offers, NOT merged, uncommitted): /bom-check + /es/bom-check, functions/api/bom.ts → R2 bom/<id>/ + leads/ (+ subscribers/ on opt-in), server job ~/.local/bin/bom-check (R2 REST via the Cloudflare token, cache-first part-lookup, Mouser 10-per-call batch, 400-call daily budget, 50 free MPNs, Gmail DRAFT via claude -p, 30-day delete). Report shows only our derived verdicts — Digi-Key API User Agreement is non-sublicensable and Mouser's Search API ToS forbids aggregating with third-party content without attribution, so no prices/stock/distributor names go to readers. Preview https://bom-check.embeddedera-site.pages.dev. Cron line not installed yet.
- 2026-09-30: Assembly quote readiness check built on branch assembly-check (worktree ~/embeddedera-site-asm, from note-offers, NOT merged): /tools/assembly-check (+/es), check runs in the browser (whats-that-gerber + papaparse + jszip, page-only bundle), gated by /api/lead → R2 leads/ (functions/_lib/leads.ts — reconcile with the inline lead write in bom-check's functions/api/bom.ts), "send for a quote" reuses /api/upload + Web3Forms so quote-drafts picks it up unchanged. Preview https://assembly-check.embeddedera-site.pages.dev/tools/assembly-check/. Tests node scripts/assembly-check.test.mjs.
- 2026-09-30: Release branch release-2026-09-30 (worktree ~/embeddedera-site-release, pushed) = origin/main + note-offers + bom-check + assembly-check as merge commits. Conflicts (click.ts TARGET_RE, offers.ts OFFER_HREF, en/es dictionaries) resolved by union; the new provisioning note got its offer + two cross-links. /api/bom now writes its lead via the shared putLead() (functions/_lib/leads.ts, one CONSENT_TEXT_VERSION, bom_id on the Lead). Production project embeddedera-apple already has UPLOADS → embeddedera-uploads and UPLOAD_SECRET; nothing else is read. Preview https://release-0930.embeddedera-site.pages.dev — all checks green. NOT deployed to production, not merged to main.
- 2026-09-30: RELEASED to production (main fast-forwarded to release-2026-09-30 @40d0a59, deploy embeddedera-apple, purge_everything, live pages verified 200): per-note offers on all 18 notes, related notes + inline links, /api/click beacon, /bom-check (lead-gated, verdict-only), /tools/assembly-check (browser-side, lead-gated), privacy EN/ES sections. Two Sonnet reviews (CHANGES → fixed privacy copy). Production checkout needed npm ci (new deps jszip/papaparse/whats-that-gerber) before deploy. bom-check cron installed (/30 7-19 weekdays). Open: Gmail app password → ~/.config/gmail-drafts/env for exact drafts; TrustedParts API key; Turnstile:Edit on the Cloudflare token for a captcha; rate limits on /api/lead and /api/click (ponytail debt).
- 2026-09-30: RELEASED calculators batch 1 (main @bd64a2b): /tools index + voltage divider (reverse E-series pair search), regulator feedback, Ohm's law & power, LED resistor, resistor codes (colour/SMD/EIA-96), op-amp gain; EN+ES; Tools in nav/footer; shared src/lib/calc.ts. Sonnet review APPROVE with independent Python recomputation. Next batches (ranked): I²C pull-up, UART baud error, timer/PWM prescaler, ADC scaling, crystal load caps, battery life; then trace width/via current, LDO thermal, RC filter, hold-up cap, MSL bake, USB-C sink. 'Email me this result' not built yet (needs /api/lead source whitelist + a send path). Feature branches/worktrees removed after merge.
- 2026-09-30: RELEASED live schematic on /tools/voltage-divider (+es) (main @3360182): owner-approved design (voltage-coloured wires, answer card with tolerance bar, current flow animation off under reduced-motion, row click selects pair, dashed RL when a load is entered). Fixed a live bug found in review of screenshots: the ±tol worst-case range ignored the load (showed 3.29–3.78 V beside a loaded 3.297 V; correct 3.07–3.53 V) — regression test added; and SVG parts can't use .hidden (use class/attribute). Open (owner feedback pending): '12 V' tight to the left edge at 375 px; RL zigzag crowds R2's power label; then roll the style to the other 5 calculators.
- 2026-09-30: All six calculators now have live visuals (shared src/styles/schematic.css): divider (load drawn like R1/R2, all tolerances ±20…±0.01 %, series sets usual tolerance, E6/E48 added, loaded worst-case range bug fixed), Ohm's law (no series picker; nearest E24 + E96; ratings named as sold e.g. 1/16 W), LED (colour picker with typical Vf; brightness 'Advanced' section on preview branch led-brightness, NOT yet published — awaiting owner), op-amp (inverting/non-inverting), resistor codes (TH bands + SMD mark), regulator (buck FB + LM317 ADJ). Fixed live correctness bug: in LM317 mode the table labelled the bottom resistor R1 (opposite of the datasheet) and suggested pairs drew ~20 µA; now datasheet naming (R1 = OUT→ADJ), formula Vout = 1.25·(1+R2/R1)+Iadj·R2, and a 'Minimum load current' constraint (default 5 mA) → 1.25→5 V gives 100 Ω / 301 Ω.
- 2026-09-30: ESP32 browser flasher on PREVIEW only (branch esp32-flasher, https://esp32-flasher.embeddedera-site.pages.dev/tools/esp32-flasher/): esptool-js 0.7.0 loaded on Connect; blocks wrong chip (image chip_id vs detected), revision out of range, image+offset > flash, header flash size > fitted, invalid/truncated images; auto offset (merged vs app); confirm naming chip+file; MD5 verify; opt-in erase; optional SHA-256 approved list (localStorage). Tested with MicroPython v1.29.0 ESP32/C3/S3 fixtures (MIT) and a simulated chip; stub compiled out of deployed builds. Before release: owner tests with a real board in Chrome. Tasmota (GPL) fixture replaced by a derived MIT one; repo is private so no distribution happened.
- 2026-09-30: STM32 DFU flasher on PREVIEW (branch stm32-flasher, contains esp32-flasher; https://stm32-flasher.embeddedera-site.pages.dev/tools/stm32-flasher/): webdfu 1.0.5 (MIT; Betaflight's GPL excluded), DfuSe layout parse, flash-alt only (option bytes/OTP never opened for download), sector-only erase (mass erase opt-in), .dfu CRC+VID/PID, Intel HEX, vector-table SRAM/flash sanity per DEV_ID family, RDP refusal; MicroPython Nucleo F401/G0B1/H743 fixtures (MIT). Sonnet safety review: CHANGES (file-selection race could desync approved-SHA check) → fixed c59bb94 (atomic loaded object, load generation, re-check on exact bytes at Flash) → APPROVE. Both previews run c59bb94. Release after owner's real-board tests (tonight). Known ceiling: a .bin shifted by less than its length passes the vector heuristic.
- 2026-09-30: Owner scope for flashers: public browser flashing only (ESP32 + STM32 as built, releasing after tonight's board tests); the signed package / custom bootloader idea is parked (see Open).
- 2026-09-30: Researched (plan, not built): (1) shared browser-capability check for all hardware tools — feature-detect navigator.serial/usb/bluetooth + isSecureContext; specific messages for Firefox/Safari/iOS (copy/email link), Brave (Web Serial off by default: brave://flags), Android Chrome 148+ serial via OTG, in-app webviews (open in browser), policy/iframe blocks; error mapping SecurityError/NetworkError/NotFoundError/NotAllowedError; driver help (CH340/CP210x/FTDI VCP, Zadig WinUSB for DFU, Linux dialout). (2) Serial terminal design: xterm.js + WebGL addon, uPlot plotter, thin own Web Serial wrapper (no good helper lib); must-haves reset-on-connect toggle with per-chip DTR/RTS profile, auto-reconnect via connect events + getPorts(), timestamps, hex, line-ending presets, auto-scroll pause; differentiators: inline ESP32 exception decode, plotter beside terminal, macros+CRC. Order proposed: add capability check to both flashers before release, then terminal phase 1 on preview.
- 2026-09-30: Flasher usage statistics on PREVIEW only (branch flasher-analytics @86b3fb1, worktree ~/embeddedera-site-stats, https://flasher-analytics.embeddedera-site.pages.dev): /api/ev → D1 binding USAGE (schema migrations/0001_events.sql), allow-listed funnel events per tool, server-side geo/UA reduction, no IP/MAC/serial/file names; opt-out checkbox on both flashers, DNT/GPC honoured; privacy section #usage EN+ES (24-month retention). BLOCKED: the claude-plex token has no D1 scope (list/create → code 10000) — add Account → D1 → Edit, then set -a; source ~/.config/cloudflare/env; set +a; bash scripts/usage-db.sh creates ee-usage-preview/ee-usage and binds them to embeddedera-site (preview) / embeddedera-apple (production, no deploy); redeploy the preview after. Until then /api/ev answers 503 on the preview. Report: ~/.local/bin/usage-report (weekly md → projects/embeddedera-site/usage/, --sql, --local for the e2e DB); cron line (not installed): 0 7 * * 1 /home/angel/.local/bin/cron-run usage-report /home/angel/.local/bin/usage-report. Tests: node scripts/usage.test.mjs, bash scripts/usage.e2e.sh (local D1, Playwright 1.62 via uv).
- 2026-09-30: Flashers release candidate flashers-rc (https://flashers-rc.embeddedera-site.pages.dev): both flashers + shared BrowserCheck (feature-detected gate, Firefox 151+ has Web Serial so ESP32 works there, WebUSB/STM32 doesn't) + usage analytics (D1 via /api/ev; privacy section /privacy#usage; opt-out; DNT/GPC honoured; no IP/UA/MAC/file data). Sonnet review APPROVE. Release gates: owner real-board tests + Cloudflare token needs Account → D1 → Edit, then bash scripts/usage-db.sh (creates ee-usage-preview / ee-usage, binds USAGE) and install cron 0 7 * * 1 cron-run usage-report. Known debt: /api/ev rate cap keyed on client install id — add a global backstop if abuse appears.
- 2026-09-30: D1 permission added by owner. scripts/usage-db.sh created ee-usage-preview (8d9f6950-…) and ee-usage (5d35af43-…), applied migrations, bound USAGE (embeddedera-site preview, embeddedera-apple production) — existing UPLOADS/UPLOAD_SECRET bindings verified intact (backups of both project configs in scratchpad). Preview verified: real visits stored with only the documented fields. usage-report cron installed (Mon 07:00) + cron-watch usage-report=192. Production starts collecting when the flashers release.
- 2026-09-30: RELEASED ESP32 browser flasher (https://embeddedera.com/tools/esp32-flasher/) after the owner's real ESP32-C3 test: chip/file safety checks, BrowserCheck, disconnect handling, esptool.py-style hard reset (esptool-js 0.7.0 HardReset only released RTS → chip stayed in download mode; fixed with DTR low + RTS pulse), usage analytics live (first production event stored). STM32 flasher shipped UNLISTED (/tools/stm32-flasher/: noindex, not in sitemap or tools index) until tested on a real board — then remove the noindex prop, the index comment and the sitemap filter. Remote branches kept; local worktrees removed.
-
2026-10-27: Eugene's 5th/6th emails read; plan in Open (dedupe regression from 01f46cb confirmed by running old vs new opampPairs; two new tools requested). Awaiting owner pick of order.
-
2026-10-27: Eugene 10-27 items BUILT, preview only (NOT merged): branch tool-eugene-oct27 (worktree ~/embeddedera-site-ratiofix; = tool-dedupe-fix 5149133 + tool-ratio-tools c735111, worktree ~/embeddedera-site-ratiotools), preview https://tool-eugene-oct27.embeddedera-site.pages.dev . Dedupe key = ratio + R2 mantissa (decade copies only); op-amp Max error + total R1+R2 range; new /tools/resistor-ratio/ (2/3 resistors, switchable divider) and /tools/level-shifter/ (design + check), EN+ES, math in src/lib/ratio.ts. Gates: calc.test, astro check 0 errors, build; preview e2e opamp 241 / divider 48 / regulator 231 / ratio 40 / levelshift 42 ok, 0 FAIL. Eugene's acceptance case 39k/56.2k/14.7k 0.025 % on both pages. Next: owner OK → rebase on origin/main, merge, check live, remove both worktrees/branches; then mail-draft reply to his 19:41 message.
-
2026-10-27: Owner asked for a current limit on the ratio finder → added on tool-eugene-oct27 (Codex 921ea54: V + Max current fields, current column, filter before ranking; Claude 004f406: limit turned into resistance bounds via currentFloor, 1-3 s → <50 ms, test proves identical to predicate-only search). Preview redeployed; e2e ratio 72 / levelshift 42 / opamp 241 ok. Still NOT merged; awaiting owner 'merge'.
-
2026-10-27: Codex read-only review of the whole Eugene thread vs code+preview: 35/41 DONE; gaps fixed on tool-eugene-oct27 bc78569 (Codex): Max error 0 = exact only (parseMaxError), Show all draws every result up to 5000, decade copy kept = nearest geometric middle of the total range (divider 5→3.3 V now 8.25k/16k… exactly his list; regulator 10.2k/3.4k). Preview redeployed; e2e divider 56 / regulator 231 / opamp 243 / ratio 78 / levelshift 42 / thermistor 149 ok, 0 FAIL. Reply notes: blank range = total 1k-1M (not ignored). Symbol options for the ratio finder sent to owner (out/ratio-symbol-options.png; recommended A star network); awaiting pick + 'merge'.
HANDOFF 2026-10-27 (Eugene 10-27 emails chat, >240k tokens)¶
State: everything Eugene asked for in his 18:36 + 19:41 emails (thread 1a166e861b5ef8f7) is BUILT on branch tool-eugene-oct27 (worktree ~/embeddedera-site-ratiofix, last commit bc78569, NOT pushed, NOT merged). Preview: https://tool-eugene-oct27.embeddedera-site.pages.dev (deploy: set -a; . ~/.config/cloudflare/env; set +a; bash scripts/deploy.sh embeddedera-site tool-eugene-oct27). Second worktree ~/embeddedera-site-ratiotools (branch tool-ratio-tools, merged into the above) and branch tool-dedupe-fix are superseded: remove after merge.
Done: dedupe regression from 01f46cb fixed (ratio + R2 mantissa key; mid-range decade copy kept); op-amp Max error + total R1+R2 range; Max error 0 = exact only; Show all draws up to 5000; new /tools/resistor-ratio/ (2/3 resistors, switchable divider, V + Max current with currentFloor fast path) and /tools/level-shifter/ (design + check), EN+ES, math in src/lib/ratio.ts. Codex full-thread review: all gaps fixed.
Checks passed at bc78569: calc.test, astro check 0 errors, build, preview e2e divider 56 / regulator 231 / opamp 243 / ratio 78 / levelshift 42 / thermistor 149 ok, 0 FAIL (PW_EXECUTABLE=/usr/bin/google-chrome uv run --with playwright python scripts/<x>.e2e.py <base>).
Open questions for the owner: (1) ratio-finder symbol — options in ~/claude-remote/out/ratio-symbol-options.png (Now / A star network / B shared R1 / C bars); Claude recommends A (it is the Y circuit Eugene described; he did not pick it) or A for 3-resistor + B for switchable mode; current schematic is src/components/RatioSchematic.astro. (2) "merge".
Next action: apply the chosen symbol (if any), redeploy preview, rerun ratio e2e; on owner "merge": rebase on origin/main, merge to main (push deploys), check live pages + production e2e, remove worktrees/branches; then mail-draft --reply-to-id on Eugene's 19:41 message (UNSENT, plain links): yes we changed the pair search on 10-23 (01f46cb) and fixed it; links to op-amp case, ratio finder (39k/56.2k/14.7k), level shifter; blank range = total 1k-1M, not ignored; don't correct his 0.666 slip; optionally ask if symbol A reads right.
-
2026-10-27: Owner asked to let Eugene test the preview now. UNSENT Gmail draft 'Re: Voltage divider calculator' (threaded on his 19:41 msg 000001dd664b$2c4b0fc0$84e12f40$@rogers.com) with preview links + attachment ~/claude-remote/out/ratio-diagram-options.png (asks which drawing). mail-draft gained --attach. Preview alias must stay up until he replies; after merge send him the live links.
-
2026-10-28: Owner SENT the preview reply to Eugene (01:07 UTC, msg 1a1800c25da9e691). Eugene wrote at 15:01 UTC (msg 1a1830781144e638, quoting his own 10-27 18:36 email, describing the LIVE site): suggests (1) Max error on op-amp or drop op-amp tool (same as divider: IA = G = ratio+1); (2) make Max error mandatory with default 0.5/1 %; (3) make Total R1+R2 mandatory, default 10k-100k; (4) then results are complete. Analysis: (1) done on preview, keep op-amp, maybe add equivalence line; (2) decline: E24 12->5 V has 0 pairs within 0.5 %, 3 within 1 %, and the dedupe fix already shows all exact pairs; (3) reasonable: visible 10k-100k default on divider + op-amp (5->3.3 V E96+E24 0.5 %: 173 pairs vs 519). Owner to choose (a) equivalence line, (b) visible 10k-100k default; wait for Eugene's preview feedback before replying.
- 2026-10-29: Eugene's NEW email 'Calculators' (23:21 UTC, new thread 1a189f7ce4fc3873, NOT a reply to our 10-28 preview email): shares his two Excel sheets (Resistors_Ratio_2_and_3, Divider_with_Offset) as references for web tools; P.S. he has not tested our preview yet. Checked: our tool-eugene-oct27 ratioSearch returns every triple his sheets list (ratio 2:5 at 0.2 %: 15/15; offset ±10 V→0.2–4.8 V: 4/4 + one more, 43/62/16.2, that his nearest-only lookup misses), peak errors equal to 5e-5 %; offsetDesign/offsetNode/switchTargets match his cells to the digit. Only gap: input impedance R1 + R2∥R3 (his C13) → added on tool-eugene-oct27 (commit below, preview redeployed, calc.test + astro check + build pass, levelshift e2e 42 ok 0 FAIL; shows 50.7 kΩ for 39k/56.2k/14.7k). Still NOT merged; awaiting owner 'merge' + Eugene's preview test.
- 2026-10-29: Owner: level-shifter schematic labels overlapped (node V ran into the op-amp + input, ADC V crossed by the feedback wire). Fixed on tool-eugene-oct27: node label right-aligned left of the node, ADC value above the terminal; preview redeployed, checked EN/ES/375 px/negative values by screenshot. Eugene's math reviewed: Millman derivation, RT2/RT3, Vref_min, switch RAT2=1/A2−1/A1 all correct.
- 2026-10-30: UNSENT Gmail draft 'Re: Calculators' to Eugene (threaded on 000201dd67fc$30b7bbf0$922733d0$@rogers.com): thanks for the sheets, both tools match them, 4 prefilled preview links (offset ratios → 39k/56.2k/14.7k, ratio 2:5 → 15 sets, switch 2/3→1/3 → 15k/30k/10k, level shifter ±10 V→0.2-4.8 V), input impedance added, two gentle notes on his sheet (nearest-only lookup misses 43k/62k/16.2k; ratio error vs Vout error), asks for preview feedback before going live. All links checked in a browser. Preview alias must stay up until merge.
- 2026-10-30: Eugene's 7th email (10-31 00:58 UTC, thread 1a166e861b5ef8f7, regulator notes; he tested LIVE, which lacks the dedupe fix) DONE on tool-eugene-oct27 7334b52 (NOT merged; preview redeployed): feedback pin current defaults to 10n (empty = 10n in FB mode, 0 = off, ADJ clears it), 'Leave empty' note gone; Max error on the regulator (regulatorPairs maxError, as divider); labels Resistor tolerance (common, divider too) / FB divider current (R1 current) column shows itop in FB mode / Feedback pin current; schemGuide '≥250× FB bias · 5–10 mA' removed; siHint 'Accepts 4k7, 4.7k, 10µ (or 10u), 10n, 2R2, 2M.' EN+ES. calc.test (+his case), astro check 0, build, preview e2e regulator 235 / divider 56 / opamp 243 / ratio 78 / levelshift 42 / thermistor 149, 0 FAIL. With 10 nA the top pair at 0.8→3.3 V E96+E24 is 499k/160k (bias helps), then his 1.8k/576, 2.4k/768, 7.5k/2.4k. Not done: his 10-28 asks (mandatory Max error default, 10k–100k total default) still await the owner's pick; 'merge regulator into divider' read as same features, not one page.
- 2026-10-31: RELEASED tool-eugene-oct27 (main 80803a9, merge; conflicts in tools.ts + tools/index.astro resolved as union with resfault; deploy run 41202570486 success). Gates on main: calc.test, astro check 0, build. Production e2e: regulator 235 (one rerun; first run caught a third-party 'null.sequence' page error, not ours) / divider 56 / opamp 243 / ratio 78 / levelshift 42 / thermistor 149, 0 FAIL; /tools/, resistor-ratio, level-shifter (EN+ES) 200. Removed worktrees ratiofix + ratiotools, branches tool-eugene-oct27, tool-ratio-tools, tool-dedupe-fix. UNSENT Gmail draft 'Re: Voltage divider calculator' to Eugene (threaded on 000001dd68d2$f45624d0$dd026e70$@rogers.com) with live links. Still open: his 10-28 asks (mandatory Max error, 10k–100k default) await owner pick.
- 2026-10-31: Owner picked Eugene 10-28 items 2+3 (declined mandatory Max error default: E24 12→5 V has 0 pairs within 0.5 %). BUILT on branch tool-range-default (worktree ~/embeddedera-site-rangedef, NOT merged; preview https://tool-range-default.embeddedera-site.pages.dev): divider + op-amp total R1+R2 prefilled 10k/100k (cleared = 1k–1M, URL keeps rmin=&rmax=), op-amp line 'non-inverting G = divider Vin/Vout = G, Rf/Rg = G − 1' EN+ES. astro check 0, build; preview e2e divider 57 / opamp 243 ok 0 FAIL. Old links without rmin/rmax now open at 10k–100k. Next: owner 'merge' → merge to main, prod e2e, remove worktree; tell Eugene (mention the declined Max error default with the reason).
- 2026-10-31: RELEASED tool-range-default (main 2ae382c fast-forward, deploy run 41208248548 success); production e2e divider 57 / opamp 243 / regulator 235 ok 0 FAIL; worktree + branch removed. Eugene's thread now has nothing open on our side. New COMBINED unsent draft to Eugene (10-31 regulator fixes + 10-28 range default/equivalence + why Max error stays optional); the earlier 10-31 draft (same subject) is superseded — owner deletes it and sends the newer one.
- 2026-11-01: Eugene's 3 new emails (10-31 16:57 ratio finder, 11-01 02:52 + 14:43 level shifter, thread 1a189f7ce4fc3873 / 1a197906792bc8ba, new sheet Z_Divider_with_Offset_EL_to_AD2.xlsx) ALL BUILT on branch tool-eugene-nov1 (worktree ~/embeddedera-site-nov1, NOT merged; preview https://tool-eugene-nov1.embeddedera-site.pages.dev). Level shifter: design mode had R1 prefilled 39k (fixed R1) → R1 field verify-only, Peak ratio tolerance 0.2 %, 12-col table (Vout + stacked currents at Vin min/0/max, a, b), sink note, summary removed; check mode Vin=0 default, 4 lines. Ratio finder: v1/v2/v3 + imax via new ratioSearch
mins; per-mode range labels; maxerr 0.1 default; <1e-4 % shown as 0 %; switchSearch ranks by attenuation error (7.5k/15k/4.99k = 0.1001 %, in at 0.11 %, listed as 75k/150k/49.9k); drawings for change-over + R3 parallel NO contact; links divider<->switchable. All tools: 'Show more results (n)' / 'Show only the first n'; maxerr placeholder removed on divider/op-amp/regulator; regulator card 'FB divider current' (itop). check-seo: query string allowed on internal hrefs. R2a↔A1 was already so in code (new drawing makes it explicit). Gates: calc.test (+switch/mins/level-shifter), astro check 0, build; preview e2e ratio 82 / levelshift 48 / divider 57 / opamp 243 / regulator 235 / thermistor 149, 0 FAIL. The unsent combined draft to Eugene is stale (predates these): rewrite after owner OK. He offered a Teams/Zoom call. - 2026-11-11: Eugene status check. tool-eugene-nov1 (feabe0a) still NOT merged, 28 commits behind origin/main; preview up. Two newer emails NOT yet handled: 11-02 01:50 (thread 1a166e861b5ef8f7, his [EL 2026-11-01] remarks on our 10-27 preview email: op-amp range label 'Total Rf + Rg/Rin' → 'Total Rf + Rg'; inverting drawing: rename Rin to Rg, current-flow dash runs past the Rin/Rf node into the op-amp input, fix or remove; divider OK) and 11-02 18:57 (thread 1a197906792bc8ba, Rev.3 sheet Z_Divider_with_Offset_EL_to_AD3.xlsx, replaces AD2; cosmetic/comments only). Two duplicate unsent drafts 'Re: Voltage divider calculator' are stale (cover only what went live 10-31).
- 2026-11-11: Eugene 11-02 op-amp notes DONE on tool-eugene-nov1 (rebased onto origin/main cae919f; commits eded911 + 4eb1e99, NOT merged, NOT pushed: force-push after rebase blocked by auto-mode): inverting Rin renamed Rg (drawing, table column, formula, pitfalls, zin note, EN+ES; cols.rin removed), range labels 'Total Rf + Rg, min/max', help '(Rf + Rg)', inverting current-flow dash now Vin → Rg → node → up through Rf → out (no longer into the − input). Gates: calc.test, astro check 0, build; preview redeployed; preview e2e opamp 243 / divider 57 / regulator 235 / ratio 82 / levelshift 48, 0 FAIL; screenshot checked. Next on owner 'merge': merge to main (push deploys), production e2e, then one new reply to Eugene replacing the two stale drafts.
- 2026-11-11: RELEASED tool-eugene-nov1 on owner 'merge' (main fast-forward cae919f → 4eb1e99, deploy run 43142904952 success). Production e2e opamp 243 / divider 57 / regulator 235 / ratio 82 / levelshift 48 / thermistor 149, 0 FAIL; op-amp, level-shifter, resistor-ratio EN+ES 200. Worktree ~/embeddedera-site-nov1 + branch removed. New reply to Eugene = UNSENT draft (mail-draft, thread 1a166e861b5ef8f7, on 000401dd6a6c$8991aa20$9cb4fe60$@rogers.com): level shifter per his 10-31/11-01 flow (live example 39k/56.2k/14.7k 0.025 %, a 0.2300431, b 2.499864 V), ratio finder, op-amp Rg fixes, Show more/fewer, the 10-31 items, call offer via /book. Two older drafts in the same thread (1a1924aa3a53d762, 1a19209c31e1d7a8) are superseded: owner deletes them. Eugene's thread: nothing open on our side.
Decisions¶
- 2026-09-30 (owner): the public flashers stay BASIC — they block clear mismatches (wrong chip/revision/size/invalid file) but don't guard every way to misuse a firmware (e.g. erase-all + app-only image, partition-table/OTA-slot handling). Misuse is the user's responsibility; deeper customisation (production mode, own bootloader, signed packages, smart app-slot handling) is paid engineering work. The app-only guard built on 2026-09-30 was discarded unmerged.
- 2026-09-30: RELEASED flasher disclaimer (above Flash + confirm dialog), /terms 'Free online tools' (EN/ES; drafted plain-English, NOT legal advice — owner/lawyer to review) and /licenses generated at build from node_modules (scripts/generate-licenses.mjs; check-licenses.mjs verifies all 7 bundled packages: esptool-js, jszip, modern-screenshot, papaparse, spark-md5, webdfu, whats-that-gerber). Footer links Terms + Licenses.
- 2026-09-30: Google data connected. Search Console read-only OAuth (scope webmasters.readonly, GAM's Desktop client; token 0600 ~/.config/google/searchconsole-token.json; helper ~/.local/bin/gsc-auth — fixed to persist the PKCE verifier between url/finish and allow the http loopback redirect). ~/.local/bin/search-report adds Google search + PageSpeed sections to the Monday usage-report. First week (W39): 99 impressions (+230%), 1 click, avg position 6.6; top page the browser-flashing note; PageSpeed mobile 99–100. Found duplicate indexing of /faq vs /faq/ → trailing-slash canonicalisation added to the SEO pack.
- 2026-09-30: Bing Webmaster connected (owner imported from Google Search Console; API key 0600 ~/.config/bing-webmaster/env — owner to add to Vaultwarden). Sitemap registered via SubmitFeed (NOT SubmitSitemap, which 404s — scripts/bing-sitemap.mjs on seo-pack uses the wrong method, fix before merge); site URL form is 'https://embeddedera.com/'. SubmitUrlBatch (10,000/day quota) used for the tool/terms/licenses URLs.
- 2026-09-30: Owner spotted the tab icon wasn't the logo: public/favicon.svg was a two-hexagon placeholder (copper + gold rings). Replaced with the real mark extracted from Notes/brand/artwork/logo/embeddedera-lockup.svg (the 4 mark paths above the wordmark) in copper #c8813f on #0b0d10; added favicon-32.png fallback; regenerated apple-touch-icon (180) and icon-192/512 (maskable-safe padding). Live 47ed99f. Search results may show the old icon until Google recrawls.
- 2026-09-30: Live today: SEO pack (62 pages pass check-seo gate; trailing-slash canonical + 301s; IndexNow on production deploys; Bing Webmaster connected), real-logo favicon, per-note share images (public/og/notes/, scripts/og-notes.mjs). Paused for a session restart (helpers move to Sonnet 5.5), all pushed as WIP, unreviewed: branch tools-grid (owner picked real schematics for calculator cards + Tabler icons for checks/flasher; thumbnails still need circuit-only fill), calc-batch2 (battery life + number converter + ADC resolution), serial-terminal (Phase 1). Details were in the Claude memory handoff-2026-09-30-tools (deleted 2026-10-19: everything in it, including utm-capture and serial-terminal, was merged into main by 2026-10-15; see git history).
- 2026-09-30: tools-grid/calc-batch2/serial-terminal finished on previews (23d953e/238749c/bb00084); awaiting owner review before merge.
- 2026-09-30: Owner approved battery-life, number-converter, adc-resolution. calc-batch2 merged into tools-grid (8c46de7); independent Sonnet review found hex-prefix bug, fixed 1ecdcdb. Release waits on owner OK of resistor + binary icon. serial-terminal waits on real-board test. Social art in Notes/brand/artwork/social (FB cover needs manual upload: token lacks pages_manage_metadata).
- 2026-09-30: SOP-018 6.4 link-tag rule. Tags live in x-post-prompt, FB caption + Story builders (assistant c7687cf, story-publisher sandbox fec6377, path-only link checks). IG bio code default tagged (39d4df8); live bio needs owner's manual edit. Quote/contact forms keep first-touch tags → 'source' line in the Web3Forms email: branch utm-capture fde0059, preview verified (e2e on deployed preview). Release of tools-grid blocked on production-deploy permission; owner to add /permissions rule or run deploy by SSH.
- 2026-09-30 ~22:00: RELEASED tools-grid to production (main 0d98082): /tools/ card grid + new resistor + battery-life, number-converter, adc-resolution (EN+ES). Live pages 200, sitemap + IndexNow done. Main checkout needed npm ci for @tabler/icons before build. Owner added allow rule Bash(bash scripts/deploy.sh embeddedera-apple main) to ~/.claude/settings.json so Claude can deploy production after an in-chat yes. Next: utm-capture (fde0059) awaiting owner approval; serial-terminal awaiting real-board test.
- 2026-09-30: serial-terminal 161b8fb: auto-reconnect dropped (owner), reset default None, esp32-usb-jtag profile removed, RX stream log fix, xterm licenses + check-licenses dependency gate; independent Sonnet review PASS. Awaiting owner 2-minute board retest, then release with redrawn ESP32 card + ADC type fix.
- Every image on embeddedera.com must be our own photo (owner rule 2026-09-30). Branch own-photos in ~/embeddedera-site-photos replaces stock/blurry images with the graded shop photos in Notes/brand/artwork/photos/studio/; inventory at Notes/audits/photos/inventory.md. Slots with no truthful match → owner shoots them.
- 2026-09-30: own-photos branch (preview https://own-photos.embeddedera-site.pages.dev, 5fba2fa): stock and blurry photos replaced by shop photos on / and /services; firmware and membrane slots still need owner photos, see audits/photos/inventory.md.
- 2026-10-01: Gerber viewer spike: tracespace v4 (pcb-stackup 4.2.8 + gerber-to-svg 4.2.8, MIT, pinned; maintainer on hiatus) renders UT-002 (4-layer KiCad X2), Robot Cow 004B, Arduino Uno (Eagle) and Altium-style core correctly (mask/silk/copper/drills/outline, top+bottom). UT-002 stackup 0.57 s Node, 0.82 s in-page unthrottled, 2.9 s end-to-end at 4x CPU throttle; dist bundle 42 kB gz (page total JS 119 kB gz incl. jszip/whats-that-gerber/papaparse). Needs buffer/events/process polyfills (aliased in astro.config.mjs). wasm-gerber-renderer not needed. Built as /tools/gerber-viewer on branch gerber-viewer in ~/embeddedera-site-gerber (0948aa1), preview https://gerber-viewer.embeddedera-site.pages.dev. Shots in ~/Notes/audits/gerber/.
- 2026-10-01: Gerber viewer Phase 2 on gerber-viewer (c92b4b5, preview https://gerber-viewer.embeddedera-site.pages.dev): side layer panel, open test fixtures (Particle Core CC BY-SA; RF-Clown Altium MIT), overlay with rotation/outlines/offset, drill table, measure, Web Worker (6-layer IMU_Array, MIT: 4x-throttled main-thread block 1793 -> 666 ms), ODB++ only recognised: wasm-gerber-renderer ODB++ is Node-only (native node-gles build fails), not shipped. Shots ~/Notes/audits/gerber/p2-*.png
- 2026-10-01: Gerber viewer (branch gerber-viewer a31adc4): tracespace v4 in a Web Worker, layers panel right, overlay/drills/measure; ODB++ not feasible in-browser (wasm-gerber-renderer is Node-only) — page tells users to export Gerbers. Independent review FAIL→fixed→PASS. Awaiting owner 'release'. own-photos (ba8428f) incl. UT-002 BOM image awaiting 'release photos'.
- 2026-10-01 ~08:25: RELEASED own-photos + gerber-viewer to production (deploy 0fbf4d1a). Found + fixed: the 07:00 daily note release had silently not deployed — check-seo failed on a 70-char title (' — EmbeddedEra' suffix pushed a 56-char note title past 60). Fix: Base.astro drops the suffix when it would exceed 60; notes page passes the bare title. Note now live before the 09:05 Story. Remaining stock image: services firmware (pexels-943096) until owner shoots a replacement.
- 2026-10-01: RELEASED geo-pass (deploy 1598947c): llms.txt generated from registry+notes, FAQPage on 28 tool pages, Article author/publisher logo, check-geo build gate. Open for owner: GBP verification (task #119), phone (#140), LinkedIn URL; optional visible FAQ questions + note lead summary.
- 2026-10-05: Website note dates fixed (embeddedera-site fc5de60, deployed): notes show the live date (publish commit), not the writing date — newest showed Sep 28 though notes went live daily to Oct 4. Follow-up: port fc5de60 to the apple-style dev branch (cherry-pick conflicts in src/pages/notes/[...slug].astro). Also: no note on Oct 5 — reserve paused for 11 h by the weekly-capacity guard during the heavy build day; week reset, refill resumes.
- 2026-10-06: /cricket instructions page (EN+ES) built on branch cricket-page (worktree ~/embeddedera-site-cricket), PREVIEW only at https://cricket-page.embeddedera-apple.pages.dev/cricket/ — not production. Facts from unmerged branch no-accelerometer (PR #1, b688e2d) firmware; open questions to owner listed in the handoff.
- 2026-10-06: Cricket QR page (branch cricket-page, preview https://cricket-page.embeddedera-apple.pages.dev/cricket/, permanent URL https://embeddedera.com/cricket/) revised with owner answers; behaviour checked against Cricket tag rev008 (main.c HandleUsbEvent 10 s window / 2x50 ms unplug / 3 s after 2nd-3rd plug / 4 plugs off; power_manager.c:14 arm delay 3600 s; OnWake quiet while VBUS) and TP4057 wiring (pin1 CHRG->D3 red, pin5 STDBY->D4 green). Not published; Spanish unreviewed.
- 2026-10-06: /cricket/ preview (branch
cricket-page): hero + OG image switched to the Cricket 008 labeled CAD render (owner-approved exception: renders of our own CAD are allowed on the site). Still unpublished; publish after bench checks and Spanish review. - 2026-10-06: Cricket page feedback form (branch
cricket-page, preview only, commit f061ace):functions/api/feedback.ts+_lib/feedback.ts(allow-list productcricket, honeypotwebsite, 4 KB cap, id-keyed idempotent write tofeedback/<product>/<id>.json, no IP/country stored),scripts/feedback.test.mjs, privacy section EN/ES. Leads had no owner review path beyond daily counts, so added host-side~/.local/bin/feedback-sync(cron */15: archive forever to ~/.local/state/feedback/, ntfy rating+tags only). R2 bucket 90-day lifecycle applies; archive keeps them. The preview project shares the production R2 bucket, so test records must be deleted by hand. - 2026-10-10: STM32 browser flasher LISTED on the owner's go-live call (no real-board test yet): tools.ts listed:true, noindex removed, sitemap filter removed; deployed to production main, IndexNow submitted. Verified live: no robots noindex, on /tools/ and /es/tools/, in sitemap.
- 2026-10-10: Listings plan agreed (owner asked "plan for 5"). Site already links Facebook + Instagram (+ X in site.ts). Open below.
- 2026-10-12: Merged main into apple-style (487e174, pushed; CI deploy green) so the dev preview https://embeddedera-site.pages.dev matches production plus the queued notes (7 unpublished notes still only on apple-style). Published notes, Footer, i18n took main; build script = main's chain + diagrams step.
/termsconflict: main's live "Terms of use" kept; the unreleased Terms of sale and limited warranty draft is preserved at tagterms-of-sale-draft— it needs its own URL (e.g. /terms-of-sale) before it can be released. - 2026-10-12: Mac set up for site work:
~/embeddedera-siteon the Mac tracks main (= embeddedera.com; verified titles + 26 notes match live).apple-styleis NOT a fresh base: it is 142 commits behind main and holds ~60 unreleased commits (queued weekly notes, terms page) that must not ship by merge — branch site tweaks off main. Node 26 (CI 24), build/checks clean. Dev server via.claude/launch.jsonin ~/Documents/GitHub (port 4321). Deploy from the Mac = git push only; no Cloudflare token or deploy.sh/wrangler there. - 2026-10-12: Push-to-deploy via GitHub Actions so the owner can edit the site from the Mac. Verified: manual run deployed main to main.embeddedera-site.pages.dev; a push to apple-style deployed the dev preview (run 38282373437). The production path (push to main) has not run in CI yet; the next note release is its first run. apple-style took main's deploy.sh + indexnow.mjs (dev had the pre-IndexNow script). Server jobs publish-note/weekly-research pull before pushing (backups in ~/.local/state/*.bak.20261012).
- 2026-10-12: Found full-res originals for site photos in Immich (matched by image hash against Immich previews; asset table in immich-postgres maps id -> originalPath under /mnt/storage/immich/library): station.jpg = admin/2026/2026-08-08/IMG_2146.heic (5712x4284), optical-head.jpg = IMG_2140.heic (4284x5712); video posters come from 1080p videos: led-test-poster/led-verify = IMG_2145.mov, livestock pick-and-place-poster = 2026-07-11/IMG_2016.mov, boost-gauge bench-run-poster = 2025-05-04/IMG_7116.mov, esp32-prototype = 2025-05-03/C030AF69….mp4. Shop photos (pnp/test-trays) originals are in brand/artwork/photos/originals (2576x1932). Not found: cricket/ (4), boost-gauge installed + switch-blank, apc.jpg. src/assets/wp/pexels-photo-943096.jpeg is a stock photo still used on services.astro*: breaks the own-photos rule; replace it (candidate: NAS design/edited/boards-deck-2).
- 2026-10-12: Home hero replaced with a PhotoCraft re-edit of the full-size original (Immich admin/2026/2026-09-19/IMG_2589.heic; 3:2 crop, no cut-out mask, natural grade, watermark), approved by owner; live on embeddedera.com via the first GitHub Actions production deploy (run 38302090928, commit fd3f2be on main), verified as the served 1400x934 WebP. Recipe: NAS design/edited/home-hero/edit.py. Pick-and-place card original = Immich IMG_2586.heic (same shoot). The Universal Tester station photo was re-edited on apple-style only (0daef6a): that page is parked, so it shows nowhere yet.
- 2026-10-12: Home pick-and-place card replaced (PhotoCraft re-edit of Immich IMG_2586.heic, watermark option A), owner approved; live via CI (commit 164435a on main), verified as the served 1400x875 WebP. Recipe: NAS design/edited/home-pnp/edit.py. Next: home test card (optical-head.jpg, original Immich admin/2026/2026-08-08/IMG_2140.heic 4284x5712).
- 2026-10-12: Home "Enclosures and fixtures" card got its first image: fixture box with acrylic window (Immich admin/2026/2026-07-18/IMG_2061.heic, PhotoCraft re-edit, watermark A), alt text EN+ES; owner approved; live via CI (26eb864), verified on / and /es/. Candidate visuals for more variety are on the NAS in design/research/ (immich-candidates., projects-candidates.: Cricket BOM, KiCad renders, test-data chart).
- 2026-10-12: Home testing card replaced (PhotoCraft re-edit of IMG_2140.heic, same 3:4 framing, laptop screen blurred, watermark A); all four home photos are now full-size re-edits with the watermark. Found that embeddedera.com kept serving cached home HTML pointing at old image hashes after a deploy; scripts/deploy.sh now purges the Cloudflare zone after every production deploy (CI secret CLOUDFLARE_ZONE_ID), verified "cache: purged" in the CI log.
- 2026-10-12: Owner found the Services membrane photo (src/assets/wp/apc.jpg, WordPress era) is someone else's: removed (also public/media/site/apc.jpg) on branch services-refresh, after I had wrongly watermarked it. Copyright lines on drawings centred so the 2rem rounded corners do not clip them. Preview: services-refresh.embeddedera-site.pages.dev, awaiting owner "push".
- 2026-10-12: Services update LIVE (merge 9354206 into main, cache purged): reflow-oven top photo, KiCad routing (with centred (c) line), real JumpToBootloader() code + STM32 photo replacing the stock photo, re-edited SMT photo, third-party membrane photo removed, bootloader/OTA wording on Services + home Firmware card (EN+ES). Schematic/BOM kept as owner asked. Verified on /services/, /es/services/; old /media/site/apc.jpg now 404. apple-style merged with main. Owner confirmed 2026-10-12: the WordPress-era PIC18 schematic (src/assets/wp/kicad-schematic.png) is ours; it stays. Cricket schematic also available at NAS design/edited/services/schematic-cricket-2800x1660.png.
- 2026-10-13: apple-style audit: by file content only 25 files differ from main (8 queued notes + diagram feature + tools/), not the 77 commits git counts. The branch is the live notes queue (publish-note, weekly-research, note_queue, waiting, content_buffer, story-handoff, sop-audit, render-note-*) — never delete it. Owner decisions: drop the re-edited Universal Tester station photo (reverted on apple-style fabc50a, never shipped); move tools/ out of the site (now ~/assistant/tools, assistant e1fb130; ~/.local/bin/render-{card,cards,diagram,doc} repointed; removed from site d91a9a7); diagram styling on preview https://diagrams.embeddedera-site.pages.dev/notes/microcontroller-end-of-life/ (branch
diagramsoff main, worktree ~/embeddedera-site-diagrams) awaiting owner OK; rename apple-style -> notes-queue (worktree -> ~/embeddedera-site-notes, compat symlink at old path) prepared, run by owner because the classifier treats it as a production deploy. - 2026-10-15: Service pages wave 1 approved (PCB design, firmware, SMT assembly, test fixtures, R&D, obsolete-parts on the template; second wave: reverse engineering, enclosures, membrane, apps). Sample built: branch
service-pages, worktree ~/embeddedera-site-services, templatesrc/pages/services/[slug].astro+ ES wrapper, copy inservicePages(en/es), SERVICES paths for PCB/schematic/BOM → /services/pcb-design, Organization JSON-LD got@id; preview https://service-pages.embeddedera-site.pages.dev/services/pcb-design/ ; build gates pass (89 pages). Waiting on owner facts (turnaround, layers >6, minimum job, review rounds, source-file ownership). /quote has no request-type preselect from the URL yet. Site search being built in parallel onsite-search(MiniSearch; Pagefind rejected: no typo tolerance). - 2026-10-15: Owner rule: the website never states who owns a design; the quote and agreement decide (contract terms may differ). Neutral wording on branch service-pages (R&D FAQ, PCB FAQ, quote-form engagement labels + help, EN+ES; the help no longer cites the unpublished clause 9). Submitted engagement values unchanged. Still LIVE on embeddedera.com until released. Terms-of-sale draft (notes queue, c093068) clause 9 already defines ownership per engagement type and keeps background IP; lawyer review pending.
- 2026-10-15: Site search built on branch
site-search(0e3c845, worktree ~/embeddedera-site-search), preview https://site-search.embeddedera-site.pages.dev . MiniSearch 7.2.0, index built from dist/.html after build (drafts/noindex excluded), en 88 docs ~51 KB gz, es 60 docs ~25 KB gz; 730-byte opener on page load, rest lazy. Typos/prefix/accents/synonyms tested (scripts/search.test.mjs). Zero-result eventsearch_missadded to /api/ev allow-list + /privacy#usage. Known: group order fixed (Services, Notes, Calculators, Pages); FAQ hits link to /faq/ (no per-question anchors); screen-reader use untested. Releasing: service-pages and site-search both touch src/i18n/.ts and Nav; release one, then rebase the other. - 2026-10-15: Privacy page rewrite on branch
privacy-rewrite(worktree ~/embeddedera-site-privacy), preview https://privacy-rewrite.embeddedera-site.pages.dev/privacy/ . Owner: no product names; providers described by role. Microsoft Clarity named once (+ Microsoft Privacy Statement link) per Microsoft's disclosure guidance; the EU consent banner also names Microsoft. All old commitments kept (phrase-checked EN+ES), #usage/#clarity anchors kept, ~25% shorter (EN ~1,260 words incl. nav/footer). Peer check: Adafruit/SparkFun/Seeed name vendors, MacroFab uses categories, Pololu has no findable policy. Release order: wording fixes (service-pages ownership copy) → privacy → search (search must carry its search_miss disclosure into the new #usage wording) → service pages. Set the effective date at release. Optional additions NOT made (owner decides): response deadline, rights for all US residents, change-notice promise. - 2026-10-15: Owner rule: the privacy policy names no products or tools (more are coming); it describes kinds of tools (upload-and-check, in-browser design-file readers, browser board programmers) and 'our products'. Only exception: Microsoft Clarity, once, with Microsoft's privacy statement link. New products/tools need no privacy edit unless they collect something new. Preview updated (privacy-rewrite).
- 2026-10-15: Master lists, one fact one home (owner). MCU_FAMILIES done (d07e317; footer names no chips). In progress on service-pages: CONNECTIVITY (owner-expanded: UART, RS-232, RS-485, I²C, SPI, CAN, LIN, USB, Ethernet, BLE, Wi‑Fi, sub-GHz/2.4 GHz radio; LIN and SPI confirmed by owner), ASSEMBLY_LIMITS, TEST_CHECKS, PCB_DELIVERABLES, plus scripts/check-repeats.mjs (build warning, allow-list) that reports lists/sentences repeated across en/es copy.
- 2026-10-15: Master lists done on service-pages (9206b1f + 383416e): src/lib/facts.ts holds MCU families, connectivity (UART, RS-232, RS-485, I²C, SPI, CAN, LIN, USB, Ethernet, BLE, Wi‑Fi, sub-GHz/2.4 GHz), SMT limits (0402, BGA 18×18 mm, 8.0×10.5 in, 52 reels, ±0.02 mm), test checks, PCB deliverables; site.ts re-exports; llms.txt header uses {{placeholders}} filled by llms.mjs. scripts/check-repeats.mjs runs after check-seo (warn-only, allow-list scripts/check-repeats.allow.json, test passes): 56 remaining repeat pairs (four-weeks prototype sentence ×3, app-platform lists, service-name lists, hand-off list, bare-metal/RTOS/C, tools copy). Owner confirmed: reverse-engineering interface capture uses the full connectivity list (was UART, SPI, I²C, CAN, USB, RF).
- 2026-10-15: Master lists round 2 started on service-pages (lead-time sentence, service names, app platforms, hand-off list, firmware styles, tools boilerplate/browser support); goal: check-repeats at 0 un-allowed.
- 2026-10-15: Master lists round 2 done (service-pages 9a081c3 + d6e6512): facts.ts adds leadTime, service short names (svc/svcList/svcDots), platforms, handoff, shipsWith, firmwareStyle, portExamples, reverseSteps, cadFormats, appFeatures, browserSupport; tools-en/es share FLASHER_DISCLAIMER/APPROVED_HELP/FLASHER_OFFER. check-repeats 56 → 0 un-allowed (23 allowed with reasons). Dist diff: only list punctuation (English Oxford comma from Intl.ListFormat), 'a BOM' unified, ES 'por comodidad'. Not yet single-sourced (not flagged by the checker): FAQ 'KiCad native files. Altium or Eagle files by arrangement' (3rd phrasing of cadFormats); ES FAQ meta/tagline vs EN differ.
- 2026-10-15: CAD fact: we design only in KiCad (owner); cadFormats = 'KiCad files, or Altium and Eagle designs, which we move into KiCad', also used by the FAQ formats answer (service-pages). Competitor session-recording scan (homepage HTML + their Google Tag Manager containers): JLCPCB uses Microsoft Clarity (via GTM-W8FT5ZR); Screaming Circuits uses Hotjar; none found at MacroFab, Adafruit, SparkFun, Pololu, Seeed, PCBWay, OSH Park, Sierra Circuits (protoexpress), Bittele (7pcb), Advanced Circuits (4pcb), Digi-Key, Mouser. Limits: homepage only, tools loaded by other means are invisible; Digi-Key served a bot-check page.
- 2026-10-15: Owner rule: keep service copy generic — no layer counts, turnaround, minimum job size or review-round promises. Removed '2–6 layers' (PCB page + /services PCB specifics, EN+ES) and the layers FAQ; PCB steps no longer promise a review gate or source files ('files listed in your quote'). Owner (2026-10-15): no lead time anywhere on the site; the 2026-09-10 'as fast as four weeks' line, its FAQ and the leadTime fact are removed (service-pages).
- 2026-10-15: One review preview for everything: branch
review-combined(worktree ~/embeddedera-site-review) = main + service-pages + privacy-rewrite + site-search, https://review-combined.embeddedera-site.pages.dev . All gates pass (89 pages). Found while merging: the search's zero-result privacy line promised no email address is ever recorded, but beaconQuery only replaced '@' with a space; fixed (any '@' query is dropped) and tested. Release = fast-forward main to review-combined once the owner approves; then delete the four feature worktrees. - 2026-10-15 ~10:05: RELEASED service pages + master lists + privacy rewrite + site search to production: main 72d47ac → cc1b188 (fast-forward of review-combined), Actions run 38747518087 success. Verified live: /privacy and /es/privacy (Oct 15, no product names, search-miss line), /services/pcb-design 200, /quote no ownership wording, home no 'four weeks' and plain footer, /search-en.json 200; real-browser search test (Ctrl+K, 'fimware' → Firmware, ES 'placa') with no console errors. Removed worktrees/branches service-pages, privacy-rewrite, site-search, review-combined (all merged). Kept: diagrams (owner decision pending), apple-style (notes queue; rename still not run). site-preview.service no longer exists.
- 2026-10-15: Pruned 13 old site worktrees + local branches (calc-batch2, clarity, cricket-page, geo-pass, gerber-viewer, lead-source, own-photos, pubdate, seo-pack, serial-terminal, store-entry, tools-grid, utm-capture), all verified merged into main first; untracked leftovers were node_modules and one OG card already in main. Remote branches kept (their Pages preview aliases). Worktrees now: main, apple-style (notes queue), diagrams, service-pages-2 (wave-1 service pages in progress).
- 2026-10-15 ~10:15: Notes queue renamed (owner OK): branch apple-style → notes-queue (GitHub, local, Cloudflare Pages dev project production branch), worktree ~/embeddedera-site-apple → ~/embeddedera-site-notes (compat symlink at the old path for the running assistant.service). Scripts updated (~/.local/bin publish-note, weekly-research, sop-audit, render-note-, note-to-social, story-handoff, notebook-; assistant 6373d08), deploy workflow on main e30222a + notes-queue 4526310, both CI runs green. Older log lines keep the old name.
-
2026-10-15: Wave-1 service pages on preview: branch service-pages-2 (ecae44f, worktree ~/embeddedera-site-services2), https://service-pages-2.embeddedera-site.pages.dev/services/{firmware,smt-assembly,test-fixtures,rd-product-development}/ (+/es). New facts: updatePaths, rdPhase. All gates pass (97 pages), check-repeats 0, search index includes them, phone check by Claude on firmware. obsolete-parts-redesign left as its own page (its sections don't fit the template without losing content). Spanish not native-reviewed. Owner to review, then release.
-
2026-10-15: impedance accuracy pass (commit d848816, preview refreshed): microstrip pairs now Kirschning-Jansen static even/odd + Jansen thickness, single Hammerstad-Jensen (equations from the Qucs technical docs; Qucs/KiCad code is GPL so not copied; no MIT/BSD JS exists), stripline pairs Cohn (Rogers note 3.2.1, reproduces its 5880 example to 0.01). Vs OSH Park table: single +3.9 % (was +5.5), pairs +9.7 % / +10.3 % (were +10.7 / +14.1). 5 % NOT reached on pairs: their stack-up has 0.6 mil solder resist; a throwaway 2-D FD solve confirms mask explains the gap (bare 98/108 ohm, masked 87-95), but no citable closed-form mask correction was found (IPC-2141A embedded is paywalled; Barbuto 2013 COMPEL paywalled), so none applied and the page says so. Open: get Wadell sec. 3.7 or Barbuto 2013 to add a cited mask option.
- 2026-10-15: branch
tool-impedance(commit 97cf17c, worktree ~/embeddedera-site-impedance) adds /tools/impedance (+/es): PCB impedance calculator, microstrip/stripline, single or pair, solve width, JLCPCB 4-layer presets; closed-form (Hammerstad-Jensen/Wadell, IPC-2141A), no vendorable MIT JS found; pushed, not merged/deployed. Origin: KiCad forum 90 ohm USB question. - 2026-10-15: impedance tool presets extended (commit c972028, preview refreshed): PCBWay 4-layer 1.6 mm 7628 (3 residual-Cu variants) and OSH Park 2/4-layer, each with source URL + read date shown under the picker. Skipped (no Er+thickness published as text): Advanced Circuits, Bay Area Circuits, SF Circuits, PCB Universe, Sierra, CircuitHub, Aisler (variable stock), PCBWay 2-layer. Cross-check vs OSH Park's own impedance table: single 50 ohm +5.5 %, pair 90 ohm +10.7 %, pair 100 ohm +14.1 % (closed form reads high on pairs; test in scripts/impedance.test.mjs).
- 2026-10-15: impedance 2-D field solver (commit 915830f, preview refreshed): src/lib/impedance-fd.ts, own TS port of the quasi-static method (Laplace twice, C and C0, Z0 = 1/(c sqrt(C C0)); pairs even/odd), Web Worker, closed form shows first then is replaced; mask on by default (typical Er 3.3, 20 um; OSH Park preset 0.6 mil). Vs OSH Park table with conformal mask: +1.05 / +0.81 / +1.05 % (was +3.9 / +9.7 / +10.3 bare); filled-gap mask model gave -1.3 / -4.8 / -5.0 %, so conformal film it is. Bare vs closed form <= 1.95 %, Cohn exact stripline <= 0.87 %, grid x2 <= 0.46 %, box x2 <= 0.13 %. Not done: trapezoid etch. Tests in scripts/impedance.test.mjs, browser timing in scripts/impedance.e2e.py. Resolves the open item from the d848816 line (mask option, cited).
- 2026-10-15: Impedance tool got its own drawn visual (branch tool-impedance):
ImpedanceSchematic.astro+src/lib/impedance-sch.ts(cross-section: planes, dielectric h/εr, 1-2 traces w/s/t, mask; microstrip/stripline, live from the form, #sch so Copy image works); tools index card uses it instead of theequalicon (visual: 'impedance'). OG cards are text-only so unchanged. Site has no light theme on this branch (dark only). Preview https://tool-impedance.embeddedera-site.pages.dev ; not released to main. - 2026-10-15: STM32 flasher card now has a drawn visual (src/components/Stm32FlasherVisual.astro, same vis-* style as ESP32: board + STM32 + BOOT0 + USB DFU cable + 0x08000000 progress). Branch tool-stm32-visual 5297c7f, preview https://tool-stm32-visual.embeddedera-site.pages.dev/tools/; awaiting owner OK before release. Tool is WebUSB DfuSe, not UART.
- 2026-10-15: branch
tool-check-visuals(00e3b22, worktree ~/embeddedera-site-checkvis, preview https://tool-check-visuals.embeddedera-site.pages.dev/tools/): drawn card visuals BomCheckVisual + AssemblyCheckVisual replace the Tabler icons on the tools grid (card thumbnails only, like Gerber/flasher; neither tool page uses a #sch panel). Not merged. - 2026-10-15: Sensor integration + HMI/display service pages on preview: branch service-sensors-hmi (0e78921 + node_modules fix, based on release-2026-10-15-services a72a242 because wave-1 pages were NOT on main), https://service-sensors-hmi.embeddedera-site.pages.dev/services/{sensor-integration,hmi-displays}/ (+/es). Two pages (one topic per page like wave 1). Tags sensors/sensor/hmi/display/touchscreen map notes to them (offers.ts, tool-links.ts). Boost-gauge case study is parked (not live), so not linked; its photos copied to src/assets/photos/hmi-gauge-*. Owner to confirm claims.
- 2026-10-23: Reader email (Eugene, el_77@rogers.com) asked for an E96+E24 series and a max-error filter on /tools/voltage-divider. BUILT on branch
tool-divider-series(worktree ~/embeddedera-site-divider, uncommitted, NOT merged, NOT pushed):E96+E24series (114 values; ±1 % default) andMax error, %field (lists up to 50 pairs within the limit, EN+ES). His 5 V→3.3 V numbers recomputed independently and match (8.25k/16k 0.031 %, E96-only 0.135 %, E24-only 0.088 %); calc.test, astro check and build pass; 375 px has no horizontal overflow (screenshot timed out, not eyeballed). Not applied to regulator/op-amp pages (one-line option each). Reply to Eugene is a Gmail draft, unsent. - 2026-10-23: Dev preview of tool-divider-series deployed to Pages project embeddedera-site (alias https://tool-divider-series.embeddedera-site.pages.dev), production untouched.
- 2026-10-23: tool-divider-series (still uncommitted) now also has E192+E24 (205 values; also in regulator + op-amp dropdowns, E96+E24 too) and a "My own values…" parts-list option on the divider (absolute ohms, <=300 values, bad tokens reported, list sets its own search range, shareable via ?parts=). calc.test, astro check pass; preview https://tool-divider-series.embeddedera-site.pages.dev verified in-browser (custom 5 V->3.3 V picks 4.7k/10k). Not yet on main.
- 2026-10-23: RELEASED tool-divider-series (main @1de1f53, deploy run 39947784034 success; live page checked: E96+E24, E192+E24, maxerr, parts). Rebased local main onto origin/main first (it had diverged: 10 local note-publish commits vs 11 remote PR merges, no conflicts) so those 10 note commits went out too. Worktree and branch removed. Reply to Eugene is an UNSENT Gmail draft with the live link; owner sends it.
- 2026-10-23: Eugene's 2nd email (3 findings) FIXED on branch
tool-divider-fix(commit 099a631, worktree ~/embeddedera-site-dividerfix, NOT merged; preview https://tool-divider-fix.embeddedera-site.pages.dev). Causes: (1) a load was ignored when picking candidate R1 (r1For used R2 not R2||RL; also the same-ratio dedupe is wrong with a load) so loaded results were not the best (old top 0.07 % vs brute 0.0003 % for 5V->3.3V/100k); (2) result cap (5 default, 50 with max error) plus the nearest-two shortcut skipping a step when the ideal R1 lands on a series value; max error now lists ALL pairs (E96+E24 3 V, 0.1 % = 189, equals brute force), default view has Show all (50), render cap 1000; (3) tiny errors showed as -0.00 % (now 2 sig digits). Also near() now binary-searches the pool (default search 595 ms -> 9 ms at 1 ohm..10 Mohm). 'Getting lost': 40 random edits all equal a fresh load of the same URL, so no stale state found; likely the cap + series silently resetting tolerance. Tests: calc.test (brute-force vs search, with load), scripts/divider.e2e.py (11 checks, local + preview), astro check, npm run build. Awaiting owner OK to merge; reply to Eugene not drafted yet. - 2026-10-23: Audit of /tools/voltage-divider (EN+ES) on tool-divider-fix (not merged; preview https://tool-divider-fix.embeddedera-site.pages.dev): LIVE BUG since 2026-10-15 — commit 46fcaac put the impedance field-solver text into the divider's
formula(EN+ES, first match) and left the impedance page's formula stale; restored both. Also fixed: lead said 'five best' and ±1/5/10 %, meta said E12/E24/E96, tolerance pitfall (±5 % only true at Vout=Vin/2, up to ±10 % at small ratio), decade pitfall wrong with a load, range fields labelled 'Resistance from / to' but limit R1+R2, parseSI rejected '3,3' (ES page) and gave 9.999999999999999e-6 for 10u. Guard: calc.test checks each page's formula text. Clean: axe (1 site-wide minor), no console errors, 0 http>=400, labels, headings, hreflang, JSON-LD, OG card. Not changed: ES page prints numbers with a dot decimal while its copy uses commas. - 2026-10-23: Owner: the site writes decimals with a dot, never a comma. Removed the decimal-comma parsing from parseSI (tool-divider-fix); kept the 10u float fix. ES tools copy still has decimal commas in prose (e.g. 3,3 / 0,67π across impedance, thermistor etc.): sweep not done, awaiting owner.
- 2026-10-23: ES tools copy decimals changed from comma to dot (69 values in src/i18n/tools-es.ts, branch tool-divider-fix; thousands commas like 20,000 kept). Scan of built dist/es: 0 decimal commas left. Note: the impedance page formula now holds the field-solver text only; the explicit stripline/pair equations (60/√Er·ln…, Zdiff=2·Z0·(1−0.48e^…)) that were there before are no longer shown in the formula block.
- 2026-10-23: RELEASED tool-divider-fix (main @d232757 after merging 24 newer origin/main commits, tests+astro check+build re-run, deploy run 39989748406 success; production e2e 16/16 ok; live formula on divider EN/ES correct). Fixes: divider formula restored (impedance text had landed there since 10-15), impedance page gets the field-solver formula, load search, max-error lists all, Show all, error digits, copy/labels, ES decimals with dot. Worktree and branch removed; preview alias tool-divider-fix.embeddedera-site.pages.dev left on Pages. Reply to Eugene: Gmail draft, unsent.
- 2026-10-23: Owner asked for sortable pairs table + what 'Best standard pairs' means. BUILT on branch tool-divider-sort (worktree ~/embeddedera-site-dividersort, committed, NOT merged; preview https://tool-divider-sort.embeddedera-site.pages.dev): 8 sortable headers (click asc, again desc, third default), hidden
sortinput so ?sort= is shareable, sorted view lists all pairs (default list is the 50 closest, Max error = all), pairsNote line under the heading explains the rows (EN+ES), sortPairs/nextSort in calc.ts, sortableHeaders in calc-ui.ts (reusable for regulator/op-amp). Tests: calc.test + divider.e2e.py (36 ok on preview). Awaiting owner OK to merge. - 2026-10-23: RELEASED tool-divider-sort (main @1d652a6, deploy run 39992881415 success; production divider.e2e.py 36 ok, 0 FAIL; ES note line live). Worktree + branch removed.
HANDOFF 2026-10-23 (voltage divider session, chat was >240k tokens)¶
Done today, all on main and live (embeddedera.com/tools/voltage-divider, EN+ES):
- Eugene's 2nd email (3 findings): load-aware search, Max error lists every pair, Show all, finer error digits. His reply is an UNSENT Gmail draft (thread 1a166e861b5ef8f7, draft msg 1a169abf89d1083b); owner reads and sends.
- Audit: divider formula had the impedance field-solver text since 10-15 (commit 46fcaac); restored, impedance page now holds the field-solver text. Lead/meta/pitfalls corrected, range fields labelled "Total R1 + R2", parseSI float fix, ES decimals now dots (69 values; thousands commas kept). Owner rule: decimals are dots, never commas.
- Sortable pairs table (8 columns, ?sort= in the URL) + pairsNote line explaining "Best standard pairs".
Checks: scripts/calc.test.mjs, astro check, npm run build, scripts/divider.e2e.py (needs uv run --with playwright python scripts/divider.e2e.py <base-url>, 36 ok on production).
Open questions / loose ends:
- The impedance page lost its explicit stripline + pair equations (formula block now field-solver text only); owner has not said whether to restore them.
- Same sortable-header helper (sortableHeaders in calc-ui.ts, sortPairs in calc.ts) is reusable for regulator-feedback and op-amp tables; owner has not asked.
- Tie order: exact-match ties list lowest total R (highest current) first; could prefer lower current. Not asked.
- Preview aliases tool-divider-series / tool-divider-fix / tool-divider-sort still exist on Pages (harmless).
Next action: wait for Eugene's follow-up (he may send the exact sequence for the "inputs getting lost" report, which could not be reproduced: 40 random edits all matched a fresh load); otherwise nothing pending.
- 2026-10-23: Owner approved logo v2. Built in worktree ~/embeddedera-site-logov2 (branch logo-v2 off main 72c8efc, commit 6d88f91 pushed, draft PR https://github.com/angelEmbeddedEra/embeddedera-site/pull/8; not live, no preview deployed): logo.svg/logo-white.svg = v2 lockups; favicon.svg/32/ico, apple-touch, icon-192/512 = v2 copper mark on #0b0d10; favicon-mark.png = v2 white mark; logo-white.png same 1280x1024 placement; og.png + 34 og/tools + illustrated og/notes re-rendered. Build 0, astro check 0 errors. Generator: scripts/logo-v2.mjs.
- 2026-10-23: RELEASED regulator fix (main @5b05179, run 40013605056 success; live dropdowns checked). Eugene follow-up: regulator page now has E96+E24 (my earlier edit missed the there) and Show all up to 50 (best 5 default); E192+E24 REMOVED from all pages and calc.ts (reader: E192-only values are exotic/expensive; plain E192 kept). calc.test + divider.e2e (40 random edits, 0 mismatches) pass. Reply to Eugene is an UNSENT Gmail draft on his 16:34 message.
- 2026-10-23 HANDOFF (divider feedback / Gmail links chat): Released to main: divider E96+E24, max error, own-values list; regulator E96+E24 + Show all (50); E192+E24 removed everywhere. Reply to Eugene (2nd follow-up) is an UNSENT Gmail draft with no link. Owner rule: never send google.com/url links; every link must be clickable. Done: claude-mail-guard blocks connector drafts containing links (matcher widened to mcp__.*__(send_message|reply|forward|create_draft|update_draft), tested), new ~/.local/bin/mail-draft (IMAP APPEND, linkifies, --reply-to-id threads; dry run checked). OPEN: (1) owner creates a Google app password for adiaz@ at https://myaccount.google.com/apppasswords (not shown on the Security page; if it says unavailable, Workspace admin must allow app passwords / less-secure IMAP is not needed, 2SV is already on) → store GMAIL_USER/GMAIL_APP_PASSWORD in ~/.config/gmail-drafts/env (0600) + Vaultwarden → run one real mail-draft to adiaz@ and check the link in Gmail is a plain clickable URL. (2) Owner deletes test draft 'link test (delete me)'. NEXT ACTION: step (1).
- 2026-10-23: app password created by owner; stored in ~/.config/gmail-drafts/env (0600). NOT yet in Vaultwarden (bw is logged out; owner adds item "Gmail app password - mail-draft"). First real mail-draft run was blocked by the auto-mode permission classifier; owner runs the test command once (or allows mail-draft in permissions), then check the draft link is plain.
- 2026-10-23: RELEASED logo v2 (PR #8 merged, main @3569db9, deploy run 40014336097 success). Live check: favicon.svg/.ico, favicon-mark.png, logo.svg, logo-white.svg, og.png, apple-touch match the build byte for byte (plain and cache-busted URLs); /, /contact/, /about/, /es/ 200. Worktree + branch removed. All 67 notes OG cards were re-rendered with v2 in that release (0 kept; verified live) — the earlier 'some keep v1' worry was wrong.
- 2026-10-23: mail-draft VERIFIED: owner allowed it in permissions; real IMAP draft read back RAW has a plain link, no google.com/url. Use mail-draft for every draft with a link. Still open: Vaultwarden copy of the app password (owner), delete the two test drafts (owner).
- 2026-10-23: Eugene's 3rd+4th emails read (20:59 divider OK, asks 'Show all' to toggle back to fewer; 22:23 regulator Iadj feedback). Regulator 'broken with Iadj' is NOT a search bug: typing Iadj switches to ADJ mode with a hidden default 'min divider current 5 mA' (imin) that drops his pairs; with imin off, regulatorPairs returns his hand numbers (5.36k/1.8k 0.02 %, 4.7k/1.58k 0.16 %). Show all is one-way (button hidden once expanded). Nothing changed in code yet; awaiting owner on fixes + reply (draft only).
- 2026-10-23: Eugene's 3rd+4th emails FIXED on branch tool-regulator-v2 (commit 6107e89, worktree ~/embeddedera-site-regv2, NOT merged, NOT pushed; preview https://tool-regulator-v2.embeddedera-site.pages.dev). Root causes: (1) typing Iadj silently switched to LM317 mode with a hidden default 5 mA min-load filter (one field was both mode switch and value); (2) regulator range fields limited EACH resistor, divider limits the TOTAL (his 820/274 = 1.094k dropped by the 1k floor); (3) feedback-pin bias current had no mode (page told FB users to leave Iadj 0). Now: Regulator type select (Feedback pin default / Three-terminal), bias field, min-load only in three-terminal, old ?iadj= links open as three-terminal, total R1+R2 range, tolerance + reference-tolerance range column, bias shift + current/bias columns, 250x guidance, 'other error sources' pitfall, Show all <-> Show only the best N on both pages (hidden while a divider sort is on). Tests: calc.test (his numbers + brute force), regulator.e2e.py (all ok local + preview), divider.e2e.py (40 ok), astro check 0 errors, build ok. Independent review agent running. Reply to Eugene not drafted yet (must ask which other free tool he'd like).
HANDOFF 2026-10-23 (regulator fixes + sortable tables chat, >240k tokens)¶
Branch tool-sort-tables (worktree ~/embeddedera-site-sort, 3 commits on top of origin/main: 6107e89 regulator rework, 153611c sortable tables by Codex, 01f46cb search fixes). NOT merged, NOT pushed. Preview: https://tool-sort-tables.embeddedera-site.pages.dev (older: tool-regulator-v2 alias = 6107e89 only). Worktree ~/embeddedera-site-regv2 (branch tool-regulator-v2) is superseded: remove both worktrees + branches after merge. node_modules in both is a symlink to ~/embeddedera-site/node_modules.
Done (Eugene's 3rd+4th emails + owner requests):
- Regulator: type select (Feedback pin default / Three-terminal), bias field, min-load only in three-terminal (empty = 5 mA, 0 = off, round-trips in URL), total R1+R2 range, tolerance + reference tolerance, Vout range / bias shift / current÷bias columns, 250x guidance, "other error sources" pitfall, old ?iadj= links open as three-terminal. Show all <-> Show only the best N on regulator, divider, op-amp.
- Sortable headers (click asc, desc, default; ?sort= in URL) on regulator, op-amp, thermistor (divider already had it). Implemented by Codex (gpt-6.1-sol, workspace-write, own worktree, systemd-run --user codex exec ... "$(cat prompt)"; stdin does not pass through systemd-run), I reviewed the diff.
- Search: R1 clamped into the window the total limit leaves; dedupe key is now the ratio (searchPairs); constrained cases compared with exhaustive loops in calc.test; corner-enumeration oracle for regulatorRange.
Checks passed: calc.test, astro check 0 errors, build, check-seo, check-translations, e2e on dev server: regulator (all ok), opamp, thermistor (149 ok), divider (no FAIL). Run e2e only after warming the dev server (first load re-optimises and reloads the page, which gives false FAILs): uv run --with playwright python scripts/<regulator|opamp|thermistor|divider>.e2e.py http://localhost:4331.
Reviews: Codex read-only review (6 findings) and Claude subagent review (5) are both applied EXCEPT the open items below.
OPEN (from the reviews, not fixed yet):
1. Search still tries only the two neighbours of the ideal R1: when the ideal lands exactly on a standard value (down==up) the next step is skipped (Vref 0.8, Vout 1.8, E96+E24, total 5k-7.5k misses 3010/2400); Eugene's own case list ends at 0.307 % and misses 3010/1000. Fix: also try the next value above and below (or walk outward like within). Re-run the brute-force script in scratchpad/review/ (bf.mjs) and extend calc.test with those cases. imin 10 mA + total 500-10k returned nothing in the first review; recheck after the clamp.
2. Blank range: placeholders say 1k / 1M but blank means per-resistor 1k-1M (totals up to 2M). A lone "min" with no max still allows 1M resistors. Decide: make blank = placeholder total range, or hide the placeholder. Same quirk on the divider.
3. Schematic: Vref is drawn mid-block in both modes; for a feedback-pin part Vref is across the BOTTOM resistor; bias arrow not drawn in feedback-pin mode (should point INTO the pin); the "I =" label sits at the bottom resistor even in three-terminal mode.
4. Weak tests: shift, current÷bias, guidance count, divider aria-expanded, ?rmin/?rmax old links (now total, not per resistor), negative bias (withBias hides columns when bias<0: either support or state "positive = into the pin" in the help text).
5. Strings: tools-en.ts ~209/47 and tools-es.ts ~191/29 still say "Iadj guidance"/"Iadj term"; the imin field always carries value=5m in the URL even in feedback-pin mode.
6. Typ vs max bias spread is not modelled (one field, "use the worst case"); optional min-divider-current filter or ratio sort for the 250x rule.
Next action: fix open items 1, 2, 3 (then 4-5) on tool-sort-tables, re-run all gates, redeploy the preview alias, show the owner, and on the owner's OK: merge to main (rebase on origin/main first, it moves fast), deploy via CI, check live, remove worktrees. THEN draft the reply to Eugene with mail-draft (unsent; clickable links; also ask which other free tool he would like us to build; mention the toggle, the regulator fixes and sortable tables).
- 2026-10-23: Codex review (9 findings) FIXED on tool-sort-tables (commits 8cfcb03 0d99a39 9042bec on top of 01f46cb, NOT merged/pushed; preview https://tool-sort-tables.embeddedera-site.pages.dev redeployed): non-finite range guard (seriesValues + parseOpt), 1 ohm floor with a minimum load, regulatorRange over all corners, explicit 0 worst-case bias, schematic shows typical bias, Vout<=0 pairs rejected + em dash for Infinity/NaN cells, divider loose Max error capped at 5000 (message EN+ES), cleared defaults stay in the URL (vref=), stale sort keys dropped. Gates: calc.test pass, astro check 0 errors, check-translations ok, build ok, check-seo PASS 149; dev e2e regulator 231 ok, opamp 86 ok, thermistor 149 ok (one earlier run had 4 FAIL under load, rerun clean), divider 47 ok + 1 own-test fix; preview e2e regulator 231 ok 0 FAIL, divider 48 ok 0 FAIL.
- 2026-10-23: RELEASED tool-sort-tables (main @8cfcb03, deploy run 40058681567 success, fast-forward, 10 commits): regulator type select + bias/worst-case bias + total R1+R2 range + tolerance + 250x guidance + schematic per mode; sortable tables on regulator, op-amp, thermistor; Show all <-> fewer on divider/regulator/op-amp; divider blank range = total 1k..1M (his 5V->3V 0.1% case now 201 pairs, not 189); divider Max error capped at 5000 pairs. Live check: 8 tool pages 200 (EN+ES); production e2e regulator 231 ok, divider 48 ok, 0 FAIL. Reviews: Codex (gpt-6.1-sol, read-only, 2 passes) + Claude subagent; all findings fixed. Reply to Eugene: unsent Gmail draft via mail-draft (plain links verified).
- 2026-10-24 worker (Sonnet 5.5) on tool-sort-tables: OPEN items 1-6 fixed in commits ee557fd (search: neighbours both sides, window clamp, blank range = 1k-1M total, divider too), 8020b86 (bias spread iadjmax, ratio column, regression + sweep tests vs exhaustive loops), e058332 (schematic Vref per mode + bias arrow + "I =" on the Vref resistor, negative bias, sign help EN+ES, strings, imin/iadjmax disabled while hidden so out of the URL, e2e), 0fa3b59 (shorter meta descriptions). Gates at 0fa3b59: calc.test pass, astro check 0 errors, build pass, check-translations pass, check-seo pass (149 pages), dev-server e2e regulator/divider/opamp/thermistor all ok (divider top pair now 825/1.6k and 201 pairs within 0.1 %: blank = 1k-1M total, pool reaches 10 ohm). Preview https://tool-sort-tables.embeddedera-site.pages.dev deployed from 0fa3b59; regulator (231 ok) and divider (48 ok) e2e pass against it. Later commits 9042bec, 0d99a39, 8cfcb03 on the branch are not mine and are NOT in that preview deploy.
- 2026-10-28: Resistor fault /tools card: schematic thumbnail (cbf79bd) looked like the other calculators; replaced with a hot 0805 on pads + heat waves + "0805 · ≥ 2.3 kΩ" (branch resfault-icon 1 commit on main cbf79bd, pushed, NOT merged, no preview: gh workflow run was denied). astro check 0 errors, build ok, local screenshot checked desktop + phone. Next: owner OK → merge to main (push deploys).
- 2026-10-28: MERGED resfault-icon to main (01c8583), deploy success, live /tools/ serves the hot-chip card. Branch resfault-icon still exists (delete was blocked by permissions).
- 2026-10-29: Work section built on preview (branch work-case-studies off main 1b87b28, 26a1984): unparked /work + /es/work (Spanish chrome, English bodies, es.title/summary frontmatter), Work in nav, new case study kitchen-panel.md (CAD renders + architecture SVG, links to /services/hmi-displays/), old summaries/titles shortened to pass check-seo. notes-queue is 189 commits behind main, so branched from main. Build + astro check + check:functions clean; preview noindex; production /work/ still 404.
- 2026-10-29: Owner sent 5 fridge photos and said watermark and use them. Used 3 (fridge-angle hero, fridge-side, cameras-page) in public/media/kitchen-panel/: front-door camera snapshot pixelated, printer serial + logo blurred, coupons/magnets cropped, embeddedera.com watermark bottom-right (script: logo-white.png + JetBrains Mono). Preview redeployed (7f37f24).
- 2026-10-29: RELEASED /work with the kitchen panel case study only (owner: "Publish this case only"). main d03bad5 (fast-forward from work-case-studies), Deploy workflow success; production /work/, /work/kitchen-panel/, /es/work/ + /es/work/kitchen-panel/ 200, in sitemap, Work in nav; other 4 studies draft (404). Worktree ~/embeddedera-site-work kept for the follow-ups.
- 2026-10-29: Livestock (cow) case study got 4 visuals on branch cow-visuals (69ca3dd, NOT pushed/merged, study still draft:true): link/failsafe SVG diagram, ACK-rate dot chart (85.9 -> 97.0 vs 99.5 gate), test-station LED-check strip (Universal_Tester camera evidence), pick-and-place video re-encoded 7.5 -> 1.2 MB. Removed the in-text link to /work/universal-tester/ (draft, would 404). Board render NOT used (page says board files stay with client; shows radio module label). Preview with the study un-drafted: https://cow-visuals.embeddedera-site.pages.dev/work/livestock-robot-controls/
- 2026-10-30: embeddedera.com/cricket (EN+ES) already links Buy a Cricket → store product ee-a-0003-a. /shop/ said 'coming soon': branch
shop-cricket(worktree ~/embeddedera-site-shop, off main f8c76bb, pushed) changes EN+ES copy to 'The Cricket is in the shop' + Buy a Cricket / Meet the Cricket links; build rc 0; preview https://shop-cricket.embeddedera-site.pages.dev/shop/ (375 px, no horizontal scroll). Awaiting owner OK to push shop-cricket:main. - 2026-10-30: Shop page published (owner 'publish'): main 46fae4c, Deploy success; https://embeddedera.com/shop/ and /es/shop/ show 'The Cricket is in the shop' + Buy a Cricket → store. Worktree and branch shop-cricket removed.
- 2026-10-30: Owner: Shop should go straight to the store, no old links. Branch
shop-to-store(worktree ~/embeddedera-site-store, pushed): NAV/footer Shop → STORE_URL https://store.embeddedera.com/ (site.ts), shop.astro + es/shop.astro and i18n shop blocks removed, /shop dropped from offers/click allowlists, _redirects /shop(/) and /es/shop(/) 301 → store. Build rc 0, offers.test pass, no /shop in dist or sitemap. Preview https://shop-to-store.embeddedera-site.pages.dev (redirects verified). Awaiting 'publish'. - 2026-10-30: Shop → store published: main 0166cbd, Deploy success; embeddedera.com/shop, /shop/, /es/shop/ 301 → https://store.embeddedera.com/, menu Shop links to the store. Worktree/branch removed.
- 2026-10-30: Owner sent 9 photos of the RealCow remote. Used the three-quarter shot (PhotoCraft recipe ~/design/edited/realcow-remote/edit.py: 16:10 crop, neutral grade, falloff, watermark A; clean copy kept) as a figure after the outcomes list. Owner clarified: LHG assembles the remote, we sell him the boards, two per remote (finger control + wrist unit); study text, FAQ and outcomes corrected to match. Commit on cow-visuals, preview redeployed and checked desktop + phone.
- 2026-10-30: Livestock/RealCow case study PUBLISHED (owner: "publish this", "only publish this cow stuff"). PR #13 merged (808628f), CI run 41127570414 success, cache purged, IndexNow 200. Scoped before merge: work-page CTA/Article/breadcrumb blocks render only on studies with
services(only livestock), so other studies are unchanged; service pages gained a data-driven 'Case studies' column (work items whose services include the slug). Verified live: /work/livestock-robot-controls/ + /es/ 200, og:image = realcow-arena.jpg, remote photo loads, linked from /services/firmware and /work/. Still open: Paul quote + LHG backlink, real numbers, Spanish body, Search Console/Bing Request indexing.