Skip to content

Commit c496480

Browse files
Require durable writes and verified release qualification (#217)
* Require durable writes and candidate-bound release qualification * test: keep first MCP tool session open until response * ci: name candidate SBOM from package version * Integrate bounded Galaxy motion and compatible release dependencies * fix: close PR 217 isolation startup and diagnostics gaps
1 parent cd71929 commit c496480

66 files changed

Lines changed: 6658 additions & 1089 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/dependabot.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ updates:
55
schedule:
66
interval: "weekly"
77
open-pull-requests-limit: 5
8+
# MCP 2 changes the server API; migrate and qualify it separately.
9+
ignore:
10+
- dependency-name: "mcp"
11+
update-types: ["version-update:semver-major"]
812
labels:
913
- "dependencies"
1014
- package-ecosystem: "npm"

‎.github/workflows/ci.yml‎

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,3 +389,68 @@ jobs:
389389
AUDIT_SITE=$(.audit-venv/bin/python -c "import site; print(site.getsitepackages()[0])")
390390
python -m pip_audit --path "$AUDIT_SITE"
391391
.audit-venv/bin/python -c "import engraphis, eval.harness; print('wheel imports OK')"
392+
393+
installed-journeys:
394+
name: Installed journey (${{ matrix.os }}, ${{ matrix.profile }})
395+
runs-on: ${{ matrix.os }}
396+
timeout-minutes: 25
397+
strategy:
398+
fail-fast: false
399+
matrix:
400+
os: [ubuntu-latest, windows-latest, macos-latest]
401+
profile: [mcp, server]
402+
env:
403+
PIP_CONSTRAINT: ${{ github.workspace }}/.github/release-constraints.txt
404+
PIP_BUILD_CONSTRAINT: ${{ github.workspace }}/.github/release-constraints.txt
405+
steps:
406+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
407+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
408+
with:
409+
python-version: "3.11"
410+
- name: Build the candidate wheel
411+
run: |
412+
python -m pip install build==1.5.0
413+
python -m build --wheel --outdir dist
414+
- name: Exercise a clean installed product outside the checkout
415+
env:
416+
ENGRAPHIS_SMOKE_PROFILE: ${{ matrix.profile }}
417+
shell: python
418+
run: |
419+
import hashlib
420+
import json
421+
import os
422+
from pathlib import Path
423+
import subprocess
424+
import sys
425+
426+
root = Path(os.environ["RUNNER_TEMP"]) / "installed-candidate"
427+
root.mkdir()
428+
environment = root / "venv"
429+
subprocess.run([sys.executable, "-m", "venv", str(environment)], check=True)
430+
executable = environment / ("Scripts/python.exe" if os.name == "nt" else "bin/python")
431+
wheels = list(Path("dist").glob("*.whl"))
432+
assert len(wheels) == 1
433+
profile = os.environ["ENGRAPHIS_SMOKE_PROFILE"]
434+
subprocess.run([str(executable), "-m", "pip", "install",
435+
str(wheels[0].resolve()) + f"[{profile}]"], check=True)
436+
subprocess.run([str(executable), "-m", "pip", "check"], check=True)
437+
(root / "environment.lock").write_text(subprocess.check_output(
438+
[str(executable), "-m", "pip", "freeze", "--all"], text=True), encoding="utf-8")
439+
(root / "artifact.json").write_text(json.dumps({
440+
"commit": os.environ["GITHUB_SHA"], "profile": profile,
441+
"wheel": wheels[0].name,
442+
"sha256": hashlib.sha256(wheels[0].read_bytes()).hexdigest(),
443+
}), encoding="utf-8")
444+
subprocess.run([str(executable), "-m", "scripts.smoke_installed_product",
445+
"--surface", profile, "--output", str(root / "journey.json")],
446+
cwd=root, check=True)
447+
- name: Preserve installed journey evidence
448+
if: always()
449+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
450+
with:
451+
name: candidate-journey-${{ matrix.os }}-${{ matrix.profile }}
452+
path: |
453+
${{ runner.temp }}/installed-candidate/journey.json
454+
${{ runner.temp }}/installed-candidate/environment.lock
455+
${{ runner.temp }}/installed-candidate/artifact.json
456+
if-no-files-found: warn

‎.github/workflows/release.yml‎

Lines changed: 109 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,10 @@ jobs:
8383
mkdir build-environment-evidence
8484
python -m pip list --format=freeze \
8585
| LC_ALL=C sort -f > build-environment-evidence/environment.lock
86+
package_version="$(python -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])')"
8687
cyclonedx-py environment --output-reproducible --of JSON \
8788
--pyproject pyproject.toml \
88-
-o build-environment-evidence/engraphis-${GITHUB_REF_NAME#v}.cdx.json
89+
-o "build-environment-evidence/engraphis-${package_version}.cdx.json"
8990
9091
- name: Build source and universal wheel distributions
9192
shell: bash
@@ -370,16 +371,18 @@ jobs:
370371
371372
372373
installed-artifact-platform-smoke:
373-
name: Installed wheel smoke (${{ matrix.os }})
374+
name: Installed wheel journey (${{ matrix.os }}, ${{ matrix.profile }})
374375
needs: build
375376
runs-on: ${{ matrix.os }}
377+
timeout-minutes: 25
376378
if: >-
377379
github.event_name == 'push' ||
378380
inputs.release_tag == ''
379381
strategy:
380382
fail-fast: false
381383
matrix:
382-
os: [windows-latest, macos-latest]
384+
os: [ubuntu-latest, windows-latest, macos-latest]
385+
profile: [base, mcp, server]
383386
env:
384387
PIP_CONSTRAINT: ${{ github.workspace }}/.github/release-constraints.txt
385388
PIP_BUILD_CONSTRAINT: ${{ github.workspace }}/.github/release-constraints.txt
@@ -393,11 +396,15 @@ jobs:
393396
with:
394397
name: python-package-distributions
395398
path: dist/
396-
- name: Install and smoke the downloaded wheel on Windows and macOS
399+
- name: Install and exercise the downloaded wheel on supported platforms
400+
env:
401+
ENGRAPHIS_SMOKE_PROFILE: ${{ matrix.profile }}
397402
shell: bash
398403
run: |
399404
set -euo pipefail
400405
python - <<'PY'
406+
import hashlib
407+
import json
401408
import os
402409
from pathlib import Path
403410
import subprocess
@@ -408,9 +415,11 @@ jobs:
408415
executable = environment / ("Scripts/python.exe" if os.name == "nt" else "bin/python")
409416
wheels = list(Path("dist").glob("*.whl"))
410417
assert len(wheels) == 1
418+
profile = os.environ["ENGRAPHIS_SMOKE_PROFILE"]
419+
requirement = str(wheels[0].resolve()) + ("" if profile == "base" else f"[{profile}]")
411420
subprocess.run(
412421
[str(executable), "-m", "pip", "install", "--disable-pip-version-check",
413-
str(wheels[0].resolve())],
422+
requirement],
414423
check=True,
415424
)
416425
subprocess.run([str(executable), "-m", "pip", "check"], check=True)
@@ -419,7 +428,32 @@ jobs:
419428
cwd=os.environ["RUNNER_TEMP"],
420429
check=True,
421430
)
431+
if profile != "base":
432+
evidence = Path(os.environ["RUNNER_TEMP"])
433+
(evidence / "installed-environment.lock").write_text(subprocess.check_output(
434+
[str(executable), "-m", "pip", "freeze", "--all"], text=True,
435+
), encoding="utf-8")
436+
(evidence / "installed-artifact.json").write_text(json.dumps({
437+
"profile": profile, "wheel": wheels[0].name,
438+
"wheel_sha256": hashlib.sha256(wheels[0].read_bytes()).hexdigest(),
439+
}), encoding="utf-8")
440+
subprocess.run(
441+
[str(executable), "-m", "scripts.smoke_installed_product", "--surface", profile,
442+
"--output", str(Path(os.environ["RUNNER_TEMP"]) / "installed-journey.json")],
443+
cwd=os.environ["RUNNER_TEMP"],
444+
check=True,
445+
)
422446
PY
447+
- name: Retain installed journey evidence
448+
if: matrix.profile != 'base'
449+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
450+
with:
451+
name: installed-journey-${{ matrix.os }}-${{ matrix.profile }}
452+
path: |
453+
${{ runner.temp }}/installed-journey.json
454+
${{ runner.temp }}/installed-environment.lock
455+
${{ runner.temp }}/installed-artifact.json
456+
if-no-files-found: error
423457

