Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
e47e798
Refresh only inherited snapshots when propagating namespaces
metaphorics Sep 9, 2026
d240616
Give computed numeric enum members a reverse mapping
metaphorics Sep 9, 2026
5a49470
Merge branch 'main' into fix/derived-namespace-propagation
metaphorics Sep 9, 2026
ab463c1
Copy owned baseline matches without a closure
metaphorics Sep 9, 2026
473a2a3
Fetch all-target crates before the offline ledger gate
metaphorics Sep 9, 2026
c93e13a
Materialize the conformance authority before receipts
metaphorics Sep 9, 2026
0a1cb6e
Stop AOT compilation from consuming the case budget
metaphorics Sep 9, 2026
aafb3cd
Resolve the authority test tree from the crate location
metaphorics Sep 9, 2026
882a46b
Provision Node and Quint for the workspace test job
metaphorics Sep 9, 2026
4513492
Let the enum plan decide the reverse-mapping index
metaphorics Sep 9, 2026
557ee0e
Keep the nearer ancestor when propagating base statics
metaphorics Sep 9, 2026
6dafcf5
Materialize the authority in the accounting jobs
metaphorics Sep 9, 2026
851f88d
Decide the enum reverse map before members are typed
metaphorics Sep 9, 2026
eee4dbc
Classify qualified and merged string enum references
metaphorics Sep 9, 2026
c014440
Rank inherited own statics by declaring depth
metaphorics Sep 9, 2026
162c1e6
Resolve enum string references by symbol, not by name
metaphorics Sep 9, 2026
487a279
Rank namespace-sourced statics by the inheritance chain
metaphorics Sep 9, 2026
4022668
Let exit end the api loop, not shutdown
metaphorics Sep 9, 2026
d13ba26
Time link cancellation from the cancel, not the spawn
metaphorics Sep 9, 2026
f5d96ac
Guard enum reverse-mapping classification with tests
metaphorics Sep 9, 2026
7d1209a
Guard namespace static precedence with tests
metaphorics Sep 9, 2026
4a1e9c6
Reap the reader before draining, keeping shutdown terminal
metaphorics Sep 9, 2026
a275a49
Fetch all-target crates before the workspace guard
metaphorics Sep 9, 2026
2a6d3db
Resolve enum owners reached through a namespace
metaphorics Sep 9, 2026
94d558e
Wait for the reader once during shutdown
metaphorics Sep 9, 2026
8dca617
Read intermediate enum-path segments like the final one
metaphorics Sep 9, 2026
6c300f8
Surface a reader that fails during the drain
metaphorics Sep 9, 2026
b168bfb
Decode escaped names before member lookup
metaphorics Sep 9, 2026
300ee6b
Refresh captured constructors on namespace merge
metaphorics Sep 9, 2026
67488b8
Forward type-state cache on namespace merge
metaphorics Sep 9, 2026
5d57c25
Advance baseline records on namespace merge
metaphorics Sep 9, 2026
5328cd3
Narrow refresh to proven capture slots
metaphorics Sep 9, 2026
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
52 changes: 52 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,34 @@ jobs:
- name: Clippy
run: cargo clippy --workspace --all-targets --locked -- -D warnings

# The workspace guard shells out to `cargo metadata --offline`,
# which resolves the graph for every target and so needs crates
# this host build never downloads. `cargo fetch` without `--target`
# gets all of them, matching the Formal job's G0 ledger step.
- name: Fetch dependencies for all targets
run: cargo fetch --locked

- name: Fetch pinned TypeScript test fixtures
run: >-
cargo run --locked -p bamts-verification -- source fetch
typescript-primary-tests --dest target/authority/typescript-7.0.2-tests

# `cargo test --workspace` covers authority, oracle-pin, and formal
# bridge tests that read `node_modules/typescript/package.json` and
# drive a local Quint. Without these the step fails on a missing
# toolchain rather than on a real defect.
- name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 24.18.0
package-manager-cache: false

- name: Install npm dependencies
run: npm ci

- name: Install Quint
run: npm ci --prefix formal/quint

- name: Test workspace
run: cargo test --workspace --locked

