unaltraweb 0.5.1 → 0.6.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 +6 -6
- data/_plugins/retained_documents.rb +62 -0
- data/docs/_documentation/en/40-distribution.md +55 -16
- data/docs/_documentation/en/45-retained-documents.md +138 -0
- data/docs/agents/mcp-contract.md +36 -1
- data/docs/agents/owner-closeout-76.md +205 -0
- data/docs/agents/retained-letter-import.md +231 -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 +5 -0
- data/scripts/unaltraweb-mcp-bootstrap.sh +1 -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 +20 -20
- 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 +13 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 33193d7900939e3cf2e4e9769e8fd9443e0a7242eaa73aef1d93b8ffcee6e79b
|
|
4
|
+
data.tar.gz: 3ef63e4f55c4b369e0926be413eb2da4d3702f49ac733d84dedc952bb1ec563c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eb799646f841a4444d315aa4a71d161ec83acacbef75f36fe00b8db7242699be40147c2829bedee18f249f3085b51328cd18a902f317196d518b4f2b8e11a9f2
|
|
7
|
+
data.tar.gz: cfe5a103146718d7bbae56c9821b2dabdc0fdf1bcde966779ee41ea96c468bd795446202844a56a0974919ce4bca33e2d90e5c6de98e8e95936b1335c44dca86
|
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.6.0
|
|
5
|
+
MCP_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.6.0
|
|
6
|
+
MCP_RELEASE_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb-mcp@sha256:908b4ce54c7bdf355e14ed55b31ed4b9baae319e211af90004a680d1d1cb8692
|
|
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.6.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 ?=
|
|
@@ -375,7 +375,7 @@ manual-pdf-image: ## Ensure the selected versioned Pandoc/XeLaTeX image is prese
|
|
|
375
375
|
@docker image inspect "$(MANUAL_PDF_IMAGE)" >/dev/null 2>&1 || docker pull "$(MANUAL_PDF_IMAGE)"
|
|
376
376
|
|
|
377
377
|
manual-pdf-image-dev: ## Build the explicitly named maintainer PDF development image
|
|
378
|
-
docker build -f scripts/manual/Dockerfile -t "$(MANUAL_PDF_DEV_IMAGE)"
|
|
378
|
+
docker build -f scripts/manual/Dockerfile -t "$(MANUAL_PDF_DEV_IMAGE)" .
|
|
379
379
|
|
|
380
380
|
define run_manual_pdf_worker
|
|
381
381
|
@set -e; set --; cidfile=""; \
|
|
@@ -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,48 @@ 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
|
+
### Pending 0.6.0 retained-letter increment
|
|
29
|
+
|
|
30
|
+
The source branch prepares a separate 0.6.0 identity for native
|
|
31
|
+
[retained-letter import]({{ '/retained-documents/' | relative_url }}).
|
|
32
|
+
Gem, wheel, base runtime and MCP are authorized as `ready` for final same-source
|
|
33
|
+
candidates. The consumer core selects reviewed integration
|
|
34
|
+
`5cf9817489c8dc47cee726bfe42fe3071cd32b85`; the PDF 0.6.0 worker is already
|
|
35
|
+
published, signed and tested at immutable digest
|
|
36
|
+
`sha256:0ba267cb87f53ebaca4e31805fe00610cd61fdf97a8d2c3692f4655700dceaed`.
|
|
37
|
+
The PDF worker changes to include complete retained documents and the same
|
|
38
|
+
integrity checkers used by its controller. Computation, capture and visual
|
|
39
|
+
companions retain their tested 0.4.0 selections.
|
|
40
|
+
|
|
41
|
+
The checkout's active launcher remains pinned to the published 0.5.1 MCP digest.
|
|
42
|
+
Its receipt and package bytes remain unchanged. Local development images and an
|
|
43
|
+
installed wheel exercise the new import without claiming a public 0.6.0 release
|
|
44
|
+
or changing real consumer sites. The
|
|
45
|
+
[owner acceptance record](https://github.com/dosquartsdedocs/unaltraweb/blob/main/docs/agents/retained-letter-import.md)
|
|
46
|
+
records the authenticated Carta packet, receiver mapping and relocation proof.
|
|
47
|
+
|
|
48
|
+
### Published 0.5.1 release
|
|
49
|
+
|
|
50
|
+
[**0.5.1**](https://github.com/dosquartsdedocs/unaltraweb/releases/tag/v0.5.1)
|
|
51
|
+
delivers the installed Docker launcher and runtime-specific generated Bundler
|
|
52
|
+
state. Source `aab5a7b030cd711b40770a3f44ad3a356eab90da` produced the signed
|
|
53
|
+
images and verified gem/wheel. Receipt/tag commit
|
|
54
|
+
`e842c733c8a274279dd5efdc3618e20669f29037` changes only the receipt from that
|
|
55
|
+
first parent. Strict release/publication gates passed before promotion, and
|
|
56
|
+
anonymous registry downloads match the receipt. The checkout launcher now selects
|
|
57
|
+
`ghcr.io/dosquartsdedocs/unaltraweb-mcp@sha256:908b4ce54c7bdf355e14ed55b31ed4b9baae319e211af90004a680d1d1cb8692`.
|
|
58
|
+
|
|
59
|
+
The four-profile populated-cache roundtrip also passed against the actual signed
|
|
60
|
+
candidate. The selected PDF stays at its published 0.5.0 digest, and computation,
|
|
61
|
+
capture and visual companions retain 0.4.0. See the
|
|
62
|
+
[delivery report](https://github.com/dosquartsdedocs/unaltraweb/blob/main/docs/agents/owner-closeout-76.md)
|
|
63
|
+
and [issue 76](https://github.com/dosquartsdedocs/unaltraweb/issues/76).
|
|
64
|
+
Strict release validation applies to the receipt/tag revision; subsequent
|
|
65
|
+
post-release launcher changes are ordinary source revisions, not new receipts.
|
|
66
|
+
|
|
67
|
+
### Previous 0.5.0 release
|
|
68
|
+
|
|
69
|
+
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
70
|
review, guided scaffold updates, caption-credit/image behavior and published
|
|
32
71
|
Diavisuals/Vegavisuals 0.4.0 acceptance. Source-bound image/package workflows,
|
|
33
72
|
tag promotion and both Trusted Publishing jobs passed. Anonymous package downloads
|
|
@@ -42,7 +81,7 @@ at source `d857f8c9f5fea90cf450c0b30b4e77a37b541275` and is selected by digest
|
|
|
42
81
|
`sha256:9e0b3a45753c170b795e9a9d6df61580085c113436beac5bf6c8de69b6562097` in
|
|
43
82
|
both the factory and the consumer tuple. It is already published and tested, so
|
|
44
83
|
final candidate receipts cover the remaining ready package/core components.
|
|
45
|
-
The post-release factory launcher
|
|
84
|
+
The 0.5.0 post-release factory launcher selected the MCP digest recorded in receipt
|
|
46
85
|
`3fa855378dcc61dc7b84b8b03812698042e02fed`:
|
|
47
86
|
`sha256:36d17edbade77edb40a687f6a744203c6329acb33fbc2eb255e88d9ff1a42c98`.
|
|
48
87
|
See [issue 69](https://github.com/dosquartsdedocs/unaltraweb/issues/69) for the
|
|
@@ -50,27 +89,27 @@ candidate, receipt, tag and package evidence.
|
|
|
50
89
|
|
|
51
90
|
`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
91
|
|
|
53
|
-
The BOM is an interoperability contract, not a bundle. The wheel contains its Python control/inspection modules, schema/BOM,
|
|
92
|
+
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
93
|
|
|
55
|
-
The selected public core release is `0.5.
|
|
94
|
+
The selected public core release is `0.5.1`; 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
95
|
|
|
57
96
|
## Docker-First Hybrid Policy
|
|
58
97
|
|
|
59
|
-
### 0.5.1
|
|
98
|
+
### 0.5.1 component selection
|
|
60
99
|
|
|
61
|
-
The
|
|
62
|
-
|
|
100
|
+
The coordinated core identity is **0.5.1**: gem, wheel, base runtime and MCP
|
|
101
|
+
images were published together. The installed host launcher and runtime-aware
|
|
63
102
|
generated Bundler state are included. The unchanged PDF worker retains its
|
|
64
103
|
published 0.5.0 digest, alongside the 0.4.0 computation/capture workers and visual
|
|
65
104
|
companions. A released PDF can be reused only by full digest; new/pending workers
|
|
66
105
|
still require the coordinated version. The historical 0.5.0 receipt remains
|
|
67
|
-
unchanged.
|
|
68
|
-
|
|
69
|
-
|
|
106
|
+
unchanged. Signed image/package evidence is recorded in the 0.5.1 receipt;
|
|
107
|
+
promotion and anonymous-download checks passed before the post-release launcher
|
|
108
|
+
pin was advanced.
|
|
70
109
|
|
|
71
110
|
### Local delivery
|
|
72
111
|
|
|
73
|
-
GHCR is the canonical delivery channel for normal local use. The released package scaffold selects `ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.5.
|
|
112
|
+
GHCR is the canonical delivery channel for normal local use. The released package scaffold selects `ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.5.1`; 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
113
|
|
|
75
114
|
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
115
|
|
|
@@ -86,7 +125,7 @@ These remain real package boundaries: the MCP image installs the Python package
|
|
|
86
125
|
|
|
87
126
|
### Installed Docker launcher
|
|
88
127
|
|
|
89
|
-
0.5.1
|
|
128
|
+
0.5.1 ships **`unaltraweb-mcp-docker`** and a complete host launcher
|
|
90
129
|
under the installation prefix's `share/unaltraweb-launcher/`. The published 0.5.0
|
|
91
130
|
wheel predates this addition; its receipt and bytes remain unchanged. An installed
|
|
92
131
|
wheel containing the launcher can use the already-published full GHCR runtime
|
|
@@ -132,7 +171,7 @@ the host, register a client, update a consumer scaffold, or change an active MCP
|
|
|
132
171
|
The site Makefile's `MCP_IMAGE`, native Gem/core revision, PDF worker, global MCP
|
|
133
172
|
registration and companion selections are separate parts of an effective tuple.
|
|
134
173
|
TIG/TIGIT retain build defaults 0.4.0; Geodisseny retains 0.5.0. A global MCP
|
|
135
|
-
selection
|
|
174
|
+
selection does not rewrite those defaults. Tests use synthetic sites,
|
|
136
175
|
image-specific test resources and dynamically allocated loopback preview ports.
|
|
137
176
|
|
|
138
177
|
Compatibility evidence is a set of tested tuples, not a continuous version range.
|
|
@@ -245,7 +284,7 @@ For that reason:
|
|
|
245
284
|
|
|
246
285
|
## Docker Runtime
|
|
247
286
|
|
|
248
|
-
Release `0.5.
|
|
287
|
+
Release `0.5.1` 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
288
|
|
|
250
289
|
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
290
|
|
|
@@ -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 belongs to the **0.6.0 development increment**. 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.
|
data/docs/agents/mcp-contract.md
CHANGED
|
@@ -16,7 +16,7 @@ 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
|
-
|
|
19
|
+
Released 0.5.1 wheels also install this native descriptor and its complete host
|
|
20
20
|
helper closure under `share/unaltraweb-launcher`. For that installed profile,
|
|
21
21
|
`${factoryRoot}` is the path returned by `unaltraweb-mcp-docker path`, rather than
|
|
22
22
|
a core checkout. Its small Makefile implements `mcp-build`, `mcp-check`,
|
|
@@ -32,6 +32,11 @@ it to an image ID before execution. The source checkout's digest pin is separate
|
|
|
32
32
|
it advances only after a new receipt exists. Explicit `--image` (or the console
|
|
33
33
|
adapter's `UNALTRAWEB_MCP_IMAGE`) permits a reviewed immutable selection.
|
|
34
34
|
|
|
35
|
+
The post-release checkout pin selects published 0.5.1 MCP digest
|
|
36
|
+
`sha256:908b4ce54c7bdf355e14ed55b31ed4b9baae319e211af90004a680d1d1cb8692`.
|
|
37
|
+
Existing processes keep their running image until clients reconnect. Site build
|
|
38
|
+
defaults and customized Makefiles remain separate, explicitly reviewed selections.
|
|
39
|
+
|
|
35
40
|
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.
|
|
36
41
|
|
|
37
42
|
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.
|
|
@@ -97,6 +102,7 @@ baseline format nor runtime cleanup changes.
|
|
|
97
102
|
| `web://manual-authoring-components` | Supported prose structures and component syntax, including callouts, definition lists, figure layouts, tables, diagrams, citations, and web/PDF compatibility. |
|
|
98
103
|
| `web://manual-computations` | Executable manual sources, selected runtime images, generated outputs, and freshness state. |
|
|
99
104
|
| `web://web-captures` | Selector-based screenshot recipes, original PNGs, editable SVG layers, edited overrides, and freshness. |
|
|
105
|
+
| `web://artifact-imports` | Native retained-letter bindings, complete seal/mapping integrity and source references; read-only. |
|
|
100
106
|
| `web://new-web-scaffolds` | Package-owned scaffold availability and contract paths for every supported site profile. |
|
|
101
107
|
|
|
102
108
|
## Tools
|
|
@@ -111,6 +117,8 @@ baseline format nor runtime cleanup changes.
|
|
|
111
117
|
| `site_context` | Read the main local state plus `update_status`: current/target package versions, planned paths, preserved customizations, conflicts and a reviewed-plan digest. |
|
|
112
118
|
| `site_doctor` | Combine distribution doctor with strict project config, identity/language, generated Make contract, scaffold drift, required generated-output/receipt status, existing HTML audit, companion actions, and core override inventory. Unknown required status is blocking. Read-only and offline. |
|
|
113
119
|
| `site_check` | Run profile, publication-copy source diagnostics, freshness, companion visualization/diagram receipt, bibliography, bibliometrics, and build-state checks without network. |
|
|
120
|
+
| `import_artifact_bundle` | Plan or explicitly apply a create-only Carta 0.3.0rc1 `letter-pdf-v1` import with the sender SHA-256, complete retained seal, standard v1 integration record and native content binding. Defaults to dry-run; apply requires `confirm_import=true`. |
|
|
121
|
+
| `artifact_import_check` | Verify retained domains, mappings and native source references; optional `output_folder` checks the bound rendered page and exact emitted PDF bytes. |
|
|
114
122
|
| `site_source_read` | Read one allowed UTF-8 site source and return its exact SHA-256. |
|
|
115
123
|
| `site_source_write` | Dry-run or atomically create/update one allowed source. Creates require `create_only`; updates require the exact SHA-256 returned by a read. |
|
|
116
124
|
| `site_source_delete` | Dry-run or delete one allowed source with exact SHA-256 and explicit confirmation. It never deletes `_config.yml` or directories. |
|
|
@@ -172,6 +180,33 @@ Manual PDF publication is a local workspace operation: it copies reviewed artefa
|
|
|
172
180
|
|
|
173
181
|
## New Site Initialization
|
|
174
182
|
|
|
183
|
+
### Retained Letter Integration
|
|
184
|
+
|
|
185
|
+
The 0.6.0 development increment adds package-only import/check commands and the
|
|
186
|
+
`web://artifact-imports` resource. Web rendering needs its containing Jekyll core;
|
|
187
|
+
manual inclusion also needs the matching PDF worker. Published 0.5.1 components
|
|
188
|
+
do not acquire this capability from a launcher-pin change.
|
|
189
|
+
|
|
190
|
+
The complete seal lives at `.unaltraweb/artifacts/<id>/bundle/`, alongside an
|
|
191
|
+
unchanged-schema v1 integration record and a separate native `binding.json`.
|
|
192
|
+
Only the byte-identical mapped PDF under `assets/documents/` is public. A new
|
|
193
|
+
draft page/chapter binds it using the `retained_document` Liquid tag and a literal
|
|
194
|
+
permalink. `site_check`, `site_doctor`, Jekyll and manual PDF preparation verify
|
|
195
|
+
the corresponding domain, seal, mapping and native reference; the PDF fingerprint
|
|
196
|
+
includes every retained dependency and checker. Producer sources are never run.
|
|
197
|
+
|
|
198
|
+
Writes require the consumer Git root, ignored/untracked recovery staging and
|
|
199
|
+
non-ignored durable paths. They are descriptor-relative and create-only, with
|
|
200
|
+
preflight and final integrity checks. The project/import locks coordinate with
|
|
201
|
+
native readers and the PDF controller. An interrupted operation retains its
|
|
202
|
+
prepared tree and partial files, without destructive rollback. An explicit retry
|
|
203
|
+
may adopt identical bytes; conflicts preserve existing content. Successful
|
|
204
|
+
identical reimport preserves authored prose. See the
|
|
205
|
+
[author reference](../_documentation/en/45-retained-documents.md) and
|
|
206
|
+
[owner acceptance record](retained-letter-import.md) for bounds and evidence.
|
|
207
|
+
|
|
208
|
+
### Package-Owned Initialization
|
|
209
|
+
|
|
175
210
|
`new_web` is intended for empty or nearly-empty website repositories. It creates common runtime files, profile-specific configuration, localized home pages, the content paths required by the selected profile, and `.unaltraweb/scaffold.json`. All scaffold assets are shipped inside the `unaltraweb_mcp` Python package and MCP Docker image; environment variables, sibling checkouts, and arbitrary template paths are not consulted.
|
|
176
211
|
|
|
177
212
|
The `unaltremanual` scaffold also creates `context/writing-profile.md` with a usable default editorial policy and `.unaltraweb/computations.yml` with both BOM-selected workers, `_chapters` and `assets/quarto` source roots, and a generated-asset root. Customize the writing profile for the manual's audience, voice, terminology, evidence policy, language workflow, and review requirements. Computation configuration is consumer-owned rather than scaffold-managed so a project can add lockfiles, dependency paths, or extension Dockerfiles without creating scaffold-sync conflicts. PDF generation and Vega manifests remain opt-in project configuration.
|