Skip to content

Architecture

How Area O1 turns your work into an evidence file, where it keeps everything, and how the code is laid out.

What it is

Area O1 is a local-first command center for building an extraordinary-ability immigration case (O-1A now, EB-1A too, more through community profiles). Underneath, it's evidence-grounded memory for long-running AI agents, applied first to O-1A and EB-1A: every fact it holds quotes its source, and you decide what counts.

Provenance follows the W3C PROV model. Area O1 makes no performance claims beyond what its evaluation harness measures, and that harness is still to come (see the roadmap).

Your case lives in a private workspace folder on your computer, its own git repo. The app repository holds only the app.

How it works

  1. Connectors (areao1/sources/) discover your repos, models, datasets, papers and pages, snapshot their metrics into data/metrics.csv, and propose evidence candidates.
  2. Every raw response becomes an observation in memory/, and every fact drawn from it becomes a claim that quotes its source verbatim, with offsets (for example "stargazers_count": 1840 from api.github.com/repos/…). Claims are append-only: a new value supersedes the old one and nothing is overwritten, so you can ask what was known on any date.
  3. Candidates land in the Inbox, where you can expand the exact claims behind each one. Nothing becomes evidence until you accept it. Accepting approves those claims, writes a capture file to evidence/<criterion>/<criterion>_<yyyy-mm-dd>_<slug>.md, and logs it in data/exhibits.json. Approval records your decision; it doesn't certify legal sufficiency.
  4. The criteria engine (areao1/criteria/) scores exhibits against a YAML profile (profiles/o1a.yaml, profiles/eb1a.yaml): each criterion is banked, building, gap or dropped. An invitation is not a completion: only completed, published or granted evidence counts, and self-reported items never count. Switching profiles re-scores the same evidence.
  5. DASHBOARD.md and the web dashboard show where you stand.

Chat-history imports follow the same path. Area O1 reads only your messages (never the assistant's) and suggests deadlines, pipeline items and letter writers. Those suggestions are self-reported: they keep your trackers current, but they can never count toward a criterion.

See How it works for each step in detail.

Plain files

All workspace data is plain JSON, JSONL, CSV and Markdown, each with a JSON Schema (generated from the models into areao1/core/schemas/, and copied into each workspace under .areao1/schemas/). You, the dashboard and any agent read the same files. areao1 validate checks them.

Every change a page or the agent makes goes through one service layer (areao1/service.py), which records it in data/changes.jsonl so it can be reviewed or undone.

The core knows nothing about immigration

The core (areao1/core/) holds the domain-agnostic models, the workspace store and the claim memory. It never imports from the immigration layer or mentions a specific profile, and a test enforces that. Profiles and scoring live in a separate layer (areao1/criteria/), so other domains could reuse the core.

Profiles are YAML files in profiles/. Each criterion has an id, the regulation it summarizes, its evidence types, its strength signals and a simple bank rule (min_exhibits, min_signals). A workspace can add or override profiles with its own profiles/*.yaml. See Contributing.

The workspace folder

A new workspace (from the first run or areao1 init) looks like this. Some folders appear only once you use the feature.

~/AreaO1/
├── areao1.yaml            settings (no secrets)
├── DASHBOARD.md           where you stand, regenerated by `areao1 run dashboard`
├── AGENTS.md              instructions for Codex and other agents
├── .claude/skills/areao1/ the Claude Code skill pack
├── .gitignore             keeps caches and .env out of git
├── data/
│   ├── person.json        you
│   ├── sources.json       connected sources (keychain entry names only)
│   ├── inbox.json         candidates waiting for review
│   ├── exhibits.json      accepted evidence
│   ├── criteria.json      the scoreboard
│   ├── metrics.csv        dated metrics history
│   ├── pipeline.json      opportunities in progress
│   ├── deadlines.json     deadlines
│   ├── letters.json       letter writers
│   ├── opportunities.json
│   ├── calendar.ics       deadlines and follow-ups, for your calendar app
│   ├── changes.jsonl      every change, for review and undo (once you make one)
│   └── contacts.json, threads.json, outreach.json, mail.json   (once you use Contacts and Gmail)
├── evidence/
│   └── <criterion>/<criterion>_<yyyy-mm-dd>_<slug>.<ext>
├── memory/
│   ├── observations.jsonl raw responses
│   ├── claims.jsonl       facts, each quoting its source
│   ├── entities.jsonl, edges.jsonl, decisions.jsonl
│   └── sources/           snapshots of raw sources
├── drafts/letters/        letter drafts
├── agent/                 conversations/, runs/ (once you use the agent)
├── vault/                 the vault's log and findings (once it runs)
└── .areao1/
    ├── schemas/           JSON Schemas for every file
    └── cache/             local caches and the vault index (gitignored)

The evidence/ folder has one subfolder per criterion id (awards, membership, press, judging, original_contributions, scholarly_articles, critical_role, high_salary, commercial_success, display). The O-1A and EB-1A profiles share these ids, so evidence carries across.

The package

Path What's in it
areao1/cli.py The areao1 command
areao1/core/ Domain-agnostic models, the workspace store, claim memory, secrets, JSON Schemas
areao1/criteria/ The domain layer: profiles, scoring, the case, contacts, letters, the constellation, DASHBOARD.md
areao1/sources/ Connectors: GitHub, Hugging Face, Semantic Scholar, OpenAlex, arXiv, ORCID, websites, chat exports
areao1/google/ Gmail with an app password: mail, the Mail view, .eml import, outreach, opportunity checks
areao1/agent/ The agent layer: tools, runner, prompts, guardrails, redaction, model routing, missions
areao1/engine/ The engine behind the agent: the OpenAI Responses API
areao1/vault/ The knowledge vault: official sources, snapshots, search, change signals, the rule check
areao1/jobs/ Scheduled jobs and the scheduler
areao1/notify/ Notifications: desktop, email, Slack, Discord, ntfy
areao1/mcp/ The read-only MCP server
areao1/onboarding/ Onboarding from your LinkedIn PDF
areao1/server/ The FastAPI server and the built web UI
areao1/service.py The service layer every write goes through
areao1/extension/ The capture browser extension
areao1/templates/workspace/ What a new workspace starts with
profiles/ Criteria profiles (YAML)
vault/sources.yaml The official sources the vault watches
web/ The dashboard's source (React, built with Vite)

Design records

Significant decisions are recorded as ADRs in docs/adr. An accepted ADR is never rewritten; a later one supersedes it.

ADR Decision
0001 Files are the source of truth
0002 An earlier naming decision, superseded by 0010
0003 Product first, research second
0004 Append-only claim memory with verbatim excerpts
0005 Agent layer: engine adapters, grounded tools, the service layer, budgets
0006 Knowledge vault: tiered sources, content-addressed snapshots, local hybrid search
0007 Design system
0008 No demo data, a conversational onboarding, and agent guardrails
0009 Chat can do what the pages do; three model tiers; long chats
0010 The name is Area O1
0011 The vault without babysitting
0012 The constellation memory map
0013 The front door: one line to a running onboarding
0014 Google, contacts and outreach
0015 OpenAI is the only engine
0016 The daily opportunity job

The full plan is in SPEC.md.