diff --git a/.github/workflows/darwin-var-revision-identities.yml b/.github/workflows/darwin-var-revision-identities.yml new file mode 100644 index 00000000..146295fa --- /dev/null +++ b/.github/workflows/darwin-var-revision-identities.yml @@ -0,0 +1,115 @@ +name: Darwin VAR frozen revision identities + +on: + pull_request: + paths: + - ".github/workflows/darwin-var-revision-identities.yml" + - "scriptorium/single_page_revision.py" + - "scriptorium/darwin_var_revision_identities.py" + - "tests/test_darwin_var_revision_identities.py" + - "corpus/candidates/source-edition-traces/darwin-origin-species-rachinsky-1864-ru.var-revision-identities-evidence.json" + workflow_dispatch: + +permissions: + contents: read + +jobs: + capture: + name: Capture six exact Wikisource revision identities + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Checkout pull-request head + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} + persist-credentials: false + + - name: Set up Python 3.13 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + with: + python-version: "3.13" + + - name: Run standard-library test suite + run: python -m unittest discover -s tests -v + + - name: Capture provider-returned source-free identities + run: | + set -euo pipefail + mkdir -p build/repro + python - <<'PY' + import json + from pathlib import Path + from scriptorium.single_page_revision import fetch_pinned_revision + + # The dependency evidence uses MediaWiki's English namespace alias in Lua + # require() strings. The Russian Wikisource API canonicalizes those page + # titles to the local `Модуль:` namespace, so preserve both identities. + resources = [ + ("Шаблон:ВАР", "Шаблон:ВАР", 3684602), + ("Модуль:Дореформенная орфография", "Модуль:Дореформенная орфография", 5721277), + ("Module:Header", "Модуль:Header", 5746249), + ("Module:BEED", "Модуль:BEED", 5746253), + ("Module:Util", "Модуль:Util", 5750249), + ("Module:RomanNumber", "Модуль:RomanNumber", 3684553), + ] + observed = [] + for closure_title, provider_title, revision_id in resources: + item = fetch_pinned_revision(title=provider_title, revision_id=revision_id) + item["closure_title"] = closure_title + observed.append(item) + assert [ + (item["closure_title"], item["title"], item["revision_id"]) + for item in observed + ] == resources + assert all(len(item["mediawiki_sha1"]) == 40 for item in observed) + payload = { + "schema_version": "scriptorium-darwin-var-provider-revision-identities-v1", + "provider": "Russian Wikisource", + "source_text_included": False, + "resources": observed, + } + path = Path("build/repro/darwin-var-provider-revision-identities.json") + path.write_text(json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True) + "\n", encoding="utf-8") + print("SCRIPTORIUM_DARWIN_VAR_IDENTITIES=" + json.dumps(payload, ensure_ascii=False, sort_keys=True, separators=(",", ":"))) + PY + + - name: Compare capture to committed identity contract + run: | + set -euo pipefail + python - <<'PY' + import json + from pathlib import Path + from scriptorium.darwin_var_revision_identities import validate_evidence + + observed = json.loads(Path("build/repro/darwin-var-provider-revision-identities.json").read_text(encoding="utf-8")) + evidence = json.loads(Path("corpus/candidates/source-edition-traces/darwin-origin-species-rachinsky-1864-ru.var-revision-identities-evidence.json").read_text(encoding="utf-8")) + validate_evidence(evidence) + expected = evidence["resources"] + assert observed["source_text_included"] is False + assert len(observed["resources"]) == len(expected) == 6 + for got, want in zip(observed["resources"], expected, strict=True): + for key in ( + "closure_title", + "title", + "page_id", + "revision_id", + "revision_timestamp", + "mediawiki_sha1", + "wikitext_character_count", + "wikitext_utf8_byte_count", + "wikitext_sha256", + ): + assert got[key] == want[key], (key, got[key], want[key]) + assert evidence["identity_gate"]["mediawiki_sha1_complete"] is True + assert evidence["identity_gate"]["replay_ready"] is False + print("SCRIPTORIUM_DARWIN_VAR_EVIDENCE_SHA256=" + evidence["evidence_sha256"]) + PY + + - name: Upload source-free identity capture + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: darwin-var-provider-revision-identities + path: build/repro/darwin-var-provider-revision-identities.json + if-no-files-found: error + retention-days: 7 diff --git a/corpus/candidates/darwin-origin-species-rachinsky-1864-ru-var-revision-identities.md b/corpus/candidates/darwin-origin-species-rachinsky-1864-ru-var-revision-identities.md new file mode 100644 index 00000000..2e5b1820 --- /dev/null +++ b/corpus/candidates/darwin-origin-species-rachinsky-1864-ru-var-revision-identities.md @@ -0,0 +1,24 @@ +# Darwin/Rachinsky 1864 — `{{ВАР}}` provider revision identities + +This source-free companion advances the independently reviewed SCRIP-CORPUS-083 observed-live `{{ВАР}}` closure by binding all six exact revisions to official Russian Wikisource identity metadata. It is an identity-completion artifact, not a full `{{ВАР}}` replay, historical-transclusion claim, or renderer promotion. + +The frozen closure remains: + +`Шаблон:ВАР@3684602` → `Модуль:Дореформенная орфография@5721277` → `Module:Header@5746249` → `Module:BEED@5746253` + `Module:Util@5750249`; loading BEED also loads `Module:RomanNumber@3684553`. + +The official MediaWiki revisions API returned a 40-hex SHA-1 for every exact revision. Russian Wikisource canonicalizes the English `Module:` namespace aliases used by Lua dependency strings to local provider titles under `Модуль:`; the evidence therefore stores both the reviewed closure alias and the provider-returned title. + +| Closure title | Provider title | Revision | MediaWiki SHA-1 | +| --- | --- | ---: | --- | +| `Шаблон:ВАР` | `Шаблон:ВАР` | 3684602 | `fdb6fa7c0d4b08157bc30d44f5f77c5b9313167c` | +| `Модуль:Дореформенная орфография` | `Модуль:Дореформенная орфография` | 5721277 | `64d28378f4f620c67e1823a0d4292445d9ab293d` | +| `Module:Header` | `Модуль:Header` | 5746249 | `2ab2bfdd7e49c73c4ec9ef24e4625c1d228cfba0` | +| `Module:BEED` | `Модуль:BEED` | 5746253 | `9e9531e9178e0333bd3a939ace91e6a71e114cc5` | +| `Module:Util` | `Модуль:Util` | 5750249 | `945f8e6bf173bb5712385995255a8b6eccef38ed` | +| `Module:RomanNumber` | `Модуль:RomanNumber` | 3684553 | `51a3956469ee3fbd4ed56ce3a1f72f76f231e1d3` | + +The machine-readable contract is [`source-edition-traces/darwin-origin-species-rachinsky-1864-ru.var-revision-identities-evidence.json`](source-edition-traces/darwin-origin-species-rachinsky-1864-ru.var-revision-identities-evidence.json), SHA-256 `98dc8aed94fd8b4e18f0ad3325673603cba1575c1e745e1175ab4cd3a8aa2a48`. It also retains provider page IDs, UTC revision timestamps, source-free wikitext counts, and SHA-256 digests captured without persisting source prose. + +`mediawiki_sha1_complete=true`, but `replay_ready=false`. `ВАР` remains unresolved at **388 invocations**, and the effective backlog remains **4 tag shapes / 130 tag tokens** plus **37 template shapes / 2,356 template invocations**. Full candidate invocation replay, historical transclusion, an explicit version-pinned Scribunto/runtime boundary, renderer promotion, literary-body identity, `>=300k` admission, FantLab analyzer-input identity, and M2 parity all remain open. + +The next bounded step is to replay the candidate `{{ВАР}}` branch against exactly these six identities under an explicit version-pinned runtime boundary; no later live descendants may silently substitute for the frozen revisions. diff --git a/corpus/candidates/source-edition-traces/darwin-origin-species-rachinsky-1864-ru.var-revision-identities-evidence.json b/corpus/candidates/source-edition-traces/darwin-origin-species-rachinsky-1864-ru.var-revision-identities-evidence.json new file mode 100644 index 00000000..13307b24 --- /dev/null +++ b/corpus/candidates/source-edition-traces/darwin-origin-species-rachinsky-1864-ru.var-revision-identities-evidence.json @@ -0,0 +1,108 @@ +{ + "candidate_id": "darwin-origin-species-rachinsky-1864-ru", + "capture_provenance": { + "api_surface": "MediaWiki revisions API: rvprop=ids|timestamp|sha1|content, rvslots=main", + "provider": "Russian Wikisource", + "source_text_persisted": false + }, + "evidence_sha256": "98dc8aed94fd8b4e18f0ad3325673603cba1575c1e745e1175ab4cd3a8aa2a48", + "fantlab_source_edition_match": "unknown", + "historical_transclusion_proven": false, + "identity_gate": { + "mediawiki_sha1_complete": true, + "missing_mediawiki_sha1_titles": [], + "provider_title_aliases_explicit": true, + "reason": "all six exact observed-live revisions are bound to provider-returned identities, but a full candidate invocation replay and an explicit version-pinned Scribunto/runtime boundary are still missing", + "replay_ready": false, + "revision_ids_complete": true + }, + "literary_body_count_and_digests_frozen": false, + "m2_parity_admissible": false, + "minimum_300k_proved": false, + "offline_version_pinned_runtime_proven": false, + "prior_closure": { + "evidence_sha256": "245f77bf3d99d6610ca5fbbe4fcdcdb4ef68bebca612c5bb81db6c2d77f26509", + "schema_version": "scriptorium-darwin-var-live-snapshot-closure-v1" + }, + "promotion_decision": { + "backlog_item_removed": false, + "effective_backlog_changed": false, + "full_var_candidate_branch_replayed": false, + "next_evidence_required": "perform a separately bounded full candidate invocation replay against these six exact identities with an explicit version-pinned Scribunto/runtime boundary", + "render_profile_rule_promoted": false, + "var_invocations_unresolved": 388 + }, + "renderer_implementation_ready": false, + "renderer_semantics_complete": false, + "researched_on": "2026-09-24", + "resources": [ + { + "closure_title": "Шаблон:ВАР", + "mediawiki_sha1": "fdb6fa7c0d4b08157bc30d44f5f77c5b9313167c", + "page_id": 122258, + "revision_id": 3684602, + "revision_timestamp": "2019-06-04T20:36:46Z", + "title": "Шаблон:ВАР", + "wikitext_character_count": 206, + "wikitext_sha256": "583f46a8f7fa2444456abede564817e134d313fb20d5cabfa2f2c48591c54707", + "wikitext_utf8_byte_count": 269 + }, + { + "closure_title": "Модуль:Дореформенная орфография", + "mediawiki_sha1": "64d28378f4f620c67e1823a0d4292445d9ab293d", + "page_id": 378940, + "revision_id": 5721277, + "revision_timestamp": "2026-06-08T13:06:13Z", + "title": "Модуль:Дореформенная орфография", + "wikitext_character_count": 1553, + "wikitext_sha256": "d0199f6df8f5f789e6a5aec0e450dae6d35c3448adca411481244e40aec3004d", + "wikitext_utf8_byte_count": 1588 + }, + { + "closure_title": "Module:Header", + "mediawiki_sha1": "2ab2bfdd7e49c73c4ec9ef24e4625c1d228cfba0", + "page_id": 361783, + "revision_id": 5746249, + "revision_timestamp": "2026-09-10T02:29:30Z", + "title": "Модуль:Header", + "wikitext_character_count": 54598, + "wikitext_sha256": "b3950aa5a04e8a8f3bec71c6c82843643dfdc1a1a82f3788f48830f21e434ecb", + "wikitext_utf8_byte_count": 67792 + }, + { + "closure_title": "Module:BEED", + "mediawiki_sha1": "9e9531e9178e0333bd3a939ace91e6a71e114cc5", + "page_id": 362284, + "revision_id": 5746253, + "revision_timestamp": "2026-09-10T03:41:25Z", + "title": "Модуль:BEED", + "wikitext_character_count": 10647, + "wikitext_sha256": "108fee006a43f146302aafda316f05f15198932c3389487ed7c760c83a7c4875", + "wikitext_utf8_byte_count": 11979 + }, + { + "closure_title": "Module:Util", + "mediawiki_sha1": "945f8e6bf173bb5712385995255a8b6eccef38ed", + "page_id": 980298, + "revision_id": 5750249, + "revision_timestamp": "2026-09-18T07:31:28Z", + "title": "Модуль:Util", + "wikitext_character_count": 1328, + "wikitext_sha256": "a69fdcf9cf4dbbfe34d3e41585f2bcd418eee4efbe6e5c42d82e450cc4045a90", + "wikitext_utf8_byte_count": 1585 + }, + { + "closure_title": "Module:RomanNumber", + "mediawiki_sha1": "51a3956469ee3fbd4ed56ce3a1f72f76f231e1d3", + "page_id": 378544, + "revision_id": 3684553, + "revision_timestamp": "2019-06-04T20:13:27Z", + "title": "Модуль:RomanNumber", + "wikitext_character_count": 1152, + "wikitext_sha256": "90edb9a1d3bf5d283112fd58e28ee60f2569ae0fe7850e936a17f4e23869cf45", + "wikitext_utf8_byte_count": 1212 + } + ], + "schema_version": "scriptorium-darwin-var-provider-revision-identities-v1", + "source_text_included": false +} diff --git a/project/CHANGELOG.d/SCRIP-CORPUS-084.md b/project/CHANGELOG.d/SCRIP-CORPUS-084.md new file mode 100644 index 00000000..593d3b27 --- /dev/null +++ b/project/CHANGELOG.d/SCRIP-CORPUS-084.md @@ -0,0 +1,10 @@ +## 2026-09-24 — Darwin `{{ВАР}}` provider revision identities + +- Selected SCRIP-CORPUS-084 / Issue #257 from the normal-flow P2 corpus queue after confirming no interrupted/open PR or issue recovery work. +- Added a dedicated source-free GitHub Actions capture for exactly the six SCRIP-CORPUS-083 observed-live revisions using the existing fail-closed MediaWiki revision fetch primitive. +- The first capture run correctly failed because Russian Wikisource canonicalizes `Module:` aliases to the local `Модуль:` namespace. The workflow was repaired to bind both the reviewed closure alias and provider-returned canonical title instead of weakening title validation. +- Successful provider capture bound all six exact revision IDs to page IDs, UTC timestamps, 40-hex MediaWiki SHA-1 values, source-free wikitext counts, and SHA-256 digests without committing source prose. +- Added deterministic evidence builder/validator, six focused regressions, and a public source-free companion. Evidence SHA-256: `98dc8aed94fd8b4e18f0ad3325673603cba1575c1e745e1175ab4cd3a8aa2a48`. +- `mediawiki_sha1_complete=true`, but `replay_ready=false`: full `{{ВАР}}` candidate replay, historical transclusion, explicit version-pinned Scribunto/runtime identity, renderer promotion, backlog reduction, literary-body identity, >=300k admission, FantLab-input identity and M2 parity remain outside this unit and closed. +- `ВАР` remains unresolved at 388 invocations; effective backlog remains 4 tag shapes / 130 tag tokens and 37 template shapes / 2,356 template invocations. M2 remains 0/5. +- Draft PR #258 remains for a later independent exact-head review; this authoring run does not self-approve or merge its substantive change. diff --git a/project/STATE_AND_QUEUE.md b/project/STATE_AND_QUEUE.md index d9d91748..f0aa4422 100644 --- a/project/STATE_AND_QUEUE.md +++ b/project/STATE_AND_QUEUE.md @@ -1,21 +1,22 @@ # STATE_AND_QUEUE — Scriptorium -STATE_REVISION: 280 +STATE_REVISION: 281 PHASE: M1 — Deterministic FantLab surface -LAST_COMMITTED_RUN_AT: 2026-09-24T11:58:00Z -LAST_RESULT: SCRIP-CORPUS-083 / Issue #255 / PR #256 independently reviewed and merged. Exact authored head `8367bc807fd30b90acae81386a481c78681c7b3e` was re-read across all 7 changed files against unchanged `master@ee57313a6974abd326311a7b70f010ae647781a2`; review `5304043399` found no merge blocker or open review thread. The source-free evidence self-digest independently recomputed to `245f77bf3d99d6610ca5fbbe4fcdcdb4ef68bebca612c5bb81db6c2d77f26509`. Fresh official Russian Wikisource evidence continued to support the pinned `Модуль:Дореформенная орфография@5721277` non-Page path through `Header.parse_title(..., "isPRS")` and `Module:Header@5746249` as the observed provider revision/load surface; direct MediaWiki API SHA-1 retrieval remained unavailable, so all six SHA-1/replay/historical-runtime/promotion gates stay closed. All 22 PR-triggered workflow runs for the exact head completed `success`; frozen-diagnostic run `35990136656` checked out that exact SHA and both jobs completed their standard-library and frozen-source replay steps successfully. PR #256 was marked Ready and squash-merged with expected-head protection as `318d223ed8745597c3b4174d29f3dc0f24a9d0df`; Issue #255 closed completed. `ВАР` remains unresolved at 388 invocations and effective backlog totals remain unchanged. -LAST_VERIFIED_PROGRESS: M1 deterministic metric families remain executable inferred candidates. Public corpus/showcase evidence includes exact frozen/admitted works and source-free derived outputs, while no retained work has an independently established FantLab analyzer-input identity. Perelman retains independently reviewed exact PDF/DjVu identities, pagination, current Wikisource/FantLab surface boundaries, zero-PDF-PageLabels evidence, front-matter anchors, transition/tail anchors and bounded restored-page interior observations. Darwin/Rachinsky has independently reviewed v5 dependency closure, v6 zero-argument `{{ё}}` output evidence, canonical SCRIP-CORPUS-078 one-shape promotion, canonical SCRIP-CORPUS-079 388/388 `` noinclude-containment evidence, canonical SCRIP-CORPUS-080 candidate-local promotion/backlog reduction, canonical SCRIP-CORPUS-081 revision-pinned `{{ВАР}}` documentation/module evidence with no promotion, canonical SCRIP-CORPUS-082 provider-drift evidence, and canonical SCRIP-CORPUS-083 observed-live six-revision load-closure evidence with MediaWiki SHA-1/replay gates explicitly closed. M2 stays 0/5. +LAST_COMMITTED_RUN_AT: 2026-09-24T13:02:00Z +LAST_RESULT: SCRIP-CORPUS-084 / Issue #257 / Draft PR #258 authored from exact `master@e7bf53b7ae2485b106158d09b728c72b86f9e5f6`. A dedicated official Russian Wikisource capture bound all six canonical SCRIP-CORPUS-083 observed-live `{{ВАР}}` revisions to provider page IDs, UTC timestamps, MediaWiki SHA-1 values and source-free wikitext digests. The first capture correctly failed closed because the API canonicalizes `Module:` aliases to local `Модуль:` titles; the workflow was repaired to preserve both closure alias and provider title rather than weakening identity validation. Corrected run `36002651033` succeeded after the full 598-test suite and artifact `10808782333` independently matched GitHub ZIP digest `sha256:725332a6cf98804f68dce5dd16322a8a2ba09d1921660f216afb55c8e3c896a4`. Deterministic identity evidence self-digest is `98dc8aed94fd8b4e18f0ad3325673603cba1575c1e745e1175ab4cd3a8aa2a48`. `mediawiki_sha1_complete=true`, but `replay_ready=false`; no full VAR replay, historical-transclusion/runtime proof, promotion or backlog change is claimed. Draft PR #258 is left for a later independent exact-head review; no self-merge was performed. +LAST_VERIFIED_PROGRESS: M1 deterministic metric families remain executable inferred candidates. Public corpus/showcase evidence includes exact frozen/admitted works and source-free derived outputs, while no retained work has an independently established FantLab analyzer-input identity. Perelman retains independently reviewed exact PDF/DjVu identities, pagination, current Wikisource/FantLab surface boundaries, zero-PDF-PageLabels evidence, front-matter anchors, transition/tail anchors and bounded restored-page interior observations. Darwin/Rachinsky has independently reviewed v5 dependency closure, v6 zero-argument `{{ё}}` output evidence, canonical SCRIP-CORPUS-078 one-shape promotion, canonical SCRIP-CORPUS-079 388/388 `` noinclude-containment evidence, canonical SCRIP-CORPUS-080 candidate-local promotion/backlog reduction, canonical SCRIP-CORPUS-081 revision-pinned `{{ВАР}}` documentation/module evidence with no promotion, canonical SCRIP-CORPUS-082 provider-drift evidence, canonical SCRIP-CORPUS-083 observed-live six-revision load-closure evidence, and review-pending SCRIP-CORPUS-084 source-free provider SHA-1 identities for all six exact revisions. M2 stays 0/5. ## Current unit ```text -UNIT_ID: SCRIP-CORPUS-083 -ISSUE: #255 (closed completed) -STATUS: COMPLETE -PR: #256 (squash-merged as 318d223ed8745597c3b4174d29f3dc0f24a9d0df) -NEXT_ACTION: Resume normal-flow P2 SCRIP-CORPUS selection. - A separate Darwin/Rachinsky unit may acquire MediaWiki SHA-1 for exactly the six bound SCRIP-CORPUS-083 revisions before attempting any full `{{ВАР}}` invocation replay. - Keep replay/historical-transclusion/offline-runtime/promotion/complete-renderer/body/>=300k/FantLab-input/M2 gates closed until separately evidenced. +UNIT_ID: SCRIP-CORPUS-084 +ISSUE: #257 +STATUS: REVIEW_PENDING +PR: #258 (Draft) +NEXT_ACTION: Independently review the exact final PR #258 head and its dedicated provider-capture evidence. + If clean, mark Ready and merge with expected-head protection; otherwise repair the identified blocker in a separate production judgement. + After merge, a separate bounded unit may attempt the full candidate `{{ВАР}}` invocation replay against exactly these six identities under an explicit version-pinned Scribunto/runtime boundary. + Keep historical-transclusion/promotion/complete-renderer/body/>=300k/FantLab-input/M2 gates closed until separately evidenced. ``` ## Current milestone gate @@ -30,6 +31,7 @@ Recovery/review-ready work and failing required checks preempt normal selection. | Priority | Unit | Mode | Deliverable | Gate / dependency | | --- | --- | --- | --- | --- | +| P1 | SCRIP-CORPUS-084 review | corpus / provenance | Independently judge Draft PR #258 exact head and provider-capture evidence | Do not self-approve substantive authoring; keep replay/runtime/promotion/body/FantLab/M2 gates closed | | P2 | SCRIP-CORPUS continuation | corpus / provenance | Add or strengthen legally usable >=300k candidates, prioritizing diversity beyond 19th-century Russian classics; Petersburg, Perelman and Darwin/Rachinsky have candidate-specific extraction/renderer work available | Preserve translation/edition identity and legal provenance; renderer/OCR work must keep body/admission/FantLab/M2 gates closed until separately verified | ## Retained corpus / provenance orientation @@ -51,7 +53,7 @@ Detailed evidence is canonical in `corpus/candidates/`, `benchmarks/`, `project/ - **The Twelve Chairs** — exact Page/PDF surfaces retained; template/reference semantics and body identity remain unresolved. - **The Life of Klim Samgin** — source graph/extractor/body identities retained; historical renderer equivalence and FantLab input remain unresolved. - **Children of Captain Grant — Beketova translation** — exact 1,095,467-character body with reviewed source-free deterministic showcase; no FantLab result/input identity for this translation. -- **On the Origin of Species — Rachinsky translation** — exact Page set/scan/render contracts retained. Independently reviewed v5/v6 and SCRIP-CORPUS-078 canonically resolve zero-argument `{{ё}}` for the selected live-snapshot evidence. Independently reviewed SCRIP-CORPUS-079 proves all 388 frozen self-closing `` tokens are inside stripped `` regions. Independently reviewed SCRIP-CORPUS-080 consumes only that containment fact to remove the candidate-local shape from the effective provider-reference backlog. Independently reviewed SCRIP-CORPUS-081 canonically freezes revision-pinned documentation/module evidence for `ВАР` (388) without promoting it. Independently reviewed SCRIP-CORPUS-082 canonically records current Header/provider drift plus a narrow `isPRS=false` classification replay. Independently reviewed SCRIP-CORPUS-083 canonically binds one observed-live six-revision root/load topology while keeping SHA-1/replay/promotion gates closed. Effective unresolved surface remains 4 tag shapes / 130 tag tokens and 37 template shapes / 2,356 invocations. Historical transclusion, complete renderer, literary body/>=300k and FantLab gates remain open. +- **On the Origin of Species — Rachinsky translation** — exact Page set/scan/render contracts retained. Independently reviewed v5/v6 and SCRIP-CORPUS-078 canonically resolve zero-argument `{{ё}}` for the selected live-snapshot evidence. Independently reviewed SCRIP-CORPUS-079 proves all 388 frozen self-closing `` tokens are inside stripped `` regions. Independently reviewed SCRIP-CORPUS-080 consumes only that containment fact to remove the candidate-local shape from the effective provider-reference backlog. Independently reviewed SCRIP-CORPUS-081 canonically freezes revision-pinned documentation/module evidence for `ВАР` (388) without promoting it. Independently reviewed SCRIP-CORPUS-082 canonically records current Header/provider drift plus a narrow `isPRS=false` classification replay. Independently reviewed SCRIP-CORPUS-083 canonically binds one observed-live six-revision root/load topology. Review-pending SCRIP-CORPUS-084 binds all six exact revisions to provider SHA-1 identities while leaving full replay and promotion closed. Effective unresolved surface remains 4 tag shapes / 130 tag tokens and 37 template shapes / 2,356 invocations. Historical transclusion, complete renderer, literary body/>=300k and FantLab gates remain open. - **Entertaining Physics, Book 1 — Perelman 1913** — exact PDF/DjVu carriers and reviewed pagination/facsimile boundaries retained. Complete interior mapping, global offset, PDF↔DjVu equivalence, OCR correctness, canonical carrier, literary body/>=300k, FantLab input identity and M2 remain open. ## Deterministic / morphology orientation @@ -65,7 +67,7 @@ Detailed evidence is canonical in `corpus/candidates/`, `benchmarks/`, `project/ ## Public repository representation -Public surfaces must remain source-free and synchronized with actual capability. Publish metadata, provenance, hashes and derived analysis only; never publish unlicensed source text. Perelman's transition/tail and restored-page interior companions are independently reviewed. Darwin's dependency and output-replay companions expose the selected `{{ё}}` live-snapshot evidence; SCRIP-CORPUS-078 canonically exposes that one-shape promotion; SCRIP-CORPUS-079 canonically exposes 388/388 `` noinclude containment; SCRIP-CORPUS-080 canonically exposes the separate candidate-local promotion/reduced effective backlog; SCRIP-CORPUS-081 canonically exposes independently reviewed `{{ВАР}}` documentation/module semantics without changing the effective backlog; SCRIP-CORPUS-082 canonically exposes independently reviewed later-Header/provider-drift evidence; SCRIP-CORPUS-083 now canonically exposes the independently reviewed explicit six-revision observed-live load closure while visibly keeping SHA-1/replay/promotion gates closed. +Public surfaces must remain source-free and synchronized with actual capability. Publish metadata, provenance, hashes and derived analysis only; never publish unlicensed source text. Perelman's transition/tail and restored-page interior companions are independently reviewed. Darwin's dependency and output-replay companions expose the selected `{{ё}}` live-snapshot evidence; SCRIP-CORPUS-078 canonically exposes that one-shape promotion; SCRIP-CORPUS-079 canonically exposes 388/388 `` noinclude containment; SCRIP-CORPUS-080 canonically exposes the separate candidate-local promotion/reduced effective backlog; SCRIP-CORPUS-081 canonically exposes independently reviewed `{{ВАР}}` documentation/module semantics without changing the effective backlog; SCRIP-CORPUS-082 canonically exposes independently reviewed later-Header/provider-drift evidence; SCRIP-CORPUS-083 canonically exposes the independently reviewed explicit six-revision observed-live load closure. SCRIP-CORPUS-084 now has a review-pending source-free public companion exposing the exact provider SHA-1 identities while visibly keeping replay/promotion/parity gates closed. ## Known blockers / invariants @@ -73,5 +75,5 @@ Public surfaces must remain source-free and synchronized with actual capability. 2. FantLab corrective coefficients and several parser/tokenization/dialogue semantics remain partly unpublished. 3. No corpus or showcase evidence may be promoted to parity without source-edition/input matching and explicit benchmark tolerances. 4. Perelman complete exact-carrier mapping is still required; current facsimile anchors do not prove every interior page, global offset, PDF↔DjVu equivalence, OCR correctness, body identity or >=300k admission. -5. Darwin/Rachinsky SCRIP-CORPUS-083 binds the observed-live revision-ID/load topology but MediaWiki SHA-1 remains unavailable for the six exact revisions. Therefore full VAR replay, historical transclusion, offline/version-pinned MediaWiki runtime and promotion remain closed. The 2026-09-08 community warning remains provider-drift risk evidence, not proof of a broken runtime. Complete renderer/body/FantLab gates remain open. +5. Darwin/Rachinsky has provider SHA-1 identity evidence for all six exact observed-live SCRIP-CORPUS-083 revisions in review-pending SCRIP-CORPUS-084, but full VAR replay, historical transclusion, explicit version-pinned Scribunto/MediaWiki runtime and promotion remain closed. The 2026-09-08 community warning remains provider-drift risk evidence, not proof of a broken runtime. Complete renderer/body/FantLab gates remain open. 6. Live Pages deployment remains subject to repository policy/administration and must not be implied by static build success. diff --git a/project/run-receipts/SCRIP-CORPUS-084.md b/project/run-receipts/SCRIP-CORPUS-084.md new file mode 100644 index 00000000..55d32539 --- /dev/null +++ b/project/run-receipts/SCRIP-CORPUS-084.md @@ -0,0 +1,42 @@ +# Run receipt — SCRIP-CORPUS-084 + +Status: REVIEW_PENDING + +## Orientation + +- Connected GitHub identity: `andy-zen-dev`. +- Repository: `drevendev/Scriptorium`; write permission available. +- Exact authoring base: `e7bf53b7ae2485b106158d09b728c72b86f9e5f6`. +- Issue: #257. +- Draft PR: #258. + +## Produced + +- A source-free identity contract for exactly the six observed-live Darwin/Rachinsky `{{ВАР}}` revisions frozen by canonical SCRIP-CORPUS-083. +- A dedicated workflow that re-fetches those exact revisions through the official Russian Wikisource MediaWiki revisions API and compares provider identity metadata without persisting source prose. +- Deterministic builder/validator, six focused regressions, and a public source-free identity companion. + +Evidence SHA-256: `98dc8aed94fd8b4e18f0ad3325673603cba1575c1e745e1175ab4cd3a8aa2a48`. + +## Provider capture + +The first exact-head capture run `36002505015` passed the full 598-test standard-library suite, then failed closed on a real namespace canonicalization mismatch: the dependency graph used `Module:Header`, while Russian Wikisource returned the canonical provider title `Модуль:Header`. The workflow was repaired to preserve both identities instead of weakening title checks. + +Corrected run `36002651033` completed successfully and produced artifact `10808782333`. The downloaded ZIP independently recomputed to GitHub's digest `sha256:725332a6cf98804f68dce5dd16322a8a2ba09d1921660f216afb55c8e3c896a4` and contained exactly one source-free JSON artifact. + +Provider-bound SHA-1 values: + +- `Шаблон:ВАР@3684602` — `fdb6fa7c0d4b08157bc30d44f5f77c5b9313167c` +- `Модуль:Дореформенная орфография@5721277` — `64d28378f4f620c67e1823a0d4292445d9ab293d` +- `Module:Header@5746249` / provider `Модуль:Header` — `2ab2bfdd7e49c73c4ec9ef24e4625c1d228cfba0` +- `Module:BEED@5746253` / provider `Модуль:BEED` — `9e9531e9178e0333bd3a939ace91e6a71e114cc5` +- `Module:Util@5750249` / provider `Модуль:Util` — `945f8e6bf173bb5712385995255a8b6eccef38ed` +- `Module:RomanNumber@3684553` / provider `Модуль:RomanNumber` — `51a3956469ee3fbd4ed56ce3a1f72f76f231e1d3` + +## Evidence boundary + +`revision_ids_complete=true` and `mediawiki_sha1_complete=true`, but `replay_ready=false`. No full candidate `{{ВАР}}` invocation has been replayed; historical transclusion and an explicit version-pinned Scribunto/runtime boundary remain unproven. No render-profile rule or backlog item is promoted. `ВАР` remains unresolved at 388 invocations; effective unresolved counts remain 4 tag shapes / 130 tag tokens and 37 template shapes / 2,356 template invocations. Literary-body identity, >=300k admission, FantLab analyzer-input identity and parity remain closed; M2 stays 0/5. + +## Handoff + +Draft PR #258 is intentionally left for a later independent exact-head review. The final authored head must re-run the dedicated provider capture, compare the fresh source-free identities to the committed contract, and pass the standard-library suite before review. This authoring run does not approve or merge its own substantive work. diff --git a/scriptorium/darwin_var_revision_identities.py b/scriptorium/darwin_var_revision_identities.py new file mode 100644 index 00000000..5a5e2b49 --- /dev/null +++ b/scriptorium/darwin_var_revision_identities.py @@ -0,0 +1,276 @@ +"""Bind source-free provider identities for the frozen Darwin/Rachinsky ``{{ВАР}}`` closure. + +This evidence follows SCRIP-CORPUS-083's independently reviewed observed-live +six-revision topology. It freezes exact Russian Wikisource revision identities +without persisting source prose. Completing the MediaWiki SHA-1 identity gate +does not establish a full Scribunto replay, historical transclusion, renderer +promotion, literary-body identity, or FantLab parity. +""" + +from __future__ import annotations + +import argparse +from hashlib import sha256 +import json +from pathlib import Path +import re +from typing import Mapping, Sequence + + +EVIDENCE_VERSION = "scriptorium-darwin-var-provider-revision-identities-v1" +CANDIDATE_ID = "darwin-origin-species-rachinsky-1864-ru" +PRIOR_CLOSURE_VERSION = "scriptorium-darwin-var-live-snapshot-closure-v1" +PRIOR_CLOSURE_SHA256 = "245f77bf3d99d6610ca5fbbe4fcdcdb4ef68bebca612c5bb81db6c2d77f26509" +RESEARCH_DATE = "2026-09-24" +_HEX40_RE = re.compile(r"^[0-9a-f]{40}$") +_HEX64_RE = re.compile(r"^[0-9a-f]{64}$") + +# closure_title preserves the alias used by the reviewed dependency graph. +# provider_title records the canonical title returned by Russian Wikisource. +RESOURCES = ( + ( + "Шаблон:ВАР", + "Шаблон:ВАР", + 122258, + 3684602, + "2019-06-04T20:36:46Z", + "fdb6fa7c0d4b08157bc30d44f5f77c5b9313167c", + 206, + 269, + "583f46a8f7fa2444456abede564817e134d313fb20d5cabfa2f2c48591c54707", + ), + ( + "Модуль:Дореформенная орфография", + "Модуль:Дореформенная орфография", + 378940, + 5721277, + "2026-06-08T13:06:13Z", + "64d28378f4f620c67e1823a0d4292445d9ab293d", + 1553, + 1588, + "d0199f6df8f5f789e6a5aec0e450dae6d35c3448adca411481244e40aec3004d", + ), + ( + "Module:Header", + "Модуль:Header", + 361783, + 5746249, + "2026-09-10T02:29:30Z", + "2ab2bfdd7e49c73c4ec9ef24e4625c1d228cfba0", + 54598, + 67792, + "b3950aa5a04e8a8f3bec71c6c82843643dfdc1a1a82f3788f48830f21e434ecb", + ), + ( + "Module:BEED", + "Модуль:BEED", + 362284, + 5746253, + "2026-09-10T03:41:25Z", + "9e9531e9178e0333bd3a939ace91e6a71e114cc5", + 10647, + 11979, + "108fee006a43f146302aafda316f05f15198932c3389487ed7c760c83a7c4875", + ), + ( + "Module:Util", + "Модуль:Util", + 980298, + 5750249, + "2026-09-18T07:31:28Z", + "945f8e6bf173bb5712385995255a8b6eccef38ed", + 1328, + 1585, + "a69fdcf9cf4dbbfe34d3e41585f2bcd418eee4efbe6e5c42d82e450cc4045a90", + ), + ( + "Module:RomanNumber", + "Модуль:RomanNumber", + 378544, + 3684553, + "2019-06-04T20:13:27Z", + "51a3956469ee3fbd4ed56ce3a1f72f76f231e1d3", + 1152, + 1212, + "90edb9a1d3bf5d283112fd58e28ee60f2569ae0fe7850e936a17f4e23869cf45", + ), +) + + +def _canonical_json(value: object) -> str: + return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def _sha256_json(value: object) -> str: + return sha256(_canonical_json(value).encode("utf-8")).hexdigest() + + +def build_evidence() -> dict[str, object]: + resources = [ + { + "closure_title": closure_title, + "title": provider_title, + "page_id": page_id, + "revision_id": revision_id, + "revision_timestamp": revision_timestamp, + "mediawiki_sha1": mediawiki_sha1, + "wikitext_character_count": character_count, + "wikitext_utf8_byte_count": byte_count, + "wikitext_sha256": wikitext_sha256, + } + for ( + closure_title, + provider_title, + page_id, + revision_id, + revision_timestamp, + mediawiki_sha1, + character_count, + byte_count, + wikitext_sha256, + ) in RESOURCES + ] + evidence: dict[str, object] = { + "schema_version": EVIDENCE_VERSION, + "candidate_id": CANDIDATE_ID, + "source_text_included": False, + "researched_on": RESEARCH_DATE, + "prior_closure": { + "schema_version": PRIOR_CLOSURE_VERSION, + "evidence_sha256": PRIOR_CLOSURE_SHA256, + }, + "capture_provenance": { + "provider": "Russian Wikisource", + "api_surface": ( + "MediaWiki revisions API: rvprop=ids|timestamp|sha1|content, rvslots=main" + ), + "source_text_persisted": False, + }, + "resources": resources, + "identity_gate": { + "revision_ids_complete": True, + "mediawiki_sha1_complete": True, + "provider_title_aliases_explicit": True, + "missing_mediawiki_sha1_titles": [], + "replay_ready": False, + "reason": ( + "all six exact observed-live revisions are bound to provider-returned " + "identities, but a full candidate invocation replay and an explicit " + "version-pinned Scribunto/runtime boundary are still missing" + ), + }, + "promotion_decision": { + "full_var_candidate_branch_replayed": False, + "render_profile_rule_promoted": False, + "backlog_item_removed": False, + "effective_backlog_changed": False, + "var_invocations_unresolved": 388, + "next_evidence_required": ( + "perform a separately bounded full candidate invocation replay against " + "these six exact identities with an explicit version-pinned " + "Scribunto/runtime boundary" + ), + }, + "historical_transclusion_proven": False, + "offline_version_pinned_runtime_proven": False, + "renderer_semantics_complete": False, + "renderer_implementation_ready": False, + "literary_body_count_and_digests_frozen": False, + "minimum_300k_proved": False, + "fantlab_source_edition_match": "unknown", + "m2_parity_admissible": False, + } + evidence["evidence_sha256"] = _sha256_json(evidence) + return evidence + + +def validate_evidence(evidence: Mapping[str, object]) -> None: + expected = build_evidence() + if dict(evidence) != expected: + raise ValueError("Darwin VAR provider revision identity evidence drift") + + unsigned = dict(evidence) + stored = unsigned.pop("evidence_sha256", None) + if not isinstance(stored, str) or not _HEX64_RE.fullmatch(stored): + raise ValueError("evidence SHA-256 missing or invalid") + if _sha256_json(unsigned) != stored: + raise ValueError("evidence self-digest drift") + + resources = evidence.get("resources") + if not isinstance(resources, list) or len(resources) != 6: + raise ValueError("exact six-revision identity set required") + for item in resources: + if not isinstance(item, dict): + raise ValueError("revision identity row must be an object") + mediawiki_sha1 = item.get("mediawiki_sha1") + if not isinstance(mediawiki_sha1, str) or not _HEX40_RE.fullmatch(mediawiki_sha1): + raise ValueError("provider MediaWiki SHA-1 missing or invalid") + wikitext_sha256 = item.get("wikitext_sha256") + if not isinstance(wikitext_sha256, str) or not _HEX64_RE.fullmatch(wikitext_sha256): + raise ValueError("wikitext SHA-256 missing or invalid") + if not isinstance(item.get("page_id"), int) or int(item["page_id"]) <= 0: + raise ValueError("provider page id missing or invalid") + timestamp = item.get("revision_timestamp") + if not isinstance(timestamp, str) or not timestamp.endswith("Z"): + raise ValueError("revision timestamp missing or invalid") + + gate = evidence.get("identity_gate") + if not isinstance(gate, dict): + raise ValueError("identity gate missing") + if gate.get("revision_ids_complete") is not True: + raise ValueError("revision IDs must be complete") + if gate.get("mediawiki_sha1_complete") is not True: + raise ValueError("MediaWiki SHA-1 identities must be complete") + if gate.get("provider_title_aliases_explicit") is not True: + raise ValueError("provider title aliases must be explicit") + if gate.get("missing_mediawiki_sha1_titles") != []: + raise ValueError("no MediaWiki SHA-1 identity may remain missing") + if gate.get("replay_ready") is not False: + raise ValueError("full replay gate must remain closed") + + for key in ( + "historical_transclusion_proven", + "offline_version_pinned_runtime_proven", + "renderer_semantics_complete", + "renderer_implementation_ready", + "literary_body_count_and_digests_frozen", + "minimum_300k_proved", + "m2_parity_admissible", + ): + if evidence.get(key) is not False: + raise ValueError(f"{key} must remain false") + if evidence.get("fantlab_source_edition_match") != "unknown": + raise ValueError("FantLab source match must remain unknown") + + decision = evidence.get("promotion_decision") + if not isinstance(decision, dict): + raise ValueError("promotion decision missing") + for key in ( + "full_var_candidate_branch_replayed", + "render_profile_rule_promoted", + "backlog_item_removed", + "effective_backlog_changed", + ): + if decision.get(key) is not False: + raise ValueError(f"{key} must remain false") + if decision.get("var_invocations_unresolved") != 388: + raise ValueError("VAR unresolved invocation count drift") + + +def main(argv: Sequence[str] | None = None) -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--output", type=Path, required=True) + args = parser.parse_args(argv) + evidence = build_evidence() + validate_evidence(evidence) + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text( + json.dumps(evidence, ensure_ascii=False, indent=2, sort_keys=True) + "\n", + encoding="utf-8", + ) + print(evidence["evidence_sha256"]) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/test_darwin_var_revision_identities.py b/tests/test_darwin_var_revision_identities.py new file mode 100644 index 00000000..41a3e4c4 --- /dev/null +++ b/tests/test_darwin_var_revision_identities.py @@ -0,0 +1,89 @@ +from __future__ import annotations + +import json +from pathlib import Path +import re +import unittest + +from scriptorium.darwin_var_revision_identities import RESOURCES, build_evidence, validate_evidence + + +ROOT = Path(__file__).resolve().parents[1] +EVIDENCE = ROOT / "corpus/candidates/source-edition-traces/darwin-origin-species-rachinsky-1864-ru.var-revision-identities-evidence.json" + + +class DarwinVarRevisionIdentityTests(unittest.TestCase): + def setUp(self) -> None: + self.evidence = json.loads(EVIDENCE.read_text(encoding="utf-8")) + + def test_committed_evidence_rebuilds_exactly(self) -> None: + self.assertEqual(self.evidence, build_evidence()) + validate_evidence(self.evidence) + + def test_exact_six_revision_set_is_bound(self) -> None: + resources = self.evidence["resources"] + expected = [ + (closure_title, provider_title, revision_id) + for closure_title, provider_title, _page_id, revision_id, _timestamp, _sha1, _chars, _bytes, _sha256 in RESOURCES + ] + self.assertEqual( + [(item["closure_title"], item["title"], item["revision_id"]) for item in resources], + expected, + ) + self.assertEqual(len(resources), 6) + + def test_provider_namespace_aliases_are_explicit(self) -> None: + resources = {item["closure_title"]: item for item in self.evidence["resources"]} + self.assertEqual(resources["Module:Header"]["title"], "Модуль:Header") + self.assertEqual(resources["Module:BEED"]["title"], "Модуль:BEED") + self.assertEqual(resources["Module:Util"]["title"], "Модуль:Util") + self.assertEqual(resources["Module:RomanNumber"]["title"], "Модуль:RomanNumber") + self.assertEqual(resources["Шаблон:ВАР"]["title"], "Шаблон:ВАР") + self.assertEqual( + resources["Модуль:Дореформенная орфография"]["title"], + "Модуль:Дореформенная орфография", + ) + + def test_mediawiki_sha1_identity_gate_is_complete(self) -> None: + gate = self.evidence["identity_gate"] + self.assertTrue(gate["revision_ids_complete"]) + self.assertTrue(gate["mediawiki_sha1_complete"]) + self.assertTrue(gate["provider_title_aliases_explicit"]) + self.assertEqual(gate["missing_mediawiki_sha1_titles"], []) + self.assertTrue( + all( + re.fullmatch(r"[0-9a-f]{40}", item["mediawiki_sha1"]) + for item in self.evidence["resources"] + ) + ) + + def test_provider_identity_rows_are_exact(self) -> None: + resources = {item["closure_title"]: item for item in self.evidence["resources"]} + self.assertEqual(resources["Шаблон:ВАР"]["mediawiki_sha1"], "fdb6fa7c0d4b08157bc30d44f5f77c5b9313167c") + self.assertEqual(resources["Модуль:Дореформенная орфография"]["mediawiki_sha1"], "64d28378f4f620c67e1823a0d4292445d9ab293d") + self.assertEqual(resources["Module:Header"]["mediawiki_sha1"], "2ab2bfdd7e49c73c4ec9ef24e4625c1d228cfba0") + self.assertEqual(resources["Module:BEED"]["mediawiki_sha1"], "9e9531e9178e0333bd3a939ace91e6a71e114cc5") + self.assertEqual(resources["Module:Util"]["mediawiki_sha1"], "945f8e6bf173bb5712385995255a8b6eccef38ed") + self.assertEqual(resources["Module:RomanNumber"]["mediawiki_sha1"], "51a3956469ee3fbd4ed56ce3a1f72f76f231e1d3") + self.assertEqual(resources["Module:Header"]["page_id"], 361783) + self.assertEqual(resources["Module:Header"]["revision_timestamp"], "2026-09-10T02:29:30Z") + + def test_identity_completion_does_not_open_replay_or_parity(self) -> None: + self.assertFalse(self.evidence["identity_gate"]["replay_ready"]) + self.assertFalse(self.evidence["historical_transclusion_proven"]) + self.assertFalse(self.evidence["offline_version_pinned_runtime_proven"]) + decision = self.evidence["promotion_decision"] + self.assertEqual(decision["var_invocations_unresolved"], 388) + self.assertFalse(decision["full_var_candidate_branch_replayed"]) + self.assertFalse(decision["render_profile_rule_promoted"]) + self.assertFalse(decision["backlog_item_removed"]) + self.assertFalse(decision["effective_backlog_changed"]) + self.assertFalse(self.evidence["renderer_semantics_complete"]) + self.assertFalse(self.evidence["literary_body_count_and_digests_frozen"]) + self.assertFalse(self.evidence["minimum_300k_proved"]) + self.assertEqual(self.evidence["fantlab_source_edition_match"], "unknown") + self.assertFalse(self.evidence["m2_parity_admissible"]) + + +if __name__ == "__main__": + unittest.main()