unaltraweb 0.5.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,185 @@
1
+ # unaltraweb 0.6.0 delivery closeout
2
+
3
+ Published **2026-10-02 17:28:14 UTC**:
4
+ [v0.6.0](https://github.com/dosquartsdedocs/unaltraweb/releases/tag/v0.6.0).
5
+ Owner coordination: [issue 80](https://github.com/dosquartsdedocs/unaltraweb/issues/80).
6
+ This report supersedes the pending delivery state in the chronological
7
+ [preparation record](retained-letter-import.md). Issue 76 and release 0.5.1
8
+ remain closed and immutable.
9
+
10
+ ## Review, source and integration
11
+
12
+ The owner explicitly authorized commits, push, PR review/integration, signed
13
+ candidate workflows, gated publication and the post-release launcher pin. The
14
+ checkout was reconciled against all existing unit-80 paths; no unrelated edits
15
+ were found. Work used one checkout and ordinary serial branches.
16
+
17
+ | Role | Revision / evidence |
18
+ | --- | --- |
19
+ | Reviewed implementation | `7af652fb83629e959af05c407a34a2f5a15f7936` |
20
+ | Integrated core selected by consumers | `5cf9817489c8dc47cee726bfe42fe3071cd32b85`, [PR 81](https://github.com/dosquartsdedocs/unaltraweb/pull/81) |
21
+ | Immutable core/PDF selection | `8e93b8b808204faef54cccaee622699f04a11805` |
22
+ | Final artifact-producing source | `de52db351490e94939aac20c6af264f22a6a1678`, [PR 82](https://github.com/dosquartsdedocs/unaltraweb/pull/82) |
23
+ | Receipt-only child | `3ce7606bc6148aee19d067c559823d8c5b52db5d` |
24
+ | Receipt integration and tag target | `ec6dcb28e890d32718aa173934527a7b4213a042`, [PR 83](https://github.com/dosquartsdedocs/unaltraweb/pull/83) |
25
+ | Annotated tag object | `1605578861a1a09157037e6085020baad4948d72` |
26
+
27
+ All three PRs have explicit agent review records and protected CI; those records
28
+ do not claim human review. Merge commits preserve the reviewed core's ancestry.
29
+ The receipt integration's first parent is exactly the artifact-producing source,
30
+ and its first-parent diff contains only `release-candidates.json`.
31
+
32
+ Review closed independent metadata-reference validation, malformed Pandoc-link
33
+ handling, internal PDF OpenAction destinations, and direct signed-runtime
34
+ acceptance. The vendored v1 verifier/schema still match the established hub pin
35
+ byte for byte; 26 reference conformance tests passed against matching fixtures.
36
+ Source checks reported 587 Python cases with 30 optional skips. Ruby, actual PDF,
37
+ MCP, wheel/gem, workflow/distribution, docs and reproducibility gates passed.
38
+
39
+ ## Receipt and published identities
40
+
41
+ [Tagged native receipt](https://github.com/dosquartsdedocs/unaltraweb/blob/v0.6.0/release-candidates.json):
42
+
43
+ ```text
44
+ schema_version: 1
45
+ release: v0.6.0
46
+ source_commit: de52db351490e94939aac20c6af264f22a6a1678
47
+ receipt SHA-256: 5ed4e6dd615367927e6ea8a3541c9e7dca9dad73a738851705f563e0e6895280
48
+ ```
49
+
50
+ Exactly the four `ready` components are bound to that source:
51
+
52
+ | Component | Registry artifact | SHA-256 / OCI index digest |
53
+ | --- | --- | --- |
54
+ | Gem | `unaltraweb-0.6.0.gem` | `276d04a71d1170220c3881cce8d0800633c42b0ee7ad07a376f80996c6afd177` |
55
+ | Wheel | `unaltraweb_mcp-0.6.0-py3-none-any.whl` | `3effb471ffd264f7fb2a8c88dd6536bc86639eae52806527c2d872653944c85a` |
56
+ | Base runtime | `ghcr.io/dosquartsdedocs/unaltraweb` | `sha256:a4e9d82b0e9a72e519c44e09ca449b2dc37964fbb9953ae6e4adff648e39b94b` |
57
+ | Full MCP | `ghcr.io/dosquartsdedocs/unaltraweb-mcp` | `sha256:736c4ddd0a543454e3edaeac2e9cfd97a1279ce472923ac54e326c1281b2ba05` |
58
+
59
+ Both `0.6.0` and `v0.6.0` OCI aliases were inspected anonymously and match those
60
+ index digests. The MCP's local configuration ID is
61
+ `sha256:73320210b19597243c7183ef255ffa1cbc36a07157e6ab4e1b3d9349fa89a063`;
62
+ its revision label is the exact artifact source above. Configuration IDs and
63
+ registry index digests are distinct identities.
64
+
65
+ The selected PDF 0.6.0 is the already-published, signed and tested specialization:
66
+ `ghcr.io/dosquartsdedocs/unaltraweb-manual-pdf@sha256:0ba267cb87f53ebaca4e31805fe00610cd61fdf97a8d2c3692f4655700dceaed`.
67
+ It was produced from core `5cf9817489c8dc47cee726bfe42fe3071cd32b85` by the
68
+ [initial signed image run](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37029374441),
69
+ and its local configuration ID is
70
+ `sha256:d7e7d3243616270fc9e6eed7f8238c412dbe3d9ffc18d2832d17d66ca630d139`.
71
+ The BOM, generated consumer tuple and Make default select that same digest.
72
+ It is reused as `released`, outside the four-component coordinated receipt.
73
+ The later image workflow also tested a verification-only PDF candidate
74
+ `sha256:9b3ae6fe1f04ff7de6c81c258d7c16f79cc7f2857c9b46b0829fc71812ace11f`;
75
+ that candidate is not the selected worker and received no coordinated semver
76
+ promotion. No self-digest or fabricated core SHA was introduced.
77
+
78
+ Computation, capture, Diavisuals and Vegavisuals retain the tested 0.4.0 selections.
79
+ Their exact immutable references remain in the BOM, and earlier published
80
+ artifacts and receipts remain at their original tags.
81
+
82
+ ## CI, signing and publication
83
+
84
+ | Gate | Successful run |
85
+ | --- | --- |
86
+ | Implementation PR CI / CodeQL | [37027921742](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37027921742) / [37027922332](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37027922332) |
87
+ | Core integration CI | [37028677932](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37028677932) |
88
+ | Tuple PR CI / CodeQL | [37032368507](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37032368507) / [37032368609](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37032368609) |
89
+ | Final source CI / CodeQL | [37033064607](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37033064607) / [37033064633](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37033064633) |
90
+ | Signed final image build/test | [37033593312](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37033593312) |
91
+ | Package preparation | [37033596931](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37033596931) |
92
+ | Receipt PR CI / CodeQL | [37038403708](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37038403708) / [37038403802](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37038403802) |
93
+ | Receipt/tag target CI / CodeQL | [37039075585](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37039075585) / [37039075748](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37039075748) |
94
+ | Tag CI | [37039786598](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37039786598) |
95
+ | Semver image promotion | [37040420721](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37040420721) |
96
+ | PyPI/RubyGems Trusted Publishing | [37040424945](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37040424945) |
97
+
98
+ The signed image workflows checked exact OCI digests, signer workflow, source
99
+ revision and labels before executing candidates. Promotion reverified those
100
+ bindings and reused the tested manifests without rebuilding. The package
101
+ authorizer bound workflow/run/source, immutable artifact ID `11237594327`, exact
102
+ inventory and checksums to the receipt. Its archive digest is
103
+ `sha256:79a67d7a8370468abe1f0265b248f3e9d6cf6187ac0bc891a0b3801e5a9931a6`.
104
+ OIDC jobs published only the staged verified gem and wheel.
105
+
106
+ The actual receipt-only branch, merged target and annotated tag passed strict
107
+ `distribution-release-check` and publication-ref/ancestry gates. Native package
108
+ run authorization, exact staging and `verify_package_publish.py release` passed
109
+ before privileged publication. Strict release checks apply to the receipt/tag
110
+ revision, not subsequent ordinary post-release source commits.
111
+
112
+ ## Real retained-letter and rollback proofs
113
+
114
+ Acceptance consumed the authenticated published Carta 0.3.0rc1 packet, not a local
115
+ producer checkout or synthetic unit fixture. The sender bundle hash is
116
+ `aeaa757ee1be19bfe56dc9af8dd1178032929b4a2bec2dad2ebb621b158ad999`.
117
+ All 12 seal files remain under `.unaltraweb/artifacts/carta/bundle/`.
118
+ The mapping `payload/output/letter.pdf` → `assets/documents/carta.pdf` retains
119
+ SHA-256 `4a661740a18fe1cf75b84aa0d8532511fd105eb5484a5af700e11e8e30828ea4`.
120
+ The native chapter is `_chapters/en/carta.md`, with its separate binding and
121
+ standard-v1 integration record outside the seal.
122
+
123
+ The downloaded final CI wheel ran against the exact signed MCP and selected PDF
124
+ digests above, without deriving another controller image. Both copied producer
125
+ and incoming trees were removed, author prose survived an identical reimport,
126
+ and the receiver was moved before native/generic verification and a forced PDF
127
+ rebuild. Web/HTTP checks passed at both locations. The complete original letter
128
+ appears on page 10 of an 11-page composed manual. Both composed PDFs have hash
129
+ `416e96f66bb6608b1e20bf5e36b6b16133bd4018c17e6c079e8987b736fe9cae`.
130
+ The integration record hash is
131
+ `ebe07ee10ad740a2bbbd36d532f336374cf4bb19ccb373b6590b2279f664a222`.
132
+ Generic verification confirms one bundle, one mapping and 14 verified files;
133
+ the native checker additionally binds the source and rendered page.
134
+
135
+ Local evidence root: `/tmp/opencode/unaltraweb-closeout-060/`.
136
+
137
+ | Retained evidence | SHA-256 |
138
+ | --- | --- |
139
+ | `candidate-letter-proof/evidence.json` | `618573b1a867daf6b1f3023e0d5700c27a6de429abea160b4c51ff8699f86f9c` |
140
+ | `candidate-roundtrip/evidence.json` | `23ec8885e8306931fb8ee4899e95b7bff4b3d23d2b63cdd3321e3f68722c3bb8` |
141
+ | `published-packages/verified.json` | `073d7ca1bbe46b8be5d89211501ca8fc7b71297d7eb542c4c9cc27ff167aa91e` |
142
+
143
+ The roundtrip exercised all four profiles using immutable MCP references:
144
+ 0.4.0 `sha256:389bc585cdb4fc89d3372f4896a55fe26e15df38b46bc114ce44fdb3f1c8deb9`,
145
+ unpatched 0.5.0 `sha256:36d17edbade77edb40a687f6a744203c6329acb33fbc2eb255e88d9ff1a42c98`,
146
+ then the new 0.6.0 digest. The unpatched failure was reproduced on a separate
147
+ copy. Two builds and a preview passed at 0.6.0 and again after returning to 0.4.0.
148
+ All six author/cache files retained their hashes; no caches were emptied.
149
+
150
+ ## Public downloads and post-release selection
151
+
152
+ Anonymous PyPI and RubyGems metadata and package bytes match the receipt exactly.
153
+ GitHub Release assets were downloaded again and pass `SHA256SUMS`, whose own hash
154
+ is `60d80d6e0803154a7b5c98c1731f4bec905def3a481152d4e59d7daf8932fc1a`.
155
+ A fresh public-wheel venv passed default `prepare`, `check` and real stdio `smoke`,
156
+ selecting the expected MCP configuration ID without a local factory dependency.
157
+ That public installation rechecked the relocated receiver and rendered mapping.
158
+ The public gem installed into an isolated gem home and activated as 0.6.0 using
159
+ the runtime's existing Ruby dependencies; this is not a network-fresh dependency
160
+ installation claim. The downloaded candidate gem also passed isolated native
161
+ helper-closure inspection.
162
+
163
+ The source-only post-release branch `chore/80-pin-published-mcp-0.6.0` selects the
164
+ published MCP digest in `Makefile` and `scripts/unaltraweb-mcp-bootstrap.sh`, updates
165
+ the pin regression and current docs, and accompanies this report. Its PR/merge
166
+ and final clean-main confirmation are recorded in issue 80 after protected CI.
167
+ It does not rebuild or alter the published receipt, tag or packages.
168
+
169
+ The post-pin local recheck passed 587 Python cases (558 passed, 29 optional
170
+ skips), distribution/workflow/wheel and prose checks, `mcp-check`, real
171
+ `mcp-smoke` with the selected public PDF, docs build and whitespace checks.
172
+ Development builds used only `unaltraweb-closeout-060-*:post-pin` resources.
173
+ The actual `MCP_CONSUMER_WORKSPACE`-bound `make mcp-stdio` transport also initialized
174
+ a fresh synthetic consumer and exposed both native import tools; Docker inspection
175
+ confirmed the published MCP configuration ID above. Its retained result is
176
+ `/tmp/opencode/unaltraweb-closeout-060/post-pin-proof/evidence.json` and the session
177
+ exited normally. `mcp-build` and the bootstrap's `--check` selected the public
178
+ runtime directly.
179
+
180
+ Acceptance covers the exact Linux/amd64 tuple and published English one-page
181
+ Carta sample. The generic conformance tests do not establish Diapora composition
182
+ or other domain imports. Active IDE processes keep their loaded runtime until
183
+ reconnected. No real manual, author artifact, client registration or helper
184
+ selection was migrated. Consumer adoption and hub catalogue integration remain
185
+ separate owner actions; this report supplies their verified intake evidence.
@@ -0,0 +1,235 @@
1
+ # Native retained-letter import — issue 80
2
+
3
+ Delivery completed on 2026-10-02; see [the 0.6.0 closeout](owner-closeout-80.md)
4
+ for final revisions, receipts, registry downloads and the post-release pin.
5
+ The following sections retain the chronological preparation and review evidence.
6
+
7
+ ## Scope and release state
8
+
9
+ This is a separate 0.6.0 development increment after the administrative closeout
10
+ of issue 76. Gem, wheel, runtime, MCP and PDF worker are pending. The 0.5.1 release,
11
+ receipt and active checkout launcher pin remain unchanged. Consumer core/PDF
12
+ integration and publication need their own reviewed immutable selections. The
13
+ tested computation, capture and visual companion selections remain 0.4.0.
14
+
15
+ The native receiver accepts Carta 0.3.0rc1 leaf `letter-pdf-v1` units. It retains
16
+ the entire bundle, maps the original PDF byte for byte, creates a native draft
17
+ page/chapter and checks its source and rendered references. The manual PDF
18
+ builder includes all pages with `pdfpages`; every retained dependency and checker
19
+ contributes to freshness. Nothing executes the retained producer recipe.
20
+ Composite profiles, edited PDF variants and Diapora are outside this acceptance.
21
+
22
+ ## Protocol and provenance
23
+
24
+ The wire v1 verifier and schema are byte-identical copies pinned to hub revision
25
+ `9167e3efb5968a64bb9100792163a179c1491860` (integration
26
+ `fc8745db950b04013c73eb49acf6781a26eb83f8`). Their respective SHA-256 values are
27
+ `48368035f242f4d4446cbbe1363f8a01a7c17fa164ffef21abadd878b288d82d` and
28
+ `b52a32b3bcfeed28cf34a9ec1557665a94466b51c451ccad47d2e87f6e23f9aa`.
29
+ No envelope fields were added. `binding.json` is a separate native record.
30
+ The integration actor identifies the importer by a hash of its code inventory,
31
+ not an invented or uncommitted Git revision.
32
+
33
+ Acceptance uses the final published
34
+ [Carta v0.3.0rc1 packet](https://github.com/dosquartsdedocs/unaltracarta/releases/tag/v0.3.0rc1),
35
+ revision `84258b6869689ea5f1a49a55abc2b865573fb512`:
36
+
37
+ | Artifact | SHA-256 |
38
+ | --- | --- |
39
+ | `distribution.json` | `9d94b918db086b445e4d8a3ece2435622e0f9f9893bcd50708b4d13f5ca0ad44` |
40
+ | `acceptance-0.3.0rc1.json` | `1bc7c467f3e35abf9fa5c27583dd8cc3ad4d4372f930c4be60ed142122158504` |
41
+ | `acceptance-0.3.0rc1.tar.gz` | `8764a717bda33e15b48b3a06fe6fbe5dc075abedf4fd52bd37fdf4ed70896179` |
42
+ | Published wheel | `0afab176ea0815d242f6e19021232bafdc63f9bb68cbacbd63b73f99b666b7c3` |
43
+ | Wheel bundle manifest | `aeaa757ee1be19bfe56dc9af8dd1178032929b4a2bec2dad2ebb621b158ad999` |
44
+ | Retained original PDF | `4a661740a18fe1cf75b84aa0d8532511fd105eb5484a5af700e11e8e30828ea4` |
45
+
46
+ The original producer job was
47
+ `.unaltracarta-handoff/jobs/a0794f7909a943eb844c87bb14002691/bundle/`.
48
+ Its renderer identity is
49
+ `sha256:ba2453fb42542433f68efd8888d628b95f256cefb9c545b3b35034d33296e340`.
50
+ The installed test authenticates the packet before bounded extraction and checks
51
+ every declared evidence file. Earlier release-candidate bytes are not inputs.
52
+
53
+ ## Installed acceptance
54
+
55
+ `test/artifact_import_smoke.py` uses a wheel-installed CLI and Docker launcher,
56
+ without a host factory dependency. It creates a synthetic manual, imports the
57
+ published wheel bundle, edits surrounding prose, verifies an identical reimport
58
+ preserves that prose and removes both the extracted producer copy and incoming
59
+ copy. It then builds the web and PDF, checks the served page/PDF, moves the
60
+ receiver, runs both native and generic v1 checks, and explicitly rebuilds the
61
+ PDF in the moved receiver. Every original page must occur in order in the
62
+ composed PDF; comparison uses the original font encoding, including ligatures.
63
+
64
+ The passing local run is retained at
65
+ `/tmp/opencode/unaltraweb-import-80/installed-proof-final/evidence.json`.
66
+ Its receiver is `relocated-receiver/` in that directory. This is local owner
67
+ evidence from development images, not a signed release receipt.
68
+
69
+ | Tested identity | Value |
70
+ | --- | --- |
71
+ | Installed unaltraweb wheel SHA-256 | `407b1275d1de558da891f391454287d1b3e76fbef0e45460695e9731932b9e39` |
72
+ | Controller image ID | `sha256:81f1da616455c7378ba3400b9d638eb8e67fce9605f18353d49a796020d9b6fa` |
73
+ | PDF worker image ID | `sha256:b7b8f5b774a528cadb2ab7aa313b9ddbffa6d54c9d3b42bd6ff59a664be8ccf6` |
74
+ | Integration record SHA-256 | `79ede9c8701eedf6ca4f182dc4fd1c9df3b56581138c677e0315310d8b998d1c` |
75
+ | Composed PDF before and after relocation | `14b0ef586874704b6d1b045d6dde1f32ee08c8a9107006e06cfe2e8147f54621` |
76
+
77
+ The receiver retains all 12 seal files under
78
+ `.unaltraweb/artifacts/carta/bundle/`. Its mapping is
79
+ `payload/output/letter.pdf` → `assets/documents/carta.pdf`, with native content at
80
+ `_chapters/en/carta.md` and permalink `/en/retained/carta/` under `/letter-proof`.
81
+ The original one-page letter appears on page 10 of the 11-page composed manual.
82
+ Both web/HTTP checks passed; the non-web archive was absent from `_site`.
83
+ Generic verification after relocation passed with one bundle, one mapping and
84
+ 14 verified files. Preview copies were cleaned through their exact receipts.
85
+
86
+ Intermediate failures are retained separately: missing explicit gem plugin
87
+ registration, an overly broad rendered-HTML scan, mismatched controller/worker
88
+ checker bytes, and an assertion that ignored the original PDF's ligature
89
+ encoding. Corrections preserve strict integrity/freshness gates. In particular,
90
+ the installed-image fixture force-reinstalls its supplied wheel even when its
91
+ development version equals the base image's version.
92
+
93
+ ## Reproduction and boundaries
94
+
95
+ Prepare an installed wheel, the matching source-containing MCP image, and a PDF
96
+ worker built from the repository root with `scripts/manual/Dockerfile`. The test
97
+ controller in `test/artifact_import.Dockerfile` binds `MANUAL_PDF_IMAGE` to the
98
+ worker image ID. Then run:
99
+
100
+ ```bash
101
+ python test/artifact_import_smoke.py \
102
+ --packet "$PUBLISHED_CARTA_PACKET" --output "$NEW_EVIDENCE_DIRECTORY" \
103
+ --cli "$INSTALLED/bin/unaltraweb-mcp" \
104
+ --launcher "$INSTALLED/bin/unaltraweb-mcp-docker" \
105
+ --image "$TEST_CONTROLLER" --pdf-image "$TEST_PDF_WORKER"
106
+ ```
107
+
108
+ The output directory must not exist. Only copies created by the test are retired.
109
+ Unit-test bundles in `test/test_artifact_imports.py` are synthetic security and
110
+ transaction fixtures, not published-producer acceptance. They cover tampering,
111
+ incomplete resources, hidden references, symlinks/hardlinks, no-overwrite,
112
+ interruption/retry, generated-source ownership, PDF action aliases/chains,
113
+ rendered URL binding, native PDF inclusion and dependency closure.
114
+
115
+ The imported unit is portable because its seal, record, mapped PDF and content
116
+ all use receiver-relative paths. The integration does not depend on the incoming
117
+ directory, producer process, absolute source location or ignored recovery tree.
118
+ Failed publication retains prepared and partial files; there is no destructive
119
+ rollback. Reimport adopts only identical existing bytes and preserves authored
120
+ prose when the binding remains valid.
121
+
122
+ Final release gates must additionally bind the reviewed core/PDF consumer tuple
123
+ and same-source package/image candidates. A local acceptance run does not update
124
+ those pins, authenticate a public 0.6.0 release, authorize real-manual adoption,
125
+ or grant author approval to the draft content.
126
+
127
+ The gem and PDF worker include a regular Python package initializer and its
128
+ stdlib-only version/contract module. This prevents an unrelated installed wheel
129
+ from shadowing the gem's helpers. The extracted-gem gate asserts the actual
130
+ module paths. Checker code and schemas enter PDF freshness; the validated BOM's
131
+ worker/self pins do not, avoiding a worker that would need to contain its own
132
+ future digest. The integration actor separately hashes the full BOM metadata.
133
+
134
+ ## Owner regression gates
135
+
136
+ - Python suite: 584 tests, 30 environment-dependent skips, no failures. The
137
+ focused importer suite covers 22 cases; the PDF builder suite covers 88.
138
+ - Ruby plugin suites: 64 tests and 334 assertions, no failures.
139
+ - Actual PDF toolchain integrations: 16 tests, no failures.
140
+ - `distribution-check`, `workflow-check`, `wheel-check`, `gem-check`,
141
+ `mcp-check`, `mcp-smoke`, `docs-build`, and fixed-epoch
142
+ `reproducible-site-check` passed on local owner resources. Distribution remains
143
+ structurally valid and explicitly not release-ready.
144
+ - The extracted-gem package gate exercises synthetic native retention using only
145
+ the gem's Python helper closure, with isolated Python and no wheel/core path.
146
+ Native deployment installs its parser dependencies before PDF/Jekyll checks.
147
+ - Populated Bundler roundtrip passed for `unaltreselfie`, `unaltreprojecte`,
148
+ `unaltredocs` and `unaltremanual`, with two builds and a preview per runtime.
149
+ It first reproduces the published unpatched 0.5.0 `google-protobuf (4.36.1)`
150
+ failure on a separate copy, then tests 0.4.0 → development 0.6.0 → 0.4.0.
151
+ The historical driver labels its patched step `fixed-050`; the recorded
152
+ image is the 0.6.0 test controller. All six retained author/cache paths keep
153
+ their initial hashes; no cache cleaning is used to obtain a pass.
154
+
155
+ Roundtrip evidence is retained at
156
+ `/tmp/opencode/unaltraweb-import-80/bundler-roundtrip-final/evidence.json`, using
157
+ the same final controller and worker IDs as the installed letter acceptance.
158
+ The source discovery descriptor additionally declares `.unaltraweb/artifacts`
159
+ as optional versioned source state with `cleanup: never`; `tmp` keeps its existing
160
+ ignored, explicit-cleanup policy. This final metadata-only addition is checked by
161
+ the path-policy and fresh-wheel gates and does not alter the tested import code.
162
+
163
+ ## Closeout review — 2026-10-02
164
+
165
+ The owner explicitly authorized the full 0.6.0 commit/PR/integration, signed
166
+ candidate, gated publication and post-release pin flow. The session preflight
167
+ reported only the known unit-80 working tree and no competing session. Review
168
+ covered every tracked/untracked unit path; no unrelated changes were identified.
169
+
170
+ The two vendored protocol files match the exact established Git pin. The pinned
171
+ reference tests and fixture payloads were also checked (the later fixture README
172
+ only renames the integrated contract), and all 26 conformance tests pass. These
173
+ generic synthetic tests do not add a composite domain to the native importer.
174
+ The retained installed wheel/PDF hashes above and the moved receiver's native
175
+ web/PDF mapping were independently rechecked before editing.
176
+
177
+ Resolved review findings:
178
+
179
+ - Metadata could contain a local link or image while retained Pandoc evidence
180
+ remained stale. Renderable metadata now receives the independent text-reference
181
+ check; effective metadata rejects render-option fields outside the supported
182
+ author/stamp projection. Malformed Pandoc link evidence returns a structured
183
+ domain failure instead of an uncaught indexing error.
184
+ - A PDF OpenAction internal destination array was treated as an action array.
185
+ Internal destinations are supported while chained action arrays retain their
186
+ stricter checks. Regression tests cover both cases.
187
+ - The acceptance driver required a derived test-controller image. It now also
188
+ verifies the immutable PDF selection declared by the actual installed MCP image
189
+ and records the exact image references and source label, allowing signed bytes
190
+ to be exercised directly.
191
+
192
+ The corrected source passes 587 Python tests (30 optional skips), including 25
193
+ native import cases, plus distribution/workflow/fresh-wheel gates. The historical
194
+ local evidence above remains retained; signed-candidate and public-download
195
+ acceptance must record their own revisions and hashes. The consumer core/PDF
196
+ tuple is closed only after the reviewed integrated core and signed PDF digest
197
+ exist; no guessed source or self-digest is inserted into the BOM.
198
+
199
+ ## Reviewed immutable consumer tuple
200
+
201
+ PR [81](https://github.com/dosquartsdedocs/unaltraweb/pull/81) integrated reviewed
202
+ implementation `7af652fb83629e959af05c407a34a2f5a15f7936` as
203
+ `5cf9817489c8dc47cee726bfe42fe3071cd32b85`. Protected PR CI
204
+ [37027921742](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37027921742)
205
+ and CodeQL [37027922332](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37027922332)
206
+ passed, followed by integrated-source CI
207
+ [37028677932](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37028677932)
208
+ and CodeQL [37028678347](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37028678347).
209
+ The PR contains an explicit agent review, not an attributed human approval.
210
+
211
+ Signed image workflow
212
+ [37029374441](https://github.com/dosquartsdedocs/unaltraweb/actions/runs/37029374441)
213
+ then published, attested and tested the PDF from that exact source. Its read-only
214
+ test job verified the signer workflow/source digest before executing the exact
215
+ image, including 16 PDF integrations and real MCP preparation. The selected
216
+ PDF 0.6.0 identity is
217
+ `ghcr.io/dosquartsdedocs/unaltraweb-manual-pdf@sha256:0ba267cb87f53ebaca4e31805fe00610cd61fdf97a8d2c3692f4655700dceaed`.
218
+ The BOM and Make contract now select that same digest and integrated core SHA.
219
+
220
+ That public signed PDF is recorded as `released` and reused by digest. The four
221
+ core/package components are `ready` for final same-commit candidates; their strict
222
+ gate still requires a new receipt-only child of the final artifact source.
223
+ Subsequent verification-only PDF builds are not substituted for this selected
224
+ worker or promoted under an assumed identity. The earlier 0.5.1 receipt and
225
+ active launcher pin remain intact until the authorized 0.6.0 closeout completes.
226
+
227
+ The tuple was exercised before its pin PR using an installed wheel and a local
228
+ MCP containing the new BOM with the actual signed PDF above. Evidence is retained
229
+ at `/tmp/opencode/unaltraweb-closeout-060/tuple-letter-proof/evidence.json`:
230
+ integration `ebe07ee10ad740a2bbbd36d532f336374cf4bb19ccb373b6590b2279f664a222`,
231
+ composed PDF `416e96f66bb6608b1e20bf5e36b6b16133bd4018c17e6c079e8987b736fe9cae`
232
+ both before and after the forced relocated rebuild. The PDF's inspected local
233
+ image ID is `sha256:d7e7d3243616270fc9e6eed7f8238c412dbe3d9ffc18d2832d17d66ca630d139`,
234
+ with the exact integrated source revision label. This preparation proof does not
235
+ substitute for the final signed MCP and downloaded package acceptance.
data/lib/unaltraweb.rb CHANGED
@@ -21,6 +21,7 @@ require_relative "unaltraweb/version"
21
21
  content_search_index
22
22
  manual_release_metadata
23
23
  reproducible_build_time
24
+ retained_documents
24
25
  profile-pages
25
26
  remove-accents
26
27
  search-data
data/requirements.txt CHANGED
@@ -3,3 +3,5 @@ scholarly
3
3
  requests
4
4
  bibtexparser
5
5
  rdata
6
+ pypdf>=6,<7
7
+ markdown-it-py>=3,<5
@@ -23,9 +23,12 @@ RUN printf '%s\n' \
23
23
  && rm -rf /var/lib/apt/lists/* \
24
24
  && pip install --no-cache-dir PyYAML==6.0.2
25
25
 
26
- COPY build_pdf.py /opt/unaltraweb/manual/build_pdf.py
27
- COPY Dockerfile /opt/unaltraweb/manual/Dockerfile
28
- COPY filters /opt/unaltraweb/manual/filters
29
- COPY templates /opt/unaltraweb/manual/templates
26
+ RUN pip install --no-cache-dir 'pypdf>=6,<7' 'markdown-it-py>=3,<5'
27
+ COPY scripts/manual/build_pdf.py /opt/unaltraweb/manual/build_pdf.py
28
+ COPY scripts/manual/Dockerfile /opt/unaltraweb/manual/Dockerfile
29
+ COPY scripts/manual/filters /opt/unaltraweb/manual/filters
30
+ COPY scripts/manual/templates /opt/unaltraweb/manual/templates
31
+ COPY src/unaltraweb_mcp/__init__.py src/unaltraweb_mcp/distribution.py src/unaltraweb_mcp/component-contract.json src/unaltraweb_mcp/component-contract.schema.json src/unaltraweb_mcp/artifact_handoff_v1.py src/unaltraweb_mcp/artifact-handoff-v1.schema.json src/unaltraweb_mcp/artifact_imports.py src/unaltraweb_mcp/letter_bundle.py src/unaltraweb_mcp/pdf_probe.py src/unaltraweb_mcp/processes.py /opt/unaltraweb/src/unaltraweb_mcp/
32
+ ENV PYTHONPATH=/opt/unaltraweb/src
30
33
 
31
34
  ENTRYPOINT ["python3", "/opt/unaltraweb/manual/build_pdf.py"]
@@ -26,6 +26,10 @@ except ImportError as exc: # pragma: no cover - supplied by the builder image
26
26
 
27
27
 
28
28
  SCRIPT_ROOT = Path(__file__).resolve().parent
29
+ for _source_root in (SCRIPT_ROOT.parent.parent / "src", SCRIPT_ROOT.parent / "src"):
30
+ if (_source_root / "unaltraweb_mcp" / "artifact_imports.py").is_file():
31
+ sys.path.insert(0, str(_source_root))
32
+ break
29
33
  DEFAULT_DOCKERFILE = SCRIPT_ROOT / "Dockerfile"
30
34
  DEFAULT_TEMPLATE = SCRIPT_ROOT / "templates" / "manual.tex"
31
35
  DEFAULT_BIBLIOGRAPHY_FILTER = SCRIPT_ROOT / "filters" / "bibliography.lua"
@@ -36,6 +40,7 @@ BIB_CUSTOM_URL_RE = re.compile(r'(?im)^\s*(?:manual_url|website)\s*=\s*(?:\{([^}
36
40
  FRONT_MATTER_RE = re.compile(r"\A---[ \t]*\r?\n(.*?)^---[ \t]*(?:\r?\n|\Z)", re.MULTILINE | re.DOTALL)
37
41
  CITE_RE = re.compile(r"{%\s*cite\s+([^%]+?)\s*%}")
38
42
  INCLUDE_RE = re.compile(r"{%\s*include\s+([^%]+?)\s*%}")
43
+ RETAINED_DOCUMENT_RE = re.compile(r"{%\s*retained_document\s+([a-z][a-z0-9-]{0,63})\s*%}")
39
44
  LIQUID_RE = re.compile(r"({[{%].*?[}%]})", re.DOTALL)
40
45
  INLINE_CODE_RE = re.compile(r"<code>(.*?)</code>", re.IGNORECASE | re.DOTALL)
41
46
  FENCED_CODE_BLOCK_RE = re.compile(r"^[ \t]*(`{3,}|~{3,})[^\n]*\n.*?^[ \t]*\1[ \t]*$", re.MULTILINE | re.DOTALL)
@@ -947,6 +952,17 @@ def transform_markdown(
947
952
  citation_keys.extend(key for key in keys if key not in citation_keys)
948
953
  return "[" + "; ".join(f"@{key}" for key in keys) + "]"
949
954
 
955
+ def retained_document(match: re.Match[str]) -> str:
956
+ from unaltraweb_mcp.artifact_imports import check_imports
957
+
958
+ result = check_imports(project, match.group(1))
959
+ if result.get("ok") is not True:
960
+ raise ManualPdfError(f"Retained document verification failed: {result.get('error')}")
961
+ path = result["imports"][0]["pdf"]
962
+ # The native import layout uses an ASCII slug and fixed project-relative
963
+ # path; no bundle text is interpolated into TeX or executed.
964
+ return protect("```{=latex}\n\\includepdf[pages=-,pagecommand={}]" + "{" + path + "}\n```")
965
+
950
966
  def table(match: re.Match[str]) -> str:
951
967
  body = match.group("body").strip()
952
968
  credit, _ = caption_source_attribute(match.group("attrs") or "")
@@ -1137,6 +1153,7 @@ def transform_markdown(
1137
1153
  transformed = transformed.replace(r"\begin{equation\*}", r"\begin{equation*}")
1138
1154
  transformed = transformed.replace(r"\end{equation\*}", r"\end{equation*}")
1139
1155
  transformed = BASEURL_RE.sub("", transformed)
1156
+ transformed = RETAINED_DOCUMENT_RE.sub(retained_document, transformed)
1140
1157
  transformed = transformed.replace("{% include manual-bibliography.liquid %}", "::: {#refs}\n:::")
1141
1158
  transformed = CITE_RE.sub(citations, transformed)
1142
1159
  transformed = CALLOUT_BLOCK_RE.sub(callout, transformed)
@@ -1481,6 +1498,17 @@ def build_dependencies(project: Path, metadata: dict[str, Any], source_paths: li
1481
1498
  ]
1482
1499
  for path in source_paths:
1483
1500
  dependencies.append((f"source:{path.relative_to(project)}", path))
1501
+ if any(RETAINED_DOCUMENT_RE.search(path.read_text(encoding="utf-8")) for path in source_paths if path.suffix.lower() == ".md"):
1502
+ from unaltraweb_mcp import artifact_imports
1503
+
1504
+ imports = artifact_imports.check_imports(project)
1505
+ if imports.get("ok") is not True:
1506
+ raise ManualPdfError(f"Retained document verification failed: {imports.get('error')}")
1507
+ for item in imports["imports"]:
1508
+ dependencies.extend((f"retained:{relative}", project / relative) for relative in item["inputs"])
1509
+ checker_root = Path(artifact_imports.__file__).parent
1510
+ for name in artifact_imports.CHECKER_FILES:
1511
+ dependencies.append((f"import-check:{name}", checker_root / name))
1484
1512
  if csl:
1485
1513
  dependencies.append((f"csl:{csl.relative_to(project)}", csl))
1486
1514
  for key in ["cover-image", "cover-logo", "series-logo"]:
@@ -10,6 +10,7 @@
10
10
  \usepackage{float}
11
11
  \usepackage{framed}
12
12
  \usepackage{graphicx}
13
+ \usepackage{pdfpages}
13
14
  \usepackage{grffile}
14
15
  \usepackage{longtable}
15
16
  \usepackage{array}
@@ -64,6 +64,9 @@ def inspect_gem(path: Path) -> None:
64
64
  editorial_files = ["scripts/editorial_check.py", "src/unaltraweb_mcp/editorial.py", "src/unaltraweb_mcp/editorial_sources.py"]
65
65
  inspection_files = editorial_files + ["src/unaltraweb_mcp/bundler_runtime.py", "scripts/image_background_check.py", "src/unaltraweb_mcp/image_backgrounds.py",
66
66
  "src/unaltraweb_mcp/image_probe.py", "src/unaltraweb_mcp/processes.py"]
67
+ inspection_files += [f"src/unaltraweb_mcp/{name}" for name in (
68
+ "__init__.py", "distribution.py", "component-contract.json", "component-contract.schema.json",
69
+ "artifact_imports.py", "artifact_handoff_v1.py", "artifact-handoff-v1.schema.json", "letter_bundle.py", "pdf_probe.py")]
67
70
  with tarfile.open(path, mode="r") as package:
68
71
  data_member = package.extractfile("data.tar.gz")
69
72
  if data_member is None:
@@ -83,6 +86,7 @@ def inspect_gem(path: Path) -> None:
83
86
  "_plugins/figure_captions.rb",
84
87
  "_plugins/manual_release_metadata.rb",
85
88
  "_plugins/reproducible_build_time.rb",
89
+ "_plugins/retained_documents.rb",
86
90
  "assets/js/content-search-match.js",
87
91
  "assets/js/content-search.js",
88
92
  "_config.yml",
@@ -134,6 +138,29 @@ def inspect_gem(path: Path) -> None:
134
138
  inspection = json.loads(run(image_command, cwd=site).stdout)
135
139
  if not inspection["ok"] or inspection["images"][0]["state"] != "transparent" or not inspection["warnings"]:
136
140
  raise RuntimeError(f"Gem-native SVG background inspection failed: {inspection}")
141
+ # This is the synthetic domain fixture, not published-Carta acceptance.
142
+ # Only its data crosses into the isolated extracted-gem subprocess.
143
+ sys.path.insert(0, str(ROOT / "test"))
144
+ from test_artifact_imports import fixture
145
+
146
+ bundle_sha, template_sha = fixture(site / "incoming/letter")
147
+ (site / ".gitignore").write_text("tmp/\n", encoding="utf-8")
148
+ run(["git", "init", "--quiet"], cwd=site)
149
+ isolated = """
150
+ import json, sys
151
+ from pathlib import Path
152
+ sys.path.insert(0, sys.argv[1])
153
+ from unaltraweb_mcp import artifact_imports, letter_bundle, artifact_handoff_v1, distribution, processes
154
+ for module in (artifact_imports, letter_bundle, artifact_handoff_v1, distribution, processes):
155
+ assert Path(module.__file__).is_relative_to(Path(sys.argv[1])), module.__file__
156
+ letter_bundle.TEMPLATES['default-letter.latex'] = sys.argv[4]
157
+ project = Path(sys.argv[2])
158
+ result = artifact_imports.import_bundle(project, 'incoming/letter/bundle.json', sys.argv[3],
159
+ 'letter', '_pages/en/letter.md', dry_run=False, confirm_import=True)
160
+ print(json.dumps(result))
161
+ raise SystemExit(0 if result['ok'] else 1)
162
+ """
163
+ run([sys.executable, "-I", "-c", isolated, str(core / "src"), str(site), bundle_sha, template_sha], cwd=site)
137
164
 
138
165
 
139
166
  def main() -> int:
@@ -90,6 +90,11 @@ def main() -> int:
90
90
  required = [
91
91
  "unaltraweb_mcp/calibre_import.py",
92
92
  "unaltraweb_mcp/bundler_runtime.py",
93
+ "unaltraweb_mcp/artifact_imports.py",
94
+ "unaltraweb_mcp/artifact_handoff_v1.py",
95
+ "unaltraweb_mcp/artifact-handoff-v1.schema.json",
96
+ "unaltraweb_mcp/letter_bundle.py",
97
+ "unaltraweb_mcp/pdf_probe.py",
93
98
  "unaltraweb_mcp/component-contract.json",
94
99
  "unaltraweb_mcp/component-contract.schema.json",
95
100
  "unaltraweb_mcp/manual_pdf_preview.py",
@@ -137,14 +142,14 @@ def main() -> int:
137
142
  fake_bin = temp / "fake-bin"
138
143
  fake_bin.mkdir()
139
144
  fake_docker = fake_bin / "docker"
140
- fake_docker.write_text("#!/bin/sh\n[ \"$1 $2\" = 'image inspect' ] || exit 99\n[ \"$5\" = \"$EXPECTED_IMAGE\" ] || exit 98\nprintf 'sha256:fixture\\n'\n", encoding="utf-8")
145
+ fake_docker.write_text("#!/bin/sh\n[ \"$1 $2\" = 'image inspect' ] || exit 99\n[ \"$5\" = \"$EXPECTED_IMAGE\" ] || exit 98\nprintf 'sha256:1111111111111111111111111111111111111111111111111111111111111111\\n'\n", encoding="utf-8")
141
146
  fake_docker.chmod(0o755)
142
147
  expected_image = json.loads((ROOT / "src/unaltraweb_mcp/component-contract.json").read_text())["components"]["mcp"]["reference"]
143
148
  launcher_env = {**no_consumer_env, "PATH": f"{fake_bin}:{env['PATH']}", "EXPECTED_IMAGE": expected_image}
144
149
  launcher_env.pop("UNALTRAWEB_MCP_IMAGE", None)
145
150
  launcher_env.pop("MCP_RELEASE_IMAGE", None)
146
151
  prepared_image = run([str(docker_cli), "prepare"], cwd=temp, env=launcher_env).stdout.strip()
147
- if prepared_image != "sha256:fixture":
152
+ if prepared_image != "sha256:" + "1" * 64:
148
153
  raise RuntimeError("Installed preparation did not use the packaged bootstrap")
149
154
  run(["make", "--silent", "--no-print-directory", "-C", str(launcher), "mcp-build"], cwd=temp, env=launcher_env)
150
155
  run([str(docker_cli), "prepare", "--image", "explicit:override"], cwd=temp,