prometeu-studio/docs/packer/agendas/Pack Wizard Studio Decision Propagation Agenda.md
2026-03-24 13:42:55 +00:00

14 KiB

Pack Wizard Studio Decision Propagation Agenda

Status: Open Domain Owner: docs/packer Cross-Domain Impact: docs/studio

Purpose

Converge the packer-side discussion that still remains open after the first Pack Wizard propagation wave: the actual packing operation.

summary and validation are already closed enough to implement and consume. What is still unresolved is how pack execution should behave as a packer-owned operation when Studio enters the Packing and Result phases.

This agenda is therefore about execution semantics, artifact emission, progress visibility, and failure boundaries for packWorkspace(...).

Problem

The repository already closed the Studio shell boundary and the packer-side preflight boundary, but the actual pack execution contract is still underspecified.

Today the gap is concrete:

  1. Studio already depends on a four-phase wizard: Summary, Validation, Packing, Result;
  2. the public packer API already exposes packWorkspace(...);
  3. prometeu-packer-v1 still throws UnsupportedOperationException for that operation;
  4. the specs define assets.pa authority and deterministic ordering, but they do not yet define the operational semantics for emitting that artifact through the Studio-facing service boundary.

Without this agenda, implementation risks falling into one of these traps:

  • a direct file-write implementation that leaks partial artifacts;
  • a Studio-visible progress model that is too vague to support the wizard honestly;
  • an execution path that does not clearly separate validation failure from emission failure;
  • or a result contract that is too poor for the Result phase even if the pack technically succeeds.

Context

The upstream state is now clear enough to isolate the remaining question.

Already closed:

Current code context:

  • getPackWorkspaceSummary(...) already exists in FileSystemPackerWorkspaceService;
  • validatePackWorkspace(...) already exists in FileSystemPackerWorkspaceService;
  • packWorkspace(...) exists in the public API but is not implemented in prometeu-packer-v1;
  • the current PackWorkspaceResult shape is minimal, but the operational meaning of its fields is not fully closed.

That means the current decision gap is no longer about whether packing should exist. It is about what guarantees packWorkspace(...) must provide when it starts emitting runtime-facing artifacts.

Options

Option A - Direct in-place pack with minimal lifecycle semantics

Implement packWorkspace(...) as one serialized write-lane operation that:

  • optionally reruns the validation gate;
  • emits assets.pa and companion artifacts directly into their final locations;
  • publishes a small number of lifecycle events;
  • returns one final result DTO with success or failure.

Option B - Staged pack transaction with explicit lifecycle phases

Implement packWorkspace(...) as one serialized packer-owned execution flow with explicit internal phases:

  1. gate
  2. plan/materialize
  3. stage emit
  4. commit/promote
  5. finalize result

The operation still appears to Studio as one packWorkspace(...) call, but the packer gives stronger semantics:

  • validation is rechecked at execution start;
  • emitted files are staged before final promotion;
  • final artifact visibility changes only at commit;
  • progress events map to meaningful lifecycle boundaries;
  • the final result distinguishes validation, emission, and persistence failure classes.

Option C - Detached build session abstraction

Introduce a larger PackSession-style model or resumable build-session protocol for packing.

Studio would create a session, observe step state, and then explicitly finalize or close it.

Tradeoffs

  • Option A is the smallest implementation step, but it leaves too many failure and visibility rules implicit.
  • Option A also makes it easier to leak partially written artifacts into final paths if the process fails mid-pack.
  • Option B fits the existing service boundary while still making artifact visibility and progress semantics explicit.
  • Option B also aligns well with the current specs: serialized writes, causal events, deterministic outputs, and packer-owned truth.
  • Option B adds some implementation structure, but that structure corresponds to real operational risk and is not ceremonial.
  • Option C could become attractive later if the build system needs cancellation, resume, remote workers, or richer host orchestration.
  • Option C is too heavy for the current repository state and would introduce a second interaction model before the first one is stable.

Recommendation

Adopt Option B.

The packer should keep packWorkspace(...) as a single public service operation, but internally define and honor explicit execution phases with staged emission and an atomic final visibility boundary.

Execution Boundary Recommendation

packWorkspace(...) should be the only first-wave operation that emits build artifacts.

Rules:

  • it runs through the packer-owned serialized write lane for the project;
  • it evaluates the active pack set as registered + included in build;
  • it must perform an internal gate check before emitting artifacts, even if Studio already ran validation;
  • it must freeze the execution input set before materialization begins;
  • a failing gate returns a terminal result without creating final artifacts.

This avoids trusting host orchestration timing as if it were a correctness guarantee.

Frozen Snapshot Recommendation

packWorkspace(...) should not pack from live filesystem rereads after execution begins.

Recommended first-wave baseline:

  • the packer creates a frozen pack-execution snapshot before materialization starts;
  • that frozen snapshot is derived from the current runtime snapshot but enriches build-relevant walk files with in-memory content bytes;
  • content bytes are needed only for:
    • 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;
  • the current runtime snapshot model should expose file bytes as optional rather than introducing a second snapshot model in the first wave;
  • PackerRuntimeWalkFile should therefore carry optional content bytes so the packer can freeze build-relevant inputs without forcing all runtime-backed reads to retain content unnecessarily;
  • the family walkers may continue to produce full file probes with bytes loaded during probe processing;
  • the variation for runtime versus packing should happen when probe results are exported into the runtime walk projection;
  • walker materialization must therefore gain clearer execution context/config so build-focused flows can request content bytes intentionally instead of coupling that behavior to every normal read path.

