Skip to content

Let Lopu start CodeQL-backed lanes on develop - #398

Closed
lopugit wants to merge 21 commits into
developfrom
codex/lopu-listener-security-events-develop
Closed

Let Lopu start CodeQL-backed lanes on develop#398
lopugit wants to merge 21 commits into
developfrom
codex/lopu-listener-security-events-develop

Conversation

@lopugit

@lopugit lopugit commented Aug 25, 2026

Copy link
Copy Markdown
Owner

Outcome

Makes develop use Lopu PR manager as its single automatic principal repository workflow. Two live failures are addressed:

  1. the latest develop push was rejected as a zero-job startup_failure because the protected reusable controller requested security-events access while the thin caller delegated none;
  2. one feature-branch push launched both Lopu and the legacy standalone rebase workflow, whose jobs were then cancelled when Lopu started its embedded rebase lane.

Changes

  • grant the caller-level maximum security-events: write permission required by the reusable controller
  • keep model-backed review read-only and alert mutations isolated in the controller writer job
  • reduce rebase-pr-stacks.yml to the exact internal rebase-pr-stack-ai repository-dispatch handoff
  • route push, PR, schedule, failed-check, conversation, and manual recovery through Lopu PR manager only
  • enforce both boundaries in the product caller contract
  • update README, regression checklists, and dated changelog
  • refresh structural and LLM-semantic Graphify output

Verification

  • node remix/scripts/workflow-caller-contract.mjs
  • Actionlint v1.7.7 on both affected workflows
  • Ruby YAML parse
  • git diff --check
  • Graphify incremental semantic extraction and regenerated report/aggregated HTML

The PR remains ready for review and does not merge or mutate develop directly. Its fresh PR run is the branch-specific proof that the unified listener compiles and creates controller jobs.

Final single-entry Lopu maintenance

This PR now also removes the three competing develop-side promotion/synchronization listeners and forwards the new maintenance inputs through Lopu PR manager. The protected components queue without cancelling active work, and explicit maintenance uses Lopu rather than separate Actions entries.

Merge controller follow-up PR #399 before evaluating this head. After #397 lands on main and main synchronizes into develop, inspect the remaining diff here; close this PR if the synchronization makes it empty, otherwise merge the develop-only residue.

Final single-entry audit

  • develop also has only seven deterministic thin listeners and no rebase/promotion/sync manager duplicates.
  • CI Control maintenance requests all dispatch Lopu PR manager with preserved typed inputs.
  • Structural and LLM-semantic Graphify outputs are refreshed for the exact branch head.

Post-merge activation dependency

Live activation testing after #397/#399 found two GitHub compiler ceilings now fixed in follow-ups: merge #403 into github-actions first, then #404 into main. Lopu's corrected main-push lane should synchronize that result into develop; re-check this PR afterward and close it if the diff becomes empty, otherwise merge only genuine develop residue. Its branch already contains the same split CodeQL listener and passes the seven-listener plus 20-test CI Control contracts.

@vercel

vercel Bot commented Aug 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
thingtime Ready Ready Preview Aug 27, 2026 5:32am
thingtime (develop) Ready Ready Preview Aug 27, 2026 5:32am

Request Review

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

🧹 Develop S3 preview removed

The PR-specific alias and every workflow-created develop deployment were removed when this PR closed.

The ordinary generated Vercel Preview remains available on the shared development runtime.

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Lopu repository review

Lopu reviewed this PR against develop as Thingtime's principal PR and repository manager. Using Claude Opus 5.

Lopu made justified improvements and pushed 699a58b to codex/lopu-listener-security-events-develop.

Lopu review — PR #398 "Let Lopu start CodeQL-backed lanes on develop"

Compared: head 043305a2 against base develop 25989863 (base is an
ancestor of head, so this is a pure fast-forward diff — no cross-merge noise).
Reviewed the 7 hand-written files; the remaining ~345k changed lines are
regenerated graphify-out/ artifacts and were treated as generated output.
Also read the protected github-actions controller checkout, the live check
state via gh pr checks, the run history for both all-branch listeners, and
the PR conversation.

Check state

All 22 reported contexts pass; nothing failed, cancelled, or timed out. No
CodeQL alerts are open on this head (398.json is []), so the disposition
file stays [] — no dismissals were warranted or written.

