Corvid

June 10, 2026 · View on GitHub

Corvid is a general-purpose programming language built for AI-native software.

Python, TypeScript, Rust, Go, and JavaScript can call models through libraries. Corvid makes the AI parts visible to the compiler: agents, tools, prompts, approvals, grounding, budgets, confidence, model routing, streaming, replay, and verification are language constructs.

The goal is not to be a RAG DSL. The goal is a real language for CLIs, servers, data pipelines, automation, embedded hosts, and AI agents where the compiler understands the parts of the program that spend money, call models, cross approval boundaries, stream partial results, and act on a user's behalf.

effect transfer_money:
    cost: \$0.50
    trust: human_required
    reversible: false

tool issue_refund(id: String) -> Receipt dangerous uses transfer_money

@budget(\$1.00)
@trust(human_required)
agent refund(id: String) -> Receipt:
    approve IssueRefund(id)
    return issue_refund(id)

Remove the approve line and the program does not compile. Increase the composed cost above $1.00 and the program does not compile. Return Grounded<T> without retrieval provenance and the program does not compile. That is the point: AI safety is not an SDK convention; it is part of the language.

Quickstart

Install (Windows PowerShell — macOS / Linux below):

curl -fsSL https://raw.githubusercontent.com/Micrurus-Ai/Corvid-lang/main/install/install.sh | sh

First program:

corvid new hello
cd hello
corvid run

Then explore:

For the full install options (Windows PowerShell, custom paths, env overrides, cargo install from source, planned package- manager paths), see Install below.

Contents

Verifiable Launch Surface

Corvid's strongest production claim is not prose; it is a signed cdylib workflow that emits externally checkable artifacts:

cargo run -q -p corvid-cli -- build app.cor --target=cdylib --sign=key.hex
cargo run -q -p corvid-cli -- claim --explain target/release/libapp.so --key pub.hex --source app.cor
cargo run -q -p corvid-abi-verify -- --source app.cor target/release/libapp.so
cargo run -q -p corvid-cli -- receipt verify-abi target/release/libapp.so --key pub.hex

Those commands are the public claim boundary:

  • corvid build --sign refuses to sign when source-declared contracts are not covered by registered, non-out_of_scope guarantee ids.
  • The cdylib embeds CORVID_ABI_DESCRIPTOR and, when signed, CORVID_ABI_ATTESTATION.
  • corvid claim --explain prints the descriptor-carried guarantee ids, signing-key fingerprint, and source/binary descriptor agreement when --key and --source are supplied.
  • corvid-abi-verify rebuilds the ABI descriptor from source through a separate process and byte-compares it with the cdylib's embedded CORVID_ABI_DESCRIPTOR (catches post-link tampering and build-cache drift; full second-implementation TCB shrinkage is post-v1.0).
  • corvid receipt verify-abi verifies the DSSE attestation and descriptor match.

For the exact trust boundary and non-goals, read docs/security/model.md. For the canonical guarantee table, read docs/reference/core-semantics.md.

Run the shipped invention tour:

cargo run -q -p corvid-cli -- tour --list
cargo run -q -p corvid-cli -- tour --topic approve-gates

The tour demos are compiler-checked in CI-style tests, so the catalog below is not detached marketing copy.

Invention Catalog

Each entry has a runnable tour topic, a spec link, a roadmap pointer, a test pointer, and an explicit non-scope. Corvid should be ambitious, but every claim below is tied to shipped source.

Safety At Compile Time

Approve Before Dangerous

Dangerous tools are not hidden behind decorators. The compiler requires an explicit approval boundary before irreversible actions.

This makes "approval happened before action" a type/effect property instead of a runtime best effort.

tool issue_refund(id: String) -> Receipt dangerous

agent refund(id: String) -> Receipt:
    approve IssueRefund(id)
    return issue_refund(id)

Spec: typing rules Tour: corvid tour --topic approve-gates Roadmap: Phase 20 safety wave Proof: approval checker tests Non-scope: Corvid proves the approval boundary exists; it does not decide whether approval is morally or legally correct.

Dimensional Effects

Effects are not flat tags. Cost, trust, reversibility, data, latency, confidence, and user-defined dimensions compose through their own algebra.

