Skip to content

Archive v0.9: Candidate Inbox and promotion workflow - #24

Merged
WangEn merged 28 commits into
mainfrom
archive/v0.9-candidate-inbox
Oct 2, 2026
Merged

WangEn merged 28 commits into
mainfrom
archive/v0.9-candidate-inbox

Conversation

@WangEn

@WangEn WangEn commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Goal

Turn the v0.8 Catalog Discovery queue into a controlled operator Inbox and explicit promotion workflow without weakening observe-first identity guarantees.

Operator Inbox

Adds /catalog-inbox with:

  • server-gated operator access using the existing Web operator token boundary;
  • discovery state filters;
  • first/last seen and observation count;
  • source type, source SHA and first-party source link;
  • review notes;
  • match-existing, ignore, promotion-ready and reopen actions;
  • explicit promotion fields for canonical slug, marketing name and initial status.

The browser never receives MODELAPSE_CONTROL_TOKEN.

Controlled API

Adds control-token protected endpoints:

  • GET /v1/control/catalog/discoveries
  • GET /v1/control/catalog/providers/:providerId/models
  • POST /v1/control/catalog/discoveries/:candidateId/reconcile
  • POST /v1/control/catalog/discoveries/:candidateId/promote

Promotion invariants

Promotion requires:

  • candidate state promotion_ready;
  • latest evidence from a provider_api model-list source;
  • a URL-backed first-party source;
  • explicit canonical slug / marketing name / status;
  • operator actor.

There is no discovered-to-Model shortcut.

Docs-derived discoveries cannot be promoted by this workflow.

Provenance

Promotion reuses the Candidate's existing immutable source record. The model registration primitive now validates and accepts an existing sourceRecordId, so canonical Model provenance and the initial execution binding point back to the exact collection evidence that produced the Candidate.

Audit

Migration 0011_catalog_candidate_promotion.sql adds append-only catalog_promotion_events with database validation for provider and canonical-source consistency. A Candidate can be promoted at most once.

Promotion also appends the normal match_existing reconciliation event and transitions the Candidate to matched.

Drift semantics

Initial promotion is registration, not drift. Later source-backed identity changes still flow exclusively through the v0.6 observer/drift path.

Coverage

Adds API control-boundary tests and PostgreSQL integration coverage for:

  • promotion-ready -> canonical registration;
  • source-record reuse;
  • initial execution binding;
  • promotion audit projection;
  • append-only promotion events;
  • duplicate promotion rejection.

See docs/catalog-inbox.md.

WangEn added 28 commits October 2, 2026 00:04
@WangEn
WangEn merged commit edf8ed7 into main Oct 2, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant