Release 1 architecture baseline and decisions
This explanation gives the Enterprise Architecture Board a fundamentals-first view of AeroSim Release 1. It complements the C1 System Context, C2 Container view, per-container C3 Component views, the item-level Board report, and the delivery-readiness architecture and handover chain.
Architecture status
Verdict: conditionally accepted Architecture boundary; not release approval. The Architecture owner accepted ADR-0001 and ADR-0002 and conditionally accepted KDD-R1-01 through KDD-R1-03. KDD-R1-04 and KDD-R1-05 were returned, and KDD-R1-06 remains open. Separately, 33 of 34 Release 1 Features remain Proposed. This page does not approve Scope, residual operational risk, implementation admission, release, promotion, UAT, or product acceptance.
| Evidence layer | Evidence reference | Meaning |
|---|---|---|
| Canonical documentation | c4db84b8f888acddfc0b05c30eb4ac0467d0bd14 | Scope, requirements, ADRs, Tasks, C4 views, and lifecycle records reviewed by this baseline |
| Integrated application source | 7e7d557291c9b15a8b97e8ef587e3faa91c5bf03 | Current application default used to verify implemented structure |
| Development deployment | source 7e7d557291c9b15a8b97e8ef587e3faa91c5bf03; GitOps fb5469900a93a607c2767342912d9b95cd09bc98 | Synced/Healthy development tuple recorded by the Board packet evidence snapshot |
| Production deployment | source dbba4a186a02cb4567c64f1c3400d38556aa1a25; GitOps 5a440bbe62b4d284b8b8ce81c2afeb79a974f762 | Synced/Healthy production tuple recorded by the Board packet evidence snapshot |
| Board packet evidence base | PR #369 source head 69bf11a18c870684ffe6ac0ca2a6c42dafef4842 | Starting packet for this revision; reviewers must freeze the current PR head because this row is not the candidate's self-identity |
The development and production deployment tuples differ. Evidence from one tuple cannot prove another. Any source, image, chart, GitOps revision, environment or required journey change invalidates prior candidate UAT evidence. A rendered-template change also invalidates the tuple.
Release 1 outcome and boundary
Release 1 is intended to provide one authenticated browser-based free-flight product slice:
- a governed engineering, build, artifact, and deployment foundation;
- Keycloak sign-in, pilot identity linkage, preferences, progress, and resumable activity;
- believable and repeatable aircraft/world behaviour;
- deliberate aircraft, world, conditions, controls, and camera configuration;
- a complete launch, fly, pause, recover, finish, abort, retry, and restart loop; and
- a controlled, traceable, and reversible release path.
Release 1 does not establish guided-training progression, advanced post-flight analysis, or later-release geometry/CI improvements merely because related proposed requirements exist in the repository. The release allocation remains the authority for membership.
Owned system boundary
| Owned element | Responsibility | Explicitly not owned |
|---|---|---|
| Web Application | Browser session, pre-flight, world bootstrap, deterministic fixed-step simulation, rendering, controls, recovery, outcomes, and API clients | Identity-provider administration, public TLS termination, Kubernetes orchestration |
| API Service | Token validation, pilot-owned HTTP persistence, health endpoints, and an authenticated fail-closed Socket.IO scaffold | Browser physics, browser-bundled catalogues, direct public certificate lifecycle |
| Pilot Data Store | Durable pilot linkage, camera preference, resumable progress, outcomes, and attempt fields within progress records | Credentials, identity-provider records, direct browser access |
| Documentation Site | Governed product, architecture, delivery, and engineering evidence | Runtime availability of the flight product |
Keycloak, Gitea, Harbor, Osgiliath, Kubernetes, Argo CD/GitOps, External Secrets, and Project Pages are external platform dependencies. They remain outside the AeroSim product boundary even when AeroSim depends on their contracts.
Architecture drivers
| Driver | Required system response | Current evidence | Decision state |
|---|---|---|---|
| Pilot isolation | Every protected read, write, and live connection resolves to one authenticated Keycloak subject; cross-pilot access is denied | API identity guard, Prisma ownership checks, isolation tests | Implemented; lifecycle and fine-grained authorization policy not approved |
| Deterministic flight | Equivalent governed initial state and timed input produce bounded-equivalent authoritative state; rendering cannot become a second authority | Browser-local 60 Hz fixed step and deterministic tests | ADR-0001 accepted with explicit residual conditions |
| Configuration integrity | Launch uses one complete, revision-bound aircraft/world/conditions/controls/camera tuple and rejects stale or mismatched references | Pre-flight and launch validation, catalogue and session tests | ADR-0002 accepted with release-coupled catalogue conditions |
| Persistence integrity | A terminal attempt is not presented as saved until transactional persistence succeeds | API/Prisma transaction and failure tests; debrief/progress withholding | Implemented; retention, deletion, recovery and audit policy not approved |
| Supply-chain integrity | Source, images, chart, rendered templates, GitOps and release evidence bind to immutable identities | Exact-head CI, digests, chart/template provenance, GitOps selection | Implemented controls; one releasable tuple and promotion decision still open |
| Security | No local passwords, browser administrative secrets, direct database access, or unvalidated protected requests | Authorization Code with PKCE, JWT/JWKS validation, External Secrets, network policy tests | Implemented controls; session lifecycle, rotation and incident policy not approved |
| Reliability | Invalid configuration, world, asset, frame, persistence and deployment states fail closed with an owned recovery path | Typed diagnostics, readiness/liveness, rollback and mismatch checks | Partial; SLO, RTO, RPO, restore and capacity decisions not approved |
| Operability | Operators can detect, diagnose, contain, restore and prove one exact candidate | Health endpoints, CI/GitOps evidence and rollback records | Partial; production observability and recovery objectives remain open |
End-to-end system flows
Sign-in and session
- The browser starts OIDC/OAuth 2.0 Authorization Code with PKCE against Keycloak.
- The Web Application holds the application session and sends the access token to protected AeroSim HTTP boundaries. The exposed Socket.IO route authenticates tokens but has no active Web client in the Release 1 flight path.
- The API validates issuer, audience, signature, expiry, and claims through Keycloak JWKS before attaching the subject context.
- Invalid, expired, wrong-issuer, or absent credentials fail closed. Health endpoints remain outside the pilot identity guard and disclose no pilot data.
Pre-flight and launch
- The API returns the authenticated pilot profile and preferences; governed aircraft, world, and condition catalogues are compiled into the Web Application.
- The pilot selects aircraft, world, conditions, controls, and camera.
- The Web Application binds the selection to the active application/catalogue revision and rejects missing, disabled, stale, or incompatible references.
- World bootstrap validates terrain, physics profile, assets, collision/world-space contracts, and camera anchors before exposing a ready session.
Flight and outcome
- Input is converted into bounded typed control state.
- One browser-local, fixed-step flight authority advances forces, wind, collision, boundaries, recovery, and attempt state.
- Rendering and presentation consume the authoritative frame; they do not mutate authoritative simulation state.
- Completion, failure, and abort retain one attempt identity and explicit terminal semantics; retry follows the governed retry contract, while a deliberate restart creates a new provenance-linked attempt identity.
- Persistence failure retains terminal attempt identity but withholds a saved debrief and progress checkpoint until the write succeeds.
Delivery and runtime
- Gitea Actions validates exact source and publishes immutable Web/API images and a versioned chart to Harbor.
- The GitOps repository selects exact image/chart identities and supplies environment-specific configuration.
- Argo CD reconciles the declared state into Kubernetes.
- Osgiliath terminates public TLS and forwards trusted HTTP to Kubernetes Ingress.
- Ingress routes HTTP
/to the Web Application and HTTP/apiand/socket.iowith WebSocket upgrade to the API Service. - Runtime acceptance and UAT must bind to one frozen source/image/chart/template/GitOps/environment tuple.
Data ownership and lifecycle
| Data class | Authoritative owner/store | Access rule | Integrity/failure rule | Governance state |
|---|---|---|---|---|
| Keycloak identity | Identity platform | AeroSim receives subject/claims only; no local password | Invalid identity fails before protected processing | Joiner/mover/leaver, MFA, recovery and privileged administration not approved |
| Pilot linkage/profile | API Service / PostgreSQL | Same authenticated subject only | Unique linkage and transactional updates | Classification, retention, export and deletion not approved |
| Preferences | API Service / PostgreSQL | Same authenticated subject; supported values only | Invalid values rejected; last valid value restored | Retention and deletion not approved |
| Resumable progress | API Service / PostgreSQL | Same authenticated subject | Only actually resumable activity is exposed | Invalidation exists; retention and deletion not approved |
| Attempt data and outcome | API Service / PostgreSQL progress records | Same authenticated subject | Attempt/configuration lineage retained; failed writes are not presented as saved | Retention, deletion and audit policy not approved |
| Operational logs/CI evidence | Delivery and Operations systems | Operational identities only | Must not contain secrets or unnecessary pilot data | Retention, disposal and audit access not approved |
The browser never receives database credentials and never connects directly to PostgreSQL. Only the API's Prisma adapter may access the Pilot Data Store.
Integration contracts and failure semantics
| Boundary | Contract | Ordering/idempotency | Fail-closed behaviour |
|---|---|---|---|
| Browser ↔ Keycloak | OIDC/OAuth 2.0 Authorization Code with PKCE | One intended-route restoration after a valid session | Reject invalid state, nonce, issuer, audience, signature, expiry or callback |
| Browser ↔ API HTTP | HTTPS/JSON through public proxy; internal route is HTTP /api | Writes use validated identity and record semantics; repeated profile resolution is idempotent | Validation, identity, ownership, persistence and conflict errors remain distinct |
| Ingress ↔ API socket scaffold | HTTP/WebSocket upgrade through /socket.io; no active Web client | Handshake authenticates and typed payloads validate, but production injects no flight-command forwarder | Reject unauthenticated/invalid payloads and return COMMAND_FORWARDER_UNAVAILABLE for valid flight commands |
| API ↔ PostgreSQL | Prisma over PostgreSQL inside the namespace NetworkPolicy boundary | Transactional pilot-owned writes and reproducible migrations | Roll back failed transactions; no partial saved outcome/progress claim; transport encryption is not assumed |
| GitOps ↔ runtime | Immutable image/chart/template/GitOps tuple | Reconciliation is declarative; candidate identity must match reviewed evidence | Reject mutable tags, missing digests, mismatched tuple, or absent approval |
| Osgiliath ↔ Ingress | Trusted internal HTTP after public TLS termination | Reverse-proxy and WebSocket upgrade preserve route intent | ADR-0004 records the accepted boundary; residual internal-hop risk remains visible |
Security and trust model
Trust zones
Pilot browser
→ public HTTPS/WSS and Osgiliath TLS boundary
→ Kubernetes Ingress
→ Web Application / API Service namespace
→ Pilot Data Store
Keycloak → external identity trust
Gitea / Harbor / GitOps / External Secrets → delivery and workload-supply trust
Required controls
- Keycloak is the only user-authentication path; AeroSim has no registration, password store, or local sign-in fallback.
- Protected HTTP and Socket.IO operations require a validated identity and subject-scoped authorization.
- The API is the only application path to PostgreSQL.
- Secret values arrive through the platform's External Secrets contract and are not stored in browser code, Git, Helm values, logs, or architecture artifacts.
- Runtime artifacts use immutable digests; chart/template/GitOps identities are part of the candidate evidence.
- Public TLS terminates at Osgiliath under accepted ADR-0004; the internal HTTP hop remains a consciously visible trust-boundary risk.
- The reviewed PostgreSQL StatefulSet and application selection establish NetworkPolicy-restricted access but do not establish database TLS; the Board must require encryption or explicitly accept and bound the internal transport risk.
- Asset intake must preserve provenance, licensing, validation, and runtime-budget evidence.
The current model does not yet define approved token/session lifetimes, revocation/logout, signing-key rollover, secrets rotation, compromise response, rate limits, abuse controls, data classification, privacy retention, or auditable security-event requirements.
Reliability and operability
| Concern | Existing mechanism | Required measurable closure |
|---|---|---|
| Liveness/readiness | Web and API health endpoints; probes bypass pilot auth and expose no pilot data | Define detection time, alert owner, dependency criteria, and false-positive budget |
| Simulation stability | Fixed 60 Hz step, bounded catch-up, finite-state guards, typed diagnostics | Approve supported browser/device envelope and quantitative frame/step budgets |
| World/asset failure | Initialization cancellation, resource disposal, manifest/world-space validation | Define retryability, user recovery, telemetry and incident threshold per failure class |
| Persistence failure | Transaction rollback and withheld saved state | Approve retry/idempotency policy, operator alerting, data-loss objective and reconciliation process |
| Database recovery | Durable PostgreSQL and reproducible Prisma migrations | Approve backup cadence, encryption, retention, restore test, RTO and RPO; no recovery claim before evidence |
| Deployment rollback | Immutable candidate identities, GitOps history and rollback evidence | Approve rollback trigger, authority, maximum restoration time and post-rollback verification |
| Capacity | Browser/runtime resource checks and Kubernetes resource configuration | Define supported concurrency, namespace limits, saturation indicators and load-test evidence |
| Observability | Health checks, CI evidence and typed application diagnostics | Define logs, metrics, traces, correlation IDs, dashboards, alerts, retention and personal-data handling |
| Environment freshness | Exact tuple and evidence-invalidation rule | Freeze one tuple, rerun all required journeys, prohibit evidence mixing, and publish durable UAT_PASSED |
RTO and RPO are deliberately not invented here: they are not approved. The Board must select objectives before Architecture can claim a recoverable service.
Architecture decision register
| Decision | Recommendation | Status and authority needed | Acceptance evidence |
|---|---|---|---|
KDD-R1-01 — Flight authority | Browser-local deterministic fixed-step flight authority; API and public Socket.IO scaffold are not physics authorities | Accepted with conditions by Architecture owner; ADR-0001 accepted | Preserve 60 Hz fixed step, five-step bounded catch-up, invalid-state fail-closed behavior, deterministic tests and supported-device envelope; no server-authoritative anti-tamper claim |
KDD-R1-02 — Configuration authority | Static browser-bundled governed catalogues plus source-revision-bound immutable launch snapshots | Accepted with conditions by Architecture owner; ADR-0002 accepted | Reject or reconfirm stale/disabled/unknown changes; catalogue changes require a new build/release and invalidate prior confirmation; dynamic catalogues remain deferred |
KDD-R1-03 — Identity/session boundary | Keycloak Authorization Code with PKCE, API JWT/JWKS validation and subject-scoped pilot authorization | Conditionally accepted by Architecture owner; closure conditions remain open | Record and verify lifetime, refresh, logout/revocation, rollover, admission/deprovisioning, and Socket.IO origin/token-age/quota/payload policy |
KDD-R1-04 — Data lifecycle and recovery | API-owned pilot persistence is established, but lifecycle and recovery policy are incomplete | Returned — not decision-ready | Product/Data/Security policy, least-privilege roles, retention, deletion/export, backup/restore, RTO/RPO and PostgreSQL TLS decision required |
KDD-R1-05 — Operability and service objectives | Objective categories are established; numeric targets and evidence are absent | Returned — not decision-ready | Operations-owned SLO, capacity, observability, recovery and incident objectives plus validation evidence required |
KDD-R1-06 — Release evidence boundary | One immutable tuple, authenticated journeys, promotion authority, runtime verification and post-release acceptance remain mandatory | Architecture concurrence; open for UAT, Releases and RootAtSkic | Exact tuple manifest, durable UAT_PASSED, promotion event, dependency-aware readiness, Argo/runtime readback, rollback and acceptance events |
ADR-0004 already accepts public TLS termination at Osgiliath, optional in-cluster chart TLS, and HTTP for the trusted Osgiliath-to-Ingress hop. Any change to that boundary requires a superseding ADR.
The Architecture owner recorded these dispositions on 2026-09-25 against merged evidence baseline 0faea543943f893601fdc90c9a64f0b566cd0d80. The attributable decision is Discord message 1552955532271296534. The decision does not approve Scope, implementation, UAT, promotion, release, residual operational risk, or human product acceptance.
Risks and required closure evidence
| Risk | Why it matters | Required owner action |
|---|---|---|
R-SEC-03 — Data lifecycle absent | Personal pilot/profile/progress/outcome data has no approved classification, retention, deletion/export or legal/operational ownership | Product data owner and Security define policy; Architecture binds it to stores, APIs and evidence |
R-SEC-04 — Recovery unproven | Database durability is not the same as a verified restore; service recovery cannot be claimed | Operations/Data owner approve backup, restore, RTO/RPO and produce restore evidence |
R-SEC-05 — Secrets lifecycle incomplete | External Secrets prevents repository storage but does not define rotation or compromise response | Gondor platform and Security record rotation cadence, emergency revocation and proof |
R-SEC-06 — Database transport encryption unproven | The reviewed PostgreSQL manifests and connection selection do not establish TLS for the API-to-database hop | Security, Operations and Architecture enable verified PostgreSQL TLS or explicitly accept the bounded namespace risk with conditions |
R-SEC-07 — Database runtime privilege is too broad | The same PostgreSQL owner/bootstrap credential is used to initialize the database and serve ordinary API requests | Create separate owner, migration, and least-privilege runtime roles; rotate the shared credential and prove negative access boundaries |
R-SEC-08 — Identity admission policy undefined | Any audience-valid Keycloak subject can provision a pilot because roles, groups, scopes, and deprovisioning are not part of authorization | Decide whether every realm user is admitted or enforce an explicit entitlement claim and lifecycle policy |
R-SEC-09 — Socket scaffold lacks abuse bounds | The exposed route authenticates only at handshake and has no approved origin, token-age, connection, event-rate, queue, or payload policy | Either remove the inactive public surface or define and verify expiry, origin, quota, backpressure, payload, timeout, and audit controls |
R-ARC-01 — Flight-authority residuals | ADR-0001 accepts browser-local authority; client variance, tampering, replay provenance and unsupported-device behaviour remain bounded residuals | Preserve the accepted KDD-R1-01 conditions; require a superseding decision for server-authoritative or competitive behaviour |
R-ARC-02 — Configuration-authority residuals | ADR-0002 accepts static browser-bundled catalogues; updates remain release-coupled and dynamic authority is deferred | Preserve the accepted KDD-R1-02 conditions; require a superseding decision for dynamic catalogues |
R-REL-02 — Environment evidence diverged | Development/integrated source and production use different immutable tuples; prior UAT cannot prove either new candidate | UAT/Releases classify the delta, freeze one tuple, rerun required journeys and forbid mixed evidence |
R-REL-03 — Release health checks can miss database failure | Release verification uses unconditional /api/health while dependency-aware /health/ready returns failure when PostgreSQL is unavailable | Make dependency-aware readiness a release gate and prove database loss removes the API from service and blocks UAT |
R-REL-04 — Single failure domain | Web, API, PostgreSQL, and NFS-backed storage each use one active instance/path with no accepted availability objective | Set the availability target, add required redundancy or explicitly accept downtime, and test node/pod/database/storage failures |
R-OBS-01 — No production observability contract | Health, logs, CI and Argo evidence exist, but metrics, traces, correlation, alerts, retention, responders, and incident objectives are not approved | Define SLIs/SLOs, telemetry and audit fields, dashboards, alerts, owners, retention, redaction, MTTD, acknowledgement, and game-day evidence |
R-SUP-01 — Chart digest is not deployment enforcement | Argo CD selects the chart by mutable version while a digest annotation/policy records but does not cryptographically bind the fetched chart | Enforce registry immutability plus digest readback or a digest-bound/signed chart and verify it before reconciliation |
R-GOV-01 — Lifecycle authority contradiction | 33 Proposed Features have extensive completed Task evidence, which can be mistaken for authorized architecture or accepted product scope | Scope and Architecture issue exact item decisions or conservatively reconcile unauthorized work |
Board completion rule
The architecture becomes decision-ready only when each decision above has an exact disposition, owner, conditions, date, evidence, and affected artifacts; every blocking risk has closure or explicit residual-risk acceptance; C4, ADR, requirement, runtime and deployment records agree; and release evidence binds to one immutable tuple. A green build, packet-completeness PASS, implementation, deployment health, or silence is not a substitute for those decisions.