Skip to content

feat(gain-web): per-project install ledger + UI (tier 2 / depends #171) #172

Description

@thehoff

Background

#162 + #171 give us the dashboard + security pane. Neither answers the question:

"What got installed into project X, when, by what command, with what verdict?"

The supply-chain JSONL has the raw data but no project context and no fast project-scoped query path.

Proposed scope

Schema

New `installs` table in `history.db`:

Column Type Notes
id INTEGER PK
ts TEXT RFC-3339
project_path TEXT CWD at install time (same key as `commands.project_path`)
ecosystem TEXT npm / PyPI / cargo / gem / etc.
package TEXT requested package name
version_spec TEXT what the user asked for (e.g. `^4.18.0`)
resolved_version TEXT what actually got installed (nullable)
verdict TEXT allow / block / skip
finding_ids TEXT CSV of GHSA / PYSEC IDs that fired
raw_command TEXT full original command for forensics

Populator

The existing supply-chain gate hook (`supply_chain_gate.rs::log_event`) writes JSONL today. Extend it to also INSERT into `installs` so both surfaces stay in sync. JSONL remains the immutable audit log; SQL is the query surface.

Backfill

One-shot ETL: read existing `supply_chain.jsonl` (~20MB) and populate `installs` for historical rows. Idempotent (skip rows by (ts, raw_command) tuple).

Dashboard

  • `GET /api/installs?project=&limit=N` — per-project install history
  • New "Installs" pane with project filter dropdown (populated from distinct `commands.project_path` + `installs.project_path`)
  • Card: total installs per project, blocked install rate per project
  • Table: ts, package, ecosystem, version, verdict, finding IDs

Why now

Closes the traceability gap: "trackback what was installed by what and when" per the Hoff (2026-05-25).

Effort

M — 1 week.

  • Schema + migration: half day
  • Populator wire-up: half day
  • ETL backfill: 1 day
  • Endpoint + tests: 1 day
  • UI pane: 2 days
  • Peer review pair + doc: 1 day

Dependencies

Depends on #162 (dashboard surface) and #171 (security pane — sibling).

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions