unaltraweb 0.5.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Makefile +13 -11
- data/_plugins/retained_documents.rb +62 -0
- data/docs/_documentation/en/40-distribution.md +73 -19
- data/docs/_documentation/en/45-retained-documents.md +138 -0
- data/docs/_documentation/en/46-live-runtime.md +89 -0
- data/docs/agents/d0-runtime-identity.md +200 -0
- data/docs/agents/mcp-contract.md +45 -2
- data/docs/agents/owner-closeout-76.md +205 -0
- data/docs/agents/owner-closeout-80.md +185 -0
- data/docs/agents/retained-letter-import.md +235 -0
- data/lib/unaltraweb.rb +1 -0
- data/requirements.txt +2 -0
- data/scripts/manual/Dockerfile +7 -4
- data/scripts/manual/build_pdf.py +28 -0
- data/scripts/manual/templates/manual.tex +1 -0
- data/scripts/test_gem_build.py +27 -0
- data/scripts/test_wheel_install.py +7 -2
- data/scripts/unaltraweb-mcp-bootstrap.sh +90 -9
- data/scripts/unaltraweb-mcp-cleanup.sh +41 -9
- data/scripts/web_captures/render.py +8 -1
- data/src/unaltraweb_mcp/__init__.py +4 -0
- data/src/unaltraweb_mcp/artifact-handoff-v1.schema.json +102 -0
- data/src/unaltraweb_mcp/artifact_handoff_v1.py +435 -0
- data/src/unaltraweb_mcp/artifact_imports.py +368 -0
- data/src/unaltraweb_mcp/component-contract.json +27 -27
- data/src/unaltraweb_mcp/distribution.py +887 -0
- data/src/unaltraweb_mcp/letter_bundle.py +223 -0
- data/src/unaltraweb_mcp/pdf_probe.py +63 -0
- metadata +16 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2ed24da568933de15be12350ea7b867a6aa7e14abac71ec303755f5b808e1837
|
|
4
|
+
data.tar.gz: a4176d255c14de252144d7669db6479bc43ee033342332cd596870eea1ddf71b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 768943c9b012a7e165ab9136d364783203c35caaaae62c2715f95361107f63377dbac30e45252ebeff78b0707d71dd14eb0481cecca18f52b15688c82f4c8c10
|
|
7
|
+
data.tar.gz: 49edeb75312f6d45e53db50a55a65f25ddb81f7ad8cc8438c9568ada3c9d699c9c00f0a329ea9b8cc2fb5812b5e48acd254e0e967b659d16650a0ea8612dad16
|
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
|
-
MCP_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.
|
|
6
|
-
MCP_RELEASE_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb-mcp@sha256:
|
|
4
|
+
MCP_RUNTIME_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb:0.7.0
|
|
5
|
+
MCP_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.7.0
|
|
6
|
+
MCP_RELEASE_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb-mcp@sha256:736c4ddd0a543454e3edaeac2e9cfd97a1279ce472923ac54e326c1281b2ba05
|
|
7
7
|
MCP_DOCKER_BUILD_NETWORK ?= default
|
|
8
8
|
INIT_SITE_PROFILE ?= unaltreselfie
|
|
9
9
|
NEW_WEB_PROFILE ?= unaltreselfie
|
|
@@ -40,8 +40,8 @@ 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.
|
|
44
|
-
MANUAL_PDF_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb-manual-pdf@sha256:
|
|
43
|
+
DOCKER_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb:0.7.0
|
|
44
|
+
MANUAL_PDF_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb-manual-pdf@sha256:0ba267cb87f53ebaca4e31805fe00610cd61fdf97a8d2c3692f4655700dceaed
|
|
45
45
|
MANUAL_PDF_DEV_IMAGE ?= unaltraweb-manual-pdf:dev
|
|
46
46
|
MCP_SMOKE_MANUAL_PDF_IMAGE ?= $(MANUAL_PDF_IMAGE)
|
|
47
47
|
MCP_SMOKE_PROJECT ?=
|
|
@@ -71,7 +71,7 @@ export MANUAL_RELEASE_SELECTOR MANUAL_PDF_LANG MANUAL_PDF_PUBLISH_DRY_RUN MANUAL
|
|
|
71
71
|
UNALTRAWEB_WORKER_ROLE ?=
|
|
72
72
|
UNALTRAWEB_WORKER_PROJECT ?=
|
|
73
73
|
UNALTRAWEB_WORKER_TOKEN ?=
|
|
74
|
-
WORKER_LABEL_ARGS = $(if $(strip $(UNALTRAWEB_WORKER_TOKEN)),--label "io.context.mcp-factory=unaltraweb" --label "io.context.mcp-role=$(UNALTRAWEB_WORKER_ROLE)" --label "io.context.mcp-project=$(UNALTRAWEB_WORKER_PROJECT)" --label "io.context.mcp-worker-token=$(UNALTRAWEB_WORKER_TOKEN)",)
|
|
74
|
+
WORKER_LABEL_ARGS = $(if $(strip $(UNALTRAWEB_WORKER_TOKEN)),--label "io.context.mcp-factory=unaltraweb" --label "io.context.mcp-role=$(UNALTRAWEB_WORKER_ROLE)" --label "io.context.mcp-project=$(UNALTRAWEB_WORKER_PROJECT)" --label "io.context.mcp-worker-token=$(UNALTRAWEB_WORKER_TOKEN)",) $(if $(strip $(UNALTRAWEB_RUNTIME_SESSION)),--label "io.context.mcp-session=$(UNALTRAWEB_RUNTIME_SESSION)",)
|
|
75
75
|
DOCS_CONTAINER ?= unaltraweb-docs-local
|
|
76
76
|
DOCS_HOST ?= 0.0.0.0
|
|
77
77
|
DOCS_PORT ?= 4000
|
|
@@ -295,17 +295,18 @@ manual-compute-render: ## Execute sources and atomically publish Markdown and fi
|
|
|
295
295
|
python_image="$(COMPUTE_PYTHON_IMAGE)"; r_image="$(COMPUTE_R_IMAGE)"; \
|
|
296
296
|
if test "$$engine" = "r"; then r_image="$$image"; else python_image="$$image"; fi; \
|
|
297
297
|
if ! docker image inspect "$$image" >/dev/null 2>&1; then \
|
|
298
|
+
if test "$${UNALTRAWEB_MANAGED_RUNTIME:-0}" = 1; then printf '%s\n' 'Selected computation image is not prepared; managed execution never builds or pulls' >&2; exit 1; fi; \
|
|
298
299
|
COMPUTE_PYTHON_IMAGE="$(COMPUTE_PYTHON_IMAGE)" COMPUTE_R_IMAGE="$(COMPUTE_R_IMAGE)" COMPUTE_DOCKER_BUILD_NETWORK="$(COMPUTE_DOCKER_BUILD_NETWORK)" $(PYTHON) "$(COMPUTE_SCRIPT)" image --project "$(PROJECT_ROOT)" --engine "$$engine" >/dev/null; \
|
|
299
300
|
fi; \
|
|
300
301
|
identity=$$(docker image inspect "$$image" --format '{{.Id}}'); \
|
|
301
302
|
digest=$$(docker image inspect "$$image" --format '{{join .RepoDigests ","}}'); \
|
|
302
303
|
set --; if test -n "$(UNALTRAWEB_WORKER_TOKEN)"; then cidfile="$$runtime_dir/worker-$(UNALTRAWEB_WORKER_TOKEN)-$$engine.cid"; rm -f "$$cidfile"; cidfiles="$$cidfiles $$cidfile"; set -- --cidfile "$$cidfile"; fi; \
|
|
303
|
-
docker run --rm "$$@" $(WORKER_LABEL_ARGS) --user "$(LOCAL_UID):$(LOCAL_GID)" --network none --read-only --cap-drop ALL --security-opt no-new-privileges --pids-limit "$(COMPUTE_PIDS_LIMIT)" --cpus "$(COMPUTE_CPUS)" --memory "$(COMPUTE_MEMORY)" --tmpfs /tmp:rw,noexec,nosuid,size=1g \
|
|
304
|
+
docker run --rm --pull never "$$@" $(WORKER_LABEL_ARGS) --user "$(LOCAL_UID):$(LOCAL_GID)" --network none --read-only --cap-drop ALL --security-opt no-new-privileges --pids-limit "$(COMPUTE_PIDS_LIMIT)" --cpus "$(COMPUTE_CPUS)" --memory "$(COMPUTE_MEMORY)" --tmpfs /tmp:rw,noexec,nosuid,size=1g \
|
|
304
305
|
-e HOME=/tmp -e COMPUTE_PYTHON_IMAGE="$$python_image" -e COMPUTE_R_IMAGE="$$r_image" \
|
|
305
306
|
-e UNALTRAWEB_COMPUTE_IMAGE_ID="$$identity" -e UNALTRAWEB_COMPUTE_IMAGE_DIGEST="$$digest" \
|
|
306
307
|
--mount "$$project_mount" \
|
|
307
308
|
--mount "$$runtime_mount" \
|
|
308
|
-
-w /project --entrypoint python3 "$$
|
|
309
|
+
-w /project --entrypoint python3 "$$identity" \
|
|
309
310
|
/opt/unaltraweb/computations/render.py render --project /project --engine "$$engine" $(if $(strip $(COMPUTE_SOURCE)),--source "$(COMPUTE_SOURCE)",) $(if $(filter 1 true TRUE yes YES y Y,$(COMPUTE_CONFIRM_OVERWRITE)),--confirm-overwrite,) $(if $(filter 1 true TRUE yes YES y Y,$(COMPUTE_STALE_ONLY)),--stale-only,) $(if $(strip $(COMPUTE_MODE)),--mode "$(COMPUTE_MODE)",) >> "$$results"; \
|
|
310
311
|
done; \
|
|
311
312
|
if test -z "$(strip $(COMPUTE_SOURCE))"; then $(PYTHON) "$(COMPUTE_SCRIPT)" prune --project "$(PROJECT_ROOT)" >/dev/null; fi; \
|
|
@@ -375,20 +376,21 @@ manual-pdf-image: ## Ensure the selected versioned Pandoc/XeLaTeX image is prese
|
|
|
375
376
|
@docker image inspect "$(MANUAL_PDF_IMAGE)" >/dev/null 2>&1 || docker pull "$(MANUAL_PDF_IMAGE)"
|
|
376
377
|
|
|
377
378
|
manual-pdf-image-dev: ## Build the explicitly named maintainer PDF development image
|
|
378
|
-
docker build -f scripts/manual/Dockerfile -t "$(MANUAL_PDF_DEV_IMAGE)"
|
|
379
|
+
docker build -f scripts/manual/Dockerfile -t "$(MANUAL_PDF_DEV_IMAGE)" .
|
|
379
380
|
|
|
380
381
|
define run_manual_pdf_worker
|
|
381
382
|
@set -e; set --; cidfile=""; \
|
|
382
383
|
if test -n "$(UNALTRAWEB_WORKER_TOKEN)"; then runtime_dir="$(PROJECT_ROOT)/tmp/.unaltraweb/manual-pdf"; mkdir -p "$$runtime_dir"; cidfile="$$runtime_dir/worker-$(UNALTRAWEB_WORKER_TOKEN).cid"; rm -f "$$cidfile"; set -- --cidfile "$$cidfile"; fi; \
|
|
383
384
|
mount=$$(/bin/sh "$(DOCKER_MOUNT_SCRIPT)" "$(PROJECT_ROOT)" /project); \
|
|
384
385
|
trap 'test -z "$$cidfile" || rm -f "$$cidfile"' EXIT; \
|
|
385
|
-
docker
|
|
386
|
+
identity=$$(docker image inspect "$(MANUAL_PDF_IMAGE)" --format '{{.Id}}'); \
|
|
387
|
+
docker run --rm --pull never --network none --cpus 2 --memory 2g --pids-limit 256 "$$@" $(WORKER_LABEL_ARGS) --user "$(LOCAL_UID):$(LOCAL_GID)" -e HOME=/tmp -e "UNALTRAWEB_MANUAL_RELEASE_SELECTOR=$${MANUAL_RELEASE_SELECTOR}" --mount "$$mount" -w /project "$$identity" $(1) --project /project $(if $(strip $(MANUAL_PDF_LANG)),--language "$(MANUAL_PDF_LANG)",) $(2)
|
|
386
388
|
endef
|
|
387
389
|
|
|
388
390
|
manual-pdf-preflight: ## Run required PDF gates without contaminating the worker JSON stream
|
|
389
391
|
@$(MAKE) --silent --no-print-directory manual-compute-check >/dev/null
|
|
390
392
|
@$(MAKE) --silent --no-print-directory web-capture-check >/dev/null
|
|
391
|
-
@docker image inspect "$(MANUAL_PDF_IMAGE)" >/dev/null 2>&1 || docker pull "$(MANUAL_PDF_IMAGE)" >/dev/null
|
|
393
|
+
@docker image inspect "$(MANUAL_PDF_IMAGE)" >/dev/null 2>&1 || { if test "$${UNALTRAWEB_MANAGED_RUNTIME:-0}" = 1; then printf '%s\n' 'Selected PDF image is not prepared; managed execution never pulls' >&2; exit 1; fi; docker pull "$(MANUAL_PDF_IMAGE)" >/dev/null; }
|
|
392
394
|
|
|
393
395
|
manual-pdf-status: ## Inspect manual PDF configuration and artefacts without Docker, network, or writes
|
|
394
396
|
@UNALTRAWEB_MANUAL_RELEASE_SELECTOR="$${MANUAL_RELEASE_SELECTOR}" $(PYTHON) "$(CURDIR)/scripts/manual/build_pdf.py" status --project "$(PROJECT_ROOT)" $(if $(strip $(MANUAL_PDF_LANG)),--language "$(MANUAL_PDF_LANG)",)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cgi"
|
|
4
|
+
require "json"
|
|
5
|
+
require "open3"
|
|
6
|
+
require "timeout"
|
|
7
|
+
|
|
8
|
+
module UnaltrawebRetainedDocuments
|
|
9
|
+
def self.verify(site, output = nil)
|
|
10
|
+
return { "imports" => [] } unless File.exist?(File.join(site.source, ".unaltraweb", "artifacts"))
|
|
11
|
+
|
|
12
|
+
source = File.expand_path("../src", __dir__)
|
|
13
|
+
command = ["python3", "-m", "unaltraweb_mcp.artifact_imports", "--project", File.expand_path(site.source)]
|
|
14
|
+
command += ["--output-folder", output] if output
|
|
15
|
+
stdout, stderr, status = Timeout.timeout(120) { Open3.capture3({ "PYTHONPATH" => source }, *command) }
|
|
16
|
+
result = JSON.parse(stdout)
|
|
17
|
+
raise Jekyll::Errors::FatalException, "Retained document check failed: #{result['error'] || stderr}" unless status.success? && result["ok"] == true
|
|
18
|
+
|
|
19
|
+
result
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class Generator < Jekyll::Generator
|
|
23
|
+
safe true
|
|
24
|
+
priority :highest
|
|
25
|
+
|
|
26
|
+
def generate(site)
|
|
27
|
+
site.config["unaltraweb_retained_documents"] = UnaltrawebRetainedDocuments.verify(site)["imports"].to_h { |item| [item["id"], item] }
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class DocumentTag < Liquid::Tag
|
|
32
|
+
def initialize(name, markup, tokens)
|
|
33
|
+
super
|
|
34
|
+
@id = markup.strip
|
|
35
|
+
raise ArgumentError, "retained_document requires one import ID" unless @id.match?(/\A[a-z][a-z0-9-]{0,63}\z/)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def render(context)
|
|
39
|
+
site = context.registers[:site]
|
|
40
|
+
item = (site.config["unaltraweb_retained_documents"] || {})[@id]
|
|
41
|
+
raise Jekyll::Errors::FatalException, "Unverified retained document #{@id}" unless item
|
|
42
|
+
|
|
43
|
+
path = site.config["baseurl"].to_s.sub(%r{/\z}, "") + "/" + item.fetch("pdf")
|
|
44
|
+
url = CGI.escapeHTML(path)
|
|
45
|
+
page = context["page"]
|
|
46
|
+
title = CGI.escapeHTML(((page && page["title"]) || @id).to_s)
|
|
47
|
+
%(<figure class="retained-document"><object data-retained-document="#{@id}" data="#{url}" type="application/pdf" aria-label="#{title}" style="width:100%;height:70vh"><a href="#{url}">#{title}</a></object><figcaption><a href="#{url}">#{title} (PDF)</a></figcaption></figure>)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
Liquid::Template.register_tag("retained_document", UnaltrawebRetainedDocuments::DocumentTag)
|
|
53
|
+
|
|
54
|
+
Jekyll::Hooks.register :site, :post_write do |site|
|
|
55
|
+
source = File.expand_path(site.source)
|
|
56
|
+
destination = File.expand_path(site.dest)
|
|
57
|
+
if destination.start_with?(source + "/")
|
|
58
|
+
UnaltrawebRetainedDocuments.verify(site, destination.delete_prefix(source + "/"))
|
|
59
|
+
elsif !(site.config["unaltraweb_retained_documents"] || {}).empty?
|
|
60
|
+
raise Jekyll::Errors::FatalException, "Retained documents require a project-confined site destination"
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -25,9 +25,63 @@ The template is the better place to validate gem consumption, centralized styles
|
|
|
25
25
|
|
|
26
26
|
## Component Contract
|
|
27
27
|
|
|
28
|
-
###
|
|
29
|
-
|
|
30
|
-
The
|
|
28
|
+
### 0.7.0 D0 runtime increment
|
|
29
|
+
|
|
30
|
+
The next containing runtime adds [live instance identity and session-scoped
|
|
31
|
+
resource control]({{ '/live-runtime/' | relative_url }}). Preparation is explicit,
|
|
32
|
+
launch is pull-never, and startup identity remains distinct from current disk
|
|
33
|
+
metadata. The owner-tested rendering closure selects Diavisuals 0.5.0 and Vega
|
|
34
|
+
0.5.1 with exact artifacts; old 0.4.0 static receipts remain integrity-checked.
|
|
35
|
+
Diavisuals' separate live-process identity correction still gates the full
|
|
36
|
+
managed coordinator closure. Publication and activation evidence belong to the
|
|
37
|
+
[D0 owner record](https://github.com/dosquartsdedocs/unaltraweb/blob/main/docs/agents/d0-runtime-identity.md).
|
|
38
|
+
|
|
39
|
+
### Published 0.6.0 release
|
|
40
|
+
|
|
41
|
+
[**0.6.0**](https://github.com/dosquartsdedocs/unaltraweb/releases/tag/v0.6.0)
|
|
42
|
+
delivers native [retained-letter import]({{ '/retained-documents/' | relative_url }}).
|
|
43
|
+
Gem, wheel, base runtime and MCP were published from
|
|
44
|
+
`de52db351490e94939aac20c6af264f22a6a1678`; receipt-only integration and tag target
|
|
45
|
+
`ec6dcb28e890d32718aa173934527a7b4213a042` bind their verified bytes.
|
|
46
|
+
The consumer core selects reviewed integration
|
|
47
|
+
`5cf9817489c8dc47cee726bfe42fe3071cd32b85`; the PDF 0.6.0 worker is already
|
|
48
|
+
published, signed and tested at immutable digest
|
|
49
|
+
`sha256:0ba267cb87f53ebaca4e31805fe00610cd61fdf97a8d2c3692f4655700dceaed`.
|
|
50
|
+
The PDF worker changes to include complete retained documents and the same
|
|
51
|
+
integrity checkers used by its controller. Computation, capture and visual
|
|
52
|
+
companions retain their tested 0.4.0 selections.
|
|
53
|
+
|
|
54
|
+
The post-release checkout launcher selects published MCP digest
|
|
55
|
+
`sha256:736c4ddd0a543454e3edaeac2e9cfd97a1279ce472923ac54e326c1281b2ba05`.
|
|
56
|
+
Signed candidates, protected CI, strict receipt/ancestry gates, registry promotion
|
|
57
|
+
and Trusted Publishing passed. Anonymous downloads match the receipt. The
|
|
58
|
+
[delivery report](https://github.com/dosquartsdedocs/unaltraweb/blob/main/docs/agents/owner-closeout-80.md)
|
|
59
|
+
records the installed Carta relocation proof and four-profile populated-cache
|
|
60
|
+
roundtrip against those exact bytes. Existing clients keep their loaded image
|
|
61
|
+
until reconnecting; real consumer adoption remains explicit.
|
|
62
|
+
|
|
63
|
+
### Published 0.5.1 release
|
|
64
|
+
|
|
65
|
+
[**0.5.1**](https://github.com/dosquartsdedocs/unaltraweb/releases/tag/v0.5.1)
|
|
66
|
+
delivers the installed Docker launcher and runtime-specific generated Bundler
|
|
67
|
+
state. Source `aab5a7b030cd711b40770a3f44ad3a356eab90da` produced the signed
|
|
68
|
+
images and verified gem/wheel. Receipt/tag commit
|
|
69
|
+
`e842c733c8a274279dd5efdc3618e20669f29037` changes only the receipt from that
|
|
70
|
+
first parent. Strict release/publication gates passed before promotion, and
|
|
71
|
+
anonymous registry downloads match the receipt. That release's launcher selected
|
|
72
|
+
`ghcr.io/dosquartsdedocs/unaltraweb-mcp@sha256:908b4ce54c7bdf355e14ed55b31ed4b9baae319e211af90004a680d1d1cb8692`.
|
|
73
|
+
|
|
74
|
+
The four-profile populated-cache roundtrip also passed against the actual signed
|
|
75
|
+
candidate. The selected PDF stays at its published 0.5.0 digest, and computation,
|
|
76
|
+
capture and visual companions retain 0.4.0. See the
|
|
77
|
+
[delivery report](https://github.com/dosquartsdedocs/unaltraweb/blob/main/docs/agents/owner-closeout-76.md)
|
|
78
|
+
and [issue 76](https://github.com/dosquartsdedocs/unaltraweb/issues/76).
|
|
79
|
+
Strict release validation applies to the receipt/tag revision; subsequent
|
|
80
|
+
post-release launcher changes are ordinary source revisions, not new receipts.
|
|
81
|
+
|
|
82
|
+
### Previous 0.5.0 release
|
|
83
|
+
|
|
84
|
+
The previous coordinated core release is [**0.5.0**](https://github.com/dosquartsdedocs/unaltraweb/releases/tag/v0.5.0). It groups the integrated editorial
|
|
31
85
|
review, guided scaffold updates, caption-credit/image behavior and published
|
|
32
86
|
Diavisuals/Vegavisuals 0.4.0 acceptance. Source-bound image/package workflows,
|
|
33
87
|
tag promotion and both Trusted Publishing jobs passed. Anonymous package downloads
|
|
@@ -42,7 +96,7 @@ at source `d857f8c9f5fea90cf450c0b30b4e77a37b541275` and is selected by digest
|
|
|
42
96
|
`sha256:9e0b3a45753c170b795e9a9d6df61580085c113436beac5bf6c8de69b6562097` in
|
|
43
97
|
both the factory and the consumer tuple. It is already published and tested, so
|
|
44
98
|
final candidate receipts cover the remaining ready package/core components.
|
|
45
|
-
The post-release factory launcher
|
|
99
|
+
The 0.5.0 post-release factory launcher selected the MCP digest recorded in receipt
|
|
46
100
|
`3fa855378dcc61dc7b84b8b03812698042e02fed`:
|
|
47
101
|
`sha256:36d17edbade77edb40a687f6a744203c6329acb33fbc2eb255e88d9ff1a42c98`.
|
|
48
102
|
See [issue 69](https://github.com/dosquartsdedocs/unaltraweb/issues/69) for the
|
|
@@ -50,27 +104,27 @@ candidate, receipt, tag and package evidence.
|
|
|
50
104
|
|
|
51
105
|
`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.
|
|
52
106
|
|
|
53
|
-
The BOM is an interoperability contract, not a bundle. The wheel contains its Python control/inspection modules, schema/BOM,
|
|
107
|
+
The BOM is an interoperability contract, not a bundle. The wheel contains its Python control/inspection modules, schema/BOM, clean package-owned scaffolds and a small host Docker launcher, described below. It does not include Ruby theme assets, Docker image layers, the factory's build/worker implementations, TeX, Chromium, computation environments, `diavisuals`, or `vegavisuals`.
|
|
54
108
|
|
|
55
|
-
The selected public core release is `0.
|
|
109
|
+
The selected public core release is `0.6.0`; earlier distributions remain immutable. Its BOM reuses immutable PDF, 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.
|
|
56
110
|
|
|
57
111
|
## Docker-First Hybrid Policy
|
|
58
112
|
|
|
59
|
-
### 0.
|
|
113
|
+
### 0.6.0 component selection
|
|
60
114
|
|
|
61
|
-
The
|
|
62
|
-
|
|
63
|
-
generated Bundler state are included. The
|
|
64
|
-
|
|
115
|
+
The coordinated core identity is **0.6.0**: gem, wheel, base runtime and MCP
|
|
116
|
+
images were published together. The installed host launcher and runtime-aware
|
|
117
|
+
generated Bundler state are included. The PDF worker uses its reviewed, signed
|
|
118
|
+
0.6.0 digest, alongside the 0.4.0 computation/capture workers and visual
|
|
65
119
|
companions. A released PDF can be reused only by full digest; new/pending workers
|
|
66
120
|
still require the coordinated version. The historical 0.5.0 receipt remains
|
|
67
|
-
unchanged.
|
|
68
|
-
|
|
69
|
-
|
|
121
|
+
unchanged. Signed image/package evidence is recorded in the 0.6.0 receipt;
|
|
122
|
+
promotion and anonymous-download checks passed before the post-release launcher
|
|
123
|
+
pin was advanced.
|
|
70
124
|
|
|
71
125
|
### Local delivery
|
|
72
126
|
|
|
73
|
-
GHCR is the canonical delivery channel for normal local use. The released package scaffold selects `ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.
|
|
127
|
+
GHCR is the canonical delivery channel for normal local use. The released package scaffold selects `ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.6.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.
|
|
74
128
|
|
|
75
129
|
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.
|
|
76
130
|
|
|
@@ -86,7 +140,7 @@ These remain real package boundaries: the MCP image installs the Python package
|
|
|
86
140
|
|
|
87
141
|
### Installed Docker launcher
|
|
88
142
|
|
|
89
|
-
0.5.1
|
|
143
|
+
0.5.1 ships **`unaltraweb-mcp-docker`** and a complete host launcher
|
|
90
144
|
under the installation prefix's `share/unaltraweb-launcher/`. The published 0.5.0
|
|
91
145
|
wheel predates this addition; its receipt and bytes remain unchanged. An installed
|
|
92
146
|
wheel containing the launcher can use the already-published full GHCR runtime
|
|
@@ -100,7 +154,7 @@ unaltraweb-mcp-docker serve --project /absolute/consumer
|
|
|
100
154
|
```
|
|
101
155
|
|
|
102
156
|
The installed default selects its package's full MCP release image, currently
|
|
103
|
-
`ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.
|
|
157
|
+
`ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.6.0`. It resolves that selection to the
|
|
104
158
|
local immutable image ID before executing. The checkout's `MCP_RELEASE_IMAGE`
|
|
105
159
|
is a separate digest pin advanced only after publication; it is not the installed
|
|
106
160
|
wheel's default. This avoids sending a new package back to an older MCP while
|
|
@@ -132,7 +186,7 @@ the host, register a client, update a consumer scaffold, or change an active MCP
|
|
|
132
186
|
The site Makefile's `MCP_IMAGE`, native Gem/core revision, PDF worker, global MCP
|
|
133
187
|
registration and companion selections are separate parts of an effective tuple.
|
|
134
188
|
TIG/TIGIT retain build defaults 0.4.0; Geodisseny retains 0.5.0. A global MCP
|
|
135
|
-
selection
|
|
189
|
+
selection does not rewrite those defaults. Tests use synthetic sites,
|
|
136
190
|
image-specific test resources and dynamically allocated loopback preview ports.
|
|
137
191
|
|
|
138
192
|
Compatibility evidence is a set of tested tuples, not a continuous version range.
|
|
@@ -245,7 +299,7 @@ For that reason:
|
|
|
245
299
|
|
|
246
300
|
## Docker Runtime
|
|
247
301
|
|
|
248
|
-
Release `0.
|
|
302
|
+
Release `0.6.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`.
|
|
249
303
|
|
|
250
304
|
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.
|
|
251
305
|
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Import A Retained Letter
|
|
3
|
+
description: Verify and retain a Carta letter bundle, display its PDF on the web and include it in a manual.
|
|
4
|
+
lang: en
|
|
5
|
+
ref: retained_documents
|
|
6
|
+
profiles:
|
|
7
|
+
- unaltredocs
|
|
8
|
+
documentation_profiles:
|
|
9
|
+
- local-authors
|
|
10
|
+
- core-developers
|
|
11
|
+
section: Build A Site
|
|
12
|
+
weight: 240
|
|
13
|
+
permalink: /retained-documents/
|
|
14
|
+
nav_title: Retained Documents
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
A retained letter combines its original PDF with the source, rendering inputs and
|
|
18
|
+
provenance needed to inspect its origin. The importer keeps that complete unit in
|
|
19
|
+
the receiving repository and creates a native page or chapter referencing the PDF.
|
|
20
|
+
The website displays the original; a manual PDF includes all its pages.
|
|
21
|
+
|
|
22
|
+
This capability ships in **0.6.0**. It requires a
|
|
23
|
+
containing Python package and Jekyll core, plus the matching PDF worker for manual
|
|
24
|
+
output. The published 0.5.1 runtime predates it. Changing the global MCP selection
|
|
25
|
+
does not update a site's Gemfile, Makefile or PDF-worker selection.
|
|
26
|
+
|
|
27
|
+
Native gem builds need Python with `PyYAML>=6,<7`, `pypdf>=6,<7` and
|
|
28
|
+
`markdown-it-py>=3,<5`. The containing MCP/PDF images provide these dependencies;
|
|
29
|
+
the containing reusable deployment workflow installs the PDF/text parsers when
|
|
30
|
+
retained imports are present.
|
|
31
|
+
|
|
32
|
+
## Supported Input
|
|
33
|
+
|
|
34
|
+
The receiving profile accepts leaf `letter-pdf-v1` bundles from **Carta
|
|
35
|
+
0.3.0rc1**, using the existing artifact handoff v1 envelope. Verification covers
|
|
36
|
+
the supplied sender SHA-256, complete file inventory, retained render recipe,
|
|
37
|
+
templates, source references, drawable resources and renderer identity. PDF
|
|
38
|
+
inspection is bounded and rejects encrypted files, embedded or external files,
|
|
39
|
+
JavaScript and unsupported actions. Internal destinations and textual HTTP,
|
|
40
|
+
HTTPS and email links are supported.
|
|
41
|
+
|
|
42
|
+
Renderable metadata is checked independently of the retained Pandoc AST. A
|
|
43
|
+
resealed bundle with an unretained local link in a subject or author field is
|
|
44
|
+
rejected even when its older parsing evidence does not mention that link.
|
|
45
|
+
|
|
46
|
+
Limits are 64 MiB for the payload unit, 32 MiB for the PDF and 1–64 pages. The
|
|
47
|
+
supported source subset excludes body images, raw markup, TeX, math and citations;
|
|
48
|
+
attachments remain text labels. Composite bundles, edited PDF variants and
|
|
49
|
+
Diapora composition require separate receiving profiles.
|
|
50
|
+
|
|
51
|
+
Obtain the bundle's expected SHA-256 through the sender's trusted handoff. A hash
|
|
52
|
+
computed only from an unknown local manifest establishes consistency, not its
|
|
53
|
+
origin. Importing never executes the retained recipe or contacts the producer.
|
|
54
|
+
|
|
55
|
+
## Import Into A Consumer
|
|
56
|
+
|
|
57
|
+
Start with an initialized consumer Git repository. Place the complete incoming
|
|
58
|
+
bundle under a workspace-relative directory such as `tmp/incoming/letter/`.
|
|
59
|
+
The recovery area under `tmp/` must be ignored and untracked; durable destinations
|
|
60
|
+
must be eligible for version control.
|
|
61
|
+
|
|
62
|
+
Review a plan using the installed CLI. Here `BUNDLE_SHA` is the sender's verified
|
|
63
|
+
manifest digest:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
unaltraweb-mcp --project /absolute/consumer mcp import-artifact-bundle \
|
|
67
|
+
--path tmp/incoming/letter/bundle.json --sha256 "$BUNDLE_SHA" \
|
|
68
|
+
--import-id correspondence --content-path _chapters/en/correspondence.md \
|
|
69
|
+
--title "Retained correspondence"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
To apply the reviewed request, repeat it with `--apply --confirm-import`.
|
|
73
|
+
The MCP equivalent is `import_artifact_bundle` with `dry_run=false` and
|
|
74
|
+
`confirm_import=true`; its default is a read-only plan.
|
|
75
|
+
|
|
76
|
+
Choose a new Markdown destination under `_pages/`, or `_chapters/` for a manual,
|
|
77
|
+
or `_documentation/` for a documentation site. An executable source owning the
|
|
78
|
+
same Markdown basename blocks creation. The generated document starts as a draft
|
|
79
|
+
in the consumer's default language, with a literal local permalink.
|
|
80
|
+
|
|
81
|
+
The resulting paths are:
|
|
82
|
+
|
|
83
|
+
| Path | Purpose |
|
|
84
|
+
| --- | --- |
|
|
85
|
+
| `.unaltraweb/artifacts/correspondence/bundle/` | Complete, unchanged incoming seal, outside the web output |
|
|
86
|
+
| `.unaltraweb/artifacts/correspondence/integration.json` | Standard v1 integration record and byte-preserving PDF mapping |
|
|
87
|
+
| `.unaltraweb/artifacts/correspondence/binding.json` | Native content path and integration-record digest |
|
|
88
|
+
| `assets/documents/correspondence.pdf` | Public PDF, identical to the retained original |
|
|
89
|
+
| `_chapters/en/correspondence.md` | Native chapter with the retained-document component |
|
|
90
|
+
|
|
91
|
+
Version the complete durable unit together. The incoming directory and ignored
|
|
92
|
+
recovery journal are not runtime dependencies. The retained archive is excluded
|
|
93
|
+
from website output, but remains ordinary repository content.
|
|
94
|
+
|
|
95
|
+
## Edit And Render The Native Document
|
|
96
|
+
|
|
97
|
+
Add explanatory prose to the generated page or chapter while preserving its
|
|
98
|
+
literal permalink and component:
|
|
99
|
+
|
|
100
|
+
{% raw %}
|
|
101
|
+
```liquid
|
|
102
|
+
{% retained_document correspondence %}
|
|
103
|
+
```
|
|
104
|
+
{% endraw %}
|
|
105
|
+
|
|
106
|
+
On the web, the component renders a PDF object with a labelled download link.
|
|
107
|
+
The build checks the bound page's exact local PDF URL and the emitted PDF bytes.
|
|
108
|
+
Exposing the retained archive in the website is an error. In a manual, the PDF
|
|
109
|
+
builder includes every original page and fingerprints the entire retained unit
|
|
110
|
+
and its checker implementation. A controller/worker mismatch therefore fails
|
|
111
|
+
freshness verification rather than silently accepting an older checker.
|
|
112
|
+
|
|
113
|
+
Run `artifact_import_check` or the CLI equivalent before building:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
unaltraweb-mcp --project /absolute/consumer mcp artifact-import-check
|
|
117
|
+
unaltraweb-mcp --project /absolute/consumer mcp artifact-import-check --output-folder _site
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`site_check` and `site_doctor` include the native integrity check. For a local
|
|
121
|
+
manual review, use `manual_pdf_preview_prepare`, then `build_site` and
|
|
122
|
+
`preview_start`. Review the web page and composed PDF, then clean only the
|
|
123
|
+
receipt-owned preview copies through `manual_pdf_preview_clean`.
|
|
124
|
+
|
|
125
|
+
## Preservation And Recovery
|
|
126
|
+
|
|
127
|
+
An identical reimport preserves authored prose. A changed mapped PDF, conflicting
|
|
128
|
+
destination, unsafe path or modified seal blocks the operation; existing files
|
|
129
|
+
are never overwritten. After an interrupted import, unchanged partial files may
|
|
130
|
+
be adopted by an explicit retry of the same request. Differing partial files
|
|
131
|
+
require inspection. The operation retains its prepared tree and journal under
|
|
132
|
+
`tmp/unaltraweb-artifact-imports/` and performs no destructive rollback.
|
|
133
|
+
|
|
134
|
+
The native check verifies references and content after the incoming producer copy
|
|
135
|
+
has been removed or the receiving repository has moved. It also detects missing
|
|
136
|
+
content, incomplete retention and altered mappings. The generic v1 verifier can
|
|
137
|
+
independently inspect `integration.json`; it does not replace the native source
|
|
138
|
+
and rendered-output checks.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Inspect And Close A Live MCP Session
|
|
3
|
+
description: Startup identity, exact prepared images and session-scoped resource release.
|
|
4
|
+
lang: en
|
|
5
|
+
ref: live_runtime_identity
|
|
6
|
+
profiles:
|
|
7
|
+
- unaltredocs
|
|
8
|
+
documentation_profiles:
|
|
9
|
+
- local-authors
|
|
10
|
+
- core-developers
|
|
11
|
+
section: Core Development
|
|
12
|
+
weight: 635
|
|
13
|
+
permalink: /live-runtime/
|
|
14
|
+
nav_title: Live Runtime
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
The 0.7.0 runtime increment distinguishes the process serving a connection from
|
|
18
|
+
the installed package, source checkout and rendering workers. Call
|
|
19
|
+
`runtime_identity` or read `web://runtime-identity` through that live MCP
|
|
20
|
+
connection. Both report the same backend instance and startup information.
|
|
21
|
+
|
|
22
|
+
The observation includes the loaded package version, startup code fingerprint,
|
|
23
|
+
current disk fingerprint, interpreter, PID/start information, workspace mapping
|
|
24
|
+
and selected versus observed image identities. A disk edit is reported as drift;
|
|
25
|
+
it does not upgrade an already-running process. Docker-host and container PID
|
|
26
|
+
namespaces are reported separately. Identity checks read engine/runtime metadata,
|
|
27
|
+
not website prose, private records or arbitrary environment variables.
|
|
28
|
+
|
|
29
|
+
## Prepare Explicitly, Then Launch
|
|
30
|
+
|
|
31
|
+
Use `unaltraweb-mcp-docker prepare --image REF` to acquire a selected release.
|
|
32
|
+
Launch, check, smoke and identity observations do not build or pull missing images.
|
|
33
|
+
For a managed launch, supply a full image ID or repository digest, or bind a local
|
|
34
|
+
reference to its independently verified configuration ID:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
unaltraweb-mcp-docker serve --project /absolute/site \
|
|
38
|
+
--image "$PREPARED_REFERENCE" --expected-image-id "$EXPECTED_IMAGE_ID" --managed
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The expected value is Docker's full `sha256:` configuration ID, not the archive
|
|
42
|
+
checksum or OCI index digest. A missing or mismatched selection is an error.
|
|
43
|
+
Execution uses that inspected ID with `--pull never`; existing aliases are not
|
|
44
|
+
rewritten. Add `--offline` for a controller without networking. The declared
|
|
45
|
+
Docker socket remains available for local inspection and prepared workers.
|
|
46
|
+
|
|
47
|
+
The normal host launcher mounts the canonical site path and a `/workspace` alias.
|
|
48
|
+
A launcher itself running in a container must supply its explicit daemon-host
|
|
49
|
+
mapping using `--host-project`. Unsupported direct controller mappings require
|
|
50
|
+
inspection rather than guessing a host path from `/workspace`.
|
|
51
|
+
|
|
52
|
+
## Close One Connection Safely
|
|
53
|
+
|
|
54
|
+
1. Retain the identity's consumer binding, session ID and exact container ID.
|
|
55
|
+
2. Call `runtime_drain(confirm=true)`. The backend stops admitting new operations.
|
|
56
|
+
3. Close that stdio connection. Bounded active work finishes before its idle
|
|
57
|
+
session resources are released.
|
|
58
|
+
4. Use the installed `session-status` command to confirm resource termination.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
unaltraweb-mcp-docker session-status --project /absolute/site \
|
|
62
|
+
--session-id "$SESSION_ID" --container-id "$CONTAINER_ID"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`connected`, `busy`, `orphaned` and `unknown` do not mean resources are free.
|
|
66
|
+
Only `stopped` with `resources_released=true` establishes observed absence.
|
|
67
|
+
After a crash, `reap-session` with the same retained tuple can recover eligible
|
|
68
|
+
idle leftovers. It preserves live backends, active jobs, other sessions, prepared
|
|
69
|
+
images, volumes and authored files. Disk cleanup remains explicit and separate.
|
|
70
|
+
|
|
71
|
+
The older `down` command is workspace-wide, and `mcp-down-all` is factory-wide.
|
|
72
|
+
Use them only for those intended scopes, not as a substitute for closing one
|
|
73
|
+
client. The managed stdio profile has one connection per backend; it does not
|
|
74
|
+
claim shared-HTTP backend reattachment semantics.
|
|
75
|
+
|
|
76
|
+
## Workers And Helpers
|
|
77
|
+
|
|
78
|
+
Worker references are fixed at startup. Managed rendering requires those exact
|
|
79
|
+
images to be prepared; it refuses a fallback pull/build or a conflicting authored
|
|
80
|
+
computation-image choice. The identity reports resource bounds and image
|
|
81
|
+
observations without running a renderer.
|
|
82
|
+
|
|
83
|
+
Visual helpers are separate MCP processes. Their versions and immutable package
|
|
84
|
+
selections describe the accepted rendering closure, not their current live
|
|
85
|
+
instances. The composing controller must obtain each helper's own live identity.
|
|
86
|
+
The selected Diavisuals 0.5.0 still requires its separately tracked D0 identity
|
|
87
|
+
correction before the entire coordinator closure can be marked managed-ready.
|
|
88
|
+
Existing 0.4.0 static provider receipts remain subject to full integrity checks
|
|
89
|
+
and do not force regeneration of authored figures during an upgrade.
|