However, a real contract failure is hidden behind a non-blocking job.
remix/scripts/workflow-caller-contract.mjs exits 1 on this head. It runs in
web-ci.yml's product-contract-advisories job, which is warning-only by
design, so the PR stays green. The deterministic advisory comment
(5426260885, 2026-08-26) has been reporting it for a day.

Finding 1 — a retired listener was resurrected by an AI merge (fixed)

.github/workflows/all-branch.yml is present on this head, and the contract's
retired-list assertion fails on it:

AssertionError: all-branch.yml must stay retired; Lopu PR manager owns its
former public triggers

This directly contradicts the PR's own stated outcome ("develop uses Lopu
PR manager
as its single automatic principal repository workflow") and its
audit claim ("no rebase/promotion/sync manager duplicates"). It is also
contradicted by TESTING.md:206-208 on this very head, which requires that
"product branches contain no .github/workflows/all-branch.yml".

Root cause. Commit 3cddf23c ("Lopu: retire duplicate product maintenance
listeners", 2026-08-25 23:44) deleted both all-branch.yml and
rebase-pr-stacks.yml, and is an ancestor of this head. Merge f64ca330
("Merge main into develop (AI-resolved conflicts)", 2026-08-26 07:13) then
resurrected both files: its develop-side parent f51cb262 had them
deleted, its main-side parent 3f58b43f still had them, and the delete/modify
conflict was resolved by keeping the files. Later branch work re-removed
rebase-pr-stacks.yml but missed all-branch.yml. So this is a merge
regression, not an intentional retention.

Impact (not theoretical). The resurrected caller declares push: [develop, main], pull_request_target (7 types), schedule: 53 * * * *, and
workflow_dispatch. Every one of those is already covered by Lopu's
handoff_all_branch_event (push on develop/main/github-actions,
pull_request_target, and the identical 53 * * * * cron) plus
maintain_all_branch (workflow_dispatch with maintenance_operation: build-all). Two principal listeners therefore raced for the same
implementation-side concurrency group. Observed on this PR: run 33029705946
is all-branch.yml firing independently on pull_request_target and burning
4m43s. Repo-wide, 14 of the 15 most recent all-branch.yml runs are
cancelled — precisely the failure mode this PR set out to eliminate.

Change made. Deleted .github/workflows/all-branch.yml from the PR
worktree.

Why this belongs on this PR rather than a controller fix branch. The file
is the product-branch thin caller, which exists only on develop/main; it
has no counterpart to edit in the protected github-actions checkout. The
protected all-branch.yml implementation there is on: workflow_call: only,
is untouched by this change, and is still reached through Lopu's
maintain_all_branch job (uses: ./.github/workflows/all-branch.yml). PR #398
is also the PR whose entire purpose is this consolidation and which ships the
failing contract, so it is the correct home for the fix — not an unrelated
branch.

Merge-blocking risk checked. Branch protection is not readable with this
token (403), so required-context loss could not be confirmed directly. Two
things bound the risk: the check context emitted by this caller
(control-plane / Lopu builds and repairs the all branch) is also emitted by
Lopu's own maintain_all_branch job, and PR #408 merged into develop at
f51cb262 while the file was already absent. Worth a maintainer glance
regardless.

Finding 2 — duplicate changelog entry introduced by this PR (fixed)

This PR adds a second byte-identical copy of the "CI Control repository
maintenance now dispatches the unified Lopu workflow" entry to
remix/CHANGELOG.md. Base develop has exactly one copy (line 180); this head
has two (lines 180 and 193) — another artifact of the repeated AI-resolved
merges. Removed the duplicate.

Also added a dated [Unreleased] entry documenting the listener removal and
its cause, per AGENTS.md:303-305.

Finding 3 — workflow_dispatch input ceiling (reported only, not changed)

actionlint flags resolve-pr-conflicts.yml:28: GitHub documents a maximum of
10 workflow_dispatch inputs; the file declares 12 (pr_number, branch,
maintenance_operation, promotion_dry_run, promotion_lookback,
promotion_source_branch, promotion_target_branch, promotion_path_prefix,
rebase_cascade, detector_handoff, manual_retry, depth).

This is identical at base develop — not introduced here — and GitHub is
demonstrably not enforcing it: the last 30 resolve-pr-conflicts.yml runs
contain zero startup failures, and workflow_dispatch run 33042235734
succeeded. I deliberately made no change: trimming the input surface would
break the typed CI Control inputs this PR explicitly preserves, for a limit
that is not currently binding. Flagging it as drift worth tracking, since the
PR body already notes two GitHub compiler ceilings hit during activation.

Finding 4 — brittle new assertion (nit, not changed)

The new CodeQL assertion requires types: on the line immediately after
pull_request_target::

/^  pull_request_target:\n    types: \[opened, synchronize, reopened, ready_for_review, edited\]$/m

Its sibling assertion for the resolver tolerates interleaved comments via
(?: #.*\n)*. Since codeql-analysis.yml is heavily commented and this PR
itself edits comments right above that trigger, a future comment placed between
the key and types: would fail the contract for no real reason. Left as-is —
it passes today and changing it is not justified by this review.

Assessment of the rest of the diff

The two workflow YAML edits are comment-only; the on: blocks, permissions,
and job graphs are byte-identical to base. The contract-script changes are a
genuine improvement: two assertions that previously matched against the whole
file are now scoped to the correct section (resolverPermissions for
actions: write, resolverTriggers for the 53 * * * * cron), which is
strictly tighter, and duplicated assertions were collapsed. The
resolverPermissions slice moved after its consumers' definitions without
breaking ordering. README/TESTING/CHANGELOG prose matches the implemented
behaviour.

One stale claim to note: the PR body says "develop also has only seven
deterministic thin listeners". Seven files existed only because
all-branch.yml had been resurrected; the correct count is six, which is what
the contract now reports.

Validation run

  • node remix/scripts/workflow-caller-contract.mjswas exit 1 on the
    unmodified head; now passes: workflow caller contract: 6 thin listeners pinned to github-actions
  • node remix/scripts/web-ci-required-context-contract.mjs — passes:
    web-ci required-context contract: path-free protected listener
  • actionlint v1.7.7 on all 6 remaining listeners — clean except the
    pre-existing input-count note in Finding 3
  • python3 yaml.safe_load on all 6 remaining listeners — all parse
  • git diff --check — clean
  • Confirmed the protected github-actions all-branch.yml is
    on: workflow_call: only and still referenced by maintain_all_branch
  • Confirmed base develop fails the same contract assertion, establishing the
    regression as inherited rather than introduced by this branch's own work

Not done

graphify-out/manifest.json still indexes .github/workflows/all-branch.yml,
so the committed graph is marginally stale after the deletion. No graphify
binary is available in this environment, and hand-editing a 338k-line generated
artifact would be worse than leaving it. Lopu owns post-merge Graphify refresh
(README:203), which reconciles this on the normal lane.

View Lopu workflow run

github-actions Bot added a commit that referenced this pull request Aug 26, 2026
# Conflicts:
#	graphify-out/cache/semantic/6a4551a09e20ba397a3d56c050644912b91ed30fc9852a637ba0a673ce1641ba.json
github-actions Bot added a commit that referenced this pull request Aug 26, 2026
# Conflicts:
#	graphify-out/cache/semantic/6a4551a09e20ba397a3d56c050644912b91ed30fc9852a637ba0a673ce1641ba.json
github-actions Bot added a commit that referenced this pull request Aug 26, 2026
# Conflicts:
#	graphify-out/cache/semantic/6a4551a09e20ba397a3d56c050644912b91ed30fc9852a637ba0a673ce1641ba.json
github-actions Bot added a commit that referenced this pull request Aug 26, 2026
# Conflicts:
#	graphify-out/cache/semantic/6a4551a09e20ba397a3d56c050644912b91ed30fc9852a637ba0a673ce1641ba.json
github-actions Bot added a commit that referenced this pull request Aug 26, 2026
# Conflicts:
#	graphify-out/cache/semantic/6a4551a09e20ba397a3d56c050644912b91ed30fc9852a637ba0a673ce1641ba.json
@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

🤝 Merged develop into codex/lopu-listener-security-events-develop — conflicts auto-resolved by Lopu's PR manager.

Conflicted files:

  • .github/workflows/codeql-analysis.yml
  • .github/workflows/resolve-pr-conflicts.yml
  • README.md
  • TESTING.md
  • graphify-out/GRAPH_REPORT.md
  • graphify-out/graph.json
  • graphify-out/manifest.json
  • remix/CHANGELOG.md
  • remix/scripts/workflow-caller-contract.mjs

graphify-out/ was reset wholesale to the develop side (repo rule: one side, never mixed — the graph merge driver is unavailable in CI).

Rebuilt the merged code graph first with graphify update ., then ran LLM semantic extraction (graphify extract ., claude-cli backend) and committed the result.

Please review the merge commit before relying on it.

github-actions Bot and others added 2 commits August 26, 2026 13:41
…solved conflicts)

Conflicted paths: .github/workflows/codeql-analysis.yml, .github/workflows/resolve-pr-conflicts.yml, README.md, TESTING.md, graphify-out/GRAPH_REPORT.md, graphify-out/graph.json, graphify-out/manifest.json, remix/CHANGELOG.md, remix/scripts/workflow-caller-contract.mjs

Resolved by the resolve-pr-conflicts workflow: https://github.com/lopugit/thingtime/actions/runs/32959095625

Co-Authored-By: Lopu <github-actions[bot]@users.noreply.github.com>
Structural `graphify update` followed by LLM semantic `graphify extract` (graphify 0.9.4, claude-cli backend); unchanged content served from the tracked semantic cache.

Refreshed by the resolve-pr-conflicts workflow: https://github.com/lopugit/thingtime/actions/runs/32959095625
@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

🤝 Merged develop into codex/lopu-listener-security-events-develop — conflicts auto-resolved by Lopu's PR manager.

Conflicted files:

  • README.md
  • TESTING.md
  • graphify-out/GRAPH_REPORT.md
  • graphify-out/cache/semantic/0075b70deb734762e680e31448d5d7ae4b722ff8da30f12d46758df11755b4ed.json
  • graphify-out/cache/semantic/de8ff3e2ff6a82e160a628793b1662887bf981d5c49910aa565b93b280999024.json
  • graphify-out/cache/semantic/e0dd61d9399bd7e29034ca3892fd7ddf5b24823ff25d07103510b7843355207c.json
  • graphify-out/graph.json
  • graphify-out/manifest.json
  • remix/scripts/workflow-caller-contract.mjs

graphify-out/ was reset wholesale to the develop side (repo rule: one side, never mixed — the graph merge driver is unavailable in CI).

Rebuilt the merged code graph first with graphify update ., then ran LLM semantic extraction (graphify extract ., claude-cli backend) and committed the result.

Please review the merge commit before relying on it.

github-actions Bot and others added 2 commits August 27, 2026 01:11
…solved conflicts)

Conflicted paths: README.md, TESTING.md, graphify-out/GRAPH_REPORT.md, graphify-out/cache/semantic/0075b70deb734762e680e31448d5d7ae4b722ff8da30f12d46758df11755b4ed.json, graphify-out/cache/semantic/de8ff3e2ff6a82e160a628793b1662887bf981d5c49910aa565b93b280999024.json, graphify-out/cache/semantic/e0dd61d9399bd7e29034ca3892fd7ddf5b24823ff25d07103510b7843355207c.json, graphify-out/graph.json, graphify-out/manifest.json, remix/scripts/workflow-caller-contract.mjs

Resolved by the resolve-pr-conflicts workflow: https://github.com/lopugit/thingtime/actions/runs/33017062645

Co-Authored-By: Lopu <github-actions[bot]@users.noreply.github.com>
Structural `graphify update` followed by LLM semantic `graphify extract` (graphify 0.9.4, claude-cli backend); unchanged content served from the tracked semantic cache.

Refreshed by the resolve-pr-conflicts workflow: https://github.com/lopugit/thingtime/actions/runs/33017062645
@github-actions
github-actions Bot temporarily deployed to develop-pr-398 August 27, 2026 01:19 Destroyed
@github-actions

Copy link
Copy Markdown
Contributor

