Skip to content

Heartbeat script should check if is there any new on main origin #75

Description

@hieplam
**[environment shift · 10:30 UTC] Master adopted a NEW written convention MID-CAMPAIGN
  (parallel owner activity, PR #195): Conventional Commits everywhere, NO `[CardName]`
  bracket prefixes** (they break release-please's parser — the same trap behind the R4
  nuance), enforced by a new `.githooks/commit-msg` + `check-conventional-commit.mjs` CI
  gate. Master also took #196 (gemini-sse fix) and release 1.11.2 — the campaign no longer
  has master to itself. **Every campaign card so far used bracket-style commits/PR titles;
  A12's in-flight branch carries 5+ bracket-prefixed commits that the new gate will
  reject.** Shaman response (R5): standing directive appended for all future briefs
  (Conventional form, examples given); A12 authorized to reword/rebase its commits
  (content unchanged) when the gate goes red — no interference with the live session.
  **Workflow observation: a convention can change UNDER a running campaign; the executor
  brief has no mechanism to receive mid-flight rule updates** (same digest-only gap as
  answers.md) — tribe fix-list.

Context

As there are many parrallel feature work by many sub agents, the main branch get update alot, Some time the file content stale during the work as another agent edit the same file or same logics.
This issue was known for a long time. But user notice LLM knows the file was stale and it fetch origin to see what changed and merge.

Above is what the Shaman caught when it found new commit in origin. User asked how can you know there are new changes in master? have you check by your sefl or the runner script? and here is what LLM answered

I checked myself — the runner had nothing to do with it. The runner's contract only reports card outcomes (shipped/escalated/blocked) through campaign-state.json and campaign-report.json; it never announces upstream master movement.

The discovery happened in two steps during the 10:22 UTC tick:

1. Passive signal from the harness: my session received file-change notices for files I had previously read — the repo's CLAUDE.md and .claude/rules/workflow-conventions.md now contained a new "Conventional Commits, no [CardName] bracket prefixes" section plus a new "Commit-message lint" row in the gate registry. The project memory index also gained a new "release-please manifest format trap" entry. Those notices told me something had changed on disk, but not how it got there.
2. Active verification by me: I then ran git fetch origin and git log origin/master --oneline -4 directly, which showed three merges the campaign didn't make — PR #195 (chore/git-conventions-cleanup…, the new convention + gate), PR #196 (fix/gemini-sse-framing), and PR #197 (release-please 1.11.2). I also confirmed the enforcement artifacts exist on master (scripts/check-conventional-commit.mjs, .githooks/commit-msg, docs/git-conventions.md) and inspected the A12 worktree's commits (git log origin/master..HEAD) to see they're bracket-prefixed and will trip the new gate.

So: harness file-change notices raised the flag, and my own git commands against origin/master established the facts. This follows the project's own resume protocol — "the file is data, the world is authority" — state files and notices are treated as hints, and GitHub/git reality is what I verify against before acting.

On the next turn, User wanted elaborate, LLM answered

The file-change notices arrived as <system-reminder> blocks injected into the tool-result stream — not as separate messages, not something I polled for. Concretely: after a Bash/Edit call returned its normal output, the harness appended a system-reminder immediately after, e.g.:

<system-reminder>
Note: /Users/home/repos/ai-dict/CLAUDE.md was modified, either by the user or by a linter.
This change was intentional... Here are the relevant changes (shown with line numbers): ...
</system-reminder>

Mechanism as best I can observe it: the harness tracks which files I've loaded into context via Read (or otherwise). When a tool call I make touches the filesystem and the harness notices that one of those previously-read files now differs on disk from what I have in context, it appends a diff-annotated reminder to that tool call's result. It's reactive and piggybacks on a call I already made — not a push notification or background watch I subscribed to, and not something the runner script sent. In this session it fired for CLAUDE.md, .claude/rules/workflow-conventions.md, and MEMORY.md because I'd read all three earlier and they'd since been edited (by the owner's parallel work merging PR #195, and by a memory-write elsewhere).

and

The mechanism, in more detail:

Claude Code (this harness) keeps a model of "what Claude currently believes a file contains," seeded whenever I read that file — either explicitly via the Read tool, or implicitly because the harness injected it into my context at conversation start (that's how CLAUDE.md and .claude/rules/workflow-conventions.md entered my context here: they appear as a <system-reminder> "Contents of ... CLAUDE.md" block right at session start, before I ran any tool).

After certain tool calls — in this session, specifically ones that do filesystem-touching work (Bash running git fetch/git merge, Write, Edit) — the harness re-checks any file I have a cached belief about. If the on-disk content no longer matches what's in my belief-model, it appends a <system-reminder> to that tool call's result, containing a line-numbered diff-style excerpt of the new content and an instruction that the change was "intentional" and shouldn't be silently reverted.

Three concrete instances from this session:

1. CLAUDE.md / workflow-conventions.md — I had these cached from session start. When I ran git fetch origin -q && git merge --ff-only (pulling in PR #189, then later #195/#196/#197), my local working copy of these files changed on disk because PR #195 edited them directly. The very next tool result carried the reminder, quoting the new "Conventional Commits, no bracket prefixes" section.
2. MEMORY.md — same pattern: I'd read it at session start, then at some point another process (an auto-memory writer, likely a separate session or a background summarizer) appended the "release-please manifest format trap" line to the file on disk. The next tool result I received carried the reminder.
3. campaign-state.json (under ~/.tribe/..., not even in the git repo) — I Write-created this file myself early on. Later the runner process (a separate bun process I'd launched via run_in_background) mutated it as cards shipped. Because I had a cached belief from my own Write call, the harness flagged the drift the next time I touched a tool.

What it is not: not a live filesystem watcher or push/subscribe channel, not something the runner script explicitly sends me, and not continuous — it's checked opportunistically, piggybacked onto the result of a tool call I was already making for some other reason. If I never called a tool again, I would not have been told about the drift. Its purpose (as best I can infer from the instruction text) is to stop me from making an Edit call with a stale old_string that no longer matches disk, or from confidently asserting a rule/fact that's since changed.

What should we do

We need to check if Claude code have done this well enough? or we can bring the check that alert session of file changes into the runner's heartbeat (as there are alot of parrallel works)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions