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: 10 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,21 @@ jobs:
cache: pip
- run: python -m pip install -r requirements-dev.txt
- run: python -m pip install --no-deps --editable .
- name: Verify repository manifest
run: python tools/rebuild_manifest.py --check
- name: Verify canon lock
run: python tools/verify_canon_lock.py --canon-root .aset-spec
- name: Run profile and semantic conformance gates
- name: Run complete profile and release gate
run: python tools/profile_gate.py --canon-root .aset-spec
- uses: actions/upload-artifact@v4
if: always()
with:
name: aset-python-sqlite-conformance
if-no-files-found: warn
path: dist/conformance-results.json
path: |
dist/conformance-results.json
dist/aset-python-sqlite-source.zip
dist/aset-python-sqlite-source.zip.sha256
dist/wheel/*.whl
dist/blackbox-release-audit.json
dist/blackbox-release-audit.md
7 changes: 4 additions & 3 deletions .github/workflows/update-canon-lock.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,16 @@ jobs:
)
PY

python tools/rebuild_manifest.py
git diff --check

if git diff --quiet -- canon.lock.json; then
if git diff --quiet -- canon.lock.json MANIFEST.json; then
printf 'changed=false\n' >> "$GITHUB_OUTPUT"
printf 'CANON_LOCK_ALREADY_CURRENT=true\n'
else
printf 'changed=true\n' >> "$GITHUB_OUTPUT"
printf 'CANON_LOCK_UPDATE_REQUIRED=true\n'
git diff -- canon.lock.json
git diff -- canon.lock.json MANIFEST.json
fi

- name: Set up Python
Expand Down Expand Up @@ -184,7 +185,7 @@ jobs:

git switch -c "$BRANCH"

git add canon.lock.json
git add canon.lock.json MANIFEST.json
git diff --cached --check
git diff --cached --stat

Expand Down
82 changes: 61 additions & 21 deletions MANIFEST.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
{
"document_type": "aset-python-sqlite-manifest",
"files": [
{
"path": ".github/workflows/ci.yml",
"sha256": "sha256:913d28cd051125ebc03671c601cc1668d3557e90a9da53038c0997d7f69d83e3",
"size_bytes": 1788
},
{
"path": ".github/workflows/update-canon-lock.yml",
"sha256": "sha256:8b6acfc528be82f69465b7c751bb0c9fd60237ba000ac787f72dfdbb45997289",
"size_bytes": 6593
},
{
"path": ".gitignore",
"sha256": "sha256:fffcfeac766a4c93019032c2a30eebdbdf7d91a187990e09a50cecba44189b7c",
"size_bytes": 125
},
{
"path": "AUTHORS.md",
"sha256": "sha256:1424b7b7dc298def67f25c6debc28040b580eb9d227c66d2ee4a12748116913e",
Expand Down Expand Up @@ -28,23 +43,23 @@
},
{
"path": "ORIGIN.json",
"sha256": "sha256:7bf99415d610be4b9601d02cc4dd4e0d2093c7d2e50ff499b25d268d391937c9",
"size_bytes": 728
"sha256": "sha256:6ab2461270ca82e0921a0d44dd338e0827f3e66762c558ae8097625ccf3470d5",
"size_bytes": 1193
},
{
"path": "README.md",
"sha256": "sha256:902eadc37021cf1125249d941523d1f937eefd3817fa34fc509b3c2bb3ff86fa",
"size_bytes": 1479
"sha256": "sha256:4e022823c5098bbd7dbe8e9e0c5150291abf9c7b6cc1f950d86cf90087366e41",
"size_bytes": 2117
},
{
"path": "README.pt-BR.md",
"sha256": "sha256:d66bf529e42c3faba2801688ede0aac1feb74e38e1a9c59ee33c915fbac37e8d",
"size_bytes": 758
"sha256": "sha256:8bc44962a333cdd3a20a2e6d8021c92a1022420be7f989f4d479b29ec3784ca7",
"size_bytes": 1432
},
{
"path": "README.ru.md",
"sha256": "sha256:ea348226560c5bc17d0881340e1bc6c3430d4b9545f116e38b1dce6b70221572",
"size_bytes": 946
"sha256": "sha256:bdae01a140d43d00d067531bc7f60abf7c0212d3eaa041f33384b0ae26445952",
"size_bytes": 1881
},
{
"path": "SECURITY.md",
Expand All @@ -58,23 +73,28 @@
},
{
"path": "canon.lock.json",
"sha256": "sha256:3c454deb42bde8ebea9964e94a5cad738cd402708d41c8ad3afe23f0fca74758",
"size_bytes": 578
"sha256": "sha256:1b1e4623bafc4011e161dc27f7a5bba483a9a1ecbee2eb201518600567dd7af8",
"size_bytes": 598
},
{
"path": "docs/ARCHITECTURE.md",
"sha256": "sha256:dc4535e57f3e6503f8af5ec1dd19920b95a21c04e7b24cbcf66ff8fac4567c93",
"size_bytes": 382
"sha256": "sha256:ff1443c9ead28700a2c2ddde67c339d89194700723cd8c227484f93ccdb8aadb",
"size_bytes": 901
},
{
"path": "docs/CONFORMANCE.md",
"sha256": "sha256:a8465bc73fe1b133c4f0035ee4c32ed7b9e1e20ca5131ee75a6288ba07db8a3a",
"size_bytes": 386
"sha256": "sha256:caddb7a3bc2b3f8115b87542c0466ff1267ed9a1350a0e7172d0e810d61d97a4",
"size_bytes": 1325
},
{
"path": "profile/PROFILE.json",
"sha256": "sha256:4b435d75dd41b4094a2fb6830cd98fd390609045af68a03e94aaf0d2d03ad83b",
"size_bytes": 23213
"sha256": "sha256:7beee4b3369345e94c87334c9327bea8903a64409414817b4dace82a41667a2b",
"size_bytes": 16304
},
{
"path": "profile/verification-map.json",
"sha256": "sha256:0f878d25fc6eed152b714f5a25dd43bae1e687665926b32dafc990296ad7e3ea",
"size_bytes": 3025
},
{
"path": "pyproject.toml",
Expand Down Expand Up @@ -346,6 +366,11 @@
"sha256": "sha256:1337dded55421f38ac071d30d570d9598c64f1cba99370aeb58643f04fea12d0",
"size_bytes": 9661
},
{
"path": "tests/test_release_assurance.py",
"sha256": "sha256:d7303899534a14d98de4b867d728f28f271c0f3785b9a2c74ec98443c0731634",
"size_bytes": 1786
},
{
"path": "tests/test_runtime.py",
"sha256": "sha256:801fbc26611f8555604879e2ee379d18777af1442185cfcf04ec7cacf04c5296",
Expand All @@ -356,22 +381,37 @@
"sha256": "sha256:49320eff4a7bc29faa0fc73b9831000e0d5586a821c953a1e382d5ad9f46a81d",
"size_bytes": 293
},
{
"path": "tools/blackbox_release_audit.py",
"sha256": "sha256:e1da402786d84357003606287675d09e642579807ec38699a0f315920e75331b",
"size_bytes": 12900
},
{
"path": "tools/build_release.py",
"sha256": "sha256:5fda7bcc5e2f4c79c91b8d26c2be9972187312fea364986b043767d066b8eeb0",
"size_bytes": 2069
},
{
"path": "tools/profile_gate.py",
"sha256": "sha256:5b5f0656f0b70cd017578c08df952147466b24fdadbf7f140af6a3c76c2b3be2",
"size_bytes": 1018
"sha256": "sha256:0fa84f7cd4f6e24b6c16a25078ac0bf23707e768d73a9edee761cee84d0162a9",
"size_bytes": 2663
},
{
"path": "tools/rebuild_manifest.py",
"sha256": "sha256:8e3745bd224509a51f94dcfbe1574e8d5328d4e68d833bb23511806adc229c90",
"size_bytes": 1355
"sha256": "sha256:8ffc1090eee86df1327fc1fa71022825d86b006e886444138af782f6c5892b46",
"size_bytes": 1442
},
{
"path": "tools/validate_profile_traceability.py",
"sha256": "sha256:26655a2ce9a39b0072af5ed47d602815ec0820b3597a1e841df437d2bfb62153",
"size_bytes": 4406
},
{
"path": "tools/verify_canon_lock.py",
"sha256": "sha256:4ab04c034681a0d190543d007c360f04f2131f3addfce65406b559741211322a",
"size_bytes": 1103
}
],
"files_count": 74,
"files_count": 82,
"schema_version": 1
}
7 changes: 6 additions & 1 deletion ORIGIN.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"creator": "Dzmitry Prychyna",
"derived_paths": [
"src/aset_seed",
"src/aset_python_sqlite",
"tests/test_runtime.py",
"tests/test_prefreeze_hardening.py",
"tests/test_cli_security.py"
Expand All @@ -11,9 +11,14 @@
"public_pseudonym": "Attractor Set",
"rights_transfer": "NONE",
"schema_version": 1,
"separation_statement": "The independent profile preserves provenance to the exact source archive while its current semantics are governed only by canon.lock.json and the external ASET conformance verdict.",
"source_archive": "ASET-main(10)(1).zip",
"source_archive_sha256": "sha256:223f19a79287475e87fbf4841a86735d1a41d7d0574b6508ca66991a07b979bd",
"source_manifest_files_count": 708,
"source_manifest_path": "MANIFEST.json",
"source_manifest_sha256": "sha256:6b996d3723e80a791a0c9c6934b3530de084fed863322ef2ce7c70b9255fb315",
"source_project": "ASET",
"source_repository": "https://github.com/attractor-set/ASET",
"source_revision_status": "NOT_EMBEDDED_IN_SOURCE_ARCHIVE",
"statement": "Repository separation and Apache-2.0 licensing do not transfer authorship or ownership of the underlying Background IP."
}
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ python tools/profile_gate.py --canon-root ../ASET

The external runner in the specification repository invokes `python -m aset_python_sqlite.adapter` and determines the conformance verdict. The adapter never declares itself conformant.

## Release assurance

`python tools/profile_gate.py --canon-root ../ASET` is the complete profile gate. It checks the repository manifest and profile traceability, runs the unit and durability tests, verifies the exact canon lock, executes the specification-owned conformance runner, builds a deterministic source archive and wheel, installs the wheel in an isolated environment, and performs documentation and runtime black-box checks against the built artifacts.

The resulting artifacts and reports are written under `dist/`. A release must not be published unless `PYTHON_SQLITE_PROFILE_GATE=PASS` and `BLACKBOX_RELEASE_AUDIT=PASS`.

## Rights and licence

Licensed under Apache License 2.0. Copyright and authorship remain with Dzmitry Prychyna unless expressly assigned in writing. See [`LICENSE`](LICENSE), [`NOTICE`](NOTICE), [`ORIGIN.json`](ORIGIN.json), [`BACKGROUND_IP_NOTICE.md`](BACKGROUND_IP_NOTICE.md), [`AUTHORS.md`](AUTHORS.md) and [`TRADEMARKS.md`](TRADEMARKS.md).
6 changes: 6 additions & 0 deletions README.pt-BR.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,9 @@ python tools/profile_gate.py --canon-root ../ASET
```

A licença Apache 2.0 não transfere autoria nem titularidade. Consulte [`LICENSE`](LICENSE), [`NOTICE`](NOTICE), [`ORIGIN.json`](ORIGIN.json) e [`BACKGROUND_IP_NOTICE.md`](BACKGROUND_IP_NOTICE.md).

## Garantia do release

`python tools/profile_gate.py --canon-root ../ASET` é o gate completo do perfil. Ele verifica o manifesto e a rastreabilidade dos requisitos do perfil, executa os testes unitários e de durabilidade, verifica o canon lock exato, executa o conformance runner pertencente à especificação, constrói um arquivo-fonte determinístico e um wheel, instala o wheel em um ambiente isolado e realiza verificações de caixa-preta da documentação e do runtime sobre os artefatos construídos.

Os artefatos e relatórios são gravados em `dist/`. Um release não deve ser publicado sem `PYTHON_SQLITE_PROFILE_GATE=PASS` e `BLACKBOX_RELEASE_AUDIT=PASS`.
6 changes: 6 additions & 0 deletions README.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,9 @@ python tools/profile_gate.py --canon-root ../ASET
```

Лицензия Apache 2.0 не передаёт авторство или право собственности. См. [`LICENSE`](LICENSE), [`NOTICE`](NOTICE), [`ORIGIN.json`](ORIGIN.json) и [`BACKGROUND_IP_NOTICE.md`](BACKGROUND_IP_NOTICE.md).

## Проверка релиза

`python tools/profile_gate.py --canon-root ../ASET` является полным гейтом профиля. Он проверяет manifest и трассируемость требований профиля, запускает unit- и durability-тесты, проверяет точную canon lock, выполняет принадлежащий спецификации conformance runner, собирает детерминированный source archive и wheel, устанавливает wheel в изолированную среду и проводит блэк-бокс проверку документации и среды исполнения по собранным артефактам.

Артефакты и отчёты создаются в `dist/`. Релиз нельзя публиковать без `PYTHON_SQLITE_PROFILE_GATE=PASS` и `BLACKBOX_RELEASE_AUDIT=PASS`.
9 changes: 8 additions & 1 deletion docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# Architecture

The package has three boundaries: the semantic core (`core.py`), the local durable profile (`runtime.py` and `store.py`), and the black-box conformance adapter (`adapter.py`). The semantic core consumes canonical documents; SQLite maps accepted transitions and audit attempts into one local transaction. Profile-specific durability does not become a Seed invariant.
The package has four explicit boundaries:

1. the semantic core (`core.py`), which implements the currently pinned Seed semantics without claiming normative authority;
2. the local durable profile (`runtime.py` and `store.py`), which maps accepted transitions and audit attempts into one SQLite transaction;
3. the black-box conformance adapter (`adapter.py`), which returns observations to the specification-owned runner and never returns a conformance verdict;
4. the release-assurance boundary (`profile/verification-map.json` and `tools/*release*`), which binds every profile requirement to executable checks and verifies built source and wheel artifacts independently from the working tree.

Profile-specific durability does not become a Seed invariant. The exact semantic dependency is `canon.lock.json`; historical extraction provenance is recorded separately in `ORIGIN.json`.
25 changes: 23 additions & 2 deletions docs/CONFORMANCE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
# Canon consumption
# Canon consumption and executable assurance

CI checks out the ASET specification repository, verifies [`canon.lock.json`](../canon.lock.json), and then executes the specification-owned external runner against the implementation adapter. The lock binds the implementation to exact canon-package bytes. After the specification patch is merged, pin `source.ref` to an immutable commit SHA or signed release tag.
CI checks out the exact ASET specification revision recorded in [`canon.lock.json`](../canon.lock.json), verifies the canon-package identity, and executes the specification-owned external runner against the implementation adapter. The adapter returns observations and never determines its own conformance verdict.

The profile requirements and invariants are bound to executable checks in [`profile/verification-map.json`](../profile/verification-map.json). [`tools/validate_profile_traceability.py`](../tools/validate_profile_traceability.py) rejects missing identifiers, stale pytest references and an incomplete release-audit binding.

The complete gate is:

```text
python tools/profile_gate.py --canon-root ../ASET
```

It requires, in order:

1. exact repository-manifest parity;
2. complete profile requirement/invariant traceability;
3. unit, durability and boundary tests;
4. exact canon-lock verification;
5. external semantic conformance;
6. deterministic source-archive construction;
7. wheel construction and isolated installation;
8. black-box documentation and runtime verification from the built artifacts.

The source archive, wheel and reports are generated under `dist/`. `ASET-PYSQL-REQ-012` is satisfied only when the black-box release audit returns `PASS`.
Loading
Loading