That lets the compiler reason about AI workflows as resource- and authority-carrying programs, not just function calls.

effect llm_call:
    cost: \$0.05
    trust: autonomous

prompt summarize(text: String) -> String uses llm_call:
    "Summarize {text}"

@budget(\$0.10)
@trust(autonomous)
agent summarize_twice(text: String) -> String:
    first = summarize(text)
    return summarize(first)

Spec: composition algebra Tour: corvid tour --topic dimensional-effects Roadmap: Phase 20a and Phase 20g Proof: effect composition tests Non-scope: Declared effects are compiler contracts; external providers still need operational verification.

Grounded Provenance

Grounded<T> means the value must flow from a retrieval source. The typechecker rejects grounded returns without a provenance chain.

At runtime the value carries its provenance, so later prompts and traces can inspect where the answer came from.

effect retrieval:
    data: grounded

tool fetch_doc(id: String) -> Grounded<String> uses retrieval

agent research(id: String) -> Grounded<String>:
    return fetch_doc(id)

Spec: grounding Tour: corvid tour --topic grounded-values Roadmap: Phase 20b Proof: grounded effect tests Non-scope: Grounding proves source linkage, not that the source itself is true.

Strict Citation Contracts

A prompt can name the grounded context it must cite. The compiler proves the cited parameter is grounded, and runtime checks the model response.

That turns "please cite your sources" from prompt text into a checked contract.

prompt answer(ctx: Grounded<String>) -> Grounded<String>:
    cites ctx strictly
    "Answer from {ctx}"

Spec: grounding and citation contracts Tour: corvid tour --topic strict-citations Roadmap: Phase 20b cites ctx strictly Proof: VM citation tests Non-scope: Citation checks textual evidence, not the truth of the cited document.

Provenance Propagation + @grounded_pure

Grounded values stay grounded as they flow through ordinary code. Add a Grounded<String> to a plain String, pass it as a call argument, return it through a branch — the wrapper carries through and the runtime delivers what the type promises.

Mark an agent @grounded_pure and the compiler refuses to launder. Every silent Grounded<T> -> T coercion, every .unwrap_discarding_sources(), every call into an agent that isn't itself @grounded_pure — all rejected at compile time. The moat composes through the call graph the same way @deterministic does.

effect retrieval:
    data: grounded

prompt audit() -> String uses retrieval:
    "Audit"

# `+` lifts `String + Grounded<String>` to `Grounded<String>`
# via the contagion law; the wrapper rides through to return.
@grounded_pure
agent run() -> Grounded<String>:
    head = "Summary: "
    tail = audit()
    return head + tail

Spec: grounded propagation design Tour: corvid tour --topic provenance-propagation Roadmap: Provenance Propagation phase Proof: proof tests + corpus fixtures (grounded_pure_* + tests/corpus/combined_all.cor, tests/corpus/legacy_grounded_coercion.cor) Non-scope: @grounded_pure forbids laundering inside an agent's body; it does not validate that the cited source is truthful (citation contracts handle one layer; trust in the upstream retrieval is the operator's responsibility).

Compile-Time Budgets

@budget is a static constraint over composed declared cost. The compiler rejects workflows whose worst-case cost exceeds the bound.

Cost becomes part of the program contract instead of a surprise on the provider invoice.

effect cheap_call:
    cost: \$0.05

prompt classify(text: String) -> String uses cheap_call:
    "Classify {text}"

@budget(\$0.10)
agent bounded(text: String) -> String:
    first = classify(text)
    return classify(first)

Spec: cost budgets Tour: corvid tour --topic cost-budgets Roadmap: Phase 20d Proof: cost analysis tests Non-scope: Static budgets use declared costs; provider billing reconciliation is still an operational concern.

Confidence Gates

Confidence is a first-class dimension with weakest-link composition. Agents can require a floor before acting autonomously.

Low-confidence paths can route into approval instead of silently pretending every model answer is equally reliable.

effect llm_decision:
    confidence: 0.95

@min_confidence(0.90)
agent bot(query: String) -> String:
    return search(query)

Spec: confidence gates Tour: corvid tour --topic confidence-gates Roadmap: Phase 20e Proof: minimum confidence tests Non-scope: Confidence only means something when model adapters report calibrated signals.

AI-Native Ergonomics

AI-Native Keywords

agent, tool, prompt, effect, approve, model, eval, and streaming constructs are syntax the compiler understands.

The language stays general-purpose, but the AI boundaries are visible instead of buried in framework calls.

model local:
    capability: basic

prompt say(name: String) -> String:
    requires: basic
    "Hello {name}"

agent hello(name: String) -> String:
    return say(name)

Spec: dimensional syntax Tour: corvid tour --topic language-keywords Roadmap: Phase 20 language surface Proof: parser tests Non-scope: Keywords do not replace ordinary application code; they expose AI-specific boundaries to the compiler.

Trace-Aware Evals

Corvid evals can assert process, not just output. They can check that an agent called, approved, ordered, and spent as intended.

This targets the failure mode where an AI system gets the right answer through the wrong process.

agent always_refund() -> Bool:
    return true

eval refund_accuracy:
    result = always_refund()
    assert result == true

Spec: verification Tour: corvid tour --topic eval-traces Roadmap: Phase 20c Proof: eval assertion tests Non-scope: This is language/checker support; the full eval runner is later workflow tooling.

Replay And Receipts

Executions become evidence. Traces, deterministic replay, trace-diff, lineage, and signed receipts make behavior changes reviewable.

That gives AI-native programs an audit trail developers can diff, verify, and bundle.

@deterministic
@replayable
agent classify(text: String) -> String:
    return text

Spec: replay and bundle format Tour: corvid tour --topic replay-receipts Roadmap: Phase 21 and Phase 22 Proof: bundle verification tests Non-scope: Receipts are evidence of observed behavior, not full formal verification of every possible run.

Replay Quarantine For Durable Jobs

@replayable durable jobs record a typed JSONL trace on their first run. corvid jobs replay --source <path>.cor --job <id> reproduces the run from the trace, and during replay every side-effect surface refuses to escape: LLM adapter calls, outbound HTTP, application store writes, and filesystem writes. Recorded calls substitute from the trace; unrecorded ones fail closed with a typed QuarantineViolation naming the surface.

This makes "replay didn't leak" a runtime invariant instead of a property of the test harness.

@replayable
agent daily_brief(user_id: String) -> String:
    return "brief for " + user_id
corvid jobs run --source app.cor --state queue.db --workers 1 --max-runtime-ms 0
corvid jobs replay --source app.cor --job <job_id>

Spec: phase-38 replay-quarantine design Tour: corvid tour --topic replay-quarantine Roadmap: Phase 38 audit-correction track 35V2-P38-C-replay-quarantine Proof: replay quarantine corpus Non-scope: Quarantine ensures no real side effect escapes a Substitute-mode replay; it does not verify the original recording was correct, and it does not cover surfaces the runtime does not own (e.g. raw process spawns outside IoRuntime).

Adaptive Routing

Typed Model Routing

Models are declarations with capabilities and policy dimensions. Prompt dispatch is checked against those contracts.

Instead of stringly selecting models in application code, routing becomes part of the typed program.

model fast:
    capability: basic

model deep:
    capability: expert

prompt answer(q: String) -> String:
    route:
        q == "hard" -> deep
        _ -> fast
    "Answer {q}"

Spec: typed model substrate Tour: corvid tour --topic model-routing Roadmap: Phase 20h Proof: dispatch tests Non-scope: Routing declarations do not automatically benchmark model quality.

Progressive Refinement

A prompt can try cheap models first and escalate only when confidence falls below a typed threshold.

That makes cost-quality tradeoffs explicit and reviewable rather than hidden in orchestration glue.

prompt classify(q: String) -> String:
    progressive:
        cheap below 0.80
        medium below 0.95
        expensive
    "Classify {q}"

Spec: progressive refinement Tour: corvid tour --topic progressive-routing Roadmap: Phase 20h slice E Proof: progressive dispatch tests Non-scope: Thresholds depend on calibrated adapter confidence.

Ensemble Voting

One prompt can dispatch to several models concurrently and fold answers through a typed voting strategy.

