feat(integrate): give the merge train its two executors #2011

Merged
sean merged 1 commit from feat/integrate-templates into trunk 2026-08-07 18:46:31 +00:00
Owner

R3. Two executors: pipeline-integrate-rebase (rebase one car, report the exact head) and pipeline-integrate-merge (ff-only merge that exact head, emit the nine change* keys).

The nine change* keys leave DormantEvidenceKeys after six days with no producer behind a fail-closed read.

Projector gains a two-writer firewall: a train-owned merge run carries change-kind=integration and its evidence belongs to the Release. A mutation proved the test.

A fourth binding edge (the dormancy unit test) failed as designed and is now inverted — it watches the dangerous direction.

128/128 guards, 14/14 packages.

R3. Two executors: pipeline-integrate-rebase (rebase one car, report the exact head) and pipeline-integrate-merge (ff-only merge that exact head, emit the nine change* keys). The nine change* keys leave DormantEvidenceKeys after six days with no producer behind a fail-closed read. Projector gains a two-writer firewall: a train-owned merge run carries change-kind=integration and its evidence belongs to the Release. A mutation proved the test. A fourth binding edge (the dormancy unit test) failed as designed and is now inverted — it watches the dangerous direction. 128/128 guards, 14/14 packages.
feat(integrate): give the merge train its two executors
All checks were successful
pipeline/ci CI green @ 69687e0eee54
69687e0eee
R3 of RELEASE-TRAIN-AND-EVENT-TRIGGERS.md. One commit, because the run contract
binds four things and the guard fails if they disagree.

pipeline-integrate-rebase puts one car on top of the integration branch and
reports the exact head. It stops there. The push starts CI by itself, and the
operator waits on the Build watch it already has.

pipeline-integrate-merge takes that head as an INPUT and merges it
fast-forward-only. A head that moved after CI accepted it is refused, so an
unvalidated revision cannot reach the branch. It keeps the revision-preservation
check: if the merge produces any other revision, it refuses to report evidence
rather than let a wrong identity ride downstream.

Two short runs, not one that waits. One run would have to poll for CI, which
holds a pod for the whole of it, or arm the provider's auto-merge, which makes
the merge instant unobserved and leaves nothing to emit evidence.

The nine change* keys leave DormantEvidenceKeys. They were dormant for six days:
their emitter was deleted on 2026-08-01, and six of them could fail a run closed
the whole time with no producer behind them.

The projector gains a two-writer firewall. A train-owned merge run carries
change-kind=integration, and its evidence belongs to the Release. An unlabelled
merge run is the legacy path the projector still owns. Without the firewall both
write the same Change and the later write wins by timing.

Both templates take every parameter as an env value. The old merge template
interpolated actor and delegatedBy into a script that holds a write-capable
token, where a parameter is code.

A mutation proved the firewall test: deleting the guard clause fails it with the
message written for that case. A fourth binding edge, the dormancy unit test,
failed exactly as designed and is now inverted -- it watches the dangerous
direction, a key going BACK to dormant while a fail-closed read survives.
sean merged commit 69687e0eee into trunk 2026-08-07 18:46:31 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
sean/pipelines!2011
No description provided.