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: 6 additions & 6 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ only the policy, language, and binding jobs relevant to the pull request.
**Speed is a first-class value alongside honesty.** Surfaces shed work that is
not required for their objective. PR CI does **not** run full `llvm-cov`.
Frequent publishing uses the **publish-track** (Binding RC → tag →
`publish.yaml` on retained bytes). M1 load, checkpoint, and m20/m21 remain
`publish.yaml` on retained bytes). release-load, checkpoint, and knowledge/epistemic remain
**human-close / milestone** evidence and are not publish-track blockers.
Wall-clock targets and the dual-track table live in
[`docs/engineering/TESTING.md`](../../docs/engineering/TESTING.md).
Expand All @@ -19,7 +19,7 @@ Bazel CI Gate cutover (#4), Test Suite no longer mounts job-isolated Cargo
`target/` sticky disks; authoritative Rust compile/test is Bazel under
`Bazel Bootstrap` (`//:ci_rust_tests`). Registry and pnpm dependencies still use
the colocated cache through upstream `actions/cache@v6` and `actions/setup-node`.
Binding RC and the M1 host-native release load matrix retain sticky `target/`
Binding RC and the release-certification host-native release load matrix retain sticky `target/`
volumes so maturin, Cargo, and napi share one build volume for packaging lanes
(see storage policy tests); put `target/` on sticky disks there, not in
`actions/cache` blobs.
Expand Down Expand Up @@ -187,7 +187,7 @@ reports without rebuilding the same surfaces on every pull request. Green runs
are not close criteria for child or construction issues that already met their
acceptance criteria on ordinary CI.

### `m1-release-certification.yml`
### `release-certification.yml`

A maintainer manually dispatches this **release-certification** workflow with
the exact current `main` SHA and the successful Rust-surface and Binding RC run
Expand All @@ -197,7 +197,7 @@ duplicate, or expired component artifacts before any native build. One Linux
release-machine job then builds one same-SHA Rust probe, Python wheel, and Node
addon and executes the existing 144-case XS-XL matrix. The final job revalidates
the Rust, binding, and load ledgers and uploads one
`M1-Release-Certification-<sha>` artifact. The workflow is manual-only,
`release-certification-Release-Certification-<sha>` artifact. The workflow is manual-only,
non-publishing, and cancels an obsolete duplicate dispatch for the same SHA.

The required Rust + Binding RC run IDs are an input contract for this workflow
Expand All @@ -215,8 +215,8 @@ retained candidate; ordinary PRs do not repeat that certification.
same-SHA Binding RC → tag / release identity → `publish.yaml` writes retained
bytes only. Skip re-RC when a complete unexpired candidate for the current
`main` tip already exists. Target wall-clock: Binding RC ≤20m p50 warm /
≤35m cold; publish-track ≤35m p50 / ≤50m cold (see TESTING.md). M1,
checkpoint, and m20/m21 are **not** required on this path.
≤35m cold; publish-track ≤35m p50 / ≤50m cold (see TESTING.md). release-certification,
checkpoint, and knowledge/epistemic are **not** required on this path.

`publish-track.yml` schedules exact-main Binding RC dispatch every six hours.
It reassembles and validates every retained partition before deciding a
Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/binding-release-candidate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -516,13 +516,13 @@ jobs:
- name: Retain aggregate publication evidence
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: M1-Binding-Release-Candidate-${{ needs.validate_source.outputs.evidence_sha }}
name: Binding-Release-Candidate-${{ needs.validate_source.outputs.evidence_sha }}
path: binding-rc-aggregate/report.json
if-no-files-found: error
retention-days: 30

release_candidate:
name: Assemble immutable M1 release candidate
name: Assemble immutable release candidate
needs: [validate_source, aggregate]
runs-on: blacksmith-4vcpu-ubuntu-2404
timeout-minutes: 90
Expand Down Expand Up @@ -709,7 +709,7 @@ jobs:
--dist-dir candidate/release-artifacts \
--out candidate/rehearsal-manifest.json \
--recorded-at "$recorded_at" \
--notes "M1 Binding Release Candidate run $GITHUB_RUN_ID; exact SHA $EVIDENCE_SHA"
--notes "Binding Release Candidate run $GITHUB_RUN_ID; exact SHA $EVIDENCE_SHA"

- name: Rehearse exact partitioned release artifacts offline
run: |
Expand All @@ -729,7 +729,7 @@ jobs:
--dist-dir candidate/release-artifacts \
--out "candidate/v${RELEASE_VERSION}-artifacts.json" \
--recorded-at "$CANDIDATE_RECORDED_AT" \
--notes "M1 Binding Release Candidate run $GITHUB_RUN_ID; exact SHA $EVIDENCE_SHA"
--notes "Binding Release Candidate run $GITHUB_RUN_ID; exact SHA $EVIDENCE_SHA"
python3 scripts/ci/clean-env-verify.py validate-release-record \
"candidate/v${RELEASE_VERSION}-artifacts.json"
python3 scripts/ci/release-candidate.py validate \
Expand All @@ -741,39 +741,39 @@ jobs:
- name: Retain the candidate manifest for publication
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: M1-Release-Candidate-manifest-${{ needs.validate_source.outputs.evidence_sha }}
name: Release-Candidate-manifest-${{ needs.validate_source.outputs.evidence_sha }}
path: candidate/v${{ env.RELEASE_VERSION }}-artifacts.json
if-no-files-found: error
retention-days: 30

- name: Retain the Python candidate partition
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: M1-Release-Candidate-python-${{ needs.validate_source.outputs.evidence_sha }}
name: Release-Candidate-python-${{ needs.validate_source.outputs.evidence_sha }}
path: candidate/release-artifacts/python/
if-no-files-found: error
retention-days: 30

- name: Retain the npm candidate partition
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: M1-Release-Candidate-npm-${{ needs.validate_source.outputs.evidence_sha }}
name: Release-Candidate-npm-${{ needs.validate_source.outputs.evidence_sha }}
path: candidate/release-artifacts/npm/
if-no-files-found: error
retention-days: 30

- name: Retain the crates candidate partition
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: M1-Release-Candidate-crates-${{ needs.validate_source.outputs.evidence_sha }}
name: Release-Candidate-crates-${{ needs.validate_source.outputs.evidence_sha }}
path: candidate/release-artifacts/crates/
if-no-files-found: error
retention-days: 30

- name: Retain the evidence candidate partition
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: M1-Release-Candidate-evidence-${{ needs.validate_source.outputs.evidence_sha }}
name: Release-Candidate-evidence-${{ needs.validate_source.outputs.evidence_sha }}
# upload-artifact does not expand bash brace globs; list both dirs.
path: |
candidate/release-artifacts/evidence/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: M21 Contract Gate
name: Epistemic Contract Gate

on:
workflow_dispatch:
Expand All @@ -20,13 +20,13 @@ jobs:
with:
toolchain: "1.96.0"
- name: Execute Rust matrix group
run: python3 scripts/ci/m21-contract-gate.py run-group --group rust --output gate-fragments
run: python3 scripts/ci/epistemic-contract-gate.py run-group --group rust --output gate-fragments
- name: Save Rust evidence for report job
if: always()
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: gate-fragments/
key: m21-transfer-${{ github.run_id }}-rust
key: epistemic-transfer-${{ github.run_id }}-rust

python:
name: Python contract rows
Expand All @@ -41,13 +41,13 @@ jobs:
with:
python-version: "3.13"
- name: Execute Python matrix group
run: python3 scripts/ci/m21-contract-gate.py run-group --group python --output gate-fragments
run: python3 scripts/ci/epistemic-contract-gate.py run-group --group python --output gate-fragments
- name: Save Python evidence for report job
if: always()
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: gate-fragments/
key: m21-transfer-${{ github.run_id }}-python
key: epistemic-transfer-${{ github.run_id }}-python

node:
name: Node contract rows
Expand All @@ -66,40 +66,39 @@ jobs:
with:
toolchain: "1.96.0"
- name: Execute Node matrix group
run: python3 scripts/ci/m21-contract-gate.py run-group --group node --output gate-fragments
run: python3 scripts/ci/epistemic-contract-gate.py run-group --group node --output gate-fragments
- name: Save Node evidence for report job
if: always()
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: gate-fragments/
key: m21-transfer-${{ github.run_id }}-node
key: epistemic-transfer-${{ github.run_id }}-node

report:
name: SHA-bound closure report
if: always()
needs: [rust, python, node]
runs-on: blacksmith-4vcpu-ubuntu-2404
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: gate-fragments
key: m21-transfer-${{ github.run_id }}-rust
key: epistemic-transfer-${{ github.run_id }}-rust
fail-on-cache-miss: true
- uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: gate-fragments
key: m21-transfer-${{ github.run_id }}-python
key: epistemic-transfer-${{ github.run_id }}-python
fail-on-cache-miss: true
- uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: gate-fragments
key: m21-transfer-${{ github.run_id }}-node
key: epistemic-transfer-${{ github.run_id }}-node
fail-on-cache-miss: true
- name: Build exact closure report
run: >-
python3 scripts/ci/m21-contract-gate.py report
python3 scripts/ci/epistemic-contract-gate.py report
--sha "${{ github.sha }}"
--fragments gate-fragments
--output gate-report
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: M20 Contract Gate
name: Knowledge Contract Gate

on:
workflow_dispatch:
Expand All @@ -20,13 +20,13 @@ jobs:
with:
toolchain: "1.96.0"
- name: Execute Rust matrix group
run: python3 scripts/ci/m20-contract-gate.py run-group --group rust --output gate-fragments
run: python3 scripts/ci/knowledge-contract-gate.py run-group --group rust --output gate-fragments
- name: Save Rust evidence for report job
if: always()
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: gate-fragments/
key: m20-transfer-${{ github.run_id }}-rust
key: knowledge-transfer-${{ github.run_id }}-rust

python:
name: Python contract rows
Expand All @@ -41,13 +41,13 @@ jobs:
with:
python-version: "3.13"
- name: Execute Python matrix group
run: python3 scripts/ci/m20-contract-gate.py run-group --group python --output gate-fragments
run: python3 scripts/ci/knowledge-contract-gate.py run-group --group python --output gate-fragments
- name: Save Python evidence for report job
if: always()
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: gate-fragments/
key: m20-transfer-${{ github.run_id }}-python
key: knowledge-transfer-${{ github.run_id }}-python

node:
name: Node contract rows
Expand All @@ -66,40 +66,39 @@ jobs:
with:
toolchain: "1.96.0"
- name: Execute Node matrix group
run: python3 scripts/ci/m20-contract-gate.py run-group --group node --output gate-fragments
run: python3 scripts/ci/knowledge-contract-gate.py run-group --group node --output gate-fragments
- name: Save Node evidence for report job
if: always()
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: gate-fragments/
key: m20-transfer-${{ github.run_id }}-node
key: knowledge-transfer-${{ github.run_id }}-node

report:
name: SHA-bound closure report
if: always()
needs: [rust, python, node]
runs-on: blacksmith-4vcpu-ubuntu-2404
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: gate-fragments
key: m20-transfer-${{ github.run_id }}-rust
key: knowledge-transfer-${{ github.run_id }}-rust
fail-on-cache-miss: true
- uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: gate-fragments
key: m20-transfer-${{ github.run_id }}-python
key: knowledge-transfer-${{ github.run_id }}-python
fail-on-cache-miss: true
- uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: gate-fragments
key: m20-transfer-${{ github.run_id }}-node
key: knowledge-transfer-${{ github.run_id }}-node
fail-on-cache-miss: true
- name: Build exact closure report
run: >-
python3 scripts/ci/m20-contract-gate.py report
python3 scripts/ci/knowledge-contract-gate.py report
--sha "${{ github.sha }}"
--fragments gate-fragments
--output gate-report
30 changes: 15 additions & 15 deletions .github/workflows/non-cypher-surface-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ jobs:
cargo test -p graphforge-api \
--test knowledge_isolation \
--test public_lifecycle_conformance \
--test m22_m18_public_surface \
--test m22_m19_public_surface \
--test m22_provider_public_surface \
--test algorithm_public_surface \
--test search_public_surface \
--test provider_public_surface \
--test provider_session \
--test public_facade_remaining_conformance \
--no-fail-fast
Expand All @@ -70,9 +70,9 @@ jobs:
test_names = [
"knowledge_isolation",
"public_lifecycle_conformance",
"m22_m18_public_surface",
"m22_m19_public_surface",
"m22_provider_public_surface",
"algorithm_public_surface",
"search_public_surface",
"provider_public_surface",
"provider_session",
"public_facade_remaining_conformance",
]
Expand All @@ -99,22 +99,22 @@ jobs:
"duration_scope": "complete_required_suite",
"error_code": None,
})
m18 = manifest["m18_registry"]["release-tested"]
for identity in m18["ids"]:
algorithm = manifest["algorithm_registry"]["release-tested"]
for identity in algorithm["ids"]:
evidence.append({
"kind": "m18_registry",
"kind": "algorithm_registry",
"identity": identity,
"test_ids": [ref["symbol"] for ref in m18["test_refs"]],
"test_ids": [ref["symbol"] for ref in algorithm["test_refs"]],
"outcome": "passed",
"duration_seconds": duration,
"duration_scope": "complete_required_suite",
"error_code": None,
})
for group_name, group in manifest["m19_evidence_groups"].items():
for group_name, group in manifest["search_evidence_groups"].items():
test_ids = [ref["symbol"] for ref in group["test_refs"]]
for identity in group["ids"]:
evidence.append({
"kind": "m19_contracts",
"kind": "search_contracts",
"identity": identity,
"evidence_group": group_name,
"test_ids": test_ids,
Expand All @@ -133,18 +133,18 @@ jobs:
"evidence": evidence,
"commands": [
"cargo test -p graphforge-api --lib --no-fail-fast",
"cargo test -p graphforge-api --test knowledge_isolation --test public_lifecycle_conformance --test public_facade_remaining_conformance --test m22_m18_public_surface --test m22_m19_public_surface --test m22_provider_public_surface --test provider_session --no-fail-fast",
"cargo test -p graphforge-api --test knowledge_isolation --test public_lifecycle_conformance --test public_facade_remaining_conformance --test algorithm_public_surface --test search_public_surface --test provider_public_surface --test provider_session --no-fail-fast",
],
}
Path("non-cypher-evidence/report.json").write_text(
json.dumps(report, indent=2, sort_keys=True) + "\n", encoding="utf-8"
)
PY

- name: Retain Rust report for M1 certification
- name: Retain Rust report for release certification
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: M1-Rust-Non-Cypher-${{ env.EVIDENCE_SHA }}
name: Rust-Non-Cypher-${{ env.EVIDENCE_SHA }}
path: non-cypher-evidence/
if-no-files-found: error
retention-days: 30
Loading