Expand Down Expand Up @@ -189,6 +212,12 @@ jobs:
rustup toolchain install "$TOOLCHAIN" --profile minimal --component rustfmt,clippy,rust-src
rustup default "$TOOLCHAIN"

# `ledger verify` shells out to `cargo metadata --offline`, which
# resolves the graph for every target and so needs crates the host
# build never downloads. `cargo fetch` without `--target` gets all.
- name: Fetch dependencies for all targets
run: cargo fetch --locked

- name: G0 ledger
run: cargo run --locked -p bamts-verification --bin bamts-verification -- ledger verify --gate G0

Expand Down Expand Up @@ -228,6 +257,18 @@ jobs:
run: cargo run --locked -p bamts-verification --bin ts_conformance -- sync --verify-pin --write-snapshot
- name: Build compiler lane worker
run: cargo build --locked --release -p bamts-verification --bin ts_lane_worker
# `suite run` hashes the locked authority markers under
# target/authority. The typescript-7.0.2 catalog reads both the
# compiler tree and the test tree, so both must be materialized
# or the receipt step fails with E_TOOL_MISSING.
- name: Fetch pinned TypeScript compiler authority
run: >-
cargo run --locked -p bamts-verification -- source fetch
typescript-7-compiler --dest target/authority/typescript-7.0.2
Comment thread
metaphorics marked this conversation as resolved.
- name: Fetch pinned TypeScript test authority
run: >-
cargo run --locked -p bamts-verification -- source fetch
typescript-primary-tests --dest target/authority/typescript-7.0.2-tests
- name: Write strict conformance receipt
env:
BAMTS_SUITE_COMPILER_ADAPTER: target/release/ts_lane_worker
Expand Down Expand Up @@ -285,6 +326,17 @@ jobs:
merge-multiple: true
- name: Build compiler lane worker
run: cargo build --locked --release -p bamts-verification --bin ts_lane_worker
# `suite merge` recomputes the run binding, whose authority digest
# reads both markers under target/authority. The receipts artifact
# carries only JSONL, so this clean runner must materialize them too.
- name: Fetch pinned TypeScript compiler authority
run: >-
cargo run --locked -p bamts-verification -- source fetch
typescript-7-compiler --dest target/authority/typescript-7.0.2
- name: Fetch pinned TypeScript test authority
run: >-
cargo run --locked -p bamts-verification -- source fetch
typescript-primary-tests --dest target/authority/typescript-7.0.2-tests
- name: Merge complete compatible matrix
env:
BAMTS_SUITE_COMPILER_ADAPTER: target/release/ts_lane_worker
Expand Down
29 changes: 29 additions & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@ jobs:
run: cargo run --locked -p bamts-verification --bin ts_conformance -- sync --verify-pin --write-snapshot
- name: Build compiler lane worker
run: cargo build --locked --release -p bamts-verification --bin ts_lane_worker
# `suite run` hashes the locked authority markers under
# target/authority. The typescript-7.0.2 catalog reads both the
# compiler tree and the test tree, so both must be materialized
# or the receipt step fails with E_TOOL_MISSING.
- name: Fetch pinned TypeScript compiler authority
run: >-
cargo run --locked -p bamts-verification -- source fetch
typescript-7-compiler --dest target/authority/typescript-7.0.2
- name: Fetch pinned TypeScript test authority
run: >-
cargo run --locked -p bamts-verification -- source fetch
typescript-primary-tests --dest target/authority/typescript-7.0.2-tests
- name: Write strict nightly receipt
env:
BAMTS_SUITE_COMPILER_ADAPTER: target/release/ts_lane_worker
Expand Down Expand Up @@ -148,6 +160,17 @@ jobs:
merge-multiple: true
- name: Build compiler lane worker
run: cargo build --locked --release -p bamts-verification --bin ts_lane_worker
# `suite merge` recomputes the run binding, whose authority digest
# reads both markers under target/authority. The receipts artifact
# carries only JSONL, so this clean runner must materialize them too.
- name: Fetch pinned TypeScript compiler authority
run: >-
cargo run --locked -p bamts-verification -- source fetch
typescript-7-compiler --dest target/authority/typescript-7.0.2
- name: Fetch pinned TypeScript test authority
run: >-
cargo run --locked -p bamts-verification -- source fetch
typescript-primary-tests --dest target/authority/typescript-7.0.2-tests
- name: Merge complete compatible matrix
env:
BAMTS_SUITE_COMPILER_ADAPTER: target/release/ts_lane_worker
Expand Down Expand Up @@ -359,6 +382,12 @@ jobs:
rustup toolchain install "$TOOLCHAIN" --profile minimal --component rustfmt,clippy,rust-src
rustup default "$TOOLCHAIN"

# `ledger verify` shells out to `cargo metadata --offline`, which
# resolves the graph for every target and so needs crates the host
# build never downloads. `cargo fetch` without `--target` gets all.
- name: Fetch dependencies for all targets
run: cargo fetch --locked

- name: G0 ledger
run: cargo run --locked -p bamts-verification --bin bamts-verification -- ledger verify --gate G0

Expand Down
19 changes: 18 additions & 1 deletion crates/bamts-cli/src/api_server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::io::{self, Write};
use std::os::fd::AsFd;
use std::sync::Arc;
use std::thread;
use std::time::Duration;

use control::{Control, ControlKind, Inbound, Next, REAP_DEADLINE, ReaderExit};
use reader::reader_main;
Expand Down Expand Up @@ -145,6 +146,15 @@ where

control.stop();
let _ = waker.wake();
// `shutdown` ends the loop by design, and the drain owes a terminal
// response to work the transport already carried. Reaping the reader
// first is what makes that set well defined: without it the loop can
// break while the next frame is still being parsed, and that request
// leaves unanswered depending only on thread scheduling. One wait
// serves both the drain and the join below, so a reader that never
// exits costs the deadline once. A reader that cannot be woken keeps
// the existing orphan path rather than stalling shutdown at all.
let reader_reaped = I::Waker::REAPABLE && control.wait_reaped(REAP_DEADLINE);
for inbound in control.drain() {
match inbound {
Inbound::Work {
Expand All @@ -168,7 +178,14 @@ where
}
}

let reaped = if I::Waker::REAPABLE && control.wait_reaped(REAP_DEADLINE) {
// A reader that exits while the drain is writing its responses still
// owes its terminal error, so re-read the state once the drain is
// done. A zero deadline reads without waiting again, which keeps the
// single bounded wait above.
let reader_reaped =
reader_reaped || (I::Waker::REAPABLE && control.wait_reaped(Duration::ZERO));

let reaped = if reader_reaped {
Comment thread
qodo-code-review[bot] marked this conversation as resolved.
Reaped::Joined(
reader
.join()
Expand Down
21 changes: 12 additions & 9 deletions crates/bamts-cli/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2879,27 +2879,30 @@ printf started > link-started
let cancel = CancellationToken::new();
let trigger = cancel.clone();
let marker = directory.join("link-started");
// Wait for the linker to actually start rather than for a fixed
// slice of wall clock: a loaded runner can take longer to spawn
// the process than a short deadline allows. The cap only breaks a
// genuine hang, and the returned instant dates the cancel so the
// bound below measures cancellation, not process startup.
let canceller = thread::spawn(move || {
let deadline = Instant::now() + Duration::from_secs(2);
let deadline = Instant::now() + Duration::from_secs(60);
while !marker.is_file() && Instant::now() < deadline {
thread::sleep(Duration::from_millis(5));
}
let started = marker.is_file();
trigger.cancel();
started
started.then(Instant::now)
});

let started = Instant::now();
let error = link_executable(&[], &directory.join("output"), &context, &cancel)
.expect_err("cancelled linker must fail as cancellation");
assert!(matches!(error, DriverError::Cancelled));
let cancelled_at = canceller
.join()
.expect("link cancellation thread completes")
.expect("the linker must start before it is cancelled");
assert!(
canceller
.join()
.expect("link cancellation thread completes")
);
assert!(
started.elapsed() < Duration::from_secs(3),
cancelled_at.elapsed() < Duration::from_secs(3),
"managed link cancellation must be bounded"
);
fs::remove_dir_all(directory)?;
Expand Down
Loading
Loading