Lopu review — a retired listener came back through a merge

Lopu (principal PR/repository manager) reviewed 043305a2 against develop 25989863.

All 22 checks pass and there are no open CodeQL alerts on this head, so the disposition file stays []. But there is a real failure hiding behind a warning-only job.

all-branch.yml is back on develop, and it shouldn't be

remix/scripts/workflow-caller-contract.mjs exits 1 on this head:

AssertionError: all-branch.yml must stay retired; Lopu PR manager owns its former public triggers

It runs in web-ci.yml's product-contract-advisories job, which is non-blocking by design — so the PR stayed green and the deterministic advisory (comment 5426260885) has been quietly reporting this since 2026-08-26.

This contradicts the PR's own Outcome ("develop uses Lopu PR manager as its single automatic principal repository workflow"), its audit line ("no rebase/promotion/sync manager duplicates"), and TESTING.md:206-208 on this very head, which requires that product branches contain no .github/workflows/all-branch.yml.

Root cause: an AI-resolved merge undid a deletion

  • 3cddf23c ("Lopu: retire duplicate product maintenance listeners", 08-25 23:44) deleted both all-branch.yml and rebase-pr-stacks.yml. It is an ancestor of this head.
  • f64ca330 ("Merge main into develop (AI-resolved conflicts)", 08-26 07:13) resurrected both: develop-side parent f51cb262 had them deleted, main-side parent 3f58b43f still had them, and the delete/modify conflict resolved to keep.
  • Later branch work re-removed rebase-pr-stacks.yml but missed all-branch.yml.

