Files
rust_browser/_bmad-output/planning-artifacts/architecture.md
Zachary D. Rowitsch 931f17b70e
All checks were successful
ci / fast (linux) (push) Successful in 6m46s
Add BMAD framework, planning artifacts, and architecture decision document
Install BMAD workflow framework with agent commands and templates.
Create product brief, PRD, project context, and architecture decision
document covering networking/persistence strategy, JS engine evolution
path, threading model, web_api scaling, system integration, and
tab/process model. Add generated project documentation (architecture
overview, component inventory, development guide, source tree analysis).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 15:13:06 -04:00

32 KiB

stepsCompleted, lastStep, status, completedAt, inputDocuments, workflowType, project_name, user_name, date
stepsCompleted lastStep status completedAt inputDocuments workflowType project_name user_name date
1
2
3
4
5
6
7
8
8 complete 2026-03-12
_bmad-output/planning-artifacts/prd.md
_bmad-output/planning-artifacts/product-brief-rust_browser-2026-03-05.md
_bmad-output/project-context.md
docs/index.md
docs/architecture.md
docs/project-overview.md
docs/component-inventory.md
docs/development-guide.md
docs/source-tree-analysis.md
docs/browser_architecture_initial_exploration.md
docs/browser_project_structure_modularization_guide.md
docs/browser_testing_strategy_high_level_to_detailed.md
docs/browser_milestone_plan.md
docs/milestone_6_phased_implementation_plan.md
docs/CSS2.1_Implementation_Checklist.md
docs/HTML5_Implementation_Checklist.md
docs/js_conformance_report.md
docs/js_feature_matrix.md
docs/known_limitations_log.md
architecture rust_browser Zach 2026-03-09

Architecture Decision Document

This document builds collaboratively through step-by-step discovery. Sections are appended as we work through each architectural decision together.

Project Context Analysis

Requirements Overview

Functional Requirements:

50 FRs spanning 9 categories. The heaviest architectural weight falls on:

  • Web Content Rendering (FR1-10): Full CSS 2.1 pipeline (parse/cascade/compute/layout/paint) plus images, generated content, and visual effects. Currently ~30% of CSS 2.1 checklist complete — the remaining 70% will systematically expand every engine crate.
  • JavaScript Execution (FR11-17): Custom engine must reach near-100% Test262 conformance. Currently at 70% on 550 vendored tests. Requires generators, async/await, ES modules, and complete built-in coverage — each touching js_parser, js_vm, and potentially web_api.
  • Navigation & Networking (FR18-25): Milestone 7's immediate focus. Cookie jar, HTTP caching, session persistence, and improved error handling require expanding the net and storage crates and wiring them through browser_runtime.
  • Browser Shell & UI (FR31-36): Tabbed browsing, reload/stop, loading status. Currently single-tab with URL bar and basic chrome. Tab management will expand browser_runtime and app_browser.
  • System Integration (FR43-46): OS font discovery, clipboard, file dialogs, URL handler registration. All must route through crates/platform/ per layering rules.

Non-Functional Requirements:

21 NFRs with the most architecturally significant being:

  • NFR1-5 (Performance): 3-second page load, smooth scrolling, 100ms JS yield budget, 2-second startup, stable memory. The single-threaded model must eventually accommodate these without architectural rewrites.
  • NFR6-10 (Security): Untrusted input everywhere, unsafe forbidden outside platform/graphics, same-origin policy, no telemetry. These are hard constraints on every architectural decision.
  • NFR11-15 (Reliability): No-crash guarantee on any input, CI gate on every change, regression tests mandatory, graceful network failure recovery.
  • NFR16-21 (Maintainability): 4-layer hierarchy enforced by CI, single-responsibility crates, file size limits, spec citations, comprehensible to one person.

Scale & Complexity:

  • Primary domain: Systems software — desktop browser engine
  • Complexity level: High (web standards surface area, multi-subsystem interaction, custom JS engine)
  • Existing architectural components: 22 crates across 4 layers
  • Estimated growth: web_api, net, storage, and browser_runtime will see the most expansion; new crates unlikely in near term

Technical Constraints & Dependencies