This preserves precision without turning the general runtime snapshot into a blanket in-memory mirror of the workspace.

Walker Policy Recommendation

The current walker baseline should remain family-oriented and generalist.

Recommended first-wave baseline:

  • family walkers continue to discover files relevant to the asset family;
  • that family-oriented discovery remains the normal runtime-backed mode;
  • packing adds one extra selection layer instead of redefining walker discovery itself;
  • the extra selection layer filters the discovered probe results down to the files that actually participate in the current build output;
  • the same export layer also decides whether optional content bytes are injected into PackerRuntimeWalkFile.

This means the first-wave split should be:

  1. family-relevant probe discovery in the walkers;
  2. export/materialization policy for runtime projection;
  3. packing-specific projection filter over discovered probe results;
  4. optional byte injection only when the export policy requests it.

This is intentionally conservative. It keeps the walkers on known ground and moves the packing-specific behavior into one explicit projection/materialization policy layer.

Recommended config shape:

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 baseline:

  • PackerWalkMode.RUNTIME means runtime-backed general projection and suppresses optional content bytes during export;
  • PackerWalkMode.PACKING means packing-focused projection and injects optional content bytes during export;
  • projectionFilter decides which discovered probe results actually survive into PackerRuntimeWalkFile;
  • the first-wave packing filter should keep only current-build probe results;
  • byte injection behavior is derived from mode rather than from a second explicit boolean in the first wave.

Emission Recommendation

Artifact emission should be staged before promotion into final visible locations.

Recommended first-wave baseline:

  • materialize assets.pa and companion artifacts in a staging location owned by the packer operation;
  • use build/.staging/<operation-id>/ as the first-wave staging location;
  • <operation-id> should be one random 20-character alphanumeric identifier;
  • if a staging directory collision happens for that identifier, the packer may overwrite that staging directory rather than adding a second collision-resolution protocol in the first wave;
  • treat staging output as non-authoritative until commit;
  • promote staged files into final build/ locations only after the operation reaches a coherent success point;
  • if emission fails before commit, final artifact locations must remain unchanged from the caller's point of view.

This is the safest baseline for a filesystem-first packer. It keeps durable visibility aligned with a packer-owned commit boundary rather than with incidental file-write timing.

Progress Recommendation

Progress should continue to flow through the existing packer event path rather than through a polling-specific result shape.

The first-wave lifecycle should be observable through summaries and progress updates equivalent to:

  1. packing_started
  2. packing_validating
  3. packing_materializing
  4. packing_emitting
  5. packing_finalizing
  6. terminal success or failure

The exact event kind names can still be finalized in the decision, but the meaning must be explicit enough for Studio to render the Packing phase honestly without fake timers or inferred state.

Result Recommendation

The final PackWorkspaceResult should stay compact but semantically explicit.

The primary result summary should expose at least:

  • final status;
  • whether validation failed or execution actually began;
  • canonical build-relative assets.pa artifact reference;
  • build-relative companion artifact references when emitted;
  • total packed asset count;
  • elapsed time in milliseconds.

The first-wave Result phase in Studio does not need a full build report dump, but it does need enough structure to distinguish successful pack, blocked pack, and failed pack after execution started.

Failure Recommendation

The packer should distinguish at least three terminal classes:

  1. validation gate failure before emission;
  2. execution or materialization failure during pack generation;
  3. persistence or promotion failure while making artifacts final.

These classes matter because they map directly to the Studio Result phase already decided upstream.

Build Output Recommendation

The packer publication boundary for this flow should remain build/.

Recommended first-wave baseline:

  • packWorkspace(...) publishes final outputs to build/;
  • the canonical runtime-facing artifact is build/assets.pa;
  • the baseline companion artifacts are:
    • build/asset_table.json
    • build/preload.json
    • build/asset_table_metadata.json
  • a future shipper may consume those packer outputs together with program.pbx;
  • the shipper is mentioned here only to keep the boundary explicit, not because it participates in packWorkspace(...).

This keeps the current domain boundary intact: the packer publishes build artifacts and the shipper assembles cartridges.

Open Questions

None for the first-wave execution shape. The remaining work is to convert this agenda into a decision and then propagate the agreed materialization policy into code and specs.

Recommendation Summary

This agenda recommends closing the first-wave packing contract as:

  1. one packer-owned packWorkspace(...) operation;
  2. internally phased and serialized through the project write lane;
  3. guarded by a packer-owned validation check at execution start;
  4. based on one frozen in-memory execution snapshot for the build-relevant asset bytes;
  5. staged under build/.staging/<operation-id>/ before promotion to final artifact visibility in build/;
  6. observable through causality-preserving progress events;
  7. finished with a result that distinguishes blocked, failed, and successful pack outcomes.

Next Suggested Step

Convert this agenda into a docs/packer decision focused on pack execution semantics and propagation targets.

That decision should then drive:

  1. one PR for prometeu-packer-api result and event-contract adjustments, if needed;
  2. one PR for prometeu-packer-v1 execution, staging, and artifact-promotion behavior;
  3. one Studio PR to bind the Packing and Result phases to the final packer-owned execution contract.