Skip to content

lattice push: include semantic diff since last push #21

@gmoon

Description

@gmoon

Problem

lattice push sends the full graph (nodes + edges) but no change context. The app has no way to know what changed since the last push without diffing the entire payload.

Proposal

1. Include semantic diff and git SHA in push payload

lattice push computes a semantic diff (added/modified/resolved/deleted nodes) since the last push and includes it in the payload alongside the current git SHA:

{
  "projectName": "lattice",
  "gitSha": "abc1234",
  "nodes": [...],
  "edges": [...],
  "diff": {
    "baseRef": "bf1011a",
    "added": [{ "id": "REQ-LINT-001", "title": "...", "nodeType": "requirement" }],
    "modified": [{ "id": "IMP-API-008", "title": "...", "nodeType": "implementation", "fields": ["body", "version"] }],
    "resolved": [{ "id": "REQ-API-014", "resolution": "verified" }],
    "deleted": []
  }
}

Key details:

  • gitSha (required): the git commit SHA this push represents
  • diff (optional): semantic diff since baseRef, omitted on first push
  • modified entries include a fields array listing which fields changed — the app cannot reconstruct this since it overwrites nodes on upsert
  • resolved captures requirements that gained a resolution status

2. Query app for baseline SHA

Before computing the diff, the CLI calls GET /api/lattice/push/last?project=<name> to get the last-push SHA from the app. The app is the source of truth — no local state needed.

  • Returns { "lastPushSha": "abc1234", "lastPushAt": "..." }
  • Returns 404 on first push → CLI omits the diff section

3. App returns last-push SHA in response

The push response includes the SHA so the CLI can confirm:

{
  "projectId": 1,
  "nodesUpserted": 113,
  "edgesReplaced": 128,
  "lastPushSha": "abc1234"
}

4. lattice diff --since-push

Convenience command that queries the app for the last push SHA and shows the diff without pushing. Useful for previewing what the next push will include.

Implementation

CLI changes

  1. Add gitSha field to PushPayload — get from git rev-parse HEAD
  2. Before push, query GET /api/lattice/push/last?project=<name> for baseline SHA
  3. If baseline exists, compute semantic diff using existing lattice_diff() with --since <sha>
  4. Extend diff to include fields array on modified entries (compare old vs new node fields)
  5. Include diff in push payload
  6. Handle 404 from last-push endpoint (first push — omit diff)
  7. Add --since-push flag to lattice diff that queries the app for baseline and shows diff

App changes (forkzero/lattice-app#2)

  1. push_history table storing per-push metadata and semantic diff as JSON
  2. Accept gitSha and optional diff in push payload
  3. New GET /api/lattice/push/last endpoint
  4. Return lastPushSha in push response

Why app-side rather than local ref

Storing the last-push ref locally (e.g., .lattice/last-push-ref) drifts when someone pushes from a different machine, CI, or without committing the ref file. The app is the canonical source of truth for what it last received.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions