issue-comment.sh reports success for a comment that was never created (no readback) #976

Open
opened 2026-07-31 02:14:32 +00:00 by Mos · 1 comment
Contributor

tools/git/issue-comment.sh reported success for a comment that does not exist at the target issue.

Observed

A reviewer seat posted its verdict via the mandated wrapper:

export MOSAIC_GIT_IDENTITY=rev-974 GITEA_LOGIN=rev-974
issue-comment.sh -i 3107 -c "$(cat provider-verdict.md)"
→ "Added comment to Gitea issue #3107"   exit 0

The comment is not there. Measured immediately afterward against the API, twice, with a cache-buster and a wider page limit:

GET /repos/usc/uconnect/issues/3107/comments  →  count=1
   id=29879  [Mos]  2026-07-31T02:07:29Z      ← a different, earlier comment

The seat's comment is absent from the target issue and did not appear under its own login.

Why the wrapper cannot detect this

set -e                                     # line 5
...
tea issue comment "$ISSUE_NUMBER" "$COMMENT" --repo "$REPO_SLUG" --login "$GITEA_LOGIN_NAME"
echo "Added comment to Gitea issue #$ISSUE_NUMBER"     # line 65 — unconditional

set -e means a non-zero tea would abort before line 65 — so tea exited 0. The success message is therefore conditioned on the command not failing, never on the comment existing. There is no readback.

This is the null-case defect in the tooling the framework mandates for exactly these operations. The operator receives a positive confirmation and a zero exit for an effect that did not occur — and a review verdict is precisely the kind of artifact whose absence nobody notices until it is needed.

Undetermined

The cause of tea exiting 0 without creating the comment is not established here. Candidates, none confirmed:

  • get_gitea_login resolves a login independently of GITEA_LOGIN, so the effective identity may differ from the caller's intent
  • get_repo_slug may resolve a different repository than the caller's cwd implies
  • tea may exit 0 on a rejected write

Filed with the cause open deliberately rather than guessed at — the reportable defect is that the wrapper cannot distinguish any of these from success.

Required

  1. Read back the comment after posting and fail loudly if it is absent — assert the positive fact (a comment with the expected body exists at the expected issue, attributed to the expected login), not the absence of an error.
  2. Make the success message conditional on that readback.
  3. Echo the resolved repo slug and login before acting, so a caller can see what the wrapper actually targeted rather than what it intended.
  4. A needle: stub tea to exit 0 without creating anything — the wrapper must fail.

Note the repo already contains tools/git/test-issue-comment-readback.sh, which suggests this verification was specified at some point. It is not present in the installed copy on the affected host, so whatever it asserts is not protecting callers there.

Impact

Any agent using the mandated wrapper for issue/PR comments may believe a verdict, hand-off, or record was posted when it was not. Discovered because an orchestrator verified an artifact instead of accepting the seat's success report — the seat reported success in good faith, quoting the wrapper verbatim.

`tools/git/issue-comment.sh` reported success for a comment that does not exist at the target issue. ## Observed A reviewer seat posted its verdict via the mandated wrapper: ``` export MOSAIC_GIT_IDENTITY=rev-974 GITEA_LOGIN=rev-974 issue-comment.sh -i 3107 -c "$(cat provider-verdict.md)" → "Added comment to Gitea issue #3107" exit 0 ``` **The comment is not there.** Measured immediately afterward against the API, twice, with a cache-buster and a wider page limit: ``` GET /repos/usc/uconnect/issues/3107/comments → count=1 id=29879 [Mos] 2026-07-31T02:07:29Z ← a different, earlier comment ``` The seat's comment is absent from the target issue and did not appear under its own login. ## Why the wrapper cannot detect this ```bash set -e # line 5 ... tea issue comment "$ISSUE_NUMBER" "$COMMENT" --repo "$REPO_SLUG" --login "$GITEA_LOGIN_NAME" echo "Added comment to Gitea issue #$ISSUE_NUMBER" # line 65 — unconditional ``` `set -e` means a **non-zero** `tea` would abort before line 65 — so `tea` exited **0**. The success message is therefore conditioned on *the command not failing*, never on *the comment existing*. There is no readback. **This is the null-case defect in the tooling the framework mandates for exactly these operations.** The operator receives a positive confirmation and a zero exit for an effect that did not occur — and a review verdict is precisely the kind of artifact whose absence nobody notices until it is needed. ## Undetermined The cause of `tea` exiting 0 without creating the comment is **not** established here. Candidates, none confirmed: - `get_gitea_login` resolves a login independently of `GITEA_LOGIN`, so the effective identity may differ from the caller's intent - `get_repo_slug` may resolve a different repository than the caller's cwd implies - `tea` may exit 0 on a rejected write Filed with the cause open deliberately rather than guessed at — the reportable defect is that **the wrapper cannot distinguish any of these from success.** ## Required 1. **Read back the comment after posting** and fail loudly if it is absent — assert the positive fact (a comment with the expected body exists at the expected issue, attributed to the expected login), not the absence of an error. 2. Make the success message conditional on that readback. 3. Echo the **resolved** repo slug and login before acting, so a caller can see what the wrapper actually targeted rather than what it intended. 4. A needle: stub `tea` to exit 0 without creating anything — the wrapper must fail. Note the repo already contains `tools/git/test-issue-comment-readback.sh`, which suggests this verification was specified at some point. It is **not present in the installed copy** on the affected host, so whatever it asserts is not protecting callers there. ## Impact Any agent using the mandated wrapper for issue/PR comments may believe a verdict, hand-off, or record was posted when it was not. Discovered because an orchestrator verified an artifact instead of accepting the seat's success report — the seat reported success in good faith, quoting the wrapper verbatim.
Author
Contributor

