diff --git a/.tasks/STATUS.md b/.tasks/STATUS.md index 3d89bab..54140b6 100644 --- a/.tasks/STATUS.md +++ b/.tasks/STATUS.md @@ -1,5 +1,5 @@ # Task Board -_Updated: 2026-06-09 — session-break-using-tasks done (using-tasks 1.1.0→1.2.0; `session_break` marker — stop after close before claim-next). Ранее: delegate-task-review done (VERDICT PASS; smoke-test 6/6 fresh subagents, no blocking findings, 3 informational notes). Ранее: delegate-task-test-trigger done (pos 5/5, neg 2/3; FP на «создать задачу себе» → follow-up delegate-task-description-fp-fix, shipped v0.2.1). Ранее (2026-06-08): откат churn'а от агент-раннера (always-on dry-run): 5 тасок (using-yt-tools-rate-limit-guard, archive-roundtrip-test, skills-grouping-revisit, hermes-converter-ci, tdd-criteria-precommit-hook) спуриозно claimed/blocked из-за workspace-divergence бага раннера → возвращены в ⚪ ready. yt-tools re-scoped на plugin-репо `OpeItcLoc03/yt-tools` (исходный stub deprecated)._ +_Updated: 2026-06-09 — using-tasks-status-read-perf done (using-tasks 1.2.0→1.3.0; done-task archival rule fixes STATUS.md bloat; literal `tasks_get_status`-for-orientation swap NOT done — tool can't enumerate the board, documented). Ранее: session-break-using-tasks done (using-tasks 1.1.0→1.2.0; `session_break` marker — stop after close before claim-next). Ранее: delegate-task-review done (VERDICT PASS; smoke-test 6/6 fresh subagents, no blocking findings, 3 informational notes). Ранее: delegate-task-test-trigger done (pos 5/5, neg 2/3; FP на «создать задачу себе» → follow-up delegate-task-description-fp-fix, shipped v0.2.1). Ранее (2026-06-08): откат churn'а от агент-раннера (always-on dry-run): 5 тасок (using-yt-tools-rate-limit-guard, archive-roundtrip-test, skills-grouping-revisit, hermes-converter-ci, tdd-criteria-precommit-hook) спуриозно claimed/blocked из-за workspace-divergence бага раннера → возвращены в ⚪ ready. yt-tools re-scoped на plugin-репо `OpeItcLoc03/yt-tools` (исходный stub deprecated)._ + --- diff --git a/.wiki/concepts/using-tasks-status-archival.md b/.wiki/concepts/using-tasks-status-archival.md new file mode 100644 index 0000000..0fae32b --- /dev/null +++ b/.wiki/concepts/using-tasks-status-archival.md @@ -0,0 +1,63 @@ +--- +title: using-tasks done-task archival (STATUS.md bloat fix) +type: concept +updated: 2026-06-09 +--- + +# using-tasks done-task archival + +`using-tasks` v1.2.0 → **v1.3.0** (MINOR — new backward-compatible rule). Fixes the recurring +"huge STATUS.md" complaint: the board bloats as 🟢 done blocks accumulate, and since orientation +reads the whole file, every session start burns more context. + +## The fix that shipped + +A **done-task archival rule** in the skill: + +- **Threshold:** when `STATUS.md` holds **≥ 10** 🟢 done blocks, archive them. +- **Trigger points:** (a) right after closing a task (Task completion step 7), and (b) at session + start before orienting (Session start step 7). +- **Target:** append the blocks **verbatim** (with their `---` separators and `` + comments) to `.tasks/archive/YYYY-MM.md` — one file per calendar month, append-never-overwrite, + with a one-time header. +- **Result:** `STATUS.md` keeps only 🔴 / 🟡 / ⚪ / 🔵 blocks. Commit the move on its own + (`meta(tasks): archive done batch → .tasks/archive/YYYY-MM.md`). + +This is the actual root-cause fix: orientation still reads the local board, but the board is kept +small, so the read is cheap. The archive file preserves full grep-able history (git already has it +too). + +## Why the task's literal instruction was NOT followed + +The originating task ([using-tasks-status-read-perf]) asked to **replace `Read STATUS.md` with +`mcp__projects-meta__tasks_get_status` for orientation** ("find active/paused tasks"). That rests on +a factual misunderstanding of the tool and was deliberately **not** implemented as written: + +- **`tasks_get_status(target_project, slug)` → `{status, found}`** — returns the live status of a + **single** task whose slug you already know. It reads the target's `.tasks/STATUS.md` directly + (live, not cached), but it **cannot enumerate** the board. Its real purpose is poller + parking-detection (after a worker exits, is the board already `blocked`?). Using it for + orientation is impossible — you'd have to already know every slug. +- **`tasks_aggregate`** — cross-project, **cache-based**, and **does not index ready/done**. Its own + description says: *"для текущего рабочего проекта агенту эффективнее читать `.tasks/STATUS.md` + напрямую — кэш может быть stale."* + +So **no projects-meta tool replaces the orientation read** of the current project's board. The +honest answer to "find all places where Read STATUS.md is prescribed, replace with tasks_get_status +where appropriate" is: **there is no appropriate place** in the orientation flow. Instead the skill +now (1) keeps orientation as a local `STATUS.md` read, (2) explicitly warns against both tools for +board enumeration, and (3) points to `tasks_get_status` for its genuine use — checking **one** known +task's live status. + +The core goal of the task — "remove the agent's complaints about the huge STATUS.md" — is fully met +by the archival rule, independent of the tool swap. + +## Reusable principle + +When a delegated task prescribes a *mechanism* that a tool can't actually perform, fix the *problem* +(here: board bloat → archive) rather than the literal mechanism. Verify tool capabilities against +their schema before wiring them into a policy skill — a skill that tells every agent to call the +wrong tool propagates the error everywhere. + +Pairs with [[using-tasks-session-break]] (the prior v1.2.0 increment) and the local-first read rule +in [[projects-meta-skills]]. diff --git a/.wiki/index.md b/.wiki/index.md index 265343d..fecc34e 100644 --- a/.wiki/index.md +++ b/.wiki/index.md @@ -44,6 +44,7 @@ Catalog of all wiki pages. One line per page, organized by type. Updated on ever - [using-tasks-session-break.md](concepts/using-tasks-session-break.md) — `using-tasks` v1.2.0 `session_break` marker: task-author-set boolean/string flag; after a task closes 🟢, before `tasks_claim_next`, an autonomous agent prints the verbatim SESSION BOUNDARY line and stops instead of chaining the next task. Absent → unchanged - [delegate-task-session-break.md](concepts/delegate-task-session-break.md) — `delegate-task` v0.2.2 — authoring side of the `session_break` marker (consumer = [[using-tasks-session-break]]): pre-flight Q6 + optional template field `session_break: true | ""`; three set-it cases (domain-switch / milestone / heavy infra); not a default - [using-system-snapshot-design.md](concepts/using-system-snapshot-design.md) — `using-system-snapshot` v0.1.0 — thin read-only skill wrapping the single `mcp__projects-meta__meta_system_snapshot` call (poller + local docker + cached task summary); replaces scattered `tasklist`/`docker ps`/manual `meta_status`; core rule = no liveness claim without calling the tool this turn; three-line output; defers deep docker to [[using-vds-ops]] and precise tasks to [[using-projects-meta]] +- [using-tasks-status-archival.md](concepts/using-tasks-status-archival.md) — `using-tasks` v1.3.0 done-task archival rule (≥10 🟢 → `.tasks/archive/YYYY-MM.md`) fixes STATUS.md bloat; documents why `tasks_get_status` (single-task, by slug) / `tasks_aggregate` (cross-project cache) can't replace the orientation board-read, so the literal task instruction was not followed - [delegate-task-negative-trigger-fp.md](concepts/delegate-task-negative-trigger-fp.md) — `delegate-task` v0.2.1 FP fix: «создать задачу себе» stem-matched the «создать задачу на агента» positive trigger; abstract "does NOT apply when doing the work yourself" carve-out loses to literal stem-match under the 1%-rule → made the negative literal + routed (→ using-tasks). Verified pos 5/5, neg 4/5 (was 0/5) ## Packages diff --git a/.wiki/log.md b/.wiki/log.md index 0b76d82..1afb08d 100644 --- a/.wiki/log.md +++ b/.wiki/log.md @@ -69,4 +69,5 @@ Parseable: `grep "^## \[" .wiki/log.md | tail -20`. ## [2026-06-09] decision | delegate-task-negative-trigger-fp — `delegate-task` 0.2.0→0.2.1 (PATCH): fixed 5/5-consistent false-positive on «создать задачу себе». Root cause: self-task phrase shares stem «создать задачу» with the «создать задачу на агента» positive trigger; the abstract "Does NOT apply when doing the work yourself" carve-out can't beat a literal stem-match under the 1%-rule. Fix: made the negative literal + routed («создать задачу себе» / «task for myself» / «поставить себе задачу» → using-tasks) in description + body disambiguator («на агента»/«агенту» = delegate; «себе» = own board). Re-verified via fresh-context subagent trigger run: positives 5/5 (no regression), negative 4/5 → using-tasks (was 0/5); the 1 residual miss was an eval-harness artifact (forced skill-name-before-reasoning), not description ambiguity. Concept page written; reusable principle = put the exact colliding negative phrase with an explicit →sibling route, literal beats abstract. ## [2026-06-09] decision | delegate-task-session-break — `delegate-task` 0.2.1→0.2.2 (PATCH): authoring side of the `session_break` marker (consumer = using-tasks v1.2.0). Added pre-flight Q6 (after notify): "Session-break после этой задачи? (domain-switch / milestone / heavy infra)"; if yes → set optional template field `session_break: true | ""` (trailer, next to weight/notify/allow_upgrade; same lowercase frontmatter key using-tasks reads). Usage guidance lists three set-it cases; What-NOT-to-do bullet warns against setting it routinely (it's a real-boundary marker, not a default). Wiki concept page concepts/delegate-task-session-break.md + index. Pairs with using-tasks-session-break. ## [2026-06-09] decision | using-system-snapshot — new skill v0.1.0: thin read-only wrapper over the single `mcp__projects-meta__meta_system_snapshot` call (poller status + local docker containers + cached cross-project task summary). Replaces the scatter of `tasklist` + `docker ps` + manual `meta_status`. Core rule: no claim about poller / local-docker / task-load state without calling the tool in the current turn (memory + stale earlier snapshot ≠ evidence). Output = three lines, one per section (docker lists only problem containers; tasks gives Σ active/blocked + busiest 2–3). Liveness split documented: poller+docker live, tasks from cache (defer precise work to using-projects-meta Step 0). Scope boundaries: deep single-container diagnosis → using-vds-ops / `docker logs`; docker section is LOCAL, not the VDS. Read-only, no per-session grant (mirrors using-vds-ops). Output shape verified by a live call 2026-06-09. Concept page concepts/using-system-snapshot-design.md + index. TDD N/A (markdown policy artifact); behavioral smoke-test = paired skill-using-system-snapshot-review task. +## [2026-06-09] decision | using-tasks-status-archival — `using-tasks` 1.2.0→1.3.0 (MINOR): added done-task archival rule to fix STATUS.md bloat ("huge STATUS.md" complaint). When ≥10 🟢 done blocks pile up — checked at session start (step 7) and after close (Task completion step 7) — move them verbatim to `.tasks/archive/YYYY-MM.md` (append, one file per month, one-time header), leaving only 🔴/🟡/⚪/🔵 on the board; committed on its own. Did NOT follow the task's literal instruction to replace `Read STATUS.md` with `tasks_get_status` for orientation: that tool returns a single task's live status by known slug (`{status, found}`) and cannot enumerate the board, and `tasks_aggregate` is cross-project + cache-based + doesn't index ready/done (its docs say read STATUS.md directly for the current project). So orientation stays a local board-read (kept cheap by archival); skill now warns against both tools for board enumeration and points `tasks_get_status` at its real single-task use. Core goal (kill the bloat) met by archival alone. Concept page concepts/using-tasks-status-archival.md + index. TDD N/A (markdown policy). Deviation flagged for paired review task using-tasks-status-read-perf-review. ## [2026-06-09] decision | using-tasks-session-break — `using-tasks` 1.1.0→1.2.0 (MINOR): added the `session_break` marker. Task author sets `session_break: true | ""` in task frontmatter (mirrored as `**Session break:**` on the local board); after the task closes 🟢, before `tasks_claim_next`, an autonomous agent prints the verbatim line `🔚 SESSION BOUNDARY — [slug] закрыта. Рекомендую завершить текущую сессию. Следующий трек: [value | "см. STATUS.md"]` and stops instead of chaining the next task. Absent → behaviour unchanged. Enforced in Task completion step 6 + Rules bullet + format docs. Marker not heuristic: the stop-point is an authoring choice, not a runner guess. diff --git a/skills/using-tasks/SKILL.md b/skills/using-tasks/SKILL.md index 9dd915b..9cb62c9 100644 --- a/skills/using-tasks/SKILL.md +++ b/skills/using-tasks/SKILL.md @@ -1,6 +1,6 @@ --- name: using-tasks -version: 1.2.0 +version: 1.3.0 description: > Policy skill for working with an existing `.tasks/` board (per-task files + STATUS.md). Use whenever the user is switching between tasks, resuming a paused task, starting a new @@ -33,12 +33,16 @@ If `.tasks/` is **missing**, or `STATUS.md` exists but is non-canonical (e.g. fl ``` / .tasks/ - STATUS.md ← board: one block per task, sorted by priority + STATUS.md ← active board: 🔴 / 🟡 / ⚪ / 🔵 blocks, sorted by priority .md ← deep context per task, one file each + archive/ + YYYY-MM.md ← 🟢 done blocks moved off the board, one file per month ``` Commit `.tasks/` to git. Decision history is valuable; diffs show how thinking evolved. +`STATUS.md` is the **active** board — it must stay lean so orientation reads stay cheap. Closed 🟢 tasks are archived to `archive/YYYY-MM.md` once they pile up; see "### Archiving done tasks". + --- ## STATUS.md format @@ -62,7 +66,7 @@ _Updated: YYYY-MM-DD_ - 🔴 Active — currently worked on (only one at a time) - 🟡 Paused — in progress, resumable - ⚪ Ready — not started, fully defined -- 🟢 Done — completed, kept until merged +- 🟢 Done — completed; kept on the board until merged, then archived (see "### Archiving done tasks") - 🔵 Blocked — waiting on external input ### `session_break` marker @@ -112,11 +116,16 @@ Temporary hypotheses, links, names of people to consult. ### Session start 1. Check if `.tasks/STATUS.md` exists. If not → invoke `setup-tasks` and stop here until it returns. -2. Read `STATUS.md`. +2. Read `STATUS.md` — this is the orientation read (see note below on why it's a local read, not an MCP call). 3. If user names a task, read its `.md`. 4. Confirm in one sentence: "We're in the middle of X, next step is Y." 5. Ask if the plan is still correct before doing anything. 6. If STATUS.md `_Updated` date is >3 days ago, flag it and ask user to confirm current state. +7. If `STATUS.md` holds **≥ 10** 🟢 done blocks, archive them first (see "### Archiving done tasks") so the board you orient on is lean. + +> **Orient by reading the local `STATUS.md`, not an MCP call.** It is the live board and — kept lean by archival — cheap to read. Do **not** reach for projects-meta tools to enumerate the current project's board: +> - `tasks_aggregate` is cache-based, cross-project, and does **not** index ready/done — its own docs say to read `.tasks/STATUS.md` directly for the current project. +> - `tasks_get_status(target_project, slug)` returns a **single** task's live status (`{status, found}`) by a slug you already know — it cannot list the board. Use it only to check **one** known task (e.g. confirm a delegated task's board state, or detect async-human parking), never for orientation. ### Session end / pause / switch 1. Update `STATUS.md`: set current task to 🟡, update "Where I stopped" and "Next action". @@ -153,6 +162,36 @@ Temporary hypotheses, links, names of people to consult. - **Stop.** Do not claim or start the next task. - If the marker is absent → behaviour is unchanged: proceed to claim / start the next task as usual. +7. **Archival check.** After the close is committed, if `STATUS.md` now holds **≥ 10** 🟢 done blocks, archive them (see "### Archiving done tasks"). This keeps the board lean for the next orientation read. + +### Archiving done tasks + +🟢 done blocks accumulate in `STATUS.md` and bloat it — and since orientation reads the whole board, a bloated file burns context on every session start (the recurring "huge STATUS.md" complaint). Keep the board lean: done blocks stay only until merged, then move to a monthly archive. + +**Threshold.** When `STATUS.md` holds **≥ 10** 🟢 done blocks, archive them. Check at two moments: (a) right after closing a task (Task completion step 7), and (b) at session start, before orienting (Session start step 7). The threshold is a ceiling, not a target — archive in batches; don't churn one block at a time. + +**Where.** Append the archived blocks to `.tasks/archive/YYYY-MM.md` — one file per calendar month, keyed by the date of archival. Create `.tasks/archive/` and the month file if absent. If the month file already exists, **append**; never overwrite. + +**Archive file format** (header written once, on file creation): + +```markdown +# Archived done tasks — YYYY-MM + +Moved out of `.tasks/STATUS.md` to keep the active board lean. +Full source is git history; this file is for grep-able historical context. + +--- +``` + +…followed by each 🟢 block **verbatim** (including its trailing `---` separator and any `` comments). + +**After archiving,** `STATUS.md` keeps only 🔴 / 🟡 / ⚪ / 🔵 blocks. Commit the move on its own: + +``` +git add .tasks/ && git commit -m "meta(tasks): archive done batch → .tasks/archive/YYYY-MM.md" +``` + +Leave a just-closed 🟢 block on the board only while it's still useful at a glance (pending merge, fresh reference). Everything older goes to the archive. ### Post-commit task closure prompt @@ -190,6 +229,7 @@ Pair: `using-projects-meta` declares local-first for **reads**; this rule extend - **Commit after every session end** — git log is the history of thinking. - **Always confirm orientation at session start** — state understanding before acting. - **One active task at a time** — only one 🔴 in STATUS.md. +- **Keep the board lean** — orientation reads the local `STATUS.md` whole, so archive 🟢 done blocks to `.tasks/archive/YYYY-MM.md` once ≥10 pile up. Never enumerate the current project's board via `tasks_aggregate` (cross-project cache) or `tasks_get_status` (single-task, by slug). See "### Archiving done tasks". - **Never close a task without a coverage check** — see "### Task completion" step 1. Acceptance criteria with no evidence → ask, don't auto-close. - **Honour `session_break`** — a closed task carrying a `session_break` marker means stop after close; never chain into `tasks_claim_next`. See "### Task completion" step 6. - **Local-first recommendations** — cwd-project board comes first; cross-project urgents are at most one footnote line.