feat: follow dependencies on every pull by default

`depends:` was filled and blockers were pulled only under `--deps`, so the
plain `pull.py <n>` — the only way to get a pushed issue back — answered
with a file whose graph was empty and an `issue_tree.py` that drew it as a
root with no blockers. The edge was not lost, but it was not asked for, and
it cannot be recovered locally: `map.from_api` writes slugs into the
`## Depends on` prose and never `#N`, so Gitea's native graph is the only
source there is.

A pull now returns the unit of work — the issue and what blocks it. `--deps`
stays accepted and does nothing, so existing calls and /tea:sync's tables
keep working; `--no-deps` is the way out and spends no request on either
half.

The cost is accepted and stated rather than hidden. The native links are now
fetched ONCE per issue instead of twice (they both fill `depends:` and steer
the walk), and only for an issue that lands in the store — a closed one that
filter mode drops no longer drags its blockers in behind it. That makes the
number quotable, and pull.py's docstring quotes it: a milestone of 50 open
issues costs one list request plus 50, where it used to cost one. In filter
mode a blocker no filter selected still lands in the store and still sits
outside `--limit`, deliberately, and both are documented; the exception is a
closed blocker, dropped like any other closed issue with the edge to it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
naudachu
2026-08-10 17:41:27 +05:00
parent bea3735e47
commit a2e9a88186
6 changed files with 478 additions and 39 deletions
+3 -1
View File
@@ -138,7 +138,9 @@ line so plain grep works without a parser.
- **A successful push deletes the local file** (`<id>.md` and
`<id>.comments.md`), and prints the number and URL the issue now lives at.
`--update` too: one rule, no exception. What is in the store is what has not
left. Get it back with `pull.py <n>`.
left. Get it back with `pull.py <n>` — which brings its blockers back with it:
a pull returns the unit of work, not one row of it. `--no-deps` narrows it to
the one issue, and the cost of the default is in `pull.py`'s docstring.
- Deletion happens only after a confirmed tracker response and only after
`.remote.json` has been written. Network down, non-2xx, an answer that does
not carry the right number: the file stays and the run stops. A never-pushed