car_server_core/coder/mod.rs
1//! Built-in coding agent ("CAR Coder").
2//!
3//! The user states an intent; the coder turns it into a **verifiable outcome
4//! contract** (shell commands that must pass), gets it confirmed, then works in
5//! a throwaway **git worktree** until every check is green — natively (CAR
6//! inference + policy-gated tools) or by delegating to an installed external
7//! CLI (Claude Code, Codex, Gemini), with CAR re-running the contract either
8//! way. Results are published as a `car/coder/<id>` branch in the user's repo;
9//! the user's checkout is never touched.
10//!
11//! ## Module map
12//!
13//! - [`contract`] — `OutcomeContract` derivation (inference, repair loop) and
14//! evaluation (runs checks through the policy-gated shell tool)
15//! - [`session`] — session state machine, event stream (`CoderEvent`), JSON
16//! snapshots under `~/.car/coder/`
17//! - [`shell_tool`] — `WorktreeExecutor`: file tools + a host `shell` tool,
18//! all rooted/clamped at the worktree and gated by the inspector chain
19//! - [`policy`] — the coder inspector set (no pushes, no privilege escalation,
20//! no writes outside the worktree, …)
21//! - [`native_loop`] — the plan→edit→verify→repair loop driving CAR inference
22//! - [`router`] — engine selection between the native loop and external CLIs
23//! - [`merge`] — squash-commit the worktree and deliver it: a local branch,
24//! a managed project's `main`, or (headless) an append-only push plus one
25//! reconciled pull request
26//! - [`discuss`] — repo-grounded, strictly READ-ONLY conversation that can be
27//! distilled into a run intent (`coder.discuss.*`); it never starts a session
28//! - [`fix_issues`] — files a dogfooding round's durable-fix proposals as
29//! - [`heal_config`] / [`heal_intake`] / [`heal_select`] / [`heal_claims`] /
30//! [`heal_gate`] / [`heal_tick`] / [`heal_service`] — the self-healing loop:
31//! read a repository's open issues and pull requests, pick one, hand it to a
32//! coder session, and open a pull request only if the outcome contract AND an
33//! independent multi-model panel both pass. Never closes an issue; a human
34//! does. See `docs/proposals/self-healing-issue-loop.md`.
35//! issues on the (public) releases tracker: the *reporting* half of
36//! self-correction
37//! - [`provenance`] — trust tiers for tracker text: every issue resolves to
38//! `runtime` / `maintainer` / `public` from its author account before its
39//! text is readable at all, and a `public` body can neither seed a session
40//! nor source an outcome contract. Live today for deduplication; the session
41//! and contract gates are the types the future tracker consumer must use
42//!
43//! ## Security boundary (read this before extending)
44//!
45//! The shell tool executes on the **host** with the daemon's privileges and
46//! (deliberately) the real toolchain + network. The inspector chain blocks the
47//! known-dangerous verbs (git push, sudo, destructive ops outside the
48//! worktree, credential reads) plus every route that would *publish* the work
49//! around the merge gate — the forge CLIs (`gh`, `glab`, `hub`) are cut to a
50//! read-only allowlist and the registry publish subcommands (`npm publish`,
51//! `cargo publish`, `docker push`) are denied — and the executor pins the
52//! working directory to the worktree. But this is policy hardening, **not a
53//! sandbox**: a model determined to misbehave can, e.g., pipe curl to sh
54//! inside the worktree, or reach `gh` through a wrapper script.
55//! The hard stops are the contract confirmation gate before any work starts
56//! and the merge approval gate before anything reaches the user's repo.
57//!
58//! Anything that reads a tracker adds a second boundary: the report target is
59//! **public**, so an issue body is attacker-controlled text. [`provenance`]
60//! resolves every issue to a trust tier from its author account — never from
61//! anything in the body — and its types are the reason a caller cannot read
62//! tracker text without one.
63
64pub mod ab;
65pub mod ab_fixer;
66pub mod ab_learnings;
67pub mod ab_loop;
68#[cfg(test)]
69mod bench;
70pub mod budget;
71pub mod config;
72pub mod contract;
73pub mod declarative;
74pub mod discuss;
75pub mod external_loop;
76pub mod fix_issues;
77pub mod foreman_loop;
78pub mod heal_claims;
79pub mod heal_config;
80/// End-to-end test of the healing loop over a real coder session. In-crate
81/// rather than under `tests/` because `SessionSeed::from_trusted` is
82/// `pub(in crate::coder)` on purpose; see the module's own docs.
83#[cfg(test)]
84mod heal_e2e;
85pub mod heal_gate;
86pub mod heal_intake;
87pub mod heal_live;
88pub mod heal_review;
89pub mod heal_runner;
90pub mod heal_select;
91pub mod heal_service;
92pub mod heal_tick;
93/// Live trials — real GitHub permissions, real models, real delivery. All
94/// `#[ignore]`d: they need credentials, a network, and real spend.
95#[cfg(test)]
96mod heal_trial;
97pub mod merge;
98pub mod native_loop;
99pub mod no_change;
100pub mod overlap;
101pub mod policy;
102pub mod project;
103pub mod project_context;
104pub mod provenance;
105pub mod router;
106pub mod rpc;
107pub mod session;
108pub mod shell_tool;
109pub mod skill_memory;
110#[cfg(test)]
111pub(crate) mod test_cmds;
112
113pub use ab::{
114 attribute_round, run_ab_suite, AbArmRunner, AbCell, AbReport, AbTask, ArmEngine, ArmOutcome,
115 ArmSpec, PairedStats, RoundAttribution,
116};
117pub use ab_fixer::{mutations_from_interventions, EvolutionAbFixer, HarnessApply};
118pub use ab_learnings::{
119 render_proposals, synthesize_proposals, Confidence, DurableFixProposal, ProposalKind,
120};
121pub use ab_loop::{
122 run_improvement_loop, AbFixer, FixResult, ImprovementRun, LoopConfig, LoopStop, RoundRecord,
123};
124pub use config::{config_path, CoderConfig, DEFAULT_MAX_ITERATIONS};
125pub use contract::{evaluate_contract, CheckResult, ContractCheck, OutcomeContract};
126pub use discuss::{DiscussEvent, DiscussEventKind, DiscussionEntry, DiscussionMap};
127pub use external_loop::{run_external_loop, CliInvoker, ExternalLoopConfig, LiveInvoker};
128pub use fix_issues::{
129 clears_reporting_bar, parse_signature_marker, proposal_signature, render_issue_body,
130 render_report, report_proposals, signature_marker, GhIssues, IssueApi, ReportOutcome,
131 ReportRecord, DEFAULT_REPORT_REPO,
132};
133pub use merge::{
134 commit_to_main, deliver_pr, deliver_pr_with, publish_branch, publish_branch_headless,
135 validate_branch_name, AzureDevOpsCli, CiCheck, CiState, CiSummary, DeliveryFailure,
136 ForgeClient, ForgeError, ForgeKind, GhCli, GhError, GitHubApi, PrAction, PrDelivery,
137 PrDeliveryOutcome, PrRecord, PrState, FORGE_OVERRIDE_ENV,
138};
139pub use native_loop::{
140 model_tool_catalog, run_native_loop, LoopFailure, LoopOutcome, NativeLoopConfig,
141};
142pub use no_change::{
143 baseline_completed, evaluate_nomination, head_commit, worktree_fingerprint,
144 worktree_is_pristine, MutationLedger, NominationContext, NominationRefusal, NominationVerdict,
145 MAX_FINDING_TEXT,
146};
147pub use project::{list_projects, resolve_or_create_project, slugify, CoderProject, ProjectKind};
148pub use project_context::{
149 agent_instructions, dot_car_knowledge, project_context, MAX_INSTRUCTIONS_BYTES,
150 MAX_KNOWLEDGE_BYTES,
151};
152pub use provenance::{
153 resolve_tier, ContractSource, GhPermissions, LocalSignatures, PermissionOracle,
154 ProvenanceRecord, ProvenanceRefusal, ProvenanceTier, RawIssue, RepoPermission, SessionSeed,
155 TieredIssue, UntrustedText, MAX_TIER_AGE,
156};
157pub use router::{
158 detect_ready_agents, resolve_engine, DetectedAgent, EngineChoice, ResolvedEngine,
159};
160pub use session::{
161 adopt_orphaned_sessions, default_state_dir, gc_sessions, needs_you_from, AdoptionOutcome,
162 CancelFlag, CoderEvent, CoderEventKind, CoderSession, CoderState, EventEmitter, EventSink,
163 NeedsYou, SessionRetention,
164};
165pub use shell_tool::WorktreeExecutor;
166pub use skill_memory::{FailureSignature, RepairMemory};