Isolation by default
Every agent runs in its own git worktree AND its own Docker container with default-deny network egress.
How Frontal isolates, encrypts, and audits every agent action.
Every architectural decision in DECISIONS.md traces back to one of these.
Every agent runs in its own git worktree AND its own Docker container with default-deny network egress.
Provider keys live only in the gateway. Secrets vault uses Fernet/AES. Never appear in prompts, logs, or the event log.
HMAC-SHA256 chained event log. Append-only. Tamper-evident. The single source of truth.
Sandbox containers start with --network none (empty allowlist) or on an internal Docker network with an egress proxy sidecar (non-empty allowlist). The proxy matches hostnames only — never TLS interception. Containers cannot reach the host filesystem except via the mounted worktree volume.
Keys and credentials have exactly one path in — and never leak sideways.
Secrets are resolved from the vault into the launcher environment at exec time ONLY — never written to .mcp.json, logs, the event log, memory, or Pi context.
Loaded from the FRONTAL_MASTER_KEY environment variable, with the OS keychain as a fallback. Never committed, never logged.
Held in os.environ and scrubbed before subprocess launch. See backend/runner.py _env.
The audit chain records THAT a secret was used (by name) — never its value. You can prove a credential was invoked without exposing it.
The engine talks to one host: its own local gateway. (D-002)
Pi's models.json points exclusively at the local gateway. No provider key ever reaches the engine subprocess.
20-call sliding window, 50% error threshold, timed cooldown, half-open probe. One provider going down never takes the pipeline with it.
GLM → MiniMax → OpenCode, configurable in backend/config/model_routing.json. Virtual tiers frontal/heavy|standard|utility|asr.
Every model call is metered in one place — feeding budgets (80% warn / 100% pause) and billing. No side-channels, no untracked tokens.
The event log is the source of truth. Everything else is rebuildable. (D-004)
Append-only. Each event's HMAC incorporates the previous event's hash. Tampering breaks the chain at the first altered record.
Per-project: .frontal/events/*.jsonl. Orchestrator-wide: .sdd/audit/YYYY-MM-DD.jsonl.
verify_chain() runs before any memory rebuild. Reconciler.run() on startup detects orphaned containers, stale worktrees, and interrupted tasks.
The memory graph is a rebuildable view of the event log. Losing it never loses memory — replay the chain and it comes back.
Parallel where safe, serialized where it isn't. No silent force-pushes.
Each task gets its own git worktree under .frontal/worktrees/. No two agents share a working directory.
Tasks with overlapping file scopes serialize. Disjoint scopes run in parallel. The trunk lock serializes all merges to main / develop.
On conflict: one automated rebase-repair attempt. If it fails: Needs-Attention — never a silent force-push.
Found something? Tell us. We move fast and we credit honestly.
Email [email protected]. PGP encouraged.
Mock address pre-launch — replace before going live.
No acknowledged reports yet.
This section is honestly empty. The first name here will be the first.
No bug bounty program yet.
We're pre-launch. We'll launch a formal program once we're stable. Until then: honest credit and our gratitude.
What we support, what we're working toward, and what we don't do.
Found a vulnerability?
Email [email protected]. We acknowledge within 24 hours and coordinate disclosure with you.
Report a vulnerability