The strategy is source-level, so reviewers can see when consensus is required instead of guessing from runtime code.

prompt classify(q: String) -> String:
    ensemble [opus, sonnet, haiku] vote majority
    "Classify {q}"

Spec: ensemble voting Tour: corvid tour --topic ensemble-voting Roadmap: Phase 20h slice F Proof: ensemble tests Non-scope: Majority voting is shipped; arbitrary custom vote functions require future function-value work.

Jurisdiction And Privacy Routing

Model declarations can carry regulatory dimensions such as jurisdiction, compliance, and privacy tier.

That lets the compiler enforce declared routing constraints before data crosses a boundary.

model eu_private:
    jurisdiction: eu_hosted
    compliance: gdpr
    privacy_tier: strict
    capability: expert

Spec: regulatory dimensions Tour: corvid tour --topic privacy-routing Roadmap: Phase 20h slice D Proof: dimension law tests Non-scope: The compiler enforces declared facts; legal compliance still requires operations, contracts, and audits.

Streaming

Streaming Effects

Streams are typed values that carry effects while data is still arriving. Budgets, confidence, provenance, and backpressure are not after-the-fact logs.

This makes streaming AI workflows safer without forcing users into untyped callback systems.

agent count() -> Stream<Int>:
    yield 1
    yield 2

Spec: streaming Tour: corvid tour --topic streaming-effects Roadmap: Phase 20f Proof: stream tests Non-scope: Provider-native continuation depends on provider APIs; local typed fallback tokens are the shipped boundary.

Progressive Structured Streams

Partial<T> lets a program read complete fields as they arrive while the rest of a structured response is still forming.

The type system exposes incomplete state safely instead of asking users to parse half-valid JSON.

type Plan:
    title: String
    body: String

agent read(snapshot: Partial<Plan>) -> Option<String>:
    return snapshot.title

Spec: streaming Tour: corvid tour --topic partial-streams Roadmap: Phase 20f Stream<Partial> Proof: partial stream tests Non-scope: Full native parity for every partial-stream path remains backend work.

Typed Stream Resumption

ResumeToken<T> captures the typed stream element contract so continuation cannot resume the wrong prompt shape.

This gives interrupted streams a language-level recovery boundary instead of an ad hoc provider session string.

agent capture(topic: String) -> ResumeToken<String>:
    stream = draft(topic)
    return resume_token(stream)

Spec: streaming Tour: corvid tour --topic stream-resume Roadmap: Phase 20f resumption tokens Proof: stream resume tests Non-scope: Provider-native session continuation waits on provider APIs; local fallback is shipped.

Declarative Fan-Out / Fan-In

Streams can split by structured fields and merge back with deterministic ordering.

The stream topology is visible in the program, so effects and ordering can be preserved through orchestration.

agent fanout() -> Stream<Event>:
    groups = source().split_by("kind")
    return merge(groups).ordered_by("fair_round_robin")

Spec: streaming Tour: corvid tour --topic stream-fanout Roadmap: Phase 20f fan-out/fan-in Proof: stream type tests Non-scope: Field-keyed split is shipped; first-class lambda extractors wait for function values.

Verification

Proof-Carrying Dimension Registry

Corvid can distribute pieces of the effect algebra as signed artifacts with law checks, proofs, and regression programs.

This is how the language can grow new policy dimensions without turning the compiler into a trust bottleneck.

effect local_policy:
    data: pii
    reversible: true

tool read_profile(id: String) -> String uses local_policy

Spec: dimension artifacts Tour: corvid tour --topic effect-registry Roadmap: Phase 20g invention 9 Proof: dimension registry tests Non-scope: The registry distributes declarations, not executable code or unverified trust.

Adversarial Bypass Testing

The compiler ships with a bypass-attempt taxonomy so AI can attack Corvid's own effect system in CI.

That turns "AI safety" into a regression target instead of a slogan.

tool refund(id: String) -> String dangerous uses transfer_money

@trust(human_required)
agent safe_refund(id: String) -> String:
    approve Refund(id)
    return refund(id)

Spec: adversarial taxonomy Tour: corvid tour --topic adversarial-tests Roadmap: Phase 20g adversarial generator Proof: adversarial tests Non-scope: Live LLM generation expands the corpus; deterministic seeds remain the safety gate.

Executing File-I/O Surface

Corvid's std/io module ships three executing tools — io_read_text, io_write_text, io_list_dir — that flow through typed effect rows (io_read, io_write, io_list) and a runtime-enforced [io] root confinement boundary.

The security boundary is declared in corvid.toml and signable: a signed cdylib carries io_source.fs_path_confinement + the two replay-quarantine guarantees in its claim manifest, so a host can verify the binary refuses to operate outside the declared root.

import "./std/io" use io_read_text, io_write_text

agent persist_summary(date: String, body: String) -> String:
    io_write_text(date + ".txt", body)
    return date

Calls outside the configured [io] root are refused with a structured diagnostic naming the offending path AND the root. Calls inside a @deterministic agent are rejected at typecheck. Calls during replay either substitute from the recorded trace or diverge — the filesystem is provably untouched.

Spec: std.io reference Tour: corvid tour --topic file-io Roadmap: Phase 33S1 Proof: executing I/O tests + replay-quarantine corpus + path-confinement tests Non-scope: Confines paths to the declared root; does not police what user code does with the contents.

Executing HTTP-Client Surface

Corvid's std/http module ships two executing tools — http_get, http_post_json — that flow through typed effect rows (http_egress_get, http_egress_post) and a two-layer security boundary: an always-on structural SSRF block that refuses RFC1918 / loopback / link-local hosts regardless of allowlist, plus a required [http] allow allowlist that fails closed when unconfigured.

The security boundary is declared in corvid.toml and signable: a signed cdylib carries io_source.http_ssrf_structural_block, io_source.http_allowlist_enforcement, and io_source.http_quarantine_on_replay in its claim manifest, so a host can verify the binary refuses to reach private networks AND can only reach explicitly approved hosts AND cannot escape replay quarantine.

import "./std/http" use http_get, http_post_json, http_ok

agent ship_event(url: String, body: String) -> Bool:
    response = http_post_json(url, body)
    return http_ok(response)
[http]
allow = ["hooks.example.com"]

A URL whose host is not in [http] allow is refused with a structured diagnostic naming the host AND the configured allowlist. A URL whose host resolves to a private range is refused by the structural SSRF block before the allowlist is consulted — even a misconfigured [http] allow = ["127.0.0.1"] cannot reach loopback. Calls inside a @deterministic agent are rejected at typecheck. Calls during Substitute-mode replay either substitute from the recorded trace or diverge — the network is provably untouched.

Spec: std.http reference Tour: corvid tour --topic http-client Roadmap: Phase 33S2 Proof: end-to-end HTTP tests + policy tests + replay-quarantine corpus Non-scope: Enforces SSRF + allowlist + replay quarantine on the URL host; does not police response-body content or rewrite request headers.

Executing SQLite Surface

Corvid's std/db module ships three executing tools — db_open, db_query, db_execute — that flow through typed effect rows (db_egress_open, db_egress_read, db_egress_write) and three load-bearing structural properties:

  1. SQL injection is prevented structurally, not by escaping. The db_query / db_execute tools' List<DbParam> signature forces every value through the typed constructors (db_param_int, db_param_text, etc.), and the runtime binds via rusqlite::params_from_iter over typed DbValues. There is no format! call anywhere on the dispatch path; a literal "'; DROP TABLE users; --" placed in db_param_text survives as text data and never reaches SQLite's parser. The structural argument is pinned by a runtime unit test AND an end-to-end driver test against a real Corvid program.

  2. [io] root path confinement reuses the file-I/O boundary. db_open routes through the same IoToolPolicy the io tools use; SQLite is structurally as narrow as io_write_text. No separate [db] allowlist exists. The documented special case ":memory:" bypasses path resolution.

  3. DbHandle is an opaque, refcounted primitive type. Constructed only by db_open's typed-Value dispatch path; user code cannot forge a handle through JSON round-trip (the VM's json_to_value REFUSES to mint a Type::DbHandle from any payload, including the trace-debug sentinel shape).

