Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
f2298cb
WIP: ci chores
Jul 22, 2026
3015abd
WIP: ci chores
Jul 22, 2026
59279cf
WIP: ci chores
Jul 22, 2026
2dc80fd
CI self-heal: derived remedy classification + P0 fixed-point witness …
Jul 22, 2026
1444039
Merge remote-tracking branch 'origin/main' into session/sleek-crane-70
Jul 23, 2026
d1c7778
WIP: ci chores
Jul 23, 2026
0699332
WIP: ci chores
Jul 23, 2026
03d15b7
WIP: ci chores
Jul 23, 2026
f8e627a
WIP: ci chores
Jul 23, 2026
b79cca6
Merge remote-tracking branch 'origin/main' into session/sleek-crane-70
Jul 23, 2026
e525551
Merge remote-tracking branch 'origin/main' into session/sleek-crane-70
Jul 23, 2026
16c3f75
WIP: ci chores
Jul 23, 2026
5ea34b7
WIP: ci chores
Jul 23, 2026
a42b041
WIP: ci chores
Jul 23, 2026
351e024
WIP: ci chores
Jul 23, 2026
1b6f09a
Heal commit scope: stage only registry paths, not git add -A (review …
Jul 23, 2026
f1d878e
WIP: ci chores
Jul 23, 2026
98d0da5
WIP: ci chores
Jul 23, 2026
da51505
WIP: ci chores
Jul 23, 2026
072920d
Merge remote-tracking branch 'origin/main' into session/sleek-crane-70
Jul 23, 2026
f87e908
Regen ROADMAP.md for heal loop-safety note correction (review 41782)
Jul 23, 2026
5eca600
WIP: ci chores
Jul 23, 2026
fdf60c7
Merge remote-tracking branch 'origin/main' into session/sleek-crane-70
Jul 23, 2026
3891fe9
WIP: ci chores
Jul 23, 2026
2d62800
Merge remote-tracking branch 'origin/main' into session/sleek-crane-70
Jul 23, 2026
fe4be2a
WIP: ci chores
Jul 23, 2026
826ac6d
WIP: ci chores
Jul 23, 2026
de87df0
WIP: ci chores
Jul 23, 2026
942a46f
Merge origin/main: absorb #7121 fleet-converge removal + #7090; recon…
Jul 23, 2026
830aeab
WIP: ci chores
Jul 23, 2026
b58f0e4
Update heal witness for PR+push heal: pr_and_push guard, existence-gu…
Jul 23, 2026
b9761b6
WIP: ci chores
Jul 23, 2026
04ec0ae
Review 41904: sync ts-loop-selfheal roadmap row to PR+push heal; add …
Jul 23, 2026
0993069
WIP: ci chores
Jul 23, 2026
8b439f0
Resolve ci.yml merge conflict: regenerate from merged authority (dash…
Jul 23, 2026
85ea870
WIP: ci chores
Jul 23, 2026
7872b56
Heal telemetry: align heal step name + regen notice title to the bran…
Jul 23, 2026
0c185e2
WIP: ci chores
Jul 23, 2026
7b6d50c
Heal: restrict to pull_request only; main drift fails ci instead of a…
Jul 23, 2026
d17fc7a
Merge remote-tracking branch 'origin/main' into session/sleek-crane-70
Jul 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 108 additions & 10 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ The operator's real TODO, organized (2026-07-22): six numbered items, each groun
- [ ] the release-build step's EAGAIN retry ladder (jobs=1, then drop RUSTC_WRAPPER) keeps builds green while masking the sccache/host deficit — the srvN build-cache provisioning lane owns the root fix (DESIGN open thread; STEP 2 fallback removal is operator-sequenced after T4).
- [ ] #7060 moved a witness to the long lane but left its explicit roster row enrolled → every main run red for ~3 hours (no-main-function-found) → hotfix #7079; enrollment-vs-definition living in two places is the same single-authority class the unconsumed-component row names. — ⏳ awaiting sign-off
- [ ] deploy-to-srv1 folded into the ci run for CD → srv1 host state now reds main daily independent of code health — the deploy-tail row above is the acute half; the CD-transport §2 node is the root.
- [ ] **structural exit — the DERIVABLE red class now heals itself on main (ci-chores lane, operator-directed 2026-07-23: 'the priority is getting heal working').** A generated-artifact drift is a red whose remedy is a pure function of the tree: regenerate the projection from its `.dag` authority. So a new `heal_generated_artifacts` job (main pushes only, the same guard the srv1 deploy job uses) runs `main_wet` — which rewrites each `committed_generated_artifacts()` projection — then commits+pushes ONLY when git diff shows a change, healing the drift with no human. It needs only `build` (the release gunbc binary), NOT `ci`: the drift gate lives inside `ci`, so a heal gated on ci passing would skip exactly when needed. `contents:write` is scoped to this one job via a new job-level `Job.permissions` field (least privilege, §5 — the workflow default stays `contents:read`, so the whole-corpus floor never runs with a push-capable token). Loop-safety is by construction: the byte-idempotent fixed point (`generated_artifact_drift_test.witness_committed_is_fixed_point` — committed bytes == `artifact_generate`, with a RED control) is PROVEN pre-merge, so a second heal would find no diff and push nothing. A push made with the workflow's `GITHUB_TOKEN` does not trigger a new run (GitHub cascade-prevention), so the heal fires no follow-on CI at all — the loop cannot recur; the healed artifacts are re-validated by the batch-0 drift gate on the next unrelated PR/push, not on the heal commit (which is correct-by-construction as main_wet's own output). main is unprotected today (verified 2026-07-23), so the push needs no branch-protection grant; protecting main later is a separate deliberate step that must add this job's identity to the push allowance. Judgment-class reds (producer bugs #7080, roster staleness #7079) are untouched — this job only re-derives what the registry already declares generatable, never a human decision; they stay the fail-fast + PR-time-detector lanes' job.
- [ ] **structural exit — the DERIVABLE red class heals itself on PRs; main drift fails CI (ci-chores lane, operator-directed 2026-07-23: 'i would regen push to PRs please — convenience in general, by the time it gets to main this should be green regardless', then 'i think we can disable main pushes for now — i don't expect this to be needed on main — we can just fail CI on main if regen somehow fails there').** A generated-artifact drift is a red whose remedy is a pure function of the tree: regenerate the projection from its `.dag` authority. So the `heal_generated_artifacts` job (on `pull_request` ONLY, `ci_regen_heal_if`) checks out the PR SOURCE branch head (`ref: github.head_ref || github.ref_name`), runs `main_wet` — which rewrites each `committed_generated_artifacts()` projection — then commits+pushes the fix back to THAT branch (`HEAD:github.head_ref || github.ref_name`) ONLY when git diff shows a change, so a drifted PR is repaired on its own branch before it reaches main. main is deliberately NOT auto-healed: main is protected by a ruleset requiring the `ci` check, so a heal push to main is rejected (GH013, receipt 2026-07-23), and it is not wanted anyway — on main the `ci` job's own drift gate reds honestly if regen ever drifts, which is the correct main behavior since a change reaching main should already be green from its PR heal. The heal needs only `build` (the release gunbc binary), NOT `ci`: the drift gate lives inside `ci`, so a heal gated on ci passing would skip exactly when needed. `contents:write` is scoped to this one job via a job-level `Job.permissions` field (least privilege, §5 — the workflow default stays `contents:read`, so the whole-corpus floor never runs with a push-capable token). The `git add` is per-path `[ -e ]`-guarded (each registered artifact staged only if present, a counted skip echo otherwise), so a registered-but-absent artifact — the #7121 `FleetConvergeArtifact` incident, deleted from the tree while its registry row lingered — is skipped rather than exit-128-ing the whole heal. Loop-safety is by construction: the byte-idempotent fixed point (`generated_artifact_drift_test.witness_committed_is_fixed_point` — committed bytes == `artifact_generate`, with a RED control) is PROVEN pre-merge, so a second heal would find no diff and push nothing. A push made with the workflow's `GITHUB_TOKEN` does not trigger a new run (GitHub cascade-prevention), so the heal fires no follow-on CI at all — the loop cannot recur; the healed artifacts are re-validated by the batch-0 drift gate on the next unrelated PR, not on the heal commit (which is correct-by-construction as main_wet's own output). Known caveat: the drift gate still lives inside `ci`, so the first run to observe drift shows `ci` red on its pre-heal snapshot (the GITHUB_TOKEN push does not re-trigger CI) even though the branch is auto-fixed — fully-green-first-run needs moving drift out of the ci floor (a merge-admission change), a follow-up. Judgment-class reds (producer bugs #7080, roster staleness #7079) are untouched — this job only re-derives what the registry already declares generatable, never a human decision; they stay the fail-fast + PR-time-detector lanes' job.

**4 · Antagonistic product review — the last two weeks of merges:**

Expand Down
41 changes: 23 additions & 18 deletions dag/gunbc/ci_spec.dag
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ data gunbc_ci_regen_spec: CiSpec = {
head: "HEAD",
mode: DiffMergeBase
},
notice_title: "self-host fixed-point (regen + staleness) — required; folded into ci job",
notice_title: "self-host fixed-point (regen + staleness) — required; own regen job upstream of ci",
deploy_stages: [],
}

Expand Down Expand Up @@ -453,7 +453,7 @@ fn gunbc_ci_heal_regen_invoke() -> String {
)
}

