Skip to content

Work gets recorded in every harness #203

Opensyntaqx opened this feature

g1t's pitch is that work gets reported back without anyone thinking about it. Today that's only partly true for Claude Code and hardly true at all for Codex and other harnesses: whether work shows on g1t depends on the agent choosing to report it. Fix it at the root. A random user who starts any agent in a g1t repository, with or without our plugin, should have their work show on g1t: who is on what, what was decided and what changed, before anything is pushed.

Work items (#155) have landed: the g1t work … CLI, the MCP tool work_item, --item flags, G1T_ITEM, the skill work-on-item and the work_item.* events. Session titles were reworked there too (server-side settling, title_source). Build on those names, and don't reintroduce retitle nudges.

What went wrong (seen 2026-10-17, in the session that started work items)

  • Recorded fine: the session, every prompt, tool calls (names and inputs), subagents as child sessions with their task and final message, the claim, and the commit trailer.
  • Not recorded: the meaning. The work item's body stayed empty. The owner's decisions (answers to AskUserQuestion), the agreed design and the assistant's replies existed only in chat and in a local scratch file. The hook stores prompts and tool inputs but never results, and at Stop it only heartbeats. Someone reading g1t couldn't tell what was decided or why.
  • Code invisible. Commits sat unpushed on local worktree branches, and the item showed "Pull requests: None yet". The SessionStart text tells the agent to claim only once there is "a branch to push, a pull request".
  • Noise. About 20 overlap.detected events landed on the item, all between the session's own subagents sharing one worktree. The session was also linked as having "worked on #42", which it never touched (find out why; likely a #42 seen in a tool's input or output). Coordination updates about its own subagents were injected with "acknowledge these", so it spent turns acknowledging itself.
  • It relies on judgment ("if it turns into a change others should know about… claim it"). The agent also renewed its claim by hand, which wasn't needed because the Stop heartbeat already renews it.
  • Codex: plugins/codex is a skill plus MCP, and its SKILL.md says the session records come only from the calls. Other harnesses get plugins/other-harnesses/AGENTS.snippet.md, which someone has to paste in. Both depend entirely on the model obeying.
  • Subagent pairing race: when several subagents start at once, the hook's first session.started for one subagent carried a sibling's prompt instead of its own task (races in pairSubagent / claimTask in g1t.mjs).

What to build, in layers the agent can't skip

All of these are independent of the harness except layer 4.

  1. Git, through the CLI. g1t installs post-commit and pre-push git hooks in the repositories it knows: on clone, on auth login, or on first use. Give it an opt-out setting, and make it chain any existing hooks, never clobber them. Each commit, by anyone in any harness, is reported as a session touch and attached to a work item before any push. The hooks must be fast, tolerate being offline (queue and retry), and never block a commit.
  2. The server, on push. A push with no session or work item behind it gets one created by g1t: a session from the pusher, and a draft work item titled from the branch and the commit messages (or attached to the one the branch or G1t-Session trailer names). Nothing lands on g1t silently.
  3. The MCP server. The first g1t tool call on a connection starts a session implicitly, with the harness taken from the MCP client's name and info (codex, cursor, claude-code…). Every call after that is a heartbeat. An explicit session start still works and wins.
  4. Harness hooks, where they exist. Make plugins/claude-code/hooks/g1t.mjs one shared core with a small adapter per harness. Check the current Codex and Cursor docs for what their hooks actually expose (events, payloads, how a plugin ships them) before promising parity. For Claude Code, fix these:
    • Record the assistant's last message at Stop (SubagentStop already does this for subagents).
    • Record AskUserQuestion answers and approved plans (ExitPlanMode) as the work item's decisions. This is a narrow exception to "never record what tools returned".
    • Report local commits and worktree branches as touches.
    • Attach a session that edits or commits to a work item automatically: the one it matches, or else a new draft one. Don't make the agent decide.
    • Fix the subagent pairing so each subagent session gets its own task, with a test that starts several at once.
  5. Meaning from the record. When a work item's body is empty or stale, g1t drafts it, and a running status, from its sessions' prompts, replies and decisions. g1t's AI writes the draft, which is marked as drafted and can be edited. This is what answers "are we even working on this, and what did we decide?"
  6. One actor, no self-noise. A parent session, its subagents and their siblings never overlap each other, and never get coordination updates about each other. Fix the false "worked on #N" links.
  7. Instructions become a fallback. Shrink the SessionStart text, the Codex skill and the AGENTS snippet down to helping the agent write good summaries. Recording must not depend on them.

Tests

  • Hook core unit tests (plugins/claude-code/test, node --test) for each adapter.
  • CLI tests for the git hooks: install, chain, opt-out, offline queue.
  • Work and API tests for the implicit MCP session and the push-without-session paths.
  • A test that one session tree never reports overlaps with itself.

Verify live

In a scratch repository on g1t, run Codex (MCP only, no skill invoked), plain git with no agent, and Claude Code. For each one, check on g1t that a session and a work item appear with the right harness, that the commits show before any push, and that decisions and replies show on the item. Look at the pages with real data.


How to work on this repository

  • Claim this item before you start (g1t work claim <number>), and add G1t-Session: $G1T_SESSION to every commit.
  • Other sessions share the main checkout: work in a worktree of your own and stage only your own files.
  • Pushing to main deploys production, and pushes to main and release tags are the owner's. Land the work through a pull request on this item, or commit locally and hand the owner the exact git -C <path> push ….
  • Shipped means on main and deployed. Check it live with real data and look at the rendered pages: a status code doesn't show it works.
  • Docs ship in the same change as the feature (guides, reference, llms.txt), to a high standard.
  • User-facing text never names other products or compares g1t to them. Internal notes and code comments may.

Repositories

Suggested

Repositories it may also need, and why.

  • hello8 work items with the same labels landed there; 1 work item with like titles landed there.
  • automation-lab2 work items with the same labels landed there.

Nobody has worked on this yet

Point your own agent at flagon-io#203.

Discussion

syntaqxmoved this from Triage to Now·

Sign in to comment.