Skip to content

Projects today

This page explains how "projects" work in Incan.

The current model

Incan source files (.incn) are the source of truth.

When you run:

incan build path/to/main.incn

Incan checks the source and generates caller-owned Rust, then Oven verifies the build receipt, selects and leases a compatible Loaf, and executes its stored direct-rustc plan. For the documented Alpha envelope, the normal command neither launches Cargo nor reads a Cargo target directory. A compatibility miss stops with actionable guidance rather than changing backend.

Cargo currently remains at one explicit maintainer boundary: the internal release publisher can prepare a supported Loaf envelope. That publication step is not part of an ordinary build, run, or test command. See Oven Alpha for the rationale, architecture, and current limitations.

Contributor source-build fallback

If you are working from a compiler checkout instead of a toolchain install, you can run the repository-built binary directly:

  • from the repository root:
./target/release/incan ...
  • or via an absolute path (from anywhere):
/absolute/path/to/incan run path/to/file.incn

Where outputs go

On build, Incan prints the generated project directory and the compiled binary path. In practice, outputs live under:

  • Generated Rust project: target/incan/<name>/
  • Built binary: target/incan/<name>/oven/release/<name>

See: CLI reference.

What gets regenerated

The generated Rust project under target/incan/ is tool-managed output. Treat it as generated:

  • It is safe to delete when no Incan command is using it: rm -rf target/incan/
  • Manual edits inside target/incan/<name>/ may be overwritten on the next build

If an incan.lock exists, its relevant dependency and source evidence contributes to the Oven compatibility identity. A normal build validates and selects an authorized Loaf from that evidence; it does not materialize a Cargo project for execution.

Dependencies

Rust crate dependencies are resolved through a three-tier system:

  1. incan.toml (highest priority): Project manifest declares explicit dependencies with versions, features, and sources.
  2. Inline annotations: import rust::foo @ "1.0" specifies versions directly in source files.
  3. Known-good defaults: For common crates, the compiler provides tested version/feature defaults.

If none of these apply, the compiler emits an error.

See: Rust Interop and Managing dependencies.

Project configuration

Projects can optionally have an incan.toml manifest at the project root:

my_project/
├── src/
│   └── main.incn
├── tests/
│   └── test_main.incn
├── incan.toml         # Project manifest (optional)
└── incan.lock         # Lock file (auto-generated, commit to VCS)

Create one with incan init. See: Project configuration reference.

Lock files

incan.lock stores resolved dependency versions and normalized build inputs for reproducible builds. It is generated by incan lock (or automatically on first build) and should be committed to version control. Oven binds relevant lock evidence into Loaf selection.

Use --locked or --frozen in CI to enforce that the lock is present and up to date. Within the Alpha envelope, an unavailable compatible Loaf is an explicit miss; normal commands do not ask Cargo to resolve or build one.

See: Managing dependencies.

  • Project lifecycle commands are available as incan new, incan init, incan version, and incan env.
  • Tooling diagnostics are available under incan tools doctor.