Changelog¶
Archived record
This page describes the Firebase-era platform or a migration step that has completed. It is kept as history and is not a current runbook. The current platform is described from the home page.
All notable changes to this project. Each entry lists the task, date, what was done, and why.
Format: task (commit) — date — what — why
2026-06-12 — Linkie/Klaviyo production stabilization¶
- fix: Retrofit Linkie integration and deploy backend/frontend — 2026-06-12
— Replaced the prior Linktree wiring with Linkie (
linkieProxy,/admin/linkie,LINKIE_API_KEY, andhttps://app.linkie.bio/api/v1); verified Notion → SOPS → Firebase Secret Manager sync forLINKIE_API_KEY,KLAVIYO_PRIVATE_KEY, andKLAVIYO_LIST_ID. —deploy-functionscompleted successfully after the secrets landed in Firebase Secret Manager. — Frontend Firebase Hosting was deployed directly with Firebase CLI without dispatching GitHub workflows;https://hybridcloudworks.comreturned HTTP 200 after release.
v1.5.0 — 2026-06-11 — Platform 2.0 release¶
Security¶
- fix: Gate
generatePostContent,fetchBlogListingsManual,fetchPodcastFeedsManualbehind admin auth — 2026-06-11 — AddedapplyAdminCors+requireAdminClaims(req, res, 'editor')to all three previously unauthenticated HTTP functions;generatePostContentnow allowlists the target collection tocontentonly. — Closes denial-of-wallet and arbitrary-collection-write paths (TODO2.0 H-1/H-2/H-3). - fix:
refreshPlaudTokenNowchecksadminRolecustom claim — 2026-06-11 — Replaced the retired legacyadminclaim check (M-1). - fix: Remove
VITE_PUBLER_*from deploy workflow and.env.example— 2026-06-11 — The Publer key no longer ships in the browser bundle; runtime usespublerProxy(M-2). — ⚠️ Manual Publer key rotation is still required (prior bundles exposed the key). - fix: Remaining P0 hardening — 2026-06-11
— Capped/whitelisted
recordLegacyBlogsReaddetails payload (M-3); HTML-escaped theServiceDocsPagehighlighter beforedangerouslySetInnerHTML(M-4); admin bootstrap button hidden when admins exist (L-1);mcpProxy/syncMcpToolsraised to editor role (L-2); malformed.gitignoreline fixed (L-3).
UI/UX¶
- feat: Hyoga dark-luxe restyle across the public site — 2026-06-11
— Near-black charcoal base, display typography, eyebrow labels, numbered sections, glassy stat
blocks; major
src/index.cssconsolidation (glass classes, per-provider link rules, glows, header/footer backgrounds tokenized). New shared components:Eyebrow,NumberedSection,StatBlock,ProviderLandingTemplate. HomePage, Header, and Footer rebuilt. — Every provider keeps its existing color theme; provider--primarytokens fill the template's accent slot.
Providers¶
- feat: Re-enable all six provider landing pages — 2026-06-11
— AWS, Azure, GCP, FinOps, Terraform, GitHub
ComingSoonPageguards removed; pages relaunched on the shared Hyoga landing template. FinOps Architecture page re-enabled; education-detail dispatcher gaps and mobile-grid/contrast defects fixed. - feat: Add VMware and Ansible providers (8 total) — 2026-06-11
— New
src/pages/vmware/andsrc/pages/ansible/page sets,.theme-vmware/.theme-ansibletoken blocks, dispatcher and validation-script coverage. - feat: Public Coder Corner pages — 2026-06-11
—
/:provider/coder-cornerlist and/:slugdetail routes viaProviderCoderCornerPageand a new dispatcher insrc/App.jsx; data layer and admin tooling already existed.
Admin¶
- feat: Guided publishing additions — 2026-06-11
—
PipelineStepper.jsxpersistent Submit → Editor → Review → Published progress indicator; pre-publish validation checklist (hero image, body length, slug uniqueness, provider/type); calendar time-of-day picker with explicit timezone handling; "Auto-post to Social" checkbox at publish pre-fills SocialHub compose. - feat: New admin pages — 2026-06-11
—
ConnectionsPage.jsx(Publer, Plaud, Sessionize, Credly, YouTube in one place; Sessionize speaker ID moved to admin settings viasrc/lib/adminSettings.js), Linkie hub,MailingListPage.jsx(Klaviyo), andLabsPage.jsxlabs dashboard.
Integrations¶
- feat: New Cloud Functions — 2026-06-11
—
linkieProxy,klaviyoProxy,newsletterSubscribe, and labs functions (functions/labs-functions.js). — Secrets now provisioned as of 2026-06-12:LINKIE_API_KEY,KLAVIYO_PRIVATE_KEY,KLAVIYO_LIST_ID. - feat: Newsletter signup component — 2026-06-11
—
NewsletterSignup.jsxmounted in the Footer and on blog posts.
Labs Platform¶
- feat: Hostinger VPS labs backend — 2026-06-11
— New
labs/vps-agent/pull-based runner agent claiming jobs from a Firestore job queue (no inbound ports on the VPS), ephemeral sandboxed containers, per-lab command allowlists, quotas, and per-run audit docs. Seedocumentation/labs-platform-guide.md.
Removed¶
- chore: Delete the obsolete
platform/ansibleVPS stack — 2026-06-11 — RabbitMQ, python-worker, k3s, kubeadm, ArgoCD roles and all related templates removed. — Replaced by the new pull-based labs platform; documentation referencing the old stack updated or marked superseded.
2026-05-27 — Delete archive/ folder¶
- chore: Remove
archive/directory after manual review — 2026-05-27 — Deleted all 26 archived docs and thearchive/folder itself. Updateddocumentation/architecture-folder-structure.mdto drop the archive section. — History is preserved in git; the folder no longer serves a current purpose.
2026-05-27 — Workspace cleanup and folder reference doc¶
-
chore: Untrack generated and local-only files under
scripts/— 2026-05-27 —git rm --cachedremovedscripts/smoke-routes-output.json,scripts/smoke-frameworks-output.json, andscripts/temp-check.yamlfrom the index. Addedscripts/*-output.jsonto.gitignorealongside the existingscripts/temp-check.yamlrule. — Generated smoke-script outputs and placeholder secrets files should never be tracked. -
chore: Nest stray archive root files into
archive/docs/— 2026-05-27 —git mvofarchive/CATCHUP.md,archive/code-review-owasp-wcag.md, andarchive/code-review-owasp-wcag-checklist.mdintoarchive/docs/.archive/root now contains onlydocs/. — Single archival location matches the Phase 2 documentation convention. -
chore: Remove empty
tests/directory — 2026-05-27 — Deleted unused empty folder. Unit tests live insrc/(Vitest); e2e tests live ine2e/(Playwright). — Eliminates stale scaffolding that suggested a test layout we don't use. -
docs: Add folder-structure reference doc — 2026-05-27 — New
documentation/architecture-folder-structure.mdenumerates every top-level folder, hidden directory, and root file with responsibilities and links to deeper references. Linked from the documentation index under "Architecture & Backend". — Canonical answer to "where does X live?" after the multi-phase cleanup.
2026-05-27 — Documentation folder audit and reorganization¶
-
docs: Standardize 4 PascalCase docs to lowercase kebab-case — 2026-05-27 — Renamed via
git mv(history preserved):AI-Integration-Inventory.md→ai-integration-inventory.md,AI-Recommendations.md→ai-recommendations.md,Firebase-GCP-Cost-Inventory.md→firebase-gcp-cost-inventory.md,Frontend-Theming-Guide.md→frontend-theming-guide.md. — Enforces the<domain>-<topic>[-<detail>].mdnaming convention across the documentation folder. -
docs: Consolidate 6 duplicate docs into primaries (full detail preserved) — 2026-05-27 — Appended verbatim source content under
## Consolidated from <source>section headers in the primary doc, then archived the originals. No summarization — every paragraph kept. Consolidations:architecture-system-report.md→architecture-system-overview.md;frontend-firebase-deployment.md→process-handover-guide.md;frontend-stitch-mapping.md→frontend-stitch-integration.md;pipeline-deployment-checklist.md→pipeline-deployment-guide.md;secrets-folder-info.md→security-secrets-guide.md;secrets-frontend.md→security-secrets-guide.md. — Removes parallel/duplicate docs that drift apart over time; primaries now hold the full detail surface. -
docs: Archive 17 outdated, migration, and historical pre-launch docs — 2026-05-27 — Moved 17 files into
archive/docs/viagit mv. — Group A (outdated / superseded, 8):ai-cover-deployment-checklist.md(one-shot deploy checklist already executed),admin-auth-architecture.md(superseded by current admin auth guide),admin-auth-setup.md(superseded by current admin auth guide),documentation-reorganization-plan.md(this reorganization replaces it),firebase-ai-cover-trigger.md(one-shot trigger configured),frontend-pages-implementation.md(superseded byfrontend-pages-guide.md),pipeline-nodejs-upgrade.md(Node 22 upgrade complete),frontend-coming-soon-recovery.md(recovery executed). — Group B (completed migrations, 3):admin-auth-migration-guide.md,admin-rules-migration-plan.md,database-migration-runbook.md— all migrations shipped. — Group C (historical pre-launch audits, 6):accessibility-testing-manual.md,audit-pages-ux-comprehensive.md,review-critical-analysis.md,review-workflow-audit.md,security-workflow-audit.md,testing-visual-regression.md— point-in-time audits whose findings have been addressed and incorporated into active guides. -
docs: Rewrite documentation/README.md as domain-grouped index — 2026-05-27 — Replaced ad-hoc list with sections: Getting Started, Frontend & Design, Architecture & Backend, Database & Storage, AI & Automation, Security & Secrets, Pipelines & DevOps, Testing & Quality, Planning & Process, Integrations, Live Smoke Tests, Reports, Archive. Reflects renamed files, consolidations, and pointers to
archive/docs/for archived items. — Single discoverable index for the now-current documentation stack. -
docs: Expand TODO Key Supporting Docs and add 2 evaluation items — 2026-05-27 — Replaced TODO.md's short Key Supporting Docs list with the full domain-grouped stack matching
documentation/README.md. Added two new Pending Work items with research-backed value assessments: (2)database-model-roadmapPhase A scheduling decision, and (3)pipeline-scraping-upgradeheadless deployment cost/benefit evaluation. — Surfaces every active doc from the root tracker and converts two "future state" docs into reviewable decisions instead of letting them rot.
2026-05-27 — OWASP / WCAG remediation + repo hygiene¶
-
chore(docs): Archive completed root-level review docs (
ea4b23c1) — 2026-05-27 — MovedCATCHUP.md,code-review-owasp-wcag.md, andcode-review-owasp-wcag-checklist.mdintoarchive/viagit mv, deleted transient.tmp-dev-*.logandfirestore-debug.logfrom root. — Root markdown policy keeps onlyREADME.mdandTODO.md; the OWASP/WCAG review is now complete so the working docs no longer belong in root. -
style(frontend): Adopt tailwind v4 canonical classes in header (
8dce62b4) — 2026-05-27 — Replaced arbitrary-value Tailwind utilities insrc/components/shared/Header.jsxwith v4 shorthand (max-w-400,w-60,min-w-50,z-100,shrink-0,w-42.5,min-w-20,w-41, andtext-(--var)for CSS-variable color tokens). — Cleared 22 canonical-class linter warnings; pure refactor with no behavior change. -
docs: Mark owasp wcag review items complete (
756122ef) — 2026-05-27 — UpdatedCATCHUP.mdto check off every reviewed-backlog and follow-up item. — Reflects that all 10 OWASP/WCAG remediation commits have landed. -
feat(frontend): Add header a11y landmarks skip link and menu semantics (
8f6b7717) — 2026-05-27 — WiredSkipToMainContentintoHeader.jsx, labeled Primary/Secondary/Mobile nav landmarks, addedrole="menu"/role="menuitem"to the Tools dropdown with Escape-key close and focus return, and exposedaria-expanded/aria-controlson the mobile menu toggle. — Closes WCAG-1, WCAG-2, WCAG-3, and WCAG-6 from the audit. -
fix(auth): Hide admin link from non-admin users (
f0bcf109) — 2026-05-27 — Gated the/adminlink inHeader.jsxbehinduseAdminAuth().isAdmin. — Closes OWASP-5; prevents enumerating admin surface area for unauthenticated visitors. -
feat(frontend): Add main-content landmark for skip link (
80c9e58c) — 2026-05-27 — Addedid="main-content"andtabIndex={-1}to the main landmark inApp.jsx. — Required target for the WCAG-1 skip-to-content link. -
fix(frontend): Parse iso speaking-event dates without timezone drift (
eeb1a447) — 2026-05-27 — Normalized ISO date parsing inCustomSessionizeWidget.jsxandSpeakingEventsPage.jsxso saved values and the public display land on the same day. — Fixes an off-by-one-day rendering bug caused by implicit UTC parsing. -
feat(frontend): Announce toast notifications with aria-live (
19a65604) — 2026-05-27 — Addedaria-live="polite"andaria-atomic="true"to the toast viewport intoaster.jsx. — Closes WCAG-7; screen readers now announce transient notifications. -
fix(frontend): Keep helper text in aria-describedby when error present (
ea753571) — 2026-05-27 — Combined helper and error ids inaria-describedbyinAccessibleForm.tsxinstead of replacing helper with error. — Closes WCAG-4; preserves context for assistive tech when validation fails. -
fix(auth): Key admin status cache by uid (
93a5ca8c) — 2026-05-27 — Replaced module-level admin-claim cache with a UID-keyed cache inuseAdminAuth.js. — Closes OWASP-6; prevents one user's admin verdict from leaking to a different signed-in user. -
fix(frontend): Externalize theme bootstrap and drop unsafe-inline csp (
17616634) — 2026-05-27 — Moved the pre-paint theme script topublic/theme-init.js, referenced it fromindex.html, and removed'unsafe-inline'fromscript-srcinfirebase.json. — Closes OWASP-3; tightens CSP against future inline-script XSS vectors. -
fix(backend): Harden rss endpoints with tls and admin auth (
63e72550) — 2026-05-27 — Replaced the silentrejectUnauthorized: falseTLS fallback with a skip-and-log path infunctions/index.js, and addedrequireAdminClaims('editor')to the manual RSS fetch and reviewer-digest HTTP endpoints. — Closes OWASP-2 and OWASP-4; eliminates MITM exposure on the retry path and rate-limits abuse by gating expensive endpoints behind admin claims.
2026-05-26 — AI Audit Stage 7 post-deploy validation¶
-
Validation: Regenerate 5 article covers with
imagen-4-fast— 2026-05-26 — TriggeredaltCoverImageTrigger=trueonpublished_blogdocs91IWYgpR31RjXmVD38Ba,IVrBFJ6yGAfCHBFT1dZM,LSzyB6gbiLyXtjQUcgGv,Ttt3Hv8d0gtcso4OQAVf,ibDYCON0ulcHmi55s1CK; ~$0.20 total (5 × $0.04google/imagen-4-fast). Two hotfixes required: (1) Replicate SDK 1.4.0 defaultuseFileOutput:truereturnedFileOutputobjects that, when passed tohttps.get(), producedECONNREFUSED 127.0.0.1:443— setuseFileOutput:falseincallReplicateApi; (2) Added missingconst historyUpdates = {}declaration ingenerateAiCoverOnContentTrigger(was referenced but never initialized, causinghistoryUpdates is not definedReferenceError). All 5 docs now serve fresh PNG+WebP atcovers/{contentId}-ai-hero.png. — Verifies that the deferred publish-time cover pipeline (R1) and the Imagen-4-fast default produce acceptable output at the new lower price point. -
Validation: Metadata-only ingest mode — 2026-05-26 — Ingested
content/stage7-metadata-test-1779829734414withCONTENTFORGE_METADATA_ONLY=true, confirmed nopostContentfield written; then triggeredgeneratePostContentHTTP function and confirmed field written. Required fixes tobuildInspectionUpdateDataundefined handling and JSON-repair fallback in AI router. — Verifies R8 (decouple draft body generation from ingest) works end-to-end on demand. -
Validation: Auto alt-text on ingest — 2026-05-26 — Ingested
content/stage7-alttext-test-1779834434558withCONTENTFORGE_ALT_TEXT_ENABLED=true; 4 alt-texts written via Vertexgemini-2.5-flashmultimodal. Hotfix:generateTextResponsewas used ingenerateAltTextsbut missing from the destructuredrequire('./lib/ai-model-router')infunctions/index.js— added to import and redeployedinspectAndPopulateContent. — Verifies G5 (imageAltTextsmap persisted to content doc) before exposing the feature publicly. -
Validation: Token usage logging — 2026-05-26 —
gcloud logging readinhybridcloudworks-61e8dshowed multiple[ai-model] vertex token usageentries after 24h traffic withCONTENTFORGE_LOG_TOKEN_USAGE=true. — Confirms R9 instrumentation lands in Cloud Logging for future per-provider cost dashboards. -
Set Firebase Functions config env vars for model selection — 2026-05-26 — Persisted
CONTENTFORGE_VERTEX_MULTIMODAL_MODEL=gemini-2.5-pro(G3) andCONTENTFORGE_VERTEX_DRAFT_MODEL=gemini-2.5-flash(G4) infunctions/.env; deployed toinspectAndPopulateContent,generatePostContent, andgenerateAiCoverOnContentTrigger. — Routes reasoning workloads togemini-2.5-proand cheap drafts togemini-2.5-flashper the audit's recommended tiering. -
chore(secrets): Secret Manager migration for AI provider keys (
41ca2add) — 2026-05-26 — WiredANTHROPIC_API_KEY,OPENAI_API_KEY,PERPLEXITY_API_KEY,GEMINI_API_KEY,REPLICATE_API_KEY,FIRECRAWL_API_KEYviadefineSecret; stripped plaintext fromfunctions/.env. Verified all 8 Cloud Run services usevalueFrom.secretKeyRef. Alt-text path re-verified oncontent/stage7-alttext-test-1779843199713. — Eliminates plaintext API keys from.env/Cloud Run metadata; centralizes rotation. Residual plaintext on historical Cloud Run revisions mitigated by provider-side rotation (the May 27ebf91cfdcommit). -
fix(functions): Dedupe duplicate
exports.syncMcpTools(00482c8e) — 2026-05-26 — Kept canonical OAuth-aware export supporting bothapiKeyEnvVar(Bearer) andoauthTokenmodes; removed the older duplicate. — Conflicting exports infunctions/index.jswere preventing predictable selection at deploy time.
2026-05-11 — AI cost & capability audit (7 stages) + Firebase/GCP cost audit¶
-
AI Cost & Capability Audit — Stages 1–7 complete (
8376be1,305e473) — 2026-05-11 — Stages 1–6 produced the full inventory, cost math, gap analysis, caching audit, and 17-item Tier 1–4 recommendations table. Stage 7 shipped every approved item: R1 deferred Imagen-4 to publish time (cbf9b81), R2/G1/R10 added image-model env vars defaulting togoogle/imagen-4-fast, R3 deleted the deprecatedscripts/generate-ai-covers.js, R4/R6 refreshed router defaults (claude-sonnet-4-6/claude-haiku-4-5/gpt-5-mini/gpt-5-nano), R5 threadedsystemPromptthrough the router and wired Anthropiccache_controlto the ≥1,024-token extracted prompts, R8 introducedCONTENTFORGE_METADATA_ONLYplus the newgeneratePostContentHTTP function, R9 added token-usage logging behind a flag, G2 added thegpt-image-1fallback path, and G5 added flagged auto alt-text generation. G3/G4 reduced to env-var-only swaps; G6/G7/G8/R7 (TTS, embeddings, flux-schnell) deferred. — Imagen-4 was firing on every ingest (94 URLs/day × $0.04 ≈ $113/mo, 72% of AI spend); R1 + R2 cuts image spend ~80% and the rest of the bundle modernizes models, adds caching, and unblocks alt-text + on-demand draft generation. -
AI Audit Stage 7 R1 — Defer Imagen-4 to publish time (
cbf9b81) — 2026-05-11 —buildInspectionUpdateDatano longer auto-firesaltCoverImageTrigger; newapplyPublishTimeCoverTriggerhelper inpublishNewBlogsets the trigger only when content transitions topublished_blogwithout a cover. Preserved two explicit opt-ins (generateAiCoverOnInspect=trueand legacyskipImageGeneration) for the regenerate-during- review workflow. — Largest single AI saver in the audit; 60–80% expected reduction in Imagen-4 spend. -
Firebase / GCP Cost Audit — F1–F12 closed — 2026-05-11 — F1 (
7864a08) replaced 4 admin full-collection scans with bounded queries +count()aggs + a maintaineddashboard_stats/v1summary doc updated viaFieldValue.incrementtriggers (added 2 composite indexes); cuts $7→<$1/mo at 1K docs and $72→<$5/mo at 10K. F2+F3 (1d48afe) deferredarchiveScrapedImagesto publish time and added a 90-day Cloud Storage lifecycle rule inplatform/firebase/storage-lifecycle.json. F4 (91f773a) switched/aboutcertifications andCustomSessionizeWidgetfrom live Firestore to build-time JSON snapshots (scripts/generate-public-data.cjs). F5 (b12adb8) replaced full-payload[ai-model]logs with metadata fingerprints (~5KB/ingest saved). F6 (7b9bba0) removed dead duplicateblogs/triggers (inspectAndPopulateArticle,generateAiCoverOnTrigger), decommissioned viafunctions:delete, and archived 10 legacy dev scripts. F7 (e4dfcb8) droppedinspectAndPopulateContentmemory 1GiB→512MiB. F8 (5bb6791) trimmed scheduler cadence (cleanupSoftDeletedContent1h→4h,monitorPublishingPipeline1h→6h) and skipped empty-run heartbeats; ~140→10 scheduled invocations/day. F9 (1af9321) added a 640w/1280w/2048w WebP responsive variant pipeline +<ResponsiveCoverImage>. F10 (58e9f27) splitvendor-firebaseby sub-package (public chunk 456→340 KB, ~35 KB gzip saved/visit; Auth/Storage now lazy via@/lib/firebaseStorage). F11 confirmedus-central1indefinitely (<20% non-US audience). F12 enabled BigQuery billing export and a $250 monthly budget with 20/40/60/80/100% alerts. — Largest single Firebase saver was F1; the bundle pulls the project from $80–120/mo at scale to <$15/mo at 10K docs and adds a budget tripwire for any regression.
2026-05-10 — Dependency upgrades, GitHub issues, theming + queue hardening¶
-
Dependency upgrades — React 19 + Vite 8 + Tailwind 4 + react-router 7 — 2026-05-10 — Closed all 13 outstanding dependency PRs (8 merged + 5 superseded by bundled commits). PR #172 consolidated 9 safe minor/patch bumps (firebase 12.12.1, react-hook-form 7.74, vitest 4.1.5, @playwright/test 1.59.1, axios 1.15.2, sharp 0.34.5, etc.); PR #173 bumped firebase-tools 15.15→15.16; workflow bumps for azure/setup-helm 1→3.5, actions/setup-java 4→5.2, actions/github-script 7→9, actions/upload-artifact 4→7; PR #160 brought replicate 0.34→1.4 (required
useFileOutput:falsecompat shim incms-functions.js:generateImageByPrompt); PR #169 react-zoom-pan-pinch 3→4; commit29ae4bashipped @vitejs/plugin-react 5→6 + Vite 7→8 + esbuild devDep; commit990c963shipped react-router-dom 6→7 with v7 future flags; commita092ffcshipped react 18→19 (codebase already R19-ready); commitsfbfb8fcshipped Tailwind 3→4 + tailwind-merge 1→3 — migratedtailwind.config.jsto CSS@theme inlineblocks, replacedtailwindcss-animatewithtw-animate-css, bumpedreact-helmet-async2→3. Build time ~4× via Oxide engine. — Brings the stack to current majors, unblocks v4 canonical classes, and resolves all open dependency PRs.@theme inlinewas critical to preserve the provider-theme cascade — without itbg-primarybaked white at parse time instead of resolving Azure blue under.theme-azure. -
GitHub issues closed — #171, #174, #147, #175 — 2026-05-10 — #171: restored
lighthouse:recommendedpreset, contrast 86→0, heading order fixed on AWS/Azure/Terraform, SEO meta-description fallback inindex.html, source mapshidden, console-error e2e guardrail, bundle split into 7 named chunks (−120 KB main vendor); suppressions documented in.lighthouserc.json_comment_*fields. #174: Azure-edu hover contrast fixed by scoping.theme-{provider} adefault-color rules to exclude button-styled<a>elements across azure/aws/github/finops. #147: jsx-eslint MetaProperty noise resolved by hoistingimport.meta.env.VITE_SOCIAL_*_URLreads inFooter.jsxto module-scopeconsts. #175: 43 lint warnings cleared via inline-style→named-CSS refactor and 24 complexity refactors + 7 mechanical fixes infunctions/; lint scope extended tofunctions/, verifiednpm run lint -- --max-warnings=0exit 0 acrosssrc/+functions/. — Brings the issue tracker to zero open dependency/lint/lighthouse defects ahead of the OWASP/ WCAG sweep. -
Theming, light/dark failsafe pipeline & queue hardening — 2026-05-10 — Removed hardcoded
class="dark"fromindex.html:2and added a pre-paint theme bootstrap script (later externalized in17616634). Consolidated theme toggles to the single floating bottom-right button.ThemeContextnow tracks OS preference and defaults toprefers-color-scheme. Lifted dark--muted-foregroundL60→L80% (contrast 4.6:1→10:1, affects 384 occurrences oftext-muted-foreground). Per-page contrast sweeps across Footer/Header/Rosetta Stone badges/Contact submit/Azure-edu hover buttons. Built a three-layer failsafe: ESLintno-restricted-syntax+scripts/axe-theme-scan.mjsPlaywright crawl + e2e contrast spec blocking merges (documented inFrontend-Theming-Guide.md). Queue persistence forensic investigation traced the "175→104 articles" loss to a daily 04:00 CT hard-delete cron - Delete-Rejected-Now button with no age filter; converted
deleteRejectedContentBatchto soft-delete and extended the reaper grace from 24h→7d (~8-day recoverable window). Added audit logging to all destructive cron paths viabuildSystemAuditLogData. ExtendedConfirmModalwith apreviewprop (bulk-reject renders top-10). Added per-card decay countdown badges inQueuePage.jsx, disambiguated theNeeds Reviewfilter, added URL-persisted sort controls. Consolidated dedup pipeline (URL + canonical + normalized title within a 7-day window) into a sharedfindDuplicateContenthelper across all 3 ingestion paths. — Light mode regressions, contrast failures, and silent queue-data loss were the top three reliability/UX risks before launch; this work closes all three and adds CI guardrails so they don't regress.
2026-04-29 — Security, performance, dependency hardening + CI hygiene¶
-
PR #150 — Performance hardening — 2026-04-29 — Resource hints in
index.html,font-display:swap, IBM Plex Mono self-hosted, ghost deps removed, FrameworkRadar lazy-loaded, Lighthouse coverage expanded to 9 routes. — Pre-launch performance baseline for Core Web Vitals. -
PR #149 — Security hardening — 2026-04-29 — Added 6 HTTP security headers in
firebase.json; Storage catch-all locked toif false; Firestore social/wiki collections restricted toisAdmin();scan-security.ymlblocks on CRITICAL/HIGH; GitHub Action versions pinned by digest. — Closes the open-by-default surface area before launch and prevents silent action-version drift. -
PR #148 — Dependency hardening — 2026-04-29 — Added Dependabot config across 3 ecosystems, annotated npm overrides with CVE justifications, added SBOM generation to
scan-security.yml. — Establishes the dependency-update cadence and produces an auditable SBOM artifact. -
CI/CD workflow hygiene — 2026-04-29 — Deleted
check-comprehensive.yml(redundant withcheck-quality+check-e2e). Added concurrency groups to all PR check workflows. Decoupled Lighthouse from deploy (deploy-frontend.yml20+min → 2–3 min).check-quality.ymlswitched from full build+tests tonpm run test:adminonly. Path-filteredscan-security.yml. — Cuts PR feedback latency and removes a duplicate workflow that was double-billing minutes.
Historical — Admin portal, editor, route factory, lifecycle baseline¶
-
Admin Portal Performance — historical — Replaced full-collection reads with summary doc + targeted queries on Dashboard, Published, Queue, Publish, OpsHealth pages; ImageGallery 500-record fetch converted to incremental loading. — Original Firestore-cost regression that motivated the F1 work above.
-
Editor Delivery — historical — Wider article layout in
BlogDetailTemplate; inline body modules (fact, recommendation, links, picture, spacer); drag-and-drop module ordering; byline control; spacer style presets. — Enables the inline-module authoring model the editorial pipeline now depends on. -
Admin Reliability — historical — Extracted
BlogReviewBoardfrom theReviewPagemonolith; removed dead multi-target publish stubs; removed legacyblogsfallback fromEditorPage; wired audit logging into mutation flows; surfaced save/publish errors; hardenedapi.js(URL validation, timeout/retry);firebaseConfig.jsfails fast on missing env vars. — Closes the most common admin-side failure modes (silent saves, env drift, monolithic page blowups). -
Route & UX standardization — historical — Introduced
src/lib/routeFactory.ts; header navigation uses provider-aware route generation; CI route-validation script; routing guide added todocumentation/. — Single source of truth for routes, preventing the provider/route mismatch class of bug. -
Live publishing & editorial verification — historical — Prod smoke test passed; Azure published content resolves to the wide article detail layout (
1136pxdesktop); byline read-order corrected (siteAuthor>publishedByName>createdByName); inline module pipeline and drag-and-drop ordering verified end-to-end. — Demonstrated the editorial pipeline works in production before opening it to non-author contributors. -
Codebase cleanup baseline — historical — Lint clean across
src/+functions/; PR quality gate enforces zero warnings; provider route/page contract validated in CI. — Becomes the zero-warning baseline that subsequent OWASP/WCAG/Tailwind-v4 work builds on. -
Lifecycle, abstraction & migration baselines — historical — Framework + architecture editorial pipeline delivered across review/detail/submission flows; public visibility rules standardized for published content; content lifecycle contract consolidated; AI model abstraction, deployment readiness validation, and data-model migration planning documented. Core Stage 2 frontend delivery reached production-ready baseline. Stages 3 & 4 (backend infra, integration/load testing, automation, FinOps shift-left) descoped May 10, 2026. — Establishes the architectural baseline referenced throughout the AI and Firebase cost audits.