diff --git a/AGENTS.md b/AGENTS.md index 743a9b8..3a77d8c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,7 +13,7 @@ flowchart LR work[work/ solutions] -->|bun run sync| docs[apps/docs/content/*.mdx] work -->|close-solved.yml| PI[problem issues] work -->|close-solved.yml POST /admin/solved| D1[(D1 = SRS state)] - PI -->|close-topics.yml| TI[topic issues] + PI -->|close-topics.yml| TI[topic + Review N issues] PI -->|close-solved.yml release job| Rel[timever release per finished topic] GH[GitHub issues = catalog] -->|nightly reconcile| D1 D1 -->|8 AM ET cron| Mail[digest email + one-tap links] @@ -39,6 +39,7 @@ flowchart LR - **DST-proof crons:** each event has two UTC crons; code fires only on the computed ET hour (`etHour`), unit-checked in `apps/api/src/srs.test.ts`. - **Chained workflows:** `GITHUB_TOKEN`-driven issue closes fire no `issues` events, so `close-topics.yml` chains off `workflow_run` of Close Solved instead. The Worker's webhook uses its own `GH_PAT`, so its events flow normally. - **One "finished topic" rule, two consumers.** `apps/cli/topics.ts` (`coreSet()`: every `set:core` sub-issue closed, zero core = never) is read by `close-topics.ts` (closes the topic issue) and `release-topics.ts` (the `release` job of `close-solved.yml`). The release reads the sub-issues, not the topic issue, so the push that finishes a topic releases it in the same run instead of waiting for Close Topics to chain after it. Version = [timever](https://gist.github.com/twolfson/de1b004dd22536b8e668) (`YYYYMMDD.HHMMSS.NNNNNNNNN`, UTC) of the instant the last core problem closed; the tag is annotated and backdated to that instant, on the last first-parent main commit before it; the body is a changelog snapshot at that instant (a one-sentence summary first — Blume's changelog makes it the page's meta description — then closed on the finish day / earlier / open at release, with solution links at the tag). A release is found by its `` body marker, never by tag name, so re-closing a core problem never mints a second one; an existing release keeps its tag and has its name (the topic title) and body rewritten whenever the render changes. The docs `/changelog` is these releases (`githubReleases` in `apps/docs/blume.config.ts`, fetched at build with `GITHUB_TOKEN`), dated by the timever tag, not `published_at` (which the API cannot backdate): `releasesDatedByTag` rewrites each timever release's `published_at` before Blume maps it, via `custom(githubReleasesSource(…))` because the config-level `githubReleases()` takes no `fetchImpl`. Changing the tag format breaks the changelog dates. +- **Review issues re-parent problems; topics still own them.** The transfer phase's 20 `Review — ` issues (label `review`, milestone `Review — Transfer & Mocks`; not the Worker's `Review — Week N` gate issues) hold open optional/deferred problems as sub-issues in solve order, moved there with `replace_parent`. `readReviews()`/`movedFromTopics()` in `apps/cli/topics.ts` recover each moved problem's topic from its last `parent_issue_removed` event naming a topic, and `readProblems()` returns it with the topic's direct sub-issues — so the finished rule and release bodies do not change when a problem moves. `close-topics.ts` also closes a Review issue once every sub-issue is closed (any set). The Worker's catalog reconcile still walks topic sub-issues only, so a moved problem's D1 row keeps its last-synced labels and topic. ## Key Directories