unaltraweb 0.4.0 → 0.5.1

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +17 -10
  3. data/README.md +19 -7
  4. data/_plugins/figure_captions.rb +47 -10
  5. data/_sass/_documentation.scss +7 -5
  6. data/_sass/_manual.scss +7 -0
  7. data/docs/_documentation/en/02-tools.md +4 -4
  8. data/docs/_documentation/en/03-usage.md +61 -0
  9. data/docs/_documentation/en/13-unaltremanual.md +1 -1
  10. data/docs/_documentation/en/20-syntax.md +14 -0
  11. data/docs/_documentation/en/25-caption-credits.md +120 -0
  12. data/docs/_documentation/en/26-image-backgrounds.md +103 -0
  13. data/docs/_documentation/en/31-template.md +1 -1
  14. data/docs/_documentation/en/32-development.md +1 -1
  15. data/docs/_documentation/en/40-distribution.md +132 -6
  16. data/docs/_documentation/en/42-docker-image.md +8 -8
  17. data/docs/_documentation/en/43-workspace-path-policies.md +232 -0
  18. data/docs/_documentation/en/44-editorial-review.md +237 -0
  19. data/docs/agents/action-prompts/00-start-site-session.txt +10 -5
  20. data/docs/agents/action-prompts/22-manual-style-audit.txt +3 -1
  21. data/docs/agents/manual-authoring-components.md +38 -0
  22. data/docs/agents/mcp-contract.md +131 -12
  23. data/docs/agents/owner-followup-76.md +144 -0
  24. data/docs/agents/owner-preparation-2026-09-29.md +254 -0
  25. data/docs/agents/visual-companions-0.4.0.md +79 -0
  26. data/docs/assets/img/caption-credits-demo.svg +19 -0
  27. data/scripts/editorial_check.py +12 -0
  28. data/scripts/image_background_check.py +12 -0
  29. data/scripts/manual/build_pdf.py +94 -16
  30. data/scripts/manual/filters/figure-captions.lua +65 -10
  31. data/scripts/manual/templates/manual.tex +2 -1
  32. data/scripts/test_gem_build.py +32 -2
  33. data/scripts/test_reproducible_jekyll_build.py +1 -1
  34. data/scripts/test_wheel_install.py +74 -0
  35. data/scripts/unaltraweb-mcp-bootstrap.sh +33 -6
  36. data/scripts/validate_distribution.py +38 -4
  37. data/src/unaltraweb_mcp/bundler_runtime.py +214 -0
  38. data/src/unaltraweb_mcp/component-contract.json +28 -28
  39. data/src/unaltraweb_mcp/editorial.py +495 -0
  40. data/src/unaltraweb_mcp/editorial_sources.py +504 -0
  41. data/src/unaltraweb_mcp/image_backgrounds.py +334 -0
  42. data/src/unaltraweb_mcp/image_probe.py +149 -0
  43. data/src/unaltraweb_mcp/processes.py +146 -0
  44. metadata +18 -2
