A task can carry BOTH linkages at once, pointing two services at ONE issue:
- GitHub: maybeCreateTrackingIssue() ADOPTS a github sourceIssue as
githubTracking.issue (github-tracking.ts, `source_issue_linked`).
- GitLab: buildGitLabTaskProvenance() always returns sourceIssue AND
gitlabTracking.item for the same item, so on GitLab EVERY imported task with
gitlabCommentOnDone on was double-commented.
With comment-on-done enabled the issue-comment service and the tracking-comment
service both posted. Reproduced against the real wiring: two comments on
acme/widgets#42 ("✅ Task FN-1 ... resolved." then "✅ Done — ...").
The issue-comment services now suppress themselves when the tracking service
provably posts to the SAME target, and the tracking comment wins — it carries
commit/branch/PR/files/merged plus the release lines.
Identity, never "both linked": the two may legitimately target DIFFERENT issues
(a tracking issue linked separately from the source issue), which is two comments
on two issues and must keep working. GitHub matches on case-insensitive
owner/repo + number; GitLab is identical by construction because
resolveGitLabTarget() prefers the tracked item.
Both guards mirror the tracking services' `from === to` no-op guard: on a
same-column re-emit the tracking service stays silent, so suppressing there would
drop the only comment rather than dedupe it.
The net split is now disjoint: issue-comment owns "imported but not tracked",
tracking owns "tracked". Suppression is logged (once per completion, not the
high-frequency skip-noise FN-8024 removed) because a custom comment template
silently not rendering on a tracked issue is otherwise unexplainable.
Behavior change, documented in settings-reference.md: githubCommentTemplate /
gitlabCommentTemplate no longer render on a tracked issue.
Tests updated where they encoded the double-post path (they exercised the
services in isolation, so the duplicate was invisible). GitLab fixtures now
distinguish tracked vs imported-not-tracked shapes. Also asserts a PRE-EXISTING
gap left unchanged: resolveGitLabTarget() early-returns on an unresolvable item
and never falls back to sourceMetadata, so neither service comments there.
Verified non-vacuous: the 4 suppression tests fail against the pre-fix source;
the "still posts" tests pass either way by design. Gate green (294/122/63).
Fusion-Task-Id: FN-7575
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
My previous commit's comments claimed GitHubIssueCommentService "effectively
never fires" and was not the surface that posts. That is wrong, and acting on it
would have deleted working, documented behavior.
The issue-comment and tracking-comment services gate on different, disjoint
linkages:
- {GitHub,GitLab}IssueCommentService -> task.sourceIssue, the IMPORT linkage set
unconditionally by buildGitHubIssueSource, plus the documented
githubCommentOnDone / gitlabCommentOnDone settings (settings-reference.md:637,
651 — no Settings UI, but reachable via the settings API/file).
- {GitHub,GitLab}TrackingCommentService -> githubTracking.enabled /
gitlabTracking.item, the explicit TRACKING linkage.
resolveImportedIssueGithubTracking() returns undefined unless
githubLinkImportedIssuesToTracking or the tracking defaults resolve on, so an
imported issue with tracking off has sourceIssue and NO tracking linkage — the
issue-comment service is then the ONLY surface that comments. Neither service is
redundant; record that so neither is deleted as a "duplicate" later.
Also records the pre-existing overlap: a task carrying BOTH linkages with
comment-on-done enabled receives two comments, one per service. Orthogonal to the
release lines and left undeduped.
Comments only — no behavior change; the 76 comment-surface tests still pass.
Fusion-Task-Id: FN-7575
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
FN-7575 (issue #1916) added "Current version:" / "Target release:" lines to
GitHubIssueCommentService, but that service is gated on `githubCommentOnDone`
— default false, with no Settings UI — so it effectively never fires. The
"✅ Done —" comments on linked issues are posted by GitHubTrackingCommentService,
which had no version logic. The lines were invisible in production for ~10 days;
issue #1916's own close comment is the proof.
Extract the self-repo check and next-minor computation into a shared
fusion-release-version.ts and apply it across all four done-comment surfaces
(GitHub/GitLab x tracking/issue) so they cannot drift again.
- Release lines join `optionalLines` rather than being appended to the finished
string, so they count against DONE_COMMENT_MAX_LENGTH and shrink the title
budget; appending would silently blow the cap on long titles.
- Version resolution is a lazy resolver, so getCliPackageVersion()'s filesystem
walk only runs for self-repo comments.
- GitLab self-repo matching uses item.projectPath: resolveGitLabTargetFromItem()
prefers the numeric projectId, which never matches the slug.
- Non-self repos stay byte-for-byte unchanged (asserted).
Per the Surface Enumeration rule, regression tests assert the invariant across
every done-comment surface — both the pure formatters and the services that
post — plus case-insensitive slug matching (issue #1916 is "Runfusion/Fusion"),
in-progress transitions, the 0.0.0 sentinel, unparseable versions, the
lazy-resolution guarantee, and the truncation ladder under the length cap.
Verified non-vacuous: 10 of the new tests fail against the pre-fix source.
Fusion-Task-Id: FN-7575
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extends GitHubIssueCommentService so task-close comments on issues in the runfusion/fusion repo itself append both a current-version and target-next-minor-release line, while comments on all other linked repos stay byte-for-byte unchanged.
- Add isFusionSelfRepo() and computeNextMinorVersion() helpers to github-issue-comment.ts
- Append "Current version: v{current}" and "Target release: v{next-minor}" lines only when the linked source issue's repo is runfusion/fusion (case-insensitive)
- Fall back silently (no version lines) when the resolved version is unparseable or the unresolved 0.0.0 sentinel
- Add changeset (minor) documenting the new behavior
- Update docs/settings-reference.md and docs/gitlab-parity-inventory.md
- Expand github-issue-comment.test.ts coverage for self-repo vs other-repo behavior and version edge cases
Files changed:
.changeset/fn-7575-release-version-comment.md | 7 +
docs/gitlab-parity-inventory.md | 2 +-
docs/settings-reference.md | 2 +-
packages/dashboard/src/__tests__/github-issue-comment.test.ts | 142 ++++++++++++++++++++-
packages/dashboard/src/github-issue-comment.ts | 69 +++++++++-
5 files changed, 212 insertions(+), 10 deletions(-)
Fusion-Task-Id: FN-7575
Fusion-Task-Lineage: b7cf7e6f-8d96-4442-8595-5d54ea911481
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>