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
93 changes: 37 additions & 56 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,67 +1,48 @@
# Repository instructions for Claude Code
# QuantCheck project guidance

## Mission

Rebuild **QuantCheck**, a Python framework that tests whether point-in-time financial research data can manufacture misleading results through timestamp leakage, unit corruption, duplicate observations, or revision-history failure.

The repository currently starts from source-code loss. Historical documents under `reference/` describe the intended behavior but are not current implementation status.

## Required first action

Before editing any file:

1. Read `IMPLEMENT.md`.
2. Read `docs/AUTHORITY_AND_READING_ORDER.md`.
3. Read `PROJECT_SCOPE.md` and `MVP_ACCEPTANCE_CRITERIA.md`.
4. Read only the task-specific historical references required for the current milestone.
5. Inspect the actual repository tree and Git status.
6. Restate the applicable invariants and acceptance criteria.
7. Propose the smallest viable diff and tests.

Do not claim that historical release behavior exists unless it is present in the new code and verified locally.
QuantCheck is a deterministic Python framework for testing whether point-in-time
financial research data can manufacture misleading results through timestamp
leakage, unit corruption, duplicate observations, or revision-history failure.
Keep the implementation and public evidence within this scope.

## Fixed technical choices

- Python 3.12
- package name `quantcheck`
- `uv`
- Hatchling
- Pydantic v2
- Ruff
- MyPy
- pytest
- Hypothesis
- Typer
- HTTPX
- pandas
- PyArrow
- Streamlit only after benchmark and CLI stability
- day-level financial availability semantics for v0.1
- end-of-day research decisions for v0.1
- JSON string serialization for `Decimal`
- SHA-256 canonical hashes

## Hard invariants

1. Detectors never receive manifests, pre-corruption values, injected-row flags, or injector-only metadata.
2. Detectors receive a sanitized `AuditInputSnapshot`, not unrestricted canonical records.
3. The same clean snapshot, configuration, seed, and code version produce the same logical corruption and artifacts.
4. Caller-owned inputs are never modified in place.
5. Period, filing, availability, as-of, and runtime dates are distinct concepts.
6. Financial values use `Decimal`; public JSON encodes them as canonical strings.
7. IDs and hashes must not depend on DataFrame row position or Python hash randomization.
8. Findings contain a rule ID, affected records, evidence, explanation, and confidence classification.
9. Every detector is evaluated against clean controls.
10. Scoring can read the private manifest only after the audit report is finalized.
11. Ordinary tests make no live network requests.
12. Unsupported source semantics are rejected or explicitly recorded rather than guessed.
13. Synthetic, controlled, and real-data claims remain clearly distinguished.
14. Historical metrics and hashes are not copied into new output unless reproduced from the rebuilt implementation.
- Python 3.12, `uv`, Hatchling, Pydantic v2, Ruff, MyPy, pytest, Hypothesis
- Typer, HTTPX, pandas, and PyArrow; Streamlit only for the read-only dashboard
- Day-level financial availability and end-of-day research decisions for v0.1
- `Decimal` for financial values, canonical JSON strings, and SHA-256 hashes

## Scientific invariants

1. Detectors receive only a sanitized `AuditInputSnapshot`, never manifests,
pre-corruption values, injected-row flags, or injector-only metadata.
2. The same clean snapshot, configuration, seed, and code version produce the
same logical corruption and artifacts.
3. Caller-owned inputs are never modified in place.
4. Period, filing, availability, as-of, and runtime dates remain distinct.
5. Financial values use `Decimal`; public JSON serializes them as canonical strings.
6. IDs and hashes do not depend on row position or Python hash randomization.
7. Findings include a rule ID, affected records, evidence, explanation, and
confidence classification.
8. Every detector is evaluated against clean controls.
9. Scoring reads the private manifest only after the audit report is finalized.
10. Ordinary tests make no live network requests.
11. Unsupported source semantics are rejected or explicitly recorded, never guessed.
12. Synthetic, controlled, and real-data claims remain clearly distinguished.
13. Historical metrics and hashes are not copied into new output unless reproduced
from the rebuilt implementation.

## Scope discipline

Do not add authentication, SaaS infrastructure, real-money trading, a generic backtester, machine learning, intraday claims, React, microservices, Kubernetes, or new fault families during the v0.1 rebuild.
Do not add authentication, SaaS infrastructure, real-money trading, generic
backtesting, machine learning, intraday claims, React, microservices, Kubernetes,
or new fault families to the v0.1 implementation.

## Completion rule
## Verification rule

A task is complete only when its acceptance criteria, positive/negative/edge/regression tests, applicable quality gates, serialization contracts, and financial semantics all pass; the diff is scoped; and `IMPLEMENT.md` is current.
A change is complete only when its acceptance criteria, positive/negative/edge/
regression tests, applicable quality gates, serialization contracts, and financial
semantics pass. Keep the diff scoped, preserve unrelated worktree changes, and
report any unverified external or production evidence explicitly.
15 changes: 11 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,14 @@ All notable changes to QuantCheck are recorded here. This project follows
Arrow IPC are supported production inputs. Imports remain lazy for CSV and
Python-row use.
* Container assembly canonicalizes virtual-environment entry order, ownership,
and timestamps before extraction. The reproducibility gate reports and
compares raw OCI archives plus index, manifest, config, and layer digests.
and timestamps before extraction. The reproducibility gate requires identical
digest-addressed OCI manifest, config, and layer identity. Raw outer-tar
archive bytes, headers, and member order remain diagnostics and do not fail
the image-identity gate by themselves.
* The cited candidate commit `3b47da9` has green Security workflow run
`32693592309`, including exact two-build OCI manifest/config/layer identity
and dependency, secret, image, and SBOM gates. This does not claim a published
image digest or trusted release attestation.

### Not claimed

Expand All @@ -39,8 +45,9 @@ All notable changes to QuantCheck are recorded here. This project follows

## [0.1.0] — 2026-08-08

First release candidate. Prepared locally; **not published**. No Git tag,
GitHub release, PyPI upload, or CI run exists.
Immutable historical baseline, published from the `v0.1.0` tag as a GitHub
release. It has no PyPI upload; install from its attached wheel, sdist, or
source checkout.

### Added

Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,6 @@ public bytes, also assert it is present in the private tree.

## Handoff

`IMPLEMENT.md` is the operational source of truth between sessions. Record the
milestone completed, files changed, commands run with exact outcomes, decisions
added, known limitations, and the exact next task.
`docs/STATUS.md` is the concise public status source of truth. Record exact
commands and outcomes in the relevant gate or release evidence, and keep
known limitations and claims scoped to the artifact or run that supports them.
21 changes: 8 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,12 @@ WORKDIR /build
COPY --from=uv /uv /usr/local/bin/uv
COPY pyproject.toml uv.lock README.md LICENSE .python-version ./
COPY src/ ./src/
# uv's cache provenance contains wall-clock nanoseconds and is not needed at
# runtime; remove it with its RECORD row before snapshotting the tree.
RUN uv sync --frozen --no-dev --no-editable \
&& find /opt/quantcheck/.venv -exec touch -h -d "@${SOURCE_DATE_EPOCH}" {} + \
&& tar \
--sort=name \
--mtime="@${SOURCE_DATE_EPOCH}" \
--owner=65532 \
--group=65532 \
--numeric-owner \
--pax-option=delete=atime,delete=ctime \
-C /opt/quantcheck \
-cf /opt/quantcheck/venv.tar \
.venv
&& find /opt/quantcheck/.venv -name uv_cache.json -delete \
&& find /opt/quantcheck/.venv -name RECORD -exec sed -i '/uv_cache[.]json,/d' {} + \
&& find /opt/quantcheck/.venv -exec touch -h -d "@${SOURCE_DATE_EPOCH}" {} +

FROM ${PYTHON_IMAGE} AS runtime

Expand Down Expand Up @@ -60,8 +54,9 @@ ENV PATH="/opt/quantcheck/.venv/bin:${PATH}" \
HOME=/nonexistent

WORKDIR /opt/quantcheck
RUN --mount=type=bind,from=builder,source=/opt/quantcheck/venv.tar,target=/tmp/venv.tar \
tar -xf /tmp/venv.tar -C /opt/quantcheck
# Copy the normalized tree directly. An intermediate tar/untar snapshot made
# BuildKit's runtime layer vary between otherwise identical no-cache builds.
COPY --from=builder --chown=65532:65532 /opt/quantcheck/.venv /opt/quantcheck/.venv
COPY --chown=65532:65532 deploy/smoke /opt/quantcheck/smoke

# /config and /input are mount points for read-only customer material.
Expand Down
Loading
Loading