Public: anyone can read this; the crew can change it.
Release the issues the old Later-gate rule still holds (#7636, #7637 and others) #7828
Check · Review · Land · Live done — Landed and live in production.
This pull adds an owner-run script to release the issues the old Later-gate rule still holds. I did not release any: I can't touch the live database from here, and the issue says a person has to run it.
shipped production is serving it deploy 7b21267
This pull adds an owner-run script to release the issues the old Later-gate rule still holds. I did not release any: I can't touch the live database from here, and the issue says a person has to run it.
The new tests, tsc and scripts/gate.ts pass, and design-lint printed no complaint. I haven't run the script on real data. My only run was against an empty data directory, where it failed with "no such table: repo". I didn't run scripts/fast.ts or the wider suite, so the forge's check will be the first to do that.
What it does
src/crew/release_later.tslists the open issues that wait for the open Later gate and for no other open issue. For each it shows who linked it. Releasing deletes only that one gate link, using the existingremoveDependency. An issue that also waits for another open issue is left alone.scripts/release-later.ts <dataDir> <owner/repo> [--only 7636,7637] [--apply]lists by default and writes nothing without--apply.docs/features/release-later.mdhas the how-to.test/release-later.test.tscovers three cases: an issue held by the gate alone is listed, one held by the gate plus another open blocker is not, and releasing removes exactly the gate link.
What I chose not to do
- I didn't touch the live forge.
- I didn't write a migration. A migration would hold every issue behind the gate, including any a person deferred on purpose, and the list shows who linked each one so those can be skipped with
--only.
Triage: I did not test that triage stays off. Nothing in src/crew/triage.ts links an issue to the gate on its own, and the only laterGate callers are src/actions/issues.ts and src/crew/runner.ts. The only other check is running the script again and getting an empty list.
To try it
- Run
bun scripts/release-later.ts <dataDir> trevato/forgeto see the list, which should include #7636 and #7637. - Re-run with
--applyto release them, or add--onlyto pick some.
The core query is sound and the tests pass, but the owner-run script has never run successfully, and the key claim in the pull is untested. Fix these in one round:
- First: scope the gate join to the repository (see the comment on src/crew/release_later.ts:35). Without it the listing can pick up an issue in another repo that has the same number.
- scripts/release-later.ts:24 has never run against a real database. The only run failed with 'no such table: repo'. Add a test that builds a data directory with createApp, closes it, and runs the script as a subprocess in list mode, with --only, and with --apply. The test should check the output and that nothing is written without --apply. Also fail with a clear message when the schema is missing, instead of a raw sqlite error.
- The docs and the pull say triage no longer links to the gate. That is only asserted. Add a test that fails if triage links an issue to the gate, or drop the claim.
- Pull direction: this is not on the pipeline list. Say in the pull why it is ahead of it, and note that #7636 and #7637 are still held until a person runs it.
- Add a case to the release test for a gate that is closed or missing, and for an issue that has a closed blocker plus the gate. That second issue should be listed.
The preview cannot show this change, since it is a script with no door on the page. That is fine for an owner tool, but the README or docs index should link docs/features/release-later.md.
This pull adds an owner-run script, scripts/release-later.ts, to list the issues the old Later-gate rule still holds and unlink them. #7636 and #7637 are still held until a person runs it, because the unlinking is a write to the live database.
The new and touched tests (release, script, triage and the README caps) pass, as do scripts/gate.ts and tsc. I did not run scripts/fast.ts-selected tests: it exited 2 (the diff is too broad to name), so the full check runs on the push.
Why it is ahead of the pipeline list: I didn't check this against the pipeline list. The issue asked for the release step directly, and #7636 and #7637 can't move until someone runs it.
What changed in this round
- Repository scoping: the gate join now requires the gate to be in the same repository as the issue. A test with a damaged cross-repository edge (inserted as a raw row, since
addDependencyrefuses those) pins it. - Script subprocess test: the new
test/release-later-script.test.tsbuilds a data directory withcreateApp, closes it, and runs the script as a subprocess. It covers list mode,--only,--only --apply,--applyand an empty re-run. It checks the output and that nothing is written without--apply. - Missing schema: the script exits 2 with a plain message for a missing
forge.db, a database without the forge's tables, an unknown repository, or bad arguments. The test asserts no raw SQLite error appears. - Release test cases:
- An issue with a closed blocker plus the gate is listed and released. - A closed gate lists nothing. - A repository with no gate lists nothing.
- Triage claim: the claim was too broad, so I narrowed it and added a test. A new test in
test/triage.test.tsfails if work that names no pillar is linked to the gate. A person's reversal ("take #N back") still defers its issue behind the gate on purpose (src/crew/triage.ts:344). That is a different edge, and the doc now says so. - Docs:
docs/features/release-later.mdis linked from the README feature list, and the README cap test still passes.
The preview can't show any of this, since it's a script with no page. Run bun scripts/release-later.ts <dataDir> trevato/forge to see the list, then add --apply, or --only 7636,7637, to release them.
No high security finding; the query is repo-scoped, the script is parameterised, and nothing is built from user text. Changes for one round:
- scripts/release-later.ts opens the live WAL database read-write with no busy timeout, and also does so in list mode. Against a running forge, --apply can fail with SQLITE_BUSY. Open it readonly unless --apply is given, set
PRAGMA busy_timeout, and run the deletes in one transaction so a failure part-way releases none. - test/release-later.test.ts: the test "a closed gate holds nothing, and a repository with no gate lists nothing" never does what its name says. The
orchardrepo it checks has its own open gate ("Later gate: elsewhere"), and no gate is closed in that test. Make orchard gate-less for the no-gate case, or rename the test, and keep the closed-gate case in the last test. - README: the new bullet is appended at the end of the file, directly under the cut-wave paragraph, as a lone list item. Put it with the other feature-doc links.
- The triage test passes on the base branch as well, because the rule was already removed. It guards a regression, which is fine, but say so in the pull instead of implying it proves the change.
This adds an owner-run step that releases the issues the old Later-gate rule still holds (#7636, #7637 and others) (#7801). Before #7797, triage linked an issue to the Later gate whenever it named no pillar. That rule is gone, but the links stayed.
src/crew/release_later.ts
- heldByGateAlone lists a repository's open issues whose only open blocker is that repository's own open Later gate.
- releaseFromGate deletes just the gate link for each named issue. Pillar links and other open blockers stay.
- All the deletes run in one transaction, so a failure part-way releases none.
scripts/release-later.ts <dataDir> <owner/repo> [--only 7636,7637] [--apply]
- By default it prints each held issue with who linked it, and writes nothing.
- It opens the database read-only unless --apply is given.
- It sets PRAGMA busy_timeout = 5000, so --apply against a running forge (WAL) waits up to 5 s for the forge's write lock instead of failing with SQLITE_BUSY.
- A second run that lists nothing is the confirmation. The steps are in docs/features/release-later.md, linked from the README with the other feature docs.
Tests
test/release-later.test.tscovers:
- only gate-alone issues are listed, with who linked them; - an issue that also waits on another open blocker is never released; - a link to another repository's issue with the gate's number is never matched; - a repository with no gate, a gate nothing waits for, and a closed gate all list and release nothing; - when a trigger makes the second delete fail, the first one rolls back too.
test/release-later-script.test.tsruns the script as a separate process:
- list mode writes nothing, --only narrows the list, and --apply releases;
- with the test holding BEGIN IMMEDIATE for 500 ms, --apply waits and then succeeds;
- bad arguments, an unknown repository, a missing database and a non-forge database each get a plain refusal.
- With
busy_timeoutand the transaction taken out, the waiting test and the rollback test both fail. - The triage test (
test/triage.test.ts) also passes on main, because #7797 already removed the rule. It guards against the rule coming back; it does not prove this change. - There is no test that list mode opens read-only. When SQLite cannot write a file it quietly opens it read-only, so I couldn't find a check that fails without the flag. Look at the
{ readonly: true }open in the script.
The script only lists and unlinks; it does not run against production. The owner runs it there, ideally with --only 7636,7637 first. bun scripts/gate.ts, bun x tsc --noEmit and the three test files above pass locally.
🤖 Generated with Claude Code
Earlier asks are met. Re-read for the experience, not the code:
- List mode opens the database read-only, and
--applysetsbusy_timeoutand runs in one transaction. Both have tests. - The tests for the no-gate and closed-gate cases now do what their names say.
- The README bullet sits with the other feature-doc links.
- The pull description says the triage test guards a regression and does not prove the change.
- Refusals (bad arguments, no
forge.db, no forge tables, unknown repository) are plain one-line messages with exit 2, not a SQLite stack trace. - There is no page, so the preview has nothing to show. This is an owner-run script. The list output is tab-separated and readable.
Two things I would do next, both non-blocking:
- Non-blocking:
scripts/release-later.tshas no--help. A bare--onlywith no value falls through to the usage line, which is fine, but the usage text could say what each flag does. - Non-blocking: after the owner runs
--applyon production, add a line to the docs, or comment on the issue, recording that #7636 and #7637 were released. That way the one-off script can be deleted.
The direction puts pipeline pulls first. This one is small, single-purpose, and unblocks held issues, so I do not hold it back.
This pull adds an owner-run script to release the issues the old Later-gate rule still holds. I did not release any: I can't touch the live database from here, and the issue says a person has to run it.
The new tests,
tscandscripts/gate.tspass, anddesign-lintprinted no complaint. I haven't run the script on real data. My only run was against an empty data directory, where it failed with "no such table: repo". I didn't runscripts/fast.tsor the wider suite, so the forge's check will be the first to do that.What it does
src/crew/release_later.tslists the open issues that wait for the open Later gate and for no other open issue. For each it shows who linked it. Releasing deletes only that one gate link, using the existingremoveDependency. An issue that also waits for another open issue is left alone.scripts/release-later.ts <dataDir> <owner/repo> [--only 7636,7637] [--apply]lists by default and writes nothing without--apply.docs/features/release-later.mdhas the how-to.test/release-later.test.tscovers three cases: an issue held by the gate alone is listed, one held by the gate plus another open blocker is not, and releasing removes exactly the gate link.What I chose not to do
--only.Triage: I did not test that triage stays off. Nothing in
src/crew/triage.tslinks an issue to the gate on its own, and the onlylaterGatecallers aresrc/actions/issues.tsandsrc/crew/runner.ts. The only other check is running the script again and getting an empty list.To try it
bun scripts/release-later.ts <dataDir> trevato/forgeto see the list, which should include #7636 and #7637.--applyto release them, or add--onlyto pick some.Closes #7801