ROOT CAUSE FOUND — and it is none of the three candidates in the original filing

tea issue comment does not exist. It is a phantom subcommand.

Verified independently, twice, from --help alone — no credential, no API call, nothing executed against the server:

$ tea issue --help
COMMANDS:
   list, ls      List issues of the repository
   create, c     Create an issue on repository
   edit, e       Edit one or more issues
   reopen, open  Change state of one or more issues to 'open'
   close         Change state of one ore more issues to 'closed'

There is no comment under tea issue. comment is a top-level entity:

$ tea --help
     comment, c    Add a comment to an issue / pr

Why it exits 0 and prints nothing wrong

With no matching subcommand, tea falls through to the parent command's default action — and tea issue defaults to list — treating the leftover words as arguments. It lists issues, succeeds, returns 0.

No write is ever attempted. There was no rejected write; there was no write.

This retires all three original candidates

Not login resolution, not slug resolution, not "tea exiting 0 on a rejected write." It also explains the one thing those candidates never did: why the failure is 100% reproducible and completely silent rather than intermittent. A broken credential is flaky; a phantom subcommand never works once.

Independent prior capture — this was known two weeks ago

A different agent (mosaic-ms-lead, 2026-07-17), on a different PR, measured the exact sibling case: tea pr comment does not exist either, tea silently falls back to tea pr list, exits 0, and nothing is posted. Two parties, two command groups, same shape, neither aware of the other — and that capture has been sitting in shared memory with the fix in it.

The fix

-    tea issue comment "$ISSUE_NUMBER" "$COMMENT" --repo "$REPO_SLUG" --login "$GITEA_LOGIN_NAME"
+    tea comment "$ISSUE_NUMBER" "$COMMENT" --repo "$REPO_SLUG" --login "$GITEA_LOGIN_NAME"

Verify with tea issue --help, which needs no credential.

The readback requirement in the original filing still stands and is arguably more important now: the correct call would also have been reported as success unconditionally. The phantom is the bug; the missing readback is why nobody noticed for two weeks.

Method note worth keeping

Reading the caller could never have found this. The shape analysis (unconditioned call, unconditional echo) was correct and insufficient — that the call was never made is not a fact contained in the source; it is a fact about the binary the source invokes.

Reading the caller does not verify the callee. When source calls an external binary, the binary's interface is a separate measurement — and --help is the cheapest one available.

## ✅ ROOT CAUSE FOUND — and it is none of the three candidates in the original filing **`tea issue comment` does not exist. It is a phantom subcommand.** Verified independently, twice, from `--help` alone — no credential, no API call, nothing executed against the server: ``` $ tea issue --help COMMANDS: list, ls List issues of the repository create, c Create an issue on repository edit, e Edit one or more issues reopen, open Change state of one or more issues to 'open' close Change state of one ore more issues to 'closed' ``` **There is no `comment` under `tea issue`.** `comment` is a **top-level** entity: ``` $ tea --help comment, c Add a comment to an issue / pr ``` ### Why it exits 0 and prints nothing wrong With no matching subcommand, tea falls through to the **parent command's default action** — and `tea issue` defaults to **list** — treating the leftover words as arguments. It lists issues, succeeds, returns 0. **No write is ever attempted.** There was no rejected write; **there was no write.** ### This retires all three original candidates Not login resolution, not slug resolution, not "tea exiting 0 on a rejected write." It also explains the one thing those candidates never did: **why the failure is 100% reproducible and completely silent rather than intermittent.** A broken credential is flaky; a phantom subcommand never works once. ### Independent prior capture — this was known two weeks ago A different agent (`mosaic-ms-lead`, 2026-07-17), on a different PR, measured the **exact sibling case**: `tea pr comment` does not exist either, tea silently falls back to `tea pr list`, exits 0, and nothing is posted. **Two parties, two command groups, same shape, neither aware of the other** — and that capture has been sitting in shared memory with the fix in it. ### The fix ```diff - tea issue comment "$ISSUE_NUMBER" "$COMMENT" --repo "$REPO_SLUG" --login "$GITEA_LOGIN_NAME" + tea comment "$ISSUE_NUMBER" "$COMMENT" --repo "$REPO_SLUG" --login "$GITEA_LOGIN_NAME" ``` Verify with `tea issue --help`, which needs no credential. **The readback requirement in the original filing still stands** and is arguably more important now: the correct call would also have been reported as success unconditionally. The phantom is the bug; **the missing readback is why nobody noticed for two weeks.** ### Method note worth keeping Reading the caller could never have found this. The shape analysis (unconditioned call, unconditional echo) was correct and insufficient — **that the call was never made is not a fact contained in the source; it is a fact about the binary the source invokes.** > **Reading the caller does not verify the callee.** When source calls an external binary, the binary's interface is a separate measurement — and `--help` is the cheapest one available.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#976