Constraint Source Architectural Impact
No unsafe outside platform/graphics CI-enforced policy All new subsystems must use safe Rust; FFI or GPU work funneled through two crates
No upward dependencies between layers CI-enforced (check_deps.sh) New features in engine crates cannot import browser_runtime or app_browser
Single-threaded rendering pipeline Design principle (determinism) Compositor thread or parallel style must be introduced carefully when performance demands it
Arena-based cross-crate IDs Existing pattern (NodeId, StyleId, LayoutId) New subsystems must follow this pattern rather than introducing lifetime-based references
Phase-based mutation model Existing pattern Parse → DOM → Style → Layout → Paint sequence must be preserved; no skipping phases
Blocking HTTP client (ureq) Current dependency Async networking would require architectural change; current model uses worker threads for I/O
Bundled fonts only (no system fonts) Known limitation System font discovery (FR43) requires expanding fonts crate and platform integration
~1 minute CI gate Existing practice Architecture changes must not significantly increase CI time; test262-full runs separately

Cross-Cutting Concerns Identified

  1. Spec compliance pipeline — Every CSS/HTML/JS feature addition touches 3-6 crates in sequence. The architecture must make this pipeline predictable and testable at each stage.

  2. Error resilience at every boundary — HTML, CSS, JS parsers plus network responses all handle untrusted input. Error recovery patterns must be consistent across all parsers without crashing or undefined behavior.

  3. Resource lifecycle management — Stylesheets, scripts, images, and fonts all follow a fetch → decode → use pattern routed through net. As caching and cookies are added, resource lifecycle becomes a cross-cutting concern touching net, browser_runtime, and every consumer crate.

  4. Testing infrastructure scaling — Golden tests, WPT harness, Test262 harness, and unit tests all need to grow proportionally with features. The testing architecture must accommodate 50,000+ Test262 tests and growing WPT coverage without CI becoming a bottleneck.

  5. State spanning navigation — Cookies, session data, browsing history, and cached resources must persist across navigations and eventually across restarts. This requires coordinating net, storage, browser_runtime, and eventually app_browser.

  6. Web API surface growth — The web_api crate bridges JS ↔ DOM and will absorb every new DOM API, event type, and Web API binding. It needs a scalable internal organization pattern to avoid becoming monolithic.

Starter Template Evaluation

Primary Technology Domain

Rust systems software — desktop browser engine. Brownfield project with established architecture.

Starter Template: Not Applicable (Brownfield)

rust_browser is not a greenfield project requiring a starter template. The codebase has been through 6+ milestones and has a mature, CI-enforced architecture.

Existing Technical Foundation

Language & Runtime:

  • Rust edition 2021, stable toolchain (pinned via rust-toolchain.toml)
  • Cargo workspace with 22 member crates
  • No async runtime on main thread; blocking is acceptable in the rendering path

Build & CI Tooling:

  • just task runner with just ci as the single validation command (~1 min)
  • cargo fmt, cargo xclippy -- -D warnings, policy scripts
  • deny.toml for license/advisory policy (cargo-deny)

Testing Framework:

  • Inline #[cfg(test)] unit tests + root tests/ integration tests
  • Golden regression tests (layout tree + display list dumps)
  • WPT harness for CSS/HTML spec compliance
  • Test262 harness (two-tier: vendored PR gate + full upstream suite)
  • proptest for property-based testing

Key Dependencies:

  • winit 0.30 (windowing), softbuffer 0.4 (pixel presentation)
  • ureq 2.x (HTTP), url 2.x, encoding_rs 0.8
  • image 0.25, resvg 0.47 (image decoding/SVG)
  • ab_glyph (font rasterization), bundled Noto Sans fonts
  • logos 0.14 (CSS tokenizer), regress 0.10 (JS regex)
  • thiserror 1.x + anyhow 1.x (error handling)
  • tracing 0.1 (structured logging)

Code Organization:

  • Strict 4-layer hierarchy enforced by scripts/check_deps.sh
  • Arena-based data flow with integer IDs across crate boundaries
  • Phase-based pipeline: parse → DOM → style → layout → display list → render
  • unsafe forbidden globally except platform/ and graphics/ (enforced by CI)

Note: No project initialization needed. Future architectural decisions build on this established foundation.

Core Architectural Decisions

Decision Priority Analysis

