diff --git a/.gitignore b/.gitignore index 837d65d..7f1f7b4 100644 --- a/.gitignore +++ b/.gitignore @@ -83,3 +83,6 @@ coverage/ # Per-machine Claude Code local settings — keep ignored despite !.claude/ above /.claude/settings.local.json + +# Runtime session lock — ephemeral, never committed (using-tasks skill) +.tasks/.lock diff --git a/.tasks/STATUS.md b/.tasks/STATUS.md index 23f1a28..bd86de5 100644 --- a/.tasks/STATUS.md +++ b/.tasks/STATUS.md @@ -1,5 +1,5 @@ # Task Board -_Updated: 2026-06-11 — meta-host-routing-review closed (VERDICT PASS; behavioral 8/8 via clean-context subagents — 5 pos→meta-host-routing, 3 neg routed away incl. known-Gitea Skip-clause; Steps verified vs live infra: yt-tools→OpeItcLoc03/meta-yt-tools dedicated host resolves, .common grep hits, excludesFile/auth.toml present; failure-modes→STOP+ask, What-NOT accurate; no blocking findings on skill v0.3.0. Observation: task acceptance «resolves .common» is stale — skill+reality route yt-tools to dedicated meta-yt-tools host. Caveat: -install + -hermes-mapping baselines remain ⚪ open — skill not in ~/.claude/skills nor hermes/mapping.yaml; review covers content+trigger-discrimination only, not live-harness activation). Ранее: task-format skill v0.1.0 created (TDD via writing-skills; RED 3-fail → GREEN 2-pass). Ранее: using-markitdown-cli-rewrite-review done (VERDICT PASS; SKILL.md без `mcp__markitdown__`, CLI-примеры совпадают с `markitdown 0.1.6 --help`, version 1.0.0→1.0.1 PATCH, dist консистентен; 1 informational finding — docker-контейнер респаунится из out-of-scope `~/.claude.json` MCP-регистрации → follow-up `using-markitdown-mcp-deregister` needs-human). Ранее: skill-using-system-snapshot-review done (VERDICT PASS 3/3; live tool-contract verify + 9-way fresh-context trigger test, 8 clean; 3 informational findings, none blocking — incl. missing deployment scaffold: skill not installed / not in hermes-mapping / no baseline tasks). Ранее: 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)._ +_Updated: 2026-06-11 — using-tasks-session-lock shipped (using-tasks 1.3.0→1.4.0; session lock guard: start step 1 + end step 1 + .gitignore + Structure docs). Ранее: meta-host-routing-review closed (VERDICT PASS; behavioral 8/8 via clean-context subagents — 5 pos→meta-host-routing, 3 neg routed away incl. known-Gitea Skip-clause; Steps verified vs live infra: yt-tools→OpeItcLoc03/meta-yt-tools dedicated host resolves, .common grep hits, excludesFile/auth.toml present; failure-modes→STOP+ask, What-NOT accurate; no blocking findings on skill v0.3.0. Observation: task acceptance «resolves .common» is stale — skill+reality route yt-tools to dedicated meta-yt-tools host. Caveat: -install + -hermes-mapping baselines remain ⚪ open — skill not in ~/.claude/skills nor hermes/mapping.yaml; review covers content+trigger-discrimination only, not live-harness activation). Ранее: task-format skill v0.1.0 created (TDD via writing-skills; RED 3-fail → GREEN 2-pass). Ранее: using-markitdown-cli-rewrite-review done (VERDICT PASS; SKILL.md без `mcp__markitdown__`, CLI-примеры совпадают с `markitdown 0.1.6 --help`, version 1.0.0→1.0.1 PATCH, dist консистентен; 1 informational finding — docker-контейнер респаунится из out-of-scope `~/.claude.json` MCP-регистрации → follow-up `using-markitdown-mcp-deregister` needs-human). Ранее: skill-using-system-snapshot-review done (VERDICT PASS 3/3; live tool-contract verify + 9-way fresh-context trigger test, 8 clean; 3 informational findings, none blocking — incl. missing deployment scaffold: skill not installed / not in hermes-mapping / no baseline tasks). Ранее: 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/dist/using-tasks.skill b/dist/using-tasks.skill index af3e8e9..ce15af1 100644 Binary files a/dist/using-tasks.skill and b/dist/using-tasks.skill differ diff --git a/skills/using-tasks/SKILL.md b/skills/using-tasks/SKILL.md index 9cb62c9..c737daf 100644 --- a/skills/using-tasks/SKILL.md +++ b/skills/using-tasks/SKILL.md @@ -1,6 +1,6 @@ --- name: using-tasks -version: 1.3.0 +version: 1.4.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 @@ -35,6 +35,7 @@ If `.tasks/` is **missing**, or `STATUS.md` exists but is non-canonical (e.g. fl .tasks/ STATUS.md ← active board: 🔴 / 🟡 / ⚪ / 🔵 blocks, sorted by priority .md ← deep context per task, one file each + .lock ← runtime session lock; **gitignored** (never committed) archive/ YYYY-MM.md ← 🟢 done blocks moved off the board, one file per month ``` @@ -43,6 +44,8 @@ Commit `.tasks/` to git. Decision history is valuable; diffs show how thinking e `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". +> **`.tasks/.lock` must be listed in `.gitignore`** (add `.tasks/.lock` to your project's `.gitignore`). The lock file is ephemeral runtime state, not project history — it must never be committed. + --- ## STATUS.md format @@ -115,23 +118,35 @@ Temporary hypotheses, links, names of people to consult. ## Agent operations ### Session start -1. Check if `.tasks/STATUS.md` exists. If not → invoke `setup-tasks` and stop here until it returns. -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. +1. **Session lock guard.** If `.tasks/` exists, read `.tasks/.lock`. + - **Active agent lock** — `type:"agent"` with `heartbeat` ≤ 10 minutes old: print the hard warning below and **require explicit user confirmation** before proceeding. Do not touch the board until the user confirms. + ``` + ⚠️ поллер ведёт — нельзя работать параллельно + ``` + (Substitute the `slug` field from the lock file if present, otherwise omit it.) + - **Stale lock** — any type whose TTL has expired (`type:"agent"` with `heartbeat` > 10 min ago; `type:"interactive"` with `started_at` > 2 h ago): silently overwrite. + - **Absent or stale lock** (including after user confirmation): write `.tasks/.lock`: + ```json + {"type":"interactive","started_at":"","ttl_minutes":120} + ``` +2. Check if `.tasks/STATUS.md` exists. If not → invoke `setup-tasks` and stop here until it returns. +3. Read `STATUS.md` — this is the orientation read (see note below on why it's a local read, not an MCP call). +4. If user names a task, read its `.md`. +5. Confirm in one sentence: "We're in the middle of X, next step is Y." +6. Ask if the plan is still correct before doing anything. +7. If STATUS.md `_Updated` date is >3 days ago, flag it and ask user to confirm current state. +8. 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". -2. Append to `.md` Decisions log any non-obvious choices made this session. -3. Move finished items to "Completed steps". -4. Commit: `git add .tasks/ && git commit -m "chore: update task status []"` +1. **Release session lock.** If `.tasks/.lock` exists and contains `"type":"interactive"`: delete `.tasks/.lock`. (Stale interactive locks are cleaned up here too; silently delete any interactive lock regardless of TTL.) +2. Update `STATUS.md`: set current task to 🟡, update "Where I stopped" and "Next action". +3. Append to `.md` Decisions log any non-obvious choices made this session. +4. Move finished items to "Completed steps". +5. Commit: `git add .tasks/ && git commit -m "chore: update task status []"` ### Task switch 1. Perform session-end operations for the current task. @@ -222,6 +237,7 @@ Pair: `using-projects-meta` declares local-first for **reads**; this rule extend ## Rules +- **Honour `.tasks/.lock`** — read the lock at session start before touching the board; write it after clearing the guard; delete it at session end/pause. Never skip the lock check when `.tasks/` exists. The lock file must be gitignored. - **Never lose "Where I stopped"** — most critical field. If unclear, ask before ending session. - **One sentence per STATUS.md field** — compress, don't write prose. - **Key files must be specific** — not "auth module" but `packages/auth/src/useAuth.ts:87`.