-
Notifications
You must be signed in to change notification settings - Fork 0
docs: add public architecture documentation #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
maxw06
wants to merge
1
commit into
main
Choose a base branch
from
docs/public-architecture
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # AGENTS | ||
|
|
||
| - Never add credentials, emails, internal URLs, or infra IDs. | ||
| - Docs must stay public-safe; architecture only. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Zosavi Public Docs | ||
|
|
||
| Public-safe engineering notes for Zosavi, a privacy-focused scan pipeline that pairs a mobile client with an event-driven backend and LLM-assisted analysis. These docs share architecture thinking only and intentionally omit operational runbooks or credentials. | ||
|
|
||
| ## Contents | ||
|
|
||
| - [Architecture overview](docs/architecture/zosavi-architecture-overview.md) | ||
| - [Architecture decisions](docs/adr/) | ||
|
|
||
| Public-safe note: No source code, secrets, or deployment details live here; this repo only captures high-level architecture rationale. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # ADR 0001: Event-driven scan pipeline | ||
|
|
||
| Status: Accepted | ||
|
|
||
| Context: Scans need to be processed asynchronously so uploads stay fast and workloads can burst without blocking the client. | ||
|
|
||
| Decision: Use an event/queue-driven pipeline where edge handlers enqueue work for dedicated scan processors. | ||
|
|
||
| Consequences: Adds a queueing dependency and retry semantics, but keeps client latency low and lets processors scale independently. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # ADR 0002: Guardrail-first LLM orchestration | ||
|
|
||
| Status: Accepted | ||
|
|
||
| Context: Model calls must stay bounded and auditable to prevent untrusted outputs from reaching clients. | ||
|
|
||
| Decision: Run all LLM work inside a lightweight orchestrator that enforces tool allowlists, step limits, schema validation, and deterministic decoding where needed. | ||
|
|
||
| Consequences: Orchestrator logic becomes a critical path component, but it centralizes safety policy and observability. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # ADR 0003: Structured results contract | ||
|
|
||
| Status: Accepted | ||
|
|
||
| Context: Downstream features need predictable outputs from scan analysis and should not depend on free-form model text. | ||
|
|
||
| Decision: Require scan processors to emit structured results that conform to a versioned schema, with validation and safe fallback states on errors. | ||
|
|
||
| Consequences: Increases upfront schema work, but simplifies client integrations, migrations, and incident triage. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| # Zosavi Architecture Overview | ||
|
|
||
| > Public-safe overview; intentionally omits sensitive implementation details, secrets, and vendor-specific endpoints. | ||
|
|
||
| ## High-level system architecture | ||
|
|
||
| ```mermaid | ||
| flowchart LR | ||
| subgraph Client | ||
| mobile[Mobile app] | ||
| end | ||
| subgraph Edge | ||
| api[Edge API / lightweight functions] | ||
| notifications[Notification service] | ||
| end | ||
| subgraph Core | ||
| firestore[Document DB] | ||
| storage[Object storage] | ||
| queue[Task / event queue] | ||
| worker[Scan processors] | ||
| telemetry[Observability + tracing] | ||
| end | ||
| subgraph Intelligence | ||
| orchestrator["LLM orchestrator / agent runtime"] | ||
| tools["Tool adapters: retrieval, scoring"] | ||
| provider["External LLM provider"] | ||
| end | ||
|
|
||
| mobile -->|Uploads assets + metadata| api | ||
| api --> storage | ||
| api --> firestore | ||
| firestore --> queue | ||
| queue --> worker | ||
| worker --> orchestrator | ||
| orchestrator --> tools | ||
| orchestrator --> provider | ||
| provider --> orchestrator | ||
| orchestrator --> worker | ||
| worker --> firestore | ||
| worker --> telemetry | ||
| worker --> notifications | ||
| notifications --> mobile | ||
| ``` | ||
|
|
||
| ## Data flow | ||
|
|
||
| ```mermaid | ||
| sequenceDiagram | ||
| participant User | ||
| participant Mobile as Mobile app | ||
| participant Edge as Edge API | ||
| participant Store as Object storage | ||
| participant DB as Document DB | ||
| participant Queue as Task queue | ||
| participant Worker as Scan processor | ||
| participant Orchestrator as LLM orchestrator | ||
| participant LLM as LLM provider | ||
| participant Notify as Notification svc | ||
|
|
||
| User->>Mobile: Capture scan (image/text) + submit | ||
| Mobile->>Store: Upload redacted asset | ||
| Mobile->>Edge: Create scan session (status=pending, asset ref) | ||
| Edge->>DB: Persist session record | ||
| DB-->>Queue: Event triggers queued work | ||
| Queue-->>Worker: Deliver job with session pointer | ||
| Worker->>Store: Fetch asset (signed URL / scoped token) | ||
| Worker->>Orchestrator: Provide normalized payload + context | ||
| Orchestrator->>LLM: Call model with guarded prompt/tool spec | ||
| LLM-->>Orchestrator: Structured analysis result | ||
| Orchestrator-->>Worker: Final output + safety verdicts | ||
| Worker->>DB: Update session (status=completed|failed, result) | ||
| Worker->>Notify: Send push/email hook | ||
| Notify-->>Mobile: Deliver user-facing notification | ||
| Mobile->>DB: Refresh session via listener/poll | ||
| ``` | ||
|
|
||
| ### LLM orchestration | ||
|
|
||
| - **Agent loop**: Workers hand off to a lightweight orchestrator that runs a bounded agent loop (max tool hops, latency budget). Each step enriches context with intermediate results to avoid repeated API calls. | ||
| - **Tool calls**: The orchestrator supports tool plugins (e.g., retrieval, scoring, formatting). Tools declare schemas and side effects; calls are logged with trace IDs for audit. | ||
| - **Guardrails**: Pre-flight validators redact obvious PII, clamp token budgets, and require allowlisted tools. Post-processing enforces JSON schema validation, truncates oversized fields, and downgrades the session to a safe failure when validation fails—never exposing raw model text to clients. | ||
| - **Safety tiers**: Different routes can select conservative model tiers and enable deterministic decoding for user-visible summaries, while background scoring can opt into higher-variance settings. | ||
|
|
||
| ### State management | ||
|
|
||
| - **Entities**: Scan session (id, status, asset pointer, structured result, retry count), user profile (tier, notification tokens), and observability spans (trace IDs, timing). | ||
| - **Persistence vs. ephemeral**: Durable state lives in the document database; large binaries stay in object storage; transient orchestration state (agent scratchpad, tool responses) remains in-memory per job. | ||
| - **Idempotency**: Session records include status + revision fields; workers short-circuit when a job replays and the session is already terminal. Storage uploads use content hashes to avoid duplicate processing. | ||
| - **Retries**: Queue-level retries are backoff-controlled; model errors trigger bounded retries with circuit breakers. Failed sessions mark a retry hint so clients can re-submit safely. | ||
|
|
||
| ## Trade-offs | ||
|
|
||
| - **Serverless vs. long-running workers**: Functions/queues keep ops light and scale to bursts but add cold-start latency; dedicated workers would reduce latency but increase ops overhead. | ||
| - **Client uploads first**: Uploading assets directly to storage minimizes edge load but requires strict validation and signed URLs to prevent abuse. | ||
| - **Central orchestrator**: A single orchestration layer simplifies policy and telemetry, yet concentrates failure domains; mitigation is heavy tracing and feature-flagged fallbacks. | ||
| - **LLM dependency**: Offloading to an external LLM accelerates iteration but adds cost and latency variance; caching + schema validation reduce waste and regressions. | ||
|
|
||
| ## Scaling considerations | ||
|
|
||
| - Horizontal scale via the task queue; concurrency tuned per region to balance throughput and model quota limits. | ||
| - Use partition-friendly keys in the document store to avoid hot shards; fan-out writes for large batches. | ||
| - Streaming uploads + chunked downloads to keep memory bounded for large assets. | ||
| - Backpressure signals (queue depth, latency SLOs) feed autoscaling policies and can trigger graceful degradation modes (reduced tool set, lower-fidelity summaries). | ||
| - Warm paths (pre-provisioned workers, connection pooling) reduce cold-start impact on peak hours. | ||
|
|
||
| ## Lessons learned | ||
|
|
||
| - Keep the session record authoritative and immutable except for status/result fields; everything else is derived to simplify retries. | ||
| - Validate and normalize all payloads before they hit the LLM to reduce downstream cost and noisy failures. | ||
| - Observability is a feature: trace IDs through client, queue, orchestrator, and model calls make incident triage far faster. | ||
| - Explicit safety fallbacks (safe failure states, redaction, conservative decoding) prevent the rare LLM glitch from leaking to end users. | ||
| - Small, deterministic schemas for model outputs are easier to evolve and migrate than free-form text blobs. | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The high-level diagram currently shows uploads flowing from
Mobile app -> Edge API -> Object storage, but the Data flow and Trade-offs sections describe direct client uploads to object storage (Mobile->>Storeand “Client uploads first”). This internal contradiction makes the documented architecture ambiguous for readers trying to understand trust boundaries and validation responsibilities, so one of these paths should be updated to match the intended design.Useful? React with 👍 / 👎.