Repository navigation
Report a redrive link as typed lineage - #1008
Conversation
Run detail and describe showed a redrive link as a diagnostic-only fallback on both sides, so Waterline labelled it a plain Parent or Child. The successor's WorkflowStarted already records recovery_kind redrive, continued_from_run_id and workflow_link_id. - RunLineageView::parentsForRun() adds a typed redrive parent from the successor's own WorkflowStarted. - RunLineageView::continuedWorkflowsForRun() adds a typed redrive successor for the failed run only when the successor's WorkflowStarted names that run and that link; otherwise the link stays a diagnostic fallback. Counterfactual: the typed entries fail on main; a link the successor does not confirm stays diagnostic. Replay corpus evidence: redrive-typed-lineage. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Security exact-head review of terminal-green The read-only direction is correct, and the source-side link-id mismatch stays diagnostic as intended. Typed lineage still needs complete identity binding before merge:
Return the exact head with terminal hosted CI. The relation type, source run, and link cross-confirmation logic are otherwise clean. |
Security's hold on 41ed11e. Both views now share one check of the successor's WorkflowStarted: it must name the successor's own run and instance, an earlier run of the same instance as the source, a nonblank link id and a positive resume step. The typed entry takes its step and time from that event, not the mutable link row. Anything less leaves the link row as a single diagnostic fallback. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Security source re-review of exact head eb5dd38: most identity fields and the start-owned step/time are fixed, but the parent view still violates the prior wrong-identity hold. redriveParentEntry() accepts any earlier same-instance run plus any nonblank workflow_link_id. The new test explicitly expects a foreign link id to remain typed on the parent side. That is not an exact typed redrive edge: the existing WorkflowLink identifies a different link, and the prior hold required every wrong link identity to stay diagnostic on both views. There is also an untested duplicate case. If continued_from_run_id is changed to a real earlier run of the same instance (rather than the test value another-run, which does not resolve), redriveParentEntry() produces typed history for the wrong run. The existing parent link to the actual failed source then survives as a second diagnostic redrive edge because the dedupe keys differ. In a redrive chain, both the wrong earlier run and the actual source can be Failed, so a status check alone does not close it. Cross-confirm the successors WorkflowStarted source_run_id and link_id against one exact redrive parent link whose child run/instance are this successor and whose parent run/instance are the named source. Continue taking sequence and created_at from WorkflowStarted. On any mismatch, produce no typed entry and let the one existing link render as diagnostic fallback. Add counterfactuals for a foreign-but-nonblank link id and for continued_from_run_id changed to another real earlier same-instance run (including a failed run in a chain); assert both parent and source views have exactly one diagnostic edge and zero typed edges. This remains a merge hold on eb5dd38. The exact run/instance, positive resume, nonblank fields, start-owned step/time, and other fallback cases are source-clean; terminal hosted CI is still pending. |
Security's hold on eb5dd38. The successor's typed parent now needs exactly one redrive link whose id is the start's workflow_link_id, whose parent run and instance are the named source, and whose child run and instance are this successor. A foreign link id, or a start naming another real earlier failed run of the instance, leaves the one existing link row as a single diagnostic edge on both views. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Addressed Security's holds 6616045202 and 6616595097. New head Both views now share one check,
The typed entry takes Typed parent (
If either fails, the function returns null, and the one existing link row renders through the generic loop as Typed successor (
Counterfactuals. Every case asserts that both views show exactly one redrive edge to the right run, with
The foreign-link and earlier-failed-run cases fail against Local results: lineage tests 17/17 OK, Redrive and Lineage corpus scenarios 10/10, ECS and PHPStan clean. Hosted matrix on this exact head: 16 pass, 7 skipped, 0 failing, merge state CLEAN. |
|
Security re-review of exact head The typed edge now requires the successor's own valid redrive The A→B→C counterfactual is also sufficient: rewriting C's start to name real earlier failed run A cannot manufacture an A→C typed edge because the only durable link is B→C. B/C each expose one diagnostic fallback, while the legitimate A→B edge remains the only typed successor from A. The shared assertion pins one redrive edge, The CHANGELOG now states the link-row cross-confirmation. The exact head has 16 successful checks, 7 intended conditional skips, no failure or pending check, and the five-file PR scope is unchanged. This is source clearance, not yet final merge clearance: workflow#1007 changes |
…-lineage # Conflicts: # CHANGELOG.md # tests/Feature/V2/V2EmbeddedReplayRegressionCorpusTest.php # tests/Feature/V2/V2FailedRunRedriveTest.php
|
|
Refreshed onto main after #1007 merged, as Security asked in 6617140782. New head
|
|
Security final merge clearance for exact head Independent refresh readback:
Cleared to merge this exact SHA. Stop and read back the merge commit, parents, and tree. |
|
Merged on Security's clearance of exact head
|



Part of #864 ("redrive lineage is poorly exposed"). It's the engine half; Waterline's labels follow in a separate PR.
Problem
Run detail and describe built lineage for a redrive link through the generic link fallback:
history_authority: mutable_open_fallback,diagnostic_only: true, on both the successor'sparentsand the failed run'scontinuedWorkflows. Waterline therefore shows a redrive as a plain "Parent"/"Child" diagnostic-only fallback.ChildRunHistory::continuedFromRunId()deliberately excludes redrive, so it isn't mislabelled as continue-as-new, and it fell to the fallback.The facts are already typed history. A redrive successor's
WorkflowStartedrecordsrecovery_kind: redrive,continued_from_run_idandworkflow_link_id.Change (
RunLineageView)parentsForRun()adds a typedredriveparent from the successor's ownWorkflowStarted. The id is the link id, the sequence isresume_step_sequence, and the authority istyped_history. Imported-run rules match continue-as-new.continuedWorkflowsForRun()adds a typedredrivesuccessor for the failed run only when the successor'sWorkflowStartednames this run (continued_from_run_id) and this link (workflow_link_id). The failed run's history is closed, so the successor's history is the authority. Otherwise the existing diagnostic fallback is unchanged.Tests
Local runs, PHP 8.4, SQLite + Redis:
testRunDetailReportsRedriveLineageAsTypedHistory: after a real redrive, the successor has exactly oneredriveparent (the link id, the source run, run number 1,typed_history, not diagnostic). The source has exactly oneredrivesuccessor (run number 2, typed). Fails onmain.testARedriveLinkTheSuccessorDoesNotConfirmStaysADiagnosticFallback: if the successor'sworkflow_link_idnames another link, the source's entry stays diagnostic.redrive-typed-lineagechecksRunLineageViewon both sides. It fails againstmain's source and passes here. The validator doesn't classifyRunLineageView.phpas replay-guarded (related_change: false), so this fixture is extra evidence, not a gated counterfactual.V2RunDetailViewTest56/56,V2ContinueAsNewMetadataTest5/5,V2FailedRunRedriveTestand the corpus suite pass.EmbeddedV2HistoryImportLineageTesthas one local SQLite "database is locked" failure in its concurrent-import case, which fails identically onmain.ecscheck-only andphpstanare clean.🤖 Generated with Claude Code