Skip to content

Adopt pack layout packs///stack (Option B)

Status

Proposed — Standardise a deterministic, tarball-safe pack discovery and resolution model.

1. Context

HybridOps.Core must resolve pack assets reliably in both source checkouts and packaged distributions. Pack resolution MUST:

  • avoid repo-root inference and .git dependencies
  • prevent path traversal
  • support stable, versioned pack identifiers
  • support multiple driver domains with independent pack inventories

A predictable layout allows packs to be shipped with the runtime or hosted separately in future packaging modes.

2. Decision

Packs are stored under a single packs root with this canonical layout:

  • packs/<driver_ref>/<pack_id>/stack/

Where:

  • <driver_ref> matches the driver reference used in the module spec (e.g., iac/terragrunt)
  • <pack_id> is a relative, versioned identifier (e.g., gcp/org/00-project-factory@v1.0)
  • stack/ is the driver-executed root directory (tool plan)

The driver MUST resolve the pack stack directory as:

  • <packs_root>/<driver_ref>/<pack_id>/stack

3. Packs root resolution

The packs root MUST be resolved using this precedence order:

1) explicit argument (internal API only) 2) $HYOPS_PACKS_ROOT 3) <release_root>/packs

<release_root> is determined relative to the installed package location, not Git.

4. Security and correctness constraints

Pack resolution MUST enforce:

  • <pack_id> is a relative path (no absolute paths, no traversal segments .., no NUL)
  • resolved stack directory MUST remain under packs_root (defense-in-depth)
  • required files MUST exist (driver-defined minimum, e.g., terragrunt.hcl for Terragrunt packs)

If the pack is missing or invalid, the driver MUST fail deterministically with a clear error message and MUST capture the error in driver evidence.

5. Pack content rules

Packs SHOULD contain:

  • terragrunt.hcl (or tool equivalent)
  • optional versions.hcl, inputs.hcl, README.md
  • optional vendored wrappers under modules/ (only when required for offline or constrained environments)

Packs MUST NOT contain:

  • backend/workspace naming policy
  • secrets or credential values
  • repo-specific assumptions (e.g., get_repo_root() usage)
  • user-environment naming (dev/prod/staging) as an implicit requirement

Environment selection, state policy, and workspace naming are owned by profiles and interpreted by drivers.

6. Consequences

6.1 Positive

  • Deterministic pack discovery across source and packaged builds.
  • Clean separation between driver domains and their pack inventories.
  • Enables future distribution modes (e.g., external pack repositories) without changing module contracts.

6.2 Negative / risks

  • Requires migration of any existing ad-hoc stack layouts into this structure.
  • Requires tooling (CI) to validate pack IDs, required files, and tarball-safe rules.

7. Alternatives considered

  • packs/<pack_id>/stack (no driver_ref) — rejected; increases collision risk and weakens domain separation.
  • repo-relative infra/terraform/live-v1/... — rejected; not tarball-safe and couples runtime to workspace layout.
  • URL-based pack IDs — deferred; not required for v1 and introduces transport/auth complexity.

8. References