Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Seven terms have exactly one meaning each, everywhere in this repository: code c
- A Cargo feature gates a real constraint such as a toolchain requirement or heavy native build. It does not describe product shape. Feature-disabled builds must not leak optional types into core paths.
- Runtime and serve paths never compile native dependencies or invoke build tools.
- Unsafe code stays in its explicitly owned boundary.
- Engine and Harness crates report every failure as the universal `Error` in `runvil-types`, which the `runvil` facade re-exports. A new kind of failure is a new `ErrorCode` variant in its hundreds family, with a number never used before, plus a `FactKey` variant only when no existing key names the value. They add no other error enum or struct, no `thiserror` derive, and no other `impl std::error::Error`; a foreign cause joins the message through `Error::with_cause`. `VfsError` and `ParsePathReasonError` in `runvil-vfs` are the only exceptions, and test code may define a throwaway error type to exercise `with_cause`. A crate-private marker returned as `Err` and turned into `Error` by its caller, or a type that pairs an `Error` with a value the caller must still release, such as `InjectFailure`, is not another error type.
- Engine and Harness crates report every failure as the universal `Error` in `runvil-types`, which the `runvil` facade re-exports. A new kind of failure is a new `ErrorCode` variant in its hundreds family, with a number never used before, plus a `FactKey` variant only when no existing key names the value. They add no other error enum or struct, no `thiserror` derive, and no other `impl std::error::Error`; a foreign cause joins the message through `Error::with_cause`. `VfsError` in `runvil-vfs` is the only exception, and test code may define a throwaway error type to exercise `with_cause`. A crate-private marker returned as `Err` and turned into `Error` by its caller, or a type that pairs an `Error` with a value the caller must still release, such as `InjectFailure`, is not another error type.
- Comments explain a non-obvious constraint, ordering requirement, or workaround. Every platform or external-bug workaround cites its upstream issue URL in the explanatory comment.
- JSON that reaches a recorder or a replay comparison round-trips exactly - `to_value`, `to_string`, `from_str` yield an identical value, object keys stay canonical (sorted), numbers must be finite. Exact parsing (`float_roundtrip`) carries that guarantee; a value derived and then logged is additionally rounded to its meaningful precision at the source.

Expand All @@ -60,7 +60,7 @@ Seven terms have exactly one meaning each, everywhere in this repository: code c
- Docs: `cargo doc --workspace --no-deps --all-features --exclude workshop --exclude workshop-server --exclude workshop-server-api` with `RUSTDOCFLAGS="-D warnings"`. Rustdoc lints are not covered by clippy; never skip the docs gate.
- Facade docs: `RUSTDOCFLAGS="-D warnings" cargo doc -p runvil --no-deps`, without `--all-features`, so the facade's docs build with default features.
- Facade surface: `cargo +<pinned nightly> xtask api --check`, where the pinned nightly is the one named in `crates/build-xtask/src/api/toolchain.rs`; on any other toolchain it fails at once, naming the nightly it needs. It checks that every path a surface item's signature, fields, bounds, impls, or doc links name is a facade re-export (or std, core, alloc, or an allowlisted crate), that no surface doc text names an internal crate, and that the surface listing matches the committed `crates/runvil/public-api.txt`. Run it with `CARGO_BUILD_WARNINGS` unset (in PowerShell, `Remove-Item Env:CARGO_BUILD_WARNINGS` after the clippy gate set it), because the nightly cargo turns its own warnings into errors while that variable is set.
- Boundary and structural checks: `cargo test -p build-xtask`. It enforces the product and container boundaries, the Workshop tier graph, the `## Invariants` marker, and lint inheritance.
- Boundary and structural checks: `cargo test -p build-xtask`. It enforces the product and container boundaries, the Workshop tier graph, the `## Invariants` marker, lint inheritance, and the type-size limits.
- Wording and rulebook scan: `node --test crates/workshop/ui/test/docs-claims.mjs`. It enforces the Engine wording rule, the rulebook Definitions, and the Pack lifecycle wording (installed, snapshotted, or declared). It needs no `npm ci` and runs from any directory, because the file resolves the repository root from its own path.

## Structural Rules
Expand All @@ -70,7 +70,8 @@ Seven terms have exactly one meaning each, everywhere in this repository: code c
- No Engine test sleeps, reads the wall clock, waits with a timeout, or draws entropy from the OS.
- Pseudo-random test input comes only from a fixed seed that the failure prints.
- Temporary directory names come from the test's name, the process id, and a counter.
- A module with more than one file keeps its files in a directory named after it, in the standard module layout (`foo.rs` beside `foo/bar.rs`). A directory may hold any number of files, one included, and a module's unit tests are one of them (`foo/tests.rs`). Never move files between a flat sibling form and a directory because of how many files a group holds, and never change a group's layout only to bring it in line with this rule. Existing `foo-bar.rs` siblings wired with `#[path = "foo-bar.rs"] mod bar;` stay as they are, and new code adds no path attribute for layout. Top-level `tests/` and `benches/` trees follow Cargo target conventions.
- A module with more than one file keeps its files in a directory named after it, in the standard module layout (`foo.rs` beside `foo/bar.rs`). A directory may hold any number of files, one included. Never move files between a flat sibling form and a directory because of how many files a group holds, and never change a group's layout only to bring it in line with this rule. Existing `foo-bar.rs` siblings wired with `#[path = "foo-bar.rs"] mod bar;` and existing unit-test files (`foo-tests.rs`, `foo/tests.rs`) stay as they are; new code adds no path attribute for layout, and new unit tests go in a `#[cfg(test)] mod tests` block in the file under test. Top-level `tests/` and `benches/` trees follow Cargo target conventions.
- A file has no length limit. Never split a file, or move code out of one, because of its length; split a file only when it holds a second unrelated concept. Size limits sit on functions and types instead: clippy denies a function over 100 lines or 7 arguments (set in every `clippy.toml`), and `cargo test -p build-xtask` fails a type with more than 25 inherent methods across its `impl` blocks or a struct with more than 12 named fields. Split an oversized type by responsibility; a new entry in the allowlist in `crates/build-xtask/src/type_size.rs` is a plan decision with a reason, never a way to make a change pass.

## SPA and CSS Rules

Expand Down
30 changes: 0 additions & 30 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ repository = "https://github.com/cppalliance/runvil"

[workspace.dependencies]
bytes = "1"
build-ceiling = { path = "crates/build-ceiling" }
runvil = { path = "crates/runvil" }
runvil-engine = { path = "crates/runvil-internal/engine" }
runvil-plugin = { path = "crates/runvil-plugin" }
Expand Down
5 changes: 5 additions & 0 deletions clippy.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
allow-unwrap-in-tests = true
allow-expect-in-tests = true

# Size limits sit on functions (here) and on types (build-xtask's
# type-size check). A file has no length limit.
too-many-lines-threshold = 100
too-many-arguments-threshold = 7

# Process-global installers. Only a binary entry point may call one, under
# `#[expect(clippy::disallowed_methods, reason = ...)]`. No entry names a
# `replacement`, because no alternative takes the same arguments and returns
Expand Down
15 changes: 0 additions & 15 deletions crates/build-ceiling/Cargo.toml

This file was deleted.

13 changes: 0 additions & 13 deletions crates/build-ceiling/build.rs

This file was deleted.

Loading
Loading