From c1c86262631cce0fe944aaa96b98523368738c28 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Tue, 24 Feb 2026 11:14:47 +0100 Subject: [PATCH 1/5] refactor(skills): lighten sprint-status context footprint Delegate sprint-status to a haiku subagent (sprint-plan pattern) so intermediate artifacts (sweep JSON, template read, PR list) stay out of the main context window. Trim sweep JSON output by removing unused fields (ok, sprint.status, priority, ticket_id) and shortening issue detail strings. Condense output template by moving rendering rules into SKILL.md and simplifying the bookkeeping table to two columns. Co-Authored-By: Claude Opus 4.6 --- .claude/skills/sprint-status/SKILL.md | 37 ++++++++++++++++--- .../references/output-template.md | 22 ++--------- db/connectors/sprint | 12 ++---- 3 files changed, 37 insertions(+), 34 deletions(-) diff --git a/.claude/skills/sprint-status/SKILL.md b/.claude/skills/sprint-status/SKILL.md index 5673405aa..5c1ac9b80 100644 --- a/.claude/skills/sprint-status/SKILL.md +++ b/.claude/skills/sprint-status/SKILL.md @@ -8,12 +8,33 @@ description: > when housekeeping feels off. Triggers on "sprint status", "cleanup sweep", "what's open", "sprint health". user-invocable: true +allowed-tools: Task, Read, Grep, Glob --- # Sprint Status -Produce a consistent, scannable sprint health report. Closed work scrolls -off the top; open work by team is visible at the bottom. +**Delegate this entire skill to a subagent** (general-purpose, model: haiku). + +When this skill is invoked, spawn a subagent using the Task tool: + +``` +Task( + subagent_type: "general-purpose", + model: "haiku", + prompt: "Run /sprint-status. Read the skill at + .claude/skills/sprint-status/SKILL.md for the full workflow + (below the --- separator), then execute it.", + description: "Sprint status report" +) +``` + +Present the subagent's output to the user verbatim. Do NOT run the +workflow yourself. + +--- + +The remainder of this file is the subagent's reference for executing +the workflow. ## Step 1 — Gather data @@ -28,7 +49,7 @@ tea pr list --login schweitz --repo jpmschweitzer/settled-reach --state open --o ``` The `sweep` command returns JSON with: -- `sprint` — id, name, status, goal +- `sprint` — id, name, goal - `progress` — total, done, pct - `by_status` — tickets grouped into done, review, in_progress, blocked, backlog - `by_team` — per-team counts @@ -57,10 +78,14 @@ Read `references/output-template.md` for the exact format spec. Render the report using data from steps 1-2. Key rules: - Sections ordered: Completed, In Review, In Progress, Blocked, Backlog - Sort tickets within sections by team then ticket ID -- Empty sections: show header with "(0)" and "(none)" -- Bookkeeping Issues table: merge ticket-side issues from `sweep` with - PR-side issues from step 2 +- Empty sections: show header with "(0)" and "(none)" — no empty table +- Bookkeeping Issues: two-column table (Issue, Fix) - Open Work by Team: summary table at the bottom +- Issue type labels: `stale_backlog` → "Stale backlog", + `unassigned_in_progress` → "Unassigned in_progress", + `assigned_but_done` → "Assigned but done", + `done_team_open_pr` → "Done team with open PR", + `orphan_pr` → "Orphan PR" ## Step 4 — Suggest actions diff --git a/.claude/skills/sprint-status/references/output-template.md b/.claude/skills/sprint-status/references/output-template.md index 74f51eab1..5976c1b39 100644 --- a/.claude/skills/sprint-status/references/output-template.md +++ b/.claude/skills/sprint-status/references/output-template.md @@ -1,7 +1,5 @@ # Sprint Status Output Template -Use this template exactly when formatting `/sprint-status` output. - ## Sprint {N}: {Theme} — Status Report **Goal:** {goal} @@ -44,11 +42,9 @@ Use this template exactly when formatting `/sprint-status` output. ### Bookkeeping Issues -| Issue | Detail | Fix | -|-------|--------|-----| -| {type} | {detail} | `{command}` | - -If no issues: "No bookkeeping issues found." +| Issue | Fix | +|-------|-----| +| {type}: {detail} | `{command}` | ### Open Work by Team @@ -56,15 +52,3 @@ If no issues: "No bookkeeping issues found." |------|---------|-------------|--------|---------|------| | {team} | {n} | {n} | {n} | {n} | {n} | | **Total** | **{n}** | **{n}** | **{n}** | **{n}** | **{n}** | - -## Rendering rules - -- Sections with 0 items: show header with "(0)" and a single line "(none)" — no empty table. -- Sort tickets within each section by team, then by ticket ID. -- Use the exact markdown table format above (pipe-separated, header row, separator row). -- Bookkeeping issue types map to human-readable labels: - - `unassigned_in_progress` → "Unassigned in_progress" - - `stale_backlog` → "Stale backlog" - - `assigned_but_done` → "Assigned but done" - - `done_team_open_pr` → "Done team with open PR" - - `orphan_pr` → "Orphan PR" diff --git a/db/connectors/sprint b/db/connectors/sprint index 8e60602fe..ff91da9ae 100755 --- a/db/connectors/sprint +++ b/db/connectors/sprint @@ -529,7 +529,6 @@ def cmd_sweep(args): "title": t["title"], "team": t.get("team") or "unassigned", "assigned_to": t.get("assigned_to"), - "priority": t["priority"], } if t["status"] == "done": by_status["done"].append(entry) @@ -559,22 +558,19 @@ def cmd_sweep(args): if t["status"] in ("in_progress", "review") and not t.get("assigned_to"): issues.append({ "type": "unassigned_in_progress", - "ticket_id": t["id"], - "detail": f"#{t['id']} is {t['status']} but has no agent assigned", + "detail": f"#{t['id']} unassigned {t['status']}", "fix": f"db/connectors/ticket assign {t['id']} ", }) if t["status"] == "backlog" and sprint["status"] == "active" and t["id"] not in blocked_by_map: issues.append({ "type": "stale_backlog", - "ticket_id": t["id"], - "detail": f"#{t['id']} still in backlog (unblocked, never started)", + "detail": f"#{t['id']} stale backlog", "fix": f"db/connectors/ticket status {t['id']} in_progress", }) if t["status"] == "done" and t.get("assigned_to"): issues.append({ "type": "assigned_but_done", - "ticket_id": t["id"], - "detail": f"#{t['id']} is done but still assigned to {t['assigned_to']}", + "detail": f"#{t['id']} done, still assigned", "fix": f"db/connectors/ticket unassign {t['id']}", }) @@ -584,11 +580,9 @@ def cmd_sweep(args): pct = int(done / total * 100) if total > 0 else 0 result = { - "ok": True, "sprint": { "id": sprint["id"], "name": sprint.get("name", f"Sprint {sprint['id']}"), - "status": sprint["status"], "goal": sprint.get("goal", ""), }, "progress": {"total": total, "done": done, "pct": pct}, From 619fbbd9f3b61e2881e3737b4706dcf00f7d3005 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Tue, 24 Feb 2026 11:14:51 +0100 Subject: [PATCH 2/5] docs(meta): document model selection and 1M context option Add model selection section to CLAUDE.md covering /model sonnet[1m] and opus[1m] for extended context sessions. Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 9f5bba849..2f5022eea 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -154,6 +154,15 @@ Key rules: Use conventional commits with project-specific scopes: `agents`, `skills`, `docs`, `briefings`, `discussions`, `schema`, `db`, `config`, `engine`, `simulation`, `client`, `ui`, `audio`, `assets`, `meta` +### Model selection + +Default model is Opus 4.6 (200K context). For heavy sessions (workshops, +sprint planning, large reviews), switch to extended context on-demand: + +- `/model sonnet[1m]` — Sonnet 4.6 with 1M context window +- `/model opus[1m]` — Opus 4.6 with 1M context window +- Cost: 2x input + 1.5x output for tokens beyond 200K (Tier 4 required) + ### Pull requests **Use `tea` (Gitea CLI), not `gh` (GitHub CLI).** The remote is Gitea at `git.schweitz.internal`. From 5106358113f5bf1603f7b253ef4d41c11dfd3cbc Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Tue, 24 Feb 2026 11:15:05 +0100 Subject: [PATCH 3/5] chore(meta): update changelog Co-Authored-By: Claude Opus 4.6 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e97eb27f..c9d2d2e84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ Format based on [Keep a Changelog](https://keepachangelog.com/). - Entity renderer migrated from ColorRect placeholders to Sprite2D with D-019 angle sprites — self_modulate for D-033 tinting, 8→4 octant direction mapping, feet-anchored y-sort (#540) ### Changed +- `/sprint-status` delegates to haiku subagent — keeps sweep JSON, template read, and PR list out of main context window +- `sprint sweep` JSON trimmed — removed unused fields (`ok`, `sprint.status`, `priority`, `ticket_id`), shortened issue detail strings +- Sprint status output template condensed — rendering rules moved to skill definition, bookkeeping table simplified to 2 columns +- Model selection documented in CLAUDE.md — `/model sonnet[1m]` and `/model opus[1m]` for 1M context sessions - Sprint 17 briefings updated with workshop results — server (14 tickets), copy (2 tickets), client (2), visual (1) - Q-024 (gossip timing), Q-025 (KG memory), Q-026 (contradiction detection) closed - Sprint 16 closed (8/8 done) From 99a7841bf2e04c84fd29dd11ec456f3228a7e865 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Tue, 24 Feb 2026 11:56:40 +0100 Subject: [PATCH 4/5] feat(config): add tea-comment wrapper for Gitea PR comments Single-command wrapper that handles temp file creation and cleanup so tea comment works reliably with multi-line strings. Pre-approved in settings.json, referenced in CLAUDE.md and pr-review skill. Co-Authored-By: Claude Opus 4.6 --- .claude/settings.json | 1 + .claude/skills/pr-review/SKILL.md | 14 +++----------- CLAUDE.md | 9 ++------- tooling/tea-comment | 18 ++++++++++++++++++ 4 files changed, 24 insertions(+), 18 deletions(-) create mode 100755 tooling/tea-comment diff --git a/.claude/settings.json b/.claude/settings.json index 90a00f426..16721c97e 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -44,6 +44,7 @@ "Bash(make)", "Bash(tea *)", + "Bash(tooling/tea-comment *)", "Bash(chmod *)", "Bash(ls *)", diff --git a/.claude/skills/pr-review/SKILL.md b/.claude/skills/pr-review/SKILL.md index c072787cb..08cb8d438 100644 --- a/.claude/skills/pr-review/SKILL.md +++ b/.claude/skills/pr-review/SKILL.md @@ -174,19 +174,11 @@ After presenting results to the user, post the review as a PR comment. Note: `tea pr reject` does not work on your own PRs. Use `tea comment` instead. -**IMPORTANT — `tea comment` hangs with inline heredocs and multi-line strings.** -Always use a two-step approach: write to a temp file first, then pass via `$(cat)`: +Post using the `tea-comment` wrapper (handles temp files and cleanup): +```bash +tooling/tea-comment "review markdown here" ``` -# Step 1: Write review to .tmp/ using the Write tool (no permission prompt) -Write(file_path: "/.tmp/review-.md", content: "...review content...") - -# Step 2: Post to Gitea (separate Bash call) -tea comment --login schweitz --repo jpmschweitzer/settled-reach "$(cat .tmp/review-.md)" -``` - -Use the Write tool for step 1 (avoids Bash permission prompts). The `.tmp/` -directory is gitignored and exists in the repo root for this purpose. ## 7. Merging approved PRs diff --git a/CLAUDE.md b/CLAUDE.md index 2f5022eea..a5860da7a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -121,7 +121,7 @@ tea pr list --login schweitz --repo jpmschweitzer/settled-reach --state open --o tea pr --login schweitz --repo jpmschweitzer/settled-reach --comments -o simple # Post a comment on a PR (or issue) -tea comment --login schweitz --repo jpmschweitzer/settled-reach "comment body" +tooling/tea-comment "comment body" # Approve a PR tea pr approve --login schweitz --repo jpmschweitzer/settled-reach @@ -133,12 +133,7 @@ tea issue list --login schweitz --repo jpmschweitzer/settled-reach --state open Key rules: - **All flags must be explicit** — omitting `--login` or `--repo` triggers interactive prompts that crash in Claude Code (no TTY) - **Use `--output simple`** for machine-readable output (no table borders) -- **`tea comment` hangs with inline heredocs and multi-line strings.** Always write the comment body to a temp file first, then pass it via `$(cat)`: - ```bash - # Step 1: Write content to .tmp/ (gitignored) using the Write tool - # Step 2: Post via cat - tea comment --login schweitz --repo jpmschweitzer/settled-reach "$(cat .tmp/review-branch.md)" - ``` +- **For comments, use `tooling/tea-comment "body"`** — handles temp files and cleanup automatically. Works with multi-line strings. - **`tea pr reject` does not work on your own PRs** — use `tea comment` instead - **Never delete protected branches:** `main`, `maintenance`, `server`, `client`, `copy`, `audio`, `visual`, `ci` are protected on Gitea. Do not use `tea pr clean`, `git push --delete`, or `git branch -D` on these branches. diff --git a/tooling/tea-comment b/tooling/tea-comment new file mode 100755 index 000000000..42fcd6252 --- /dev/null +++ b/tooling/tea-comment @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Post a comment to a Gitea PR or issue. +# Usage: tea-comment "comment body" +set -euo pipefail + +if [[ $# -lt 2 ]]; then + echo "Usage: tea-comment " >&2 + exit 1 +fi + +NUMBER="$1" +BODY="$2" +HASH=$(echo -n "$BODY" | md5sum | cut -c1-8) +TMPFILE="/tmp/tea-comment-${NUMBER}-${HASH}.md" +trap 'rm -f "$TMPFILE"' EXIT + +printf '%s' "$BODY" > "$TMPFILE" +tea comment --login schweitz --repo jpmschweitzer/settled-reach "$NUMBER" "$(cat "$TMPFILE")" From ffaf635e9a9838d41a0765e129529bb841b87fd6 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Tue, 24 Feb 2026 11:56:54 +0100 Subject: [PATCH 5/5] chore(meta): update changelog Co-Authored-By: Claude Opus 4.6 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9d2d2e84..29b3b34c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Format based on [Keep a Changelog](https://keepachangelog.com/). ## [Unreleased] ### Added +- `tooling/tea-comment` — single-command wrapper for posting Gitea PR/issue comments with multi-line bodies - `/sprint-status` cleanup sweep skill — consistent health report with tickets by status, PR cross-reference, bookkeeping issue detection, and open work by team - `sprint sweep` CLI subcommand — structured JSON output for sprint health checks (grouped tickets, per-team summary, issue detection) - Knowledge Flow & NPC Boundaries workshop — 5 D-records (D-079–D-083) covering grant architecture, NPC-to-NPC propagation, unprompted disclosure, NPC information boundaries MVP, contradiction detection pipeline