Frontend User Stories — Overview & Conventions

This section documents the sharded, INVEST + Gherkin-formatted product backlog for the AMTP web frontend. The application is a pure React SPA; all routing is client-side (React Router), environment variables are baked at build time or fetched via /config, and no Node.js runtime logic exists in the frontend bundle.

Personas

Persona Abbrev. Primary Goals RBAC Summary
Business User BU Connect repos, trigger runs, review PRs and artifacts Create/edit projects, trigger runs, view history and artifacts, manage notification preferences
Approver AP Decide on awaiting_approval gates with full context View and action approval inboxes; no project/run mutation beyond approval decisions
Operator / Admin OP Maintain system health, GitHub App credentials, tenant roster, rate-limit config Full admin surface; can terminate workflows, rotate secrets, manage tenants and roles
Auditor AU Read-only compliance and audit access with zero mutation side-effects Read-only everywhere; mutating controls hidden; sensitive fields pre-redacted; clipboard copy intercepted and redacted

Reading Conventions

Story shape

### Story X.Y — <Imperative title>

**As a** <persona abbrev>
**I want** <capability>
**So that** <user outcome>

**Acceptance criteria**

- **Scenario: <label>**
  - **Given** …
  - **And** …
  - **When** …
  - **Then** …
  - **And** …

Gherkin grammar

Optimistic mutations additionally require a mutation addendum block in each mutating story. Any mutation Gherkin that lacks a prior_state clone in the Given/And block fails PR review.

Source citation format

**Source**
- `@/c:/ZT_AMTP/docs/AMTP_Docs_Website/<page>.html#<anchor>` — purpose

Endpoint map grammar

**Endpoint map**
- `<METHOD> /<path>` — purpose
- `<SSE|WS> /<path>` — streamed payload description
- DB: `<table>.<column>` — state read or written

Cross-Cutting NFRs

These requirements apply to every story across all 15 epics. They are declared here and inherited; epics do not repeat them.

Accessibility

WCAG 2.1 AA — visible focus rings on all interactive elements, full keyboard reachability, semantic landmark regions (<main>, <nav>, <aside>), aria-live regions for all SSE/streaming updates, colour contrast ≥ 4.5:1 for body text, interactive element hit-targets ≥ 44 × 44 CSS px.

Theming

prefers-color-scheme parity with the AMTP docs site. Palette: OKLCH, ZagTrader blue hue 240–241°, accent oklch(63% 0.20 241). Fonts: Chakra Petch (headings) + Hanken Grotesk (body). Callouts use full border: 1px solid + background tint — no accent left-stripes. No hard-coded colour values outside the design-token layer.

Internationalisation & Logical Properties

Copy externalised to i18n resource files. RTL-readiness (Arabic) is mandatory. Physical CSS direction properties are forbidden. CI enforcement is automated and blocks merge with no override path.

ForbiddenRequired
margin-left / margin-rightmargin-inline-start / margin-inline-end
padding-left / padding-rightpadding-inline-start / padding-inline-end
left: / right: (layout)inset-inline-start / inset-inline-end
border-left / border-rightborder-inline-start / border-inline-end
text-align: left|righttext-align: start|end

Reduced Motion

prefers-reduced-motion: reduce disables stage-timeline animations, skeleton shimmer, and all transition effects; static representations replace them.

Security

Privacy — Redaction Filter (dual-mode)

The Redaction Filter (RedactionFilter) operates in two modes:

ModeSurfacesStrategy
HeuristicEpics 5, 8Regex/pattern catalogue — catches tokens, JWTs, PEM markers, emails, SSNs
Schema-StrictEpic 15JSON-pointer allow-list of known-sensitive keys per audit-event schema

Every redaction emits a typed breadcrumb to the structured client log and OTel browser SDK envelope. The breadcrumb never carries the value, a prefix, a hash, or any reversible derivative.

Auditor copy/cut/drag interception: On the Artifact Viewer (Epic 5) and Audit Log (Epic 15), the UI intercepts copy, cut, and dragstart events for the Auditor persona, calls event.preventDefault(), runs the selection through the appropriate Redaction Filter mode, and writes only the redacted projection to event.clipboardData/DataTransfer.

Performance Budget

Dev-Prod Parity (Error Provenance)

Every error surface distinguishes between local infra failures (Docker daemon down, missing PEM, Postgres not bootstrapped, Valkey unreachable) and production API failures (GitHub API 5xx, OpenAI provider degradation, OAuth IdP outage). The deciding axis is the VITE_ENV build flag, resolved by the EnvProvenance module. PR reviewers reject error copy that conflates the two.

Traceability — Correlation Chip + Last-Synced Badge

Correlation Chip (CorrelationChip): Every error toast, banner, modal, and empty state renders the Correlation chip showing run_id (when scoped) and request_id from the X-Request-ID response header, copyable to clipboard.

