unaltraweb 0.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9b1d06c849d3893c28fa69a879e93f56acef7a742aa8e2d8ae7df78fa53d4a2
4
- data.tar.gz: '0995fe545e4466b531edc89ed8c8a37ca707e847cc31a8a3acd3647d6b77ecdd'
3
+ metadata.gz: be599804b31390cca31133227e0e15f4ba623339a1072a441c74960b79c039fa
4
+ data.tar.gz: d70f999b0d814f6a579dbb06534c611034792a1cd29972b3015ecce5e21522a4
5
5
  SHA512:
6
- metadata.gz: 06dd87a7428129eb5ab81655c892abddf159d223aefec27cbdf5e7b5512a72fe7940061313cec5ccee5032ac1b0343cc6b8390617106c59b76d979b109d73cfc
7
- data.tar.gz: e2a1cc1fe578e4df0968d1f9b9fbc1abbb0cfed254d38c192e7ec24a55e254adf14c9ed57128255f5a18cbaacf68b4fc64a8c519c99d5f87e1a98798db42a1ca
6
+ metadata.gz: cb11d05e8660d167d311c7a9e1d03f895918d02c754e7189f52b25f1403f0056731aa94f77116b11cf30049c9d54b1ca6ffcae312c08d3127f942c756a1ed222
7
+ data.tar.gz: c7c798ce0e589fbd2fdaddfa9c4d632afd043ccfca6ecd65c780dfcae33932f6314da270968c665dfcdbac080f48e67022c66344b45961c8b87c1cfe0704ff9a
data/Makefile CHANGED
@@ -1,9 +1,9 @@
1
1
  PYTHON ?= python3
2
2
  override PROJECT := $${MCP_CONSUMER_WORKSPACE:?MCP_CONSUMER_WORKSPACE is required}
3
3
  override PROJECT_ROOT := $(PROJECT)
4
- MCP_RUNTIME_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb:0.5.0
5
- MCP_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.5.0
6
- MCP_RELEASE_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb-mcp@sha256:389bc585cdb4fc89d3372f4896a55fe26e15df38b46bc114ce44fdb3f1c8deb9
4
+ MCP_RUNTIME_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb:0.5.1
5
+ MCP_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.5.1
6
+ MCP_RELEASE_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb-mcp@sha256:36d17edbade77edb40a687f6a744203c6329acb33fbc2eb255e88d9ff1a42c98
7
7
  MCP_DOCKER_BUILD_NETWORK ?= default
8
8
  INIT_SITE_PROFILE ?= unaltreselfie
9
9
  NEW_WEB_PROFILE ?= unaltreselfie
@@ -40,10 +40,13 @@ WEB_CAPTURE_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb-web-capture@sha256:0bf1b
40
40
  WEB_CAPTURE_DEV_IMAGE ?= unaltraweb-web-capture:dev
41
41
  WEB_CAPTURE_DOCKER_BUILD_NETWORK ?= default
42
42
  VEGAVISUALS_CLI ?=
43
- DOCKER_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb:0.5.0
43
+ DOCKER_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb:0.5.1
44
44
  MANUAL_PDF_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb-manual-pdf@sha256:9e0b3a45753c170b795e9a9d6df61580085c113436beac5bf6c8de69b6562097
45
45
  MANUAL_PDF_DEV_IMAGE ?= unaltraweb-manual-pdf:dev
46
46
  MCP_SMOKE_MANUAL_PDF_IMAGE ?= $(MANUAL_PDF_IMAGE)
47
+ MCP_SMOKE_PROJECT ?=
48
+ override MCP_SMOKE_PROJECT := $(value MCP_SMOKE_PROJECT)
49
+ export MCP_SMOKE_PROJECT
47
50
  MANUAL_PDF_LANG ?=
48
51
  MANUAL_PDF_PUBLISH_DRY_RUN ?= 1
49
52
  MANUAL_PDF_CONFIRM_PUBLISH ?= 0
@@ -142,14 +145,18 @@ mcp-smoke: mcp-image manual-pdf-image-dev ## Build and prove a real MCP stdio co
142
145
 
143
146
  mcp-smoke-prebuilt: ## Prove a real MCP stdio connection using the selected prebuilt MCP image
144
147
  docker run --rm --user "$(LOCAL_UID):$(LOCAL_GID)" -e HOME=/tmp --entrypoint python3 "$(MCP_IMAGE)" /opt/unaltraweb/test/mcp_smoke.py
145
- @mkdir -p "$(CURDIR)/tmp/mcp-preview-smoke"
146
- @docker_socket="$${UNALTRAWEB_DOCKER_SOCKET:-/var/run/docker.sock}"; socket_group=$$(stat -c '%g' "$$docker_socket"); \
148
+ @mkdir -p "$(CURDIR)/tmp"
149
+ @project="$${MCP_SMOKE_PROJECT:-}"; \
150
+ if test -n "$$project"; then mkdir -- "$$project" || exit $$?; \
151
+ else project=$$(mktemp -d "$(CURDIR)/tmp/mcp-preview-smoke.XXXXXX") || exit $$?; fi; \
152
+ project=$$(realpath -e -- "$$project") || exit $$?; \
153
+ docker_socket="$${UNALTRAWEB_DOCKER_SOCKET:-/var/run/docker.sock}"; socket_group=$$(stat -c '%g' "$$docker_socket"); \
147
154
  image_id=$$(docker image inspect --format '{{.Id}}' "$(MCP_IMAGE)"); \
