fix: surface the shadow review's own comment on a plain PR reassignment #479

Merged
igor merged 2 commits from agent/476-fix-rework-pickup-ignores-feedback-when-the into master 2026-08-09 03:27:49 +00:00
Collaborator

What this PR does

  • fix: surface the shadow review's own comment on a plain PR reassignment
  • Add review_reassignment_feedback_section (lib/review.sh): on a
    reassignment where pending_rc_body is empty (last shadow verdict was
    COMMENT, not REQUEST_CHANGES), find the most recent shadow-review
    comment (bot-authored, filtered out of every other comment feed) plus
    any comment posted by someone else after it, and fold that into the
    rework prompt. Empty when there's no shadow-review comment on the
    thread at all, so the existing "no changes made" no-op stays correct.
  • Wire it into bin/tick.sh's reassignment pickup path, only on the
    non-binding branch (the RC-binding branch already carries its own
    findings via BINDING_RC_BODY).
  • Fence the shadow-review comment as untrusted, model-generated text and
    strip forged structural delimiters/headings before it reaches the
    prompt -- same treatment review_dismissals_section already applies to
    bot-authored, diff-derived text just above it in the same file.
  • Tests in bin/test-review.sh: reassignment with a COMMENT-verdict
    shadow comment (+ a post-review operator comment) surfaces both; no
    shadow-review marker at all leaves the section empty (unchanged from
    today); a comment predating the review, an unmarked bot comment, and a
    superseded older round are all excluded; a forged delimiter inside the
    shadow comment is neutralised; plus fetch-failure / malformed-payload
    degrade-to-empty coverage matching the sibling function's contract.

Test plan

  • make test passes (full suite, including the new/extended
    bin/test-review.sh cases)
  • make lint passes (shellcheck + mdl)
  • No manual verification needed beyond the above; this path only runs
    inside a live PR-reassignment pickup against a real Forgejo PR, which
    isn't reachable from this worktree.

Closes #476

## What this PR does - [x] fix: surface the shadow review's own comment on a plain PR reassignment - [x] Add `review_reassignment_feedback_section` (`lib/review.sh`): on a reassignment where `pending_rc_body` is empty (last shadow verdict was `COMMENT`, not `REQUEST_CHANGES`), find the most recent shadow-review comment (bot-authored, filtered out of every other comment feed) plus any comment posted by someone else after it, and fold that into the rework prompt. Empty when there's no shadow-review comment on the thread at all, so the existing "no changes made" no-op stays correct. - [x] Wire it into `bin/tick.sh`'s reassignment pickup path, only on the non-binding branch (the RC-binding branch already carries its own findings via `BINDING_RC_BODY`). - [x] Fence the shadow-review comment as untrusted, model-generated text and strip forged structural delimiters/headings before it reaches the prompt -- same treatment `review_dismissals_section` already applies to bot-authored, diff-derived text just above it in the same file. - [x] Tests in `bin/test-review.sh`: reassignment with a COMMENT-verdict shadow comment (+ a post-review operator comment) surfaces both; no shadow-review marker at all leaves the section empty (unchanged from today); a comment predating the review, an unmarked bot comment, and a superseded older round are all excluded; a forged delimiter inside the shadow comment is neutralised; plus fetch-failure / malformed-payload degrade-to-empty coverage matching the sibling function's contract. ## Test plan - [x] `make test` passes (full suite, including the new/extended `bin/test-review.sh` cases) - [x] `make lint` passes (shellcheck + mdl) - [x] No manual verification needed beyond the above; this path only runs inside a live PR-reassignment pickup against a real Forgejo PR, which isn't reachable from this worktree. Closes #476
fix: surface the shadow review's own comment on a plain PR reassignment
All checks were successful
Lint / check-sync (pull_request) Successful in 6s
Lint / check-sync (push) Successful in 6s
44770aa3f7
Author
Collaborator

🤖 Review — REQUEST_CHANGES (automated)

CI for 44770aa3: success

Adds review_reassignment_feedback_section (lib/review.sh), wires it into the plain-reassignment prompt in bin/tick.sh, and covers the new function with unit tests. The library function itself is well-built and the behavioural tests are genuinely good — my block is about the one line that makes the fix actually work being both untested and mis-described.

