KB-5420

04 — Registry Pin / Ghim Pack (Branch C)

4 min read Revision 1
registries-pivotregistry_pinghimPIV-321REGISTRY_MISSINGno-localstoragebegin-rollback2026-05-31

title: 04 — Registry Pin / Ghim Pack (Branch C) date: 2026-05-31 status: rehearsed GREEN; NEW table; COMMIT DEFERRED (RG6)

04 — Registry Pin / Ghim Pack (Branch C)

Goal: PG-backed pinning — not localStorage, not frontend-only state.

Re-scan for reuse (live)

Table scan ~* 'pin|ghim|favorit|watch|bookmark|star|monitor|saved'0 rows. No favourite/watchlist/pin artifact exists. registry_pin is genuinely NEW (REGISTRY_MISSING) → propose-only, classify NEW (not REUSE/EXTEND).

Rehearsal (live BEGIN..ROLLBACK, GREEN)

CREATE TABLE registry_pin (
  id          serial PRIMARY KEY,
  object_ref  text NOT NULL,                 -- CAT code / pivot code / substrate key
  object_kind text,                          -- 'registry' | 'pivot' | 'list' | 'node'
  surface_ref text NOT NULL,                 -- route/surface the pin shows on
  pinned_by   text NOT NULL,
  scope       text NOT NULL DEFAULT 'user',
  scope_ref   text,                          -- user/role/team id when scope <> global
  reason      text,
  priority    int  NOT NULL DEFAULT 0,
  active      boolean NOT NULL DEFAULT true, -- soft-retire only (Đ0 Atom: never hard-delete)
  created_at  timestamptz NOT NULL DEFAULT now(),
  CONSTRAINT registry_pin_scope_ck CHECK (scope IN ('global','user','role','team'))
);

Result: table created, 2 pilot rows inserted (CAT-023 global, PIV-007 user), CHECK def confirmed scope = ANY (ARRAY['global','user','role','team']); ROLLBACK → registry_pin gone, idle_in_transaction = 0.

Required properties — all satisfied

requirement mechanism
not localStorage / frontend-only PG table, read via Directus/API
scope global/user/role/team scope CHECK + scope_ref
reason reason
priority priority (sort key)
active active (soft-retire, Đ0 Atom)
audit fields pinned_by, created_at
governance owner scope + future governance_owner (Đ37; via scope_ref=role/team)
pivot-countable PIV-321 (pins by scope, grouped-count) activates on commit

API contract (read)

GET /api/registries-pivot/pins?scope=&surface=[{object_ref, object_kind, surface_ref, scope, scope_ref, pinned_by, reason, priority, active}], ordered by priority, created_at. Write path (pin/unpin) is a separate gated macro (needs write API + Đ32 per-action approval); this macro exposes read only.

UI contract

A pin column / 📌 affordance on each row; pinned rows float to top within scope; the pin list itself is a living list (PIV-321 countable). No hierarchy/state in the frontend — order and membership come from PG.

No-hardcode tests

  • No localStorage for pins (confirmed absent in Nuxt source scan, doc 09/12).
  • Pin membership/order from PG only; no hardcoded pinned codes in .vue.
  • Pin count traces to PIV-321 or count(registry_pin), never a frontend array length.

Commit-ready SQL (RG6 — DEFERRED)

CREATE TABLE registry_pin … above; additive/reversible (DROP TABLE registry_pin). No persistent creation performed — no RG6 approval exists.

Verdict

Pin pack COMPLETE. NEW table, rehearsed GREEN, PG-backed, scoped, pivot-countable; commit deferred to RG6.

Back to Knowledge Hub knowledge/dev/reports/architecture/registries-pivot-macro2-3-combined-ui-api-legacy-acceptance-2026-05-31/04-registry-pin-ghim.md