unaltraweb 0.7.1 → 0.7.2
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.
- checksums.yaml +4 -4
- data/Makefile +26 -4
- data/docs/_documentation/en/40-distribution.md +33 -10
- data/docs/_documentation/en/43-workspace-path-policies.md +13 -0
- data/docs/_documentation/en/47-private-practice-pdfs.md +130 -0
- data/docs/agents/consolidation-0.7.2.md +97 -0
- data/docs/agents/d0-runtime-identity.md +8 -0
- data/docs/agents/deployment-integration-0.7.1.md +4 -0
- data/docs/agents/manual-authoring-components.md +23 -0
- data/docs/agents/mcp-contract.md +109 -4
- data/docs/agents/owner-closeout-93.md +185 -0
- data/docs/agents/practice-editions-98.md +816 -0
- data/docs/agents/practice-pdf-installable-98.md +250 -0
- data/docs/agents/practice-runtime-archives-98.md +147 -0
- data/docs/agents/private-practice-verifier-98.md +296 -0
- data/docs/agents/source-ci-98.md +148 -0
- data/scripts/check_practice_verifier_runtime.py +69 -0
- data/scripts/export_practice_runtime_archives.py +138 -0
- data/scripts/manual/filters/practice-finish.lua +36 -0
- data/scripts/manual/filters/practice-layout.lua +84 -0
- data/scripts/manual/practice_pdf.py +31 -0
- data/scripts/manual/render_practice.py +125 -0
- data/scripts/manual/templates/practice.tex +95 -0
- data/scripts/prepare_practice_candidate.py +159 -0
- data/scripts/prepare_practice_editions_candidate.py +119 -0
- data/scripts/test_wheel_install.py +15 -0
- data/scripts/unaltraweb-mcp-bootstrap.sh +1 -1
- data/scripts/validate_distribution.py +18 -1
- data/src/unaltraweb_mcp/component-contract.json +28 -17
- data/src/unaltraweb_mcp/editorial_sources.py +62 -4
- metadata +19 -2
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# Web #98 — installable practice-PDF candidate
|
|
2
|
+
|
|
3
|
+
Coordination: [gaContExt #32](https://github.com/dosquartsdedocs/gacontext/issues/32).
|
|
4
|
+
Owner: [Web #98](https://github.com/dosquartsdedocs/unaltraweb/issues/98).
|
|
5
|
+
Date: 2026-10-08. **Phase 1 completed as a local immutable candidate; publication
|
|
6
|
+
and real-manual adoption remain separate decisions.**
|
|
7
|
+
|
|
8
|
+
## Scope and checkout
|
|
9
|
+
|
|
10
|
+
Authoritative checkout: `/home/benizar/git/unaltraweb`.
|
|
11
|
+
Branch: `feat/98-installable-practice-pdf`.
|
|
12
|
+
HEAD and exact candidate runtime source:
|
|
13
|
+
`d37ef4c64eb7d2f2e7ef83cf037640ff42a964e0` (approved PR #101).
|
|
14
|
+
Preflight was ELIGIBLE, clean, one checkout and no competing session.
|
|
15
|
+
|
|
16
|
+
The W1 branch/PR #103 remains preserved at
|
|
17
|
+
`6b81fc0466254a9bc8f506335d82b5f532a4fc35`; its source and historical test resources
|
|
18
|
+
were not used as this candidate. The superseding shared-runtime direction in
|
|
19
|
+
gaContExt #30 is respected. This unit creates no job volumes, ledgers or generic
|
|
20
|
+
runtime implementation.
|
|
21
|
+
|
|
22
|
+
[Exact reservation](https://github.com/dosquartsdedocs/unaltraweb/issues/98#issuecomment-6066502338):
|
|
23
|
+
|
|
24
|
+
- `scripts/prepare_practice_candidate.py` — explicit offline candidate preparation.
|
|
25
|
+
- `packaging/practice-candidate/Dockerfile` — installation onto the prepared public MCP base.
|
|
26
|
+
- `test/practice_candidate_smoke.py` — installed selection and actual two-recipient acceptance.
|
|
27
|
+
- `test/test_practice_candidate.py` — preparation identity/no-clobber/path refusal tests.
|
|
28
|
+
- `test/test_practice_pdf.py` — reserved, unchanged.
|
|
29
|
+
- `docs/agents/practice-pdf-installable-98.md` — this return.
|
|
30
|
+
|
|
31
|
+
Only the five new preparation/test/report files are local changes. Runtime code,
|
|
32
|
+
approved templates, package versions, consumer pins and published receipts are
|
|
33
|
+
unchanged on this branch. New tooling is left uncommitted: this assignment did not
|
|
34
|
+
grant a new commit/push/release approval. The candidate itself comes entirely from
|
|
35
|
+
the already committed approved source, not these uncommitted helper files.
|
|
36
|
+
|
|
37
|
+
## Immutable candidate
|
|
38
|
+
|
|
39
|
+
Candidate directory:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
/home/benizar/git/unaltraweb/tmp/practice-candidate-98/candidate-02/
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
| Artifact | SHA-256 |
|
|
46
|
+
| --- | --- |
|
|
47
|
+
| `candidate.json` | `68f2b87763d401e37d01eced4da66a4cfa4dc39c7c684dd457266ab4839bba42` |
|
|
48
|
+
| `packages/unaltraweb_mcp-0.7.1-py3-none-any.whl` | `9fb813becf28e89f6e6b39d6f045cf2236d5085de03ef9c8b5c94f2d6721516a` |
|
|
49
|
+
| `controller.docker.tar.gz` | `72d35901a3e890bba554e5325523ea1764d8f92a4a01e9d258891101010f9bfe` |
|
|
50
|
+
| `source.tar.gz` | `12cf228f87188cd51882e27d8183969818692f4ae712e51dfc2d6e0649220b22` |
|
|
51
|
+
|
|
52
|
+
The portable image archive is 523,629,933 bytes. Its real `docker image load` was
|
|
53
|
+
tested. The loaded **Docker configuration ID** is:
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
sha256:b73e47d1f75b4c3f8fc3e3f86b04ddc8c1ae32029b160a1acc997a91a2ee130e
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
It has no published registry digest. The configuration ID, archive-byte digest
|
|
60
|
+
and registry/index digest are different identities; no registry digest is invented.
|
|
61
|
+
|
|
62
|
+
The candidate keeps the approved slice's package metadata version **0.7.1**.
|
|
63
|
+
It is **not the published 0.7.1 wheel or MCP image**. Install/select only by the
|
|
64
|
+
hashes and explicit image ID above, preferably in a separate client environment.
|
|
65
|
+
Do not publish these bytes under an existing 0.7.1 version or mutable alias.
|
|
66
|
+
|
|
67
|
+
Preparation used `git archive` of the approved revision, offline wheel building,
|
|
68
|
+
the already prepared public MCP base, and an offline image layer that installs
|
|
69
|
+
the candidate wheel. It does not build or pull a worker during a consumer call.
|
|
70
|
+
`candidate-01` retains an unsuccessful preparation: Docker interpreted a
|
|
71
|
+
configuration-ID `FROM` as a repository name. The corrected preparation uses the
|
|
72
|
+
already inspected immutable repository digest; no image was pulled by that failed
|
|
73
|
+
attempt. `candidate-02` is the completed delivery.
|
|
74
|
+
|
|
75
|
+
## Coherent identities
|
|
76
|
+
|
|
77
|
+
| Responsibility | Selected identity |
|
|
78
|
+
| --- | --- |
|
|
79
|
+
| Candidate controller and embedded practice template/core | `d37ef4c64eb7d2f2e7ef83cf037640ff42a964e0` |
|
|
80
|
+
| Prepared controller base | `ghcr.io/dosquartsdedocs/unaltraweb-mcp@sha256:6aa20cff86c3891a876e37ba0548fa36f3c5633c9f22ba672e9f50123d677cf6` |
|
|
81
|
+
| Consumer website core | `3332e0b93933f12317e05f1ce8d38ce80046feab` |
|
|
82
|
+
| Reusable deployment workflow | `3332e0b93933f12317e05f1ce8d38ce80046feab` (independent field) |
|
|
83
|
+
| PDF worker | `ghcr.io/dosquartsdedocs/unaltraweb-manual-pdf@sha256:1bb3f2dafd741e96c28639ec1cc8ccaeb81cbaa73e649f787c0b4ef59997bd4b` |
|
|
84
|
+
| PDF worker configuration ID | `sha256:618163d3f924439792b2306617bd9612f566c5881166102fa544b4e782d569fa` |
|
|
85
|
+
| Actual PDF producer source | `b7ec1d7a139c65b3b0b88699cdbeb19080f13be1` |
|
|
86
|
+
|
|
87
|
+
The installed controller, selected core Git objects and actual prepared PDF worker
|
|
88
|
+
agree byte-for-byte on all nine `artifact_imports.CHECKER_FILES`. In particular,
|
|
89
|
+
`processes.py` remains
|
|
90
|
+
`5ed7fd9b427042a0c2d5ec213fef1d58732d7f8e21b4705864accd764e9a9f31`.
|
|
91
|
+
The W1 closure mismatch is absent from this candidate; no checker or compatibility
|
|
92
|
+
allowlist was weakened to obtain agreement.
|
|
93
|
+
|
|
94
|
+
The original reviewed PDF hash remains
|
|
95
|
+
`c92ec8a0937e9c9c735171d889e5bbca19b7ccd9ccbe8d33da2b6c0e49f9a245`.
|
|
96
|
+
The candidate retains the approved `practice.tex` SHA-256
|
|
97
|
+
`971c3594107d9645579f9b45a303048452cdd982a219a64b710ff515b3053491`;
|
|
98
|
+
the manual preamble, layout and finish-filter hashes are in `candidate.json`.
|
|
99
|
+
|
|
100
|
+
## Select it without editing a factory or consumer scaffold
|
|
101
|
+
|
|
102
|
+
On this host the image is already loaded. On another accepted Linux/amd64 Docker
|
|
103
|
+
host, verify the archive SHA-256 and load `controller.docker.tar.gz`. Prepare the
|
|
104
|
+
exact published PDF digest explicitly if missing. Normal execution uses
|
|
105
|
+
`--pull never` and refuses missing/mismatched selections.
|
|
106
|
+
|
|
107
|
+
Install the hash-pinned wheel into a fresh environment. `install-requirements.txt`
|
|
108
|
+
in the candidate directory contains the local wheel URI and required SHA-256;
|
|
109
|
+
if relocated, change only that URI, retaining the hash:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
python3 -m venv /absolute/practice-pdf-client
|
|
113
|
+
/absolute/practice-pdf-client/bin/python -m pip install \
|
|
114
|
+
--no-index --no-deps --require-hashes \
|
|
115
|
+
-r /absolute/candidate-02/install-requirements.txt
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
The launcher wheel is a small host adapter; the full installed implementation and
|
|
119
|
+
factory assets are inside the candidate image. A native wheel alone is not a TeX
|
|
120
|
+
installation or factory checkout.
|
|
121
|
+
|
|
122
|
+
Use this executable/argument selection for the MCP connection, with the explicit
|
|
123
|
+
authorised consumer in place of `/absolute/manual`:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
/absolute/practice-pdf-client/bin/unaltraweb-mcp-docker serve \
|
|
127
|
+
--project /absolute/manual \
|
|
128
|
+
--image sha256:b73e47d1f75b4c3f8fc3e3f86b04ddc8c1ae32029b160a1acc997a91a2ee130e \
|
|
129
|
+
--expected-image-id sha256:b73e47d1f75b4c3f8fc3e3f86b04ddc8c1ae32029b160a1acc997a91a2ee130e \
|
|
130
|
+
--managed --offline \
|
|
131
|
+
--worker-images '{"manual_pdf":{"reference":"ghcr.io/dosquartsdedocs/unaltraweb-manual-pdf@sha256:1bb3f2dafd741e96c28639ec1cc8ccaeb81cbaa73e649f787c0b4ef59997bd4b","expected_image_id":"sha256:618163d3f924439792b2306617bd9612f566c5881166102fa544b4e782d569fa"}}'
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The installed Make transport is also available under the directory printed by
|
|
135
|
+
`unaltraweb-mcp-docker path`; set `MCP_RELEASE_IMAGE` to the candidate ID and inherit
|
|
136
|
+
`MCP_CONSUMER_WORKSPACE` through the environment. Reconnect deliberately, then
|
|
137
|
+
verify `runtime_identity` and `list_tools` in that actual connection. The tested
|
|
138
|
+
loaded package fingerprint is
|
|
139
|
+
`sha256:4eedb5ad683ec76310c1bac3556e37ec5c6ce16442e23236bf33b1713652641a`.
|
|
140
|
+
The observed tool inventory contains `manual_practice_pdf_build`, not `job_storage`.
|
|
141
|
+
|
|
142
|
+
### Two recipient requests
|
|
143
|
+
|
|
144
|
+
The consumer supplies its own `_config.yml` manual metadata and local PNG/JPEG/PDF
|
|
145
|
+
resources. Keep `practiques/`, `sandbox/` and `dist/` excluded from Jekyll, and
|
|
146
|
+
`sandbox/` ignored by Git. Source paths, language and filename must agree:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{"source":"practiques/candidate/ca/alumnat/LLEGIU-ME.md","version":"2026-10-r1","run":"lectura-01"}
|
|
150
|
+
{"source":"practiques/candidate/ca/docent/LLEGIU-ME.md","version":"2026-10-r1","run":"lectura-01"}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Call **`manual_practice_pdf_build`** for each request. ES uses `LEEME.md`; EN uses
|
|
154
|
+
`README.md`. Replace the fixture slug `candidate` with the selected activity slug.
|
|
155
|
+
`dry_run:true` plans without creating a job. Changing an existing
|
|
156
|
+
explicit run's inputs is a collision; choose a new run/version. An unchanged
|
|
157
|
+
sealed job returns `state:current` only after rechecking its complete receipt.
|
|
158
|
+
|
|
159
|
+
Equivalent commands **inside the selected controller**, with its consumer and
|
|
160
|
+
Docker socket mounts established by the authorised launcher:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
unaltraweb-mcp --project "$MCP_CONSUMER_WORKSPACE" mcp manual-practice-pdf-build \
|
|
164
|
+
--source practiques/candidate/ca/alumnat/LLEGIU-ME.md \
|
|
165
|
+
--version 2026-10-r1 --run lectura-01
|
|
166
|
+
|
|
167
|
+
PRACTICE_SOURCE='practiques/candidate/ca/docent/LLEGIU-ME.md' \
|
|
168
|
+
PRACTICE_VERSION='2026-10-r1' PRACTICE_RUN='lectura-01' \
|
|
169
|
+
make --silent --no-print-directory -C /opt/unaltraweb manual-practice-pdf-build
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
These CLI and Make paths were both executed against the installed image, not
|
|
173
|
+
imports from the checkout. The factory Make invocation honours the inherited
|
|
174
|
+
consumer binding. `test/practice_candidate_smoke.py:runtime_args` records the
|
|
175
|
+
equivalent explicit one-shot Docker mount/socket invocation for non-stdio callers.
|
|
176
|
+
|
|
177
|
+
## Verification and PDFs
|
|
178
|
+
|
|
179
|
+
Final evidence:
|
|
180
|
+
|
|
181
|
+
```text
|
|
182
|
+
/home/benizar/git/unaltraweb/tmp/practice-candidate-98/acceptance-03/evidence.json
|
|
183
|
+
SHA-256 241adf1bcd1029f1795597dc185628bcf8a0a386cbeac9161037116b99b1d89a
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Two synthetic consumers, each with student and teacher readings, produced four
|
|
187
|
+
four-page PDFs. Dimensions are A4 landscape (approximately 841.89 × 595.276 pt).
|
|
188
|
+
The tests inspect executed image XObjects, not merely shared PDF resources: both
|
|
189
|
+
logos appear only on page 1. Course names/codes, author, recipient and practice
|
|
190
|
+
version are present; academic year `2099/2100` is absent. DejaVu fonts are embedded;
|
|
191
|
+
actual Serif/Sans/Mono worker font paths and hashes are retained. The teacher-only
|
|
192
|
+
solution marker is absent from the student PDF.
|
|
193
|
+
|
|
194
|
+
Under `acceptance-03/consumer-N/sandbox/practiques/candidate/`:
|
|
195
|
+
|
|
196
|
+
| Consumer / recipient | PDF SHA-256 | Receipt SHA-256 |
|
|
197
|
+
| --- | --- | --- |
|
|
198
|
+
| 1 / alumnat | `6358d6c010edd81ae352937d5ff4ad641d45b365facc522d3df30fd08c187de4` | `1c68ecf8d87a777e03ce8b29c55683f86a53db2d32eba4dad3ef0281a8dd060e` |
|
|
199
|
+
| 1 / docent | `748fd60f78bfc87253795ca88f7c7589bc771e75c37ab2b97d39fd9f65b04167` | `fb21d904cf67fff5fcbf6d973930088653eaa72b1aff06a1238bc8435ac2cc5c` |
|
|
200
|
+
| 2 / alumnat | `e7e8fbe82fdb7b588b9fdb62bc8e678bea27d258a0a54ed8cc70ee7c3169e4a4` | `c283bf7c6c8521487e5a9e7a7dd2b0394ece412bf7746614f948a0ede503d135` |
|
|
201
|
+
| 2 / docent | `b8e213fb2f185bf17660a3240adcb0af589ac6c8c2e72fd07f348530110b76c3` | `044cb618e7ae36b5a76fdebfc0c817301685dc09dd144244594f69af93acc8a3` |
|
|
202
|
+
|
|
203
|
+
Each job directory is
|
|
204
|
+
`lectura-2026-10-candidate-ca-<recipient>-installed-01/`.
|
|
205
|
+
Its PDF is `outputs/LLEGIU-ME.pdf`, preview `outputs/preview.png`, and seal
|
|
206
|
+
`receipt.json`. These hashes repeated unchanged across acceptance runs 01–03.
|
|
207
|
+
|
|
208
|
+
Additional real checks passed:
|
|
209
|
+
|
|
210
|
+
- Fresh installed wheel environment; loaded MCP image, package location/fingerprint,
|
|
211
|
+
actual tool inventory, explicit original consumer mapping and narrow worker mounts.
|
|
212
|
+
- Idempotent MCP reuse, installed CLI and factory Make reuse with identical bytes.
|
|
213
|
+
- Modified author source, modified snapshot font, missing input, missing image,
|
|
214
|
+
wrong controller ID and wrong PDF expected ID fail without replacing sources or jobs.
|
|
215
|
+
- A real empty-fontconfig test fails in XeLaTeX/fontspec without producing a final
|
|
216
|
+
PDF or receipt. Its failed outputs/logs are retained separately.
|
|
217
|
+
- All four PDFs rebuild **byte-identically offline after relocation**, using only
|
|
218
|
+
the retained effective snapshot and exact PDF worker; no original site/factory mount.
|
|
219
|
+
- Actual Jekyll builds on isolated disposable copies produce 13 files per consumer,
|
|
220
|
+
with no `practiques`, `sandbox`, `dist`, reading PDF or teacher solution marker in
|
|
221
|
+
the rendered site. Author-source hashes remain unchanged.
|
|
222
|
+
- Exact observed backend/worker/test-container absence is recorded. **Zero job
|
|
223
|
+
volumes were created.** Images, source snapshots, receipts, PDFs, negative logs
|
|
224
|
+
and the install environment remain available for review.
|
|
225
|
+
|
|
226
|
+
Local source checks: **657 cases, 630 passed / 27 optional skips**,
|
|
227
|
+
`scripts/validate_distribution.py` and `git diff --check` pass. The installed
|
|
228
|
+
launcher `check` passed with the exact candidate ID. The accepted source slice's
|
|
229
|
+
full CI remains the PR #101 baseline; this unit does not borrow W1 CI results.
|
|
230
|
+
|
|
231
|
+
## Release blocker and next handoff
|
|
232
|
+
|
|
233
|
+
The delivered selection is usable locally by hash. A new public release is blocked
|
|
234
|
+
by the absence of a new publication authorisation for this unit and the normal
|
|
235
|
+
review/version/candidate-signing/receipt/publication gates. The package metadata
|
|
236
|
+
must receive a new release identity through that process; these candidate bytes
|
|
237
|
+
must never be uploaded as released 0.7.1. This is not a technical checker-closure
|
|
238
|
+
blocker: the coherent tuple above has been executed and compared exactly.
|
|
239
|
+
|
|
240
|
+
For reviewed adoption, the minimum is selecting/reconnecting the candidate MCP
|
|
241
|
+
and exact prepared PDF worker, checking the live tool, and reviewing only the
|
|
242
|
+
manual's practice source mapping, metadata, ignores and private exclusions.
|
|
243
|
+
No core/workflow/scaffold/figure migration is needed just to exercise this PDF tool.
|
|
244
|
+
The wheel alone cannot turn an already-running 0.7.1 server into the new candidate.
|
|
245
|
+
|
|
246
|
+
The coordinator still needs QGIS's **owner-defined verified descriptor/fixture**,
|
|
247
|
+
then may commission recipient/edition ZIP packaging. This unit implements no GIS
|
|
248
|
+
schema/QGZ parser or speculative ZIP composition. No real manual is declared
|
|
249
|
+
practice-ready: complete GIS/project/capture/two-PDF/two-ZIP acceptance and the
|
|
250
|
+
authorised adoption in each manual remain later phases.
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Web #98 / D1 #33 — prepared controller and PDF archives
|
|
2
|
+
|
|
3
|
+
**Distribution classification superseded by the private-QGIS decision:** the
|
|
4
|
+
historical candidate-04 controller below embeds the rc2 QGIS wheel. Keep it as a
|
|
5
|
+
private/local retained artifact; **do not publish that controller archive as a
|
|
6
|
+
public Web release asset**. The new public Web controller delegates to QGIS and
|
|
7
|
+
must prove provider-package absence before public distribution. The existing PDF
|
|
8
|
+
0.7.1 archive remains independently public with its original producer. See
|
|
9
|
+
[private-practice-verifier-98.md](private-practice-verifier-98.md).
|
|
10
|
+
|
|
11
|
+
This is a distribution/export path for the hub's existing H2 immutable
|
|
12
|
+
Docker-save loader. Web adds no loader, store, registry, allocator or activation
|
|
13
|
+
implementation. Images are already prepared; export neither rebuilds nor renders.
|
|
14
|
+
|
|
15
|
+
## Retained historical create-only handoff
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
/tmp/opencode/practice32-web-runtime-archives-candidate04/ready.json
|
|
19
|
+
SHA-256 665bd8cea160673f010ffc485c7d54a6ab55deb5cfea6671c46efb84b69d8b5a
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
| Archive | Bytes | SHA-256 |
|
|
23
|
+
| --- | ---: | --- |
|
|
24
|
+
| `controller.docker.tar.gz` | 525178465 | `392853842dc49dafe15d10d37a7456d52add2d341b90ff3e3fe8142f66a9f9f3` |
|
|
25
|
+
| `manual-pdf.docker.tar.gz` | 340849248 | `b96826e2875e449f0b7cf713bfcc0b4176f53ebb435150dff7e6fe861d9e5c46` |
|
|
26
|
+
|
|
27
|
+
The controller archive is copied byte-for-byte from the sealed candidate-04
|
|
28
|
+
delivery. Only the already existing PDF image was newly exported, using the
|
|
29
|
+
bounded `export_image` implementation from `prepare_practice_candidate.py`.
|
|
30
|
+
Each tar contains one configuration-ID-selected image and no `RepoTags` aliases.
|
|
31
|
+
Archive configuration bytes were hashed against the exact image IDs; source
|
|
32
|
+
labels, platform and layer presence were checked without loading or extracting.
|
|
33
|
+
|
|
34
|
+
| Role | Configuration ID | Actual source |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| Controller candidate-04 | `sha256:17ef0d24e8611a6802b3c01ff440e6e552eac728343733198056fdbc6cdf379e` | `sha256:8810efd4f4725eea5910996b790b9704786ef42b683c26e1c4d0ae12be24616e` |
|
|
37
|
+
| Published PDF 0.7.1 | `sha256:618163d3f924439792b2306617bd9612f566c5881166102fa544b4e782d569fa` | `b7ec1d7a139c65b3b0b88699cdbeb19080f13be1` |
|
|
38
|
+
|
|
39
|
+
The PDF registry reference remains:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
ghcr.io/dosquartsdedocs/unaltraweb-manual-pdf@sha256:1bb3f2dafd741e96c28639ec1cc8ccaeb81cbaa73e649f787c0b4ef59997bd4b
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`runtime-archives.json` records each archive, the pre-export image observation,
|
|
46
|
+
its independently checked configuration/producer and the offline selection.
|
|
47
|
+
`ready.json` is written last and hashes both archives and that manifest. This
|
|
48
|
+
handoff is still candidate-04, not a claim that the future C072 source or the
|
|
49
|
+
independent-PDF change is already inside that immutable image.
|
|
50
|
+
|
|
51
|
+
## Reproduce an export after a reviewed image selection
|
|
52
|
+
|
|
53
|
+
`scripts/export_practice_runtime_archives.py` accepts an explicit immutable
|
|
54
|
+
controller reference, expected configuration ID and expected source label.
|
|
55
|
+
It obtains the PDF digest and its separate producer from the existing component
|
|
56
|
+
BOM/deployment record. A mismatched PDF source fails before any export.
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
python3 scripts/export_practice_runtime_archives.py \
|
|
60
|
+
--output /tmp/opencode/NEW-CREATE-ONLY-ARCHIVE-DELIVERY \
|
|
61
|
+
--controller-image "$CONTROLLER_REFERENCE" \
|
|
62
|
+
--controller-id "$CONTROLLER_ID" \
|
|
63
|
+
--controller-source "$CONTROLLER_SOURCE" \
|
|
64
|
+
--pdf-id "$PDF_ID"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Optional `--controller-archive PATH --controller-archive-sha256 SHA` reuses an
|
|
68
|
+
already sealed archive exactly. Outputs must be new, non-symlink directories
|
|
69
|
+
under factory `tmp/` or `/tmp/opencode/`. The operator supplies reviewed identities;
|
|
70
|
+
the command does not discover or pull a replacement image.
|
|
71
|
+
|
|
72
|
+
## H2/native loading and the digest distinction
|
|
73
|
+
|
|
74
|
+
The hub verifies `ready.json`, copies the files into its existing persistent
|
|
75
|
+
store and invokes H2 with the declared image IDs. H2 owns loading, alias
|
|
76
|
+
preservation and activation receipts. Web has not invoked `docker load` here.
|
|
77
|
+
|
|
78
|
+
Docker-save does not promise to restore registry `RepoDigests` on a fresh host.
|
|
79
|
+
The registry digest above is an honest pre-export/provenance record, not an
|
|
80
|
+
invented post-load observation. After H2 loading, the existing native selector can
|
|
81
|
+
use configuration IDs directly:
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
serve --project ABSOLUTE_CONSUMER --image CONTROLLER_ID
|
|
85
|
+
--expected-image-id CONTROLLER_ID --managed --offline
|
|
86
|
+
--worker-images '{"manual_pdf":{"reference":"PDF_ID","expected_image_id":"PDF_ID"},"practice_verifier":{"reference":"QGIS_CONTROLLER_ID","expected_image_id":"QGIS_CONTROLLER_ID"}}'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
For the new Web-only controller, replace the schematic values with the full
|
|
90
|
+
`sha256:...` IDs from the public archive manifest and external private-runtime
|
|
91
|
+
descriptor. The complete pinned worker JSON and precise `runtime_identity`
|
|
92
|
+
observations are documented in
|
|
93
|
+
[private-practice-verifier-98.md](private-practice-verifier-98.md#selection-and-native-boundary).
|
|
94
|
+
The QGIS engine is declared separately in that descriptor and checked before
|
|
95
|
+
native `reopen`; it is not another Web `--worker-images` entry.
|
|
96
|
+
For a one-shot CLI/Make without an active MCP runtime, explicitly pass
|
|
97
|
+
`MANUAL_PDF_IMAGE=PDF_ID` as well. The published BOM/workflow digest is not rewritten.
|
|
98
|
+
If an operation requires the registry digest to be present locally, the native
|
|
99
|
+
alternative is explicit preparation/pull of that exact GHCR reference and an
|
|
100
|
+
ID check; no new resolver or silent build/pull fallback is introduced.
|
|
101
|
+
|
|
102
|
+
## External private dependency declaration
|
|
103
|
+
|
|
104
|
+
The public `runtime-archives.json` image inventory contains only the accepted
|
|
105
|
+
Web-only `controller` and the separately produced public `manual_pdf`. The existing
|
|
106
|
+
exporter emits those two image rows. Its receipt must never list the private QGIS
|
|
107
|
+
archive or any older Web controller that embeds QGIS bytes as public assets.
|
|
108
|
+
|
|
109
|
+
The exact package-owned `practice-verifier-runtime.json` accompanies the public
|
|
110
|
+
handoff as metadata, with its own file hash in the handoff inventory. It declares
|
|
111
|
+
QGIS as private and hub-prepared, and `release.receipt` points to:
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
https://github.com/dosquartsdedocs/unaltracaptura-qgis/releases/download/v0.6.0/release.json
|
|
115
|
+
1251 bytes; SHA-256 45db1e016e666126e5a51f157be0be1066aaa08f32042f5907d46e0e7da1e404
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
H2 preparation consumes this external producer receipt through the hub's
|
|
119
|
+
authenticated acquisition path, verifies its hash and declared archive, and
|
|
120
|
+
checks both prepared image IDs. Web's declaration does not fetch, mirror or
|
|
121
|
+
re-export that receipt/archive, and does not create an attestation for QGIS.
|
|
122
|
+
The native package/schema identity remains separate from this release provenance.
|
|
123
|
+
The descriptor is public metadata; the QGIS wheel, archive and implementation
|
|
124
|
+
remain private. No credentials belong in either handoff.
|
|
125
|
+
|
|
126
|
+
## Public release assets and the existing publisher boundary
|
|
127
|
+
|
|
128
|
+
The language-package publisher accepts only its exact wheel/gem inventory and
|
|
129
|
+
its strict `release-candidates.json` fields. Docker archives must not be inserted
|
|
130
|
+
into that staging directory, its `SHA256SUMS`, or the old container receipt rows.
|
|
131
|
+
|
|
132
|
+
At the authorised release turn, publish only the accepted public Web-only
|
|
133
|
+
controller archive and the public PDF archive, with their separate
|
|
134
|
+
`runtime-archives.json`/ready receipt and external-dependency descriptor as
|
|
135
|
+
**additional GitHub Release assets**, with a separate `RUNTIME-SHA256SUMS`,
|
|
136
|
+
through the existing native `gh release upload`
|
|
137
|
+
operation. Use new asset names and never `--clobber`; retain the immutable GHCR
|
|
138
|
+
references and provenance alongside them. This is artifact attachment, not a new
|
|
139
|
+
runtime manager or a modification of the PyPI/RubyGems publisher.
|
|
140
|
+
|
|
141
|
+
For the final tool release, export its newly reviewed controller and record its
|
|
142
|
+
own producing commit. Reuse the selected PDF 0.7.1 archive/digest and producer
|
|
143
|
+
`b7ec1d…` honestly; do not attribute those existing bytes to C072 or retag them as
|
|
144
|
+
a newly built PDF. The current candidate archives and receipts stay unchanged
|
|
145
|
+
and retain the private/local classification above. Until the new public release
|
|
146
|
+
assets exist, H2 may use that explicitly private local handoff; public acquisition
|
|
147
|
+
uses only already public GHCR images, never private wheel-containing candidates.
|