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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: be599804b31390cca31133227e0e15f4ba623339a1072a441c74960b79c039fa
4
- data.tar.gz: d70f999b0d814f6a579dbb06534c611034792a1cd29972b3015ecce5e21522a4
3
+ metadata.gz: 33193d7900939e3cf2e4e9769e8fd9443e0a7242eaa73aef1d93b8ffcee6e79b
4
+ data.tar.gz: 3ef63e4f55c4b369e0926be413eb2da4d3702f49ac733d84dedc952bb1ec563c
5
5
  SHA512:
6
- metadata.gz: cb11d05e8660d167d311c7a9e1d03f895918d02c754e7189f52b25f1403f0056731aa94f77116b11cf30049c9d54b1ca6ffcae312c08d3127f942c756a1ed222
7
- data.tar.gz: c7c798ce0e589fbd2fdaddfa9c4d632afd043ccfca6ecd65c780dfcae33932f6314da270968c665dfcdbac080f48e67022c66344b45961c8b87c1cfe0704ff9a
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.1
5
- MCP_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb-mcp:0.5.1
6
- MCP_RELEASE_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb-mcp@sha256:36d17edbade77edb40a687f6a744203c6329acb33fbc2eb255e88d9ff1a42c98
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.5.1
44
- MANUAL_PDF_IMAGE ?= ghcr.io/dosquartsdedocs/unaltraweb-manual-pdf@sha256:9e0b3a45753c170b795e9a9d6df61580085c113436beac5bf6c8de69b6562097
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)" scripts/manual
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
- ### Published 0.5.0 release
29
-
30
- The coordinated core release is [**0.5.0**](https://github.com/dosquartsdedocs/unaltraweb/releases/tag/v0.5.0). It groups the integrated editorial
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 selects the MCP digest recorded in receipt
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, 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`.
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.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.
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 preparation
98
+ ### 0.5.1 component selection
60
99
 
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
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. 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.
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.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.
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 source adds **`unaltraweb-mcp-docker`** and a complete host launcher
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 of 0.5.0 does not rewrite those defaults. Tests use synthetic sites,
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.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`.
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.
@@ -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
- Next-release wheels also install this native descriptor and its complete host
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.