So this was a merge regression, not a deliberate retention.

It was actually costing runs

The resurrected caller declares push: [develop, main], pull_request_target (7 types), schedule: 53 * * * *, and workflow_dispatch. Every one is already covered by Lopu's handoff_all_branch_event (push on develop/main/github-actions, pull_request_target, the identical 53 * * * * cron) plus maintain_all_branch (workflow_dispatchbuild-all).

Two principal listeners raced for the same implementation-side concurrency group:

  • On this PR, run 33029705946 is all-branch.yml firing independently on pull_request_target, burning 4m43s.
  • Repo-wide, 14 of the 15 most recent all-branch.yml runs are cancelled — exactly the failure mode item 2 of this PR set out to fix.

What I changed

  1. Deleted .github/workflows/all-branch.yml. The protected github-actions implementation is on: workflow_call: only, is untouched, and is still reached via maintain_all_branch (uses: ./.github/workflows/all-branch.yml) — so Lopu's all-branch lane is unaffected. This is the product-branch thin caller, which has no counterpart in the protected controller, and this is the PR that both owns the consolidation and ships the failing contract, so the fix belongs here.
  2. Removed a duplicate changelog entry. This PR added a second byte-identical copy of "CI Control repository maintenance now dispatches the unified Lopu workflow" (develop has one at line 180; this head had two). Another merge artifact.
  3. Added a dated [Unreleased] entry recording the removal and its cause, per AGENTS.md:303-305.

Validation

Check Result
workflow-caller-contract.mjs was exit 1 → now 6 thin listeners pinned to github-actions
web-ci-required-context-contract.mjs path-free protected listener
actionlint v1.7.7 (6 listeners) clean apart from the pre-existing note below
YAML parse (6 listeners) all parse
git diff --check clean

I also confirmed base develop fails the same assertion, so the regression is inherited rather than introduced by this branch's own work.

Two things I deliberately did not change

  • resolve-pr-conflicts.yml declares 12 workflow_dispatch inputs; GitHub documents a max of 10. actionlint flags it, but this is identical at base and GitHub is demonstrably not enforcing it — zero startup failures in the last 30 runs, and dispatch run 33042235734 succeeded. Trimming the input surface would break the typed CI Control inputs this PR explicitly preserves, for a limit that isn't currently binding. Flagging as drift, not fixing.
  • The new CodeQL assertion is brittle: it requires types: immediately after pull_request_target:, while its resolver sibling tolerates interleaved comments via (?: #.*\n)*. Given how heavily commented that file is — and that this PR edits comments right above that trigger — a future comment there would fail the contract for no real reason. Passes today; not worth churning.

Notes

  • The body's "develop also has only seven deterministic thin listeners" was true only because all-branch.yml had been resurrected. The correct count is six.
  • graphify-out/manifest.json still indexes the deleted file. No graphify binary here, and hand-editing a 338k-line generated artifact would be worse; Lopu's post-merge Graphify refresh (README:203) reconciles it.
  • Worth a maintainer glance: branch protection isn't readable with this token, so I couldn't confirm no required context is lost. Mitigating evidence — control-plane / Lopu builds and repairs the all branch is also emitted by Lopu's own job, and PR Lopu: unify develop PR automation and every-head wakeup #408 merged into develop at f51cb262 while the file was already absent.

The rest of the diff looks right. Both workflow YAML edits are comment-only (on: blocks, permissions, and job graphs are byte-identical to base), and the contract-script changes are a genuine tightening — two assertions that previously matched the whole file are now scoped to the correct section.

@lopugit

lopugit commented Aug 27, 2026

Copy link
Copy Markdown
Owner Author

Closing as superseded by the unified listeners and protected manager now live on develop/main. The current listener already covers all-branch PR CodeQL plus newer first-party workflow_run failure signals; merging this older branch would restore obsolete workflow copies and regress that coverage. No unique product behavior remains.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant