Skip to content

afx spawn: "On it" safety check false-positives on substring matches and architect's own comments #1054

@amrmelsayed

Description

@amrmelsayed

Symptom

afx spawn <issue> --protocol <name> refuses with a "someone may already be working on this" warning in two scenarios where no one actually claimed the work:

  1. The architect's own analysis comment is treated as an "On it" claim. When the architect posts a long-form follow-up analysis on the issue before spawning (a natural workflow), the spawn safety check matches it even though the architect IS the one initiating the spawn.
  2. Comments containing the substring "on it" inside unrelated words match. A comment with "evaluate it on its own merits" or "it depends on iteration timing" gets matched as if it were a literal "on it!" claim.

Both fire today, both required --force to work around. Forcing erodes the value of the safety check over time (architects learn to reach for --force reflexively, defeating the protection).

Reproduction

Both are reliably reproducible.

Substring false positive:

  1. Post an issue comment containing the phrase "on its own" or "on iteration" or similar (substring on it inside another word).
  2. Try to spawn a builder for that issue.
  3. Observe: [error] Issue #N has "On it" comment from 0h ago...

Architect-own-comment false positive:

  1. Post any analysis comment on an issue as the architect who will run afx spawn.
  2. Try to spawn the builder.
  3. Observe: same error, citing the architect's own comment back at them.

Root cause

packages/codev/src/agent-farm/commands/spawn-worktree.ts:524-527:

const onItComments = issue.comments.filter((c) =>
  c.body.toLowerCase().includes('on it'),
);

Two bugs in the same call site:

  1. .includes('on it') is substring matching, not word matching. Phrases like on its own, on iteration, or claim on item #5 all contain on it as a substring and trigger the check.
  2. No filter for the spawning architect's own comments. A comment from the same GitHub user running afx spawn cannot, by definition, be a claim that someone else is working on the issue. The check ignores authorship and treats every match the same way.

Proposed fix

Two small changes at the same call site:

  1. Word-boundary regex instead of substring:

    const onItPattern = /\bon it\b/i;
    const onItComments = issue.comments.filter((c) => onItPattern.test(c.body));

    \b on both sides requires a word boundary, so:

    • on it! matches (boundary after t because of !)
    • on it, matches
    • on it (end of sentence) matches
    • on its own does NOT match (no boundary between t and s)
    • on iteration does NOT match
    • on item does NOT match
  2. Filter out the spawning architect's own comments:

    const spawnerLogin = await getSpawningArchitectLogin();   // resolves via gh auth
    const onItComments = issue.comments.filter((c) =>
      c.author.login !== spawnerLogin && onItPattern.test(c.body),
    );

    The architect's own analysis or planning comments are not "someone else is on this" claims, regardless of phrasing.

getSpawningArchitectLogin() can either reuse an existing helper that resolves the GitHub login (likely already used elsewhere in the agent-farm or forge code) or call gh auth status --show-token and parse the login line. The forge abstraction probably already exposes the current user's login.

Why both fixes (not just one)

  • Word-boundary fix alone: the architect could still trigger their own check by posting a comment that literally says "on it" anywhere (e.g., "this depends on it before we can ship").
  • Author filter alone: a substring match like on its own still trips on teammates' analysis comments, defeating the check's value.
  • Together: the check fires only when a non-architect user posts an actual \bon it\b claim phrase. False positives collapse to near-zero; the genuine "someone else is working on this" protection remains intact.

Acceptance criteria

  • \bon it\b (case-insensitive) replaces the .includes('on it') substring match.
  • Comments authored by the spawning architect's GitHub login are filtered out before the regex check.
  • Existing test 'fatals when recent "On it" comment exists and no --force' at spawn-worktree.test.ts:385 still passes (regression for the genuine "someone else claimed it" case).
  • New test: architect's own comment containing On it! body → spawn proceeds without --force.
  • New test: comment from a different user with body containing on its own (substring) → spawn proceeds without --force (no false match).
  • New test: comment from a different user with body containing On it, working a fix. → spawn refused without --force (genuine claim still caught).
  • Warning message format (Issue #N has "On it" comment from Mh ago (by @user)...) is unchanged for the cases where the check still fires.

Out of scope

  • Adding more claim phrases (I'll take this, working on it, claiming this, WIP) to the regex. Useful but a separate enhancement; this issue focuses on fixing false positives in the existing single-phrase check.
  • Auto-deleting the spawning architect's own stale "On it" comments. The author filter sidesteps this; deletion would be over-reaching.
  • Multi-architect workspace handling. The author filter uses the GitHub login of whoever runs afx spawn right now, which is the right behavior in multi-architect setups too.

Suggested protocol

BUGFIX. Fully specified, mechanical fix, no architectural ambiguity. ~30-50 LOC including the three new test cases. Single builder.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/towerArea: Tower server / agent farm CLI

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions