> ## Documentation Index
> Fetch the complete documentation index at: https://docs.myrqen.cc/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture

> The pieces, where each one runs, and the boundaries that decide what may cross between them.

Myrqen is local-first. The scan, the findings, the secrets, and the reports live on your
machine. The hosted service exists to make a report visible to other people, and it only
ever receives what the sync contract explicitly allows.

## The pieces

| Path                                                                    | What runs there                                                                                                                 |
| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `apps/cli`                                                              | The local control plane: session lifecycle, policy gates, finding intake, report rendering, sync, device link, signed updates.  |
| `apps/web`                                                              | Next.js dashboard, JSON API under `/api/v1`, the share viewer at `/s/<slug>`, and platform admin.                               |
| `apps/worker`                                                           | Retention deletion, quota reconciliation, and operational pruning.                                                              |
| `packages/scan`                                                         | Static analysis: intra-procedural taint tracking over the TypeScript AST, plus configuration, credential, and dependency rules. |
| `packages/policy`                                                       | Authorization scope, prohibited actions, redaction, quota windows, effort profiles, deduplication, share projections.           |
| `packages/report`                                                       | The canonical report builder and the HTML, Markdown, SARIF, and fix-prompt renderers.                                           |
| `packages/contracts`                                                    | Types plus runtime validators generated from `schemas/*.json`.                                                                  |
| `packages/skill`                                                        | The portable Agent Skill — the behavioural source of truth.                                                                     |
| `packages/db` · `auth` · `storage` · `events`                           | Drizzle schema and generated SQL migrations, passwords and sessions, encrypted object storage, live-progress fanout.            |
| `packages/analytics` · `entitlements` · `updater` · `billing` · `brand` | Allowlisted event taxonomy, plan limits, signed updates, Polar integration, brand identifiers.                                  |

## Who supplies the reasoning

The host agent does. Myrqen never holds a model provider credential and never asks for
one — [ADR 001](https://github.com/stijnswapped/Myrqen/blob/main/docs/adr/001-host-agent-provides-llm.md)
records that decision. What Myrqen supplies is everything around the reasoning:

* the methodology and the phase structure,
* the authorization and safety gates the agent must pass through,
* the finding contract, identity, deduplication, and redaction,
* the report, in four formats,
* and, if asked, the cloud collaboration layer.

## The two halves of a scan

<Steps>
  <Step title="Myrqen's static pass">
    `session start` parses the project and follows attacker-controlled data through a
    function — including the shapes real code uses: destructured request reads, values
    accumulated into an array and joined, aliases, type assertions — and records where
    that data reaches a sink with nothing in between. It runs whether or not an agent is
    involved, which is what makes the engine measurable against a
    [corpus](/guides/benchmark).
  </Step>

  <Step title="The agent's dynamic validation">
    Static reading cannot observe a response. Every static candidate is therefore a
    claim, and the agent settles it against the running application:
    `finding verify` raises it to `verified`, `finding refute` records that it could not
    be reproduced and keeps the finding labelled. An unsettled candidate stays
    `needs_review` and the report says so.
  </Step>
</Steps>

## Trust boundaries

These are the lines the implementation is built around. The full set is in
[`docs/02-architecture/TRUST-BOUNDARIES.md`](https://github.com/stijnswapped/Myrqen/blob/main/docs/02-architecture/TRUST-BOUNDARIES.md).

<AccordionGroup>
  <Accordion title="Local source and secrets never leave raw">
    Repository files, `.env` values, cookies, tokens, test credentials, raw traffic, and
    local database contents stay local. What may reach the cloud is report prose,
    explicitly selected evidence, redacted secret *references* (a label, a kind, and a
    local HMAC fingerprint — never the value), and the metadata the sync contract names.
    The full repository is never uploaded; `policy.uploadFullRepository` is `false` in
    every session context.
  </Accordion>

  <Accordion title="Assessed content is data, not instructions">
    Application pages, API responses, source comments, issue text, dependency metadata,
    and logs are untrusted. They cannot grant scope, authorize a target, change policy,
    or redirect a tool. An attempt is recorded as a finding, and the scan continues under
    the original policy.
  </Accordion>

  <Accordion title="Device credential and browser session are separate">
    The CLI holds a revocable device credential scoped to API operations. The browser
    holds a session cookie. The device-link approval URL carries an opaque request id and
    never a durable bearer token.
  </Accordion>

  <Accordion title="Report content and product analytics are separate streams">
    Analytics events are an allowlisted schema with no generic properties path. Report
    text is never copied into an analytics row to enrich it.
  </Accordion>

  <Accordion title="A viewer only ever sees a server-side projection">
    Share filtering happens on the server. Nothing a viewer may not see is present in
    their HTML, their JSON, or their export. Client-side visibility is never the security
    boundary.
  </Accordion>

  <Accordion title="A platform admin has metadata, not content">
    Administrators see operational metadata by role. Reaching a customer's report body
    requires a separate, expiring **support grant** with a written reason, a password
    re-entry, and an audit trail — and every use is counted.
  </Accordion>

  <Accordion title="Update metadata is untrusted until verified">
    Clients verify an ed25519 signature against a pinned public key, check the artifact
    digest and size, and refuse downgrades, stale manifests, and revoked versions before
    anything is written to disk. A compromised API response cannot become code
    execution.
  </Accordion>
</AccordionGroup>

## Data at rest in the hosted service

Report bodies are encrypted with `REPORT_ENCRYPTION_KEY` before they reach object
storage, so the store never holds plaintext. `REPORT_ENCRYPTION_KEY_PREVIOUS` accepts
retired keys for reads only, which is what makes rotation possible without orphaning
every stored report.

Live progress is fanned out over PostgreSQL `LISTEN`/`NOTIFY` by default, which works
across replicas; a single-process `memory` driver exists for development.

## Related

<CardGroup cols={2}>
  <Card title="Scan lifecycle" icon="timeline" href="/concepts/scan-lifecycle">
    The eight phases and the states a scan moves through.
  </Card>

  <Card title="Authorization and safety" icon="shield-check" href="/concepts/authorization-and-safety">
    Scope classes, the prohibited list, and injection quarantine.
  </Card>
</CardGroup>
