Skip to content

Record the deployed commit for each layer source #473

Open

Description

@David-Noble-at-work

A machine deployed from three repositories has three positions, and "what is installed here" is not
answerable without them.

Related: #252 (LKG tagging for dependency pinning) is the same problem for a build dependency.


Epic: #466 · Feature: #472

Activity

  1. David-Noble-at-work commented on Sep 6, 2026

    @David-Noble-at-work
    ContributorAuthor

    Finding, 2026-09-06: the deployed commit per layer is already recorded — in the graph, not the trace.

    Today's first base-layer deploy (writ deploy --allow-dirty --conflict=replace common, two layers) left this
    in the persisted graph, graphs/sha256-ff9be840….yaml:

    timestamp: 2026-09-06T09:17:22.977061-07:00
    origin:
        tool: writ
        scope: home
        annotations:
            commit_hashes:
                base: 74f83ebf6edc00fc3c4c3a6da56808fe3575b90b
                personal: 27e53171af5eb5c3079dfcc744c83db8e5488c27
            dirty_layers:
                - personal
            files:
                file.link-30:
                    action: file.link

    deploy.go pins every layer source to a detached git worktree at HEAD before planning
    (snapshot.Pin, under ~/.cache/devlore/snapshots/<layer>-<hash12>/), and PinInfo.CommitHashes /
    DirtyLayers "ride the graphs' origin annotations" (plan.go, pkg/op/graph.go:702). Both layers'
    hashes and the dirty-layer list are there.

    The trace for the same run carries none of it — top level is still graph_checksum run_status stack catalog checksum signature — and writ reconcile reports layer per entry but no commit. So
    the question "what was deployed here, and from where" is answerable today by reading the graph, and
    by nothing a user actually runs.

    What this changes for beat 3

    Not "record the commit" — it is recorded. Surface it: the trace's metadata gains the origin block
    (layer, repository, ref, dirty) copied from the graph's annotations at run time, and reconcile
    prints the ref beside the layer. That is smaller than the beat was filed as, and it is exactly the
    shape #806 sketched.

    One semantic worth writing down while here

    Plan from HEAD, serve from the working tree. Planning enumerates the pinned snapshot, so an
    uncommitted addition is never linked and an uncommitted deletion is planned and then dangles. But
    the links themselves point at the working tree (~/Workspace/…/Home/…), not the snapshot — the
    snapshot is removed after the run — so a file that exists at HEAD and is locally modified serves the
    modified content. --allow-dirty only lifts the refusal; it does not change any of that. The origin
    block should say dirty: true for such a layer, which DirtyLayers already knows.

  2. David-Noble-at-work commented on Sep 28, 2026

    @David-Noble-at-work
    ContributorAuthor

    Closes with #971 (lane 17 of #916), 2026-09-28: under kept snapshots each layer is pinned by a refs/devlore/ ref and the record names each layer's commit and snapshot, so the deployed commit per layer is structural.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Epic:LayerSplitSplit the dotfiles into base, team, and personal layersThread:WritOriginCross-cutting: writ records and verifies where a deployment came fromtaskImplementation work item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions