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
12 changes: 8 additions & 4 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,14 @@ Python, Gherkin, native binding, Pulumi, Terraform, or Bazel jobs. Pull-request
native binding acceptance is Linux-only and uses Cargo's `dev` profile for
maturin/napi assembly. Authoritative Rust compile/test is Bazel
(`//:ci_rust_tests`) under `Bazel Bootstrap`.
When Rust surfaces change, `Windows graphforge-storage Locks` runs
`cargo test -p graphforge-storage project_generation::tests:: --lib` on
`blacksmith-4vcpu-windows-2025` so the `#[cfg(windows)]` project-root lock unit
tests stay covered outside Binding RC.
When Rust surfaces change, `Windows graphforge-storage Locks` runs the native
project-root lock, exact filesystem primitive, NTFS admission, and real
publication-kill/fault-oracle cross-checks on `blacksmith-4vcpu-windows-2025`.
`macOS graphforge-storage Durability` runs the corresponding native APFS
primitive, admission, and publication-kill cross-checks. Linux executes the same
storage unit suite through authoritative `//:ci_rust_tests`. These platform jobs
record actual subprocess/handle observations; the simulator does not stand in
for native evidence.

### Behavioral acceptance

Expand Down
81 changes: 81 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,52 @@ jobs:
cargo test -p graphforge-storage
filesystem_admission::tests:: --lib --no-fail-fast

- name: Cross-check Windows publication-kill results against the fault oracle
shell: bash
env:
GRAPHFORGE_NATIVE_ORACLE_EVIDENCE: ${{ runner.temp }}/durability-certification-evidence/native-oracle-windows.json
run: >-
cargo test -p graphforge-storage --features test-failpoints --lib
project_recovery::tests::subprocess_kill_matrix_never_exposes_a_partial_generation
--no-fail-fast -- --exact --nocapture

- name: Upload Windows native oracle evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: native-oracle-windows-${{ github.sha }}
path: ${{ runner.temp }}/durability-certification-evidence
if-no-files-found: error
retention-days: 1

- name: Run Windows injected publication error recovery test
shell: bash
run: >-
cargo test -p graphforge-storage --features test-failpoints --lib
project_recovery::tests::injected_operation_errors_report_exact_commit_state
--no-fail-fast -- --exact --nocapture

- name: Run Windows commit-lock cloned-descriptor test
shell: bash
run: >-
cargo test -p graphforge-storage --lib
project_publication::tests::commit_lock_guard_unlocks_before_a_cloned_descriptor_closes
--no-fail-fast -- --exact --nocapture

- name: Run Windows checkpoint-lock cloned-descriptor test
shell: bash
run: >-
cargo test -p graphforge-storage --lib
project_checkpoints::tests::checkpoint_read_guard_unlocks_before_a_cloned_descriptor_closes
--no-fail-fast -- --exact --nocapture

- name: Run Windows optimistic-promotion handle test
shell: bash
run: >-
cargo test -p graphforge-storage --lib
project_publication::tests::optimistic_promotion_closes_staged_handles_before_directory_rename
--no-fail-fast -- --exact --nocapture

- name: Run Windows durability certification unit tests
shell: bash
run: >-
Expand Down Expand Up @@ -916,6 +962,41 @@ jobs:
run: >-
cargo test -p graphforge-filesystem --lib --no-fail-fast

- name: Cross-check macOS publication-kill results against the fault oracle
env:
GRAPHFORGE_NATIVE_ORACLE_EVIDENCE: ${{ runner.temp }}/durability-certification-evidence/native-oracle-macos.json
run: >-
cargo test -p graphforge-storage --features test-failpoints --lib
project_recovery::tests::subprocess_kill_matrix_never_exposes_a_partial_generation
--no-fail-fast -- --exact --nocapture

- name: Upload macOS native oracle evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: native-oracle-macos-${{ github.sha }}
path: ${{ runner.temp }}/durability-certification-evidence
if-no-files-found: error
retention-days: 1

- name: Run macOS injected publication error recovery test
run: >-
cargo test -p graphforge-storage --features test-failpoints --lib
project_recovery::tests::injected_operation_errors_report_exact_commit_state
--no-fail-fast -- --exact --nocapture

- name: Run macOS commit-lock cloned-descriptor test
run: >-
cargo test -p graphforge-storage --lib
project_publication::tests::commit_lock_guard_unlocks_before_a_cloned_descriptor_closes
--no-fail-fast -- --exact --nocapture

- name: Run macOS checkpoint-lock cloned-descriptor test
run: >-
cargo test -p graphforge-storage --lib
project_checkpoints::tests::checkpoint_read_guard_unlocks_before_a_cloned_descriptor_closes
--no-fail-fast -- --exact --nocapture

bazel-bootstrap:
# Job display name kept for continuity; this is the authoritative Rust
# compile/test path under CI Gate after #4 cutover.
Expand Down
22 changes: 0 additions & 22 deletions crates/graphforge-api/src/durability_certification_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@
use graphforge_storage::project_certification::{
CERT_CONTRACT, CERT_SEED, WRITE_SKEW_CLASSIFICATION, evidence_summary, run_certification_suite,
};
use graphforge_storage::project_fault_oracle::{
AuthorityClass, PublicationPhase, native_shared_boundary_authority,
};

#[test]
fn seeded_certification_suite_is_clean_at_required_budget() {
Expand All @@ -37,25 +34,6 @@ fn seeded_certification_suite_is_clean_at_required_budget() {
assert!(!rendered.contains("universal filesystem"));
}

#[test]
fn native_shared_boundaries_agree_with_oracle_authority() {
for phase in [
PublicationPhase::BeforeCurrentReplace,
PublicationPhase::AfterCurrentReplace,
PublicationPhase::AfterRootFsync,
] {
let native = native_shared_boundary_authority(phase);
let expected = match phase {
PublicationPhase::BeforeCurrentReplace => AuthorityClass::PriorGeneration,
PublicationPhase::AfterCurrentReplace | PublicationPhase::AfterRootFsync => {
AuthorityClass::NewGeneration
}
_ => unreachable!(),
};
assert_eq!(native, expected, "phase={phase:?}");
}
}

#[test]
fn write_skew_classification_remains_honest() {
assert_eq!(WRITE_SKEW_CLASSIFICATION, "allowed_documented_not_ssi");
Expand Down
25 changes: 25 additions & 0 deletions crates/graphforge-storage/src/filesystem_admission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2411,4 +2411,29 @@ mod tests {
assert_eq!(std::fs::read_dir(parent.path()).unwrap().count(), 0);
filesystem_durability_preflight(&target).unwrap();
}

#[test]
fn admitted_filesystem_class_selects_the_matching_fault_oracle_profile() {
let parent = canonical_tempdir();
let target = parent.path().join("project");
let evidence = filesystem_durability_preflight(&target).unwrap();
let profile =
crate::project_fault_oracle::DurabilityProfile::for_admitted_filesystem_class(
&evidence.filesystem_class,
)
.expect("every admitted durable filesystem has oracle semantics");
let outcomes =
crate::project_fault_oracle::simulate_all_phases_for_profile(0x749a, profile)
.expect("admission profile phase sweep");
assert_eq!(
outcomes.len(),
crate::project_fault_oracle::PublicationPhase::all().len()
);
assert!(outcomes.iter().all(|outcome| {
outcome.actual == outcome.expected
&& outcome.actual != crate::project_fault_oracle::AuthorityClass::Unexpected
&& (!outcome.acknowledged
|| outcome.actual == crate::project_fault_oracle::AuthorityClass::NewGeneration)
}));
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
}
18 changes: 1 addition & 17 deletions crates/graphforge-storage/src/project_certification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ use sha2::{Digest, Sha256};

use crate::project_fault_oracle::{
AuthorityClass, PublicationPhase, default_durable_ids, expected_authority, history_budget,
minimize_durable_ids, native_shared_boundary_authority, publication_ops, simulate_crash,
simulate_torn_bytes,
minimize_durable_ids, publication_ops, simulate_crash, simulate_torn_bytes,
Comment thread
coderabbitai[bot] marked this conversation as resolved.
};

/// Contract id frozen with the certification evidence schema.
Expand Down Expand Up @@ -567,21 +566,6 @@ fn apply_op(model: &mut ReferenceModel, seed: u64, op: &HistoryOp) -> Result<(),
actual: authority_label(report.actual).into(),
});
}
// Native process-kill boundary must agree with the oracle at shared phases.
if matches!(
*phase,
PublicationPhase::BeforeCurrentReplace
| PublicationPhase::AfterCurrentReplace
| PublicationPhase::AfterRootFsync
) {
let native = native_shared_boundary_authority(*phase);
if native != report.expected {
return Err(CertInvariant::AuthorityMismatch {
expected: authority_label(report.expected).into(),
actual: format!("native:{}", authority_label(native)),
});
}
}
if !phase.is_linearized() && report.actual == AuthorityClass::NewGeneration {
return Err(CertInvariant::PreAckAtomicityBroken);
}
Expand Down
Loading