Scira
Architecture

Agent loop

How the research agent processes a question — from first search to final report.

The research agent follows a fixed five-phase loop. Each phase is driven by the model calling tools; the harness records events to run.log.jsonl as it goes.

Phases

0 — Bootstrap (mandatory)

Before doing any work, the agent reads relevant research skills with readSkill. Skills are plain-text tactics baked into the binary that tell the agent how to structure searches, evaluate sources, record claims, and write reports. Skipping this is a bug — the skill names are injected into the system prompt as a catalog, and the agent is instructed to pull them before starting.

Available skills:

NameWhat it covers
research-planHow to structure discovery, deep-dive, and synthesis phases
search-strategyQuery formulation, parallel fetch, iteration on failures
source-qualityPrimary vs. secondary sources, bias indicators, corroboration
claim-verificationVerification status taxonomy, cross-checking methods
report-structureSection layout, citation format, how to treat unverified claims
browser-researchWhen and how to use Chrome DevTools MCP for live page evidence
tool-efficiencyToken and turn budgeting, when to escalate vs. answer directly

1 — Plan

The agent writes plan.md with research questions, approach, and phase checkboxes. In code agent mode it also uses todo to break the task into trackable steps.

2 — Gather

webSearch runs 3–10 parallel queries in a single call — the tool accepts an array of query strings and fires them concurrently. Results come back as a JSON array of { query, results: [{ title, url, snippet, publishedDate }] }.

For the best sources, the agent calls readUrl to fetch the full page. Each call saves a snapshot to snapshots/<slug>.md inside the run directory and returns the snapshot path, which the agent records in sources.jsonl.

In code agent mode, grepWorkspace and listWorkspaceDir replace web searches for understanding the codebase.

3 — Extract claims

After reading each source the agent calls createClaim with:

{ id: "claim_001", text: "...", confidence: "high" | "medium" | "low",
  sourceIds: ["src_01"], reason: "..." }

Claims are appended to claims.jsonl immediately. The agent does not batch — recording happens right after each source is read so nothing gets lost if the loop is interrupted.

4 — Verify

Once all claims are recorded, the agent iterates through them with verifyClaim:

{ id: "claim_001", status: "verified" | "weak" | "contradicted" | "needs_review",
  reason: "..." }

claims.jsonl is rewritten in-place. Verification status is recorded in the run log and used by scira verify <run-id>.

5 — Synthesize

The agent writes report.md following the report-structure skill — typically: executive summary, findings with inline citations, open questions, source list. On the research agent, a report.updated event is fired and the TUI shows the report in the feed. The loop ends on the next turn without a tool call.

One-shot escalation

The one-shot agent has a lighter toolset and no harness mandate. It handles most single-turn questions directly. When the question is genuinely research-grade, it calls requestFullResearch:

{ reason: "Topic requires multi-source verification and a written report." }

The TUI intercepts this, the research agent takes over with a fresh harness, and the full five-phase loop runs.

Temporal context

Both agents receive today is <weekday, month day, year> in the system prompt. All searches include the current year in query suggestions. The agents are instructed to treat model memory as unreliable for date-sensitive facts and to verify against sources.

Event log

Every tool call writes to run.log.jsonl:

{"type":"tool.search","data":{"queries":["..."],"resultCount":12},"ts":"..."}
{"type":"tool.open_url","data":{"url":"...","title":"...","snapshot":"snapshots/foo.md"},"ts":"..."}
{"type":"claim.created","data":{"id":"claim_001","confidence":"high","sourceIds":["src_01"]},"ts":"..."}
{"type":"claim.verified","data":{"id":"claim_001","status":"verified"},"ts":"..."}
{"type":"report.updated","data":{"chars":4200},"ts":"..."}

scira show <run-id> reads this log to render the run timeline.

On this page