feat(warpline): lifecycle facts on entity-assoc reverse-lookup + atomic reverify ingest#69
Closed
tachyon-beep wants to merge 3 commits into
Closed
feat(warpline): lifecycle facts on entity-assoc reverse-lookup + atomic reverify ingest#69tachyon-beep wants to merge 3 commits into
tachyon-beep wants to merge 3 commits into
Conversation
…p (warpline b-ii)
GET /api/entity-associations?entity_id=<sei> (and the MCP/db reverse lookup)
now enriches each binding row with the bound issue's claimed_at, closed_at,
status, and status_category, so warpline can correlate "changed since the
issue was claimed/closed" against its own changed-set in one round trip.
closed_at is the proven-good signal ("issue closed at commit X"); Filigree
exposes the resolution timestamp verbatim and stores no commit SHA — warpline
maps timestamp->commit on its side.
Implemented as a separate enriched projection (EntityAssociationByEntityRow)
via a LEFT JOIN to issues — the shared _row_to_entity_association mapper, the
forward list_entity_associations, the add-response, and governance.py are all
untouched and byte-identical. LEFT (not INNER) JOIN keeps an orphaned binding
(issue row absent) in the result with null facts rather than dropping it.
Additive and Loomweave-safe: the Loomweave consumer
(parse_entity_associations_response) has no serde deny_unknown_fields and is
tested to ignore unknown fields, so the v1 consumer still parses v2. Contract
fixture bumped to fixture_version 2.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…t-UNBOUND) ingest_reverify_worklist created the issue and bound its SEI in two separate @_in_immediate_tx transactions, so a non-retryable storage error on the bind left the issue FILED-but-UNBOUND. Because the loop-closure contract keys on the SEI association warpline reads back, the next ingest then saw the entity as untracked and re-filed a duplicate. Route the bind through create_issue's existing atomic inline-bind path (entity_id / content_hash / entity_kind), so file+bind commit together in one transaction; a bind failure rolls the whole item back. The warpline content sentinel is preserved verbatim. Regression test simulates a bind failure and asserts no orphaned issue remains. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…fy ingest Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Collaborator
Author
|
Superseded by #70, which now targets main with the full set of commits (b-ii + atomicity fix + commit anchor). Consolidated to avoid fragmenting the work across stacked branches. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of warpline's P1 federation integration request (tracker:
filigree-1299255fb5). This PR lands the two complete, low-risk pieces; the commit-anchor enhancement follows as a separate stacked PR.Context
Warpline asked Filigree to support "if I touch X, what must I re-verify?" without crossing the authority boundary. After investigation, 2 of the 4 sub-deliverables were already built (consume reverify worklists;
closed_aton the issue read). This PR closes the two real gaps that don't need a schema change, under the agreed contract Option B — warpline computes the "changed since claimed/closed" correlation; Filigree exposes the facts.Changes
Added — issue lifecycle facts on the entity-association reverse-lookup (b-ii)
GET /api/entity-associations?entity_id=<sei>(and the MCP + data-layer reverse lookups) now enriches each binding row with the bound issue'sclaimed_at,closed_at,status,status_category, so warpline can correlate against its own changed-set in one round trip.closed_atis the proven-good signal ("issue closed at commit X"); Filigree exposes the resolution timestamp and stores no commit SHA — warpline maps timestamp→commit on its side.EntityAssociationByEntityRowprojection over aLEFT JOIN issues. The shared_row_to_entity_associationmapper, the forwardlist_entity_associations, the add-response, and the governance closure gate are untouched and byte-identical.LEFT(notINNER) JOIN keeps an orphaned binding (issue row absent — a contemplated state) in the result with null facts rather than dropping it.parse_entity_associations_response) has no serdedeny_unknown_fieldsand is tested to ignore unknown fields, so the v1 consumer still parses v2. Contract fixture bumped tofixture_version 2.Fixed — non-atomic reverify ingest (
filigree-8340b79615)warpline_worklist_ingestcreated the issue and bound its SEI in two separate transactions, so a non-retryable storage error on the bind left the issue FILED-but-UNBOUND — and the next ingest re-filed a duplicate (the loop-closure contract keys on the SEI binding). File + bind now commit in one transaction viacreate_issue's inline ADR-029 bind path. Regression test simulates a bind failure and asserts no orphan remains.Boundary & acceptance
Filigree stays the work-state authority; nothing here calls warpline. With warpline absent, all flows are unchanged — these are pure read-field additions + an internal atomicity fix.
Tests
New:
TestReverseLookupLifecycleFacts(5 cases incl. open/closed/claimed/orphan/forward-isolation),TestFileAndBindAtomicity. Gate green:ruff+ruff format --check+mypy src/filigree/+ fullpytest(exit 0).Follow-up (separate PR)
Commit-anchor (
branch@shaat claim/close) — a v29 schema migration threaded throughupdate_issueand the claim/close/reopen/release verbs, exposingclaim_commit/close_commitso warpline correlates on commits, not clocks. Caller-supplied (Filigree stays out of git/CI). Tracked onfiligree-1299255fb5.🤖 Generated with Claude Code