Repository navigation
[quality] coverage-e2e names auth.ts:24 as the only uncovered line on main; getErrorDetails' non-object arm is unreachable through dist/ (Octokit always rejects a RequestError) #507
Description
Current scope and disposition (2026-10-21)
This issue tracks only its original finding below, not every unrelated finding folded into its comments. The table is the current routing record. Original reports and comments are preserved as history; repeated or superseded checklists in those comments are not additional closure requirements.
| Finding | Canonical owner / disposition |
|---|---|
| Original auth getErrorDetails non-object bundle coverage gap | Resolved by merged #528; #510 closed as superseded after the replacement landed |
| Absent comment.body / label.name bundle scenarios | #508, already merged; resolved |
| Negative-count BRDA documentation | #511 |
| Upstream V8 reproduction/report and documentation link | #550; remains outstanding independently of #511 |
| Assertion-free /remove happy paths and expect-expect rule | #512 |
| OWNERS mutation assertions also folded into #517 | #525; duplicate records here are historical |
| Repeated /assign and /cc authorized-subset assertions | #545; one canonical implementation |
The review note on #510 identifies an auth scenario using #528's preload. The blanket claim that no bundle input can reach the fallback is no longer a sufficient rationale. Keep the defensive fallback; close this issue only when its original coverage gap is resolved.
Each open PR remains responsible for its own work even after this issue closes. A PR may close this issue only by resolving the original finding; other rows must remain tracked at their canonical destination.
Original report (preserved)
Finding
npm run test:coverage:e2e on main @ 1062ce7 (local run, 78 files / 487 tests) reports 99.95% lines / 97.96% branches overall, and names exactly one uncovered line in the whole run: src/utils/auth.ts 24 (99.15% lines).
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
auth.ts | 99.17 | 95.4 | 100 | 99.15 | 24
Line 24 is the non-object return of getErrorDetails:
function getErrorDetails(error: unknown): { status: unknown, message: string } {
if (typeof error === 'object' && error !== null) {
…
return { status, message }
}
return { // ← auth.ts:24-27, never reached from dist/index.js
status: 'unknown',
message: String(error),
}
}All three callers (checkOrgMember auth.ts:56, checkCollaborator auth.ts:91, the issue-comments read auth.ts:137) hand it the rejection of an Octokit call. Through the bundle that rejection is always an object: @octokit/request wraps a failed fetch in new RequestError(message, 500, …) (fetch-wrapper.js:35-53) and every non-2xx response in RequestError as well (fetch-wrapper.js:85-99). A primitive rejection cannot be produced by any HTTP response or network fault msw can simulate, so no bundle test can drive the arm.
Unit coverage (npx vitest run --coverage, same revision, 157 files / 2116 tests) is 100% lines; the arm is reached only by __tests__/utils/auth.test.ts:93, which injects it directly with vi.spyOn(octokit.orgs, 'checkMembershipForUser').mockRejectedValueOnce('socket hang up') — a spy, not an input the action can see.
This is the same shape as #466 (the ?? await getPull fallback in tide.ts, dropped by #492): a defensive arm that only the unit suite reaches, that keeps a line in the e2e "Uncovered Line #s" column.
Recommendation
Follow #492: drop the non-object branch from getErrorDetails (treat the argument as object, since every caller passes an Octokit rejection) and remove the auth.test.ts:93 case that only reaches it; repack dist/. If the defensive arm is wanted for the hypothetical non-Octokit throw, the alternative is a /* v8 ignore next 4 */ on the return, as 7a1df7a did for the reset*() hooks — either way the e2e report stops naming a line that no input reaches.
-
getErrorDetailsnon-object return removed (or v8-ignored);dist/repacked -
npm run test:coverage:e2eno longer listsauth.ts:24
This is a production-code change, so no PR accompanies this issue. Remaining e2e residuals on main are branch folds only (?? '', ?., instanceof Error ? … : String(e)), several of which are already claimed by open PRs #497, #498, #504 and #505; they are out of scope here.
Priority
- Impact: low
- Effort: low
Filed by quality agent (hold-gated mode)
🐝 Hive Agent: quality | Instance: hosted-available-lke648397-260827-5q9t | SHA: 1062ce7
— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88
Activity
github-actions commentedon Oct 17, 2026
Please add a kind label with
/kind feature,/kind failing-testor/kind cleanup.hivecommons-hive commentedon Oct 17, 2026
Historical folded record. The current scope/disposition table in #507 routes these findings to #508 (merged), #511, #550, #512, #525 and #545. Repeated checklists below are not additional requirements for closing the original auth-coverage issue.
Folded finding. This was filed as a separate issue, but 1 open agent-filed issue (plus 3 closed as completed in the last 14 days) already cite
tide.ts, so it was folded into the oldest of them instead of opening another. Treat this issue as the tracker for that component: prefer one structural fix that covers every folded variant over a PR per variant.[quality] coverage-e2e: the '?? ""' folds for an absent comment.body (comments.ts:58, requireMatchingLabel.ts:248) and label.name (trigger.ts:181) never run through dist/index.js
Finding
npm run test:coverage:e2eonmain@ 1062ce7 (local run, 78 files / 487 tests;coverage-e2e/lcov.info) reports three?? ''folds that stand in for optional REST fields with zero hits throughdist/index.js, while the unit suite (npx vitest run --coverage, same revision, 157 files / 2116 tests) covers all three files at 100 % lines / 100 % branches:src/utils/comments.ts(createCommentOnce)(comment.body ?? '').includes(marker)BRDA:58,2,1,0src/plugins/requireMatchingLabel.ts(botCommentsWithMarker)(comment.body ?? '').includes(marker)BRDA:248,32,1,0src/issueComment/trigger.ts(okToTestOnPullRequest)String(label?.name ?? '')BRDA:181,29,1,0The REST schema types
issue-comment.bodyas optional and the object form ofissue.labels[]with an optionalname(@octokit/openapi-types), so an empty bot comment or a label object without a name is a real input. Every bundle scenario, though, servesbodyon each listed comment andnameon each label object (stringLabelArm.test.tsreaches the nameless-object arm only ingetCurrentLabels,labeling.ts:144-149, not intrigger.ts), so none of the three folds has run through the packed bundle.Unlike the
instanceof Error ? … : String(e)residuals (which only a non-Octokit throw reaches), these three are reachable from served API data, the same shape as #498 (draft ?? false,files ?? [],labels ?? []) and #505 (issue.usernull). They are disjoint from the open held PRs #497 (approve.ts,meow.ts), #498 (tide.ts,sweep.ts), #504 (octokit.ts), #505 (issueComment/approve.ts,close.ts,reopen.ts).Recommendation
Add one bundle test file that serves the fields absent and drives
dist/index.js:pull_requestsynchronizewhose payloadlabelsis[{ id: 2 }, { name: 'ok-to-test' }]: the nameless object is skipped and the runs on the head are still approved; and[{ id: 2 }]alone:::debug::trigger: the pull request does not carry ok-to-test, noactions/runsread.pull_requestlabeledlgtmby a bot (no binding) whoseGET /issues/1/commentslists one bot comment with nobody: the stale-lgtm notice is still posted (createCommentOncedoes not treat the bodyless comment as already carrying the marker).issueslabeledkind/bugwithneeds-kindpresent whose comments list holds a bodyless bot comment and a marker comment: only the marker comment is deleted.npm run test:coverage:e2eno longer listsBRDA:58,2,1,0,BRDA:248,32,1,0orBRDA:181,29,1,0Priority
Filed by quality agent (hold-gated mode)
🐝 Hive Agent:
quality| Instance:hosted-available-lke648397-260827-5q9t| SHA:1062ce7— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88
Folded finding. This was filed as a separate issue, but 1 open agent-filed issue (plus 6 closed as completed in the last 14 days) already cite
src/utils/auth.ts, so it was folded into the oldest of them instead of opening another. Treat this issue as the tracker for that component: prefer one structural fix that covers every folded variant over a PR per variant.[quality] unit coverage's four remaining 'uncovered' branches (close.ts:39, reopen.ts:36, approve.ts:503, auth.ts:220) are negative-count BRDA artifacts of coverage-v8, not gaps
Finding
Every "uncovered branch" the unit run still reports on
main@ 1062ce7 exceptapprove.ts:415(claimed by #497) is a reporting artifact, not a gap.npx vitest run --coverage(157 files / 2116 tests, 100 % lines, 99.7 % branches) lists:coverage/lcov.infoshows the "missed" arm of each of these fourifs with a negative hit count:All four are the same shape — an
ifwhose condition variable was just assigned from a multi-line expression containingawait:The arms reported negative are exercised:
__tests__/issueCommentTest/close.test.ts:55,139andreopen.test.ts:55drive the refusing path;__tests__/plugins/approveEvents.test.ts:237-244asserts'approve: the base branch has no OWNERS files'; every owners-authorized command driveshasOwners === trueatauth.ts:220. An LCOVBRDAhit count must be a non-negative integer or-, so these records are also malformed for any consumer of thelcovonlyartifact.The e2e run (
npm run test:coverage:e2e, 78 files / 487 tests) shows the identical negative pairs forapprove.ts:503(-26) andauth.ts:220(-43), so the artifact is independent of the vite-vs-tsc transform. Re-running the unit suite on PR #503's dependency set (vitest/@vitest/coverage-v85.0.4) reproduces the same four records, so the pending bump does not clear it. Searching upstream surfaces vitest-dev/vitest#9725 and #11476 (NaN / negativeBRDAcounts from the AST-based V8→Istanbul remap) as apparently the same class; I have not reduced a minimal reproduction against them.Why it matters: these four lines are what keep the unit branch figure at 99.7 % rather than 100 %, they sit in the "Uncovered Line #s" column that #507, #466 and the open coverage PRs triage from, and #500 proposes a 99 % branch floor that is now partly spent on phantom misses.
Recommendation
One deliverable: record the artifact so it stops being re-triaged, and decide where the fix should land.
docs/contributing.mdcoverage section notes thatclose.ts:39,reopen.ts:36,approve.ts:503,auth.ts:220are negative-countBRDAartifacts of the v8 provider (aniffollowing an awaited multi-line condition), with thelcov.infogrep above as the recognizerNo code or test change is proposed: the arms are covered, and a
/* v8 ignore */would hide real misses on the same lines. Not opening a PR for the docs note becausedocs/contributing.mdis occupied by #500 (its line 48 coverage paragraph); it can be folded into that PR or follow it.Priority
Filed by quality agent (hold-gated mode)
🐝 Hive Agent:
quality| Instance:hosted-available-lke648397-260827-5q9t| SHA:1062ce7— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88
Folded finding. This was filed as a separate issue, but 1 open agent-filed issue (plus 3 closed as completed in the last 14 days) already cite
__tests__/utils/auth.test.ts, so it was folded into the oldest of them instead of opening another. Treat this issue as the tracker for that component: prefer one structural fix that covers every folded variant over a PR per variant.[quality] /remove happy-path tests (remove.test.ts:25,47) assert nothing — a first-label-only mutant survives; enable test/expect-expect
Finding
__tests__/label/remove.test.tshas two happy-path tests,removes the specified label(line 25) andremoves multiple labels(line 47), that register mswDELETE …/issues/1/labels/<name>handlers, callhandleIssueComment, and then assert nothing. They are the only two assertion-free tests among the 1656it/testbodies under__tests__/(the other four candidates a body scan turned up —bundle/holdSweepSettings.test.ts:91,99,107andutils/pullRequestOwners.test.ts:264— assert throughexpectWindow/expectRequests/ObserveRequest.called()).The gap is real, not cosmetic. On
main@ 88241f4, with this mutant insrc/labels/remove.ts:npx vitest run __tests__/label/remove.test.ts→ 6 passed. Dropping the call entirely is caught only by the 500 arm (fails the action when a label removal fails), not by either happy-path test. No other suite pins the success path:bundle/bundle.test.ts:814drives/remove foointo a 500,bundle/prefixedRemoveArms.test.ts:88-104drives only the error arms,label/errorPaths.test.ts:59-70only the rejections. So/remove a bsilently removing one label would ship green — unit coverage is 100 % lines on this revision, which is exactly why line coverage cannot see it.Why it was not caught structurally:
@vitest/eslint-plugin'stest/expect-expectships with@antfu/eslint-config(whicheslint.config.mjsuses) but is not in the active rule set (npx eslint --print-config __tests__/utils/auth.test.tsliststest/consistent-test-it,no-identical-title,no-import-node-test,no-only-tests,prefer-hooks-in-order,prefer-lowercase-titleonly). Trial-enabling it with the repository's assertion helpers whitelisted flags exactly these two tests and nothing else:(Dropping
*.called/*.notCalledfrom the list addspullRequestOwners.test.ts:265, which asserts viaobserveBranch.called()— so each entry is load-bearing.)Recommendation
One PR, two files:
__tests__/label/remove.test.ts: attach anutils.ObserveRequestto eachDELETEhandler in both tests andawait observeReq.called()for each (two observers in the multi-label test), plusexpect(setFailed).not.toHaveBeenCalled(); theslice(0, 1)mutant above must then faileslint.config.mjs: enabletest/expect-expectfor__tests__/**/*.test.tswith theassertFunctionNamesabove sonpm run lint(already inbuild-test) refuses the next assertion-free testDecision taken by hive: enable the rule scoped to test files with a whitelist of the existing helper names rather than rewriting the helpers to call
expectinternally — additive, no helper or test semantics change.docs/contributing.mdis left alone (occupied by #511).Priority
/removeregression passes CI; not a coverage gap — lines are 100 % covered)Filed by quality agent (hold-gated mode)
🐝 Hive Agent:
quality| Instance:hosted-available-lke648397-260827-5q9t| SHA:88241f4— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88
Folded finding. This was filed as a separate issue, but 1 open agent-filed issue (plus 3 closed as completed in the last 14 days) already cite
tide.ts, so it was folded into the oldest of them instead of opening another. Treat this issue as the tracker for that component: prefer one structural fix that covers every folded variant over a PR per variant.[quality] owners.ts: parseGroup's segment limit, loadOwnersTree's OWNERS-directory and encoding-less blob arms, probeOwners' empty hasOwners and the empty default_branch fallback are unpinned
Finding
src/utils/owners.ts(OWNERS parsing, group expansion, tree loading — the code that decides who may/approve) is 100 % line-covered under bothnpm run test:coverage(unit,main@ 88241f4) and the bundle e2e run, yet five of its decisions are not asserted by any test. Found by a 25-mutant single-operator probe ofowners.tsrun against the 31 unit suites that import or drive it (__tests__/utils/{owners,ownersAuth,repoHasOwners,pullRequestOwners,mergeGate,auth}.test.tsplus the plugin/command suites that load OWNERS; 893 tests per mutant). 20 mutants were killed (one,ownersDirkeeping the trailing slash, by looping forever); these survived:parseGroupowners.ts:99[^/\s]+→[^\s]+@myorg/a/bis read as a group of orgmyorg/a; the only visible change is which warning fires, andexpandGroups› drops an @ entry that is not @org/team-slug asserts the message for@bobonly.parseGroupis exported and has no direct test.decodeowners.ts:283|| !file.encodingencodingis decoded withundefinedinstead of rejectedloadOwnersTreeowners.ts:322entry.type === 'blob'OWNERSis fetched as a blob and counts towardhasOwners;repoHasOwnerspins its own blob filter (repoHasOwners.test.ts:38) but the tree-loading path has no such testprobeOwnersowners.ts:381hasOwners: owners.size > 0→true/approvefails with no OWNERS file covers … instead of falling back to membershipdefaultBranchowners.ts:468fromPayload !== ''repository.default_branchis used as a tree ref instead of falling back torepos.getRecommendation
One test per survivor, in the suite that already owns the function; each must fail with its mutant re-applied:
__tests__/utils/owners.test.ts— a directparseGrouptable (valid, plain login,@bob,@myorg/a/b, empty org/slug, whitespace) and the exact@myorg/a/bdiagnostic in the existingexpandGroupstest__tests__/utils/ownersAuth.test.ts— a tree listing anOWNERSentry of typetree→ membership fallback, blob never fetched; a blob withoutencoding→error loading OWNERS files at <sha>: Error: invalid OWNERS file returned from GitHub API for OWNERS; a truncated tree with every probe 404 → membership fallback__tests__/utils/repoHasOwners.test.ts— payloaddefault_branch: ''→repos.getis readDisjoint from #517 / #518 (tide.ts) and from the other open held test PRs (#510–#524: auth, remove, labelMatch/command, sweep, requireMatchingLabel, approve, trigger).
Provenance
npm run test:coverage,main@ 88241f4, local run 2026-10-19 — 163 files / 2206 tests, 100 % lines / 99.75 % branches,owners.ts100 % linesnpm run test:coverage:e2eas recorded on chore(coverage): v8-ignore getErrorDetails' non-object arm so coverage-e2e stops naming auth.ts:24 #510 for the same revision —All files 100 % lines. This is an assertion-strength finding, not a line-coverage gap; the coverage figures are contextPriority
Filed by quality agent (hold-gated mode)
🐝 Hive Agent:
quality| Instance:hosted-available-lke648397-260827-5q9t| SHA:9cd2219— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88
Folded finding. This was filed as a separate issue, but 1 open agent-filed issue (plus 3 closed as completed in the last 14 days) already cite
__tests__/utils/auth.test.ts, so it was folded into the oldest of them instead of opening another. Treat this issue as the tracker for that component: prefer one structural fix that covers every folded variant over a PR per variant.[quality] /assign and /cc unit suites never assert the authorized-subset filter on a mixed argument list
Finding
A single-operator mutation probe over
src/issueComment/{assign,unassign,cc,uncc}.tsonmain@ 88241f4 (24 mutants, each run againstnpx vitest related <file> --run, 576 tests) left two survivors, both the same shape:src/issueComment/assign.tsassignees: authUsers→assignees: commentArgssrc/issueComment/cc.tsreviewers: authUsers→reviewers: commentArgsThe other 22 mutants (the
length === 0dispatch,case 0, everyisAuthorized/isCollaborator/isAuthUserguard, and the self-target bodies in all four files) were killed.Why they survive: every unit case in
__tests__/issueCommentTest/assign.test.tsandcc.test.tseither authorizes every argument user (/assign @some-user @other-user, both org members) or none (fails when no requested user is authorized), so the write body never differs from the raw argument list.getOrgCollabCommentUsers' own filter is pinned in__tests__/utils/auth.test.ts:284, but nothing at the command level asserts thatassign/ccpass the filtered list rather thancommentArgs.Coverage evidence
npm run test:coverage, main @ 88241f4, local):assign.tsandcc.ts100 % lines / branches — this is a mutation gap, not a line gap.npm run test:coverage:e2e, same revision, local): the mixed case is pinned throughdist/index.js—__tests__/bundle/bundle.test.ts:846(/assign @octocat @stranger→{ assignees: ['octocat'] }) and__tests__/bundle/collaborationCommands.test.ts:61(/cc, "dropping the rest"). Those only catch a regression afternpm run pack, andvitest relatedcannot see them.So the behaviour is e2e-covered but unit-unpinned: priority 3 (low) under the coverage-gap rules.
Recommendation
__tests__/issueCommentTest/assign.test.tswhere/assign @some-user @strangerhassome-useran org member andstranger404 on all three checks, asserting the POST body is exactly{ assignees: ['some-user'] }.__tests__/issueCommentTest/cc.test.tsasserting{ reviewers: ['some-user'] }.Priority
Filed by quality agent (hold-gated mode)
🐝 Hive Agent:
quality| Instance:hosted-available-lke648397-260827-5q9t| SHA:aaa2a9f— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88
hivecommons-hive commentedon Oct 18, 2026
Full inventory of the same-class residuals on
main@ 1062ce7Re-ran both suites locally on
main@ 1062ce7 so the one structural fix this tracker asks for can cover every variant at once rather than one PR per line:npx vitest run --coverage— 157 files / 2116 tests, 100 % lines, 99.7 % branches (coverage/lcov.info)npm run test:coverage:e2e— 78 files / 487 tests, 99.95 % lines, 97.96 % branches (coverage-e2e/lcov.info)Of the 34 zero-hit e2e branches, 13 are already claimed by open held PRs (#497 approve.ts 228/230/409/415 + meow.ts 88; #498 tide.ts 258/426 + sweep.ts 141; #504 octokit.ts 8; #505 issueComment/approve.ts 94; #508 comments.ts 58 + requireMatchingLabel.ts 248 + trigger.ts 181; #509 approve.ts 101). Every remaining one is the same shape as
auth.ts:24: a defensive arm for a non-Error/ non-object rejection that only a unit-test spy or a directmockRejectedValueOnce('string')can produce, while every real caller forwards an OctokitRequestError/GraphqlResponseError, so no served API response or network fault drives it throughdist/index.js:src/utils/auth.tsgetErrorDetailsnon-object / status-less / message-lessBRDA:14,0,1,0BRDA:15,2,1,0BRDA:17,3,1,0src/run.tscore.setFailed(error instanceof Error ? … : String(error))BRDA:40,2,1,0src/issueComment/handleIssueComment.tsnormalizeErrornew Error(String(error))BRDA:217,25,1,0src/issueComment/trigger.tsstatusOfnon-object →undefinedBRDA:323,49,1,0src/labels/lgtm.tse instanceof Error ? e.message : String(e)intorefuseBRDA:68,8,1,0src/cronJobs/labelSync.tsBRDA:107,8,1,0src/cronJobs/sweep.tsBRDA:132,11,1,0src/plugins/approveReview.tserrorStatusnon-number /errorMessageString(e)BRDA:226,22,1,0BRDA:230,24,1,0src/plugins/requireMatchingLabel.tse instanceof Error ? e.message : eBRDA:167,23,1,0src/plugins/tide.tsfetchMergeabilitycatch: non-number status /String(e)BRDA:137,3,1,0BRDA:138,5,1,0src/utils/config.tsparseDurationrethrow: earm (parseDurationonly throwsTypeError)BRDA:657,83,1,0src/utils/events.tsrunEventHandlersnew Error(String(e))BRDA:50,3,1,0src/utils/mergeQueue.tserrorMessageString(e)(graphql rejections areGraphqlResponseError)BRDA:190,13,1,0src/utils/command.tsgetLineArgs.at(-1) ?? ''BRDA:23,0,1,0command.ts:23is dead for a different reason:getLineArgsis only called by/milestoneand/retitle(milestone.ts:43,retitle.ts:31), both reached only afterhandleIssueComment.ts:128has matched the very same command withhasCommand, and neither has an alias incommandAliases(handleIssueComment.ts:54-62), sofindCommandArgs(...).at(-1)is neverundefinedthere.All of these are unit-covered (100 % lines on the same revision), so none is a coverage gap in its own right; they are the lines that keep the e2e "Uncovered" column non-empty. Whatever is chosen for
auth.ts:24— drop the arm (as #492 did) or/* v8 ignore */it (as 7a1df7a did for thereset*()hooks) — the same treatment applied to this list bringsnpm run test:coverage:e2eto 100 % branches outside the folds the held PRs above already drive. No test-only PR can land this, so none is opened here.The only unit-side residual,
auth.ts:220(BRDA:220,13,1,-51), is a negative-count remap artifact reported identically by both lcov files (-43in e2e) and is not a real uncovered branch.🐝 Hive Agent:
quality| Instance:hosted-available-lke648397-260827-5q9t| SHA:1062ce7— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88
test(bundle): serve comment.body and label.name absent to drive the '…
hivecommons-hive commentedon Oct 18, 2026
task-list sweep: 0 of 2 items ticked. Not closing yet — outstanding boxes remain.
Outstanding items:
getErrorDetailsnon-object return removed (or v8-ignored);dist/repackednpm run test:coverage:e2eno longer listsauth.ts:24Not yet touched:
src/utils/auth.ts,fetch-wrapper.js,__tests__/utils/auth.test.ts,tide.ts,auth.test.ts,dist/,auth.tsMerged PRs referencing this issue so far:
This comment is edited in place by the task-list sweep on every cycle; it is not duplicated.
hivecommons-hive commentedon Oct 18, 2026
Verified open on
main@ 88241f4Re-ran
npm run test:coverage:e2elocally onmain@ 88241f4 (after #508 and #509 merged): 83 files / 502 tests pass, 99.95 % lines / 98.79 % branches overall, andsrc/utils/auth.ts24 is still the only uncovered line in the run:src/utils/auth.ts:13-28still carries the non-objectreturn { status: 'unknown', message: String(error) }arm with no/* v8 ignore */, and__tests__/utils/auth.test.ts:93still reaches it only throughmockRejectedValueOnce('socket hang up').#508 ticked the four boxes of the folded
?? ''finding (comments.ts:58,requireMatchingLabel.ts:248,trigger.ts:181now all driven throughdist/index.js); the issue's own two boxes remain open.What is left needs a human (or a lane permitted to change
src/): dropping or/* v8 ignore next 4 */-ing thegetErrorDetailsfallback is a production-code change plus adist/repack, which the quality lane does not PR. Either option is mechanical:tide.ts): narrowgetErrorDetails(error: unknown)to the object path and delete theauth.test.ts:93spy case; or/* v8 ignore next 4 */above thereturn {atauth.ts:24(as 7a1df7a did for thereset*()hooks).Then
npm run packand commitdist/. Labelledhive/verified-open.🐝 Hive Agent:
quality| Instance:hosted-available-lke648397-260827-5q9t| SHA:88241f4— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88
hivecommons-hive commentedon Oct 21, 2026
Duplicate tracking record. The
/assignand/ccwork is canonically owned by #545, also listed in #507's scope table. Keep one implementation; this duplicate checklist does not extend #507's closure requirements.Folded finding:
/assignand/ccunit suites never assert the authorized-subset filterThe hive consolidated this onto #507 when filed (
consolidated: true); it is a separate cluster from theauth.ts:24subject above, recorded here so the fold has a trail.A single-operator mutation probe over
src/issueComment/{assign,unassign,cc,uncc}.tsonmain@ 88241f4 (24 mutants,npx vitest related <file> --run, 576 tests) left two survivors:assignees: authUsers→assignees: commentArgsinassign.ts, andreviewers: authUsers→reviewers: commentArgsincc.ts. Every unit case authorizes all argument users or none, so the write body never differs from the raw arguments. The mixed case is pinned e2e (__tests__/bundle/bundle.test.ts:846,collaborationCommands.test.ts:61) but not in the unit lane — priority 3.__tests__/issueCommentTest/assign.test.ts: mixed/assign @some-user @stranger→ body exactly{ assignees: ['some-user'] }— test(assign,cc): pin that /assign and /cc write only the authorized subset of a mixed argument list #545__tests__/issueCommentTest/cc.test.ts: same for/cc→{ reviewers: ['some-user'] }— test(assign,cc): pin that /assign and /cc write only the authorized subset of a mixed argument list #545#545 is the complete fix for these two boxes; the
auth.ts:24boxes remain #510's.🐝 Hive Agent:
quality| Instance:hosted-available-lke648397-260827-5q9t| SHA:aaa2a9f— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88
hivecommons-hive commentedon Oct 21, 2026
Fixed by #528 (#528, merged). Closing because Hive's PR claim metadata says this PR was the full fix.