feat: add normalized analysis-run registry (Milestone 2 slice 1) - #89
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
7ddf20c to
ec1ebe5
Compare
ec1ebe5 to
05f00a0
Compare
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
62af5a6 to
e58f094
Compare
The fail-closed rollback script starts an explicit transaction. On an autocommit connection a RAISE left that transaction aborted, so the empty-registry cleanup could not run.
Buyer gap: after #95 the home Analysis runs row was inert text. Clicking the seeded Demo Corp lineage run now loads GET /api/analysis-runs/{id} and shows cutoff, requested date, and document count. Hidden runs stay not-visible. Synthetic aggregates only -- never a DSN or source SQL.
Buyer gap: after #100 the detail showed cutoff and counts but not the legal lifecycle the registry already stored. GET /api/analysis-runs/{id} now returns labeled status_history (Pending → Running → Succeeded with occurrence times). The list stays latest-status only. Hidden runs still 404 and never leak events. Failure codes stay machine tokens. Synthetic Demo Corp seed only.
Buyer gap: after #102 the run detail showed history but no way to open a post. Detail now lists ABAC-visible titles in the run's scope. Other-corp private posts stay hidden. List payloads stay aggregates-only. Synthetic titles only.
The #74 changelog fold still called that decision ADR 0013. This stack keeps the analysis-run registry as ADR 0013, so the adaptive record is 0015. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
15e90ca to
955d0b0
Compare
There was a problem hiding this comment.
v0.83 follow-up is on the same tip plus one commit: analysis-run detail must not list posts written after knowledge_cutoff, and it should show revision/config digest prefixes so an operator can confirm the run they approved.
What this PR already does well
- Migration 0018 keeps snapshot availability and run cutoff on different relations, with 3NF names and append-only lifecycle evidence.
- Authorized list/detail stay source-redacting: labels and aggregates only; hidden runs 404.
- Status history is detail-only and uses stored machine failure codes.
- Synthetic Demo Corp seed only.
Required before claiming temporal truth on the post list
fetch_visible_scope_posts currently returns every ABAC-visible title in scope. Fixture posts use created_at = now() (August 2026) while the seeded run cutoff is 2026-01-12T12:00:00Z, so a later own-corp post would appear inside that January reconstruction. ADR 0013 already requires the cutoff; the read projection has to apply it.
The v0.83.0 slice on cursor/bc-4e088f14-f62b-4ed5-90d0-2167410c4cda-226d adds created_at <= knowledge_cutoff, backdates in-cutoff fixture posts, asserts the late post is absent, and shows digest prefixes. Land that (or equivalent) before treating the post list as as-of evidence.
Merge gates that are still outside this review
- Do not merge before #74 is on protected
main. Localtests.ymlonly runs on PRs targetingmain, so this stacked PR has no Full test suite / Frontend check on the current head. - #105 and #107 cover overlapping registry work. Keep one exact-head stack after #74 lands.
- Qualifying independent approval is still required by the live ruleset.
I cannot merge from this automation. Next action: review the v0.83 cutoff slice, then rebuild this stack onto protected main after #74.
Sent by Cursor Automation: fix all
| rows = await conn.fetch( | ||
| "select post_id, post_title, visibility_code, corporate_entity_id " | ||
| "from source_post where corporate_entity_id = $1 " | ||
| "order by created_at, post_title", |
There was a problem hiding this comment.
This scope query has no created_at <= knowledge_cutoff predicate. A post written after the run cutoff still appears in visible_posts, so the detail contradicts ADR 0013's temporal ownership.
Add the cutoff bind to every scope branch (corporate entity, process unit, thread group, all-visible). The v0.83.0 follow-up does that and adds a late own-corp fixture post that must stay absent.
| ))} | ||
| </ol> | ||
| )} | ||
| {selected.visible_posts && selected.visible_posts.length > 0 && ( |
There was a problem hiding this comment.
The detail lists posts but not the reproducibility digests the API already returns (code_revision_sha, configuration_sha256). An operator cannot confirm this run matches the code they approved.
Show 12-character prefixes here, and keep full digests on the API only. v0.83.0 extracts this panel to AnalysisRunsPanel so the list/detail object can be inventoried for Storybook without growing this file further.
f27ecfb
into
feat/role-responsibility-agent-ontology
The #89 review asked for 12-character code and config prefixes so an operator can match the approved revision. Full digests stay on the API only. Do not merge until this review item is checked. Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>


Buyer impact
Adds the first clean, additive Milestone 2 persistence boundary to the reviewed LineageWeave product. Operators gain a durable derivation root for immutable source captures, aggregate reconciliation, authenticated requests, product scope, reproducibility digests, and legal lifecycle evidence without merging the retained parallel application or exposing private source material.
Refs #79; does not close it.
Exact stack boundary
feat/role-responsibility-agent-ontology.59cde232fbf2b4876a5acb0c1873a364ac3d8eeb(linear replay; stale parents3bd4fb0and80905cfare gone).955d0b068d6f18a3697a6ddfa18a1da690ea2204.cursor/rebase-analysis-run-registry-3276(PR feat: rebase analysis-run registry onto current #74 head #107).main, ancestry and all base-sensitive evidence must be regenerated on the exact resulting head.Normalized registry
Migration
0018_analysis_run_registry.sqladds:analysis_source_snapshot— immutable capture digest, source-contract version, latest evidence-availability time, and capture time;analysis_source_count— one non-negative aggregate per snapshot/count vocabulary;analysis_run— non-null authenticated requester, account-scoped idempotency, run-owned knowledge cutoff, and reproducibility digests;analysis_run_scope— exactly shaped all-visible, corporate-entity, process-unit, or thread-group scope;analysis_run_status_event— append-only state-machine evidence with occurrence and database record time;analysis_run_current_status— derived latest-status view, not a second mutable authority.All database objects use descriptive two-or-more-word
snake_case; enum-like values remain incommon_lookup_value; category allowlists prevent an unrelated lookup code from satisfying a run column.Temporal truth
The snapshot owns
maximum_available_time; each run ownsknowledge_cutoff. This preserves the functional dependency that one immutable capture can support multiple later analyses. Run creation locks the snapshot and requires:This aggregate leakage guard complements, rather than replaces, TEPP's finer event/assertion/document/system/availability/cutoff clocks.
Concurrency and immutability
Lifecycle contract
The first status must be
pending; ordinals are contiguous; occurrence time is monotonic; and only these transitions are accepted:Failed events require a bounded machine failure code. Raw exceptions and source/provider payloads are prohibited. Update/delete of status events is rejected.
Authorization and privacy boundary
Every run references a real
user_account; idempotency is unique per account. The next repository/API slice must create run, scope, and first status atomically and enforce the existing RBAC/ABAC contract when reading registry data. This PR does not claim an API or UI already exists.Necessary PII remains in purpose-bound authorized source/product contexts. The registry retains only opaque identifiers, digests, aggregate counts, bounded codes, and clocks. It supports CSAP/SOC 2 evidence readiness without claiming certification.
TDD and verification
The real-PostgreSQL contract was committed before the migration implementation. The one-shot branch verifier and any temporary repair workflow are absent from the final diff versus #74.
Documentation
Merge gates
59cde232fbf2b4876a5acb0c1873a364ac3d8eeb.main.main.