|
3 | 3 | - **YAML frontmatter parsing:** use `bytes.SplitN(content, []byte("---"), 3)` to |
4 | 4 | split. Element 0 is empty (before first `---`), element 1 is YAML, element 2 |
5 | 5 | is body. Handle `\r\n` line endings. |
6 | | -- **`next_id` atomicity:** since the server is single-process, a mutex on |
7 | | - `ProjectConfig` is sufficient. Multi-instance would need file locking. |
8 | | -- **`go-git` performance:** fine for ContextMatrix boards (small files, <10k |
9 | | - cards). If it becomes an issue, shell out to `git` binary. |
10 | 6 | - **Deferred git commits (`git_deferred_commit`):** When |
11 | 7 | `git_deferred_commit: true` in `config.yaml`, agent mutations (heartbeats, log |
12 | 8 | entries, intermediate updates) are batched and committed in a single flush at |
|
18 | 14 | API — the PUT/PATCH handlers set `ImmediateCommit: true` when |
19 | 15 | `card.AssignedAgent == ""`, triggering an immediate commit. MCP tool callers |
20 | 16 | (agents) never set this flag, so their commits continue to defer normally. |
21 | | -- **SSE headers:** `Content-Type: text/event-stream`, `Cache-Control: no-cache`, |
22 | | - `Connection: keep-alive`. Must call `Flusher.Flush()` after each event. |
23 | 17 | - **SSE and MCP streaming vs. `WriteTimeout`:** Go's `http.Server.WriteTimeout` |
24 | 18 | is an absolute deadline measured from when request headers are read — it is |
25 | 19 | NOT reset by intermediate writes (keepalive comments, partial event data, etc.). |
|
47 | 41 | in both `App.tsx` (top-level) and `ProjectShell.tsx` (nested project routes). |
48 | 42 | If you add a new `Routes` subtree, add its own catch-all or users will see a |
49 | 43 | blank screen instead of the 404 page. |
50 | | -- **Tailwind purge:** `content` in `tailwind.config.js` must include |
51 | | - `./src/**/*.tsx` or classes get stripped. |
52 | | -- **Activity log bloat:** capped at 50 entries in frontmatter. Older entries are |
53 | | - only in git history. If an agent writes very frequently, entries may be lost |
54 | | - between git commits — this is acceptable. |
55 | | -- **Vite proxy:** `vite.config.ts` must proxy `/api` to `http://localhost:8080` |
56 | | - during dev. Without this, frontend can't reach the backend. |
57 | 44 | - **stdlib URL params:** use `r.PathValue("project")` (Go 1.22+). Route patterns |
58 | 45 | use `{project}` syntax: |
59 | 46 | `mux.HandleFunc("GET /api/projects/{project}", handler)`. |
60 | 47 | - **`time.Duration` in YAML:** `time.Duration` doesn't unmarshal from strings |
61 | 48 | like `"30m"` with `gopkg.in/yaml.v3`. Either use a custom type with |
62 | 49 | `UnmarshalYAML`, or store as string in config and parse with |
63 | 50 | `time.ParseDuration()` at load time. |
64 | | -- **MCP Streamable HTTP transport:** `POST /mcp` handles all MCP traffic. |
65 | | - Responses are either plain JSON (for non-streaming operations) or |
66 | | - `text/event-stream` (for streaming tool results). Registered on the same |
67 | | - `http.ServeMux` as the REST API — no separate server or port needed. |
68 | | -- **MCP auth:** support an optional bearer token (`mcp.auth_token` in |
69 | | - `config.yaml`). When set, the `/mcp` endpoint requires |
70 | | - `Authorization: Bearer <token>`. Essential for container deployments exposed |
71 | | - beyond localhost. |
72 | | -- **MCP prompts + card context:** most prompt handlers return delegation |
73 | | - wrappers (not raw skill content); interview skills (`create-task`, |
74 | | - `init-project`) return raw content for inline execution. The `get_skill` tool |
75 | | - fetches card context at execution time, calling the service layer in-process. |
76 | | - The MCP handler and HTTP API share the same `CardService` instance. The |
77 | | - `## Agent Configuration` section is stripped from all skill content delivered |
78 | | - via `get_skill` and prompt handlers — the required model is returned as a |
79 | | - separate `model` field. |
80 | | -- **Sub-agent death during idle user-approval wait:** Claude Code can kill a |
81 | | - sub-agent between turns if the conversation goes quiet (e.g., while waiting |
82 | | - for the user to read and approve a plan). The fix is to never have a sub-agent |
83 | | - wait for user input — instead, the sub-agent should write its output to the |
84 | | - card body and return immediately, and let the always-alive main agent (CC) |
85 | | - handle the user interaction. All skills that previously had this problem have |
86 | | - been fixed: |
87 | | - - `create-plan`: Phase 1 drafts and writes the plan then returns |
88 | | - `PLAN_DRAFTED`; CC presents the plan to the user and collects approval; |
89 | | - Phase 2 creates subtasks from the already-approved plan. |
90 | | - - `review-task`: The review sub-agent writes `## Review Findings` to the card |
91 | | - body and returns `REVIEW_FINDINGS` immediately; CC presents findings to the |
92 | | - user and collects the approve/reject decision directly. |
93 | | - - `document-task`: The doc sub-agent writes files to disk and returns |
94 | | - `DOCS_WRITTEN` immediately — no user approval gate before writing, since |
95 | | - docs are built from already-reviewed code; CC presents the summary after. |
96 | | - - `create-task` and `init-project`: These interview skills now run inline in |
97 | | - CC (no sub-agent at all) — see the "Interview skills run inline" entry |
98 | | - below. Any new skill that must get user approval before continuing should |
99 | | - follow the same split-phase pattern: sub-agent writes output to card body |
100 | | - and returns a structured result immediately; CC handles the user |
101 | | - interaction. |
102 | | -- **Interview skills (create-task, init-project) run inline:** These skills |
103 | | - require multi-turn back-and-forth conversations with the user (gathering |
104 | | - requirements, confirming config). Delegating them to a sub-agent breaks this |
105 | | - because the `Agent` tool does not support relaying multiple user turns back |
106 | | - into the sub-agent. Their prompt handlers return the raw skill content (with |
107 | | - `## Agent Configuration` stripped) rather than a delegation wrapper, so the |
108 | | - main agent executes them directly in its own context. **Never delegate |
109 | | - `create-task` or `init-project` to a sub-agent.** |
110 | | -- **Execute-task agents never spawn review:** The `execute-task` skill |
111 | | - explicitly instructs agents to ignore any `next_step` field returned by |
112 | | - `complete_task` (e.g., when the parent card transitions to `review`). The |
113 | | - lifecycle continuation (spawning review sub-agents) was removed from |
114 | | - execute-task agents because it caused nested agent chains with unpredictable |
115 | | - lifetimes. The orchestrator (main CC) is solely responsible for detecting that |
116 | | - the parent entered `review` and spawning the review sub-agent. |
117 | 51 | - **`/healthz` requests are not logged:** the HTTP logging middleware skips |
118 | 52 | `slog.Info` for `GET /healthz` to prevent k8s liveness/readiness probe traffic |
119 | 53 | from spamming logs. The endpoint still responds normally — only the log line |
120 | 54 | is suppressed. If you expect to see probe traffic in logs for debugging, hit |
121 | 55 | any other path or check the endpoint directly with `curl`. |
122 | | -- **Health-check polling interval:** the monitoring loop in `create-plan.md` |
123 | | - polls every 1 minute (not 2-3 min). Shorter intervals mean stalled agents are |
124 | | - detected and respawned faster, reducing idle time for the user. |
125 | | -- **Agents must never use curl:** `CLAUDE.md` mentions `curl` for "Manual |
126 | | - verification for API tasks" — that applies to human developers checking API |
127 | | - handler code, NOT to agents interacting with the board. Agents must use MCP |
128 | | - tools exclusively (`claim_card`, `heartbeat`, `update_card`, `complete_task`, |
129 | | - etc.). Using curl bypasses claim tracking, heartbeats, and the event bus, |
130 | | - leaving cards orphaned. This rule is enforced in the `workflowPreamble` |
131 | | - prepended to every skill prompt. |
0 commit comments