Repository navigation
Description
Context
Drew's direction (2026-10-25): a standing registry of every domain/DNS name we own, a regular backup of the full DNS config for every zone, and one place to see which domain renews next, which are completely unused, and which are unused but earmarked for projects.
First pass is DONE (2026-10-25) — this issue covers only the recurring machinery that pass deliberately did not build.
- Register:
~/workspace/goals/stand-up-lab-cluster-talm-talos-cozystack-postgres-rustfs/files/dns-domain-register.md— 41 domains (39 in the Porkbun accountdevelopingtoday, + drewrypope.com and boats.dev which are Porkbun-registered under a different account), sorted by next renewal, with registrar, DNS host, renewal date, auto-renew state, list renewal price, where-used evidence, plan/status, and a review flag per domain. - Seed snapshot:
~/workspace/goals/stand-up-lab-cluster-talm-talos-cozystack-postgres-rustfs/hidden_files/dns-backup-2026-10-25/— Cloudflare zone export (1 zone: security.cab, all 21 records), Porkbun account inventory (39 domains) + full TLD pricing table, public-DNS probe for all 41 domains, RDAP for the 2 outside-account domains. The snapshot README documents coverage and gaps precisely.
Headline facts from the first pass: all 39 account domains have auto-renew ON ($595.62/yr at list prices); next renewal is 1110x.de on 2027-02-09; only 3 of 41 domains show genuine use (security.cab, developing-today.com, drewrypope.com).
To build
1. Scheduled DNS-config backup job
Recurring (suggest weekly) read-only export producing a dated snapshot in the seed's format, diffed against the previous snapshot, surfacing: record changes, new/removed domains, expiry-date changes, price changes. Sources: Cloudflare API (zones + records; tokens in Bitwarden as cloudflare.api-token-day-to-day / cloudflare.api-token-account-wide) and Porkbun API (porkbun.api-key / porkbun.secret-key in Bitwarden).
2. Renewal & cost tracking over time
Each cycle appends to the register (or a history file beside it): observation date, per-domain renewal date, per-TLD list renewal price. This is how prior-year costs accumulate — the first pass could only mark them "unknown" (no invoice source reachable). Alert when a domain enters its renewal window (suggest ≤45 days; with auto-renew universal, the alert is about upcoming spend, not lapse risk) and when a renewal price changes cycle-over-cycle. If an invoice-grade source becomes available (Porkbun billing history, Gmail receipts), record actual charged amounts alongside list prices.
3. Dashboard / aggregator view
A view of the register data showing Drew's three lists: next renewal (with date + price), completely unused, unused but earmarked — fed by a structured export (e.g. register.json) the backup job emits alongside the Markdown register, consumed by the PM aggregator (same pattern as the fleet feed / quota panel).
4. Gap-closers identified by the first pass
- Porkbun API key is domain-restricted:
dns/retrievesucceeds only for security.cab and refuses the other 38 domains, so zone-file-grade exports don't exist yet for the Porkbun-hosted zones (first pass used a public-DNS probe instead). Extend the key's domain allowlist in the Porkbun control panel, or file an unrestricted key in Bitwarden (by name) and point the job at it. - Second Porkbun account: drewrypope.com (expires 2028-06-14) and boats.dev (expires 2027-04-02) are Porkbun-registered but absent from the
developingtodayAPI account — identify the account and bring both domains under the same inventory (auto-renew state and full exports are currently unknowable). - security.cab expiry discrepancy: Porkbun account says expires 2027-02-24 (created 2018-02-24); registry RDAP said 2027-08-14. Resolve against the Porkbun control panel and correct whichever source is wrong.
Acceptance
- Backup job runs on schedule and produces a diffed snapshot without human prompting.
- Register history shows ≥2 cycles of renewal/price observations appended automatically.
- Aggregator renders the three lists from the structured export.
- A test domain entering the renewal window produces the spend alert.
Acceptance criteria
- A scheduled (weekly or better) read-only job exports the full DNS config for every owned zone/domain (Cloudflare + Porkbun) into a dated snapshot in the seed snapshot's format, using the Bitwarden-stored API credentials.
- Each snapshot is diffed against the previous one; record changes, new/removed domains, expiry-date changes, and price changes are surfaced in the run output.
- A renewal/cost history accumulates per domain (observation date, renewal date, list renewal price; actual charged amounts when an invoice-grade source is reachable).
- An alert fires when a domain enters the renewal window (≤45 days) or a renewal price changes cycle-over-cycle.
- A dashboard view shows the domain register sorted by next renewal, flagging unused and earmarked-but-unused domains.
Activity
developing-today commentedon Oct 25, 2026
CODE-146
dezren39 commentedon Oct 25, 2026
Correction to the gap-closers list, same day as filing: item (c), the "security.cab expiry discrepancy", does not exist. The first pass briefly worked from a partial RDAP read (2027-08-14); the full registry RDAP record — re-fetched and saved in the seed snapshot under
rdap/security.cab.json— agrees with the Porkbun account exactly: registered 2018-02-24, expires 2027-02-24, transfer recorded 2024-02-15. RDAP for developing-today.com and developing.today likewise matches the account dates. Gap (c) is closed; the register and snapshot README have been corrected. Items (a) the domain-restricted Porkbun API key and (b) the unidentified second Porkbun account (drewrypope.com, boats.dev) remain open as filed.dezren39 commentedon Oct 25, 2026
Updates from Drew (2026-10-25), corrections applied to the register (commit 9b44e22 in hatch-personal):
aggregator slice 3 (#906): pages, DNS + sessions views, comments UI +…
dezren39 commentedon Oct 25, 2026
Coordination note from #906 (dashboard DNS page, now live).
The dashboard's
/dnspage (PR #920) renders the register through the fleet-feed collector, which parses the register Markdown keyed on its exact table header row:| Domain | Registrar | DNS hosted at | Next renewal | Auto-renew | Renewal price (list) | Prior-year cost | Where it's used | Plan / status | Review? |Two things for this issue's recurring pipeline:
src/dns.ts(parseDnsRegister) in the aggregator in the same pass — the parser fails soft (no section, page says why) rather than rendering garbage, so a silent format break shows up as the DNS page going absent, not wrong.dezren39 commentedon Oct 26, 2026
Intake review
Fleet monitor intake pass (2026-10-25 run). Acceptance criteria appended to the body this pass (original body preserved verbatim above it).
State per the body: The first pass is DONE (register of 41 domains + seed snapshot, 2026-10-25); this issue covers only the recurring machinery that pass deliberately did not build — the scheduled backup job, renewal/cost history, and the dashboard view. Nothing in this repo or the register suggests any of the three recurring pieces exist yet.
Related: #910 (org-level GitHub Project / dashboard layer — a different dashboard surface, but the DNS dashboard view should follow the same fleet-feed collector pattern rather than inventing a second one).
Notes / suggested approach: Build in the body's own order: (1) the read-only scheduled export + diff is the foundation and is independently useful; (2) the history append falls out of the snapshot format almost for free once (1) exists — decide the history file's home (beside the register) in that step; (3) the dashboard view last, reading the register + history. Credentials are Bitwarden-stored per the body; the job must stay read-only against Cloudflare/Porkbun.
Risks: Porkbun/Cloudflare API shapes changing under the job (pin expectations, fail loud on schema drift); renewal-window alerts becoming noise if the window is too wide — 45 days with universal auto-renew is about spend visibility, as the body notes. Effort classed l (three-part build).
dezren39 commentedon Nov 1, 2026
🤖 Agent note — triage verdict: CONFIRMED, still unbuilt; slice 1 routed (queue task 2284, lane D, 2026-11-01T02:4xZ)
Verified against live state today:
hidden_files/contains only the seeddns-backup-2026-10-25/; no later snapshot exists. The cron list has no DNS backup job (only the one-shotdns-spending-review-reminderfor 2027-01-11 and theporkbun-account-nudge)./dnspage is live via PR impl(dashboard): slice 3 — pluggable pages, DNS register, comments, session registry (#906) #920, rendering the register's three lists — but it parses the Markdown register on its exact table header, so the structuredregister.jsonexport is still owed and is folded into slice 1 below.second-porkbun-account…goal + its weekly nudge cron.Routing: follow-up queue task 4867 (small_fix) enqueued — slice 1: the weekly read-only backup job (dated snapshot in the seed format, diff vs previous, renewal/price history appends,
register.jsonexport, ≤45-day renewal-window spend alert). This issue stays open as the tracker for the remaining acceptance (≥2 history cycles maturing, gap items).50 remaining items
dezren39 commentedon Nov 3, 2026
agent-note:v1
event: done
task: 7602 (repo-health-code-pilot, repo-worker-code — OpenChamber scheduled lane c29174f1)
state: Completed as
triaged; issue #902 stays OPEN by design.fresh_evidence: Triage comment of 2026-11-03 (this run) records the per-acceptance state at main
cd3b299ae: slices 1-2 built (weekly job + snapshots + history + register.json + aggregator JSON consumption, PR #4366 merged), remaining acceptance date-gated on the 2026-11-08/2026-11-15 runs and on Drew's Porkbun control-panel actions.next: Follow-up queue task 8054 (not-before 2026-11-09T15:00Z) verifies the first scheduled run, the second distinct history cycle, and closes #902 or records the residual gap. Queue labels for task 7602 cleared;
status/triagedset.bookkeeping: Sandbox backlog and sweep log deferred to fleet reconciliation.
dezren39 commentedon Nov 5, 2026
Porkbun second account — pickup #3 (2026-11-05): password accepted for
dezren3i; stopped at email 2FA, which is the remaining Drew-act.bitwarden_export_20261019234319.csv, 2026-10-19): 20 Porkbun rows, one distinct password per username. The export was parsed inside the login driver process on the laptop — the password was never passed through command strings — and both export copies (sandbox + laptop) were shredded after the login leg.dezren3iadvanced to the password stage and the export password was accepted — the flow proceeded to the 2FA step (a wrong password does not get there).twoFactorLoginCodeEmail; no TOTP exists anywhere in the export). Per protocol the lane stopped here: Drew-act = supply that emailed code (or a backup code). The browser session is parked on the 2FA form; a fresh code will be needed if it lapses.drewrypope.comin the account's domain list, then creating the new API key pair and storing it in Bitwarden Secrets Manager (sibling namesporkbun2.api-key/porkbun2.secret-key, distinguished from the main account's pair) with a live ping + listAll verification.mcpxCNAME), 0 change, 1 destroy (a state-only01b.usremnant, unrelated to either issue's work). No apply. Full detail on mcpx docs: a custom subdomain for the site (DNS, CNAME, HTTPS) #1943.dezren39 commentedon Nov 5, 2026
Porkbun pass — pickup #4 (2026-11-05 ~02:15 CST).
Second account (
dezren3i) — still gated at email 2FA; the blocker is now precise. The password was accepted on the prior pass; the emailed code exists in Gmail only as a redacted credential-store reference — the mail tooling never exposes the value to an agent, and its one sanctioned consumer is the browser sign-in step itself. Neither CDP typing nor the RustDesk channel (Drew's 02:09 mechanism order) can receive it from this seat, so login completion routes to the parent browser flow: a fresh login at porkbun.com (which triggers a fresh code — the 01:59 code is likely expired), then the audit,porkbun2.api-key/porkbun2.secret-keycreation, and the account's Opt In All Domains toggle. RustDesk channel status, for the record: laptop portal repaired (xdg-desktop-portal active again 02:09:43), laptop RustDesk server healthy, SSH forward to 127.0.0.1:21118 works — but this sandbox's virtual X servers (Xvfb, Xvnc, nix Xvfb) expose no GLX, so the Flutter client renders nothing from this seat. A separate client-side blocker, and moot next to the code channel.Main account (
developingtoday) — audited via API:porkbun.api-key/porkbun.secret-key: verified live tonight (ping SUCCESS, listAll SUCCESS). No new key created — a working key is not churned.apiAccessflag in listAll). Nothing to toggle on this account.dns/retrievesucceeds only forsecurity.cab(10 records); the other 38 domains return "This API key is restricted to specific domains". Drew's end state — API working for all domains — therefore needs this key's allowed-domains widened (editable in the key's settings) or a second unrestricted key, both web-session acts riding the same browser flow as the second account. Correction note: an earlier probe pass reported o3d.dev/0x111.dev as the allowed domains; that output was wrong and was caught on independent re-verification —security.cabis the only allowed domain of the 39.drewrypope.comconfirmed NOT in the main account — it belongs to the second account, as established on the prior pass.No terraform apply anywhere.
dezren39 commentedon Nov 5, 2026
Porkbun second account (
dezren3i) — 2FA code entry attempt, 2026-11-05 ~02:32 CST: the code Drew pasted in chat was typed into the parked Helium tab's email-2FA field via keyboard-class CDP input and submitted. Porkbun rejected it — verbatim form response: "Invalid two factor authentication code." (with banner "Uh Oh! We were unable to log you in."). Per protocol, no further attempts were made (one entry attempt only).State preserved: the session is still parked at the 2FA step — username stage and accepted password intact, prompt unchanged ("Please enter your two factor code. This code was emailed to your account email address. You can also use a backup code."). A fresh emailed code (the form offers a send-email-code path) or a re-confirmed backup code can still complete entry without redoing the login.
Still pending entry: the account audit, creation of
porkbun2.api-key/porkbun2.secret-keyin BWS with live verification, and API opt-in for all domains in the account. The main-account key-widening leg was not attempted — it would have required resetting this parked session, and it remains sequenced behind entry. No terraform apply or plan changes.dezren39 commentedon Nov 5, 2026
Porkbun dezren3i — corrected-code entry attempt (2026-11-05 ~02:37 CST): the 10-character code Drew pasted in chat (replacing the earlier corrupted 12-character transcription) was entered into the still-parked 2FA form exactly once — field cleared first, length verified in-page before a single Log in click. A fresh
login_20230305_1XHR confirms the submission reached the server. The server rejected it: verbatim form response "Invalid two factor authentication code." (modal: "Uh Oh! We were unable to log you in.") The parked form is unchanged (same prompt, no lockout reported). Stopped per protocol — no resend, no variants. Likely explanations: the emailed code (sent ~01:59 CST) had expired by entry time, or the pasted string is not a currently-valid backup code. Next step needs Drew's word: a fresh code resend, entered promptly on arrival. Remaining legs (audit,porkbun2.*key creation, opt-in-all-domains) remain gated on entry; the main-account key-widening leg was not attempted — it was sequenced after entry and its own web login would need the same code path settled first. No terraform apply; no code or secret value appears in any record.developing-today commentedon Nov 5, 2026
Gap closed (2026-11-05): Drew logged into the second Porkbun account (dezren3i) on the laptop; the fleet completed the audit + API setup in that live session.
porkbun.dezren3i-api-key/porkbun.dezren3i-secret-key(read-back fingerprints verified; broker route also live).apiAccess: 1per domain), and DNS record reads proven via the API for all 8 (drewrypope.com: 12 records) — so this account's domains can now be backed up at record level and their auto-renew state verified via API, not just public DNS.developing-today commentedon Nov 5, 2026
Correction to the comment above (earlier figures came from a corrupted tool delivery; corrected values from two independent synchronous API re-reads, 2026-11-05): the per-domain
apiAccessflag reads 0 for all 8 domains — API access works via the account-level "Opt In All Domains" setting (ON), which grants the unrestricted key account-wide access. DNS record reads proven for all 8: drewrypope.com 17 records, dezren39.dev 12, the other six 11 each. The gap this issue tracked is still closed: the account's domains can be read at record level via the vaulted API pair.dezren39 commentedon Nov 5, 2026
Backup email — dezren3i account (Drew directive, main chat 2026-11-05): STAGED, blocked on Drew's verification step.
popesdrew@gmail.comwas entered as the Backup Email Address (Account Settings → "Account owner and recovery" → Email Addresses) in the live dezren3i session on the laptop and "Update Account Details" was clicked. Porkbun gates this save behind its Account Update Verification modal: it requires the account's current password and presents a 2FA login-code field. That credential step is Drew's physical act, so the lane stopped there.Verified state after stopping (two independent reads):
To finish (Drew, ~20 seconds on the laptop): in that tab, enter the account password (+ 2FA code if it insists) and click "Update Account". Porkbun will then email a verification link to popesdrew@gmail.com — the backup sits in a pending state until that link is confirmed.
dezren39 commentedon Nov 5, 2026
Backup-email attempt on dezren3i (2026-11-05): per Drew's directive, popesdrew@gmail.com was entered as the account's Backup Email Address in Account Settings (live dezren3i session, Helium) and submitted via "Update Account Details" twice (programmatic fill, then real keystrokes). It did not persist: a fresh tab shows the field empty, status still "not submitted". The settings form carries unrelated validation errors (address block "not validated" ×4, "Validation not available for this country") that appear to block the save. No other account data was changed. Drew can finish this in one manual pass on the settings tab (left open with the address typed in), or after the address-validation snag is cleared. The main account's backup email waits on his main-account login (see #1943).
dezren39 commentedon Nov 5, 2026
Dezren3i password inventory — backup-email save still blocked on Drew (2026-11-05)
Drew's note ("you have the password somewhere — you logged in") was checked exhaustively. Verdict: the dezren3i Porkbun password is in neither vault:
bwvault: unauthenticated on both machines (could not be searched).Where the password actually lives: the laptop's synced Chrome password store holds saved Porkbun logins (
developingtoday×2,dezren3i, times_used 11) — this morning's login almost certainly came from Chrome autofill. The lane did not extract it from Chrome's encrypted store.State unchanged: the backup-email change stays staged in the Helium Porkbun tab with the "verify your current password" modal open. Drew's ~20s at the laptop (password + 2FA if demanded → Update Account) completes it; Porkbun then emails a confirmation link to popesdrew@gmail.com. Durable fix once he's in: save the dezren3i login into Bitwarden/1Password so a vault copy exists.
dezren39 commentedon Nov 5, 2026
BWS rename — done (Drew directive, main chat 2026-11-05: "…and same for dezren full").
This account's pair renamed (values unchanged — new-named secrets created with identical values, sha256-verified before the old names were deleted):
porkbun.dezren3i-api-key→porkbun.dezren-full-api-key(sha256 d9971fc716e9…, len 68)porkbun.dezren3i-secret-key→porkbun.dezren-full-secret-key(sha256 0cd7cb99fd32…)Old names deleted from BWS afterward; get-by-old-id now errors.
Consumers: this pair was never in the sops mirror (
secrets/sops/common/bws.yaml) and has no programmatic readers; the next fulllib/bws-to-sops.shsync will add it under the new names. Post-rename smoke (creds fetched via the new names):domain/listAll200, 8 domains;dns/retrieve/drewrypope.com200, 17 records.Full scheme now:
porkbun.devtoday-limited-*(main account, allowlist-limited),porkbun.devtoday-full-*(main account full pair, landing via the parallel lane),porkbun.dezren-full-*(this account). Goal record updated in GOAL.md. (Broker cache may serve the deleted names for ≤15 min until its periodic refresh — BWS no longer has them.)dezren39 commentedon Nov 5, 2026
Correction to my rename-completion comment above (comment 6664073964): the claim "nothing reads the BWS names programmatically" was incomplete. A delayed full-tree grep finished after that comment and surfaced one real consumer: the weekly DNS backup script
dns-backup.py(goal crondns-backup-weekly, Sundays 09:12, built for this issue's slice 1) fetchedporkbun.api-key/porkbun.secret-keyby name at runtime.Fixed in the same pass:
dns-backup.pynow fetchesporkbun.devtoday-limited-api-key/porkbun.devtoday-limited-secret-key(docstring + the twoget_secret()calls; no old-name references remain in the script).get_secret()returns values whose sha256 fingerprints match the renamed secrets exactly (52c1d1026fb7…/4f5c0e526b52…),--self-testpasses, and a read-onlylistAllthrough the script returns SUCCESS with all 39 domains.All other old-name mentions found by the full grep are historical records (dated snapshot READMEs, memory logs, baseline backups) describing the names as they were at the time — left as-is. The old BWS names stay deleted; the rename is complete with this consumer migrated.
dezren39 commentedon Nov 6, 2026
Porkbun account status — verified live 2026-11-06 (fleet-side solve pass)
developingtoday(39 domains): reachable via BWSporkbun.devtoday-limited-*(fp52c1d102) — listAll OK, but the key carries a domain allowlist (security.cab only);dns/retrieveon any other domain 403s. This is the standing root cause blocking mcpx docs: a custom subdomain for the site (DNS, CNAME, HTTPS) #1943.dezren3i(8 domains): BWSporkbun.dezren-full-*(fpd9971fc7) verified working today — listAll OK,dns/retrieve200, all-domains access as recorded.infra/dns) authenticates with a sops-held pair (secrets/sops/common/porkbun.yaml, fp ak2e4b92ec/ skec0a99bd) that matches neither BWS-tracked pair — a third, older pair outside the current naming/registry. Worth identifying and reconciling as part of this issue's register work.porkbun.devtoday-full-*) remains uncreated, blocked on the same login leg.dezren39 commentedon Nov 6, 2026
Porkbun accounts — status after the 2026-11-06 browser session (Helium/CDP on the laptop):
dezren3i (8 domains): one 30-second Drew-step from done.
dezren3i; primary email drewrypope@gmail.com, backup email was unset.developingtoday (main, 39 domains): blocked at sign-in — same password-fill wall; the standing Drew-step is one manual sign-in on the laptop (details on #1943). Backup email + unrestricted API pair follow immediately once that session exists.