Upgrade to 1.2.1: distinguish libraries from private caches
The patch matches document, provenance and asset directives for reuse; equal empty documents can contain different assets. SOPacks are validated before referenced-unit selection, while unused local XML remains strictly checked. Public namespace, manifests and CLI flags are unchanged.
Repeated text shares content; multi-fragment concatenation still materializes visible text when needed. Provenance, logical byte budgets and diagnostic ordering stay independent. XML and string arguments need no rewrite.
Failure diagnostics retain the actual source record and call chain, not a guessed header or provider location; existing error codes remain.
Catalog preparation does not reopen derived CAS outputs merely for that step, but still verifies published files. Warm SOPack proof reuse matches the frozen encoding digest and size; this is not a zero-I/O warm-build promise.
Canonical schema-1 readers accept existing v1.2.0 SOPacks; rewriting a single relocated archive retains its _providers names and normalized bytes. Input archives and SHA-256 pins remain immutable. Fresh provider fingerprints can evolve between producer versions, so cross-version rebuilds are not byte-identity guaranteed; existing dependencies are not rewritten.
Private cache/action-recipe identities can evolve and trigger rebuilding; do not edit hashes, SQLite records or internal paths. Use the existing clean command only if cleanup is needed, and retain inputs for offline rebuilds. The measured checkpoint passed hosted contracts, Site and mechanisms; the exact release commit subsequently passed main and six-platform release gates. Version 1.2.1 is published; scoped results do not mean every workload is faster.
Pack: deliver entries and assets together
Collects compiled entry products and complete asset bytes into a reproducible ZIP .pack.
<xs:pack xmlns:xs="https://xmlsquish.moesegfault.dev/ns">
<xs:include path="instructions.xml" name="instructions.prompt"/>
<xs:asset path="scripts/check.py" name="scripts/check.py"/>
</xs:pack>include accepts entries, never modules. asset preserves complete bytes without XML parsing or whitespace processing. name is optional: assets retain their relative path; includes use the source stem plus .prompt.
SOPack: a library, not a cache or final product
Preserves IR, compiled modules, macros, assets and metadata, without final products.
<xs:sopack xmlns:xs="https://xmlsquish.moesegfault.dev/ns">
<xs:import src="macros.xml"/>
<xs:asset path="schema.json"/>
</xs:sopack>
# xmlsquish.toml
[dependencies]
common = { sopack = "vendor/common.sopack" }
[target.library]
entry = "src/library.xml"
backend = "sopack"
output = "library.sopack"xmlsquish add common --path vendor/common.sopack
xmlsquish remove common --dry-runSOPack forbids include, even inside macros. Macros can expand assets, but asset paths belong to the definition. Relocated identities preserve correct bytes across devices. Treat the dependency as immutable; do not edit an archive under an existing lock pin.
Enable telemetry and tracing when needed
Tracing is off by default, with no default recording or outbound transmission. summary records command/stage spans; events adds lifecycle events and diagnostics. Explicit off overrides the environment.
xmlsquish --trace=summary build
xmlsquish --trace=events build
xmlsquish --trace=off build
# XMLSQUISH_TRACE=summary or events; bare --trace means eventsRecords persist at <target-dir>/metadata/traces/<invocation>.jsonl using xmlsquish.trace.v1. Events can expose paths and diagnostics; review before sharing. A trace I/O failure emits TRACE001 without changing the operation result. Records are not product content. Old derived caches may be invalidated on upgrade, while all caches remain project-owned.
Build pipeline
Lower DSL to IR, optimize compile-time work, link referenced units, then distribute prompt, pack or SOPack products.
- 01front endDSL → IR
- 02middle endevaluate + optimize
- 03linkeraggregate + optimize
- 04backendprompt · pack · sopack
The project owns the complete build root
The default target-dir is target/xmlsquish. Products, rebuild caches, and compiler metadata move together; cache/ and metadata/ are tool-managed, so their hashes, database, and journals are not APIs.
target/xmlsquish/
├── artifacts/ # *.prompt, *.pack, *.sopack, optional IR/debug outputs
├── cache/
│ ├── sources/ # locked dependency material
│ ├── cas/ # content-addressed build objects
│ └── actions.sqlite3 # rebuildable action index
├── metadata/
│ ├── layout.json # private layout schema
│ ├── publications/ # publication + recovery records
│ └── catalog/ # compiler/build catalog
└── work/ # disposable stagingxmlsquish clean removes the complete configured target-dir; the next build reconstructs it from sources, the manifest, and lockfile. An offline build succeeds only while cache/sources still contains every required dependency.
What each artifact is for
Product backends emit .prompt, .pack or .sopack, plus optional .xsir intermediate representation and .psdbg provenance/debug evidence.
.promptThe final consumable product.
.packCollects compiled entry products and complete asset bytes into a reproducible ZIP .pack.
.sopackPreserves IR, compiled modules, macros, assets and metadata, without final products.
.xsirCanonical binary intermediate representation.
.psdbgProvenance and debug mapping.
Why XSD is not enough
Import closure, QName symbols, call contracts, recursion budgets, and publication transactions are cross-file rules validated by the manager.