Skip to content

Commit 76f91a3

Browse files
authored
Phase 2A: durable cases and bound C++ evidence (#6)
* feat(storage): add durable governed case store * feat(engine): admit bound C++ v1 evidence * docs: publish Phase 2A operator contract * fix(engine): accept checkout canonical remote * fix: preserve deterministic behavior on Windows
1 parent 0081a47 commit 76f91a3

33 files changed

Lines changed: 5735 additions & 136 deletions

.github/workflows/ci.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,50 @@ jobs:
9191
run: python -m scripts.inspect_packages --dist-dir dist
9292
- name: Verify runtime and CLI versions
9393
run: python -c "import quantforge, subprocess, sys; assert quantforge.__version__ == '0.1.0'; subprocess.run([sys.executable, '-m', 'quantforge', '--version'], check=True)"
94+
95+
cpp-v1-adapter:
96+
name: C++ v1.0.0 adapter / ${{ matrix.os }}
97+
runs-on: ${{ matrix.os }}
98+
timeout-minutes: 30
99+
strategy:
100+
fail-fast: false
101+
matrix:
102+
os: [ubuntu-24.04, macos-14]
103+
steps:
104+
- name: Check out exact QuantForge source
105+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
106+
with:
107+
path: quantforge-ai
108+
persist-credentials: false
109+
- name: Check out immutable C++ v1.0.0 source
110+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
111+
with:
112+
repository: MrithunjoyB/cpp-event-driven-backtester
113+
ref: v1.0.0
114+
fetch-depth: 0
115+
fetch-tags: true
116+
path: cpp-engine
117+
persist-credentials: false
118+
- name: Set up Python 3.12 with lock-bound cache
119+
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
120+
with:
121+
python-version: "3.12"
122+
cache: pip
123+
cache-dependency-path: quantforge-ai/requirements-dev.lock
124+
- name: Install the reviewed QuantForge development lock
125+
working-directory: quantforge-ai
126+
run: python -m pip install --require-hashes -r requirements-dev.lock
127+
- name: Build the immutable C++ release target
128+
working-directory: cpp-engine
129+
run: >-
130+
cmake -S . -B build
131+
-DCMAKE_BUILD_TYPE=Release
132+
-DQUANT_ENABLE_STRICT_WARNINGS=ON
133+
&& cmake --build build --parallel 2
134+
- name: Exercise the read-only release adapter twice
135+
working-directory: quantforge-ai
136+
run: python -m pytest -q tests/integration/test_cpp_v1_adapter.py
137+
env:
138+
QUANTFORGE_CPP_V1_EXECUTABLE: ${{ github.workspace }}/cpp-engine/build/quant_cli
139+
QUANTFORGE_CPP_V1_REPOSITORY: ${{ github.workspace }}/cpp-engine
140+
QUANTFORGE_CPP_V1_WORK_ROOT: ${{ runner.temp }}

CHANGELOG.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,27 @@ policy versions remain independently governed.
66

77
## [Unreleased]
88

9-
No changes recorded.
9+
### Added
10+
11+
- Add a backend-neutral durable case-store contract, crash-safe SQLite backend, forward-only
12+
checksummed migrations, historical fixture, deterministic reconstruction, and export lineage.
13+
- Add a read-only adapter for the exact protected C++ v1.0.0 public synthetic fixture and canonical
14+
engine-evidence bundles with optional fixture-only signing.
15+
- Add narrowly scoped store, migration, engine, evidence, reconstruction, and package CLI commands.
16+
- Add adversarial storage/bundle/process tests and Linux/macOS tagged-engine integration CI.
17+
18+
### Security
19+
20+
- Bind engine evidence to release, executable, invocation, configuration, inputs, complete outputs,
21+
validators, methodology, case, workflow revision, constitution, amendments, and bundle lineage.
22+
- Reject injection, stale writers, schema tampering, path/symlink attacks, substitution, malformed or
23+
non-finite output, process flooding, audit/graph drift, and post-finalization admission.
24+
25+
### Limitations
26+
27+
- The adapter is research-only, read-only, and limited to one public synthetic fixture. Live
28+
providers, market data, brokers, orders, live trading, investment advice, and profitability claims
29+
remain out of scope.
1030

1131
## [0.1.0] - 2026-07-15
1232

README.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ pure policy compute the strongest defensible verdict.
1313
> Most financial AI searches for strategies to believe. QuantForge searches for reasons not to
1414
> believe them.
1515
16-
This is the independently audited **Phase 1 governance foundation**, prepared as a local `v0.1.0`
17-
publication candidate. It is not an AI investment committee: roles may propose or explain, but
16+
This repository contains the independently audited **Phase 1 governance foundation** and the Phase
17+
2A durable local case store plus research-only C++ v1.0.0 evidence adapter. Version `v0.1.0` remains
18+
the immutable Phase 1 release; current Phase 2A work is unreleased. Roles may propose or explain, but
1819
code owns workflow state, evidence validity, human approval, and verdict strength.
1920

2021
After the locked development environment is installed, the exact offline demo command is:
@@ -27,9 +28,11 @@ The command uses packaged synthetic fixtures, performs no network request, and e
2728
case, evidence, claim-graph, manifest, and audit artifacts. Those artifacts are validation evidence
2829
for governance behavior—not financial evidence and not evidence of profitability.
2930
30-
Current limitations are deliberate: there is no live model provider, real OpenAI execution,
31-
market-data ingestion, real C++ engine integration, database, retrieval system, web UI, broker
32-
connectivity, order submission, live trading, production deployment, or investment advice.
31+
Phase 2A adds a schema-versioned SQLite backend, deterministic case packages, and one narrowly
32+
allow-listed, read-only adapter for the protected C++ `v1.0.0` public synthetic fixture. The C++
33+
release remains the numerical authority. There is no live OpenAI/provider integration, external
34+
market-data ingestion, retrieval system, web UI, broker connectivity, order submission, live
35+
trading, production deployment, investment advice, profitability claim, or guarantee.
3336
3437
## Install and verify offline behavior
3538
@@ -96,6 +99,13 @@ remains human-directed, reviewed, and maintained by Mrithunjoy Basumatary. AI sy
9699
project authors or copyright holders.
97100
98101
- [Architecture](docs/ARCHITECTURE.md)
102+
- [Storage model](docs/STORAGE_MODEL.md)
103+
- [Migration policy](docs/MIGRATION_POLICY.md)
104+
- [C++ engine integration contract](docs/ENGINE_INTEGRATION_CONTRACT.md)
105+
- [Evidence model](docs/EVIDENCE_MODEL.md)
106+
- [Deterministic semantics](docs/DETERMINISM.md)
107+
- [Operator runbook](docs/OPERATOR_RUNBOOK.md)
108+
- [Limitations](docs/LIMITATIONS.md)
99109
- [Governance](docs/GOVERNANCE.md)
100110
- [Security Model](docs/SECURITY_MODEL.md)
101111
- [Threat Model](docs/THREAT_MODEL.md)

docs/ARCHITECTURE.md

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,47 @@
11
# Architecture
22

3-
QuantForge Phase 1 is a deterministic domain application arranged as inward-facing layers:
3+
QuantForge is a deterministic, offline research tribunal arranged as inward-facing layers:
44

5-
1. `domain` owns immutable versioned contracts and constitution factories.
6-
2. `serialization` owns canonical JSON, SHA-256 identity, defensive parsing, and export.
7-
3. `evidence` owns the append-only ledger and typed claim graph.
8-
4. `audit` owns the single-case append-only hash chain, hashed payloads, and full state replay.
9-
5. `verdict` owns the pure conservative policy.
5+
1. `domain` owns immutable, versioned contracts and constitution factories.
6+
2. `serialization` owns canonical JSON, SHA-256 identity, defensive parsing, and atomic files.
7+
3. `evidence` owns the append-only ledger, typed claim graph, and bound engine bundles.
8+
4. `audit` owns the single-case append-only hash chain and semantic state replay.
9+
5. `verdict` owns the pure conservative eligibility policy.
1010
6. `roles` owns provider-neutral typed interfaces and authority checks.
1111
7. `workflow` owns the only legal sequential orchestration.
12-
8. `adapters` contains package-owned mock roles and evidence only.
13-
9. `cli` exposes offline demos and validators.
12+
8. `storage` owns a backend-neutral case-store contract, SQLite implementation, migrations,
13+
reconstruction, and deterministic package export.
14+
9. `engine` owns the narrow read-only adapter contract for the protected C++ release.
15+
10. `adapters` contains package-owned mock roles and synthetic evidence only.
16+
11. `cli` exposes bounded offline operations; it is not an arbitrary process or filesystem API.
1417

15-
The architecture deliberately uses an in-memory aggregate and canonical files. A database, graph
16-
database, web framework, queue, vector store, and agent framework would add operational state without
17-
evidence that Phase 1 needs it.
18+
## Authority boundary
1819

19-
External provider output can enter only through a future adapter that returns the same validated
20-
domain models. Workflow state, evidence integrity, and verdict policy remain code-owned even when a
21-
language model later proposes role findings.
20+
QuantForge owns workflow state, human approval, constitution locking, evidence admission, reviewer
21+
authority, audit replay, the claim graph, verdict eligibility, and Chair constraints. The protected
22+
`MrithunjoyB/cpp-event-driven-backtester` release `v1.0.0` remains the numerical authority for
23+
simulation, statistics, reconstruction artifacts, and engine-side validation. The adapter cannot
24+
let the engine change tribunal state or decide that its own output is evidence.
2225

23-
A case file is a deterministic snapshot, not independent proof of history. Governed restoration
24-
requires the complete audit JSONL: replay validates every state, actor, action, payload, identity,
25-
derived verdict input, and final snapshot. The CLI therefore requires both files for `case validate`.
26+
Raw engine files are untrusted. The adapter first validates the exact release and executable,
27+
stages a fixed public synthetic fixture into an isolated directory, executes fixed argument arrays,
28+
runs the release validator, inventories and hashes every output, and emits a bundle. QuantForge then
29+
checks the bundle against current durable case state in the same transaction that appends its
30+
workflow event and evidence materialization.
31+
32+
## Durable and derived state
33+
34+
The semantic audit chain is authoritative for case reconstruction. SQLite stores that chain plus
35+
referentially constrained materializations of the constitution, evidence, graph, reviewer outputs,
36+
verdict result, bundle inventory, and export lineage. Reconstruction replays the events and compares
37+
every materialization and hash; a snapshot is never trusted independently. See
38+
[Storage Model](STORAGE_MODEL.md) and [Migration Policy](MIGRATION_POLICY.md).
39+
40+
SQLite is deliberately local and single-node. It provides transactions, WAL recovery, foreign keys,
41+
bounded busy waiting, and optimistic revisions, but not distributed consensus or an external trust
42+
anchor. A complete locally rehashed replacement remains detectable only when compared with a trusted
43+
external digest or signed/anchored publication.
44+
45+
No live provider, market-data ingestion, broker, order, or trading component exists. A later
46+
provider adapter may propose typed role output, but code-owned workflow and evidence authority must
47+
remain unchanged.

docs/DETERMINISM.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Deterministic Semantics
2+
3+
QuantForge distinguishes semantic identity from observations that necessarily vary between runs.
4+
5+
- Canonical JSON sorts object keys and normalizes Unicode, UTC timestamps, finite decimals, and
6+
negative zero.
7+
- Audit event hashes, case semantic hashes, materialization hashes, migration checksums, artifact
8+
semantic hashes, and export manifests use canonical JSON.
9+
- Engine bundle semantic hashes contain every meaningful input, invocation, schema, validator,
10+
output value, methodology, unit, and lineage identity.
11+
- Execution/admission time and raw byte observations have a separate observation hash. Documented
12+
volatile JSON provenance fields are removed only from semantic artifact hashing; their original
13+
artifact bytes remain byte-hashed in observations and therefore remain bound by the bundle hash.
14+
- Exports include no export-time clock. Their ID derives from case ID and revision; parent lineage is
15+
the prior durable manifest; artifacts and manifest end in one normalized newline.
16+
17+
Repeated approved fixture execution must produce identical output semantics, numeric facts,
18+
validator identity, config/input identity, and canonical semantic bundle bytes. Observation and full
19+
bundle hashes may differ when truthful timestamps or raw volatile bytes differ. Re-exporting the
20+
same revision to new empty directories must be byte-identical. Reconstructing from events must equal
21+
the stored case, ledger, graph, verdict result, and audit head. Migration must not change those
22+
semantic identities.
23+
24+
Tests exercise repeated fake and real tagged-engine runs, repeat export, independent package
25+
verification, serial full-suite runs, reversed file order, and branch-aware coverage. This design
26+
does not claim bit-identical executables across compilers or remove meaningful provenance to create
27+
an artificial deterministic result.
Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,51 @@
1-
# Future Engine Integration Contract
1+
# C++ Engine Integration Contract
22

3-
The protected dependency is `cpp-event-driven-backtester` release `v1.0.0`.
3+
The protected numerical dependency is `MrithunjoyB/cpp-event-driven-backtester` release `v1.0.0`:
44

5-
- Annotated tag object: `20ac53c5e4b61ae7b431d5bb263f246e35f8d2a2`
6-
- Release commit: `2f86b71dbc9f29dbda861942d8afbb10c04b6625`
7-
- Integration status: disabled in Phase 1
5+
- annotated tag object: `20ac53c5e4b61ae7b431d5bb263f246e35f8d2a2`;
6+
- peeled release target: `2f86b71dbc9f29dbda861942d8afbb10c04b6625`;
7+
- invocation contract: `1.0`;
8+
- numerical methodology: `causal_daily_v3_stochastic_v2`;
9+
- stable RNG identity reported by the executable: `portable_bounded_v1`.
810

9-
The future read-only adapter may invoke only reviewed argument arrays for the documented
10-
`validate-config`, `print-resolved-config`, `run --dry-run`, and `run` CLI forms. It must never accept
11-
a command string or shell expansion. Inputs and outputs use explicit normalized paths inside an
12-
isolated run directory. The adapter must confirm the release identity, executable digest, resolved
13-
configuration, input and manifest hashes, output inventory, schemas, validator results, and
14-
provenance before producing evidence.
11+
The Phase 2A adapter is research-only and read-only. It neither changes nor builds inside the
12+
protected sibling checkout. A separately reviewed executable is supplied with an expected SHA-256,
13+
and all experiment outputs go to an isolated `quantforge-engine-*` directory outside both
14+
repositories.
1515

16-
The C++ release is the numerical authority. An LLM cannot modify engine source, configuration after
17-
constitution lock, canonical outputs, manifests, or validators. Failed schemas, hashes, provenance,
18-
or reconstruction produce failed evidence; they are never repaired by prose. The sibling repository
19-
must not be a writable submodule or copied implementation.
16+
## Exact allow-list
2017

21-
This contract is derived read-only from release documentation at `v1.0.0`, including
22-
`docs/CONFIGURATION.md`, `docs/RESULT_SCHEMA.md`, and `docs/REPRODUCIBILITY.md`. No adapter code or
23-
engine source is copied here.
18+
The adapter has no command-string API. It executes argument vectors corresponding only to:
19+
20+
```text
21+
quant_cli version
22+
quant_cli validate-config --config configs/portfolio_equal_weight.json
23+
quant_cli print-resolved-config --config configs/portfolio_equal_weight.json
24+
quant_cli run --config configs/portfolio_equal_weight.json --dry-run
25+
quant_cli run --config configs/portfolio_equal_weight.json --execution-mode serial --threads 1
26+
python scripts/validate_results.py
27+
```
28+
29+
The `python` label documents the normalized contract; execution uses the current trusted Python
30+
interpreter and the release validator copied from the verified tag. Processes use `shell=False`, an
31+
explicit working directory, stdin isolation, a minimal environment, `C` locale, UTC timezone,
32+
timeouts, output caps, process-group termination, and return-code checks. Arbitrary arguments,
33+
configuration paths, input paths, commands, environment inheritance, and symlinks are rejected.
34+
35+
## Identity and staging
36+
37+
Before every identity query or run the adapter checks the approved remote, clean tracked tree,
38+
annotated tag object, peeled target, release-relative config/input/validator diff, executable regular
39+
file and executable bit, executable size/digest, version, methodology, and RNG lines. The only inputs
40+
are the fixed equal-weight config and six public synthetic files. Each is copied with no-follow and
41+
inode/replacement checks, bounded size, exclusive destination creation, and `fsync`.
42+
43+
Successful execution alone is insufficient. Admission additionally requires the exact config/input
44+
semantic and byte hashes, a complete bounded output inventory, supported JSON/CSV schema versions,
45+
the release `validate_results.py` result, finite decimal facts at declared CSV locations, closed
46+
units, and methodology metadata. The resulting bundle must match the locked constitution, case,
47+
workflow revision, amendment-chain head, engine identity, and prior-bundle head.
48+
49+
The C++ engine remains authoritative for numerical values; QuantForge validates and cites those
50+
values without recalculating or strengthening them. Failed identity, schema, validation, provenance,
51+
or inventory checks fail closed and cannot be repaired by prose.

0 commit comments

Comments
 (0)