Last-Synced Badge (LastSyncedBadge): Any view rendered from a reconciliation snapshot, prior_state rollback, or SSE Circuit-Breaker stall must display Synced at: <ISO local time> · Snapshot beside the Correlation chip. When the live SSE/WS stream is healthy, the badge reads Live.

Shared Frontend Modules

Canonical nameDescriptionOwner epic(s)
RedactionFilterDual-mode filter (Heuristic / Schema-Strict) + redactSelection() clipboard helper5, 8, 15
audit-export-worker.tsWeb Worker for non-blocking audit blob processing15
ReconnectControllerSSE/WS reconnect manager with Circuit-Breaker (3 disconnects / 60 s → Manual Reconnect Only)4
ReconciliationFetcherGET /runs/{id} post-reconnect re-sync; suppressed in Manual Reconnect Only4
TemporalLifecycleDetectorDistinguishes Network Idle from Activity Heartbeat Timeout4
SessionRefreshControllerSingle-flight 401 → POST /auth/refresh → retry + in-flight form preservation1
ReturnToValidatorWhitelist + HMAC verification; anti-Open-Redirect1
OptimisticMutationHelperprior_state capture / restore; persists x-idempotency-key for retry replay2, 3
EnvProvenanceResolves development / staging / production build flagAll
CorrelationChipRenders copyable run_id / request_id chip on all error surfacesAll error surfaces
LastSyncedBadgeLive vs Synced at: <time> · Snapshot indicator on streamed / snapshot views4+
design-tokensSingle source of truth for palette, typography, callout shapesAll

Failure-Class Distribution

Failure classOwning epicTrigger surface
Rate-limit rejection (Valkey)Epic 3Submit-run form, pre-flight 429
MalformedLlmOutputEpic 4Stage card error state + retry counter
SchemaValidationErrorEpic 4Stage card error state + artifact link disabled
BranchProtectionViolationEpic 6Approval gate banner + decision form
StaleBaseBranchEpic 7Terminal failure card on PR delivery view
PR-lock contention (pr_lock)Epic 7“Waiting for repository lock” status
GitHub App auth failureEpic 13Install status panel + remediation wizard
OTel/Tempo/Prometheus downEpic 14Service map degraded badges
Artifact JSON oversize/binaryEpic 5Viewer fallback + download-only mode

Zero-State Ownership

The cold-start onboarding flow (empty tenant → first project → GitHub App install → first run trigger) is owned by Epic 2 — Project Management. Epics 1 and 3 cross-link to this flow and do not duplicate empty-state acceptance criteria.

EpicOne-line summary
Epic 1 — AuthenticationOAuth login, silent token refresh, deep-link re-auth, Open-Redirect protection
Epic 2 — Project ManagementProject CRUD, soft-delete/restore, running-state guard, onboarding zero-state
Epic 3 — Run TriggeringManual run trigger, client-side idempotency key, rate-limit rejection
Epic 4 — Live Run TimelineSSE/WS timeline, circuit-breaker, reconciliation, Temporal lifecycle detection
Epic 5 — Artifact InspectionJSON viewer, diff, sanitizer staleness warning, Auditor redaction
Epic 6 — Approval WorkflowApproval inbox, approve/reject, 7-day pause, BranchProtectionViolation
Epic 7 — Pull Request DeliveryPR cards, idempotent re-PR, StaleBaseBranch, pr_lock contention
Epic 8 — Run History & SearchGlobal/project history, filters, full-text search, Auditor masking
Epic 9 — In-App ObservabilityPer-run token usage, latency, MCP cache-hit ratio, Grafana deep-links
Epic 10 — NotificationsIn-app + email/Slack subscriptions, quiet hours, theme/locale
Epic 11 — Quota & Rate LimitsRead-only quota visibility, concurrency gauge, pr_lock wait queue
Epic 12 — Admin: TenancyOrg CRUD, role assignment, invitations, SSO mapping
Epic 13 — Admin: GitHub AppApp install status, PEM rotation wizard, auth-failure remediation
Epic 14 — Admin: System HealthService map, Temporal task-queue backlog, Operator panic-button
Epic 15 — Audit LogImmutable feed, Web Worker export, non-persistence guarantee, redaction

Glossary

Core terms are defined at Concepts & Primer.

TermShort definition
RunOne end-to-end pipeline execution (runs table, V2)
StageOne Temporal activity invocation within a run (stages table, V3)
ArtifactStructured JSON output persisted between agent boundaries (artifacts table, V4)
ApprovalHuman or automated decision gate for a stage (approvals table, V5)
depth_levelPipeline thoroughness tier: smoke / core / standard / deep
pr_lockAdvisory lock preventing concurrent PR delivery for the same repository
heartbeat_timeoutPer-stage maximum inter-event silence before an Activity Heartbeat Timeout is declared
SanitizerPer-artifact schema-normalisation version recorded in artifacts.content.meta.sanitizer