Critical Decisions (Block Implementation):

  • Networking & state persistence architecture (Milestone 7 blocker)
  • Web API crate scaling strategy (affects all new API work)

Important Decisions (Shape Architecture):

  • JS engine bytecode introduction timing
  • Threading model evolution path
  • System integration routing through platform/

Deferred Decisions (Decide When Needed):

  • Multi-process tab architecture (when tabs are implemented)
  • Tab state sharing model (when tabs exist + performance data)
  • JIT compilation (after bytecode + high spec compliance)

Networking & State Persistence

Decision Choice Rationale
Cookie jar location Module within net, interface designed for swappable backing store Cookies are consumed at the HTTP layer; keep them close. Interface allows later migration to storage-backed persistence. Extract to own crate if complexity warrants.
HTTP cache In-memory first, disk persistence later via storage In-memory caching is already partially implemented. Disk persistence adds complexity that can wait.
Storage crate role General-purpose persistence layer for all disk-persisted data storage manages the persistence engine; cookies, cache, localStorage, sessionStorage ride on top. Each consumer starts in-memory and plugs into storage when disk persistence is needed.

JavaScript Engine Evolution

Decision Choice Rationale
Bytecode introduction When generators/async-await become the next JS priority AST walker is sufficient for current spec compliance work (built-ins, Test262 gaps). Bytecode IR (not JIT) introduced as a bytecode interpreter when suspension semantics require it. Provides natural model for generators, better dispatch performance, and future JIT foundation.
Generators/async-await Forcing function for bytecode introduction Implementing suspension on the AST walker is architecturally awkward. Let this feature drive the bytecode transition.
ES modules registry Lives in js_vm Keeps JS engine self-contained. Module fetching involves net but the registry and linking semantics are JS-internal.
JIT compilation Deferred until bytecode exists + spec compliance is high Interpreter remains the correctness oracle. JIT is a performance optimization, not a correctness requirement.

Threading Model Evolution

Decision Choice Rationale
First concurrency step Compositor thread consuming immutable display lists Already hinted at in architecture exploration doc. Display list abstraction is built for this. Main thread produces display list, compositor thread rasterizes asynchronously.
JS yield mechanism Cooperative yielding via statement counter Existing max_statements in VmConfig provides the infrastructure. Check budget periodically, yield to rendering. Simpler than preemptive interruption. Less critical once JS eventually moves to its own thread.

Web API Crate Scaling

Decision Choice Rationale
Organization strategy Module-per-domain initially, extract to web_api_<domain> crates when complexity warrants Start with internal module organization (dom_bindings/, events/, scheduling/, etc.). When a domain crosses ~10-15 files or develops internal module structure, extract to web_api_events, web_api_storage, etc. Original web_api becomes facade/coordinator. Follows js/js_vm/js_parser pattern.

System Integration

Decision Choice Rationale
System font discovery platform/ handles OS-specific discovery via trait; fonts crate provides FontProvider facade Platform-specific behavior belongs in platform/. fonts owns the facade the rest of the project uses, with platform implementation injected at startup. Bundled Noto Sans remains fallback.
Clipboard & file dialogs Wrapped in platform/ behind traits (ClipboardProvider, FileDialogProvider); consumed by app_browser Cross-platform crates (arboard, rfd) wrapped behind traits for testability and platform-agnosticism in app_browser.

Tab & Process Model

Decision Choice Rationale
Process model Single-process now; multi-process when tabs are implemented No reason to build multi-process complexity before tabs exist. Design the multi-process architecture when tabbed browsing is the active milestone.
Tab state isolation Fully isolated per tab (each tab owns its own DOM, JS engine, styles, layout) Simpler starting point. Maps naturally to multi-process later. Shared caches (fonts, images) can be introduced as optimization. Cookie jar will need semantic sharing across tabs — design with tab implementation.

Decision Impact Analysis

Implementation Sequence:

  1. Cookie module in net + storage crate persistence interface (Milestone 7)
  2. HTTP cache improvements using in-memory store (Milestone 7)
  3. Web API internal module reorganization (ongoing, as APIs are added)
  4. System font discovery via platform/ + fonts facade (Phase 3)
  5. Bytecode IR introduction (when generators/async-await are prioritized)
  6. Compositor thread (when performance NFRs become blocking)
  7. Tab architecture + multi-process model (Phase 3)