The security boundary is declared in corvid.toml (via [io] root) and signable: a signed cdylib carries io_source.sqlite_parameter_binding_only, io_source.sqlite_write_quarantine_on_replay, io_source.sqlite_read_passthrough_on_replay, and the reused io_source.fs_path_confinement in its claim manifest.

import "./std/db" use db_open, db_execute, db_query, db_param_int, db_param_text

agent record_user(email: String) -> Int:
    handle = db_open(":memory:")
    db_execute(handle, "CREATE TABLE users(id INTEGER PRIMARY KEY, email TEXT NOT NULL)", [])
    db_execute(handle, "INSERT INTO users(id, email) VALUES (?, ?)", [db_param_int(1), db_param_text(email)])
    rows = db_query(handle, "SELECT id FROM users WHERE email = ?", [db_param_text(email)])
    return rows[0].rows_affected

Calls inside a @deterministic agent are rejected at typecheck. Calls during Substitute-mode replay refuse db_execute with QuarantineViolation { surface: "db", .. } — the database is provably untouched. SQLite only; the Postgres path remains envelope-only (declare a Postgres tool in user code and reach corvid-runtime::PostgresDbRuntime from a tool wrapper).

Spec: std.db reference Tour: corvid tour --topic sqlite Roadmap: Phase 33S3 Proof: end-to-end SQLite tests + DbHandleRegistry tests + replay-quarantine corpus Non-scope: SQLite only — the Postgres path remains envelope-only. Path confinement reuses [io] root; no separate [db] allowlist exists.

Executing JSON Surface (Opaque + Typed-Decoder)

Corvid's std/json module ships 13 executing tools across TWO complementary shapes — the load-bearing "no Python required for JSON" promise of the batteries umbrella:

  1. Opaque pathjson_parse(text) -> Result<JsonValue, String>, typed accessors (json_get_int, json_get_string, ...), fluent builder (json_object_newjson_object_set_*json_object_finish). For dynamic JSON: LLM responses of unknown shape, debug tooling, polymorphic APIs.

  2. Typed-decoder convention — user declares tool decode_<X>_from_json(text: String) -> Result<X, String> where X is any Corvid type the runtime can convert from JSON. The interpreter pattern-matches the tool name + return type and routes through serde_json::from_str + json_to_value against the declared target. No per-type runtime handler exists — the dispatch is generic over the declared signature. For typed APIs and the 33S4 HTTP→JSON→SQLite tutorial.

The surface enforces two load-bearing structural safety properties:

  1. Parse safetyjson_parse against arbitrary bytes returns Result::Err(message) rather than panicking. The typed-decoder convention inherits this.
  2. Field-type safetyjson_get_int against a String field returns Result::Err, never coerces. The typed-decoder convention inherits this too — JSON shape mismatches surface as Result::Err rather than runtime panics.

The security boundary is structural in the typechecker: a signed cdylib carries json.parse_safety_no_panic and json.field_type_safety_at_access_boundary in its claim manifest.

effect json_decode_eff:
    reversible: true

type User:
    id: Int
    email: String

import "./std/json" use json_parse, json_get_int

tool decode_user_from_json(text: String) -> Result<User, String> uses json_decode_eff

agent typed_decoder(text: String) -> Result<Int, String>:
    user = decode_user_from_json(text)?
    return Ok(user.id)

Calls inside a @deterministic agent are rejected at typecheck. JSON parse/build are deterministic and process-internal so replay-mode dispatch runs IDENTICALLY to live (no quarantine flag needed). The cdylib corvid_json_* C-ABI exports already exist in corvid-runtime::ffi_bridge::json_exports; cdylib codegen for JsonValue / JsonBuilder is interpreter-only in 33R5b (follow-up slice).

Spec: std.json reference Tour: corvid tour --topic json Roadmap: Phase 33R5b Proof: end-to-end JSON tests + runtime JSON tests + replay-quarantine corpus Non-scope: No JSON Path / JSONata / JMESPath query language (nested access via json_get_object chains). cdylib codegen for the opaque types is a follow-up slice; the C-ABI exports already exist.

Architecture

source .cor
  -> lex / parse
  -> resolve names
  -> typecheck
  -> effect, budget, confidence, grounding, approval, routing checks
  -> typed IR
  -> interpreter, native Cranelift backend, Python backend, WASM backend
  -> traces, replay, receipts, bundles

The language is designed as one compiler pipeline with multiple execution tiers. Safety properties belong in the shared frontend and IR, not in one backend's runtime glue.

Status

Corvid is pre-v1.0 and under active development. The compiler, interpreter, effect system, model substrate, streaming substrate, replay/bundle infrastructure, native backend, signed cdylib attestation, separate-binary ABI descriptor verifier, and claim explanation workflow are in the repository today. Some backend paths intentionally reject newer high-level features until parity work lands; signed builds fail closed when contract-like syntax is not mapped to a registered guarantee.

A 2026-04-29 internal audit of Phases 35-41 found four phase-done bullets in Phases 38-41 that were structurally absent (multi-worker job runner + crash-recovery / DST tests, real JWT verification + corvid auth/approvals CLI, OTel SDK conformance, connector real mode + corvid connectors CLI). The ROADMAP now carries audit-correction tracks (35-N, 38K-M, 39K-L, 40J-K, 41K-M) that close the gaps end-to-end. Slice checkmarks before those tracks land are honest only at the layer the slice named — composition with the surfaces above stays disabled.

Use the roadmap for source-of-truth status:

rg -n "^- \\[ \\]" ROADMAP.md

Install

Windows (PowerShell):

irm https://raw.githubusercontent.com/Micrurus-Ai/Corvid-lang/main/install/install.ps1 | iex

macOS / Linux:

curl -fsSL https://raw.githubusercontent.com/Micrurus-Ai/Corvid-lang/main/install/install.sh | sh

The installer downloads a prebuilt corvid for your OS/arch into ~/.corvid/, adds ~/.corvid/bin to your PATH, and runs corvid doctor. If a prebuilt archive is not available for your platform, it falls back to a cargo install from source.

Override defaults with CORVID_REPO, CORVID_VERSION (e.g. v0.1.0), or CORVID_HOME.

Or via your package manager (planned, post-v1.0)

Status: the install scripts above (install/install.{sh,ps1}) are the canonical install path for Corvid v1.0. The package- manager manifests below are tracked as Phase 33P slices in ROADMAP.md and ship post-v1.0 — none of them is the "installer," each is additive metadata that a language-installer manager's central repo consumes and routes back to the GitHub Release artifacts release.yml produces. They're filed but not built yet; running them today will report "formula/manifest not found."

ManagerEnd-user command (post-v1.0)Filed slice
Homebrew (macOS / Linux)brew install Micrurus-Ai/corvid/corvid33P1-homebrew-tap
Scoop (Windows)scoop bucket add corvid https://github.com/Micrurus-Ai/scoop-corvid && scoop install corvid33P2-scoop-bucket
winget (Windows)winget install Micrurus-Ai.Corvid33P3-winget-manifest
Chocolatey (Windows)choco install corvid33P4-chocolatey-package
AUR (Arch Linux)yay -S corvid-bin (or equivalent AUR helper)33P5-aur-package
APT / RPM (Debian / Fedora)apt install corvid / dnf install corvid after one-time repo add33P6-apt-rpm-repo

If you want to track or contribute any of these, ROADMAP.md's Phase 33P block names each filed slice with what it actually does. Manifest contributions are welcome at any time — the GitHub Release artifacts they consume (release.yml) are already shipping; the manifests are post-v1.0 only because Path A defers public packaging-manager listings until launch by deliberate design.

Install From Source

cargo install --path crates/corvid-cli
corvid doctor

Python runtime pieces are only needed when using the Python backend. Native and interpreter work do not require a Python deployment target.

Developer Commands

cargo check --workspace
cargo test --workspace
cargo run -q -p corvid-cli -- tour --list
cargo run -q -p corvid-cli -- check examples/refund_bot_demo/refund.cor

If cargo fmt --check fails because cargo-fmt is not installed, install the Rust formatter for the active toolchain before treating formatting as validated.

Documentation

License

Corvid is released under the MIT License.

Contributions are licensed under the same MIT terms (inbound = outbound) unless the contributor marks otherwise.