Blocking

  • bin/test-review.sh (new "source assertions" block) claims coverage it doesn't provide. The comment says the test pins that the plain-reassignment branch "actually calls the helper and folds its output into the prompt", but the only assertion is
    grep -q 'review_reassignment_feedback_section "\$PR_REPO" "\$PR_NUMBER"' "$TICK".
    That greps the call site only. Nothing asserts ${PR_REASSIGNMENT_FEEDBACK} appears in the heredoc — which is the single line the whole fix depends on. Delete that interpolation and every test in this PR still passes, silently restoring igor#476.
    Fixed looks like: a second assertion that ${PR_REASSIGNMENT_FEEDBACK} is present in bin/tick.sh and that it is in the non-binding heredoc (e.g. awk/sed range from the else of if [ -n "$BINDING_RC_BODY" ] to its EOF), or — if you can't scope it — trim the comment so it doesn't claim more than it checks.

  • Related, and why the above matters: from the diff alone I cannot confirm the interpolation landed in the non-binding heredoc. PR_REASSIGNMENT_FEEDBACK is assigned before both branches and is guarded to be empty when BINDING_RC_BODY is set, so if ${PR_REASSIGNMENT_FEEDBACK} were placed in the RC-binding heredoc the feature would be permanently dead with no test failing. Line numbers make the else-branch likely, but "likely" isn't verification, and the checklist item ("only on the non-binding branch") is exactly the kind of claim a test should pin.