Cross-Component Dependencies:

  • Storage persistence interface must be designed before cookies can be persisted to disk
  • Bytecode IR must exist before generators/async-await can be cleanly implemented
  • Compositor thread requires display list to be fully immutable after generation (already the case)
  • Multi-process tabs require fully isolated tab state (chosen as the default)

Implementation Patterns & Consistency Rules

Feature Implementation Checklists

CSS Property Implementation Order:

  1. Parse in css/ (tokenizer + parser + CssValue variant)
  2. Add computed style field in style/ (ComputedStyles + inheritance + initial value)
  3. Implement layout effect in layout/ (if layout-affecting)
  4. Implement paint effect in display_list/ (if visual)
  5. Add golden test(s) in tests/goldens/
  6. Update docs/CSS2.1_Implementation_Checklist.md
  7. Run just ci

HTML Element/Feature Implementation Order:

  1. Add parsing support in html/ (tokenizer recognition, tree builder handling)
  2. Add DOM representation in dom/ if needed (new NodeKind variant, element-specific data)
  3. Add default styling in style/ (UA stylesheet rules for the element)
  4. Implement layout behavior in layout/ (if element has special layout semantics)
  5. Implement paint behavior in display_list/ (if element has special visual rendering)
  6. Wire runtime behavior in web_api/ (if element has JS-observable behavior)
  7. Add golden test(s) in tests/goldens/
  8. Update docs/HTML5_Implementation_Checklist.md
  9. Run just ci

JS Feature Implementation Order:

  1. Add tokenization in js_parser/ (if new syntax)
  2. Add AST node(s) in js_parser/
  3. Implement execution in js_vm/
  4. Add unit tests inline in the implementing crate
  5. Add/update Test262 conformance tests in manifest
  6. Update docs/js_feature_matrix.md
  7. Run just ci

Not every feature needs every step — a semantic HTML element may only need parsing + UA styling + golden test + checklist. But the ordering is always: parser first, work down the pipeline, tests and docs last.

Error Handling Patterns

Crate Category Pattern Details
Parser crates (html, css, js_parser) Specific error types with source locations thiserror derive. Never panic on malformed input — return error or recover gracefully.
Engine crates (style, layout, display_list, render) SharedResult<T> for fallible operations Internal bug indicators use debug_assert! but must not panic in release builds.
Bridge crates (web_api, browser_runtime) Convert between error domains at boundaries JS-visible errors become JsValue error objects. Navigation errors become NavigationState::Failed.

Error type conventions:

  • Always derive Debug, Error, Clone, PartialEq, Eq via thiserror
  • Include constructor helpers (e.g., NavigationError::network(msg))
  • Implement From conversions for related error types manually

Test Placement & Naming

