11 KiB
Pack Wizard Pack Execution Semantics Decision
Status: Accepted
Date: 2026-03-20
Domain Owner: docs/packer
Cross-Domain Impact: docs/studio
Context
The Studio-side Pack Wizard flow is already closed as a shell over packer-owned operations.
On the packer side, the repository also already closed the first-wave summary and validation contracts.
What remained open was the execution contract for the actual pack operation:
- how
packWorkspace(...)should behave when Studio entersPackingandResult; - how the packer should avoid filesystem drift while packing;
- how final artifact visibility should be protected during emission;
- and how the operation should report success, blocking failure, and execution failure without pushing semantic reconstruction into Studio.
The agenda that closed this discussion is:
Relevant upstream references are:
../decisions/Pack Wizard Summary and Validation Contracts Decision.md../specs/1. Domain and Artifact Boundary Specification.md../specs/4. Build Artifacts and Deterministic Packing Specification.md../specs/5. Diagnostics, Operations, and Studio Integration Specification.md../../studio/decisions/Pack Wizard in Assets Workspace Decision.md
Decision
The first-wave packer execution contract for the Pack Wizard adopts the following direction:
packWorkspace(...)is one packer-owned public operation.- It executes through the project-scoped serialized write lane.
- It must rerun a packer-owned gate check before artifact emission begins.
- It must pack from one frozen execution snapshot rather than from live filesystem rereads.
- It must stage emitted outputs before promotion to final
build/locations. - It publishes final build artifacts to
build/only after a coherent success point is reached. - It remains the only first-wave operation that emits build artifacts for the Studio
Pack Wizard.
Adopted Constraints
1. Execution Boundary
packWorkspace(...)evaluates the active pack set asregistered + included in build;- it runs under the same packer-owned project write serialization model already adopted for same-project writes and build operations;
- it must not trust Studio call ordering as if that were a correctness guarantee;
- a failing pack gate returns a terminal result without publishing final build artifacts.
2. Frozen Execution Snapshot
- pack execution must not reread live workspace files once execution materialization begins;
- the packer must create a frozen pack-execution snapshot before payload materialization starts;
- that frozen snapshot is derived from the current runtime snapshot and packer-owned walk/materialization path;
- file content bytes are required only for build-relevant inputs:
- registered assets included in build;
- artifact files that actually participate in the current build output;
- non-build assets and non-selected artifact files do not need in-memory content in the pack-execution snapshot.
3. Runtime Walk Projection Shape
- the existing runtime walk projection model remains the baseline;
PackerRuntimeWalkFilegains optional content bytes instead of introducing a second snapshot model in the first wave;- optional content bytes remain absent in normal runtime-backed projection and become present only in packing-focused projection.
4. Materialization Policy Shape
The adopted first-wave shape is:
public record PackerRuntimeMaterializationConfig(
PackerWalkMode mode,
Predicate<PackerProbeResult> projectionFilter) {
public static PackerRuntimeMaterializationConfig runtimeDefault() {
return new PackerRuntimeMaterializationConfig(PackerWalkMode.RUNTIME, probe -> true);
}
public static PackerRuntimeMaterializationConfig packingBuild() {
return new PackerRuntimeMaterializationConfig(
PackerWalkMode.PACKING,
PackerProbePolicies::isIncludedInCurrentBuild);
}
}
With this contract:
PackerWalkMode.RUNTIMEsuppresses optional content bytes during export to runtime walk projection;PackerWalkMode.PACKINGinjects optional content bytes during export to runtime walk projection;projectionFilterdecides which discovered probe results survive intoPackerRuntimeWalkFile;- the first-wave packing filter keeps only current-build probe results.
5. Walker Boundary
- family walkers remain family-oriented discovery mechanisms;
- they may continue to produce full file probes with bytes available during probe processing;
- the runtime-versus-packing variation happens during export/materialization into runtime walk projection;
- packing-specific selection is one additional projection/materialization policy layer over the discovered probe results;
- first-wave pack execution must not fork the repository into one discovery model for runtime and another discovery model for packing.
6. Staging and Promotion Boundary
- pack execution stages outputs under
build/.staging/<operation-id>/; <operation-id>is one random 20-character alphanumeric identifier;- if a staging directory collision occurs for that identifier, the packer may overwrite that staging directory in the first wave;
- staged outputs are non-authoritative until promotion;
- promotion into final
build/locations happens only after the operation reaches a coherent success point; - if emission fails before promotion, final
build/outputs must remain unchanged from the caller's point of view.
7. Build Publication Boundary
- the canonical runtime-facing output is
build/assets.pa; - the baseline companion outputs are:
build/asset_table.jsonbuild/preload.jsonbuild/asset_table_metadata.json
packWorkspace(...)stops at build artifact publication;- shipper behavior remains outside this operation and is mentioned only as a future consumer boundary.
8. Result and Failure Semantics
The final pack result must distinguish at least:
- validation gate failure before emission;
- execution or materialization failure during pack generation;
- persistence or promotion failure while making outputs final.
The first-wave result summary must expose at least:
- final status;
- whether execution actually began or stopped at gate failure;
- canonical build-relative reference to
assets.pa; - build-relative companion artifact references when emitted;
- total packed asset count;
- elapsed time in milliseconds.
9. Minimum Structural Conformance
The first-wave pack execution is not successful unless the emitted outputs satisfy the already adopted baseline structural guarantees:
asset_tableordering is deterministic by increasingasset_id;- header serialization is canonical;
- offsets are relative to
payload_offset; - preload entries are resolved by
asset_id; - invalid preload references or preload slot clashes fail the operation rather than being deferred to host guesswork.
Why This Direction Was Chosen
- It preserves packer ownership of build semantics while keeping Studio as an honest shell.
- It prevents filesystem drift during execution without turning the general runtime snapshot into a wasteful full-memory mirror.
- It aligns build visibility with the same commit-oriented operational model already adopted elsewhere in the packer runtime.
- It keeps the first-wave implementation on known terrain by reusing current walker/materialization structure instead of inventing a second discovery stack.
- It gives the Studio enough structured outcome information to render
PackingandResultwithout semantic reconstruction.
Explicit Non-Decisions
This decision does not yet define:
- the format-specific payload materialization rules for each asset output format;
- the canonical payload contract for
tile bank,sound bank, or other family-specific outputs; - the final event kind vocabulary for pack execution progress beyond requiring causality-preserving observable lifecycle;
- cancellation semantics;
- future incremental or remote build behavior;
- shipper packaging rules, cartridge manifest generation, or final packaged cartridge layout.
Implications
packWorkspace(...)can no longer be implemented as a direct live-filesystem read/write shortcut;- runtime walk projection and materialization code must gain explicit packing-aware export policy;
PackerRuntimeWalkFilemust support optional content bytes;- pack execution implementation must include frozen-input creation, staging, promotion, and structured terminal outcomes;
- format-specific packing discussions must now happen as follow-up decisions rather than being guessed inside the generic execution path.
Propagation Targets
Specs:
../specs/4. Build Artifacts and Deterministic Packing Specification.md../specs/5. Diagnostics, Operations, and Studio Integration Specification.md
Plans:
../pull-requests/PR-28-pack-wizard-public-contracts-summary-validation-and-execution.md../pull-requests/PR-29-pack-wizard-contract-adjustments-for-summary-and-validation.md- future packer PR for pack execution, staging, and result semantics
Cross-domain references:
../../studio/decisions/Pack Wizard in Assets Workspace Decision.md../../studio/pull-requests/PR-11-pack-wizard-shell-and-packer-contract-consumption.md
Follow-up agenda references:
Implementation surfaces:
prometeu-packer-apipack execution result contractprometeu-packer-v1runtime materialization/export policyprometeu-packer-v1frozen execution snapshot creationprometeu-packer-v1staging and promote pipeline- Studio
Pack Wizardpacking/result bindings
Validation Notes
This decision is correctly implemented only when all of the following are true:
packWorkspace(...)does not depend on live filesystem rereads after frozen execution materialization begins;- only build-relevant selected inputs carry frozen content bytes into the packing path;
- normal runtime-backed reads do not retain optional content bytes by default;
- failed execution before promotion does not leave partial final
build/artifacts presented as success; - successful pack publication produces
build/assets.paand the expected companion outputs coherently; - Studio can distinguish blocked, failed, and successful pack outcomes from packer-owned results alone.