148
155
  socket_mount=$$(/bin/sh "$(DOCKER_MOUNT_SCRIPT)" "$$docker_socket" /var/run/docker.sock); \
149
- project_mount=$$(/bin/sh "$(DOCKER_MOUNT_SCRIPT)" "$(CURDIR)/tmp/mcp-preview-smoke" /workspace); \
150
- mirror_mount=$$(/bin/sh "$(DOCKER_MOUNT_SCRIPT)" "$(CURDIR)/tmp/mcp-preview-smoke" "$(CURDIR)/tmp/mcp-preview-smoke"); \
156
+ project_mount=$$(/bin/sh "$(DOCKER_MOUNT_SCRIPT)" "$$project" /workspace); \
157
+ mirror_mount=$$(/bin/sh "$(DOCKER_MOUNT_SCRIPT)" "$$project" "$$project"); \
151
158
  docker run --rm --user "$(LOCAL_UID):$(LOCAL_GID)" --group-add "$$socket_group" \
152
- -e HOME=/tmp -e "UNALTRAWEB_DOCKER_ROOT=$(CURDIR)/tmp/mcp-preview-smoke" \
159
+ -e HOME=/tmp -e "UNALTRAWEB_DOCKER_ROOT=$$project" \
153
160
  -e "UNALTRAWEB_PROJECT_USER=$(LOCAL_UID):$(LOCAL_GID)" -e "UNALTRAWEB_MCP_IMAGE=$$image_id" \
154
161
  -e "MANUAL_PDF_IMAGE=$(MCP_SMOKE_MANUAL_PDF_IMAGE)" \
155
162
  --mount "$$socket_mount" \
data/README.md CHANGED
@@ -34,7 +34,7 @@ The default distribution is Docker-first. Generated sites run their normal build
34
34
 
35
35
  ## Current Status
36
36
 