Test Type Location Naming When to Use
Unit tests Inline #[cfg(test)] mod tests test_<what_is_being_tested> Internal/private logic within a single crate
Split test files src/tests/ with mod.rs _tests suffix (e.g., flex_layout_tests.rs) When inline test module exceeds ~200 lines
Integration tests tests/*.rs Descriptive name + [[test]] in Cargo.toml Cross-crate behavior requiring full pipeline
Golden tests tests/goldens/fixtures/ + expected/ NNN-descriptive-name.html (sequential) Any rendering behavior change
Regression tests Inline or integration depending on scope Named for the bug, not the fix Every bug fix (mandatory)

Spec Citation Format

  • CSS: // CSS 2.1 §8.3.1 or // Per CSS 2.1 §17.5.2.1
  • HTML: // HTML §12.2.6.4.7 (WHATWG section numbers)
  • ECMAScript: // ECMAScript §13.15.3
  • When: Any non-obvious behavior implementing a specific spec rule. Not needed for plumbing code.
  • Where: Inline comment on the implementing line/block, not in doc comments.

New Crate & Module Introduction

Action When Requirements
New file within a crate Adding a logically distinct subsystem Don't add unrelated functionality to existing files. Respect file size limits.
New crate Subsystem needed by multiple Layer 1 crates, or extracting from an overgrown crate Add to workspace Cargo.toml members. Update check_deps.sh layer assignment.
Module visibility Always New modules are mod (private) in lib.rs. Public API re-exported via pub use. No pub mod.

Dependency Addition Protocol

  1. Check if std can do it — don't add a crate for what the standard library provides
  2. Pin in [workspace.dependencies] in root Cargo.toml with exact version
  3. Crates reference via dep.workspace = true
  4. Document rationale in PR/commit message (why needed, alternatives considered)
  5. Must pass deny.toml license/advisory checks
  6. Prefer lightweight crates — avoid large dependency trees for small functionality

Enforcement

All AI agents MUST:

  • Follow feature implementation checklists in order (parser → pipeline → tests → docs)
  • Update the relevant checklist document when implementing any CSS, HTML, or JS feature
  • Include a regression test with every bug fix
  • Cite spec sections for non-obvious behavior
  • Run just ci after every code change
  • Never add unsafe outside platform/ and graphics/
  • Never introduce upward dependencies between layers

Violations are caught by:

  • just ci (formatting, linting, tests, policy scripts)
  • scripts/check_deps.sh (layer violations)
  • scripts/check_unsafe.sh (unsafe policy)
  • scripts/check_file_size.sh (file size limits)
  • Code review (naming, spec citations, test quality)

Project Structure & Boundaries

Complete Project Directory Structure

rust_browser/
├── Cargo.toml                    # Workspace root: members, dependency versions, lints
├── Cargo.lock                    # Pinned dependency versions
├── CLAUDE.md                     # AI agent development instructions
├── AGENTS.md                     # Agent contract and rules
├── rust-toolchain.toml           # Toolchain: stable, rustfmt, clippy
├── deny.toml                     # License/advisory policy (cargo-deny)
├── justfile                      # Task runner: ci, test, lint, fmt, policy, metrics
├── src/lib.rs                    # Root crate: re-exports for integration tests
│
├── crates/                       # ── All workspace crates ──
│   ├── shared/                   # [Layer 0] Common types, geometry, errors
│   │
│   ├── js_parser/                # [Layer 1] JS tokenization + AST
│   ├── js_vm/                    # [Layer 1] JS interpreter + runtime
│   ├── js/                       # [Layer 1] JS engine facade
│   │
│   ├── html/                     # [Layer 1] HTML tokenizer + tree builder
│   ├── dom/                      # [Layer 1] DOM tree representation
│   ├── css/                      # [Layer 1] CSS tokenizer + parser
│   ├── selectors/                # [Layer 1] Selector matching + specificity
│   ├── style/                    # [Layer 1] Cascade + computed styles + UA stylesheet
│   │
│   ├── layout/                   # [Layer 1] Layout engine (block/inline/flex/table/positioned)
│   ├── display_list/             # [Layer 1] Display list builder
│   ├── render/                   # [Layer 1] CPU rasterizer
│   ├── graphics/                 # [Layer 1] Graphics backend abstraction (unsafe allowed)
│   │
│   ├── net/                      # [Layer 1] HTTP/file/data-URI loading + caching
│   │   └── src/
│   │       ├── cookie_jar.rs     # [PLANNED] Cookie storage + domain scoping
│   │       └── cache.rs          # [EXISTS]  In-memory HTTP cache
│   ├── storage/                  # [Layer 1] Persistent storage engine (placeholder → expand)
│   ├── image/                    # [Layer 1] Image decode pipeline
│   ├── fonts/                    # [Layer 1] Font loading + metrics + rasterization
│   │   └── data/                 #   Bundled Noto Sans fonts (3.1 MB)
│   ├── platform/                 # [Layer 1] OS windowing + events (unsafe allowed)
│   ├── web_api/                  # [Layer 1] JS↔DOM bridge, events, scheduling
│   │   └── src/
│   │       ├── dom_bindings/     # [PLANNED] querySelector, classList, style, ...
│   │       ├── events/           # [PLANNED] click, keyboard, focus, ...
│   │       └── scheduling/       # [EXISTS]  setTimeout, microtasks, promises
│   │
│   ├── browser_runtime/          # [Layer 2] Tabs, navigation, history
│   └── app_browser/              # [Layer 3] Desktop shell, event loop, chrome
│
├── tests/                        # Integration tests (each in root Cargo.toml)
│   ├── goldens.rs                #   Golden rendering regression tests
│   ├── goldens/                  #   Fixtures + expected outputs
│   ├── wpt_harness.rs            #   Web Platform Tests
│   ├── js262_harness.rs          #   Test262 JS conformance
│   ├── js_tests.rs               #   JS execution tests
│   ├── js_dom_tests.rs           #   DOM + JS interaction tests
│   ├── js_events.rs              #   Event system tests
│   ├── js_scheduling.rs          #   Microtask/promise tests
│   ├── navigation_tests.rs       #   Navigation lifecycle
│   ├── external_css_test.rs      #   CSS parsing tests
│   ├── main_cli_tests.rs         #   CLI integration tests
│   ├── regen_goldens.rs          #   Regenerate golden expected outputs
│   └── external/                 #   External test data (WPT, Test262)
│
├── scripts/                      # Policy enforcement + utilities
├── investigations/               # Site rendering reports
└── docs/                         # Project documentation + checklists

Architectural Boundaries

Layer Boundaries (enforced by CI):

Layer 3: app_browser    → can depend on anything below
Layer 2: browser_runtime → can depend on Layer 1 and 0
Layer 1: engine crates   → can depend on Layer 1 and 0 (no upward deps)
Layer 0: shared          → no internal dependencies

Unsafe Boundary:

  • unsafe code allowed ONLY in crates/platform/ and crates/graphics/
  • All other crates inherit unsafe_code = "forbid" from workspace lints
  • Enforced by scripts/check_unsafe.sh

Pipeline Phase Boundaries:

html (parse) → dom (tree) → css (parse) → selectors (match) → style (compute)
  → layout (position) → display_list (paint commands) → render (pixels)

Each phase produces a stable representation. No phase may skip ahead or reach back.

JS ↔ DOM Boundary:

  • web_api is the sole bridge between JS engine and DOM/browser
  • JS crates (js, js_vm, js_parser) never import DOM types directly
  • DOM crate (dom) never imports JS types directly
  • All interaction flows through web_api host bindings

Network Boundary:

  • net is the sole network access point for all resource loading
  • Engine crates request resources via net; they don't make HTTP calls directly
  • browser_runtime coordinates resource loading through net

Requirements to Structure Mapping

PRD Requirement Category Primary Crates Supporting Crates
Web Content Rendering (FR1-10) css, selectors, style, layout, display_list, render html, dom, fonts, image, shared
JavaScript Execution (FR11-17) js_parser, js_vm, js, web_api dom, shared
Navigation & Networking (FR18-25) net, browser_runtime storage, shared
Forms & User Input (FR26-30) app_browser, web_api, dom html, layout, display_list
Browser Shell & UI (FR31-36) app_browser, browser_runtime platform, shared
Content Security & Privacy (FR37-39) net, browser_runtime web_api
Offline & Storage (FR40-42) storage, net browser_runtime
System Integration (FR43-46) platform, fonts app_browser
Conformance & Testing (FR47-50) All crates tests/, scripts/

Planned Structural Evolution

Change Trigger Crates Affected
Cookie jar module in net Milestone 7 net, browser_runtime
Storage crate expansion (disk persistence) Milestone 7 (post-cookie) storage, net
web_api internal module reorganization As APIs are added web_api
web_api_events extraction When events/ exceeds ~15 files web_api → web_api_events
web_api_storage extraction When Web Storage APIs are added web_api → web_api_storage
Platform font discovery Phase 3 (system fonts) platform, fonts
Platform clipboard/file dialog traits Phase 3 (system integration) platform, app_browser
Bytecode crate (js_bytecode or within js_vm) When generators/async-await are prioritized js_vm (or new crate)

Data Flow

User Input (URL/click/keyboard)
  → app_browser (event handling)
    → browser_runtime (navigation lifecycle)
      → net (fetch resource)
        → html (parse HTML)
          → dom (build tree)
            → css (parse stylesheets)
              → selectors (match rules to nodes)
                → style (compute cascaded styles)
                  → layout (compute box geometry)
                    → display_list (generate paint commands)
                      → render (rasterize to pixels)
                        → platform (present to screen)

JS execution (orthogonal):
  → web_api (script execution trigger)
    → js (facade) → js_parser (parse) → js_vm (execute)
      → web_api (host bindings: DOM reads/writes, event dispatch)
        → dom (mutations) → [re-style → re-layout → re-paint]

Architecture Validation Results

Coherence Validation

Decision Compatibility: All architectural decisions are mutually compatible. No contradictions found. Key compatibility checks:

  • Cookie jar in net with swappable backing store aligns with storage as persistence layer
  • Bytecode deferral until generators/async-await is consistent with current AST walker spec compliance focus
  • Compositor thread model is compatible with existing immutable display list abstraction
  • web_api extraction pattern follows established js/js_vm/js_parser precedent
  • Platform traits for system integration extend existing FontProvider pattern

Pattern Consistency: Implementation checklists follow uniform principle (parser → pipeline → tests → docs). Error handling patterns align with existing thiserror/anyhow usage. Test placement and naming rules match established practice.

Structure Alignment: All planned evolution points (cookie_jar.rs, web_api subdirectories, storage expansion) fit into existing crate layout without layer violations.

Requirements Coverage

Functional Requirements: 49 of 50 FRs have clear architectural support. FR37 (tracker/ad blocking) is architecturally unspecified — deferred to Phase 3 design.

Non-Functional Requirements: All 21 NFRs are architecturally addressed. Performance NFRs have evolution paths (compositor thread, JS yield). Security NFRs are enforced by CI. Reliability NFRs are covered by error patterns and testing mandate. Maintainability NFRs are enforced by layer hierarchy and policy scripts.

Implementation Readiness

Decision Completeness: All critical and important decisions are documented with rationale. Deferred decisions have clear triggers for when they need to be made.

Structure Completeness: Project structure is fully defined with existing layout, planned additions marked, and evolution triggers specified.

Pattern Completeness: Feature implementation checklists, error handling, test placement, spec citations, module introduction, and dependency protocols are all specified with concrete rules.

Architecture Completeness Checklist

Requirements Analysis

  • Project context thoroughly analyzed (50 FRs, 21 NFRs, 42 project context rules)
  • Scale and complexity assessed (High — web standards surface area)
  • Technical constraints identified (8 constraints documented)
  • Cross-cutting concerns mapped (6 concerns identified)

Architectural Decisions

  • Critical decisions documented with rationale (networking, web API scaling)
  • Technology stack fully specified (existing brownfield foundation)
  • Evolution paths defined (JS bytecode, compositor thread, multi-process tabs)
  • Performance considerations addressed (yield mechanism, compositor thread)

Implementation Patterns

  • Feature implementation checklists established (CSS, HTML, JS)
  • Error handling patterns defined by crate category
  • Test placement and naming rules specified
  • Spec citation format standardized
  • Module introduction and dependency protocols documented

Project Structure

  • Complete directory structure defined with annotations
  • Architectural boundaries established (layers, unsafe, pipeline, JS↔DOM, network)
  • Requirements mapped to specific crates
  • Planned structural evolution documented with triggers

Architecture Readiness Assessment

Overall Status: READY FOR IMPLEMENTATION

Confidence Level: High — brownfield project with 6 milestones of proven architecture; decisions extend rather than replace existing patterns.

Key Strengths:

  • Architecture is battle-tested through 6 milestones of real implementation
  • CI enforcement (layers, unsafe, formatting, linting) prevents architectural drift
  • Clear evolution paths for major subsystems avoid premature complexity
  • Deferred decisions have explicit triggers, preventing analysis paralysis

Areas for Future Enhancement:

  • Tracker/ad blocking architecture (Phase 3)
  • Multi-process tab isolation details (when tabs are implemented)
  • GPU rendering pipeline architecture (when CPU rasterization becomes a bottleneck)
  • JIT compilation architecture (after bytecode + high spec compliance)

Implementation Handoff

AI Agent Guidelines:

  • Follow all architectural decisions exactly as documented
  • Use feature implementation checklists for every CSS, HTML, or JS addition
  • Respect layer boundaries and unsafe policy — CI will reject violations
  • Consult this document + project-context.md + CLAUDE.md for all architectural questions

First Implementation Priority: Milestone 7 — Cookie jar module in net with domain scoping and swappable backing store, followed by HTTP cache improvements and session persistence via storage.