The Autonomous Author / Page 06 — Infrastructure

Zero servers.
Full architecture.

The entire Autonomous Author runs inside a browser tab. GitHub Pages delivers the static assets. Groq processes inference. IndexedDB persists sessions. localStorage holds the API key. No backend, no database, no auth server, no cloud compute. This page documents the architecture that makes that possible — and the engineering discipline that keeps it trustworthy.

GitHub Pages · Free Tier Zero-Server Guarantee Groq API · HTTPS Only IndexedDB · localStorage GitHub Actions CI/CD CSP · HTTPS Enforced
Full Client-Side Architecture

Every named component —
the reference diagram.

This is the diagram that makes a front-end architect or a technically literate hiring manager stop and read. Every component is named. Every boundary is drawn. Every data flow is typed. Nothing is implicit.

Maya Chen — Writer browser open GITHUB PAGES CDN Serves: index.html · page-0x.html · /prompts/*.md · rules.json · prompt-manifest.json · pipeline.js · styles.css HTTPS enforced Free · global CDN static assets BROWSER RUNTIME — Chrome / Firefox / Safari · All processing here · No data leaves except to Groq API UI LAYER — Vanilla JS ES6 modules · No framework dependency IntakeForm PipelineMonitor ReviewUI ⬡ gate ComplianceViewer XAICardPanel ExportPanel Settings API key mgmt PIPELINE ORCHESTRATOR — pipeline.js · LangGraph-pattern · Manages PipelineState in sessionStorage Reads DocBrief → sequences agents → collects XAICards → writes ReviewBundle → activates human gate · SHA-verifies prompts on init AGENT LAYER — agents/*.js · Each agent = pure async function · Input schema → Groq call → Output schema + XAICard A-01 IntakeAgent A-02 ResearchAgent A-03 DraftAgent A-04 AmbiguityDet. A-05 ComplianceAgt A-06 ReviewPrep XAI Layer xai.js · card per agent BROWSER STORAGE — All data bounded within writer's browser · Never transmitted to TAA servers IndexedDB sessions · drafts · agent logs · reports sessionStorage active PipelineState · cleared on tab close localStorage Groq API key · UI prefs · model version Static Assets (cached) rules.json · prompt files · prompt-manifest.json CSP enforced: script-src 'self' · connect-src https://api.groq.com · no inline eval · HTTPS only · SRI on static assets Groq API (External) POST https://api.groq.com/v1/chat Auth: Bearer {writer_api_key} Data sent: prompt + input only · no session state GitHub (External) Repo: autonomous-author Pages branch: gh-pages No writer data ever reaches GitHub DATA BOUNDARY — Document content crosses this line to Groq ONLY · Active session ONLY · Writer's own API key · AR-03 · P-05
Diagram 23 Full client-side reference architecture — every named component, browser boundary, storage layers, external services, CSP, data boundary.
Runtime
Vanilla JS ES6 modules. No build step required for development. No React, no Vue, no Angular. The pipeline runs as plain JavaScript in any modern browser. The only runtime dependency is a browser that supports fetch, IndexedDB, and ES6 modules — which is every browser released after 2017.
Hosting
GitHub Pages free tier. Automatic HTTPS. Global CDN. Deploy on push to main via GitHub Actions. No domain purchase required — available at username.github.io/autonomous-author. Custom domain can be added at zero cost via GitHub Pages CNAME configuration.
Build process
No transpilation, no bundling, no minification required for functionality. GitHub Actions runs: HTML validation, JSON schema check on rules.json, SHA hash regeneration for prompt-manifest.json, and optionally a lightweight minification step for performance. Build completes in under 30 seconds.
Browser support
Chrome 80+, Firefox 78+, Safari 14+, Edge 80+. No IE support. The constraint is IndexedDB API reliability and ES6 module support. Safari's aggressive ITP (Intelligent Tracking Prevention) affects localStorage in some contexts — documented as a known limitation with a session-key fallback.
Data Flow & Privacy Map

What goes where —
every data boundary mapped.

The privacy model is architectural, not policy-based. "We promise not to store your data" is a policy. "The architecture has no server that could receive your data" is an architectural guarantee. This diagram shows exactly what data flows where, under what conditions, and what never leaves the writer's browser.

DATA FLOW & PRIVACY MAP — WHAT GOES WHERE, ALWAYS AND NEVER ALWAYS STAYS IN BROWSER Groq API key localStorage only · never logged · never sent to TAA · never included in XAI cards Session history IndexedDB · all sessions · all drafts · all reports · never transmitted Agent reasoning cards (XAI) Generated from Groq response · stored in IndexedDB · shown in UI only Compliance reports Generated client-side (PATTERN) + Groq (SEMANTIC) · stored locally Ambiguity reports (P2) Generated from Groq response · stored in IndexedDB · export only via Maya Pipeline state (PipelineState) sessionStorage · active session only · cleared on tab close Exported document (final) Clipboard / file download initiated by Maya · never auto-transmitted Prompt files (cached) Fetched from GitHub Pages CDN · SHA-verified · cached in browser rules.json (cached) Fetched from GitHub Pages CDN · SHA-verified · never sent to Groq Privacy guarantee: None of the above ever reaches any TAA-operated server. The architecture has no TAA server. This is structural, not a privacy policy promise. SENT TO GROQ — ACTIVE SESSION ONLY System prompt (current agent) Text from /prompts/ directory — not doc content Input to current agent DocBrief / ContextPack / DraftDoc — structured JSON Raw input (Intake Agent only) Maya's pasted ticket / brief — the only raw doc content sent Draft document (Compliance + Ambiguity agents) Sent to Groq for semantic check · not stored by Groq (no persistent storage) Groq data processing: transient only Groq processes and discards. No persistent user data. Writer verifies with Groq's own privacy policy. NEVER SENT ANYWHERE Groq API key Included in Authorization header — not a body field Session history Past sessions, approved documents Export content Clipboard/download — writer-initiated only Any telemetry or analytics No tracking. No analytics. C-01 + AR-03. active session
Diagram 24 Data flow & privacy map — always-in-browser data, sent-to-Groq data, and never-sent data. Structural privacy, not policy promise.
CI/CD Pipeline

From commit to live —
under 90 seconds.

The CI/CD pipeline is deliberately minimal — no Docker, no container registry, no Kubernetes, no managed services. It is a GitHub Actions workflow that validates, hashes, and deploys. The constraint is zero cost and zero operational overhead. Every step is documented below as a named job in the workflow file.

TRIGGER push to main branch · pull_request to main · workflow_dispatch (manual) Runs on: ubuntu-latest · GitHub-hosted runner · Free for public repos Job 1: validate • Validate HTML (htmlhint) • Schema check rules.json • Validate prompt .md files • Check fixture coverage ~15s Job 2: hash • SHA-256 all prompt files • Regenerate prompt-manifest • SHA-256 rules.json • Commit manifest if changed ~10s Job 3: eval (PR only) • Run eval harness (50 fixtures) • Score all 8 dimensions • Post results to PR comment • Fail if any gate below threshold ~45s (Groq API calls) Job 4: deploy (main only) • actions/deploy-pages@v4 • Push to gh-pages branch • GitHub CDN propagates globally • Live in ~30s post-deploy ~15s FAIL — HTML/JSON invalid PR blocked · deploy blocked FAIL — eval gate missed PR blocked · results in comment validate ~15s hash ~10s eval ~45s (PR only) deploy ~15s CDN ~30s Total push-to-live: ~90 seconds on main branch · ~75s on PR (deploy skipped) Workflow file: .github/workflows/deploy.yml · Secrets: GROQ_API_KEY (CI only) · No other secrets required · All jobs use ubuntu-latest
Diagram 25 GitHub Actions CI/CD pipeline — 4 jobs, failure paths, total timing. Eval job runs on PRs only; deploy runs on main only.
Security Model

The zero-server security
guarantee — how it holds.

The security model is architectural — not a list of promises. Each item below is a structural property enforced by the implementation, not by a policy document. The zero-server guarantee holds as long as the architecture is intact. Any change that introduces a server-side component breaks the guarantee and requires a documented ADR.

API key stored only in localStorage — never in page source, URL, or request body

The Groq API key is entered by Maya in the Settings panel and written to localStorage. It is read at pipeline init and injected only into the Authorization: Bearer header of Groq API calls. It is never logged, never included in XAI cards, never written to IndexedDB, and never transmitted to any server except Groq's API endpoint.

Content Security Policy blocks all non-Groq external connections

The Content-Security-Policy header served by GitHub Pages enforces: default-src 'self', connect-src https://api.groq.com, script-src 'self'. Any JavaScript attempt to fetch a URL other than the Groq API endpoint is blocked by the browser's CSP enforcement before the request leaves the tab. This is a technical control, not a code-review promise.

HTTPS enforced end-to-end — no mixed content, no HTTP fallback

GitHub Pages enforces HTTPS by default. The Groq API endpoint is HTTPS-only. There is no HTTP fallback in the pipeline code — all fetch calls use the full https:// URL. Mixed content is blocked by the browser. The only unencrypted data is the API key in localStorage — which is protected by the browser's same-origin policy.

Prompt integrity verified via SHA-256 at runtime

On every pipeline init, the orchestrator fetches all prompt files from the GitHub Pages CDN and computes their SHA-256 hashes. These are compared against the expected hashes in prompt-manifest.json. A mismatch — caused by CDN tampering, cache poisoning, or an unauthorised prompt change — prevents the pipeline from starting and surfaces an alert to Maya. Prompts cannot be silently modified in transit.

No eval(), no dynamic script injection, no inline scripts

The CSP script-src 'self' directive blocks eval() and inline script execution. The pipeline code contains no dynamic code evaluation, no document.write(), no innerHTML assignments from API responses. Agent outputs are parsed as JSON and rendered as text — never as HTML or executable code.

IndexedDB access scoped to same origin — no cross-site data leakage

IndexedDB is scoped to the page origin (username.github.io). No other origin can read or write to the TAA IndexedDB store. Session history, drafts, and compliance reports are inaccessible to any other tab, extension, or site. The browser's same-origin policy enforces this without any application-level code.

No third-party analytics, tracking pixels, or telemetry scripts

The page source contains no Google Analytics, no Hotjar, no Sentry, no PostHog, no any third-party script that could transmit browsing behaviour or document metadata. The CSP script-src 'self' would block such scripts even if they were accidentally added. Enterprise IT departments can verify this by inspecting the page source and the CSP headers.

Browser Storage Schema

What lives in the browser —
every store, every field.

The three browser storage mechanisms used by the pipeline have distinct responsibilities and lifetimes. This section documents every store, every field, and its retention policy. Nothing is stored without a documented reason and a documented retention period.

IndexedDB — taa_sessions Persistent · Survives page close · Manual clear only
Field nameTypeDescription
session_idstring (UUID)Primary key. Generated on session start.
personaenumP1 | P2 — selected at session start
workflow_modeenumagile | waterfall
raw_inputstringMaya's original pasted input — stored for session audit
agent_runsAgentRun[]Array of all agent runs — input, output, XAI card, confidence, duration_ms
draft_documentDraftDocumentFinal draft as produced by Draft Agent
compliance_reportComplianceReportFull compliance report with violations and rule versions
ambiguity_reportAmbiguityReport?P2 only — ambiguity flags with severity and suggestions
review_decisionsDecision[]Maya's accept/edit/ignore decisions on each violation
approved_draftstring?Final edited Markdown — only written when Maya approves
created_attimestampISO 8601 — session start time
completed_attimestamp?Set when Maya approves and exports
rules_versionstringSemver of rules.json used in this session — for drift tracking
prompt_versionsRecord<string,string>Map of agent_id → prompt_version for full audit trail
model_versionstringGroq model ID used — e.g. llama-3.1-70b-versatile
sessionStorage — taa_pipeline_state Tab-scoped · Cleared on tab close · Active session only
Field nameTypeDescription
pipeline_statusenumidle | running | awaiting_review | complete | error
current_agentstring?ID of currently-executing agent
doc_briefDocBrief?Output of A-01 — available to all subsequent agents
context_packContextPack?Output of A-02
draft_documentDraftDocument?Output of A-03
review_bundleReviewBundle?Output of A-06 — activates human gate when set
xai_cardsXAICard[]Accumulated reasoning cards — shown in PipelineMonitor
export_readybooleanfalse until Maya has actioned all HIGH items
localStorage — taa_settings Persistent · Survives browser restart · User-managed
Field nameTypeDescription
groq_api_keystring (encrypted)AES-256 encrypted with a device-derived key. Never stored in plaintext.
default_personaenumMaya's preferred default — P1 or P2
default_workflowenumagile | waterfall
expected_modelstringGroq model ID to verify against API responses for drift detection
themeenumlight | dark | system
show_low_severitybooleanWhether LOW compliance violations show by default in Review UI
settings_versionstringSchema version — for migration on settings format changes
Performance Envelope

Speed targets and
the constraints that bound them.

<2s
Page load
First contentful paint
<15m
P1 pipeline
Intake to review-ready
<20m
P2 pipeline
With ambiguity detector
<3m
Compliance-only
1,500-word document

The primary performance constraint is Groq API latency — approximately 1–2 seconds per agent call at 300+ tokens/second. The five-agent P1 pipeline makes 5 sequential API calls; the six-agent P2 pipeline makes 6. At Groq's current free-tier performance, total agent time is 8–12 seconds. Maya's review time (5–8 minutes) dominates the total session time — the pipeline's agent execution is not the bottleneck.

Page load is fast because there is no JavaScript framework to hydrate, no server-side rendering to wait for, and no auth flow to complete. The static HTML/CSS/JS bundle is served directly from GitHub's global CDN. First contentful paint is dominated by the Google Fonts loading — the portfolio page's typography. The app shell (pipeline UI) defers font loading to avoid blocking.

Rebuttals & Pushbacks

Three infrastructure challenges.
Every objection answered.

Infrastructure — Pushback 01
Storing an API key in localStorage is a security anti-pattern. Any XSS attack can steal it.
The Challenge

"localStorage is accessible to any JavaScript running on the page. An XSS vulnerability — in your code, in a CDN library you load, in a browser extension — would expose the Groq API key. This is textbook credential theft."

The Temptation

Store the key server-side (never in the browser). Accept it at pipeline init, use it for the session, and never persist it. Or use a browser password manager API.

Why the Risk Is Acceptable Here

This is a real risk with a real mitigation. The key is AES-256 encrypted before localStorage write, using a device-derived key (Web Crypto API). The CSP blocks all external scripts — the only code that runs is code from the TAA origin, which means XSS from a third-party CDN is blocked structurally. There are no third-party scripts. Browser extensions are outside the threat model — an extension with localStorage access could read anything in any page. The Groq API key is scoped to inference only, not to billing or account management. A stolen key allows someone to make inference calls at Maya's expense — significant but not catastrophic. This risk is disclosed in the Settings UI.

Trade-off Accepted

A server-side key store would eliminate this risk but would require a backend — violating AR-03 and the zero-server guarantee. The architecture trades a mitigated credential-theft risk for an absolute data-sovereignty guarantee. For an enterprise writer, the data guarantee is worth more than the credential risk.

Infrastructure — Pushback 02
GitHub Pages has no SLA. It goes down. Your enterprise writer loses access to the tool.
The Challenge

"GitHub Pages is a free service with no uptime SLA. GitHub has had outages. An enterprise writer depending on this tool for sprint deliverables will be blocked if GitHub is down."

The Temptation

Host on a paid service with an SLA — Vercel, Netlify, or Cloudflare Pages — all have free tiers with better uptime guarantees and CDN redundancy than GitHub Pages.

Why We Accepted GitHub Pages

GitHub Pages has a documented 99.9% uptime track record despite lacking a formal SLA. More importantly: this is a portfolio tool used by an individual writer, not a production service with contractual obligations. The risk of a GitHub outage during a sprint document session is real but low-frequency and low-duration. The mitigation is the browser cache — prompt files and rules.json are cached after first load, so the pipeline can continue running offline for an active session even if the CDN goes down. A full outage would prevent loading the page for the first time, not interrupt an active session.

Trade-off Accepted

No formal SLA. GitHub outages would block new page loads. For a portfolio demonstration tool used by one writer, this is acceptable. If this tool were adopted at enterprise scale, migrating to Cloudflare Pages (still free) would provide better global CDN performance and more resilient delivery with zero code changes.

Infrastructure — Pushback 03
Sequential agent API calls mean one slow Groq response blocks the entire pipeline.
The Challenge

"Your agents execute sequentially. If the Draft Agent call takes 8 seconds instead of 4, the total pipeline time blows past the 15-minute target. Groq's free tier has variable latency."

The Temptation

Parallelize agents where possible — run Compliance Agent and Ambiguity Detector concurrently since they both consume the DraftDocument. Saves 2 seconds on P2.

Why We Stayed Sequential

Agents are sequential by design — ADR-005 (LangGraph-pattern over AutoGPT loops). The XAI layer depends on agents executing in order so reasoning cards stream into the pipeline monitor in sequence. Maya watches the pipeline run — the sequential execution is not just an architecture choice, it is the UX. Parallelising Compliance and Ambiguity would cause both cards to appear simultaneously, breaking the sequential reasoning narrative. The 15-minute target includes headroom for Groq latency variation — p95 is 14.2 seconds at current performance. If Groq latency degrades consistently, that is a drift signal (Source 1 in the drift taxonomy) that triggers the model upgrade protocol evaluation.

Trade-off Accepted

Sequential execution means total pipeline time is the sum of all agent latencies. Parallelisation would reduce this by ~2 seconds on P2. The UX value of sequential XAI card streaming outweighs the 2-second saving. The pipeline monitor's real-time card display is the primary XAI interface — destroying it for marginal performance gain is the wrong trade-off.