37
- - Public release `v0.4.0` provides the Docker images, Ruby gem and Python wheel as one receipt-bound distribution.
37
+ - Public release [`v0.5.0`](https://github.com/dosquartsdedocs/unaltraweb/releases/tag/v0.5.0) provides the Docker images, Ruby gem and Python wheel as one receipt-bound distribution.
38
38
  - `ghcr.io/dosquartsdedocs/unaltraweb-mcp` is the canonical normal local runtime for generated sites; `ghcr.io/dosquartsdedocs/unaltraweb` is its lower-level Jekyll runtime base.
39
39
  - The Ruby gem supports native Bundler/Jekyll consumers. The modular MCP wheel supports native creation and inspection, and does not bundle the gem, factory checkout, worker images or companion renderers.
40
40
  - PDF, browser-capture and computation environments remain separate images so the normal site image does not carry every heavy toolchain.
@@ -74,11 +74,11 @@ Create a child site directly with the public Docker image:
74
74
  mkdir my-site && \
75
75
  docker run --rm --network none --user "$(id -u):$(id -g)" -e HOME=/tmp \
76
76
  --mount "type=bind,src=${PWD}/my-site,dst=/workspace" \
77
- ghcr.io/dosquartsdedocs/unaltraweb-mcp@sha256:389bc585cdb4fc89d3372f4896a55fe26e15df38b46bc114ce44fdb3f1c8deb9 \
77
+ ghcr.io/dosquartsdedocs/unaltraweb-mcp@sha256:36d17edbade77edb40a687f6a744203c6329acb33fbc2eb255e88d9ff1a42c98 \
78
78
  --project /workspace new-web --site-profile unaltreselfie --title "My site" --default-lang en
79
79
  ```
80
80
 
81
- The chained `mkdir` requires a new destination, the digest binds creation to the reviewed `v0.4.0` receipt, and `--network none` keeps scaffold generation offline.
81
+ The chained `mkdir` requires a new destination, the digest binds creation to the reviewed `v0.5.0` receipt, and `--network none` keeps scaffold generation offline.
82
82
 
83
83
  If Python package tooling is already available, the PyPI adapter exposes the equivalent native command:
84
84
 
@@ -129,7 +129,7 @@ make docs-serve DOCKER_IMAGE=unaltraweb:dev
129
129
  make docs-build DOCKER_IMAGE=unaltraweb:dev
130
130
  ```
131
131
 
132
- The public distribution contract selects `ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.4.0` for normal generated-site commands. `MCP_RELEASE_IMAGE` pins the reviewed MCP digest from the same `v0.4.0` receipt for gContExt (formerly ContExt), the GNOME Shell extension. The mutable `:main` channel is reserved for explicit maintainer testing; locally built core images use the `:dev` name.
132
+ The public distribution contract selects `ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.5.0` for normal generated-site commands. `MCP_RELEASE_IMAGE` pins the reviewed MCP digest from the same `v0.5.0` receipt for gContExt (formerly ContExt), the GNOME Shell extension. The mutable `:main` channel is reserved for explicit maintainer testing; locally built core images use the `:dev` name.
133
133
 
134
134
  The lower-level `unaltraweb` image supplies Ruby, Jekyll and runtime dependencies. The MCP image layers the full reviewed factory and installed Python package on top; generated Make targets load the theme as a path gem from `/opt/unaltraweb`. Native Bundler consumers can instead resolve the independently published gem, and native Python users can install the wheel.
135
135
 
@@ -30,10 +30,10 @@ nav_title: Local Tools
30
30
  The current public core runtime image is:
31
31
 
32
32
  ```bash
33
- ghcr.io/dosquartsdedocs/unaltraweb:0.4.0
33
+ ghcr.io/dosquartsdedocs/unaltraweb:0.5.0
34
34
  ```
35
35
 
36
- That image provides Ruby, Bundler, Jekyll system dependencies, ImageMagick, Node for ExecJS and Python tooling needed by local commands. Package-generated `v0.4.0` sites select the matching public MCP image for normal local commands. The external integration fixture can advance from its older release pin independently.
36
+ That image provides Ruby, Bundler, Jekyll system dependencies, ImageMagick, Node for ExecJS and Python tooling needed by local commands. Package-generated `v0.5.0` sites select the matching public MCP image for normal local commands. The external integration fixture can advance from its older release pin independently.
37
37
 
38
38
  ## Generated Site Commands
39
39
 
@@ -143,4 +143,4 @@ When the core docs and all template profiles are running together, use this conv
143
143
  - Keep deploy workflows as thin `workflow_dispatch` wrappers pinned to a reviewed full commit SHA of `dosquartsdedocs/unaltraweb/.github/workflows/site-deploy.yml`.
144
144
  - The optional integration template may retain its local `gh-pages` publishing target for testing that separate workflow.
145
145
  - After the first Docker publish, make `ghcr.io/dosquartsdedocs/unaltraweb` public.
146
- - Confirm `docker pull ghcr.io/dosquartsdedocs/unaltraweb:0.4.0` works without `docker login`.
146
+ - Confirm `docker pull ghcr.io/dosquartsdedocs/unaltraweb:0.5.0` works without `docker login`.
@@ -65,7 +65,7 @@ docker compose -f docker-compose.yml down --remove-orphans
65
65
 
66
66
  This can be resource-heavy because the inherited demo build minifies JavaScript and can generate many responsive WebP images.
67
67
 
68
- The currently public base Dockerfile image is `ghcr.io/dosquartsdedocs/unaltraweb:0.4.0`. Published generated consumers select the higher-level `ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.4.0`, which adds the reviewed core and Python control plane. Their Make targets use `/opt/unaltraweb` as a path gem; the RubyGems package remains the optional native Bundler channel. gContExt prepares the full post-release `MCP_RELEASE_IMAGE` digest with `mcp-build`, while `mcp-image`, `mcp-check` and `mcp-smoke` reserve local `:dev` names for source testing. Mutable `:main` channels remain explicit maintainer paths.
68
+ The currently public base Dockerfile image is `ghcr.io/dosquartsdedocs/unaltraweb:0.5.0`. Published generated consumers select the higher-level `ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.5.0`, which adds the reviewed core and Python control plane. Their Make targets use `/opt/unaltraweb` as a path gem; the RubyGems package remains the optional native Bundler channel. gContExt prepares the full post-release `MCP_RELEASE_IMAGE` digest with `mcp-build`, while `mcp-image`, `mcp-check` and `mcp-smoke` reserve local `:dev` names for source testing. Mutable `:main` channels remain explicit maintainer paths.
69
69
 
70
70
  The root core build excludes `docs/`. The reference site is published from the `docs/` folder through a dedicated workflow so its root-relative permalinks do not collide with the inherited core demo build.
71
71
 
@@ -25,12 +25,13 @@ The template is the better place to validate gem consumption, centralized styles
25
25
 
26
26
  ## Component Contract
27
27
 
28
- ### 0.5.0 release preparation
28
+ ### Published 0.5.0 release
29
29
 
30
- The next coordinated core release is **0.5.0**. It groups the integrated editorial
30
+ The coordinated core release is [**0.5.0**](https://github.com/dosquartsdedocs/unaltraweb/releases/tag/v0.5.0). It groups the integrated editorial
31
31
  review, guided scaffold updates, caption-credit/image behavior and published
32
- Diavisuals/Vegavisuals 0.4.0 acceptance. Package, core/MCP and manual PDF candidates
33
- are verified through the existing source-bound workflows before publication.
32
+ Diavisuals/Vegavisuals 0.4.0 acceptance. Source-bound image/package workflows,
33
+ tag promotion and both Trusted Publishing jobs passed. Anonymous package downloads
34
+ match the receipt and clean native installations were checked.
34
35
  Unchanged already-published computation and web-capture workers retain their own
35
36
  0.4.0 versions and digests. New/pending worker candidates must still match the
36
37
  coordinated release; an old mutable alias cannot qualify for reuse. The selected
@@ -41,19 +42,35 @@ at source `d857f8c9f5fea90cf450c0b30b4e77a37b541275` and is selected by digest
41
42
  `sha256:9e0b3a45753c170b795e9a9d6df61580085c113436beac5bf6c8de69b6562097` in
42
43
  both the factory and the consumer tuple. It is already published and tested, so
43
44
  final candidate receipts cover the remaining ready package/core components.
44
- The factory launcher remains on its previous published image until the normal
45
- post-release pin update. Follow [issue 69](https://github.com/dosquartsdedocs/unaltraweb/issues/69)
46
- for the candidate, receipt, tag and package evidence.
45
+ The post-release factory launcher selects the MCP digest recorded in receipt
46
+ `3fa855378dcc61dc7b84b8b03812698042e02fed`:
47
+ `sha256:36d17edbade77edb40a687f6a744203c6329acb33fbc2eb255e88d9ff1a42c98`.
48
+ See [issue 69](https://github.com/dosquartsdedocs/unaltraweb/issues/69) for the
49
+ candidate, receipt, tag and package evidence.
47
50
 
48
51
  `src/unaltraweb_mcp/component-contract.json` is the canonical versioned bill of materials. Its `consumer_integration` object is the sole source for the reviewed core Git revision, reusable deploy workflow, manual PDF image digest, and Vega renderer revision. Scaffold templates render that tuple atomically into consumer `Gemfile`, `Gemfile.lock`, and deploy workflow files. `component-contract.schema.json` defines schema version 1. Runtime loading and `scripts/validate_distribution.py` validate the complete document against that schema, then enforce semantic parity between versions, release tags, repositories, references, wheel contents, CLI availability, and consumer integration pins.
49
52
 
50
- The BOM is an interoperability contract, not a bundle. The wheel contains only its Python control/inspection modules, schema/BOM, and clean package-owned scaffolds. In particular it does not contain Ruby theme assets, Docker image layers, factory Make/scripts/docs, TeX, Chromium, computation environments, `diavisuals`, or `vegavisuals`.
53
+ The BOM is an interoperability contract, not a bundle. The wheel contains its Python control/inspection modules, schema/BOM, and clean package-owned scaffolds. Next-release source also packages a small host Docker launcher, described below. Neither includes Ruby theme assets, Docker image layers, the factory's build/worker implementations, TeX, Chromium, computation environments, `diavisuals`, or `vegavisuals`.
51
54
 
52
- The selected public core release is `0.4.0`; `v0.3.0` remains the immutable previous distribution. The next-release source BOM reuses immutable compute and web-capture worker digests and selects published `diavisuals v0.4.0` and `vegavisuals v0.4.0` through SHA-256-pinned wheel URLs. Companion references can describe either a provider/release-matching Git reference or a provider/release/version-matching wheel with its content hash. The wheel boundary remains external. The scaffold's Vega revision is the published `68c0b231402ae9485cc34ce530dc5239cb0ec194` commit. These source changes require a new coordinated core release; they do not alter the already published `0.4.0` artifacts or the factory's `MCP_RELEASE_IMAGE` digest. `distribution-check` validates structural integrity for normal CI. `distribution-release-check` blocks coordinated publication while any component is `pending` or `unavailable`; reviewed source authorized to produce the final same-commit candidates is `ready`, while an already-published component is `released`.
55
+ The selected public core release is `0.5.0`; earlier distributions remain immutable. Its BOM reuses immutable compute and web-capture worker digests and selects published `diavisuals v0.4.0` and `vegavisuals v0.4.0` through SHA-256-pinned wheel URLs. Companion references can describe either a provider/release-matching Git reference or a provider/release/version-matching wheel with its content hash. The wheel boundary remains external. The scaffold's Vega revision is the published `68c0b231402ae9485cc34ce530dc5239cb0ec194` commit. `distribution-check` validates structural integrity for normal CI. `distribution-release-check` blocks coordinated publication while any component is `pending` or `unavailable`; reviewed source authorized to produce final same-commit candidates is `ready`, while an already-published component is `released`. Final receipt values remain immutable after publication.
53
56
 
54
57
  ## Docker-First Hybrid Policy
55
58
 
56
- GHCR is the canonical delivery channel for normal local use. The released package scaffold selects `ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.4.0`; existing `v0.3.0` sites can remain on their immutable previous release until deliberately updated. Its `make build`, `make serve` and `make test` targets mount the thin child site and run inside that image. The image contains both the installed Python control plane and the reviewed factory source at `/opt/unaltraweb`, so those targets load the theme as a path gem without downloading PyPI or RubyGems packages.
59
+ ### 0.5.1 preparation
60
+
61
+ The next coordinated core identity is **0.5.1**: gem, wheel, base runtime and MCP
62
+ image candidates change together. The installed host launcher and runtime-aware
63
+ generated Bundler state are included. The unchanged PDF worker retains its
64
+ published 0.5.0 digest, alongside the 0.4.0 computation/capture workers and visual
65
+ companions. A released PDF can be reused only by full digest; new/pending workers
66
+ still require the coordinated version. The historical 0.5.0 receipt remains
67
+ unchanged. Final signed image/package receipts and promotion are later gates;
68
+ the launcher continues selecting the last published MCP digest until its normal
69
+ post-release update.
70
+
71
+ ### Local delivery
72
+
73
+ GHCR is the canonical delivery channel for normal local use. The released package scaffold selects `ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.5.0`; existing sites can remain on their immutable previous release until deliberately updated. Its `make build`, `make serve` and `make test` targets mount the thin child site and run inside that image. The image contains both the installed Python control plane and the reviewed factory source at `/opt/unaltraweb`, so those targets load the theme as a path gem without downloading PyPI or RubyGems packages.
57
74
 
58
75
  Factory registration uses a stricter pin. gContExt runs `mcp-build`, which inspects or pulls the full `MCP_RELEASE_IMAGE` digest, and `mcp-stdio` launches that exact image. Checkout builds use local `:dev` names by default through `mcp-image`, `mcp-check` and `mcp-smoke`, so they do not shadow public semver references unless a maintainer explicitly overrides them. The digest is advanced in a separate post-release change after each new receipt exists; candidate source continues to select the last completed release instead of attempting to embed an unknown self-digest.
59
76
 
@@ -67,6 +84,95 @@ The distribution keeps native channels for interoperability rather than making t
67
84
 
68
85
  These remain real package boundaries: the MCP image installs the Python package and uses the core through Ruby's gem interface. The policy only makes their public registry installation optional for Docker users. It does not combine all toolchains into one image or duplicate worker layers in the wheel or gem.
69
86
 
87
+ ### Installed Docker launcher
88
+
89
+ 0.5.1 source adds **`unaltraweb-mcp-docker`** and a complete host launcher
90
+ under the installation prefix's `share/unaltraweb-launcher/`. The published 0.5.0
91
+ wheel predates this addition; its receipt and bytes remain unchanged. An installed
92
+ wheel containing the launcher can use the already-published full GHCR runtime
93
+ without a local core checkout:
94
+
95
+ ```bash
96
+ unaltraweb-mcp-docker prepare
97
+ unaltraweb-mcp-docker check
98
+ unaltraweb-mcp-docker smoke
99
+ unaltraweb-mcp-docker serve --project /absolute/consumer
100
+ ```
101
+
102
+ The installed default selects its package's full MCP release image, currently
103
+ `ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.5.1`. It resolves that selection to the
104
+ local immutable image ID before executing. The checkout's `MCP_RELEASE_IMAGE`
105
+ is a separate digest pin advanced only after publication; it is not the installed
106
+ wheel's default. This avoids sending a new package back to an older MCP while
107
+ also avoiding an impossible self-digest in the candidate image/wheel.
108
+ `--image` selects a different explicitly prepared image for a test or a reviewed
109
+ adoption. `prepare` only inspects/pulls; `check` and `smoke` use the local image ID,
110
+ without pulling, building, mounting a consumer or starting a preview. `serve`
111
+ requires an explicit consumer or inherited `MCP_CONSUMER_WORKSPACE`; it starts one
112
+ labelled stdio container and preserves the canonical host-path mirror for workers.
113
+ `down --project /absolute/consumer` uses the same project-scoped cleanup helper.
114
+
115
+ `unaltraweb-mcp-docker path` locates the installed profile from wheel metadata;
116
+ `manifest` prints its discovery descriptor. The profile ships the same native
117
+ schema-v1 `mcp-factory.yml`, a small launcher-only Makefile, and the bootstrap,
118
+ project-ID, Docker CSV mount and cleanup scripts. Its `${factoryRoot}` is this
119
+ installed directory, and the declared `make -C` transport and lifecycle targets
120
+ remain usable. That directory can also be relocated as a unit and run with Make,
121
+ a POSIX shell, Linux core utilities and Docker, without host Python or Ruby.
122
+ The console adapter itself requires the wheel's Python interpreter. Linux/amd64
123
+ is the acceptance platform; other host/platform combinations remain unverified.
124
+
125
+ This adapter launches the **full container runtime**. The native `unaltraweb-mcp`
126
+ CLI keeps the exact wheel-only/factory-required boundary declared in the BOM.
127
+ Installing the adapter does not install Jekyll, workers or companion servers on
128
+ the host, register a client, update a consumer scaffold, or change an active MCP.
129
+
130
+ ### Separate selections and compatibility evidence
131
+
132
+ The site Makefile's `MCP_IMAGE`, native Gem/core revision, PDF worker, global MCP
133
+ registration and companion selections are separate parts of an effective tuple.
134
+ TIG/TIGIT retain build defaults 0.4.0; Geodisseny retains 0.5.0. A global MCP
135
+ selection of 0.5.0 does not rewrite those defaults. Tests use synthetic sites,
136
+ image-specific test resources and dynamically allocated loopback preview ports.
137
+
138
+ Compatibility evidence is a set of tested tuples, not a continuous version range.
139
+ The [initial owner preparation report](https://github.com/dosquartsdedocs/unaltraweb/blob/main/docs/agents/owner-preparation-2026-09-29.md)
140
+ records all four 0.5.0 profiles, manual PDF coverage, the 0.4.0 comparison and
141
+ the reproduced retained-cache failure. The 0.5.1 correction is recorded in the
142
+ [follow-up report](https://github.com/dosquartsdedocs/unaltraweb/blob/main/docs/agents/owner-followup-76.md).
143
+ Range adoption belongs at
144
+ the native dependency/version checks, companion receipt checks and atomic
145
+ consumer-integration selection. Exact wheel hashes, image digests and published
146
+ receipts remain identity evidence even if future compatibility rules accept a
147
+ range. Central catalogue/range fields await the accepted hub integration.
148
+
149
+ ### Generated Bundler state
150
+
151
+ 0.5.1 keys generated dependencies by the effective Ruby/platform, Bundler,
152
+ installed gem inventory, core inputs and Bundler configuration, rather than a
153
+ mutable Docker tag. The offline resolver prepares a verified cache under
154
+ `tmp/unaltraweb-bundle/<identity>/`. Returning to an identity reuses its cache;
155
+ changing identities does not rewrite another runtime's lock. Credential-bearing
156
+ Bundler environment/configuration values contribute only hashes to the receipt.
157
+
158
+ New native build/preview targets execute with invocation-owned copies of that
159
+ generated state. Bundler can complete local default-gem checksum metadata without
160
+ rewriting the verified cache or disabling checksum validation. An
161
+ explicit `LOCAL_GEMFILE` is author-managed: its existing lock is required and
162
+ used frozen. Project `Gemfile`, `Gemfile.lock` and Bundler configuration are
163
+ preserved. Edited or incomplete generated caches fail for inspection instead of
164
+ being silently repaired. Failed preparation directories remain under `tmp/`.
165
+
166
+ For unchanged historical package Makefiles, the updated MCP prepares the same
167
+ runtime-specific cache and passes invocation-owned Gemfile/lock copies to the
168
+ old recipes. The retained `tmp/Gemfile.local.lock` remains untouched, so a later
169
+ 0.4.0 build can use its original selection. This adapter requires the Makefile to
170
+ match its recorded scaffold baseline; authored Makefile customizations retain
171
+ their own dependency policy. Those consumers can deliberately adopt the updated
172
+ native targets through the normal reviewed scaffold workflow. New native targets
173
+ require a containing core/runtime; the already-published 0.4.0 and 0.5.0 images do
174
+ not acquire the correction automatically.
175
+
70
176
  ## Optional Wheel And Doctor
71
177
 
72
178
  A clean `unaltraweb-mcp` wheel works without a factory checkout for `version`, `new-web`, top-level `doctor`, constrained source management, scaffold synchronization, `site-doctor`, HTML audit, and pure inspection where feasible. Examples include `mcp list-tools`, `starter-templates`, `detect-site`, `site-context`, `profile-check`, content/language/bibliography inventories, and `build-health`.
@@ -139,7 +245,7 @@ For that reason:
139
245
 
140
246
  ## Docker Runtime
141
247
 
142
- Release `0.4.0` publishes the selected base runtime, MCP runtime and specialized workers. Local maintainers continue to use explicit development names such as `unaltraweb:dev`; generated sites select the reviewed semver MCP image rather than `main` or `latest`.
248
+ Release `0.5.0` publishes the selected base/MCP runtime and packages while pinning the verified PDF worker and reusing unchanged specialized workers. Local maintainers continue to use explicit development names such as `unaltraweb:dev`; generated sites select the reviewed semver MCP image rather than `main` or `latest`.
143
249
 
144
250
  The base runtime owns Ruby, Jekyll and system dependencies. The MCP image builds on its exact candidate digest and adds the full reviewed factory plus the Python package. Specialized workers remain separate. This keeps each layer focused without adding Chromium, TeX or computation stacks to every site; the coordinated core-image workflow still rebuilds and verifies runtime, MCP and manual PDF candidates together.
145
251
 
@@ -13,21 +13,21 @@ weight: 140
13
13
  permalink: "/docker-image/"
14
14
  nav_title: Docker Images
15
15
  ---
16
- Release `v0.4.0` currently publishes two core images. Published generated sites select the self-contained MCP/site image for normal local commands:
16
+ Release `v0.5.0` currently publishes two core images. Published generated sites select the self-contained MCP/site image for normal local commands:
17
17
 
18
18
  ```text
19
- ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.4.0
19
+ ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.5.0
20
20
  ```
21
21
 
22
22
  It contains the Python control plane and the reviewed factory at `/opt/unaltraweb`. Its lower-level base is:
23
23
 
24
24
  ```text
25
- ghcr.io/dosquartsdedocs/unaltraweb:0.4.0
25
+ ghcr.io/dosquartsdedocs/unaltraweb:0.5.0
26
26
  ```
27
27
 
28
28
  The base provides Ruby, Bundler, Jekyll system dependencies, ImageMagick, Node for ExecJS and Python tooling. Generated Make targets run in the MCP image and load layouts, styles and plugins as a path gem from `/opt/unaltraweb`. RubyGems remains an optional native Bundler channel rather than a download required by the local Docker path.
29
29
 
30
- The `v0.4.0` receipt binds matching `unaltraweb:0.4.0` and `unaltraweb-mcp:0.4.0` references to their tested immutable digests. The semver aliases were promoted only after the coordinated receipt and tag checks completed.
30
+ The `v0.5.0` receipt binds matching `unaltraweb:0.5.0` and `unaltraweb-mcp:0.5.0` references to their tested immutable digests. The semver aliases were promoted only after the coordinated receipt and tag checks completed.
31
31
 
32
32
  gContExt prepares and launches the MCP image through the full digest in `MCP_RELEASE_IMAGE`. That post-release pin is separate from the semver scaffold reference and cannot be shadowed by checkout builds, which use local `:dev` names. A new release advances the pin only after its receipt records the published digest.
33
33
 
@@ -58,7 +58,7 @@ make mcp-image
58
58
  make mcp-smoke-prebuilt MCP_IMAGE=unaltraweb-mcp:dev
59
59
  ```
60
60
 
61
- Both core GHCR packages are public, and unauthenticated `v0.4.0` pulls have been verified.
61
+ Both core GHCR packages are public; their `v0.5.0` references resolve to the verified receipt digests.
62
62
 
63
63
  ## Computation Images
64
64
 
@@ -188,8 +188,8 @@ Selector-based screenshot authoring uses a separate Playwright image rather than
188
188
  ghcr.io/dosquartsdedocs/unaltraweb-web-capture@sha256:0bf1bc67fe63e1440bffe708a168beefa11c54441650a871ab99380d362f7c1e
189
189
  ```
190
190
 
191
- The `v0.4.0` contract reuses this already-published worker by immutable digest. The image contains pinned Playwright/Chromium, the capture worker, the Python status controller, and the core visual sources used in fingerprints. `make web-capture-image` builds the explicitly named `unaltraweb-web-capture:dev` maintainer image; set `WEB_CAPTURE_IMAGE` to that name when testing it. The manual `Web capture image` workflow publishes default-branch, commit, and semver/release tags to GHCR.
191
+ The `v0.5.0` contract reuses the already-published 0.4.0 worker by immutable digest. The image contains pinned Playwright/Chromium, the capture worker, the Python status controller, and the core visual sources used in fingerprints. `make web-capture-image` builds the explicitly named `unaltraweb-web-capture:dev` maintainer image; set `WEB_CAPTURE_IMAGE` to that name when testing it. The manual `Web capture image` workflow publishes default-branch, commit, and semver/release tags to GHCR.
192
192
 
193
- Published `v0.4.0` sites consume `ghcr.io/dosquartsdedocs/unaltraweb-manual-pdf:0.4.0`. `manual-pdf-image` reuses or pulls the selected image instead of rebuilding it locally. Maintainers use `make manual-pdf-image-dev` and then pass `MANUAL_PDF_IMAGE=unaltraweb-manual-pdf:dev` for local PDF runtime changes.
193
+ Published `v0.5.0` scaffolds consume `ghcr.io/dosquartsdedocs/unaltraweb-manual-pdf@sha256:9e0b3a45753c170b795e9a9d6df61580085c113436beac5bf6c8de69b6562097`. `manual-pdf-image` reuses or pulls the selected image instead of rebuilding it locally. Maintainers use `make manual-pdf-image-dev` and then pass `MANUAL_PDF_IMAGE=unaltraweb-manual-pdf:dev` for local PDF runtime changes.
194
194
 
195
195
  Rendering creates an ephemeral Docker `--internal` network shared only by Jekyll and Chromium, keeps browser requests on the preview origin, blocks service workers, popups, and WebSockets, drops Linux capabilities, uses a read-only container root and bounded resources, and writes only the declared PNG/SVG outputs under the mounted project. Ordinary checks run without browser execution or network access.
@@ -16,13 +16,29 @@ MCP_CONSUMER_WORKSPACE="$PWD" make --silent --no-print-directory -C /path/to/una
16
16
 
17
17
  Replace `/path/to/unaltraweb` with the checkout's absolute path. The bootstrap canonicalizes the inherited environment value after process launch; neither Make nor generated shell source evaluates consumer path text. The declared launcher remains `make`, which gContExt permits for a container runtime without a `runtime.allowed_host_launchers` exception. Restart clients such as OpenCode after changing their MCP registration.
18
18
 
19
+ Next-release wheels also install this native descriptor and its complete host
20
+ helper closure under `share/unaltraweb-launcher`. For that installed profile,
21
+ `${factoryRoot}` is the path returned by `unaltraweb-mcp-docker path`, rather than
22
+ a core checkout. Its small Makefile implements `mcp-build`, `mcp-check`,
23
+ `mcp-smoke`, `mcp-stdio` and `mcp-down` against the selected released image;
24
+ it cannot build checkout images. `unaltraweb-mcp-docker serve --project PATH`
25
+ is the direct installed entry point. Preparation may pull, whereas check/smoke
26
+ require a locally prepared image and use no consumer or Docker socket mount.
27
+ The copied schema-v1 descriptor retains the same server, workspace, inventory
28
+ and dependency identities. The released 0.5.0 wheel lacks these host assets;
29
+ the full 0.5.0 GHCR runtime already supports the operations they launch.
30
+ The installed profile selects its own BOM release image by default and resolves
31
+ it to an image ID before execution. The source checkout's digest pin is separate:
32
+ it advances only after a new receipt exists. Explicit `--image` (or the console
33
+ adapter's `UNALTRAWEB_MCP_IMAGE`) permits a reviewed immutable selection.
34
+
19
35
  gContExt dependency preparation ensures the selected MCP release image and prepares required companions but does not initialize consumer content. The transport passes `${workspaceFolder}` only through `MCP_CONSUMER_WORKSPACE`; it never sets `transport.cwd` or embeds the consumer path in a Make assignment. The factory command may therefore use `make -C` without changing or reparsing the selected consumer root. Companion-aware checks and smoke tests include both required providers, while provider updates remain explicit. The manifest does not advertise an `init` command, and both companion dependencies set `init: false`. Use `new_web` explicitly when a new consumer site should be created. Restart long-lived MCP clients after registration, release-pin changes, or provider upgrades so their stdio processes use the selected releases.
20
36
 
21
37
  Repository editing coordination remains a control-plane responsibility rather than an `unaltraweb` runtime feature. Request one top-level MCP and let the control plane select its declared dependency closure; unrelated user registrations remain configured until explicitly removed and clients reconnect. Before editing, the control plane runs its read-only checkout preflight against the one primary mutable checkout and, when required, holds a process-scoped cooperative lease through its `exec` wrapper. Only one editing session may be active per repository. The control plane must never create, switch to, move, prune, repair, or remove Git worktrees implicitly.
22
38
 
23
39
  For a new agent-driven workspace, create or select the empty Git repository first, open that directory in the IDE, register the factory, restart the client, and then call `new_web`. The tool remains confined to the configured project root and does not accept an arbitrary destination. Generated sites include user-owned `README.md` and `AGENTS.md`, profile-specific source directories, and a managed runtime baseline; `scaffold_sync` never rewrites those user-owned guidance or content files.
24
40
 
25
- The Python wheel remains modular. Without a factory checkout it supports `version`, `new-web`, top-level `doctor`, the host-only `import-calibre` command, and the exact package-only MCP inventory declared in `component-contract.json`. The complementary exact inventory fails clearly with `UNALTRAWEB_FACTORY_DIR` remediation. The BOM selects the published `diavisuals v0.3.1` and `vegavisuals v0.3.1` releases. Its `consumer_integration` object is also the single source for the immutable core, workflow, PDF worker, and Vega revisions rendered into consumer scaffolds. Neither companion is bundled in the wheel or MCP server namespace.
41
+ The native Python CLI remains modular. Without a factory checkout it supports `version`, `new-web`, top-level `doctor`, the host-only `import-calibre` command, and the exact package-only MCP inventory declared in `component-contract.json`. The complementary exact inventory fails clearly with `UNALTRAWEB_FACTORY_DIR` remediation. The separate Docker adapter delegates to the full image and does not expand that native inventory. The BOM selects the published `diavisuals v0.4.0` and `vegavisuals v0.4.0` releases. Its `consumer_integration` object is also the single source for the immutable core, workflow, PDF worker, and Vega revisions rendered into consumer scaffolds. Neither companion is bundled in the wheel or MCP server namespace.
26
42
 
27
43
  Static Vega-Lite and Vega rendering remains owned by the required companion `vegavisuals` MCP dependency. Use its `visualization_status`, `visualization_check`, `render_visualizations`, and `vegavisuals://project/*` resources directly; `unaltraweb` exposes the authoring syntax but does not proxy those tools into the `web://` server.
28
44
 
@@ -226,7 +242,7 @@ For companion linking, compare the selected BOM and dependency capabilities with
226
242
  each running provider's `factory_manifest`, `compatibility_status` and release
227
243
  evidence. A development checkout announcing a future version is not a published
228
244
  release or evidence that a long-lived MCP process has upgraded. The current
229
- published companion selections are `diavisuals v0.3.1` and `vegavisuals v0.3.1`.
245
+ published companion selections are `diavisuals v0.4.0` and `vegavisuals v0.4.0`.
230
246
  Advance them only after their immutable releases exist and their receipt/tool
231
247
  contracts have been verified; source-checkout version drift remains an explicit
232
248
  control-plane finding, not a reason to weaken receipt validation.
@@ -247,6 +263,17 @@ Translations are a pre-publication task. They should preserve `ref`, citations,
247
263
 
248
264
  Run `site_doctor` and `site_check`, then resolve any blocking validation result before compiling. `build_site` reuses the active MCP container and the consumer's `build-native` target, and runs the local HTML audit after a successful Jekyll process. The generated `test-native` target also runs `html_audit`. This is intentionally different from the consumer's normal host-side `make build`, which starts a Jekyll container and would create a nested runtime when called from MCP.
249
265
 
266
+ In 0.5.1, `bundler_runtime` prepares offline, identity-keyed generated locks under
267
+ `tmp/unaltraweb-bundle`, verifying their receipts on reuse and retaining edited
268
+ or incomplete caches. Identity includes the actual Ruby/Bundler/gem inventory,
269
+ core inputs and hashed Bundler configuration. Updated native targets use private
270
+ invocation copies; an explicit author `LOCAL_GEMFILE` requires its own existing frozen lock.
271
+ For unchanged historical package Makefiles, `build_site` and the same-image
272
+ preview pass invocation-owned copies through `LOCAL_GEMFILE`, preserving the old
273
+ generated lock and all author sources. A modified Makefile is not overridden.
274
+ The fix requires a containing runtime, and does not mutate released 0.5.0 images
275
+ or real consumers. See [the populated-cache follow-up](owner-followup-76.md).
276
+
250
277
  Make delegation and feasible Docker control calls use one bounded subprocess runner. Status and control commands have short deadlines, builds/renders have target-specific longer deadlines, timeout terminates the process group and returns code `124`, and retained stdout/stderr is capped with explicit truncation fields. Factory commands that promise JSON fail closed when output is empty, malformed, non-object, non-finite, or truncated. Every bind source and target is encoded as a quoted Docker CSV field, so commas or quotes in host paths cannot introduce duplicate mount fields; carriage-return and newline path characters are rejected before canonicalization or mount construction. Computation, capture, and PDF containers carry factory, worker-role, project, and invocation-token labels plus cidfiles; after timeout cleanup selects all four labels and cannot remove unrelated containers.
251
278
 
252
279
  A preview must outlive one MCP tool invocation, so it runs in a separate container made from the same MCP/Jekyll image. Its deterministic name is derived from the canonical host project path and it carries the factory, role, and project labels. Its isolated container always listens on port `4000`; the default host port is allocated atomically by Docker on loopback and is reported as `preview_status.port`, preventing the old cross-project collision on host port `4000`. Starting an already-running preview probes it again instead of creating a duplicate. A preview created under the former fixed-port default is accepted as compatible with the new automatic default until it is stopped; its next start uses dynamic allocation. Changing an explicit requested port or profile still requires stopping first. Stdio session containers intentionally have Docker-generated names so independent clients can run simultaneously, but carry the same stable project ID and labels as previews and capture resources. That process-level capability does not authorize concurrent editing sessions in one repository. Stop and cleanup operations select ownership labels before removing anything.
@@ -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.