424458
encryption:
425459
name: Encryption driver release gate (Python ${{ matrix.python-version }})
@@ -732,6 +766,11 @@ jobs:
732766
with:
733767
name: independent-reproducibility
734768
path: release-evidence/
769+
- name: Download complete installed journey evidence
770+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
771+
with:
772+
pattern: installed-journey-*
773+
path: installed-journey-inputs/
735774
- name: Generate evidence from captured release artifacts
736775
shell: bash
737776
run: |
@@ -745,6 +784,7 @@ jobs:
745784
--image-digest "$(tr -d '\r\n' < release-evidence/image.digest)" \
746785
--image-scan release-evidence/grype.json \
747786
--reproducibility release-evidence/reproducibility.json \
787+
--installed-journeys installed-journey-inputs \
748788
--verified-check ruff \
749789
--verified-check pyright-core-backends \
750790
--verified-check codeql \
@@ -777,6 +817,7 @@ jobs:
777817
publish:
778818
name: Publish to PyPI
779819
needs: release-evidence
820+
environment: release-qualification
780821
# Manual dispatch is intentionally build/check-only. Publication requires a pushed
781822
# semver tag, whose value was matched to pyproject.toml in the build job above.
782823
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
@@ -811,6 +852,19 @@ jobs:
811852
mkdir verified-dist
812853
cp dist/*.whl dist/*.tar.gz verified-dist/
813854
855+
- name: Require signed full-product qualification before PyPI publication
856+
env:
857+
ENGRAPHIS_RELEASE_QUALIFICATION: ${{ vars.ENGRAPHIS_RELEASE_QUALIFICATION }}
858+
ENGRAPHIS_RELEASE_VERIFY_KEY: ${{ vars.ENGRAPHIS_RELEASE_VERIFY_KEY }}
859+
ENGRAPHIS_RELEASE_CANDIDATE_ID: ${{ vars.ENGRAPHIS_RELEASE_CANDIDATE_ID }}
860+
ENGRAPHIS_RELEASE_LEDGER_SHA256: ${{ vars.ENGRAPHIS_RELEASE_LEDGER_SHA256 }}
861+
shell: bash
862+
run: |
863+
set -euo pipefail
864+
python -m pip install --disable-pip-version-check "cryptography==50.0.0"
865+
python -m scripts.verify_release_qualification --dist dist \
866+
--commit "$GITHUB_SHA" --tag "$GITHUB_REF_NAME"
867+
814868
- name: Publish distributions to PyPI
815869
uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # v1.14.1
816870
with:
@@ -825,12 +879,17 @@ jobs:
825879
github-release:
826880
name: Publish GitHub Release
827881
needs: publish
882+
environment: release-qualification
828883
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
829884
runs-on: ubuntu-latest
830885
permissions:
831886
contents: write
832887

833888
steps:
889+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
890+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
891+
with:
892+
python-version: "3.11"
834893
- name: Download distributions
835894
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
836895
with:
@@ -843,6 +902,19 @@ jobs:
843902
name: public-release-evidence
844903
path: release-evidence/
845904

905+
- name: Require signed full-product qualification before GitHub publication
906+
env:
907+
ENGRAPHIS_RELEASE_QUALIFICATION: ${{ vars.ENGRAPHIS_RELEASE_QUALIFICATION }}
908+
ENGRAPHIS_RELEASE_VERIFY_KEY: ${{ vars.ENGRAPHIS_RELEASE_VERIFY_KEY }}
909+
ENGRAPHIS_RELEASE_CANDIDATE_ID: ${{ vars.ENGRAPHIS_RELEASE_CANDIDATE_ID }}
910+
ENGRAPHIS_RELEASE_LEDGER_SHA256: ${{ vars.ENGRAPHIS_RELEASE_LEDGER_SHA256 }}
911+
shell: bash
912+
run: |
913+
set -euo pipefail
914+
python -m pip install --disable-pip-version-check "cryptography==50.0.0"
915+
python -m scripts.verify_release_qualification --dist dist \
916+
--commit "$GITHUB_SHA" --tag "$GITHUB_REF_NAME"
917+
846918
- name: Create GitHub Release
847919
env:
848920
GH_TOKEN: ${{ github.token }}
@@ -867,6 +939,7 @@ jobs:
867939
868940
github-release-repair:
869941
name: Repair GitHub Release
942+
environment: release-qualification
870943
if: >-
871944
github.event_name == 'workflow_dispatch' &&
872945
github.ref == 'refs/heads/main' &&
@@ -962,6 +1035,7 @@ jobs:
9621035
import json
9631036
import sys
9641037
from pathlib import Path
1038+
from scripts.release_evidence import installed_bundle_records
9651039
9661040
tag, commit = sys.argv[1:]
9671041
evidence_root = Path("candidate-evidence")
@@ -991,6 +1065,8 @@ jobs:
9911065
evidence["container"]["sbom"],
9921066
evidence["container"]["vulnerability_scan"],
9931067
]
1068+
if "installed_journeys" in evidence:
1069+
records.extend(installed_bundle_records(evidence["installed_journeys"], actual))
9941070
for record in records:
9951071
path = evidence_root / Path(record["path"]).name
9961072
assert path.is_file()
@@ -1004,6 +1080,7 @@ jobs:
10041080
fi
10051081
done < "$RUNNER_TEMP/release-run-candidates"
10061082
test -n "$selected_run"
1083+
printf 'ENGRAPHIS_REPAIR_COMMIT=%s\n' "$tag_sha" >> "$GITHUB_ENV"
10071084
10081085
- name: Verify any previously published subset
10091086
env:
@@ -1021,6 +1098,20 @@ jobs:
10211098
mkdir verified-dist
10221099
cp dist/*.whl dist/*.tar.gz verified-dist/
10231100
1101+
- name: Require signed full-product qualification before PyPI repair
1102+
env:
1103+
RELEASE_TAG: ${{ inputs.release_tag }}
1104+
ENGRAPHIS_RELEASE_QUALIFICATION: ${{ vars.ENGRAPHIS_RELEASE_QUALIFICATION }}
1105+
ENGRAPHIS_RELEASE_VERIFY_KEY: ${{ vars.ENGRAPHIS_RELEASE_VERIFY_KEY }}
1106+
ENGRAPHIS_RELEASE_CANDIDATE_ID: ${{ vars.ENGRAPHIS_RELEASE_CANDIDATE_ID }}
1107+
ENGRAPHIS_RELEASE_LEDGER_SHA256: ${{ vars.ENGRAPHIS_RELEASE_LEDGER_SHA256 }}
1108+
shell: bash
1109+
run: |
1110+
set -euo pipefail
1111+
python -m pip install --disable-pip-version-check "cryptography==50.0.0"
1112+
python -m scripts.verify_release_qualification --dist dist \
1113+
--commit "$ENGRAPHIS_REPAIR_COMMIT" --tag "$RELEASE_TAG"
1114+
10241115
- name: Publish only missing verified distributions
10251116
uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # v1.14.1
10261117
with:
@@ -1034,6 +1125,19 @@ jobs:
10341125
python scripts/verify_release_artifacts.py --dist verified-dist
10351126
--version "${RELEASE_TAG#v}" --retries 18 --delay 10
10361127
1128+
- name: Require signed full-product qualification before GitHub repair
1129+
env:
1130+
RELEASE_TAG: ${{ inputs.release_tag }}
1131+
ENGRAPHIS_RELEASE_QUALIFICATION: ${{ vars.ENGRAPHIS_RELEASE_QUALIFICATION }}
1132+
ENGRAPHIS_RELEASE_VERIFY_KEY: ${{ vars.ENGRAPHIS_RELEASE_VERIFY_KEY }}
1133+
ENGRAPHIS_RELEASE_CANDIDATE_ID: ${{ vars.ENGRAPHIS_RELEASE_CANDIDATE_ID }}
1134+
ENGRAPHIS_RELEASE_LEDGER_SHA256: ${{ vars.ENGRAPHIS_RELEASE_LEDGER_SHA256 }}
1135+
shell: bash
1136+
run: |
1137+
set -euo pipefail
1138+
python -m scripts.verify_release_qualification --dist verified-dist \
1139+
--commit "$ENGRAPHIS_REPAIR_COMMIT" --tag "$RELEASE_TAG"
1140+
10371141
- name: Repair GitHub Release
10381142
env:
10391143
GH_TOKEN: ${{ github.token }}

‎BENCHMARKS.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ For the locked operator sequence for a public canonical run, see
99
### Public numeric evidence registry
1010

1111
Every exact public aggregate retained below comes from the checked-in, public-safe
12-
[`offline-fixtures-v1.json`](docs/benchmark-evidence/offline-fixtures-v1.json) artifact. Its
12+
[`offline-fixtures-v3.json`](docs/benchmark-evidence/offline-fixtures-v3.json) artifact. Its
1313
SHA-256 is
14-
`4d5056d137182ae5cf116c5d59af18b38a7a0ed7731885e9597f63e549cb46b7`, also recorded in the
14+
`2d6b4fab9e75edc91d105d49877f9225f28ffe4d366e40a44e931f19cb13f498`, also recorded in the
1515
adjacent `.sha256` file. The artifact contains no raw questions, answers, prompts, customer data,
1616
or per-record content fingerprints.
1717

1818
The fixture-suite digest is
19-
`f5544b56f009b2fc16dbae992039971899daf2b0095ee8d15bad5914c7f399a9`. The artifact defines
19+
`95c233e3fb79a1618bf40f0daefb36d3d1772b1f332d281d6f4c5d6cc902455b`. The artifact defines
2020
the digest algorithm and records the SHA-256 of every suite and dataset file. Each evidence ID
2121
also binds its exact command through `sha256(UTF-8 exact command)`:
2222

‎CHANGELOG.md‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,21 @@ All notable changes to Engraphis are documented here. Format loosely follows
55

66
## [Unreleased]
77

8+
- Writable SQLite files now default to WAL plus FULL synchronization, with an explicit
9+
balanced option and effective-policy diagnostics. Disposable fault tests cover abrupt
10+
process exit and database-full rollback; hardware power loss remains unverified.
11+
- Consolidation recall batches evidence-visibility checks within the Store's 500-ID bound,
12+
preserving citations for larger digests under scope and temporal filters.
13+
- Pi resolves patched Hono while retaining MCP SDK compatibility below version 2.
14+
- Release verification exercises installed MCP and dashboard writes, restarts, corrections
15+
and history on Windows, macOS and Linux. Product-readiness receipts bind exact components,
16+
underlying evidence and independent release/leadership decisions.
17+
- Normal and repair publication require owner-signed qualification of the exact source,
18+
distributions and private ledger. Protected authority configuration is a release prerequisite;
19+
no signing authority or approval is created by installing this package.
20+
- Performance diagnostics accept pinned local models, real files and exact vector backends,
21+
and expose opt-in recall phase timings. Planner promotion now has an explicit failing CLI
22+
gate when its evaluation booleans are unmet; ranking defaults are unchanged.
823
- Added schema 18 content-free command receipts and cross-process source revalidation for
924
corrections, approvals, promotions and merges. Combined memory revisions have expected
1025
versions, operation IDs, atomic metadata/history, and typed conflicts.
@@ -21,6 +36,9 @@ All notable changes to Engraphis are documented here. Format loosely follows
2136
- Added content-free diagnostics and build/capability information, strict coding
2237
acceptance validation and a file-backed independent-process capacity harness.
2338
These provide measurement infrastructure, not verified 100k capacity claims.
39+
- Preload the optional `sentence-transformers` dependency before Windows stdio MCP
40+
accepts JSON-RPC, avoiding the observed native import/thread startup stall while
41+
preserving deterministic fallback and exact-backend policy.
2442

2543
## [1.7.3] - 2026-09-07
2644

0 commit comments

Comments
 (0)