From 7ac936eb1c12acfa53d12dd0ce2f2cad559632cb Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Tue, 2 Jun 2026 20:15:33 +0200 Subject: [PATCH] =?UTF-8?q?restore=20the=20Give=20Claude=20hands=20initiat?= =?UTF-8?q?ive=20(T-208=E2=80=93T-225)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A pql rebuild reset planning state to the committed changelog baseline (max T-207), dropping the T-208–T-225 ticket tree sourced from self-analysis.md. Re-created it deterministically (same order → same IDs) and ran `pql plan export` so the changelog now carries the full tree: - T-208 initiative "Give Claude hands" - epics T-209 (PATH delivery), T-214 (bootstrap), T-218 (observability), T-222 (events) + tasks T-224/T-225, with blockers and decision refs. Committing the regenerated changelog makes the work durable: the next `pql plan rebuild` replays it instead of resetting to T-207. Co-Authored-By: Claude Opus 4.8 (1M context) --- .pql/changelog/ticket_deps/2026-06.sql | 5 +++++ .pql/changelog/tickets/2026-06.sql | 29 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/.pql/changelog/ticket_deps/2026-06.sql b/.pql/changelog/ticket_deps/2026-06.sql index 8f665b7c..c85eb16a 100644 --- a/.pql/changelog/ticket_deps/2026-06.sql +++ b/.pql/changelog/ticket_deps/2026-06.sql @@ -1,3 +1,8 @@ INSERT INTO ticket_deps (blocker_id, blocked_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-204', 'T-205', '2026-06-01 18:48:57', '2026-06-01 18:48:57', NULL, '114c7894d0dad6ad52fdaf55ac973ba8', 1) ON CONFLICT(blocker_id, blocked_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash); INSERT INTO ticket_deps (blocker_id, blocked_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-205', 'T-206', '2026-06-01 18:48:57', '2026-06-01 18:48:57', NULL, 'a7d8d53a36034ef6c6f48425d52da49e', 1) ON CONFLICT(blocker_id, blocked_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash); INSERT INTO ticket_deps (blocker_id, blocked_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-207', 'T-206', '2026-06-01 18:48:58', '2026-06-01 18:48:58', NULL, '03d07c24f7a03b17a9d21de621494494', 1) ON CONFLICT(blocker_id, blocked_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash); +INSERT INTO ticket_deps (blocker_id, blocked_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-211', 'T-214', '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, 'ad31bd62c76d0b1987008e2a9e8863ae', 1) ON CONFLICT(blocker_id, blocked_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash); +INSERT INTO ticket_deps (blocker_id, blocked_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-219', 'T-221', '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, 'c9cc9e67b4af3cdcb71aee1a0b34bf9c', 1) ON CONFLICT(blocker_id, blocked_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash); +INSERT INTO ticket_deps (blocker_id, blocked_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-210', 'T-211', '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, 'e481571d98a8569f88f339427198eff1', 1) ON CONFLICT(blocker_id, blocked_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash); +INSERT INTO ticket_deps (blocker_id, blocked_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-220', 'T-221', '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, 'f054e1277bdd77ecfdac7b78902aa543', 1) ON CONFLICT(blocker_id, blocked_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash); +INSERT INTO ticket_deps (blocker_id, blocked_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-224', 'T-214', '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, 'fb0b5ec4b479363fd4e4a4de1d9e5d82', 1) ON CONFLICT(blocker_id, blocked_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_deps.updated_at OR (excluded.updated_at = ticket_deps.updated_at AND excluded.hash > ticket_deps.hash); diff --git a/.pql/changelog/tickets/2026-06.sql b/.pql/changelog/tickets/2026-06.sql index 98696f41..b07cc8ea 100644 --- a/.pql/changelog/tickets/2026-06.sql +++ b/.pql/changelog/tickets/2026-06.sql @@ -50,3 +50,32 @@ INSERT INTO tickets (id, type, parent_id, title, description, status, priority, 3. A regression test exercises a representative motion (`j` → cursor down) and a mode change (`i` → insert). Refinement (2026-06-01): scoped Vim-first for a Vim-power-user demo this weekend. ''Author a YAML file'' was wrong — T-117 shipped single-chord resolution + scope flags + when-clauses only. Decomposed into children: T-204 (fix dead default preset — live bug), T-205 (key-sequence + count resolution), T-206 (modal editor motion/edit intents), T-207 (Vim mode service + status indicator). T-65 itself becomes assets/keymaps/vim.yaml + regression tests once children land. T-64/T-66 deferred (single-chord, easy; T-205 hands JetBrains shift+shift later). Foundation is shared, not Vim-only.', 'in_progress', 'medium', NULL, NULL, NULL, '2026-04-24 06:34:16', '2026-06-01 19:29:15', NULL, 'efc76aa91cfc889968d5bda60f897afa', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-220', 'task', 'T-218', 'Reflect active editor buffer + focused file + selection into EditorRegistry', 'For UI-driven (non-IPC) opens and focus changes, mirror the active file + selection into EditorRegistry (lib/src/editor/registry.dart, read by editor_commands.dart:120/136) so `editor active` / `editor list` track what the user is actually looking at, not only IPC-opened buffers. Acceptance: focusing/opening a file in the GUI is reflected in `clide editor active`.', 'backlog', 'high', NULL, NULL, NULL, '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, '024c50b98b31cb66da1a7361f068415d', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-216', 'task', 'T-214', 'Inject an agent context note describing the CLI surface + parity contract', 'Give the hosted agent a short note (CLAUDE.md fragment / system reminder) stating it is inside clide and how to drive the editor / git / file tree / panes via `clide ...`, plus the D-6 parity contract. Acceptance: a hosted agent is told, without the user having to explain it.', 'backlog', 'medium', NULL, NULL, NULL, '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, '032f132431556cd5b9e478ce052abfff', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-208', 'initiative', NULL, 'Give Claude hands', 'Make a Claude agent able to actually WORK inside clide: reach the CLI, know clide is hosting it, and observe the same workspace the user sees. Source: self-analysis.md (2026-06-02), a live dogfood probe by a Claude (Opus 4.8) running against a live instance (socket + MCP SSE up, version 2.1.0). + +Finding: the IPC/CLI foundation (D-1, D-6, D-56; built under T-99 incl. the C client T-126 and the `clide tail --events` stream T-129) works end-to-end at the socket level. But a fresh agent cannot REACH or OBSERVE it. Three blockers: +1. No `clide` binary on PATH, and no install path that delivers one (Epic A — blocker). +2. No bootstrap: nothing tells a fresh agent clide is running or where its socket is (Epic B). +3. The live UI panes / active file are not reflected in the CLI registries, so the D-6 parity premise (agent sees what the user sees) breaks (Epic C). + +Plus: a governance decision on WHICH agent model is the dogfood target (hosted stream-json session vs external CLI driver vs both) and an MCP follow-up. The pleasant surprise per the probe: the hard part (a live, correct, single-process IPC contract with proper 0/1/3 exit codes) is done; what''s missing is the last mile that puts the tool in the agent''s hands. NOTE: the report says ''daemon'' but D-56 dissolved it — this is the in-process IPC server; the socket contract is unchanged.', 'backlog', 'high', NULL, NULL, 'D-6', '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, '0c8826a602ec3d1f5fd9cb24d57cb4df', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-218', 'epic', 'T-208', 'Make the live workspace observable to the CLI (D-6 parity)', 'Gap 3 from self-analysis.md, verified in code. PaneRegistry (lib/src/panes/registry.dart) is written ONLY by the pane.spawn IPC path, so the built-in TabContribution panes — Claude (builtin/claude/src/extension.dart:42), Files (builtin/files/.../extension.dart:22), Editor (builtin/editor/.../extension.dart:52) — render in the kernel layout tree but never appear in `pane list` (read at pane_commands.dart:121). EditorRegistry is written by editor.open IPC (the Files tree uses it) but the active Claude pane / focused file / selection are not reflected. Result while the UI is in use: `clide pane list` -> {"panes":[]}, `clide editor active` -> {"active":null}. The ''agent sees what the user sees'' half of D-6 is missing.', 'backlog', 'high', NULL, NULL, 'D-6', '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, '1abeb011393b813cc9810eab72c56d15', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-222', 'epic', 'T-208', 'Agent-friendly event observation (pull-based)', 'Gap 4 from self-analysis.md. `clide tail --events` (T-129) is a never-returning stream — awkward for a request/response agent loop; the agent must background it and poll a file or it misses events between polls. Provide a pull-based form that fits an agent loop natively.', 'backlog', 'medium', NULL, NULL, 'D-6', '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, '52bfa2fc2cd53bf08cd94573643cdf15', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-221', 'task', 'T-218', 'Add a clide status one-shot snapshot command', 'Gap 6. Add a `status` command to the dispatcher (currently unknown -> exit 3) returning a single snapshot: active pane, focused file + selection, git summary, layout — the natural first call an agent makes to orient. Acceptance: `clide status` returns a structured snapshot with exit 0. Depends on the pane/editor registries (C1/C2) for its pane and file fields.', 'backlog', 'medium', NULL, NULL, NULL, '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, '5ba39937538d85c2475c0e706445bd07', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-209', 'epic', 'T-208', 'Ship the clide CLI on PATH', 'Gap 1 (BLOCKER) from self-analysis.md. The C client native/clide-cli/clide.c (T-126, done) is the real CLI, but there is no supported way for `clide` to land on an agent''s PATH: +- `make clide-cli` (Makefile:284) is a non-default target; `build` (Makefile:169) does not depend on it, so the binary is never produced by a normal build (native/macos-arm64/clide had never been built). +- `make install` (Makefile:195) copies the GUI bundle and `ln -sf $(INSTALL_PREFIX)/clide/clide $(INSTALL_DIR)/clide` (Makefile:200) symlinks the FLUTTER GUI runner — not the C client — on BOTH macOS and Linux (on macOS that path doesn''t even resolve inside clide.app). + +Net: `which clide` -> not found, `clide ping` -> exit 127. The CLI-first contract (D-1) has no delivery mechanism. Related to the broader installer epic T-46, but that is the GUI/runtime installer; this epic is specifically C-client-on-PATH delivery.', 'backlog', 'high', NULL, NULL, 'D-1', '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, '7b9a66f2daa4a692c7eb08cad919eb71', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-223', 'task', 'T-222', 'Add cursor-based pull events: clide events --since ', 'Return all events since a cursor plus a new cursor, alongside the existing stream (T-129). Acceptance: `clide events --since ` returns events + next-cursor with exit 0; repeated calls neither drop nor duplicate. Coordinate the cursor/persistence design with open questions Q-2 (event back-pressure) and Q-3 (event persistence + audit) — this dovetails with both.', 'backlog', 'medium', NULL, NULL, NULL, '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, '9c1c0c333670cd884794f5e8ccd521e0', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-212', 'task', 'T-209', 'In-app ''Install clide command in PATH'' affordance', 'VS Code-style: the GUI offers to install the `clide` shell command on PATH, for users who run the .app without `make install`. A command + command-palette entry that copies/symlinks the bundled C client to a PATH dir and reports success/failure. Acceptance: invoking it makes `clide` resolve on PATH from a fresh shell.', 'backlog', 'medium', NULL, NULL, NULL, '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, '9cd1982fd89036a7fd9c8aa181c73cca', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-219', 'task', 'T-218', 'Register built-in panes into the PaneRegistry the CLI reads', 'Make the kernel layout''s TabContribution panes (Claude / Files / Editor and any viewer) visible to `pane list` / `pane focus` by registering or mirroring them into PaneRegistry (lib/src/panes/registry.dart, read by pane_commands.dart:121). Acceptance: with the GUI open, `clide pane list` enumerates the live panes the user sees, with stable ids and focus state.', 'backlog', 'high', NULL, NULL, NULL, '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, 'a81479a52653c4e644baa58121c17f01', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-213', 'task', 'T-209', 'Regression test: clideVersion matches pubspec version', 'Gap 6 version-drift guard. clideVersion in lib/src/build_info.g.dart (generated by gen-build-info) currently matches pubspec.yaml `version:` (both 2.1.0). Add a test asserting they stay equal so an agent keying off `clide version` is never misled.', 'backlog', 'low', NULL, NULL, NULL, '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, 'af3253c0d2ad462a32f5ff31ba688d77', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-211', 'task', 'T-209', 'install delivers the C client to PATH on macOS and Linux', 'Fix `make install` so $(INSTALL_DIR)/clide (default ~/.local/bin/clide) IS the compiled C client, not the Flutter GUI binary. Today Makefile:200 symlinks the GUI bundle runner on both platforms. Acceptance: after `make install`, `which clide` resolves and `clide ping` returns {"pong":true} against a running instance on macOS and Linux. Blocked by ''Build the C client by default''.', 'backlog', 'high', NULL, NULL, NULL, '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, 'b9771b279b7249b8efe59eb702c5c05f', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-217', 'task', 'T-214', 'Pre-seed a Bash(clide *) permission allow rule for hosted agents', 'So the hosted agent is not prompted on every `clide ...` call. Acceptance: clide-hosted sessions get a Bash(clide *) allow rule in their effective settings.', 'backlog', 'medium', NULL, NULL, NULL, '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, 'bdcb7506945369bb6a84bd68583274b4', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-224', 'task', 'T-208', 'Decide the dogfood agent model (governance Q/D record)', 'Gap 5 from self-analysis.md — foundational. Two distinct ''Claude inside clide'' stories with different gaps: (A) the clide-HOSTED stream-json session (D-77/D-78) — the user''s primary Claude pane, which itself needs `clide` on PATH to drive the surrounding IDE; (B) an EXTERNAL agent (e.g. a Claude Code harness, TERM_PROGRAM=zed as observed) driving via `clide ...` IPC, which clide cannot fully observe because plain file reads / `make test` / `git` bypass clide. Decide the intended model — hosted, external, or both — and record it under governance/ (claim via `pql decisions claim`). Gates how Epic B bootstraps and how Epic C frames observability.', 'backlog', 'high', NULL, NULL, 'D-77', '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, 'c220bfde67438d19824eef10006a8c1a', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-214', 'epic', 'T-208', 'Bootstrap the clide-hosted/launched agent', 'Gap 2 from self-analysis.md. Even with the binary installed, a fresh session has no signal it is hosted by clide. There IS an MCP discovery lock (~/.claude/ide/.lock pointing at workspace + SSE URL) but NOTHING for the Bash/CLI path: no CLIDE_SOCK/CLIDE_WORKSPACE env var, no injected context note, no pre-seeded Bash(clide *) allow rule. Discovery is the difference between a capability existing and getting used — the probing agent had to be told ''you''re inside clide'' and then hunt for the socket.', 'backlog', 'high', NULL, NULL, 'D-6', '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, 'd95247263694e8a70fbeae3570b9579c', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-210', 'task', 'T-209', 'Build the C clide client by default', 'Make the `clide-cli` target (Makefile:284) a dependency of `build` (Makefile:169) and `install` (Makefile:195) so the C client is always produced. Today it builds only via the explicit, non-default `make clide-cli`. Acceptance: a plain `make build` / `make install` produces the C client binary for the current OS.', 'backlog', 'high', NULL, NULL, NULL, '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, 'e2bead8a722cf0375adf79d22050b30e', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-225', 'task', 'T-208', 'MCP transport reachable by an external agent', 'Gap 6 from self-analysis.md. The MCP SSE server (T-130, D-68) is live but mcp__ide__* tools are not exposed to an external agent out of the box, and getDiagnostics/executeCode were noted as stubs. The CLI path is the priority (Epics A-C); MCP follows. Decide + wire the minimal reachable MCP surface, or explicitly defer with a note. Relates to open question Q-32 (minimum MCP tool surface).', 'backlog', 'low', NULL, NULL, 'D-68', '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, 'ebc32a0ac23296877246ac17f50d15b5', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-215', 'task', 'T-214', 'Export CLIDE_SOCK/CLIDE_WORKSPACE + ensure clide on the child PATH', 'When clide spawns/hosts an agent (the stream-json session per D-77, and any launched agent), inject CLIDE_SOCK (the per-workspace deterministic socket, D-70) and CLIDE_WORKSPACE into the child env, and guarantee `clide` is on the child PATH. Acceptance: a hosted agent''s shell has both vars and `clide ping` works with zero manual socket discovery. Blocked by Epic A delivery.', 'backlog', 'high', NULL, NULL, NULL, '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, 'fed9697da84ca9013659b9a882475c3a', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);