IW-426: Route iw feedback to Forgejo instead of the archived GitHub mirror #457

Merged
mph merged 34 commits from IW-426 into main 2026-08-26 14:08:10 +00:00
Owner

Fixes IW-426.

Summary

iw feedback posted every submission to github.com/iterative-works/iw-cli, an archived
read-only mirror, so the command always failed with Repository was archived so is read-only.
The one channel for reporting an iw-cli problem was dead. Feedback now goes to Forgejo at
https://code.iterative.works, where the project's issues actually live.

Defects fixed

Defect 1 — feedback routed to the archived GitHub mirror. Feedback.submit now calls
env.tracker.createForgejoIssue against Constants.Feedback.Repository at the new
Constants.Feedback.BaseUrl, replacing the createFeedbackIssue/GitHubClient path. The
--type bug|feature selector is carried in the issue body (analysis Option A), together with the
working directory and branch the feedback was filed from, so a triager sees the provenance without
asking. Body rendering lives in core/model/FeedbackBody.scala; values interpolated into the
provenance footer are wrapped as markdown code spans so they cannot close the span and render as
live markdown.

Defect 2 — no guidance when the token is missing. A missing FORGEJO_API_TOKEN is now caught
before any API call and reports what is unset, where iw-cli files feedback, and what access the
token needs — instead of surfacing a raw API error after the request.

Cleanup (Phase 2). The createFeedbackIssue layer that Phase 1 orphaned is removed from
CommandEnv, LiveCommandEnv and the FakeCommandEnv recorder, and the PURPOSE headers,
test/feedback.bats header and test name no longer describe the command as targeting GitHub.

Testing

  • core/test/FeedbackBodyTest.scala — body rendering, type label, provenance footer, and the
    code-span escaping of backticks and newlines.
  • core/test/FeedbackHarnessTest.scala — the Forgejo call and its arguments, the missing-token
    guard and its exact message, and the reported issue number and URL.
  • test/feedback.bats — E2E wiring smoke test.
  • Unit suite and command compilation green; both phase PRs (#449, #453) passed CI before merge.
  • Manual end-to-end submission against the live Forgejo instance was exercised while probing the
    create-issue API during Phase 1.

Lessons

Triaged before this PR. Two new tracker issues filed (IW-455 dead test-only helper, IW-456 forge
resolution duplicated across five call sites); two entries matched issues already open (IW-450,
IW-437); one lesson went to the global CLAUDE.md; one is retained as issue context. The decision
ledger is in project-management/issues/IW-426/LESSONS.md.

Release notes

project-management/issues/IW-426/release-notes.md (Czech, for non-technical readers).

🤖 Generated with Claude Code

Fixes IW-426. ## Summary `iw feedback` posted every submission to `github.com/iterative-works/iw-cli`, an archived read-only mirror, so the command always failed with `Repository was archived so is read-only`. The one channel for reporting an iw-cli problem was dead. Feedback now goes to Forgejo at `https://code.iterative.works`, where the project's issues actually live. ## Defects fixed **Defect 1 — feedback routed to the archived GitHub mirror.** `Feedback.submit` now calls `env.tracker.createForgejoIssue` against `Constants.Feedback.Repository` at the new `Constants.Feedback.BaseUrl`, replacing the `createFeedbackIssue`/`GitHubClient` path. The `--type bug|feature` selector is carried in the issue body (analysis Option A), together with the working directory and branch the feedback was filed from, so a triager sees the provenance without asking. Body rendering lives in `core/model/FeedbackBody.scala`; values interpolated into the provenance footer are wrapped as markdown code spans so they cannot close the span and render as live markdown. **Defect 2 — no guidance when the token is missing.** A missing `FORGEJO_API_TOKEN` is now caught before any API call and reports what is unset, where iw-cli files feedback, and what access the token needs — instead of surfacing a raw API error after the request. **Cleanup (Phase 2).** The `createFeedbackIssue` layer that Phase 1 orphaned is removed from `CommandEnv`, `LiveCommandEnv` and the `FakeCommandEnv` recorder, and the PURPOSE headers, `test/feedback.bats` header and test name no longer describe the command as targeting GitHub. ## Testing - `core/test/FeedbackBodyTest.scala` — body rendering, type label, provenance footer, and the code-span escaping of backticks and newlines. - `core/test/FeedbackHarnessTest.scala` — the Forgejo call and its arguments, the missing-token guard and its exact message, and the reported issue number and URL. - `test/feedback.bats` — E2E wiring smoke test. - Unit suite and command compilation green; both phase PRs (#449, #453) passed CI before merge. - Manual end-to-end submission against the live Forgejo instance was exercised while probing the create-issue API during Phase 1. ## Lessons Triaged before this PR. Two new tracker issues filed (IW-455 dead test-only helper, IW-456 forge resolution duplicated across five call sites); two entries matched issues already open (IW-450, IW-437); one lesson went to the global CLAUDE.md; one is retained as issue context. The decision ledger is in `project-management/issues/IW-426/LESSONS.md`. ## Release notes `project-management/issues/IW-426/release-notes.md` (Czech, for non-technical readers). 🤖 Generated with Claude Code
mph added 33 commits 2026-08-26 13:47:33 +00:00
feedback command posts to the archived GitHub mirror, so it always fails

Artifacts:
- analysis.md

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JXfJvKSTj49QaAAW9oAVWT
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JXfJvKSTj49QaAAW9oAVWT
Resolved:
- analysis.md: Which forge should feedback target for users who have no token
  on our Forgejo instance? → team-only channel, target stays hardcoded to
  Forgejo; no external-filer path for now, revisit as a separate issue

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JXfJvKSTj49QaAAW9oAVWT
feedback command posts to the archived GitHub mirror, so it always fails

Artifacts:
- tasks.md
- review-state.json (tasks_ready)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JXfJvKSTj49QaAAW9oAVWT
Issue: IW-426
Phase: 1 - Route feedback to Forgejo, with a guided missing-token path

This commit marks the checkpoint for phase 1 context generation.
Use dx-fix IW-426 to return to this point.

🤖 Generated with Claude Code
Route feedback to Forgejo, with a guided missing-token path

Artifacts:
- phase-01-tasks.md

🤖 Generated with Claude Code
Route feedback to Forgejo, with a guided missing-token path
Some checks failed
CI / contract (pull_request) Has been skipped
CI / format (pull_request) Successful in 8s
CI / lint (pull_request) Successful in 8s
CI / compile (pull_request) Successful in 1m30s
CI / dashboard-build (pull_request) Successful in 1m14s
CI / test (pull_request) Has been cancelled
71625d87ba
- Route iw feedback to Forgejo instead of the archived GitHub mirror
- Guard a missing FORGEJO_API_TOKEN with an actionable three-line message
- Carry the issue type and filing provenance in the issue body
chore(IW-426): update review-state for phase 01
All checks were successful
CI / contract (pull_request) Has been skipped
CI / format (pull_request) Successful in 8s
CI / lint (pull_request) Successful in 9s
CI / compile (pull_request) Successful in 1m30s
CI / dashboard-build (pull_request) Successful in 1m16s
CI / test (pull_request) Successful in 10m46s
49ab3c2c71
chore(IW-426): update review-state to awaiting_review
All checks were successful
CI / contract (pull_request) Has been skipped
CI / format (pull_request) Successful in 12s
CI / lint (pull_request) Successful in 8s
CI / compile (pull_request) Successful in 1m33s
CI / dashboard-build (pull_request) Successful in 1m15s
CI / test (pull_request) Successful in 10m43s
26b35c0a12
Reviewed-on: #449
Filed issue #450 through the merged iw feedback command; verified the
server accepted it and the body carries the type and provenance lines.
Probed the label endpoint to close the open question from the phase
context: create takes label IDs as integers, not names.
Issue: IW-426
Phase: 2 - Clear the stale GitHub assumptions left behind

This commit marks the checkpoint for phase 2 context generation.
Use dx-fix IW-426 to return to this point.

🤖 Generated with Claude Code
Clear the stale GitHub assumptions left behind

Artifacts:
- phase-02-tasks.md

🤖 Generated with Claude Code
Clear the stale GitHub assumptions left behind
Some checks failed
CI / contract (pull_request) Has been skipped
CI / format (pull_request) Successful in 8s
CI / lint (pull_request) Successful in 11s
CI / test (pull_request) Has been cancelled
CI / dashboard-build (pull_request) Has been cancelled
CI / compile (pull_request) Has been cancelled
ba66953c11
- Rewrite the commands/feedback.scala PURPOSE header to name Forgejo
- Name the Forgejo destination in the test/feedback.bats NOTE and rename its test off GitHub
- Remove the dead createFeedbackIssue layer from TrackerOps and both its implementations
- Drop the three FeedbackParser imports the removal orphans
- Open follow-up issue #452 for the GitHubClient.createIssue overload the removal orphans
chore(IW-426): update review-state for phase 02
All checks were successful
CI / contract (pull_request) Has been skipped
CI / format (pull_request) Successful in 7s
CI / lint (pull_request) Successful in 9s
CI / compile (pull_request) Successful in 1m29s
CI / dashboard-build (pull_request) Successful in 1m1s
CI / test (pull_request) Successful in 9m38s
bc9dc7b971
workflow(dx): record phase-pr false-failure lesson for IW-426
All checks were successful
CI / contract (pull_request) Has been skipped
CI / format (pull_request) Successful in 7s
CI / lint (pull_request) Successful in 8s
CI / compile (pull_request) Successful in 1m25s
CI / dashboard-build (pull_request) Successful in 59s
CI / test (pull_request) Successful in 9m42s
666a3150b6
Reviewed-on: #453
workflow: Triage lessons for IW-426
Some checks failed
CI / contract (pull_request) Has been skipped
CI / format (pull_request) Successful in 8s
CI / lint (pull_request) Successful in 8s
CI / test (pull_request) Has been cancelled
CI / dashboard-build (pull_request) Has been cancelled
CI / compile (pull_request) Has been cancelled
3cbabaf560
Promoted:
- a helper kept alive only by its own tests reads as live code -> IW-455
- issue creation resolves its forge four separate ways -> IW-456
- iw phase-pr cannot resume its own CI wait -> already filed as IW-450
- phase-pr marked a green phase ci_failed -> already covered by IW-437
- a baseline comparison reached for the shared stash stack -> ~/.claude-iw/CLAUDE.md (outside this repo)

Retained:
- Forgejo POST /issues takes label IDs, not names: explains this issue only

Also adds release-notes.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JXfJvKSTj49QaAAW9oAVWT
chore(IW-426): update review-state to all_complete
All checks were successful
CI / contract (pull_request) Has been skipped
CI / format (pull_request) Successful in 7s
CI / lint (pull_request) Successful in 7s
CI / compile (pull_request) Successful in 1m30s
CI / dashboard-build (pull_request) Successful in 1m47s
CI / test (pull_request) Successful in 12m2s
047aebf8f2
mph merged commit 25b48cece0 into main 2026-08-26 14:08:10 +00:00
mph deleted branch IW-426 2026-08-26 14:08:10 +00:00
Sign in to join this conversation.
No description provided.