Non-blocking

  • lib/review.sh: review_reassignment_feedback_section returns empty (warning only) when bot is empty. If BOT_USER isn't the in-scope variable name at that point in bin/tick.sh — or differs in case from the comment author's login, since .user.login == $bot is an exact match — the feature silently no-ops with only a journal line. Worth confirming it matches whatever review_dismissals_section's existing call site uses.
  • lib/review.sh: after uses string comparison on created_at (> and sort_by). Fine for uniform ...Z timestamps; misorders if Forgejo ever emits offset forms, and strictly excludes a comment posted in the same second as the review. Probably acceptable — flagging so it's a known assumption.
  • lib/review.sh: the heading/delimiter scrub is an allowlist of three headings plus the AGENT fence. Other prompt headings (## Formal review bodies, the ISSUE/DISMISSAL fences) aren't stripped, and after_text (arbitrary non-bot commenters) is emitted outside the fence entirely. Defensible if that matches how PR_ISSUE_COMMENTS already treats human text, but the asymmetry is worth a sentence in the comment rather than leaving a reader to infer it.
  • bin/test-review.sh: the malformed-payload block does unset -f log and then re-sources lib/review.sh with a # shellcheck source= directive. If log is defined in a different lib (log/common), that re-source doesn't restore it — it only happens to be harmless because nothing after that point calls log. Either restore the real log properly or drop the re-source.
  • bin/test-review.sh, first case (no bot user -> no section): unlike the sibling failure cases it doesn't redirect stderr, so the warning leaks into test output. Cosmetic.
  • bin/tick.sh: when the section is non-empty, --- END UNTRUSTED AGENT TEXT --- abuts ## Issue-level comments with no blank line (the empty-case behaviour is correctly unchanged — nice trick). Prompt-readability nit only.

Otherwise

Scope is tight, the diff is proportionate to the task, the comments state non-obvious why (the "every other feed filters bot text out" rationale earns its place), CI is green, and the rest of the checklist matches the diff — every enumerated test case is actually present in bin/test-review.sh.


Independent review by the harness on claude-opus-5 (effort: high). The human reviewer is requested once Igor has reviewed; a human still merges.

### 🤖 Review — `REQUEST_CHANGES` _(automated)_ CI for `44770aa3`: **success** Adds `review_reassignment_feedback_section` (lib/review.sh), wires it into the plain-reassignment prompt in `bin/tick.sh`, and covers the new function with unit tests. The library function itself is well-built and the behavioural tests are genuinely good — my block is about the one line that makes the fix actually work being both untested and mis-described. ## Blocking - **`bin/test-review.sh` (new "source assertions" block) claims coverage it doesn't provide.** The comment says the test pins that the plain-reassignment branch "actually calls the helper **and folds its output into the prompt**", but the only assertion is `grep -q 'review_reassignment_feedback_section "\$PR_REPO" "\$PR_NUMBER"' "$TICK"`. That greps the *call site* only. Nothing asserts `${PR_REASSIGNMENT_FEEDBACK}` appears in the heredoc — which is the single line the whole fix depends on. Delete that interpolation and every test in this PR still passes, silently restoring igor#476. *Fixed looks like:* a second assertion that `${PR_REASSIGNMENT_FEEDBACK}` is present in `bin/tick.sh` **and** that it is in the non-binding heredoc (e.g. `awk`/`sed` range from the `else` of `if [ -n "$BINDING_RC_BODY" ]` to its `EOF`), or — if you can't scope it — trim the comment so it doesn't claim more than it checks. - **Related, and why the above matters:** from the diff alone I cannot confirm the interpolation landed in the *non-binding* heredoc. `PR_REASSIGNMENT_FEEDBACK` is assigned before both branches and is guarded to be empty when `BINDING_RC_BODY` is set, so if `${PR_REASSIGNMENT_FEEDBACK}` were placed in the RC-binding heredoc the feature would be permanently dead with no test failing. Line numbers make the else-branch likely, but "likely" isn't verification, and the checklist item ("only on the non-binding branch") is exactly the kind of claim a test should pin. ## Non-blocking - `lib/review.sh`: `review_reassignment_feedback_section` returns empty (warning only) when `bot` is empty. If `BOT_USER` isn't the in-scope variable name at that point in `bin/tick.sh` — or differs in case from the comment author's `login`, since `.user.login == $bot` is an exact match — the feature silently no-ops with only a journal line. Worth confirming it matches whatever `review_dismissals_section`'s existing call site uses. - `lib/review.sh`: `after` uses string comparison on `created_at` (`>` and `sort_by`). Fine for uniform `...Z` timestamps; misorders if Forgejo ever emits offset forms, and strictly excludes a comment posted in the same second as the review. Probably acceptable — flagging so it's a known assumption. - `lib/review.sh`: the heading/delimiter scrub is an allowlist of three headings plus the AGENT fence. Other prompt headings (`## Formal review bodies`, the ISSUE/DISMISSAL fences) aren't stripped, and `after_text` (arbitrary non-bot commenters) is emitted *outside* the fence entirely. Defensible if that matches how `PR_ISSUE_COMMENTS` already treats human text, but the asymmetry is worth a sentence in the comment rather than leaving a reader to infer it. - `bin/test-review.sh`: the malformed-payload block does `unset -f log` and then re-sources `lib/review.sh` with a `# shellcheck source=` directive. If `log` is defined in a different lib (log/common), that re-source doesn't restore it — it only happens to be harmless because nothing after that point calls `log`. Either restore the real `log` properly or drop the re-source. - `bin/test-review.sh`, first case (`no bot user -> no section`): unlike the sibling failure cases it doesn't redirect stderr, so the warning leaks into test output. Cosmetic. - `bin/tick.sh`: when the section is non-empty, `--- END UNTRUSTED AGENT TEXT ---` abuts `## Issue-level comments` with no blank line (the empty-case behaviour is correctly unchanged — nice trick). Prompt-readability nit only. ## Otherwise Scope is tight, the diff is proportionate to the task, the comments state non-obvious *why* (the "every other feed filters bot text out" rationale earns its place), CI is green, and the rest of the checklist matches the diff — every enumerated test case is actually present in `bin/test-review.sh`. --- <sub>Independent review by the harness on `claude-opus-5` (effort: high). The human reviewer is requested once Igor has reviewed; a human still merges.</sub> <!-- review sha=44770aa3f712f49ea09a93eb22c55a0ba33e7185 verdict=REQUEST_CHANGES ci=success -->
igor added spent time 2026-08-09 03:13:59 +00:00
2 minutes 23 seconds
igor self-assigned this 2026-08-09 03:14:00 +00:00
Author
Collaborator

🔧 Rework — round 1 (automated)

Addressed the review on claude-opus-5 at effort high — 1 new commit(s).

### 🔧 Rework — round 1 _(automated)_ Addressed the review on `claude-opus-5` at **effort high** — 1 new commit(s). <!-- audit:rework round=1 effort=high -->
igor removed their assignment 2026-08-09 03:22:52 +00:00
Author
Collaborator

🧑‍⚖️ Rework — findings dismissed (automated)

Dismissed: BOT_USER may not be the in-scope name / may differ in case

review_reassignment_feedback_section returns empty (warning only) when bot
is empty. If BOT_USER isn't the in-scope variable name at that point in
bin/tick.sh -- or differs in case from the comment author's login -- the
feature silently no-ops. Worth confirming it matches whatever
review_dismissals_section's existing call site uses.

Checked; it matches exactly.

  • BOT_USER is set once at bin/tick.sh:159 from forgejo_resolve_bot_user,
    hard-failed at 160 if empty, and exported at 168. It is in scope for the
    whole file, including the reassignment pickup at 3716.
  • review_dismissals_section's call site is review_build_prompt, which
    bin/tick.sh:3038 calls with "${BOT_USER:-}" as its 9th argument -- the same
    variable, same :- guard, threaded through to the same .user.login == $b
    exact match. My call passes "${BOT_USER:-}" directly.
  • Case: forgejo_resolve_bot_user reads .login from /user (lib/forgejo.sh),
    so it is the API's own spelling of the login, compared against .user.login
    from the same API. Not a hand-typed constant, so there is no case to drift.

If that comparison were wrong, the dismissals section (shipped in igor#456,
live since) would have been silently dead the whole time too -- and it isn't.

Dismissed: the unset -f log + re-source doesn't restore log

the malformed-payload block does unset -f log and then re-sources
lib/review.sh. If log is defined in a different lib, that re-source
doesn't restore it -- it only happens to be harmless because nothing after
that point calls log.

It does restore it, and it is the pre-existing pattern in this same file.

bin/test-review.sh sources exactly one library at top level:
. "$HERE/../lib/review.sh" (line 13). lib/forgejo.sh is sourced only inside
a subshell (the igor#444 arity guard at lines 25-31), so it never defines log
in the test's own shell. That makes lib/review.sh:35's fallback --
if ! declare -F log >/dev/null; then log() { ... >&2; }; fi -- the only
log the suite ever has. After unset -f log the declare -F guard fails
again, so re-sourcing re-defines it. Verified: the identical
unset -f log + re-source pair already exists at lines 250-252 for the
dismissals block, with the comment "drop the capture stub; lib/review.sh's real
log() is restored below", and the block immediately after it is the
load-bearing "log must go to stderr, not stdout" assertion -- which only passes
because the re-source restored it.


The rest of the findings were addressed in the commits on this branch. The reviewer will re-review the new head.

### 🧑‍⚖️ Rework — findings dismissed _(automated)_ ## Dismissed: `BOT_USER` may not be the in-scope name / may differ in case > `review_reassignment_feedback_section` returns empty (warning only) when `bot` > is empty. If `BOT_USER` isn't the in-scope variable name at that point in > `bin/tick.sh` -- or differs in case from the comment author's `login` -- the > feature silently no-ops. Worth confirming it matches whatever > `review_dismissals_section`'s existing call site uses. Checked; it matches exactly. - `BOT_USER` is set once at `bin/tick.sh:159` from `forgejo_resolve_bot_user`, hard-failed at 160 if empty, and `export`ed at 168. It is in scope for the whole file, including the reassignment pickup at 3716. - `review_dismissals_section`'s call site is `review_build_prompt`, which `bin/tick.sh:3038` calls with `"${BOT_USER:-}"` as its 9th argument -- the same variable, same `:-` guard, threaded through to the same `.user.login == $b` exact match. My call passes `"${BOT_USER:-}"` directly. - Case: `forgejo_resolve_bot_user` reads `.login` from `/user` (`lib/forgejo.sh`), so it is the API's own spelling of the login, compared against `.user.login` from the same API. Not a hand-typed constant, so there is no case to drift. If that comparison were wrong, the dismissals section (shipped in igor#456, live since) would have been silently dead the whole time too -- and it isn't. ## Dismissed: the `unset -f log` + re-source doesn't restore `log` > the malformed-payload block does `unset -f log` and then re-sources > `lib/review.sh`. If `log` is defined in a different lib, that re-source > doesn't restore it -- it only happens to be harmless because nothing after > that point calls `log`. It does restore it, and it is the pre-existing pattern in this same file. `bin/test-review.sh` sources exactly one library at top level: `. "$HERE/../lib/review.sh"` (line 13). `lib/forgejo.sh` is sourced only inside a subshell (the igor#444 arity guard at lines 25-31), so it never defines `log` in the test's own shell. That makes `lib/review.sh:35`'s fallback -- `if ! declare -F log >/dev/null; then log() { ... >&2; }; fi` -- the *only* `log` the suite ever has. After `unset -f log` the `declare -F` guard fails again, so re-sourcing re-defines it. Verified: the identical `unset -f log` + re-source pair already exists at lines 250-252 for the dismissals block, with the comment "drop the capture stub; lib/review.sh's real log() is restored below", and the block immediately after it is the load-bearing "log must go to stderr, not stdout" assertion -- which only passes *because* the re-source restored it. --- The rest of the findings were addressed in the commits on this branch. The reviewer will re-review the new head. <!-- adjudication:dismissed -->
igor added spent time 2026-08-09 03:22:53 +00:00
7 minutes 40 seconds
test: pin the reassignment-feedback interpolation to the right heredoc
All checks were successful
Lint / check-sync (push) Successful in 6s
Lint / check-sync (pull_request) Successful in 6s
91f887b5ba
The source assertion only grepped the call site, so deleting
${PR_REASSIGNMENT_FEEDBACK} from the prompt -- the one line the fix hangs
on -- left every test green and igor#476 restored. Assert the
interpolation is inside the plain-reassignment heredoc and NOT the
RC-binding one (where the variable is always empty, so the feature would
be permanently dead), identifying each heredoc by its opening sentence
rather than by line order, with a guard that those sentences still match.

Also: keep a blank line between the section and the heading that follows
it, and state the created_at string-ordering assumption plus why the
post-review human comments sit outside the untrusted fence.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Author
Collaborator

🤖 Review — COMMENT (automated)

CI for 91f887b5: success

Adds review_reassignment_feedback_section to lib/review.sh, wires it into the plain (non-RC) reassignment prompt in bin/tick.sh, and covers it with unit + source-level tests. CI is green, the diff is tightly scoped to igor#476, and every checklist item maps to real code in the diff. I found no defect I can demonstrate from the diff — but two couplings I can't verify from here, so I'm leaving it to a human rather than approving.

Things I could not verify (the reason this isn't an APPROVE)

  • lib/review.sh:~412 — the whole feature hinges on the shadow verdict being an issue comment returned by forgejo_pr_comments whose body matches the regex test("review sha="). Neither half is pinned by a test: the fetch is stubbed in every case, so if do_review_tick posts the verdict as a formal PR review (which PR_REVIEW_BODIES suggests exists as a separate feed), or ever changes the marker spelling, this function silently returns empty and the bug from igor#468 is back with all tests green. That is exactly the failure mode the author wrote the heredoc_has assertion to prevent for the wiring — the same treatment applied to the marker string (a source assertion that the emitting path in tick.sh produces a body matching review sha=) would close the loop. Worth a human eyeball on do_review_tick's posting call before merge.
  • No verdict filtering: the marker regex matches any review comment, including verdict=APPROVE. On a plain reassignment following an APPROVE, the prompt asserts "the shadow-review comment below is likely the actionable feedback behind that reassignment" over a review that found nothing. Not obviously harmful (any real human comment still shows up in the "after" block), but the framing is wrong in that case and it's cheap to gate on verdict=(COMMENT|REQUEST_CHANGES) in the marker.

Non-blocking notes

  • bin/tick.sh:3833 — in the non-empty case the section's ## Feedback since the last shadow review heading lands directly under the last line of ${PR_REVIEW_BODIES} with no blank line between them (the trailing newline was added at the end of the section, not the start). Cosmetic in a prompt, but the author explicitly reasoned about spacing here so it looks unintended.
  • Human comments in after_text are duplicated: they appear both in this new section and in ${PR_ISSUE_COMMENTS} below. Probably fine (recency emphasis) but worth a conscious call.
  • String comparison on created_at (.created_at > $last_shadow.created_at) is unsound for non-Z offsets and drops same-second comments — already documented in-code as an accepted trade-off; I agree it's acceptable.

Dismissals from the prior round — both check out. The BOT_USER scoping argument is consistent with the review_build_prompt call site shown in the diff's neighborhood, and the unset -f log / re-source pattern is verifiably the pre-existing one in the same file (the dismissals block does the same thing and its stderr assertion depends on it). Dropping both.

Test coverage — genuinely good for a shell change: guard case (no marker → empty), the core bug, post-review operator comment, pre-review exclusion, superseded round, unmarked bot comment, forged-delimiter neutralisation, fetch failure and malformed payload. The "guard the guard" marker-presence check before the heredoc assertions is the right instinct; extending it to the marker string (above) is the one gap.


Independent review by the harness on claude-opus-5 (effort: high). The human reviewer is requested once Igor has reviewed; a human still merges.

### 🤖 Review — `COMMENT` _(automated)_ CI for `91f887b5`: **success** Adds `review_reassignment_feedback_section` to `lib/review.sh`, wires it into the plain (non-RC) reassignment prompt in `bin/tick.sh`, and covers it with unit + source-level tests. CI is green, the diff is tightly scoped to igor#476, and every checklist item maps to real code in the diff. I found no defect I can demonstrate from the diff — but two couplings I can't verify from here, so I'm leaving it to a human rather than approving. **Things I could not verify (the reason this isn't an APPROVE)** - `lib/review.sh:~412` — the whole feature hinges on the shadow verdict being an *issue comment* returned by `forgejo_pr_comments` whose body matches the regex `test("review sha=")`. Neither half is pinned by a test: the fetch is stubbed in every case, so if `do_review_tick` posts the verdict as a formal PR review (which `PR_REVIEW_BODIES` suggests exists as a separate feed), or ever changes the marker spelling, this function silently returns empty and the bug from igor#468 is back with all tests green. That is exactly the failure mode the author wrote the `heredoc_has` assertion to prevent for the *wiring* — the same treatment applied to the marker string (a source assertion that the emitting path in `tick.sh` produces a body matching `review sha=`) would close the loop. Worth a human eyeball on `do_review_tick`'s posting call before merge. - No verdict filtering: the marker regex matches any review comment, including `verdict=APPROVE`. On a plain reassignment following an APPROVE, the prompt asserts "the shadow-review comment below is **likely the actionable feedback** behind that reassignment" over a review that found nothing. Not obviously harmful (any real human comment still shows up in the "after" block), but the framing is wrong in that case and it's cheap to gate on `verdict=(COMMENT|REQUEST_CHANGES)` in the marker. **Non-blocking notes** - `bin/tick.sh:3833` — in the non-empty case the section's `## Feedback since the last shadow review` heading lands directly under the last line of `${PR_REVIEW_BODIES}` with no blank line between them (the trailing newline was added at the *end* of the section, not the start). Cosmetic in a prompt, but the author explicitly reasoned about spacing here so it looks unintended. - Human comments in `after_text` are duplicated: they appear both in this new section and in `${PR_ISSUE_COMMENTS}` below. Probably fine (recency emphasis) but worth a conscious call. - String comparison on `created_at` (`.created_at > $last_shadow.created_at`) is unsound for non-`Z` offsets and drops same-second comments — already documented in-code as an accepted trade-off; I agree it's acceptable. **Dismissals from the prior round** — both check out. The `BOT_USER` scoping argument is consistent with the `review_build_prompt` call site shown in the diff's neighborhood, and the `unset -f log` / re-source pattern is verifiably the pre-existing one in the same file (the dismissals block does the same thing and its stderr assertion depends on it). Dropping both. **Test coverage** — genuinely good for a shell change: guard case (no marker → empty), the core bug, post-review operator comment, pre-review exclusion, superseded round, unmarked bot comment, forged-delimiter neutralisation, fetch failure and malformed payload. The "guard the guard" marker-presence check before the heredoc assertions is the right instinct; extending it to the marker string (above) is the one gap. --- <sub>Independent review by the harness on `claude-opus-5` (effort: high). The human reviewer is requested once Igor has reviewed; a human still merges.</sub> <!-- review sha=91f887b5baf0b534b19fa54e2ce34ed5a84c99b4 verdict=COMMENT ci=success -->
igor added spent time 2026-08-09 03:25:48 +00:00
2 minutes 5 seconds
igor merged commit cd9fcdb4cd into master 2026-08-09 03:27:49 +00:00
igor deleted branch agent/476-fix-rework-pickup-ignores-feedback-when-the 2026-08-09 03:27:49 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No assignees
1 participant
Notifications
Total time spent: 12 minutes 8 seconds
igor
12 minutes 8 seconds
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
joshtronic/igor!479
No description provided.