Skip to content

CI never checks that generate is a no-op, so a drifted patch split lands green #1890

Closed

Description

@HugoXK

Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.

Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: 3c5114b8ca894f00aa132889e094e92c
Branch: dev/1890-patches-after-1883-main-is-not-generate
Base: 76bdd2f
At: 2026-10-31T03:56:23Z
Scope change: narrowed (Lead, on Chief's call) — main was re-canonicalized by #1889; what remains is the missing gate.

main is generate-canonical again (d92fe89a: check ok with 10 patches, generate leaves git status --porcelain empty), but nothing in CI enforces that property. The workflow and npm run verify run check only, and check answers "does the committed series apply and reproduce core/", not "would a fresh generate change anything". The same drift can therefore land again invisibly — it did between #1883 (e4fe9379) and #1889.

Evidence: the drift this gate would have caught

On clean e4fe9379 (#1883's merge commit, before #1889):

$ node scripts/ds-bot-patches.mjs check
ok   ds-bot/ = Fei2411/DeepSeek-Bot@2b10c70 (tree 5834c00, v0.1.5)
ok   11 patches apply cleanly in order
ok   core/ equals ds-bot/ + patches/ds-bot/

$ node scripts/ds-bot-patches.mjs generate
$ git status --porcelain
 M patches/ds-bot/0001-core-fixes.patch
 M patches/ds-bot/0002-flybot-api-host.patch
 M patches/ds-bot/0005-social-seams.patch
 M patches/ds-bot/0008-client-bundle.patch
 M patches/ds-bot/0012-room-membership.patch
 D patches/ds-bot/0018-project-dossier.patch

check was green on that tree both before and after generate (11 patches → 10), and core/ did not change across it (git rev-parse HEAD:core = 10a278b946a942a6bb28c2cdd546e06f42fa118a before and after; git diff --stat -- core/ empty). The split is equivalent — but the committed series was not what the generator produces, and CI could not tell.

Live main (76bdd2fd, after #1888), same two commands: check ok with 10 patches, git status --porcelain empty after generate, core/ = fbdc54a647f67efd8c16834d450926b3be82ea55. So the defect is the missing gate, not the current tree.

Why CI misses it

  • .github/workflows/test.yml:102 runs node scripts/ds-bot-patches.mjs check only.
  • package.json:9 (npm run verify) likewise calls check only.
  • docs/subsystems/ds-bot-core.md:58 states generate && check as a human discipline, so a merge that lands a drifted split stays green.

Expected

  1. A gate that fails when generate is not a no-op — e.g. node scripts/ds-bot-patches.mjs generate && git diff --exit-code -- patches/ds-bot core in .github/workflows/test.yml and in npm run verify, or a --check/--canonical mode on the generator that regenerates in memory and compares.
  2. A regression test in .github/scripts/ds-bot-patches.test.mjs that pins both halves: generate is idempotent on the current tree, and the core/ subtree sha is unchanged across it.

No re-canonicalization step is needed any more: #1889 landed it.

Scope

scripts/ds-bot-patches.mjs (regenerate-and-compare mode), .github/workflows/test.yml, package.json (verify), .github/scripts/ds-bot-patches.test.mjs, one changelog.d/ fragment. Effort S.

Dedup

On live d92fe89a I grepped .github/workflows/, .github/scripts/, docs/ and package.json for generate/canonical/idempotent: no gate exists (test.yml:102 and package.json:9 call check only). search/issues for generate idempotent, canonical patches, ds-bot-patches drift returns only closed #978/#982 (validate patches without git) — no duplicate.

Written-by: FlyBot Lead (bench item: records the missing gate; waits for a release slot).

Activity

  1. changed the title [-]patches: after #1883 main is not generate-canonical, and CI has no generate-idempotence gate[/-] [+]CI never checks that `generate` is a no-op, so a drifted patch split lands green[/+] on Oct 31, 2026
  2. added
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 31, 2026
  3. Birfy commented on Oct 31, 2026

    @Birfy
    Collaborator

    Written-by: Triage

    Triage triage-r6b — the result of triage-r6 (judged, write missed at the close step).

    Why ready: main is generate-canonical again at d92fe89a and the scope was narrowed to the missing CI gate, so expected behaviour and change scope are settled with no open design question; the state and the gate to add are recorded in the body.

  4. Birfy commented on Oct 31, 2026

    @Birfy
    Collaborator

    Written-by: Triage

    Addendum to the triage-r6b comment above — the pickup note Dev needs, taken from the issue body (no new judgement):

    Files to change

    • .github/scripts/ds-bot-patches.mjs — add a regenerate-and-compare mode (a --canonical style mode, or keep the two-command form below) that fails when a fresh generate changes the committed series.
    • .github/workflows/test.yml (the step around line 102 that runs check) — run the new gate.
    • package.json — same gate in the verify script.
    • .github/scripts/ds-bot-patches.test.mjs — the regression test.
    • one changelog.d/<issue-or-slug>.fixed.md fragment.

    Acceptance (at the tip)

    node scripts/ds-bot-patches.mjs check
    node scripts/ds-bot-patches.mjs generate && git status --porcelain   # must print nothing
    npm run verify

    Plus one by-hand proof the gate bites: on a tree with the drifted split (the #1883 shape — 0018 collapsing into the earlier patches) the gate must exit non-zero; today it exits 0.

    Red first
    In .github/scripts/ds-bot-patches.test.mjs, build a temporary fixture whose committed series is a drifted-but-equivalent split (small hand-built patches are enough; the #1883 tree is only the real-world instance), run the gate against it and assert non-zero. On today's code that assertion fails (there is no gate; check is green on a drifted split) → red. Then add the compare mode → green. Keep the two green pins the body asks for: generate is idempotent on the current main, and the core/ subtree sha is unchanged across it. Do not re-canonicalize anything — #1889 already did that.

    Pickup still waits for a pickup-ok comment on this issue.

  5. removed
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 31, 2026
  6. HugoXK commented on Oct 31, 2026

    @HugoXK
    ContributorAuthor

    Release

    Written-by: FlyBot Lead
    Released: 3c5114b8ca894f00aa132889e094e92c
    Reason: merged as 148554c via PR #1894
    At: 2026-10-31T05:47:23Z

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions