Repository navigation
test(schedules): pin the row a copy writes against the dsh-schedule task type (#1320) - #1349
Merged
Merged
Conversation
…ask type (#1320) `copyRow` builds the stored task row itself instead of copying one it holds. The fake service accepts whatever literal it is handed, so a required key added upstream would fail silently at runtime. Decode the row it writes against the pinned `@deepseek-ai/dsh-schedule@0.2.0-rc.2` `tasks.valueSchema`, and pin the keys it supplies, so that drift fails here instead. No source change: the assertion covers the row as `copyRow` already writes it.
The first push reached enqueue-guard before the body was corrected, and a pull request body edit does not re-trigger that workflow: only [opened, synchronize, reopened, labeled, unlabeled, ready_for_review] do. Same tree, new tip, so the guard judges a body whose checkpoint names this head.
HugoXK
pushed a commit
to HugoXK/FlyBot
that referenced
this pull request
Oct 27, 2026
…hinkFlowLab#1348 prose (ThinkFlowLab#1350) (ThinkFlowLab#1352) Owner: Dev Reviewer: Reviewer Fixes ThinkFlowLab#1350 Fixes ThinkFlowLab#1354 Tip SHA: a09f330 **Executor decision B: remove the frozen-branch seal whole, and keep what `ThinkFlowLab#1350` asked for that is not about the seal.** `ThinkFlowLab#1354`'s repair — read the list from `main`, list `ThinkFlowLab#1328`'s number in code — is on this branch's earlier commits and is now moot: with no seal there is nothing to read and no number to list. ## Reproduce **The seal could not hold.** `ThinkFlowLab#1328` (branch `dev4/1265-step2-one-board`, base `8d0a99c1`) entered the queue at `06:01:1xZ`, was turned draft, and merged at `06:03:21Z` — the seal never answered it: the base read found no document, and its branch matched no listed prefix. `ThinkFlowLab#1350`/`ThinkFlowLab#1354` patched the reading so the next such pull request would be refused. The owner then decided the mechanism goes instead of being patched: the cost of the seal (a queue-entry stop re-read on every `labeled` event, a policy document no pull request may edit, a number list that had to live in code) was not worth what it caught, and it never was a permission boundary — a direct push, an admin merge or a renamed branch walked past it. **The check that judges this pull request is `main`'s copy, and that copy still carries the seal.** That is why the document is not deleted here. The first push of this change (`8f97e4f5`) deleted `.github/agent/frozen-branches.json` along with the code; the check run at that head answered `do not enqueue ThinkFlowLab#1352: frozen: .github/agent/frozen-branches.json is not editable by a pull request`. `enqueue-guard.yml` checks out `ref: main` and never runs pull request code, so any diff that deletes or edits that document is refused by the seal until the seal itself is on `main`. Removing the reader and removing the document cannot travel in one pull request; this one removes the reader, keeps the document byte-identical to the previous tip, and the deletion is the follow-up pull request. ## What changed 1. **`.github/scripts/enqueue-guard.mjs` — the whole path, not a branch of it.** `FROZEN_PATH`, `FROZEN_REASON`, `FROZEN_EDIT_REASON`, `FROZEN_PULL_REQUESTS`, `frozenList()`, `frozenRefusal()` and the `decidePull` call site with its early return are gone; `decidePull` returns `{ decision, pull, repo, pr }` from `guard()` alone. No dead import, no dead export, no always-true branch left. `guard()`, `recordOnlyAt` and every other rule are untouched. 2. **The nine cases that existed only for the seal are deleted** — the five `ThinkFlowLab#1344` cases, the `ThinkFlowLab#1350` `merged`-short-circuit case (it pinned the seal's own ordering and has no meaning without it) and the three `ThinkFlowLab#1354` cases. The fixture loses the `/contents/` answer and the `frozen`, `prNumber` and `baseSha` knobs and the `BASE` constant that fed them: nothing reads them now, so none is left dangling. **No other test was touched** — every remaining assertion is byte-identical. 3. **`AGENTS.md` — the section is gone.** `#### Untrusted external agent branches` goes whole: the three `Do not` bullets, the `dequeuePullRequest` paragraph, the "never the baseline for `generate`" paragraph and the Chinese release sentence. What `ThinkFlowLab#1350` asked for that is *not* about the seal stays: rule 7 now matches `accountRefusal()` — only `type === 'User'` writes a conclusion, a report with **no `type` at all** is refused too, the account and its text stay as a note in `judged`, and the refusal's sentence stays `no Verifier report names the tip <sha>`. 4. **`.github/agent/frozen-branches.json` is unchanged here** — `cmp` against the previous tip is identical. Nothing reads it after this change; it is deleted in the follow-up pull request, which is possible only once `main` no longer carries the rule that refuses that deletion. 5. **`ThinkFlowLab#1354` is not needed any more.** Nothing is read from `main` or from a base, so the base-vs-main defect cannot recur; the issue is closed by this pull request as "the mechanism was removed", not by a fix. ## What I ran On `/data/w1352`, a tree extracted from the repository's own tarball of this branch's previous tip `c6ba9a09`, with `git` 2.53.0 and its `libexec/git-core` on `PATH`: - `node --test ".github/scripts/*.test.mjs"` → **543 / 543 pass** (this branch was 552 before this change; `−9` is exactly the nine cases removed with the seal). - `node .github/scripts/enqueue-guard.test.mjs` → **88 / 88 pass** (was 97; `−9` again). - `node .github/scripts/testing-layers.mjs --check` → `440 test file(s) in 16 workflow(s)`, every file and every workflow classified. - `node .github/scripts/check-mojibake.mjs` → `ok — 0 occurrences of U+FFFD in 1155 text file(s)`. - `diff -rq` against `c6ba9a09` → exactly three files, all listed under Scope. `cmp` on the JSON document: identical. - `grep -rn 'frozen-branches\|frozenRefusal\|frozenList\|external agent branch'` over `*.mjs`, `*.md`, `*.json`, `*.yml` → **0** (22 lines at the previous tip). The document file exists but no text names it. - GitHub's own read of the pull request: `3 files, +3 / −116`. ## Red without the source change **A deletion has nothing that can go red.** The nine cases were removed together with the code they pinned, so restoring the source would restore the tests and the suite would be green either way — claiming a red here would be a fabrication. The mechanical substitutes, each run: 1. **The grep.** The command above returns no line and exit status 1 (22 lines at the previous tip). 2. **The module's exports.** `import()` of `enqueue-guard.mjs` names exactly `decidePull, guard, main, recordOnlyAt`; `frozenRefusal` is `undefined`. The export does not exist to be called. 3. **The same fake `gh`, both tips, through the printed reader.** A pull request on a listed prefix branch with no conclusion, run through `main()`: - previous tip: `REFUSE — do not enqueue ThinkFlowLab#566: frozen: external agent branch; owner decision pending` - this tip: `REFUSE — do not enqueue ThinkFlowLab#566: no Verifier report names the tip aaaa…; no checkpoint: …` The seal's sentence no longer appears in any decision; the pull request is judged by the ordinary rules, which is the point of B. 4. **The one genuine red this change can show, and it did:** main's own seal refused this pull request while its diff deleted the document — the `8f97e4f5` run quoted under Reproduce. That red is real and is the reason the document is not in this diff. ## Not run - `npm run verify`: nothing under `core/`, `plugins/` or `apps/` is touched. - `generate` / `scripts/ds-bot-patches.mjs check`: `patches/` is untouched. - `check-arch-docs`: its rule reads `core/` changes; there are none. - A live queue entry: the next real enqueue exercises `decidePull`; a pull request cannot stage one without merging. ## Risk - **The seal is gone, so its refusal is gone.** A branch under a listed prefix, or a body carrying the agent's PR-body marker, is now judged by the ordinary rules only; one that carries a PASS at its tip and a clean body can enter the queue. That is the owner's decision, and the seal never stopped a direct push or an admin merge anyway. - **The document outlives its reader for one pull request.** Between this merge and the follow-up, `.github/agent/frozen-branches.json` sits in the tree with nothing reading it; nothing can act on it, and the follow-up deletes it. Anyone reading the tree in that window should read it as a stale config, not a live rule. Deleting the reader and deleting the file cannot travel in one pull request: `enqueue-guard.yml` is `pull_request_target` with `ref: main` and never runs pull request code, so main's copy of the seal refuses any diff that edits or deletes the document. That is a mechanical constraint of the check, not a choice made here. - **`ThinkFlowLab#1328` stays merged.** This removes the mechanism, not that merge; nothing here reopens or reverts it, and `ThinkFlowLab#1346`'s branch is untouched. ## Scope - `.github/scripts/enqueue-guard.mjs` — removal only. - `.github/scripts/enqueue-guard.test.mjs` — removal of the nine seal cases and of the fixture knobs they used. - `AGENTS.md` — the external-agent section deleted; rule 7's `accountRefusal()` alignment kept. Unchanged, deliberately: `.github/agent/frozen-branches.json`. Not touched: `core/`, `patches/`, `package*`, `.github/workflows/pass-label.yml`, tier calculation, and every tip belonging to `ThinkFlowLab#1328`, `ThinkFlowLab#1346`, `ThinkFlowLab#1348`, `ThinkFlowLab#1342`, `ThinkFlowLab#1349`. ## Checkpoint <!-- flybot:checkpoint --> ```json { "pr": 1352, "claim": "Dev", "issue": 1350, "summary": "Executor decision B: the frozen-branch seal is removed whole, not patched. enqueue-guard.mjs loses the four constants, frozenList(), frozenRefusal() and the decidePull call site; the nine cases that only pinned the seal go with the fixture knobs they used; the AGENTS.md external-agent section goes, while ThinkFlowLab#1350's rule-7 alignment stays. ThinkFlowLab#1354's fix is moot with no list to read. The document itself is not in this diff: main's own check refuses any pull request that edits it, so it stays byte-identical for a follow-up.", "files": [".github/scripts/enqueue-guard.mjs", ".github/scripts/enqueue-guard.test.mjs", "AGENTS.md"], "checks": { "ran": "node --test \".github/scripts/*.test.mjs\" (543/543); enqueue-guard 88/88; testing-layers --check; check-mojibake; grep for the seal names; cmp of the JSON document", "result": "green", "at": "a09f330ab2b298fc1095884a7f79dd086435c26f" }, "next": "none — ready for review at this tip" } ``` <!-- /flybot:checkpoint -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Written-by: Dev3
Owner: Dev3
Reviewer: Reviewer2
Tip SHA: 5522794
Fixes #1320
Reproduce
copyRow(core/src/host/schedules.js:368-376) does not copy a row it holds: it builds one at:374—{ sessionId, record: { ...source.record, id }, status, deliveryHistory }— andputs it through a private@deepseek-ai/dsh-scheduleAPI. The test fake accepts whatever literal it is handed, so a required key that moves upstream would not fail a rename or a copy; it would fail silently at runtime. The upgrade note abovemoveSchedulesnames the private calls to re-check but not the row keys a copy must supply, which is exactly the gap the PASS on#1307described and#1320tracks (option 1 of the issue: assert against the pinned package's row type).What changed
core/test/schedules.test.js: one case,#1320: the row a copy writes matches the pinned dsh-schedule task type. It creates a schedule, swaps the fake's source record for a realcreateEveryScheduleRecord(...)from@deepseek-ai/dsh-schedule(the fake keeps atimingfield no stored record has), copies it to another Bot, then assertsscheduleDomain.tables.tasks.valueSchema.safeParse(row).successfor the row the copy wrote, pins the keys it supplies (deliveryHistory,record,sessionId,status), and pins that itsrecorddiffers from the source's only inid. The pinned version is written in the comment:@deepseek-ai/dsh-schedule@0.2.0-rc.2.patches/ds-bot/0001-core-fixes.patchregenerated withnode scripts/ds-bot-patches.mjs generate; it carries only this test hunk (plus the hunk's line count). No product code changed, as the issue's scope allows.What I ran
node --test test/schedules.test.jsincore/→# tests 29 / # pass 29 / # fail 0node scripts/ds-bot-patches.mjs check→ threeoklines: pinFei2411/DeepSeek-Bot@2b10c70 (tree 5834c00, v0.1.5),10 patches apply cleanly in order,core/ equals ds-bot/ + patches/ds-bot/node scripts/build-client.mjs --check→ exit 0npm run lint→ 70 warnings, 0 errors (same as base;arch-docsreports "cannot diff against origin/main" locally only, nooriginremote in this checkout)Red without the source change
This is a test-only issue: zero source changes here — the knife is a temporary source edit, measured on this tip and then reverted.
Knife: in
core/src/host/schedules.js:374, make the written row carry a key the pinned type does not have —record: { ...source.record, id, timing: {} }— then run the file:One failure and it is the new case: the field-level assertions of
#1287/#1319do not see the extra key, only the strictvalueSchemadoes. Restored (cmpagainst the saved copy: identical, andgit statusshows only the test file), the file is back to# tests 29 / # pass 29 / # fail 0.Not run
core/suite locally: CItests-okruns it at this tip, and the diff is one test file plus its generated mirror.index.js, client orsrc/host/behaviour change.Risk
Test-only: no runtime behaviour moves, and the generated patch only mirrors the test file. The case pins a current contract (the row shape
copyRowsupplies today) against a pinned package version — when the package moves, this case fails first, which is the point; a deliberate row-shape change must update it together with themoveSchedulesupgrade note.Checkpoint
{
"pr": 1349, "claim": "Dev3", "issue": 1320,
"summary": "Adds one case that decodes the row copyRow writes against the pinned @deepseek-ai/dsh-schedule@0.2.0-rc.2 task type instead of trusting the fake service. It swaps the fake's source record for a real createEveryScheduleRecord one, copies it to another Bot, and asserts the written row satisfies tasks.valueSchema. It also pins the keys a copy supplies and that the copied record differs from the source only in id. No product code changes; the assertion covers the row as it is written today.",
"files": ["core/test/schedules.test.js", "patches/ds-bot/0001-core-fixes.patch"],
"checks": { "ran": "node scripts/ds-bot-patches check; node --test test/schedules.test.js", "result": "green", "at": "55227943da9ed2eb01a503defc79e870ac22b2ea" },
"next": "none — ready for review"
}