@@ -0,0 +1,144 @@
1
+ # Owner follow-up 76: populated Bundler transitions and 0.5.1 preparation
2
+
3
+ This follows the immutable historical intake in
4
+ [owner-preparation-2026-09-29.md](owner-preparation-2026-09-29.md) and the hub's
5
+ `owner-followups/05-unaltraweb.txt`. Tracking and final execution results:
6
+ [issue 76](https://github.com/dosquartsdedocs/unaltraweb/issues/76).
7
+
8
+ ## Correction and source identity
9
+
10
+ Implementation commit: `c23e12b0e1567d18a7f9dd225dc062ddc77dad8b`, on the existing
11
+ `feat/76-distributed-mcp-launcher` primary checkout. Local commits were explicitly
12
+ authorized. The following integration commit pins `consumer_integration.core_sha`
13
+ to this real 0.5.1 core, so the generated Gemfile/lock/workflow tuple no longer
14
+ combines a 0.5.1 gem version with a 0.5.0 source revision.
15
+
16
+ The correction lives in `src/unaltraweb_mcp/bundler_runtime.py` and is included in
17
+ both wheel and gem. It keys generated state by the actual Ruby/platform, Bundler,
18
+ installed gem inventory, core dependency inputs and hashed Bundler configuration.
19
+ No mutable Docker alias or project build default acts as the cache identity.
20
+
21
+ - Offline `bundle lock --local` and `bundle check` prepare a new identity cache
22
+ under `tmp/unaltraweb-bundle/<hash>/` and record exact Gemfile/lock hashes.
23
+ - Reuse verifies that receipt. Edited, unsafe or incomplete caches are retained
24
+ and rejected rather than silently reset. No old generated tree is removed.
25
+ - Each build/preview gets private invocation copies. This also accommodates
26
+ Bundler 4's local default-gem checksum completion without disabling checksums
27
+ or changing a cached or authored lock. An initially attempted frozen generated
28
+ lock exposed empty `rake` CHECKSUMS entries in the owner runtime; private copies
29
+ fixed that additional regression. Explicit author Gemfiles require an existing
30
+ lock and run with `BUNDLE_FROZEN=true`.
31
+ - Updated package scaffolds use the helper in native build/test/serve targets.
32
+ - MCP build and same-image preview adapt unchanged historical Makefiles only
33
+ when their bytes match the recorded package scaffold baseline. They pass
34
+ `LOCAL_GEMFILE` pointing to an invocation copy. The original
35
+ `tmp/Gemfile.local.lock`, project Gemfile/lock, Makefile and scaffold manifest
36
+ remain byte-identical. Custom Makefiles retain their own dependency policy;
37
+ adopting the new native targets remains an explicit scaffold update.
38
+
39
+ The already-published 0.5.0 image is still unpatched. The roundtrip fixture retains
40
+ its exact Ruby/gem layers and adds the new owner controls as a separately named
41
+ test image; this proves the correction against the problematic 0.5.0 inventory,
42
+ not a new empty cache or an unrelated fresh Ruby installation.
43
+
44
+ ## Component decision
45
+
46
+ | Component | 0.5.1 preparation |
47
+ | --- | --- |
48
+ | Core gem | New 0.5.1: ships the runtime helper and updated controls/docs. |
49
+ | Python wheel | New 0.5.1: installed Docker launcher, cache orchestration, scaffolds and integration tuple. |
50
+ | Full MCP image | New 0.5.1: required to run the correction without a local core. |
51
+ | Base Ruby/Jekyll image | Coordinated 0.5.1 candidate under the existing image workflow. The Dockerfile/toolchain recipe itself is unchanged. |
52
+ | Manual PDF | Reuse published 0.5.0 digest `sha256:9e0b3a45753c170b795e9a9d6df61580085c113436beac5bf6c8de69b6562097`. |
53
+ | Python/R computation, web capture | Retain their published 0.4.0 versions/digests. |
54
+ | Diavisuals/Vegavisuals | Retain published hashed 0.4.0 wheels and current receipt contract. |
55
+
56
+ The native validator now permits a released, digest-pinned PDF to retain its
57
+ actual version across a coordinated core patch. Pending/ready PDF candidates,
58
+ mutable aliases and other repositories do not receive that exception. The
59
+ existing source image workflow may build a PDF verification candidate; it does
60
+ not thereby replace the selected released worker or put it in the new receipt.
61
+ The new receipt must contain exactly `gem`, `wheel`, `runtime`, `mcp` when those
62
+ four components remain `ready`.
63
+
64
+ The 0.5.0 receipt is unchanged, SHA-256
65
+ `e57a9dbb041c1e7fcd781cd1524f4de0317382e0f7303bb36bfa59c0b6d1cb9b`.
66
+ Historical tags and published packages are untouched. The launcher retains the
67
+ last published MCP digest until a separately reviewed post-release selection.
68
+ Local 0.5.1 artifacts have new names and are not registry-published candidates.
69
+
70
+ ## Regressions and pre-integration owner gates
71
+
72
+ Executed on Linux/amd64:
73
+
74
+ - All four historical profiles: successful 0.4.0 host build first, containing
75
+ `google-protobuf (4.36.1-x86_64-linux-gnu)` in the retained generated lock.
76
+ - Unpatched 0.5.0 fails with the known missing `google-protobuf (4.36.1)` on a
77
+ disposable copy of each populated consumer; this negative control is required.
78
+ - Corrected controls on 0.5.0 Ruby layers: two builds, preview and HTTP pass.
79
+ - Return to unchanged published 0.4.0: two builds, preview and HTTP pass.
80
+ - Hash comparisons verify preservation of both authored and retained generated
81
+ Gemfile/lock pairs, Makefile and scaffold baseline across the roundtrip.
82
+ - The manual additionally builds/stages real PDFs and performs receipt-bound
83
+ preview cleanup. No source mount or real manual is used.
84
+ - Unit regressions cover populated A→B→A cache reuse, modified generated locks,
85
+ symlink ancestors, author Makefile overrides, frozen author locks, credential
86
+ hashing, and private checksum-completion copies.
87
+
88
+ Initial evidence is retained under
89
+ `/tmp/opencode/unaltraweb-followup-76/all-profiles-first/` (three completed
90
+ profiles) and `manual-first-roundtrip/` (completed manual). The first combined
91
+ run reached its 20-minute terminal limit during the final historical preview;
92
+ the manual was rerun to completion. No test container remained from that timeout.
93
+
94
+ Before integration: **562 unit tests, 30 optional skips**; distribution, workflow,
95
+ wheel, gem, MCP CLI, MCP stdio/manual-preview, prose and docs-build gates passed.
96
+ The final native smoke passed using `unaltraweb-followup-76-mcp:precommit3`; the
97
+ earlier frozen-generated-lock attempts remain failed intermediate evidence.
98
+ The old report's 0.5.0-labelled local wheel is not a release artifact.
99
+
100
+ ## Final-version artifact gate protocol
101
+
102
+ After pinning the corrected core, build the final 0.5.1 wheel and gem from that
103
+ clean integration commit, retain their hashes, install the wheel non-editably,
104
+ and repeat the gates against those bytes. Retain final outcomes and immutable
105
+ local image IDs in issue 76 rather than inserting a self-referential artifact
106
+ digest into its own source. Evidence belongs under
107
+ `/tmp/opencode/unaltraweb-followup-76/final-artifacts/` and
108
+ `/tmp/opencode/unaltraweb-followup-76/final-roundtrip/`.
109
+
110
+ The reproducible populated-cache command is:
111
+
112
+ ```bash
113
+ python3 test/bundler_transition_smoke.py \
114
+ --launcher /tmp/opencode/unaltraweb-followup-76/final-venv/bin/unaltraweb-mcp-docker \
115
+ --legacy-image ghcr.io/dosquartsdedocs/unaltraweb-mcp@sha256:389bc585cdb4fc89d3372f4896a55fe26e15df38b46bc114ce44fdb3f1c8deb9 \
116
+ --broken-image ghcr.io/dosquartsdedocs/unaltraweb-mcp@sha256:36d17edbade77edb40a687f6a744203c6329acb33fbc2eb255e88d9ff1a42c98 \
117
+ --fixed-image unaltraweb-followup-76:051-on-050-final \
118
+ --output /tmp/opencode/unaltraweb-followup-76/final-roundtrip
119
+ ```
120
+
121
+ Use a fresh output directory and a sufficiently long outer deadline; the driver
122
+ never clears a populated fixture to obtain a pass. The test overlay is built
123
+ with `test/bundler_transition.Dockerfile`, the exact published 0.5.0 base digest,
124
+ and a named `wheel` build context containing the final wheel. Installation uses
125
+ `--no-index --no-deps`, and the build uses `--network none`. Ordinary owner
126
+ `mcp-check`/`mcp-smoke` also run against separate test tags and fresh fixtures.
127
+
128
+ ## Publication status and next gate
129
+
130
+ Issue 76 stays open until integration and release. No PR, push, tag, workflow
131
+ dispatch, registry upload or consumer activation is authorized by the local
132
+ commit approval. The native schema remains unchanged; H1 range/catalogue fields
133
+ are not invented here. Tested points are the explicit tuples above, not a
134
+ continuous semver compatibility interval.
135
+
136
+ The strict `distribution-release-check` is mandatory and must remain blocking
137
+ until there is a new 0.5.1 receipt-only child commit with the correct default-branch
138
+ candidate ancestry, signed image digests and verified package checksums. The
139
+ retained 0.5.0 receipt cannot satisfy that gate and is not rewritten to do so.
140
+ Next: reviewed branch integration (preserving or deliberately refreshing the
141
+ core pin), approved signed candidate/package preparation on the resulting source,
142
+ new receipt-only commit, strict gate, then separately approved promotion and
143
+ post-release launcher selection. TIG, TIGIT, Geodisseny, their active registrations
144
+ and their image/worker selections are outside this test and adoption scope.
@@ -0,0 +1,254 @@
1
+ # Checkout-free MCP launcher: owner preparation report
2
+
3
+ Date: 2026-09-29. Hub handoff: **unaltraweb owner preparation**, following
4
+ `gacontext/src/bash/mcp_factories/handoffs/owner-preparation-prompts.md` and its
5
+ existing-manual baseline. Tracking: [issue 76](https://github.com/dosquartsdedocs/unaltraweb/issues/76).
6
+
7
+ ## Source and delivery status
8
+
9
+ - Primary checkout: `unaltraweb`; branch `feat/76-distributed-mcp-launcher`.
10
+ - Base/source checkpoint: `260271e41b17be0f95dcb8047014c35cb97142ee`.
11
+ - Implementation is an **uncommitted owner working-tree change**, not a release,
12
+ tag, pushed branch or PR. The hub can ingest this report without changing its
13
+ catalogue or activating a client registration.
14
+ - The full published 0.5.0 GHCR runtime already contains the factory and supports
15
+ checkout-free site work. No replacement image release is needed to run it.
16
+ - The published 0.5.0 wheel lacks the standalone host launcher. The new wheel
17
+ contents require a future reviewed package release under a new version. The
18
+ local test wheel still reports source version 0.5.0 and must never replace the
19
+ published wheel of that name.
20
+
21
+ Changed paths:
22
+
23
+ ```text
24
+ Makefile
25
+ pyproject.toml
26
+ packaging/launcher/Makefile
27
+ src/unaltraweb_mcp/docker_launcher.py
28
+ scripts/unaltraweb-mcp-bootstrap.sh
29
+ scripts/test_wheel_install.py
30
+ scripts/validate_distribution.py
31
+ test/test_distributed_launcher.py
32
+ test/distributed_launcher_smoke.py
33
+ docs/_documentation/en/40-distribution.md
34
+ docs/agents/mcp-contract.md
35
+ docs/agents/owner-preparation-2026-09-29.md
36
+ ```
37
+
38
+ The source `mcp-factory.yml`, component BOM/schema, published receipt, managed
39
+ consumer scaffolds and their version selections are unchanged. Preserved hashes:
40
+
41
+ | File | SHA-256 |
42
+ | --- | --- |
43
+ | `src/unaltraweb_mcp/component-contract.json` | `f3de4b289fc6ae66ddc86bf6a701b3a2cfaed66ab6303f64252c92639a7aab98` |
44
+ | `release-candidates.json` | `e57a9dbb041c1e7fcd781cd1524f4de0317382e0f7303bb36bfa59c0b6d1cb9b` |
45
+
46
+ ## Native installed profile and capability boundary
47
+
48
+ The wheel installs `share/unaltraweb-launcher/Makefile`, the **byte-identical native
49
+ schema-v1 `mcp-factory.yml`**, and the existing bootstrap, project-ID, CSV mount and
50
+ cleanup scripts under `scripts/`. It uses the current `runtime.kind: container`,
51
+ `runtime.package_manager: docker`, consumer binding, `transport.command` with
52
+ `make -C ${factoryRoot} mcp-stdio`, and inherited `MCP_CONSUMER_WORKSPACE`.
53
+ Here `${factoryRoot}` names the installed launcher directory. No new H1 fields or
54
+ alternative central schema were introduced. Companion lifecycle flags and exact
55
+ tool/resource inventories remain those in the native manifest.
56
+
57
+ `unaltraweb-mcp-docker path` resolves that directory from installed wheel metadata.
58
+ `manifest` prints the descriptor. `prepare`, `check`, `smoke`, `serve` and `down`
59
+ delegate to packaged shell scripts. Preparation may pull; check/smoke require a
60
+ local image, use its immutable local ID and mount neither source nor consumer.
61
+ Serve requires an explicit consumer and preserves both canonical host-path mounts
62
+ and the original factory/project labels. Cleanup retains its exact project scope.
63
+
64
+ The profile directory is independently relocatable with Make, POSIX shell, Linux
65
+ core utilities and Docker. The console adapter requires Python. The native
66
+ `unaltraweb-mcp` CLI retains the BOM's exact package-only and factory-required
67
+ inventories: shipping a Docker adapter does not put Ruby/core/TeX/Chromium or
68
+ worker/companion implementations into the wheel. `new-web`, doctor and inspection
69
+ remain usable natively; full MCP serving and build/PDF orchestration execute in
70
+ the selected GHCR image.
71
+
72
+ ## Published identities and dependency closure
73
+
74
+ Native identities use existing BOM `kind`, `version`, `release`, `reference` and
75
+ `image_repository`, and manifest `mcp_dependencies[].uv_spec`. Container references
76
+ below are in `ghcr.io/dosquartsdedocs/`; each hash is an OCI repository digest,
77
+ not a Docker image configuration ID.
78
+
79
+ | Component / repository | Version | Exact selected digest |
80
+ | --- | --- | --- |
81
+ | Full MCP `unaltraweb-mcp` | 0.5.0 | `sha256:36d17edbade77edb40a687f6a744203c6329acb33fbc2eb255e88d9ff1a42c98` |
82
+ | Base Ruby/Jekyll `unaltraweb` (receipt) | 0.5.0 | `sha256:4c7bfa51b8f936993ca5a1350d8b63ac3af77f88e97065a9b4a223583528fa8e` |
83
+ | PDF `unaltraweb-manual-pdf` | 0.5.0 | `sha256:9e0b3a45753c170b795e9a9d6df61580085c113436beac5bf6c8de69b6562097` |
84
+ | Python `unaltraweb-compute-python` | 0.4.0 | `sha256:18cb269811bd4005800382da25a480ec2bca7eac8d0501ad1ef36bad1c0f8cd9` |
85
+ | R `unaltraweb-compute-r` | 0.4.0 | `sha256:928ffb93f221e09e8b929157dee473b838e061915a2eb67224e4124b85f81837` |
86
+ | Chromium `unaltraweb-web-capture` | 0.4.0 | `sha256:0bf1bc67fe63e1440bffe708a168beefa11c54441650a871ab99380d362f7c1e` |
87
+ | Historical full MCP `unaltraweb-mcp` | 0.4.0 | `sha256:389bc585cdb4fc89d3372f4896a55fe26e15df38b46bc114ce44fdb3f1c8deb9` |
88
+ | Historical PDF `unaltraweb-manual-pdf` | 0.4.0 tuple | `sha256:bb3e373f8a512495eeed684c23ad904d298c2e20a6dc3ade0d0a60c7ec9a9f11` |
89
+
90
+ The runtime layer is embedded in the full MCP image. The four workers remain
91
+ separate feature-selected containers; compute/capture were inventoried, not
92
+ rendered again in this preparation. Companions remain separate MCP servers:
93
+
94
+ | Companion | Native selected wheel and SHA-256 |
95
+ | --- | --- |
96
+ | Diavisuals 0.4.0 | `diavisuals[mcp] @ https://github.com/dosquartsdedocs/diavisuals/releases/download/v0.4.0/diavisuals-0.4.0-py3-none-any.whl#sha256=bfedcc9e2554f25ce4a1c33e556f352210848fccb8da800d1c3900dd86c48c93` |
97
+ | Vegavisuals 0.4.0 | `vegavisuals[mcp] @ https://github.com/dosquartsdedocs/vegavisuals/releases/download/v0.4.0/vegavisuals-0.4.0-py3-none-linux_x86_64.whl#sha256=b52ffa743643dd6b5e0320e7a9aa0cd500ea06262b7d5098c0c3f94a379bc0ea` |
98
+
99
+ Both dependencies retain `required/install/build/check/smoke: true` and
100
+ `init/update: false`. Their renderer archive identities and earlier real receipt
101
+ acceptance are in [visual-companions-0.4.0.md](visual-companions-0.4.0.md); that
102
+ 2026-09-26 evidence is not presented as a new rendering run here. Historical core
103
+ 0.4.0 selects companions 0.3.1; the 0.5.0 receipt verifier does not promise to accept
104
+ those older provider identities.
105
+
106
+ ## Synthetic acceptance and isolation
107
+
108
+ Platform: Linux/amd64, host Python 3.12, Docker 27.2.0. A non-editable wheel was
109
+ installed with `--no-deps --no-index` into
110
+ `/tmp/opencode/unaltraweb-owner-20260929/venv`. Its launcher metadata resolved
111
+ outside the source checkout. The retained test wheel SHA-256 is
112
+ `a8b2136ffb23970980b86b70e64d509e2e24500f1e032b023f857cde22a7988f`.
113
+
114
+ All acceptance consumers, Git indexes, caches, generated PDFs and Jekyll outputs
115
+ are synthetic under `/tmp/opencode/unaltraweb-owner-20260929/`. No host core was
116
+ mounted. Preview inspection verified only the synthetic consumer bind and no
117
+ Docker socket. Ports were allocated on loopback; preview stop and digest-bound
118
+ PDF preview cleanup passed. Full stdio sessions used the installed launcher.
119
+
120
+ | Scaffold / host build | Active MCP / PDF | Profile coverage | Result |
121
+ | --- | --- | --- | --- |
122
+ | 0.5.0 / MCP build | 0.5.0 / 0.5.0 | All four profiles | Empty detection, creation, site check, build, preview, HTTP and HTML audit pass; manual PDF/cover pass. Ports 32770–32773. |
123
+ | 0.4.0 / 0.4.0 host build | 0.4.0 / historical pinned PDF | `unaltremanual` | Host build/PDF, MCP build, preview, HTTP and HTML audit pass. Port 32776. New image-background and update-advisory tools are absent as expected. |
124
+ | 0.4.0 / no earlier host build cache | 0.5.0 / 0.5.0 | `unaltremanual` | Pass with fresh synthetic runtime cache, port 32774. Update advisory reports `update_available`; no sync is applied. |
125
+ | 0.4.0 / successful 0.4.0 host build first | 0.5.0 / 0.5.0 | `unaltremanual` | Site check and PDF pass; MCP build fails because retained `tmp/Gemfile.local.lock` selects `google-protobuf (4.36.1)`, unavailable in the 0.5.0 image. No automatic cache deletion or pin migration. |
126
+
127
+ Evidence directories are `released-050-full`, `released-040-manual-full`,
128
+ `mixed-fresh-040-050`, and `mixed-retained-lock-final`. Runs retain `evidence.json`,
129
+ server stderr and actual outputs, including the reproduced mixed-cache failure's
130
+ MCP response, host-build log and generated lock. The initial
131
+ four-profile run hit the terminal's 120-second limit after one profile; its owned
132
+ test session was cleaned by exact consumer identity and the complete run passed
133
+ with a 600-second outer limit. An initial historical runner call to the newer
134
+ `image_background_check` was corrected to inspect actual capabilities; it was a
135
+ test-driver mismatch, not a claimed 0.4.0 feature.
136
+
137
+ Retained PDF hashes:
138
+
139
+ - 0.5.0 and fresh 0.4.0-scaffold/0.5.0 runtime:
140
+ `4e6e405ed690caf075ec33ea04090d2a5c4bfbf0fb0a49a35cdab819c6f40939`.
141
+ - Historical host/runtime 0.4.0:
142
+ `68f067addf5e009364edb42042de2410af5ce8c38543556852d4498bd9663a75`.
143
+
144
+ Both covers were visually inspected. The 0.5.0 PDF has nine pages including the
145
+ synthetic Coordinates chapter, contents and expected draft marker. This is
146
+ technical acceptance, not human publication approval.
147
+
148
+ ## Owner gates and exact reproduction
149
+
150
+ Passed:
151
+
152
+ ```bash
153
+ PYTHONPATH=src python3 -m unittest discover -s test -p 'test_*.py'
154
+ make distribution-check
155
+ make workflow-check
156
+ make wheel-check
157
+ make mcp-check mcp-smoke \
158
+ MCP_RUNTIME_IMAGE=unaltraweb-owner-76-runtime:20260929 \
159
+ MCP_IMAGE=unaltraweb-owner-76-mcp:20260929-final \
160
+ MANUAL_PDF_DEV_IMAGE=unaltraweb-owner-76-pdf:20260929 \
161
+ MCP_SMOKE_MANUAL_PDF_IMAGE=unaltraweb-owner-76-pdf:20260929 \
162
+ MCP_SMOKE_PROJECT=/tmp/opencode/unaltraweb-owner-20260929/owner-preview-final
163
+ docker run --rm --network none --user "$(id -u):$(id -g)" -e HOME=/tmp \
164
+ --entrypoint make unaltraweb-owner-76-mcp:20260929 -C /opt/unaltraweb gem-check
165
+ make --silent --no-print-directory \
166
+ -C /tmp/opencode/unaltraweb-owner-20260929/venv/share/unaltraweb-launcher \
167
+ mcp-check mcp-smoke
168
+ PYTHONPATH=src python3 -m unaltraweb_mcp.cli --project docs mcp prose-check \
169
+ --target _documentation/en/40-distribution.md
170
+ make docs-build DOCKER_IMAGE=unaltraweb-owner-76-runtime:20260929
171
+ git diff --check
172
+ ```
173
+
174
+ Unit suite: **553 tests, 30 optional skips**. `wheel-check` verifies all four
175
+ factory-free native scaffolds and every byte of the launcher/helper closure.
176
+ The installed-profile smoke uses the published image, no socket/source mount and
177
+ `--network none`. Owner source smoke additionally runs a real stale PDF worker and
178
+ a socket-free persistent preview. Docker's content-addressed build cache reused
179
+ existing layers; test image tags and consumer/Python/Jekyll caches were separate.
180
+ The owner smoke now creates a fresh unique fixture by default and refuses any
181
+ existing explicit `MCP_SMOKE_PROJECT`, preventing its fixture reset from touching
182
+ prior work. Prose check reports only one pre-existing informational long-sentence
183
+ finding in the publication-workflow paragraph; docs build and diff check pass.
184
+ Existing `:dev`, manual build and TIGIT local worker image IDs were rechecked and
185
+ preserved. Test image configuration IDs:
186
+
187
+ - `unaltraweb-owner-76-runtime:20260929`: `sha256:df6a55511b5e40c3fde8a10326263cc7a87723b8c090e8333d64bf848c3a853f`.
188
+ - `unaltraweb-owner-76-mcp:20260929`: `sha256:dd795ad90dc30547ae09c9175e06f296af1072f4277a2b02d8122000c7378e07`.
189
+ - Final source gate `unaltraweb-owner-76-mcp:20260929-final`: `sha256:1ef3d4e7ac5fbb60b66103415c87c30bb432802016ccc30b46b896de3bf35a1b`.
190
+ - `unaltraweb-owner-76-pdf:20260929`: `sha256:6c7c5411b4f570fcdcfb1f984a9d9a0e36cc54d606bf459ca67929af0bc0d145`.
191
+
192
+ The host `make gem-check` initially refused the absent semver-tagged base image;
193
+ the exact gate then passed inside the isolated owner image using its local Ruby.
194
+ `make distribution-release-check` correctly **fails** at this post-release source
195
+ checkpoint: it is not the receipt-only child of the recorded candidate source.
196
+ The published receipt is preserved rather than rewritten to make a source
197
+ preparation look publication-ready.
198
+
199
+ Acceptance driver (fresh output directories are required):
200
+
201
+ ```bash
202
+ L=/tmp/opencode/unaltraweb-owner-20260929/venv/bin/unaltraweb-mcp-docker
203
+ MCP05=ghcr.io/dosquartsdedocs/unaltraweb-mcp@sha256:36d17edbade77edb40a687f6a744203c6329acb33fbc2eb255e88d9ff1a42c98
204
+ MCP04=ghcr.io/dosquartsdedocs/unaltraweb-mcp@sha256:389bc585cdb4fc89d3372f4896a55fe26e15df38b46bc114ce44fdb3f1c8deb9
205
+ python3 test/distributed_launcher_smoke.py --launcher "$L" --image "$MCP05" \
206
+ --output /tmp/opencode/unaltraweb-owner-20260929/released-050-full
207
+ python3 test/distributed_launcher_smoke.py --launcher "$L" --image "$MCP04" \
208
+ --profiles unaltremanual --host-build \
209
+ --output /tmp/opencode/unaltraweb-owner-20260929/released-040-manual-full
210
+ python3 test/distributed_launcher_smoke.py --launcher "$L" --image "$MCP05" \
211
+ --scaffold-image "$MCP04" --profiles unaltremanual \
212
+ --output /tmp/opencode/unaltraweb-owner-20260929/mixed-fresh-040-050
213
+ python3 test/distributed_launcher_smoke.py --launcher "$L" --image "$MCP05" \
214
+ --scaffold-image "$MCP04" --profiles unaltremanual --host-build \
215
+ --output /tmp/opencode/unaltraweb-owner-20260929/mixed-retained-lock-final
216
+ ```
217
+
218
+ The final command intentionally reproduces the retained-lock failure in a new
219
+ output directory. The original `mixed-040-050` run used the driver's then-default
220
+ host-build step before that option was made explicit.
221
+
222
+ ## Range adoption points, gaps and next action for the hub
223
+
224
+ 1. **Install/discovery:** map the installed `path` and existing descriptor into the
225
+ accepted hub contract. Do not treat a source checkout's `make mcp-check` (which
226
+ builds) as equivalent to the installed profile's prepared-image check.
227
+ 2. **Compatibility versus exact selection:** `mcp_dependencies` and
228
+ `distribution.py:companion_dependency_requirements` currently select exact
229
+ provider versions/wheels; `site_tools.py` receipt validation also requires exact
230
+ provider version/release. A future accepted range must be tested there without
231
+ weakening request/input/artifact hashes or equating wheel hashes with images.
232
+ 3. **Consumer tuple:** `consumer_integration`, scaffold rendering/update planning,
233
+ the Make image selection and native Gemfile pins remain atomic reviewed
234
+ selections. Preserve their concrete revision and hashes after any future range
235
+ resolution. Fix/test runtime-specific generated Bundler-cache handling before
236
+ promising transparent switching across the mixed 0.4.0/0.5.0 tuple.
237
+ 4. **Coverage:** tested endpoints are 0.4.0 and 0.5.0, not a promised `[0.4,0.6)`
238
+ interval. The other three 0.4.0 profiles, non-Linux/amd64 platforms, independent
239
+ new compute/capture/companion rendering and stable publication channels were
240
+ not covered by this preparation.
241
+ 5. **Delivery:** review the owner diff, assign a new package version through the
242
+ normal release procedure, bind final artifacts to new receipt evidence, then
243
+ adopt the installed profile in a separate synthetic hub pilot. The full 0.5.0
244
+ image can remain selected. Client activation and each real-manual upgrade need
245
+ their own later owner session.
246
+
247
+ TIG/TIGIT retain 0.4.0 build defaults; Geodisseny retains 0.5.0. Their sources,
248
+ generated artifacts, registrations and worker identities were not migrated.
249
+ During this session the author separately approved storage cleanup: five stopped
250
+ old test containers were removed, and exact unused/unshared unaltraweb cache IDs
251
+ were submitted to BuildKit pruning (131.1 kB actually reclaimed). Active stdio
252
+ containers, manual previews, images and volumes were not removed by that cleanup.
253
+ Other concurrent Docker activity changed disk availability; its reclaimed space
254
+ is not attributed to this preparation.
@@ -0,0 +1,79 @@
1
+ # Published visual companions: native acceptance and release handoff
2
+
3
+ Tracking: [issue 67](https://github.com/dosquartsdedocs/unaltraweb/issues/67).
4
+ Publication update: the acceptance is included in
5
+ [unaltraweb v0.5.0](https://github.com/dosquartsdedocs/unaltraweb/releases/tag/v0.5.0),
6
+ receipt `3fa855378dcc61dc7b84b8b03812698042e02fed`, and the post-release launcher
7
+ selects MCP digest `36d17edbade77edb40a687f6a744203c6329acb33fbc2eb255e88d9ff1a42c98`.
8
+ The preparation notes and original 0.4.0 image below retain their historical context.
9
+ Owner branch: `fix/67-published-visual-companions`, based on
10
+ `bfabaa2738ddd24725f5e386d60b58a9a8294316` after an eligible primary-checkout
11
+ preflight. This is next-release source, not a replacement for published core 0.4.0.
12
+
13
+ ## Selected artifacts
14
+
15
+ | Provider | Integrated published source | Wheel SHA-256 |
16
+ | --- | --- | --- |
17
+ | Diavisuals v0.4.0 | `1e842967eabbad4cdb7dcb081493c1c25772dc5f` | `bfedcc9e2554f25ce4a1c33e556f352210848fccb8da800d1c3900dd86c48c93` |
18
+ | Vegavisuals v0.4.0 | `68c0b231402ae9485cc34ce530dc5239cb0ec194` | `b52ffa743643dd6b5e0320e7a9aa0cd500ea06262b7d5098c0c3f94a379bc0ea` |
19
+
20
+ Canonical URLs are in `components.<provider>.reference`; dependency `uv_spec`
21
+ values derive from them. Validation binds a wheel's repository, release path,
22
+ package/version filename and nonzero SHA-256. Existing exact Git references
23
+ remain accepted. No additional component-contract field or wire version is needed.
24
+ The published Vega wheel/renderer archive targets Linux/amd64.
25
+
26
+ Native lifecycle flags, tools/resources and the complete dependency closure are
27
+ preserved. Vega consumer scaffold revision now comes from its published commit.
28
+ The current native receipts retain their original provider-owned semantics.
29
+ This unit does not add a v1 artifact importer or claim domain bundle compatibility.
30
+
31
+ ## Executed acceptance — 2026-09-26
32
+
33
+ - `make distribution-check`: passed.
34
+ - `PYTHONPATH=src python3 -m unittest discover -s test -p 'test_*.py'`:
35
+ 544 discovered, 515 passed, 29 optional cases skipped.
36
+ - `make wheel-check`: passed against a clean factory-free installed wheel.
37
+ - `make mcp-check mcp-smoke`: passed through the owner Docker development images,
38
+ including real stdio and preview/manual-PDF paths.
39
+ - `make docs-build`: passed in the published core runtime.
40
+ - `test/published_companion_smoke.py`: passed with separate installed published
41
+ wheel CLIs, their tested renderer images and a new temporary consumer with spaces.
42
+ It renders Mermaid, PlantUML, Vega-Lite with retained CSV data, and raw Vega;
43
+ checks actual provider receipts through `site_check`; rejects modified data and
44
+ diagram bytes; then accepts the relocated consumer. No receipt is fabricated.
45
+ - `git diff --check`: passed.
46
+
47
+ Reproduce the provider acceptance after installing the exact BOM wheel URLs and
48
+ loading/verifying the renderer archives from their releases:
49
+
50
+ ```bash
51
+ PYTHONPATH=src python3 test/published_companion_smoke.py \
52
+ --diavisuals /absolute/published-diavisuals/bin/diavisuals \
53
+ --vegavisuals /absolute/published-vegavisuals/bin/vegavisuals
54
+ ```
55
+
56
+ Tested renderer IDs:
57
+ `sha256:5a6887b372a0e1c386a7b54981d11ae1910215baeb6a12dfd0706b3e85ef0846`
58
+ (Diavisuals) and
59
+ `sha256:695125943d0fbc3aa7c877babb9a11a6501bbc7ac265b0975bb5657c60439d98`
60
+ (Vega). These identify the release archives' images, not OCI registry RepoDigests.
61
+
62
+ ## Activation and publication order
63
+
64
+ 1. Review/integrate this owner PR and choose the next coordinated core release
65
+ version. Do not rebuild or republish the existing 0.4.0 artifacts under this
66
+ changed BOM. Keep other already integrated editorial/scaffold changes in scope
67
+ when preparing that coherent release.
68
+ 2. Run the normal candidate/receipt/signing/package release procedure in
69
+ `docs/_documentation/en/40-distribution.md`. Verify installed runtime and
70
+ native receipts against the exact candidate digests; unchanged workers can
71
+ retain their existing reviewed identities.
72
+ 3. Advance `MCP_RELEASE_IMAGE` only in the normal post-release change, using its
73
+ new receipt. It currently remains
74
+ `ghcr.io/dosquartsdedocs/unaltraweb-mcp@sha256:389bc585cdb4fc89d3372f4896a55fe26e15df38b46bc114ce44fdb3f1c8deb9`.
75
+ A green development manifest does not mean that this older running image has
76
+ acquired the new companion contract.
77
+ 4. Reconcile hub dependency state and repair the existing unaltraweb client drift
78
+ through normal dependency-aware installation. Reconnect clients and inspect the
79
+ selected runtime's own manifest before updating real consumer scaffolds.
@@ -0,0 +1,19 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="640" height="180" viewBox="0 0 640 180" role="img" aria-labelledby="title desc">
2
+ <title id="title">Three linked stages</title>
3
+ <desc id="desc">Three labelled boxes, A, B and C, connected from left to right.</desc>
4
+ <rect width="640" height="180" fill="#fff"/>
5
+ <g fill="#eaf1f7" stroke="#315a75" stroke-width="2">
6
+ <rect x="35" y="45" width="150" height="90" rx="8"/>
7
+ <rect x="245" y="45" width="150" height="90" rx="8"/>
8
+ <rect x="455" y="45" width="150" height="90" rx="8"/>
9
+ </g>
10
+ <g fill="none" stroke="#315a75" stroke-width="3">
11
+ <path d="M185 90h50m-10-8 10 8-10 8"/>
12
+ <path d="M395 90h50m-10-8 10 8-10 8"/>
13
+ </g>
14
+ <g fill="#213f56" font-family="sans-serif" font-size="18" text-anchor="middle">
15
+ <text x="110" y="97">A</text>
16
+ <text x="320" y="97">B</text>
17
+ <text x="530" y="97">C</text>
18
+ </g>
19
+ </svg>
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env python3
2
+ """Run the gem's offline editorial publication check without an MCP checkout."""
3
+ from pathlib import Path
4
+ import sys
5
+
6
+ sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
7
+
8
+ from unaltraweb_mcp.editorial import main
9
+
10
+
11
+ if __name__ == "__main__":
12
+ raise SystemExit(main())
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env python3
2
+ """Run the packaged image background advisory without an MCP factory runtime."""
3
+ from pathlib import Path
4
+ import sys
5
+
6
+ sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
7
+
8
+ from unaltraweb_mcp.image_backgrounds import main
9
+
10
+
11
+ if __name__ == "__main__":
12
+ raise SystemExit(main())