data ci_heal_commit_push_note: String = "The heal COMMIT+PUSH step: a GitHub Actions run: foreign-executor context (the shell-intent design's bootstrap/foreign-executor case that renders through bash), so the git commit/push is a hand-authored shell string like the deploy invoke and the release-bins unpack script beside it. COMMIT SCOPE IS ARTIFACT-ONLY BY CONSTRUCTION (review 41703, DESIGN §5 no-silent-widen): staging is `git add` over EXACTLY committed_generated_artifact_paths() (the registry the drift gate guards and the exact set main_wet writes) — never `git add -A`, so an incidental dirty file on the runner (checkout residue, line-ending normalization, leftover state) can never be swept into an unattended push to main. The commit fires ONLY when `git diff --cached --quiet` reports a staged change — i.e. only when main_wet actually healed a registry artifact — so a clean tree is a no-op, and the byte-idempotent fixed point makes the healed commit's own re-run a no-op that terminates the loop. The push authenticates with the job's GITHUB_TOKEN (persisted by actions/checkout) and needs the job-scoped contents:write grant. Loop termination is NOT a re-run of CI on the healed commit: a push made with the workflow's GITHUB_TOKEN does NOT trigger a new workflow run (GitHub's cascade-prevention is by design), so the healed commit fires no follow-on run — termination is guaranteed instead by the byte-idempotent fixed point itself, PROVEN pre-merge by generated_artifact_drift_test.witness_committed_is_fixed_point (committed bytes == artifact_generate) with its RED control, so a second heal would be a no-op even if one were triggered (review 41782 correction: the earlier 'verified by execution on the healed commit' claim was wrong — no such run exists). The healed artifacts are re-validated by the batch-0 drift gate on the NEXT unrelated PR/push, not on the heal commit, which is correct-by-construction (it is main_wet's own output). A concurrent main advance makes the push a non-fast-forward that fails LOUDLY (never a force-push), and the next main push retries."
data ci_heal_commit_push_note: String = "The heal COMMIT+PUSH step: a GitHub Actions run: foreign-executor context (the shell-intent design's bootstrap/foreign-executor case that renders through bash), so the git commit/push is a hand-authored shell string like the deploy invoke and the release-bins unpack script beside it. COMMIT SCOPE IS ARTIFACT-ONLY BY CONSTRUCTION (review 41703, DESIGN §5 no-silent-widen): staging is `git add` over EXACTLY committed_generated_artifact_paths() (the registry the drift gate guards and the exact set main_wet writes) — never `git add -A`, so an incidental dirty file on the runner (checkout residue, line-ending normalization, leftover state) can never be swept into an unattended push. Each path is guarded by a `[ -e ]` existence test (ci_heal_git_add_lines): a registered artifact that is absent on this tree — e.g. one a later PR deleted while its registry row lingered (the #7121 FleetConvergeArtifact incident) — is loudly echoed and skipped, never an exit-128 `git add` pathspec error that fails the whole heal; the drift gate remains the wall for a registered-but-missing artifact, the heal just commits what main_wet actually produced. The commit fires ONLY when `git diff --cached --quiet` reports a staged change — i.e. only when main_wet actually healed a registry artifact — so a clean tree is a no-op, and the byte-idempotent fixed point makes the healed commit's own re-run a no-op that terminates the loop. The push target is the TRIGGERING branch, not hardcoded main: `git push origin HEAD:${{ github.head_ref || github.ref_name }}` resolves to the PR source branch on a pull_request and to main on a push (operator-directed 2026-07-23: heal pushes to PRs so drift is repaired on the PR branch before it reaches main). The push authenticates with the job's GITHUB_TOKEN (persisted by actions/checkout, which checked out that same branch head) and needs the job-scoped contents:write grant. Loop termination is NOT a re-run of CI on the healed commit: a push made with the workflow's GITHUB_TOKEN does NOT trigger a new workflow run (GitHub's cascade-prevention is by design), so the healed commit fires no follow-on run — termination is guaranteed instead by the byte-idempotent fixed point itself, PROVEN pre-merge by generated_artifact_drift_test.witness_committed_is_fixed_point (committed bytes == artifact_generate) with its RED control, so a second heal would be a no-op even if one were triggered (review 41782 correction: the earlier 'verified by execution on the healed commit' claim was wrong — no such run exists). The healed artifacts are re-validated by the batch-0 drift gate on the NEXT unrelated PR/push, not on the heal commit, which is correct-by-construction (it is main_wet's own output). A concurrent advance on the target branch makes the push a non-fast-forward that fails LOUDLY (never a force-push), and the next run on that branch retries. A fork PR's branch is not writable by the workflow GITHUB_TOKEN, so a fork heal push fails loudly rather than silently — fork heals are out of scope; the fleet's PR model is same-repo session branches, which are pushable."

data ci_heal_commit_push_shell_emit_scaffold: Disposition = Scaffold {
dissolves_to: SingleAuthority,
Expand All @@ -466,25 +466,30 @@ data ci_heal_commit_push_shell_emit_scaffold: Disposition = Scaffold {

data ci_heal_commit_push_shell_emit_dissolution_trigger: String = "🟡 dissolve-on: gunbc_ci_heal_commit_push_script — hand-authored git config/add/commit/push shell for the unattended generated-artifact heal, a foreign-executor (GitHub Actions run:) git transport (the same scaffold class as merge_admission_ci_gate_step_scaffold and merge_admission_shell_emit_disposition beside it); DISSOLVES WHEN the shell→intent lane models git commit/push as typed host effects on host_effect_apply (host-effect-orchestration Do-effect migration, ROADMAP shell→intent), at which point the heal's git transport is a realization handler bound to the modeled operation, not emitted bash — the regen half (main_wet) is already modeled, only the git transport awaits (the host_effect Do-effect carrier, not a command string)."

fn ci_heal_git_add_scoped_line() -> String {
fold(committed_generated_artifact_paths(), init: "git add", f: fn(acc, p) {
concat(acc, concat(" \"", concat(p, "\"")))
})
fn ci_heal_git_add_lines() -> List<String> {
map(committed_generated_artifact_paths(), p =>
concat("if [ -e \"", concat(p, concat("\" ]; then git add \"", concat(p, concat("\"; else echo \"chore-heal: registered generated artifact absent on this tree, not staging: ", concat(p, "\"; fi")))))))
}

fn ci_heal_shell_lines() -> List<String> {
[
"git config user.name \"gunbc-ci-auto-heal\"",
"git config user.email \"gunbc-ci-auto-heal@users.noreply.github.com\"",
ci_heal_git_add_scoped_line(),
"if git diff --cached --quiet; then",
" echo \"chore-heal: no generated-artifact drift on this tree; nothing to commit\"",
"else",
" git commit -m \"chore: regenerate drifted generated artifacts (ci auto-heal)\"",
" git push origin HEAD:main",
" echo \"chore-heal: pushed regenerated generated artifacts to main\"",
"fi"
]
concat(
[
"git config user.name \"gunbc-ci-auto-heal\"",
"git config user.email \"gunbc-ci-auto-heal@users.noreply.github.com\""
],
concat(
ci_heal_git_add_lines(),
[
"if git diff --cached --quiet; then",
" echo \"chore-heal: no generated-artifact drift on this tree; nothing to commit\"",
"else",
" git commit -m \"chore: regenerate drifted generated artifacts (ci auto-heal)\"",
" git push origin HEAD:${{ github.head_ref || github.ref_name }}",
" echo \"chore-heal: pushed regenerated generated artifacts to the triggering branch\"",
"fi"
]
)
)
}

fn gunbc_ci_heal_commit_push_script() -> String {
Expand Down
Loading
Loading