Skip to content

cli-common state components: path/dir resolver + hermetic test helper + tier-1 cache core #17

@rianjs

Description

@rianjs

Build the shared cli-common state components — §6 step 1 ("commons-first") of docs/working-with-state.md. Foundational layer; no CLI port in this issue (ports are per-unit, later, each with its own §3.2 migration matrix).

Scope (§5)

(a) Path/dir resolver (§5a) — owns the genuinely-common policy, not a thin os.User*Dir()+Join wrapper:

  • credential-scope config-dir naming rule (§3) + per-binary cache-dir rule (§4.1)
  • create vs. no-create split (resolver must not mkdir on dry-run / config clear paths)
  • a migration-source enumeration seam so each CLI's bespoke legacy probing plugs in without the resolver trying to be generic about legacy layouts
  • does not ban a CLI from calling os.User*Dir() for its own legacy-probe paths

(a) 7-var hermetic test helper (§3.1) — overrides the full set: HOME, USERPROFILE, AppData, LocalAppData, XDG_CONFIG_HOME, XDG_CACHE_HOME, XDG_DATA_HOME. Ships once here; no CLI re-derives the list. Load-bearing (HOME-only is a Windows real-dir leak).

(b) Tier-1 cache core (§5b) — directory-agnostic:

  • Envelope[T]{Resource,Instance,FetchedAt,TTL,Version,Data} + ReadResource[T]/WriteResource[T]
  • atomic temp-file-in-same-dir → chmod 0600 → rename; dir 0700
  • version-mismatch-as-miss (schema bumps self-heal)
  • freshness Classify/Age/Status (Fresh|Stale|Uninitialized|Manual|Unavailable; manual = never auto-expire)
  • cache path from an injected Locator{Root, InstanceKey} — receives Root, never derives it

Tier 2 (registry/DAG/fetchers/refresh wiring) is explicitly deferred (§5b rule-of-three; post-cfl).

Out of scope

  • Any CLI port / config relocation / §3.2 migration matrix (per-unit, later)
  • Tier-2 cache layer
  • Cutting the INT-310 semver tag (only after the consumer matrix is green — §5 guardrail)

Acceptance

  • One PR, decomposed commits: (1) resolver, (2) hermetic helper, (3) tier-1 cache core
  • make check green (tidy + lint + test); stdlib-only (no go.sum)
  • Unit tests for resolver naming/create-split, hermetic helper env coverage, envelope round-trip / atomic-write / version-miss / freshness classification
  • Codex architect convergence (blockers=0 majors=0)

Jira: MON-5364 (child of INT-310, Feature, 5pts, Sprint 71)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions