108 lines
151 KiB
JSON
108 lines
151 KiB
JSON
{"_type":"issue","id":"forgejo-mcp-9r4","title":"promote-image-tag deletes build-tmp → cascades to delete v2.27.0 + latest manifest on Codeberg registry","description":"Forgejo/Codeberg container registry deletes the underlying MANIFEST when a tag is deleted. Since :build-tmp, :vX.Y.Z and :latest all share one digest, the 'skopeo delete :build-tmp' cleanup (added in f026f8c) removed all three tags. Result: v2.27.0 image absent from registry; only cosign .sig/.att survived. Fix (decided): eliminate build-tmp entirely — push directly to :vX.Y.Z, sign+attest in place, promote :latest; add finally-cleanup to delete :vX.Y.Z if sign/attest fail (preserves fail-closed).","status":"closed","priority":0,"issue_type":"bug","owner":"goern@b4mad.net","created_at":"2026-06-02T15:25:45Z","created_by":"Christoph Görn","updated_at":"2026-06-10T22:14:46Z","closed_at":"2026-06-10T22:14:46Z","close_reason":"Verified implemented + working; closing. The decided fix shipped in 748de51 ('push image version tag directly, never delete a staging tag') across both pipelines: (1) push-image-by-digest pushes :vX.Y.Z directly, no :build-tmp staging tag anywhere (grep clean); (2) cosign-sign + attach-sbom operate on the digest in place; (3) promote-image-tag only ADDS :latest (skipped for pre-releases), never deletes; (4) fail-closed finally task delete-tag-on-failure deletes :vX.Y.Z when attach-sbom status notin [Succeeded] — at that point :latest is unpromoted, so :vX.Y.Z is the manifest's only tag and the delete is safe. Wired identically in .tekton/on-tag-push-release.yaml (codeberg.org/goern/forgejo-mcp) and .tekton/release-tools-on-tag-publish.yaml (operate-first/release-tools). Empirical proof: registry now holds v2.28.0, v2.29.0, latest — two post-fix releases survived promotion+cleanup. Residue tracked separately: v2.27.0 image still absent, one orphaned .sig/.att pair remains.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-k5f","title":"Extend #136 scope: webhook resource-templates, not just tools","description":"Codeberg issue #136 (feat: expose repository webhook management tools) currently scopes only MCP *tools* for webhook CRUD (create/list/get/edit/delete/test_repo_hook). Per the project's resources convention (AGENTS.md / openspec/specs/mcp-resources-core), entities should ALSO be exposed as forgejo:// resource-templates — additive, instance-portable, coexisting with tools.\n\nAction: update #136 to add a resource-templates section alongside the tools section.\n\nProposed resource-templates:\n- forgejo://repos/{owner}/{repo}/hooks -\u003e embedded, bounded list of hooks\n- forgejo://repos/{owner}/{repo}/hooks/{id} -\u003e single hook\n\nRequirements carried from the resources convention:\n- Place under operation/\u003cdomain\u003e/resources*.go; use operation/resource helpers (ParseXxx, Bounded, MapForgejoError).\n- Embedded list MUST use operation/resource.Bounded (consistent truncation sentinel).\n- Bound the list resource per docs/design/output-bounding.md (client-controlled bound + resumability + documented params).\n- secret field MUST be masked in resource reads exactly as in the tool results (issue #136 already requires this for tools).","acceptance_criteria":"#136 body updated with a resource-templates section listing forgejo://repos/{owner}/{repo}/hooks and /hooks/{id}, plus the bounding + secret-masking + operation/resource helper requirements. Acceptance-criteria checklist in #136 extended to cover the resource-templates surface.","status":"closed","priority":0,"issue_type":"task","assignee":"goern","owner":"goern@b4mad.net","created_at":"2026-06-02T05:53:14Z","created_by":"Christoph Görn","updated_at":"2026-06-02T06:21:06Z","closed_at":"2026-06-02T06:21:06Z","close_reason":"Updated Codeberg #136: added Resource-templates section (forgejo://repo/{owner}/{repo}/hooks + /hooks/{id}) with bounding/secret-masking/operation-resource-helper requirements, extended acceptance-criteria checklist to cover resource surface, assigned goern, added Priority/High. Used singular 'repo' URI segment to match mcp-resources-core (deferral text's plural 'repos' was shorthand). Unblocks merge of mcp-resource-templates change which defers webhooks to #136.","external_ref":"codeberg-136","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-uc6","title":"Branch protection management: MCP tools + forgejo:// resource-templates","description":"OpenSpec change 'branch-protection-management' proposed (proposal/design/specs/tasks; validate --strict passes). Spec-only proposal PR opened on branch feat/branch-protection-uc6. Implementation is a follow-up (partial impl stashed locally: parse.go BP parsers + params.go BP descriptions). Decisions: self-contained branch-protection capability (no mcp-resources-core delta), new operation/branchprotection/ package, comma-separated status_check_contexts, edit PATCH pointer semantics, full CRUD in one impl PR.","acceptance_criteria":"Tools registered under operation/\u003cdomain\u003e/; list output bounded per docs/design/output-bounding.md; resource-templates under operation/\u003cdomain\u003e/resources*.go using operation/resource helpers (ParseXxx, Bounded, MapForgejoError); create/edit round-trips status_check_contexts correctly; covered by tests.","status":"closed","priority":0,"issue_type":"feature","assignee":"goern","owner":"goern@b4mad.net","created_at":"2026-06-02T05:40:32Z","created_by":"Christoph Görn","updated_at":"2026-06-02T14:40:20Z","closed_at":"2026-06-02T14:40:20Z","close_reason":"Shipped across #195 (proposal) -\u003e #196 (impl: 5 CRUD tools + 2 bounded forgejo:// resources + tests + showboat demo) -\u003e #197 (archive: live spec openspec/specs/branch-protection/spec.md + co-located demo). All merged, CI green. Forgejo SDK fully bound the endpoints (no upstream block).","dependencies":[{"issue_id":"forgejo-mcp-uc6","depends_on_id":"forgejo-mcp-f6h","type":"discovered-from","created_at":"2026-06-02T05:52:50Z","created_by":"Christoph Görn","metadata":"{}"}],"dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-f6h","title":"Renovate/Gitea merges PR while required-less commit status is PENDING (main has no branch protection)","description":"PR #187 (Renovate docker-digest bump) merged 02:18:05 while Tekton build-and-test was still running; merge cancelled the PipelineRun (TaskRunCancelled). Root cause = two compounding holes.\n\nHOLE 1 — main has zero branch protection: GET /repos/goern/forgejo-mcp/branch_protections returns []. No required status checks; nothing gates merge on CI green.\n\nHOLE 2 — PaC posts no pending/running commit status at pipeline start, only a final status on completion. During the run window only the faster code-scans context exists (=success), so combined commit status = success. Renovate (default:automergeDigest + automergeSchedule '* * * * *') sees green branch and merges.\n\nStatuses on head 7279457:\n success | op1st Pipelines as Code / forgejo-mcp-code-scans | 02:17:31\n cancell | op1st Pipelines as Code / forgejo-mcp-on-pull-request | 02:18:10 (AFTER merge)\n\nbuild-and-test did NOT fail on merits — killed by the merge.","acceptance_criteria":"main branch protection requires both PaC status check contexts (forgejo-mcp-code-scans, forgejo-mcp-on-pull-request) with enable_status_check=true. A PR with an absent or non-success required check is not mergeable, including by Renovate automerge. Verified by re-running a Renovate digest PR and confirming it waits for build-and-test before merge.","notes":"Fix command (outward-facing config):\ncurl -X POST -H 'Authorization: token $CODEBERG_TOKEN' -H 'Content-Type: application/json' https://codeberg.org/api/v1/repos/goern/forgejo-mcp/branch_protections -d '{\"rule_name\":\"main\",\"enable_status_check\":true,\"status_check_contexts\":[\"op1st Pipelines as Code / forgejo-mcp-code-scans\",\"op1st Pipelines as Code / forgejo-mcp-on-pull-request\"]}'\n\nRequired-but-absent check blocks merge, closing both holes. Secondary hardening: have PaC emit a pending status at pipeline start.\n── CORRECTION 2026-06-02 (supersedes original Hole 2) ──\nOriginal bead claimed 'Hole 2 — PaC posts no pending status at pipeline start'. That is FALSE. Evidence:\n\nFull commit-status history (GET /commits/7279457/statuses, all entries):\n 02:16:49 pending | op1st PaC / forgejo-mcp-code-scans\n 02:16:49 pending | op1st PaC / forgejo-mcp-on-pull-request \u003c- PaC DID post pending\n 02:17:31 success | op1st PaC / forgejo-mcp-code-scans\n 02:18:10 cancelled | op1st PaC / forgejo-mcp-on-pull-request\n\nAt merge (02:18:05) the latest-per-context combined status = PENDING (on-pull-request still pending). PaC posts a pending status on in_progress — confirmed in source openshift-pipelines/pipelines-as-code pkg/provider/gitea/gitea.go (CreateStatus sets forgejo.StatusPending when status.Status=='in_progress', then calls CreateStatus).\n\nREAL ROOT CAUSE (single hole, confirmed): main has NO branch protection / NO required status checks. Because no check is *required*, the pending PaC status is non-blocking to the merge path, so the PR was merged while still yellow. With required status checks, a pending check =\u003e not mergeable =\u003e neither Renovate nor Gitea native automerge would merge.\n\nOPEN QUESTION (needs Renovate run logs to pin, does NOT change the fix): which merge path ignored the pending status —\n (a) Renovate client-side merge: with no required checks, Renovate's getBranchStatus/automerge did not treat the ambient pending status as blocking; or\n (b) Gitea/Forgejo native scheduled auto-merge: without branch protection Gitea has no definition of 'green', so it merged immediately.\nBoth are downstream of the missing required checks. FIX UNCHANGED: require both PaC contexts in main branch protection.","status":"closed","priority":0,"issue_type":"bug","assignee":"goern","owner":"goern@b4mad.net","created_at":"2026-06-02T05:40:22Z","created_by":"Christoph Görn","updated_at":"2026-06-02T05:52:51Z","closed_at":"2026-06-02T05:52:51Z","close_reason":"Fixed: created main branch protection rule (enable_status_check=true) requiring both PaC contexts (forgejo-mcp-code-scans, forgejo-mcp-on-pull-request). Verified live via GET branch_protections. Codeberg issue #188 closed. Pending/absent required check now blocks merge for both Renovate and Gitea native auto-merge.","external_ref":"codeberg-188","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-1b4","title":"Build dedicated release-tools container image for op1st Tekton release pipeline","description":"Currently .tekton/tasks/goreleaser-release.yaml installs syft + goreleaser at runtime in separate Tekton Steps, which fails (exit 127) because /usr/local/bin/ is per-container, not shared across Steps in a Pod. Workaround in current code is to collapse all installs+run into one Step (loses log granularity, repeats install on every release run, fragile to upstream URL changes). Proper fix: build a custom OCI image with pinned Go + syft + goreleaser + cosign + jq + curl + node22 + npx + @anthropic-ai/mcpb prefetched. Reference this image from all three Tasks (goreleaser-release, cosign-sign-release, mcpb-pack). Image rebuild on tool bump only. Likely lives in op1st-emea-b4mad or ghcr.io/operate-first/release-tools.","acceptance_criteria":"Image published at a stable registry path; .tekton/tasks/*.yaml reference it via params with versioned tag; release pipeline still passes; install-at-runtime removed; Renovate/dependabot config bumps the image tag","notes":"PR #155 merged into main as 550db7f. OpenSpec design + adversarial review now canonical. Implementation work begins on branch feat/release-tools-image-impl. Tracking via /var/home/goern/Source/codeberg.org/goern/forgejo-mcp-release-tools-impl worktree. Dev team release-tools-image-iter1 spawned for iteration 1 (source tree only; pipelines deferred to iter 2).","status":"closed","priority":0,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-25T11:47:01Z","created_by":"Christoph Görn","updated_at":"2026-05-25T22:20:29Z","started_at":"2026-05-25T12:09:21Z","closed_at":"2026-05-25T22:20:29Z","close_reason":"PR #157 merged (commit e02cf56). release-tools image built and pushed to codeberg.org/operate-first/release-tools:latest (sha256:b0387a762c54). All .tekton/tasks/ rewritten. OpenSpec change implemented end-to-end.","dependencies":[{"issue_id":"forgejo-mcp-1b4","depends_on_id":"forgejo-mcp-29g","type":"blocks","created_at":"2026-05-25T11:47:15Z","created_by":"Christoph Görn","metadata":"{}"}],"dependency_count":1,"dependent_count":5,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-puz","title":"fix: tekton go-ci lint step broken by golangci-lint v2 config migration","description":"Found checking .tekton/ after .golangci.yml v2 migration (commit 59c86b6). Earlier CI-impact check only grepped .forgejo/.github/Makefile/justfile and missed .tekton/.\n\nProblems in .tekton/tasks/go-ci.yaml:\n1. GOLANGCI_LINT_IMAGE default = docker.io/golangci/golangci-lint:v1.64-alpine — v1 binary cannot read version:\"2\" config: 'can't load config: unsupported version of the configuration'. Lint step exits nonzero on every run.\n2. LINT_REQUIRED default = \"false\" masks that failure as a warning — lint coverage silently zero in CI since migration.\n3. Version drift vs local toolchain (local golangci-lint 2.12.2).\n\nstaticcheck: not used standalone in .tekton (only as golangci-lint linter) — no action.\nGO_IMAGE golang:1.25 matches go.mod go 1.25.0 — OK.\n\nFix: bump image to v2.12.2-alpine (matches local exactly); flip LINT_REQUIRED default to \"true\" — task comment says 'Flip to true after baseline cleanup' and baseline is now 0 issues (commit dd9116f).","status":"closed","priority":1,"issue_type":"bug","owner":"goern@b4mad.net","created_at":"2026-06-10T22:10:03Z","created_by":"Christoph Görn","updated_at":"2026-06-10T22:11:05Z","closed_at":"2026-06-10T22:11:05Z","close_reason":"Fixed .tekton/tasks/go-ci.yaml: GOLANGCI_LINT_IMAGE default v1.64-alpine → v2.12.2-alpine (exact match to local 2.12.2; v1 could not parse the version:\"2\" .golangci.yml and failed every run, masked by warn-only mode). LINT_REQUIRED default false → true — baseline cleaned in dd9116f, and verified by replicating the CI step locally: 'podman run golangci-lint:v2.12.2-alpine golangci-lint run --timeout=5m ./...' → 0 issues, binary built with go1.26.2 (compatible with go.mod 1.25.0 + GOTOOLCHAIN=local). staticcheck has no standalone .tekton usage (runs as golangci-lint linter only). GO_IMAGE golang:1.25 unchanged, matches go.mod.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-fcm","title":"fix: page/limit defaulting uses wrong 'ok' variable in 4 handlers","description":"Copy-paste bug: 'if !ok { page = N }' tests the ok from an earlier unrelated type assertion (state/sha/all), not whether page/limit were provided. When the earlier param IS provided, page/limit stay 0 when omitted by the client.\n\nLocations:\n- operation/pull/pull.go:181,185 (ListRepoPullRequestsFn — ok from 'state')\n- operation/repo/commit.go:48,52 (ListRepoCommitsFn — ok from 'sha')\n- operation/user/notification.go:90,94 (CheckNotificationsFn — ok from 'all')\n- operation/user/notification.go:275,279 (ListRepoNotificationsFn — ok from 'all')\n\nFix: use the 'if page == 0 { page = 1 }' pattern used everywhere else.","status":"closed","priority":1,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-06-10T21:49:50Z","created_by":"Christoph Görn","updated_at":"2026-06-10T21:53:50Z","started_at":"2026-06-10T21:50:27Z","closed_at":"2026-06-10T21:53:50Z","close_reason":"Fixed: replaced 'if !ok' (stale ok from earlier type assertion) with 'if page == 0 / limit == 0' defaulting in operation/pull/pull.go (ListRepoPullRequestsFn), operation/repo/commit.go (ListRepoCommitsFn), operation/user/notification.go (CheckNotificationsFn + ListRepoNotificationsFn). Build/vet/tests pass.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-xjv","title":"track-downloads workflow: switch direct main push to PR + auto-merge (branch protection)","status":"closed","priority":1,"issue_type":"task","assignee":"@me","owner":"goern@b4mad.net","created_at":"2026-06-02T14:21:48Z","created_by":"Christoph Görn","updated_at":"2026-06-02T14:23:53Z","started_at":"2026-06-02T14:21:48Z","closed_at":"2026-06-02T14:23:53Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-773","title":"Implement label-crud OpenSpec change (tools + label resources)","description":"OpenSpec change 'label-crud' in PR #192 (branch feat/label-openspec, worktree ../forgejo-mcp-label-openspec). Adversarially reviewed by debate team 2026-06-02 (design.md Adversarial Review section). FINAL scope: (1) repo-label CRUD create_repo_label/edit_repo_label/delete_repo_label/get_repo_label via forgejo-sdk/v3 (renamed for symmetry — deviates from #190's create_label names, map on acceptance); (2) org-label CRUD create_org_label/edit_org_label/delete_org_label/get_org_label via pkg/forgejo DoJSON; (3) safe delete: delete_mode enum safe|force (NOT a boolean — reserves dry_run/reassign), in-use guard — repo count via SDK ListRepoIssues pagination (DoJSON discards X-Total-Count), org count best-effort/MAY-undercount token-invisible repos; (4) color 6-digit-only (3-digit unverified, gated); (5) resources forgejo://repo/{o}/{r}/labels{?page,limit} + /label/{id} + forgejo://org/{org}/labels{?page,limit} (renamed from owner→org root; page/limit client-controlled bound, EmbeddedListCap ceiling; scope-less label/{id} invalid); (6) mcp-resources-core MODIFIED Collection-resource requirement KEPT (goern decision; archive after mcp-resource-templates). Pre-code gates: org get-one endpoint, 3-digit hex. Out of scope: exclusive/is_archived (reserved optional). openspec validate --strict OK.","status":"closed","priority":1,"issue_type":"feature","owner":"goern@b4mad.net","created_at":"2026-06-02T07:44:00Z","created_by":"Christoph Görn","updated_at":"2026-06-10T06:59:51Z","started_at":"2026-06-10T06:27:41Z","closed_at":"2026-06-10T06:59:51Z","close_reason":"Closed","external_ref":"codeberg-190","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-8if","title":"Merge PR #185, finish stateless-http-auth smoke tests, archive change","description":"After PR #185 (fix: reject bare tokens) is reviewed by byteflavour and merged to main, complete the remaining stateless-http-auth tasks and archive the OpenSpec change.\n\nPR: https://codeberg.org/goern/forgejo-mcp/pulls/185\n\nRemaining tasks (openspec/changes/stateless-http-auth/tasks.md):\n- 6.4 Manual smoke: start server --transport http --url https://codeberg.org (no --token); two requests w/ distinct tokens; each get_my_user_info returns correct distinct identity.\n- 6.5 Manual smoke: Authorization: bearer xyz (lowercase) resolves to per-request identity, not global fallback (validates 2.4).\n- 6.6 Manual smoke: broken Forgejo URL so SDK version probe fails; request returns error, not silent global-token auth (validates 1.3).\n- 6.7 Archive: openspec archive stateless-http-auth (moves to openspec/changes/archive/\u003cdate\u003e-stateless-http-auth/).\n\nBlocker fixes 1.3, 2.4, 2.5, 4.2-4.4 already implemented (most on main, bare-token fix in #185). Build/test/validate all green.","status":"closed","priority":1,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-06-01T21:43:09Z","created_by":"Christoph Görn","updated_at":"2026-06-01T22:00:43Z","started_at":"2026-06-01T21:54:17Z","closed_at":"2026-06-01T22:00:43Z","close_reason":"PR #185 merged; smoke tests 6.4/6.5 passed E2E (valid-\u003egoern, bogus/no-auth-\u003eerror, lowercase bearer-\u003egoern), 6.6 covered by unit test 4.3; specs synced to openspec/specs/stateless-http-auth/; change archived to openspec/changes/archive/2026-06-02-stateless-http-auth/","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-wbw","title":"Fix PaC task annotation YAML folding bug in .tekton/release-tools-*.yaml","description":"PipelinesAsCode failed on PR #172 with 'annotations in pipeline are in wrong format: [git-clone,\\n .tekton/release-tools/tasks/build-image.yaml,...]'. Two PaC PipelineRun manifests use 'pipelinesascode.tekton.dev/task: \u003e-' with continuation lines indented one space deeper than the first content line. YAML folded scalar (\u003e-) preserves newlines when continuation lines are MORE indented than the first content line, so PaC sees a literal multi-line string instead of a flat bracketed list. Affects: .tekton/release-tools-on-pull-request-build.yaml and .tekton/release-tools-on-tag-publish.yaml.","notes":"Fix: collapse the bracketed task list to a single double-quoted string on the annotation line, e.g.:\n pipelinesascode.tekton.dev/task: \"[git-clone, .tekton/release-tools/tasks/build-image.yaml, .tekton/release-tools/tasks/verify-image-tools.yaml, .tekton/release-tools/tasks/syft-scan-image.yaml]\"\nPR #172 comment: https://codeberg.org/goern/forgejo-mcp/pulls/172#issuecomment-16027445","status":"closed","priority":1,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-28T15:35:11Z","created_by":"Christoph Görn","updated_at":"2026-05-28T15:36:11Z","started_at":"2026-05-28T15:35:15Z","closed_at":"2026-05-28T15:36:11Z","close_reason":"Fixed in 3a12931. PaC task annotations collapsed to single-line inline lists in release-tools-on-pull-request-build.yaml + release-tools-on-tag-publish.yaml.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-kva","title":"fix: cosign-sign task fails with --output-signature deprecated","description":"cosign v2.4+ deprecated --output-signature in favor of --bundle. When new-bundle-format is active (now default), --output-signature is silently ignored and cosign tries to write bundle to empty path → 'create bundle file: open : no such file or directory'. Fix: replace --output-signature with --bundle in .tekton/tasks/cosign-sign-release.yaml (and .forgejo/workflows/release.yml for consistency). External: PipelineRun on-tag-push-release-srlfm, task cosign-sign.","status":"closed","priority":1,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-26T06:19:20Z","created_by":"Christoph Görn","updated_at":"2026-05-26T06:19:52Z","started_at":"2026-05-26T06:19:22Z","closed_at":"2026-05-26T06:19:52Z","close_reason":"Fixed: --output-signature → --bundle in cosign-sign-release.yaml and release.yml. Committed cee6465.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-aps","title":"Fix build-image task: remove privileged, use rootless buildah","description":"build-image.yaml sets securityContext.privileged: true which is rejected by OpenShift container-build SCC bound to the pipeline SA. Fix: remove privileged: true, run as UID 1000, use --isolation=chroot --storage-driver=vfs so buildah works rootless under container-build SCC.","status":"closed","priority":1,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-25T23:10:09Z","created_by":"Christoph Görn","updated_at":"2026-05-26T00:14:57Z","started_at":"2026-05-25T23:10:13Z","closed_at":"2026-05-26T00:14:57Z","close_reason":"PR #163 open. All task bugs fixed and validated by run11. build/push/sign/sbom/promote all succeeded.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-8sz","title":"Move release-tools PipelineRuns to .tekton/ root — PaC v0.42.0 does not scan subdirectories","description":"PaC v0.42.0 only reads PipelineRun YAMLs from .tekton/*.yaml (root level). .tekton/release-tools/on-tag-publish.yaml and on-pull-request-build.yaml are invisible to PaC and never trigger. Fix: move both PipelineRun files to .tekton/ root with release-tools- prefix. Task YAMLs in .tekton/release-tools/tasks/ stay in place (PaC fetches them by explicit path in the task annotation).","status":"closed","priority":1,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-25T22:53:37Z","created_by":"Christoph Görn","updated_at":"2026-05-25T22:59:33Z","started_at":"2026-05-25T22:53:40Z","closed_at":"2026-05-25T22:59:33Z","close_reason":"PR #160 merged — PipelineRuns moved to .tekton/ root, CEL fixed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-00o","title":"Restore cosign fail-closed signing after release-tools/v1.0.0 bootstrap ships","description":"Bootstrap exception: the first release-tools/v1.0.0 publish run will be invoked with SKIP_SIGN=true PipelineRun param so signing is skipped (allowed per D4 of design.md — chicken-egg unknowns at first end-to-end run). After v1.0.0 is published and pullable, run a smoke release-tools/v1.0.1 (no-op image bump or tooling rev) with SKIP_SIGN=false (default) to confirm cosign-signing-key Secret shape matches and signature objects land in codeberg.org/operate-first/release-tools registry. Verify cosign verify --key \u003cop1st-pub\u003e against the v1.0.1 manifest. Once green: remove the SKIP_SIGN param from on-tag-publish.yaml entirely (revert to spec.md A3 fail-closed posture exactly).","acceptance_criteria":"release-tools/v1.0.1 (or later) published with SKIP_SIGN=false. cosign verify succeeds. SKIP_SIGN param removed from on-tag-publish.yaml. Bead closes when commit landing the removal merges.","notes":"PR #158 created: https://codeberg.org/goern/forgejo-mcp/pulls/158. Code removes SKIP_SIGN param, validate-skip-sign task, and all when: guards — cosign-sign/attach-sbom now unconditional. Pre-merge: operator must verify release-tools/v1.0.1 publishes with signing enabled and cosign verify passes.","status":"closed","priority":1,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-25T17:08:31Z","created_by":"Christoph Görn","updated_at":"2026-05-26T00:14:57Z","started_at":"2026-05-25T22:34:46Z","closed_at":"2026-05-26T00:14:57Z","close_reason":"PR #158 merged. v1.0.1 published with signing enabled (run11 succeeded). SKIP_SIGN removed from on-tag-publish.yaml. A3 fail-closed posture restored.","dependencies":[{"issue_id":"forgejo-mcp-00o","depends_on_id":"forgejo-mcp-1b4","type":"blocks","created_at":"2026-05-25T17:08:36Z","created_by":"Christoph Görn","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-j52","title":"Split cosign keypair: separate release-tools-image signing from release-artifact signing","description":"Origin: L4 from release-tools-image adversarial review. v1.0.0 of the image is signed with the same cosign-signing-key Secret used to sign forgejo-mcp release artifacts. The release-tools image is consumed by .tekton/tasks/cosign-sign-release.yaml at release time, so a compromised image (via Containerfile change, transitive dep, or npm-package takeover) has access to the signing key and can sign attacker-supplied binaries. Mitigation: provision a second keypair in op1st-pipelines (e.g. cosign-signing-key-images vs cosign-signing-key-artifacts) so a release-tools image compromise cannot forge release artifact signatures. Coordinate with op1st-emea-b4mad maintainers for the second secret + reflector ruleset.","notes":"Blocked on op1st-emea-b4mad-yn5 (op1st-emea-b4mad beads, P1): 'Provision second cosign keypair to isolate release-tools image signing from forgejo-mcp artifact signing'. That task covers Secret provisioning + reflector ruleset. forgejo-mcp-j52 unblocks once op1st-emea-b4mad-yn5 is complete and both Secrets exist in op1st-pipelines.","status":"closed","priority":1,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-25T13:52:20Z","created_by":"Christoph Görn","updated_at":"2026-05-26T09:18:37Z","started_at":"2026-05-26T09:05:07Z","closed_at":"2026-05-26T09:18:37Z","close_reason":"PR #164 merged, cosign-signing-key-artifacts + cosign-signing-key-images confirmed in op1st-pipelines, v2.25.1 released with correct key separation.","dependencies":[{"issue_id":"forgejo-mcp-j52","depends_on_id":"forgejo-mcp-1b4","type":"blocks","created_at":"2026-05-25T13:52:44Z","created_by":"Christoph Görn","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-3h2","title":"Tighten release-tools pinning: vendor goreleaser, SHA256-verify curl-installed binaries","description":"Origin: L2 from release-tools-image adversarial review. The v1.0.0 image installs goreleaser via 'go install \u003ctag\u003e' which re-resolves transitive deps from proxy.golang.org on every build; syft and cosign installed via curl by tag only (no SHA256 verify). A transitive-dep takeover in goreleaser's module graph OR a CDN poisoning of anchore/sigstore release URLs would ship unnoticed. Fix: vendor goreleaser source at pinned SHA (build via 'go build' from a committed go.mod/go.sum), and SHA256-verify all curl-downloaded binaries against checksums recorded in VERSIONS.md before installing them.","notes":"PR #159: https://codeberg.org/goern/forgejo-mcp/pulls/159. goreleaser: go install → prebuilt tarball + dual SHA256 verify. syft: curl|sh → direct tarball + dual SHA256 verify. Hashes in VERSIONS.md + Containerfile ARG defaults. cosign unchanged.","status":"closed","priority":1,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-25T13:52:15Z","created_by":"Christoph Görn","updated_at":"2026-05-26T00:14:57Z","started_at":"2026-05-25T22:37:39Z","closed_at":"2026-05-26T00:14:57Z","close_reason":"PR #159 merged. goreleaser+syft now SHA256-verified via dual check against repo hash and publisher checksums.txt. Filename bug fixed in PR #162.","dependencies":[{"issue_id":"forgejo-mcp-3h2","depends_on_id":"forgejo-mcp-1b4","type":"blocks","created_at":"2026-05-25T13:52:44Z","created_by":"Christoph Görn","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-aun","title":"Hummingbird base health monitoring: SLO on hi/go tag lag + scheduled CVE rescan","description":"Origin: A6 + L6 from release-tools-image adversarial review (openspec/changes/release-tools-image/review.md). Hummingbird is young; hi/go may lag upstream Go releases. Renovate bumps tags but does NOT surface CVEs landing between bumps. Need: (a) documented SLO for acceptable lag between upstream Go GA and hi/go:\u003cver\u003e-builder availability, (b) second-source mirror policy if Red Hat pulls a tag mid-cycle, (c) scheduled PipelineRun (e.g. weekly) that pulls the published release-tools image and runs grype or trivy against it, opening issues on findings. Defer until release-tools-image v1.0.0 ships + one CVE-cycle of operational data exists.","notes":"Tracked in design.md Open Questions as forgejo-mcp-bd-A6L6 placeholder. Filed under Status/Blocked per acceptance criteria of release-tools-image change.","status":"open","priority":1,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-05-25T13:52:10Z","created_by":"Christoph Görn","updated_at":"2026-05-25T13:52:10Z","dependencies":[{"issue_id":"forgejo-mcp-aun","depends_on_id":"forgejo-mcp-1b4","type":"blocks","created_at":"2026-05-25T13:52:44Z","created_by":"Christoph Görn","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-trb","title":"Fix goreleaser-release Task: move Go cache out of git checkout to avoid dirty-tree","description":"GoReleaser run on v2.24.1 failed: 'git is in a dirty state' caused by GOCACHE=/workspace/src/.gocache + GOMODCACHE=/workspace/src/.gomodcache placing untracked dirs inside the repo. GoReleaser checks git status before publishing and bails on any uncommitted/untracked content. Fix: move caches to /tmp/gocache + /tmp/gomodcache (per-step but acceptable; release runs once per tag).","acceptance_criteria":"goreleaser release succeeds on v2.24.2; cosign-sign + mcpb-pack downstream Tasks complete; all 8 assets uploaded","status":"closed","priority":1,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-25T11:54:05Z","created_by":"Christoph Görn","updated_at":"2026-05-25T11:55:30Z","started_at":"2026-05-25T11:54:05Z","closed_at":"2026-05-25T11:55:30Z","close_reason":"PR #154 merged. Go cache moved to /tmp. v2.24.2 cut next.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-29g","title":"Fix goreleaser-release Task: collapse install steps to survive Pod step-isolation","description":"Path B workaround for forgejo-mcp-1b4. Step containers in a Tekton Pod don't share /usr/local/bin/, so syft + goreleaser installed in install-* steps disappear before the release step runs (exit 127 'goreleaser: command not found' on first v2.24.0 run). Collapse install-syft + install-goreleaser + release into a single Step that installs both tools inline and then invokes goreleaser release. Smoke-test stays separate (reads from dist/ on workspace). Proper image-based fix tracked in forgejo-mcp-1b4.","acceptance_criteria":"goreleaser-release Task succeeds end-to-end on v2.24.1; all 8 release assets uploaded to Codeberg; cosign-sign + mcpb-pack downstream Tasks complete","status":"closed","priority":1,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-25T11:47:11Z","created_by":"Christoph Görn","updated_at":"2026-05-25T11:49:15Z","started_at":"2026-05-25T11:47:15Z","closed_at":"2026-05-25T11:49:15Z","close_reason":"PR #153 merged. Inline syft+goreleaser install in release Step; v2.24.1 cut next to validate.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-hvr","title":"Fix release workflow smoke-test: --help + dead ldflags break v2.23.0 release","description":"Release run 172 (tag v2.23.0) failed at smoke-test step in .forgejo/workflows/release.yml. Two compounding bugs:\n\n1. main.go declares 'var Version = \"dev\"' but .goreleaser.yml ldflags inject '-X main.BuildTag={{.Version}}' (and BuildCommit/BuildDate). Symbol main.BuildTag is not defined anywhere — grep returns zero hits. So Version stays 'dev' in shipped binaries.\n\n2. Smoke-test runs '$BIN --help' but the CLI uses flag.NewFlagSet with ExitOnError; --help is undefined, exits non-zero with 'flag provided but not defined: -help' on stderr and Usage banner. The expected regex '^forgejo-mcp ${VERSION}([+-]|$)' never matches.\n\nFix:\n- .goreleaser.yml: rewrite ldflags to -X main.Version={{.Version}} (drop dead BuildCommit/BuildDate or wire them to real vars).\n- .forgejo/workflows/release.yml: invoke '$BIN version' (the 'version' subcommand documented in cmd.go isVersionRequest) instead of '--help'.\n\nTracks: https://codeberg.org/goern/forgejo-mcp/actions/runs/172","notes":"PR #149 opened: https://codeberg.org/goern/forgejo-mcp/pulls/149. Fix verified locally (ldflags + 'version' subcommand). Awaiting merge + next release tag to re-cut release pipeline.","status":"closed","priority":1,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-25T08:28:14Z","created_by":"Christoph Görn","updated_at":"2026-05-25T08:37:38Z","started_at":"2026-05-25T08:28:17Z","closed_at":"2026-05-25T08:37:38Z","close_reason":"PR #149 merged into main (merge commit 332b989). Release pipeline fixed; next semantic-release tag (v2.23.1+) will re-cut a clean release.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-5x8","title":"fix: add pull_request event to Codeberg webhook for op1st PaC","description":"Codeberg repo webhook (id 60326) to op1st Pipelines-as-Code controller only subscribes to push event. No pull_request event delivered, so on-pull-request, openspec-validate-pr, code-scans PR pipelines never fire on any open PR (#126, #138, #139). Push pipelines on main work fine (verified on 4f57c57). Fix: PATCH hook events to include pull_request (and pull_request_comment for /ok-to-test on fork PRs).","notes":"Verified via curl: events=['push']. Root cause of all three open PRs lacking PaC statuses.","status":"closed","priority":1,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-24T07:13:31Z","created_by":"Christoph Görn","updated_at":"2026-05-24T07:16:46Z","started_at":"2026-05-24T07:15:18Z","closed_at":"2026-05-24T07:16:46Z","close_reason":"Patched webhook 60326 events from ['push'] to push+pull_request+pull_request_comment (plus auto-expanded subevents). Verified: /test comment on PR #139 triggered op1st Pipelines as Code / on-pull-request status (pending). All future PR opens/syncs/comments will now reach PaC.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-f37","title":"CI: add lint, race, mod-tidy, govulncheck to go-ci task","description":"Current .tekton/tasks/go-ci.yaml only does build+test. Missing critical correctness gates. Add golangci-lint (gofmt, errcheck, staticcheck, ineffassign, gosec), go test -race -shuffle=on -count=1, go mod tidy drift check, govulncheck ./...","acceptance_criteria":"go vet runs, golangci-lint runs (warning-only first pass acceptable), race detector on, govulncheck zero high-severity findings, go.mod/go.sum drift fails build","notes":"PR opened: https://codeberg.org/goern/forgejo-mcp/pulls/142 (mergeable). Bead stays in_progress until merge — close on merge.","status":"closed","priority":1,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-24T07:06:30Z","created_by":"Christoph Görn","updated_at":"2026-05-24T07:24:57Z","started_at":"2026-05-24T07:06:57Z","closed_at":"2026-05-24T07:24:57Z","close_reason":"Merged via PR #142 (rebase). Step 1 hardening live in main.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-r7h","title":"fix: -debug flag defaults to true, FORGEJO_DEBUG env is dead code","description":"cmd/cmd.go:84-95 — fs.BoolVar(\u0026debug, \"d\"/\"debug\", true, ...). Debug-level logging always on by default; the FORGEJO_DEBUG/GITEA_DEBUG env fallback (lines 170-190) only runs when debug==false, which requires explicitly passing -debug=false. Default for a debug flag should be false.\n\nFix: default both flags to false.","status":"closed","priority":2,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-06-10T21:50:20Z","created_by":"Christoph Görn","updated_at":"2026-06-10T21:53:53Z","started_at":"2026-06-10T21:50:28Z","closed_at":"2026-06-10T21:53:53Z","close_reason":"Fixed: -d/-debug flag default changed true→false (cmd/cmd.go). Debug logging now opt-in; FORGEJO_DEBUG / deprecated GITEA_DEBUG env fallback path is reachable again. Build/vet/tests pass.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-3nu","title":"fix: search_users and search_org_teams ignore page/limit params","description":"operation/search/search.go: both tools advertise page/limit with defaults; handlers never set ListOptions. SDK SearchUsersOption and SearchTeamsOptions both embed ListOptions.\n\nFix: parse page/limit (to.Float64 + zero-default) and set ListOptions in both handlers.","status":"closed","priority":2,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-06-10T21:50:19Z","created_by":"Christoph Görn","updated_at":"2026-06-10T21:53:52Z","started_at":"2026-06-10T21:50:27Z","closed_at":"2026-06-10T21:53:52Z","close_reason":"Fixed: SearchUserFn and SearchOrgTeamsFn now parse page/limit (default 1/100, matching schema defaults) and set embedded ListOptions on SearchUsersOption / SearchTeamsOptions (operation/search/search.go). Also added missing log.Debugf to SearchUserFn. Build/vet/tests pass.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-7f8","title":"fix: label resources ignore documented {?page,limit} query params","description":"operation/issue/resources_label.go pageLimit() is a stub: always returns page=1, limit=EmbeddedListCap. Template descriptions + AGENTS.md resource table document forgejo://repo/{owner}/{repo}/labels{?page,limit} and forgejo://org/{org}/labels{?page,limit} as client-controlled. Output-bounding design requires client-controlled bound.\n\nFix: parse query from req.Params.URI (url.Parse → Query()), clamp limit to EmbeddedListCap, default page=1.","status":"closed","priority":2,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-06-10T21:50:19Z","created_by":"Christoph Görn","updated_at":"2026-06-10T21:53:53Z","started_at":"2026-06-10T21:50:28Z","closed_at":"2026-06-10T21:53:53Z","close_reason":"Fixed: pageLimit() in operation/issue/resources_label.go now parses ?page,limit from req.Params.URI via url.Parse; limit clamped to EmbeddedListCap (30), malformed/absent values fall back to defaults. Added unit tests (resources_label_pagelimit_test.go): defaults, query values, clamp, malformed. {?page,limit} contract in template descriptions + AGENTS.md now honored. Build/vet/tests pass.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-9ii","title":"fix: list_repo_issues 'type' parameter parsed but never applied","description":"operation/issue/issue.go:282-285 — issueType is read from args, then an empty if-block does nothing. SDK ListIssueOption has 'Type IssueType' (issue.go:66 in forgejo-sdk v3). Tool schema advertises type=(issues|pulls) but filter is silently ignored.\n\nFix: set opt.Type = forgejo_sdk.IssueType(issueType).","status":"closed","priority":2,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-06-10T21:50:19Z","created_by":"Christoph Görn","updated_at":"2026-06-10T21:53:51Z","started_at":"2026-06-10T21:50:27Z","closed_at":"2026-06-10T21:53:51Z","close_reason":"Fixed: ListRepoIssuesFn now sets opt.Type = forgejo_sdk.IssueType(issueType) when type arg provided (operation/issue/issue.go). SDK v3 ListIssueOption.Type confirmed. Build/vet/tests pass.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-cdf","title":"fix: list_repo_pull_requests advertises milestone+labels but ignores both","description":"operation/pull/pull.go ListRepoPullRequestsFn: 'milestone' and 'labels' params in tool schema; handler reads neither (comments claim SDK doesn't support). SDK v3 ListPullRequestsOptions HAS Milestone int64. Labels is genuinely unsupported by SDK.\n\nFix: wire milestone (parse to int64, set opt.Milestone); remove 'labels' from tool schema so schema matches behavior.","status":"closed","priority":2,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-06-10T21:50:19Z","created_by":"Christoph Görn","updated_at":"2026-06-10T21:53:51Z","started_at":"2026-06-10T21:50:27Z","closed_at":"2026-06-10T21:53:51Z","close_reason":"Fixed: ListRepoPullRequestsFn parses milestone arg to int64 and sets opt.Milestone (SDK v3 supports it). Removed 'labels' from list_repo_pull_requests tool schema — SDK ListPullRequestsOptions has no labels filter, so the param was unimplementable; schema now matches behavior. Build/vet/tests pass.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-tc6","title":"fix: delete_file advertises new_branch_name but drops it","description":"operation/repo/file.go DeleteFileFn: tool schema includes new_branch_name (params.NewBranchName); handler never reads it, FileOptions.NewBranchName never set — delete always commits to branch_name directly.\n\nFix: read arg, set FileOptions.NewBranchName like CreateFileFn/UpdateFileFn do.","status":"closed","priority":2,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-06-10T21:50:19Z","created_by":"Christoph Görn","updated_at":"2026-06-10T21:53:52Z","started_at":"2026-06-10T21:50:28Z","closed_at":"2026-06-10T21:53:52Z","close_reason":"Fixed: DeleteFileFn reads new_branch_name and sets FileOptions.NewBranchName (operation/repo/file.go), matching CreateFileFn/UpdateFileFn. Build/vet/tests pass.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-6ua","title":"track-downloads: daily snapshot PRs stick when required 'on-pull-request' check never posts a status","description":"## Problem\n\nThe track-downloads workflow (.forgejo/workflows/track-downloads.yml) opens a daily snapshot PR against protected `main` and relies on Forgejo auto-merge to land it unattended. Verified live 2026-06-02 via workflow_dispatch (run #249).\n\nTwo failure modes observed, only the first is fixed:\n\n1. FIXED (#201): immediate merge returns HTTP 405 while required Tekton checks are still pending. Workflow now tries immediate merge, else schedules `merge_when_checks_succeed`.\n\n2. OPEN: `goern/main` branch protection requires the `op1st Pipelines as Code / forgejo-mcp-on-pull-request` status check, but on PR #199 only `forgejo-mcp-code-scans` posted a status — `on-pull-request` never reported on the data-only commit (likely a path filter skipping docs/downloads/*). Result: required check is permanently 'pending/missing', merge 405s forever, and scheduled auto-merge never fires (no future status event). #199 had to be force-merged manually.\n\nIf on-pull-request systematically skips docs/downloads-only commits, EVERY daily bot PR will stick and need manual force-merge — defeating the unattended design.\n\n## Options to fix\n- Exempt the bot's docs/downloads path from the 'on-pull-request' required-status-check rule on main (branch protection config), OR\n- Drop on-pull-request from required checks for these PRs, OR\n- Have the workflow force-merge its own data-only PR (curl merge with force_merge=true) after opening it, accepting the protection bypass for this narrow path, OR\n- Make the on-pull-request Tekton pipeline post a (trivially-passing) status even on docs-only changes.\n\n## Repro\n1. Dispatch track-downloads when counts have moved.\n2. Workflow opens bot/downloads-\u003cdate\u003e PR.\n3. Observe: only code-scans posts a commit status; merge stays 405.\n\n## Refs\n- Fixed merge-pending: PR #201 (merged)\n- Stuck PR example: #199 (force-merged 2026-06-02)\n- Initial rework: PR #198","status":"open","priority":2,"issue_type":"bug","owner":"goern@b4mad.net","created_at":"2026-06-02T16:54:25Z","created_by":"Christoph Görn","updated_at":"2026-06-02T16:54:25Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-0zl","title":"README §4 verify-blob fetches renamed cosign key (cosign-signing-key.pub now 404)","description":"operate-first/op1st-emea-b4mad split the single cosign key into cosign-signing-key-artifacts.pub (blob/artifacts) + cosign-signing-key-images.pub (images) on 2026-06-02. README §4 (verify-blob, ~L417-418) still fetches cosign-signing-key.pub from branch/main, which now 404s. Fix: point §4 at cosign-signing-key-artifacts.pub. README §5/§6 (cosign-signing-key-images.pub) are already correct. Pinned-commit URL (8a3c55e) for the old name still resolves, so this only breaks the branch/main fetch. Discovered during signed-sbom-attestation archive (PR #189 follow-up). See bd memory signed-sbom-key-drift.","status":"closed","priority":2,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-06-02T13:13:47Z","created_by":"Christoph Görn","updated_at":"2026-06-02T13:52:26Z","started_at":"2026-06-02T13:47:30Z","closed_at":"2026-06-02T13:52:26Z","close_reason":"Merged in PR #194. README §2 fetches cosign-signing-key-artifacts.pub (branch-tip + re-pinned commit cd3715f); prose clarifies artifact vs image key. All key URLs 200; no stale cosign-signing-key.pub refs.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-tcy","title":"CLI resource-read path (--cli read forgejo://...) for resource-template parity","description":"Codeberg #191. --cli mode (cmd/cli.go) reaches tools (registerToolsWithDomains + cliExec dispatch by name) but NOT resources: registerToolsWithDomains registers tools only, no forgejo:// reader, no 'read' subcommand. All shipped resources (repo/commit/status/issue/pr/comment/owner) are MCP-only, invisible from CLI. Add 'forgejo-mcp --cli read \u003cforgejo-uri\u003e' wired to the same resource handlers (shared registerResourcesWithDomains, no MCP-vs-CLI divergence), honour output-bounding contract, surface templates in --cli list. Cross-cutting: blocks resource-template halves of #136 (webhook) and #190 (label). Tool CLI parity already automatic. Showboat demo must read \u003e=1 resource over --cli.","status":"open","priority":2,"issue_type":"feature","owner":"goern@b4mad.net","created_at":"2026-06-02T06:39:22Z","created_by":"Christoph Görn","updated_at":"2026-06-02T06:39:22Z","external_ref":"codeberg-191","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-3y1","title":"OpenSpec: update release-tools-image SBOM requirement for signed cosign attest","description":"Archived + live spec synced in PR #193 (branch openspec/archive-signed-sbom-attestation), follows merged #189. Showboat demo added (real cosign attest/verify-attestation roundtrip). Key-split README §4 follow-up filed as forgejo-mcp-0zl. Keep open until #193 merges.","acceptance_criteria":"An OpenSpec change updates the 'SBOM attached as registry artifact' requirement + scenario in release-tools-image/spec.md to: (a) state the SBOM is a signed cosign attestation (cosign attest --type cyclonedx), (b) replace the 'cosign download sbom' retrieval contract with 'cosign verify-attestation --type cyclonedx' (and/or download attestation). Change validated and archived; main spec synced. README already updated under aa6.","notes":"Code already migrated (aa6, .tekton/release-tools/tasks/cosign-attach-sbom.yaml). README consumer block already updated under aa6. Remaining drift is the governed spec only.\nPR #189 opened (branch openspec/signed-sbom-attestation, commit 5207bd9): https://codeberg.org/goern/forgejo-mcp/pulls/189\nOpenSpec change 'signed-sbom-attestation' — 1 MODIFIED delta on release-tools-image. openspec validate --strict passes. Spec-only (task+README already landed under aa6/b2619fc).\nRemaining (tasks.md 3.2): after merge, archive change + sync openspec/specs/release-tools-image/spec.md. Keep 3y1 open until merged+archived.","status":"closed","priority":2,"issue_type":"task","assignee":"goern","owner":"goern@b4mad.net","created_at":"2026-06-02T05:58:49Z","created_by":"Christoph Görn","updated_at":"2026-06-02T13:42:28Z","closed_at":"2026-06-02T13:42:28Z","close_reason":"Merged in PR #193 (merge commit on main). Live release-tools-image spec synced to signed cosign attest --type cyclonedx + verify-attestation; change archived 2026-06-02-signed-sbom-attestation; real showboat demo committed. README §4 key-rename remains as follow-up forgejo-mcp-0zl.","external_ref":"codeberg-pr-189","dependencies":[{"issue_id":"forgejo-mcp-3y1","depends_on_id":"forgejo-mcp-aa6","type":"discovered-from","created_at":"2026-06-02T05:59:07Z","created_by":"Christoph Görn","metadata":"{}"}],"dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-o5b","title":"Gate image :latest promotion to stable releases only","description":"promote-image-tag (.tekton/release-tools/tasks/promote-image-tag.yaml) unconditionally tags BOTH :vX.Y.Z and :latest. The release pipeline triggers on any refs/tags/v[0-9], including pre-releases (alpha/beta/rc). Result: a pre-release would move :latest to a non-stable image. For v2.27.0-alpha.1 (2026-06-01) :latest was deliberately skipped via a manual skopeo copy. Fix: skip the :latest promotion when TAG matches a pre-release pattern (contains '-'), or pass a PROMOTE_LATEST flag from the pipeline computed from the tag.","status":"closed","priority":2,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-06-01T08:59:32Z","created_by":"Christoph Görn","updated_at":"2026-06-01T09:08:59Z","closed_at":"2026-06-01T09:08:59Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-01e","title":"Add OWNERS file to authorize PaC CI triggering","description":"PR #178 (author: byteflavour) is blocked with 'User byteflavour is not allowed to trigger CI via pull_request in this repo'. This is Pipelines as Code (op1st-pipelines ns), which reads a Prow-style OWNERS file from the default branch to decide who may trigger a PipelineRun without /ok-to-test. Add OWNERS listing goern, byteflavour, b4mad-renovate, op1st-gitops so their PRs trigger CI automatically.","status":"closed","priority":2,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-31T19:00:57Z","created_by":"Christoph Görn","updated_at":"2026-05-31T19:02:06Z","started_at":"2026-05-31T19:01:00Z","closed_at":"2026-05-31T19:02:06Z","close_reason":"OWNERS file added on main branch; PaC will now auto-trigger for goern, byteflavour, b4mad-renovate, op1st-gitops PRs. Unblocks PR #178.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-vbz","title":"Update Containerfile to use hummingbird-project based containers","description":"Migrate Containerfile base images from registry.access.redhat.com (go builder + core-runtime) to hummingbird-project based containers. Affects both build stage and runtime stage. Verify build still works (make build, CGO_ENABLED=0) and image runs the forgejo-mcp entrypoint.","notes":"Project Hummingbird = Red Hat hardened images (gitlab.com/redhat/hummingbird/containers), public mirror quay.io/hummingbird/*, non-root. Current Containerfile uses registry.access.redhat.com/hi/* (same images, RH registry). Migration = repoint to quay mirror. Mapping: build stage /hi/go:1.26.3-builder -\u003e quay.io/hummingbird/go:\u003cver\u003e-builder ; runtime /hi/core-runtime:2.42 -\u003e quay.io/hummingbird/core-runtime (or quay.io/hummingbird/static, binary is CGO_ENABLED=0 static). Decide static vs core-runtime, pin tags + digests. Verify: make build (CGO_ENABLED=0), image runs /app/forgejo-mcp entrypoint.","status":"closed","priority":2,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-31T18:39:10Z","created_by":"Christoph Görn","updated_at":"2026-05-31T19:23:43Z","started_at":"2026-05-31T18:44:31Z","closed_at":"2026-05-31T19:23:43Z","close_reason":"Done in PR (branch feat/hummingbird-containers, commit 988398a). Containerfile repointed to quay.io/hummingbird/{go,core-runtime} (identical digests); VERSION injected via build-arg fixing empty version/--version output.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-5zy","title":"Track + visualize release asset download counts","description":"Forgejo API exposes cumulative download_count per release asset, but keeps no history. Snapshot daily into JSONL (git = time-series DB), then visualize per-release and feat-vs-fix (semver-bump classification) in a static Chart.js dashboard. Scheduler: one reintroduced Forgejo Actions cron workflow (Tekton-only stack otherwise; user accepted the tradeoff).","status":"closed","priority":2,"issue_type":"feature","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-31T14:55:18Z","created_by":"Christoph Görn","updated_at":"2026-05-31T15:06:14Z","started_at":"2026-05-31T14:55:22Z","closed_at":"2026-05-31T15:06:14Z","close_reason":"Shipped via PR #177 — daily download tracking + Chart.js dashboard","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-dn0","title":"Extend release pipeline to build and push an OCI container image","description":"The app release pipeline (.tekton/on-tag-push-release.yaml, fired on tag push) builds binaries via GoReleaser + cosign-signs + packs mcpb, but does NOT build or publish an OCI container image for forgejo-mcp itself. A multi-stage root Containerfile already exists and builds a working runtime image — it's just never built/pushed on release.\n\nScope:\n- On tag push, build the OCI image from the root Containerfile (binary already produced by 'make build').\n- Push by digest to a registry (Codeberg package/OCI registry under goern/forgejo-mcp, or quay — decide), tagged with the release version + a moving tag (e.g. latest).\n- Sign the image with cosign and attach an SBOM, matching the binary-release security posture.\n- REUSE the existing Tekton tasks already in-repo for the release-tools image: .tekton/release-tools/tasks/{build-image,push-image-by-digest,cosign-sign-image-by-digest,cosign-attach-sbom,promote-image-tag}.yaml — wire them into the app release pipeline rather than authoring new ones.\n- Document the published image (registry path, supported tags, cosign verify command) in README.\n\nOpen decisions: target registry + namespace; whether to build multi-arch (amd64/arm64); tag scheme (semver + latest); whether image publish gates on the same tag event as GoReleaser or a separate pipeline.\n\nWhy: ship a runnable container so users can 'podman run' the MCP server without building from source; aligns app distribution with the already-containerized release-tools image and the signed-binary posture.","status":"closed","priority":2,"issue_type":"feature","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-31T14:45:07Z","created_by":"Christoph Görn","updated_at":"2026-06-01T06:49:21Z","started_at":"2026-06-01T06:29:55Z","closed_at":"2026-06-01T06:49:21Z","close_reason":"Implemented: tag-push release pipeline now builds, signs, SBOM-attaches and publishes the OCI image to codeberg.org/goern/forgejo-mcp by reusing the release-tools tasks. Commit bdfd968.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-fd6","title":"Label tools + label resource templates","description":"forgejo-mcp exposes list_repo_labels / list_org_labels / add_issue_labels / remove_issue_labels, but has NO label CRUD: cannot create, edit, or delete a repo/org label. Surfaced 2026-05-31 while creating the 'RFC - Request For Comments' label for #176 — had to fall back to raw curl against the Forgejo REST API because no MCP tool exists. (Reactions read was the same gap.)\n\nScope:\n- Tools: create_label, edit_label, delete_label for repo labels (POST/PATCH/DELETE /repos/{o}/{r}/labels[/{id}]); consider org-label equivalents (/orgs/{org}/labels).\n- Resource templates: forgejo://repo/{owner}/{repo}/label/{id} and/or a labels listing resource, so labels are URI-addressable like the existing issue/pr/commit resources. Follow operation/resource conventions (ParseXxx, Bounded, MapForgejoError) and docs/design/output-bounding.md.\n- Implement via forgejo-sdk where available, else pkg/forgejo raw-HTTP (DoJSON) like the wiki/attachment precedent.\n- Surface in README tool+resource tables and AGENTS.md.\n\nWhy: closes a real CRUD gap (label management currently impossible via MCP) and extends the resource-template surface to labels for discoverability.","status":"closed","priority":2,"issue_type":"feature","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-31T14:40:12Z","created_by":"Christoph Görn","updated_at":"2026-06-02T06:35:37Z","started_at":"2026-06-02T06:33:08Z","closed_at":"2026-06-02T06:35:28Z","close_reason":"Created well-prepared Codeberg #190 (feat: label CRUD tools + label resource-templates), labeled Kind/Feature + Priority/Medium, assigned goern. Issue captures: repo-label CRUD via SDK v3 (CreateLabel/EditLabel/DeleteLabel/GetRepoLabel — already in pinned dep), org-label CRUD via pkg/forgejo raw-HTTP DoJSON (no SDK method, mirrors fetchOrgLabels), resource-templates forgejo://repo/{owner}/{repo}/labels + /label/{id} (singular repo, EmbeddedListCap+Bounded, output-bounding). Notes exclusive/is_archived out of scope (SDK v3 doesn't model). Ready to base OpenSpec change on; change NOT created per instruction.","external_ref":"codeberg-190","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-3ph","title":"OpenSpec: wiki tools via direct API + wiki page resource template","description":"Codeberg issue #32 (goern/forgejo-mcp). Author an OpenSpec change proposing wiki support implemented via direct Forgejo REST API calls (pkg/forgejo/rawhttp.go DoJSON helpers) rather than forgejo-sdk v3 (which has NO wiki methods — current operation/wiki/wiki.go behind //go:build wiki tag does not compile). Scope: 6 wiki tools (list/get/get_revisions/create/update/delete), a forgejo://repo/{owner}/{repo}/wiki/{pageName} resource template, output-bounding compliance, discovery surfacing (README+AGENTS.md), and a showboat demo. This bead covers authoring the spec only.","status":"closed","priority":2,"issue_type":"feature","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-31T12:49:49Z","created_by":"Christoph Görn","updated_at":"2026-05-31T12:54:17Z","started_at":"2026-05-31T12:49:53Z","closed_at":"2026-05-31T12:54:17Z","close_reason":"OpenSpec change add-wiki-support authored, validated (--strict), pushed as PR #176; minutes on Codeberg #32. Implementation tracked by the spec tasks.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-pkz","title":"demos: mcp-resource-templates walkthrough for forgejo:// URIs","description":"PR #172 shipped 7 resource templates on the forgejo:// scheme (owner, repo, commit, commit-status, issue, comment, pr), but no entry in demos/ covers them. Other features in demos/ all have one-file-per-feature walkthroughs (see demos/README.md). This is the gap that aligns with the deferred OpenSpec task 1.11 (manual client verification).\n\nDeliverable: demos/mcp-resource-templates.md following the structure in demos/README.md:\n1. Background / what resource templates are and why (instance-portable forgejo:// URIs, additive to tools, JSON + markdown sidecar)\n2. Setup (export FORGEJO_URL, FORGEJO_ACCESS_TOKEN, make build)\n3. Walkthrough — one shell block per URI template (7 total) with REAL output captured against codeberg.org/goern/forgejo-mcp. Note: --cli does NOT support resources, so use stdio JSON-RPC: echo a resources/list or resources/read request, pipe to ./forgejo-mcp -t stdio -url $FORGEJO_URL -token $FORGEJO_ACCESS_TOKEN, parse with jq/python.\n4. End-to-end / autonomous agent workflow — how an MCP client uses templates instead of tools (e.g. fetch repo metadata + recent commits via templates, fall back to list_repo_commits for pagination).\n\nConstraints:\n- Must use real codeberg.org payloads, not fabricated.\n- Must show both JSON and markdown sidecar where applicable (commit/issue/pr/comment).\n- Must document the EmbeddedListCap=30 truncation sentinel + comments_list_tool escape hatch.\n- Keep payloads excerpted where huge (use jq/python to slice).\n- Follow demos/bounded-responses.md style for tone.\n\nRelated: PR #172 (forgejo-mcp-13x), follow-ups forgejo-mcp-7ra (subscribe) and forgejo-mcp-7de (cap telemetry). Closes part of deferred OpenSpec task 1.11.","notes":"PR #173 opened — https://codeberg.org/goern/forgejo-mcp/pulls/173. Branch: demo-resource-templates. Commit: 945b54b. Bead stays in_progress until PR merges. Bead closes at merge time per workflow-issue-pr-create-bead. Security: gitleaks clean, no token leaks, only commit SHAs in 40+ char matches.","status":"closed","priority":2,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-05-28T15:59:40Z","created_by":"Christoph Görn","updated_at":"2026-05-28T22:29:09Z","started_at":"2026-05-28T15:59:54Z","closed_at":"2026-05-28T22:29:09Z","close_reason":"Merged via PR #173 (commit 12613c1a). Demo file demos/mcp-resource-templates.md shipped on main. Gitleaks clean, CI green, op1st-gitops PaC pipelines all success.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-ylb","title":"Address all PR #172 code review findings (fix-pull_172)","description":"Umbrella bead tracking all 13 fix beads created from the automated code review on https://codeberg.org/goern/forgejo-mcp/pulls/172#issuecomment-16022165. Closes when all child fix beads are closed. Two clusters dominate the findings: (1) truncation sentinel never fires because 4 SDK call sites pass empty options and Forgejo's default PageSize=30 == EmbeddedListCap; (2) parse errors in 4 sibling handlers wrap with fmt.Errorf instead of resource.MapForgejoError, losing -32602. Plus errors.go substring-classification, owner fallback, parse.go empty-segment handling, and a typo.","notes":"Children (13 beads):\n\nHigh-impact (P2, 5 beads):\n- forgejo-mcp-cmw — Fix double-wrapped ResourceError in resources_commit.go:51\n- forgejo-mcp-u3y — Pass PageSize \u003e EmbeddedListCap to ListIssueComments (issue/resources.go:93)\n- forgejo-mcp-ghr — Pass PageSize \u003e EmbeddedListCap to ListIssueComments (pull/resources.go:108)\n- forgejo-mcp-5dz — Pass PageSize \u003e EmbeddedListCap to ListPullReviews (pull/resources.go:111)\n- forgejo-mcp-827 — Pass PageSize \u003e EmbeddedListCap to ListStatuses (resources_status.go:73)\n\nMedium-impact (P3, 8 beads):\n- forgejo-mcp-vzz — Map parse error via MapForgejoError (resources_commit.go:39)\n- forgejo-mcp-s2g — Map parse error via MapForgejoError (resources_repo.go:61)\n- forgejo-mcp-g5s — Map parse error via MapForgejoError (resources_status.go:65)\n- forgejo-mcp-iqi — Map parse error via MapForgejoError (resources_owner.go:56)\n- forgejo-mcp-wgs — Replace substring-based HTTP classification (errors.go:26)\n- forgejo-mcp-91j — Fix user→org fallback masking + nil-userErr (resources_owner.go:96)\n- forgejo-mcp-16t — Reject empty/whitespace URI segments (parse.go:220)\n- forgejo-mcp-8ia — Fix CommmentsTruncated typo (pull/resources.go:79)","status":"closed","priority":2,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-05-28T13:48:49Z","created_by":"Christoph Görn","updated_at":"2026-05-28T14:18:53Z","closed_at":"2026-05-28T14:18:53Z","close_reason":"All 13 review findings fixed in commits 683404c..182898a. PR #172 review-fix chain complete.","dependencies":[{"issue_id":"forgejo-mcp-ylb","depends_on_id":"forgejo-mcp-16t","type":"blocks","created_at":"2026-05-28T13:48:54Z","created_by":"Christoph Görn","metadata":"{}"},{"issue_id":"forgejo-mcp-ylb","depends_on_id":"forgejo-mcp-5dz","type":"blocks","created_at":"2026-05-28T13:48:53Z","created_by":"Christoph Görn","metadata":"{}"},{"issue_id":"forgejo-mcp-ylb","depends_on_id":"forgejo-mcp-827","type":"blocks","created_at":"2026-05-28T13:48:53Z","created_by":"Christoph Görn","metadata":"{}"},{"issue_id":"forgejo-mcp-ylb","depends_on_id":"forgejo-mcp-8ia","type":"blocks","created_at":"2026-05-28T13:48:54Z","created_by":"Christoph Görn","metadata":"{}"},{"issue_id":"forgejo-mcp-ylb","depends_on_id":"forgejo-mcp-91j","type":"blocks","created_at":"2026-05-28T13:48:53Z","created_by":"Christoph Görn","metadata":"{}"},{"issue_id":"forgejo-mcp-ylb","depends_on_id":"forgejo-mcp-cmw","type":"blocks","created_at":"2026-05-28T13:48:52Z","created_by":"Christoph Görn","metadata":"{}"},{"issue_id":"forgejo-mcp-ylb","depends_on_id":"forgejo-mcp-g5s","type":"blocks","created_at":"2026-05-28T13:48:53Z","created_by":"Christoph Görn","metadata":"{}"},{"issue_id":"forgejo-mcp-ylb","depends_on_id":"forgejo-mcp-ghr","type":"blocks","created_at":"2026-05-28T13:48:53Z","created_by":"Christoph Görn","metadata":"{}"},{"issue_id":"forgejo-mcp-ylb","depends_on_id":"forgejo-mcp-iqi","type":"blocks","created_at":"2026-05-28T13:48:53Z","created_by":"Christoph Görn","metadata":"{}"},{"issue_id":"forgejo-mcp-ylb","depends_on_id":"forgejo-mcp-s2g","type":"blocks","created_at":"2026-05-28T13:48:53Z","created_by":"Christoph Görn","metadata":"{}"},{"issue_id":"forgejo-mcp-ylb","depends_on_id":"forgejo-mcp-u3y","type":"blocks","created_at":"2026-05-28T13:48:52Z","created_by":"Christoph Görn","metadata":"{}"},{"issue_id":"forgejo-mcp-ylb","depends_on_id":"forgejo-mcp-vzz","type":"blocks","created_at":"2026-05-28T13:48:53Z","created_by":"Christoph Görn","metadata":"{}"},{"issue_id":"forgejo-mcp-ylb","depends_on_id":"forgejo-mcp-wgs","type":"blocks","created_at":"2026-05-28T13:48:53Z","created_by":"Christoph Görn","metadata":"{}"}],"dependency_count":13,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-5dz","title":"Pass PageSize \u003e EmbeddedListCap to ListPullReviews in operation/pull/resources.go:111","description":"ListPullReviews with empty options — reviews capped at server default 30 = EmbeddedListCap so reviews_truncated/reviews_list_tool sentinel never fires. ReviewCount: len(reviews) also wrong (first-page count, not total). Review: https://codeberg.org/goern/forgejo-mcp/pulls/172#issuecomment-16022165 (conf 92).","notes":"Fix: at operation/pull/resources.go:111, pass forgejo_sdk.ListPullReviewsOptions{ListOptions: forgejo_sdk.ListOptions{PageSize: resource.EmbeddedListCap + 1}}. For accurate ReviewCount when truncated, either omit the field when truncated or paginate fully (probably out of scope for v1; document the caveat).","status":"closed","priority":2,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-28T13:46:42Z","created_by":"Christoph Görn","updated_at":"2026-05-28T14:18:53Z","started_at":"2026-05-28T14:17:15Z","closed_at":"2026-05-28T14:18:53Z","close_reason":"All 13 review findings fixed in commits 683404c..182898a. PR #172 review-fix chain complete.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-827","title":"Pass PageSize \u003e EmbeddedListCap to ListStatuses in operation/repo/resources_status.go:73","description":"ListStatuses with empty ListStatusesOption{} — server pages at default 30 = EmbeddedListCap so the \u003ecap truncation check never fires for SHAs with many status contexts. AGENTS.md output-bounding rule violated. Review: https://codeberg.org/goern/forgejo-mcp/pulls/172#issuecomment-16022165 (conf 90).","notes":"Fix: at operation/repo/resources_status.go:73, pass forgejo_sdk.ListStatusesOption{ListOptions: forgejo_sdk.ListOptions{PageSize: resource.EmbeddedListCap + 1}}.","status":"closed","priority":2,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-28T13:46:42Z","created_by":"Christoph Görn","updated_at":"2026-05-28T14:14:17Z","started_at":"2026-05-28T14:11:59Z","closed_at":"2026-05-28T14:14:17Z","close_reason":"Fixed in ee1217d. PageSize=cap+1; truncation sentinel surfaces correctly.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-cmw","title":"Fix double-wrapped ResourceError in operation/repo/resources_commit.go:51","description":"commitResourceHandler does 'return nil, fmt.Errorf(\"%w\", mappedErr)' where mappedErr is *resource.ResourceError. Downstream code using err.(*resource.ResourceError) gets (nil, false) — so -32603 internal error surfaces instead of the intended -32003/-32002 for commit URIs only. Every other handler returns the ResourceError directly. Review: https://codeberg.org/goern/forgejo-mcp/pulls/172#issuecomment-16022165 (conf 92).","notes":"Fix: at operation/repo/resources_commit.go:50-51, replace\n mappedErr := resource.MapForgejoError(uri, fmt.Errorf(\"%d %s\", resp.StatusCode, err.Error()))\n return nil, fmt.Errorf(\"%w\", mappedErr)\nwith\n return nil, resource.MapForgejoError(uri, fmt.Errorf(\"%d %s\", resp.StatusCode, err.Error()))","status":"closed","priority":2,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-28T13:46:42Z","created_by":"Christoph Görn","updated_at":"2026-05-28T13:57:03Z","started_at":"2026-05-28T13:55:39Z","closed_at":"2026-05-28T13:57:03Z","close_reason":"Fixed in f8d661e. ResourceError now returned directly; type-assertion surfaces correct JSON-RPC code.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-ghr","title":"Pass PageSize \u003e EmbeddedListCap to ListIssueComments in operation/pull/resources.go:108","description":"Same defect as issue handler — PR comments ListIssueComments uses empty options so server caps at default 30 = EmbeddedListCap, sentinel never fires. Review: https://codeberg.org/goern/forgejo-mcp/pulls/172#issuecomment-16022165 (conf 92).","notes":"Fix: at operation/pull/resources.go:108, pass forgejo_sdk.ListIssueCommentOptions{ListOptions: forgejo_sdk.ListOptions{PageSize: resource.EmbeddedListCap + 1}}.","status":"closed","priority":2,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-28T13:46:42Z","created_by":"Christoph Görn","updated_at":"2026-05-28T14:17:15Z","started_at":"2026-05-28T14:15:49Z","closed_at":"2026-05-28T14:17:15Z","close_reason":"Fixed in 9e5b930.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-u3y","title":"Pass PageSize \u003e EmbeddedListCap to ListIssueComments in operation/issue/resources.go:93","description":"ListIssueComments called with default ListIssueCommentOptions{}. Forgejo's default PageSize=30 == EmbeddedListCap, so the \u003ecap truncation check NEVER fires. Issues with \u003e30 comments silently lose the recent_comments_truncated/list_tool sentinel. AGENTS.md output-bounding rule violated. Review: https://codeberg.org/goern/forgejo-mcp/pulls/172#issuecomment-16022165 (conf 92).","notes":"Fix: at operation/issue/resources.go:93, pass an explicit PageSize:\n comments, _, _ := client.ListIssueComments(params.Owner, params.Repo, params.Index,\n forgejo_sdk.ListIssueCommentOptions{ListOptions: forgejo_sdk.ListOptions{PageSize: resource.EmbeddedListCap + 1}})\nVerify via a new test that 31 mock comments produce truncated=true.","status":"closed","priority":2,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-28T13:46:42Z","created_by":"Christoph Görn","updated_at":"2026-05-28T14:15:49Z","started_at":"2026-05-28T14:14:17Z","closed_at":"2026-05-28T14:15:49Z","close_reason":"Fixed in 321b1a0.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-13x","title":"Implement all 7 slices of mcp-resource-templates (resource framework + 7 entity resources + docs)","description":"Implement the first two slices of the mcp-resource-templates OpenSpec change merged via PR #148. Slice 1 (mcp-resources-core): server.WithResourceCapabilities(false,false), operation/resource/ package (parse, register, bound, errors helpers), RegisterCoreResources stub wired in operation/operation.go, plus unit tests. Slice 2 (mcp-resource-commit): operation/repository/resources_commit.go with RegisterCommitResource, forgejo://repo/{owner}/{repo}/commit/{sha} template, JSON + markdown sidecar handler, unit tests, wiring, README row. Verifier: go build ./... \u0026\u0026 go test ./... . Driven via team:dev-loop.","notes":"Originally scoped to slices 1+2. Team:dev-loop completed all 7 slices in one session. PR #172 opened: https://codeberg.org/goern/forgejo-mcp/pulls/172. Awaiting CI + review. Follow-ups: forgejo-mcp-7ra (subscribe=true), forgejo-mcp-7de (EmbeddedListCap).","status":"closed","priority":2,"issue_type":"feature","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-28T12:15:54Z","created_by":"Christoph Görn","updated_at":"2026-05-28T15:49:26Z","started_at":"2026-05-28T12:15:58Z","closed_at":"2026-05-28T15:49:26Z","close_reason":"PR #172 merged to main (commit 872d4c5). 7 slices shipped. Follow-ups tracked in 7ra/7de. Manual client verification (task 1.11) remains post-merge work.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-1tc","title":"Fix openspec spec/release-tools-image format (missing Purpose+Requirements headers)","description":"The archived spec at openspec/specs/release-tools-image/spec.md (introduced in bd92d21) starts with '## ADDED Requirements' (the change-delta format), but openspec validate --strict requires top-level specs to have '## Purpose' and '## Requirements' headers. This breaks the Tekton openspec-validate gate on any PR that merges main, including PR #148. Fix: rewrite spec headers to conventional spec format. Land via PR #148 to unblock it.","status":"closed","priority":2,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-28T12:02:16Z","created_by":"Christoph Görn","updated_at":"2026-05-28T12:03:06Z","started_at":"2026-05-28T12:02:19Z","closed_at":"2026-05-28T12:03:06Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-het","title":"Dashboard: focus mode highlights node + neighbours in subway map","description":"When user clicks an issue card in the registry, highlight that bead node plus its transitive dependencies and dependants in the dependency graph. Dim unrelated nodes/edges. Clicking the same card again clears focus.","acceptance_criteria":"Clicking an issue card highlights the matching subway-map station and its full upstream + downstream chain; unrelated stations and edges dim; clicking the focused card again or any non-station SVG area clears focus.","status":"closed","priority":2,"issue_type":"feature","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-26T13:39:15Z","created_by":"Christoph Görn","updated_at":"2026-05-26T13:42:48Z","started_at":"2026-05-26T13:39:18Z","closed_at":"2026-05-26T13:42:48Z","close_reason":"focus-mode shipped in 8fc1e75 — card click dims unrelated dep-graph nodes, highlights full ancestor+descendant chain; SVG background click clears focus","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-3a9","title":"Dashboard: subway-map dependency graph","description":"Replace the flat text edge list in beads-dashboard.html with a layered SVG subway-map view of issue dependencies. Goals: visualise upstream→downstream chains, colour 'lines' per source issue, click station to jump to that issue card.","acceptance_criteria":"SVG renders all dep edges with no overlapping stations; click on a station selects and scrolls to the matching issue; nodes coloured by status (closed/in_progress/open); responsive layout (page still usable at 800px width).","status":"closed","priority":2,"issue_type":"feature","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-25T23:08:05Z","created_by":"Christoph Görn","updated_at":"2026-05-25T23:10:21Z","started_at":"2026-05-25T23:08:09Z","closed_at":"2026-05-25T23:10:21Z","close_reason":"subway-map dep view shipped in beads-dashboard.html — layered SVG with orthogonal routing, status-coloured stations, click-to-jump.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-wqm","title":"Rewrite .tekton/tasks/ to use release-tools image (drop runtime installs)","description":"All 5 tasks in .tekton/tasks/ still install tools at runtime (microdnf, curl, go install, npx -y, npm install -g). With govulncheck and openspec now baked into the release-tools image, all runtime installs can be removed. Tasks to rewrite: goreleaser-release (syft+goreleaser go install), cosign-sign-release (microdnf jq+curl in upload step), mcpb-pack (npx -y mcpb + apt-get jq), go-ci (govulncheck go install), openspec-validate (npm install -g openspec). Each task should use RELEASE_TOOLS_IMAGE param defaulting to codeberg.org/operate-first/release-tools:latest. External PR: https://codeberg.org/goern/forgejo-mcp/pulls/157","status":"closed","priority":2,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-25T21:21:01Z","created_by":"Christoph Görn","updated_at":"2026-05-25T21:24:08Z","started_at":"2026-05-25T21:21:04Z","closed_at":"2026-05-25T21:24:08Z","close_reason":"All 5 tasks rewritten in commit 0dcb2e1. No runtime installs remain. Minutes posted to PR #157.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-6t6","title":"Fix code review issues from PR #157 automated review","description":"Address all 11 inline review comments from the automated multi-agent review on PR #157 (release-tools image + Tekton pipelines). Comments span: (1) build-image IMAGE_DIGEST extraction broken, (2) syft-scan-image tries registry pull for unpushed image, (3) push-image-by-digest TOCTOU concern, (4) Containerfile floating base tag, (5) syft installer from main branch, (6) cosign no integrity verify, (7) npm install -g re-resolves transitive deps, (8-9) cosign-sign + cosign-attach-sbom unverified downloads, (10) SKIP_SIGN ungated, (11) mutable cosign.pub URL in README. External PR: https://codeberg.org/goern/forgejo-mcp/pulls/157","status":"closed","priority":2,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-25T21:04:41Z","created_by":"Christoph Görn","updated_at":"2026-05-25T21:12:09Z","started_at":"2026-05-25T21:04:45Z","closed_at":"2026-05-25T21:12:09Z","close_reason":"All 11 review findings fixed in commit d59b910, pushed to feat/release-tools-pipelines, minutes posted to PR #157","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-46j","title":"Publish SLSA provenance attestation for release-tools image via Tekton Chains","description":"Origin: L5 from release-tools-image adversarial review. Tekton Chains is deployed in op1st-pipelines (per ADR docs/design/release-pipeline-migration.md and op1st-emea-b4mad manifests/applications/op1st-pipelines/tekton-chains.yaml) but the release-tools publish pipeline does not consume its in-toto SLSA v1.0 attestations. Cosign signature alone attests signer-holds-key, NOT build-provenance binding image digest → PipelineRun → git commit → builder identity. With key-split (L4) still pending, the provenance gap is exploitable. Fix: enable Chains annotations on the publish PipelineRun (chains.tekton.dev/transparency-upload: true), have Chains produce SLSA v1.0 provenance, attach as cosign attestation, document 'cosign verify-attestation --type slsaprovenance' in README.","notes":"PR #165 opened: https://codeberg.org/goern/forgejo-mcp/pulls/165. Changes: chains.tekton.dev/transparency-upload annotation, IMAGE_URL+IMAGE_DIGEST pipeline results, push-image-by-digest IMAGE_URL result, README verify-attestation section, ADR addendum.","status":"closed","priority":2,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-25T13:52:26Z","created_by":"Christoph Görn","updated_at":"2026-05-26T13:09:04Z","started_at":"2026-05-26T13:04:36Z","closed_at":"2026-05-26T13:09:04Z","close_reason":"PR #165 merged — Tekton Chains SLSA provenance enabled for release-tools image","dependencies":[{"issue_id":"forgejo-mcp-46j","depends_on_id":"forgejo-mcp-1b4","type":"blocks","created_at":"2026-05-25T13:52:44Z","created_by":"Christoph Görn","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-a2y","title":"Remove in-repo secrets/ + use op1st-emea-b4mad as normative source for cosign public key","description":"Delete secrets/cosign.pub, secrets/cosign-signing-key.enc.yaml, secrets/.gitkeep (and the dir). Cosign-signing-key public key normative source moves to https://codeberg.org/operate-first/op1st-emea-b4mad/raw/.../cosign-signing-key.pub, matching the Tekton release pipeline's signing key in op1st-pipelines namespace. Note: legacy releases signed via Forgejo Actions (Codeberg Actions COSIGN_PRIVATE_KEY) used a different keypair (now-deleted secrets/cosign.pub) — historical verification still possible via git history of commit 791ef6d.","acceptance_criteria":"secrets/ directory removed from main; .gitignore rules for secrets/ cleaned up; README Verifying Releases chapter points at op1st-emea-b4mad URL; ADR + runbook references updated; legacy-key note explains historical signature verification","notes":"PR opened: https://codeberg.org/goern/forgejo-mcp/pulls/152 (branch chore/remove-stale-secrets). Stale secrets/ + scripts/cosign-keygen.sh removed; README + ADR + runbook now point at op1st-emea-b4mad/.../cosign-signing-key.pub (commit 8a3c55e5).","status":"closed","priority":2,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-25T11:33:54Z","created_by":"Christoph Görn","updated_at":"2026-05-25T11:38:24Z","started_at":"2026-05-25T11:34:01Z","closed_at":"2026-05-25T11:38:24Z","close_reason":"PR #152 merged. secrets/ + scripts/cosign-keygen.sh removed; README + ADR + runbook now point at op1st-emea-b4mad/.../cosign-signing-key.pub as normative source.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-n85","title":"Disable Forgejo Actions release workflow auto-trigger (soft cutover)","description":"Switch .forgejo/workflows/release.yml trigger from 'push tags v*' to 'workflow_dispatch' only. Stops auto-firing on tag push while preserving the file as a manual fallback if the op1st Tekton release pipeline (added in PR #150) fails. Full file deletion deferred to forgejo-mcp-gdz once 2 successful Tekton releases prove the cutover.","acceptance_criteria":".forgejo/workflows/release.yml on=workflow_dispatch only; ADR addendum noting soft-disable date; PR opened","notes":"PR opened: https://codeberg.org/goern/forgejo-mcp/pulls/151 (branch chore/disable-forgejo-release). Trigger switched to workflow_dispatch only; ADR moved to Accepted (soft-cutover phase). Close on merge.","status":"closed","priority":2,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-25T11:29:02Z","created_by":"Christoph Görn","updated_at":"2026-05-25T11:31:15Z","started_at":"2026-05-25T11:29:06Z","closed_at":"2026-05-25T11:31:15Z","close_reason":"PR #151 merged. Trigger now workflow_dispatch only; Tekton sole auto-firing release path; Forgejo workflow preserved as manual fallback.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-d4b","title":"Migrate Forgejo release workflow to op1st Tekton pipeline","description":"Port .forgejo/workflows/release.yml to .tekton/ as a PipelinesAsCode release pipeline triggered on tag push v*. Cover all current features: GoReleaser w/ syft SBOMs, smoke-test of linux/amd64 binary, cosign sign-blob of checksums.txt + upload, .mcpb pack per platform (linux/darwin × amd64/arm64) + upload to Codeberg release. Run in parallel with existing Forgejo Actions release; cutover deferred. Add ADR + migration notes.","design":"PipelinesAsCode on-event=push with on-target-branch=refs/tags/v* (matches forgejo-mcp-33k cross-repo spike pattern only if PaC supports tag-push; falls back to tag-push directly). Three new tasks mirroring go-ci.yaml structure. Secrets: RELEASE_TOKEN, COSIGN_PRIVATE_KEY/PASSWORD assumed present in op1st-pipelines namespace. Existing release.yml stays untouched.","acceptance_criteria":"release pipeline yaml in .tekton/ triggered by tag push v*; reusable tasks for goreleaser, cosign-sign-blob, mcpb-pack defined under .tekton/tasks/; docs/design/release-pipeline-migration.md ADR explaining parallel-run + cutover criteria; PR opened on Codeberg","notes":"PR #150: https://codeberg.org/goern/forgejo-mcp/pulls/150. Secret validation done 2026-05-25: op1st-release-token + cosign-signing-key both confirmed in op1st-pipelines (shape + scope + cosign.pub match). Pipeline ready; next v* tag triggers parallel Tekton run. Close after 2 successful Tekton releases satisfy ADR cutover criteria.","status":"closed","priority":2,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-25T09:10:22Z","created_by":"Christoph Görn","updated_at":"2026-05-25T11:28:00Z","started_at":"2026-05-25T09:10:26Z","closed_at":"2026-05-25T11:28:00Z","close_reason":"PR #150 merged (commit 6c824c9). All acceptance criteria met: .tekton release PipelineRun + 3 reusable Tasks + ADR + runbook + README verification chapter all in main. Parallel-run begins on next v* tag. Cutover decision tracked in forgejo-mcp-gdz.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-dhd","title":"ci: gitleaks allowlist for placeholder tokens in demo docs","description":"gitleaks 'generic-api-key' rule flags 'Authorization: token invalid_token' on demos/multi-tenant-http.md:109 (commit bd08d6147 on fork branch byteflavour/stateless-token, incoming PR). The token is intentional test data — request 4 in the multi-tenant HTTP demo shows what an invalid token does. Add a path+regex-scoped allowlist so demo docs can use placeholder tokens (invalid_token, changeme, etc.) without tripping the scanner, while real generic-api-key detection stays intact elsewhere.","acceptance_criteria":"gitleaks scan over demos/multi-tenant-http.md returns 0 leaks. Real secret patterns elsewhere in repo still flagged. Allowlist scope limited to demos/*.md.","notes":"PR opened: https://codeberg.org/goern/forgejo-mcp/pulls/147 (mergeable). Per-rule allowlist on curl-auth-header scoped to demos/*.md + placeholder regexes. Local gitleaks v8.30.1 negative test confirms real github-pat still flagged.","status":"closed","priority":2,"issue_type":"bug","owner":"goern@b4mad.net","created_at":"2026-05-25T07:21:45Z","created_by":"Christoph Görn","updated_at":"2026-05-25T07:46:29Z","closed_at":"2026-05-25T07:46:29Z","close_reason":"PR #147 merged 2026-05-25T09:45:33+02:00; worktree + local branch ci/gitleaks-allowlist-demos cleaned up","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-phn","title":"Set Codeberg Actions secrets COSIGN_PRIVATE_KEY and COSIGN_PASSWORD","description":"Mirror cosign signing material from SOPS-encrypted secrets/cosign-signing-key.enc.yaml into Codeberg Actions repo secrets so the release pipeline can sign artifacts. Source-of-truth stays in SOPS; this is one-way sync to CI.","notes":"Decrypt with sops, extract via yq, PUT to Forgejo API /repos/goern/forgejo-mcp/actions/secrets/{name}. Never write plaintext to disk.","status":"closed","priority":2,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-24T11:09:58Z","created_by":"Christoph Görn","updated_at":"2026-05-24T11:11:01Z","started_at":"2026-05-24T11:10:08Z","closed_at":"2026-05-24T11:11:01Z","close_reason":"Both Codeberg Actions secrets created (HTTP 201). Verified via API list. Source-of-truth remains secrets/cosign-signing-key.enc.yaml (SOPS).","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-p1p","title":"ci: bump x/net + jsonparser to clear govulncheck advisories (run #151)","description":"Forgejo Actions ci.yml run #151 (https://codeberg.org/goern/forgejo-mcp/actions/runs/151) flagged govulncheck findings. Local scan (govulncheck v1.3.0) shows 7 findings: 0 reachable, 2 package-level (x/net/idna GO-2026-5026, buger/jsonparser GO-2026-4514), 5 module-level (x/net/html GO-2026-5025..5030). Default govulncheck exits 0 on non-reachable findings, so the CI failure may be from a stricter flag/version on the runner — fix in this PR clears them regardless. Bump x/net to v0.55.0 (clears 6), add direct require for buger/jsonparser v1.1.2 to override transitive (clears 1).","acceptance_criteria":"govulncheck ./... locally returns 0 findings at all tiers OR only retains findings not present in advisories. Next ci.yml run on a fresh PR passes the govulncheck step.","notes":"PR opened: https://codeberg.org/goern/forgejo-mcp/pulls/145 (mergeable). Local govulncheck verified clean at all tiers.","status":"closed","priority":2,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-24T11:06:20Z","created_by":"Christoph Görn","updated_at":"2026-05-25T22:28:25Z","started_at":"2026-05-24T11:06:27Z","closed_at":"2026-05-25T22:28:25Z","close_reason":"PR #145 merged 2026-05-25 (612da9f). govulncheck ./... on main: no vulnerabilities. All 7 advisories cleared.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-1l5","title":"RFC: introduce MCP resource templates for core entities (owner, repo, commit, issue, pr, comment, status)","description":"## Why\n\nforgejo-mcp is currently tool-only. No MCP resources registered in operation/operation.go. Core Forgejo entities (owner, repo, commit, issue, pr, comment, status) are noun-like, addressable, and often immutable or stable — natural fit for MCP resource templates. Exposing them as resources unlocks:\n\n- URI-based references the LLM can auto-resolve (e.g. PR diff mentions a sha → fetch commit resource)\n- Cacheable, content-addressable lookup (commits especially)\n- Cleaner composition: a PR resource can link to commit + comment resources instead of forcing tool-call ceremony\n\nDoing this piecemeal (one entity at a time) creates an inconsistent server. A coherent design pass covering all seven entities at once avoids that.\n\n## What\n\nProduce an OpenSpec proposal that designs MCP resource templates for:\n\n- owner (user or org): `forgejo://owner/{name}`\n- repo: `forgejo://repo/{owner}/{repo}`\n- commit: `forgejo://repo/{owner}/{repo}/commit/{sha}`\n- issue: `forgejo://repo/{owner}/{repo}/issue/{index}`\n- pr: `forgejo://repo/{owner}/{repo}/pr/{index}`\n- comment: `forgejo://repo/{owner}/{repo}/{issue|pr}/{index}/comment/{id}`\n- status: `forgejo://repo/{owner}/{repo}/commit/{sha}/status` (combined) + `.../statuses` (list)\n\nURI scheme above is illustrative — proposal must justify final scheme.\n\n## Acceptance criteria\n\n- OpenSpec change proposal created via /openspec-propose covering all 7 entity templates\n- Proposal includes: URI scheme rationale, capability registration changes to operation/operation.go, handler pattern, MIME type per resource, relationship to existing tools (coexist or replace?), output bounding strategy (AGENTS.md docs/design/output-bounding.md), client compatibility matrix, migration/rollout plan\n- design.md addresses: listable vs template-only per entity, subscription semantics (do we support resource updates?), error handling for missing/private entities, auth scope\n- Specs cover behavior for each of the 7 entities\n- Tasks broken down per-entity so implementation can land incrementally even though design is unified\n\n## Out of scope\n\n- Implementation (this bead = design only)\n- Wiki/projects resources (blocked upstream per docs/plans/)\n- Webhook/event resources\n\n## Notes\n\nDriven by session discussion 2026-05-24 around replacing curl-based commit status fetches with proper MCP surface. Decision: design resources holistically rather than one-off per entity.","notes":"OpenSpec change created at openspec/changes/mcp-resource-templates/ on branch worktree-rfc-resource-templates. 4/4 artifacts pass strict validation (proposal, design, 8 spec files, tasks). 13 design decisions documented. 7-slice rollout plan in tasks.md. Ready for /opsx:apply to start implementation.","status":"closed","priority":2,"issue_type":"feature","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-24T07:35:50Z","created_by":"Christoph Görn","updated_at":"2026-05-25T08:04:39Z","started_at":"2026-05-25T07:30:03Z","closed_at":"2026-05-25T08:04:39Z","close_reason":"OpenSpec proposal complete: proposal.md, design.md, 8 spec files, tasks.md all pass strict validation. Branch: worktree-rfc-resource-templates.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-e9i","title":"CI: investigate Forgejo Actions ci.yml failure on PR #143","description":"First run of .forgejo/workflows/ci.yml (run #147, SHA d711f32) failed at 3m43s. Merged anyway. No per-step detail available via Codeberg API. Need to: (1) open https://codeberg.org/goern/forgejo-mcp/actions/runs/147 in browser, identify which step failed; (2) fix root cause (likely candidates: golangci-lint-action@v6 incompatibility on Codeberg runner, cache mount permissions, missing toolchain, setup-go@v6 quirk); (3) verify on follow-up PR.","acceptance_criteria":"ci.yml run on a fresh PR completes with all steps green (lint warn-only acceptable). Document root cause in bd notes.","status":"closed","priority":2,"issue_type":"bug","owner":"goern@b4mad.net","created_at":"2026-05-24T07:35:45Z","created_by":"Christoph Görn","updated_at":"2026-05-26T09:18:37Z","closed_at":"2026-05-26T09:18:37Z","close_reason":"ci.yml deleted — Forgejo Actions CI superseded by Tekton PaC pipeline. Failure moot.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-51l","title":"CI: harden release pipeline (SBOM, cosign, smoke-test)","description":"release.yml ships .mcpb per platform but never verifies binary boots. Add: syft SBOM upload as release asset, cosign sign binaries+containers (keyless via OIDC if available, else key from secret), smoke-test ./forgejo-mcp --version per arch before .mcpb upload.","acceptance_criteria":"SBOM uploaded per release, signatures verifiable, smoke-test runs on linux/amd64 at minimum","notes":"PR opened: https://codeberg.org/goern/forgejo-mcp/pulls/144 (mergeable). Branch ci/step3-release-hardening. 3 commits:\n1. .goreleaser.yml: checksums + per-archive CycloneDX SBOMs via syft\n2. release.yml: syft + cosign install, smoke-test linux/amd64 binary, conditional cosign sign-blob on checksums.txt\n3. scripts/cosign-keygen.sh: SOPS-encrypted k8s Secret keypair generator (tmpfs + shred + no-echo password)\n\nSigning gated on COSIGN_PRIVATE_KEY + COSIGN_PASSWORD repo secrets — releases keep working until secret provisioned. Activation steps in PR body.\n\nLocal verification:\n- goreleaser check → 1 configuration file(s) validated\n- YAML lint → OK\n- bash -n on script → OK (no shellcheck available locally)\n\nUntested in PR (require tagged release): SBOM upload path, smoke-test on real built binary, cosign sign flow.","status":"closed","priority":2,"issue_type":"feature","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-24T07:06:38Z","created_by":"Christoph Görn","updated_at":"2026-05-24T10:59:53Z","started_at":"2026-05-24T10:30:14Z","closed_at":"2026-05-24T10:59:53Z","close_reason":"Merged via PR #144 (commit b2c67f8). Activation pending: run scripts/cosign-keygen.sh, add COSIGN_PRIVATE_KEY + COSIGN_PASSWORD to Codeberg Actions secrets, then signing kicks in on next v* tag.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-9n2","title":"CI: add Forgejo Actions PR workflow with Go cache","description":"Tekton has no cross-run Go cache (PVC ephemeral). Add .forgejo/workflows/ci.yml mirroring go-ci gates on codeberg-small runner using actions/setup-go cache. Run parallel to Tekton 2 weeks, then decide canonical.","acceptance_criteria":"ci.yml runs on pull_request + push to main, uses setup-go cache, runs build/test/lint/race/govulncheck, completes \u003c5min on cache hit","notes":"PR opened: https://codeberg.org/goern/forgejo-mcp/pulls/143 (mergeable). Will close on merge. First Forgejo Actions run will be cold-cache; verify \u003c5min on second run.","status":"closed","priority":2,"issue_type":"feature","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-24T07:06:34Z","created_by":"Christoph Görn","updated_at":"2026-05-24T07:35:56Z","started_at":"2026-05-24T07:25:05Z","closed_at":"2026-05-24T07:35:56Z","close_reason":"Merged via PR #143 (rebase, force_merge — run #147 failed, fix tracked in forgejo-mcp-e9i).","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-33k","title":"C5 spike: verify cross-repo workflow_call on Codeberg Forgejo v11.x","description":"Battle-test of forgejo-action-code-review deferred this spike. Spike scaffolding under openspec/changes/forgejo-action-code-review/spikes/c5-cross-repo-workflow-call/. Library + consumer repos already exist on Codeberg (goern/c5-spike-lib, goern/c5-spike-consumer). Remaining steps: (1) create tag v0.0.1 on c5-spike-lib main, (2) set repo secret SPIKE_SECRET on both repos, (3) push trigger commit to c5-spike-consumer main, (4) observe whether cross-repo uses: resolves, secret propagates, event context shape. Result drives design.md D9: keep Path B as recommended, or demote to experimental.","status":"open","priority":2,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-05-13T06:33:23Z","created_by":"Christoph Görn","updated_at":"2026-05-24T06:02:27Z","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-673","title":"Implement forgejo-action-code-review workflow","description":"OpenSpec change forgejo-action-code-review has spec deltas (8 capability requirements, PR specs/action-code-review/spec.md) but no implementation. The workflow file .forgejo/workflows/claude-code-review.yml does not exist. Need to ship the reusable Forgejo Actions workflow that runs Claude Code with forgejo-mcp on PR events, installs CC, registers forgejo-mcp as MCP server, runs /code-review skill in -p mode, and posts findings via create_pull_review. Depends on forgejo-code-review-skill (delivered). See openspec/changes/forgejo-action-code-review/ for proposal + specs.","status":"open","priority":2,"issue_type":"feature","owner":"goern@b4mad.net","created_at":"2026-05-12T13:37:41Z","created_by":"Christoph Görn","updated_at":"2026-05-12T13:37:41Z","dependencies":[{"issue_id":"forgejo-mcp-673","depends_on_id":"forgejo-mcp-33k","type":"blocks","created_at":"2026-05-13T06:33:31Z","created_by":"Christoph Görn","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-fdx","title":"Migrate openspec validate from Forgejo Actions to op1st Tekton","description":"Pivot PR 132: drop .forgejo/workflows/openspec.yml, add Tekton PipelineRuns for openspec validate using op1st-pipelines (PaC). Path-gated via CEL on openspec/** and .tekton/*openspec* changes. Same trigger semantics: push to main + PR open/sync.","acceptance_criteria":"- .tekton/tasks/openspec-validate.yaml runs openspec@1.3.1 validate --all --strict --no-interactive\n- .tekton/on-pull-request-openspec.yaml + on-push-to-main-openspec.yaml gate on path changes via CEL\n- .forgejo/workflows/openspec.yml deleted\n- PR 132 retitled to reflect Tekton migration","status":"closed","priority":2,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-05-12T07:46:04Z","created_by":"Christoph Görn","updated_at":"2026-05-12T07:48:35Z","closed_at":"2026-05-12T07:48:35Z","close_reason":"Landed in PR 132 commit fbd1203 on feat/openspec-workflow. on-pull-request-openspec PipelineRun green (24s). Old .forgejo/workflows/openspec.yml deleted.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-43k","title":"Replace .forgejo/workflows/go.yml with op1st Tekton CI","description":"Codeberg Forgejo runners enforce strict job time limits. Move CI to op1st-pipelines (Pipelines-as-Code on OpenShift). Run go build + go test on every push to main and every PR change. Follow patterns from goern/epaper-service and feeldata/feeldata.app.","acceptance_criteria":"- .tekton/repository.yaml registers repo with op1st-pipelines\n- .tekton/on-push-to-main.yaml triggers go build + go test on push to main\n- .tekton/on-pull-request.yaml triggers go build + go test on PR open/sync\n- Custom go-ci task uses docker.io/library/golang:1.25\n- PaC secrets reuse codeberg-runner-openshift-pac + codeberg-org-op1st-pipelines\n- .forgejo/workflows/go.yml deleted","notes":"Tracked on Codeberg as goern/forgejo-mcp#133 (https://codeberg.org/goern/forgejo-mcp/issues/133). Implementation in commit ae35a30. Remaining: Repository CR apply in op1st-pipelines namespace (cluster-side, out-of-band).","status":"closed","priority":2,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-05-12T06:38:01Z","created_by":"Christoph Görn","updated_at":"2026-05-12T06:40:54Z","closed_at":"2026-05-12T06:39:55Z","close_reason":"Implemented in commit ae35a30. .tekton/ PaC config + go-ci task replace .forgejo/workflows/go.yml.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-zwr","title":"Complete add-bounded-text-responses change for Codeberg #124","description":"Pre-existing scaffold at openspec/changes/add-bounded-text-responses/ has only proposal.md. Codeberg issue #124 (\"Add paged or per-file diff\", reporter fiesh, Kind/Enhancement, Reviewed/Confirmed) is still open.\n\nProposal scope:\n- Add optional `file_path` param to get_pull_request_diff (per-file slicing on `diff --git` boundaries)\n- Add optional `start_line` + `end_line` to get_file_content (1-indexed inclusive line slice)\n- README updates for missing tool entries\n\nRemaining work:\n- Add design.md, specs/bounded-pr-diff/spec.md, specs/bounded-file-content/spec.md, tasks.md\n- Implement in operation/pull/pull.go + operation/repo/file.go\n- Optional pkg/diff/ helper for unified-diff splitting\n- Tests per proposal's Impact section\n\nCurrently fails `openspec validate --all --strict` with 'no deltas found', so it blocks forgejo-mcp-6jc (workflow).\n\nUpstream: https://codeberg.org/goern/forgejo-mcp/issues/124","status":"closed","priority":2,"issue_type":"feature","owner":"goern@b4mad.net","created_at":"2026-05-11T14:32:54Z","created_by":"Christoph Görn","updated_at":"2026-05-24T06:02:27Z","closed_at":"2026-05-11T14:58:24Z","close_reason":"Impl + tests landed in PR #131 (commit dda4ba1). New pkg/diff splitter; get_pull_request_diff gained file_path; get_file_content gained start_line/end_line with clamping. 11 new unit tests; full suite green. README tool table updated incl previously-missing entries.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-6jc","title":"Add Forgejo Actions workflow for openspec validate","description":"Add `.forgejo/workflows/openspec.yml` running `openspec validate --all --strict --no-interactive` on PRs touching `openspec/**` or the workflow file itself. Reference: https://codeberg.org/goern/epaper-service/src/branch/main/.forgejo/workflows/openspec.yml\n\nPinned version: `@fission-ai/openspec@1.3.1` (current local).\n\nBlocked by the 4 spec/change cleanup tasks (forgejo-mcp-6un, forgejo-mcp-a0p, forgejo-mcp-517, forgejo-mcp-cpb) — workflow strict would fail on day 1 otherwise.","status":"closed","priority":2,"issue_type":"feature","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-11T14:18:58Z","created_by":"Christoph Görn","updated_at":"2026-05-11T15:04:35Z","started_at":"2026-05-11T15:03:34Z","closed_at":"2026-05-11T15:04:35Z","close_reason":"Landed in PR #132 (commit 16ca60f). Workflow runs openspec validate --all --strict on openspec/** and workflow file changes, modeled on epaper-service workflow. Pre-existing failures (4 specs/changes) were cleaned up first so gate is green from day one.","dependencies":[{"issue_id":"forgejo-mcp-6jc","depends_on_id":"forgejo-mcp-517","type":"blocks","created_at":"2026-05-11T14:19:03Z","created_by":"Christoph Görn","metadata":"{}"},{"issue_id":"forgejo-mcp-6jc","depends_on_id":"forgejo-mcp-6un","type":"blocks","created_at":"2026-05-11T14:19:02Z","created_by":"Christoph Görn","metadata":"{}"},{"issue_id":"forgejo-mcp-6jc","depends_on_id":"forgejo-mcp-a0p","type":"blocks","created_at":"2026-05-11T14:19:02Z","created_by":"Christoph Görn","metadata":"{}"},{"issue_id":"forgejo-mcp-6jc","depends_on_id":"forgejo-mcp-cpb","type":"blocks","created_at":"2026-05-11T14:19:03Z","created_by":"Christoph Görn","metadata":"{}"},{"issue_id":"forgejo-mcp-6jc","depends_on_id":"forgejo-mcp-zwr","type":"blocks","created_at":"2026-05-11T14:33:02Z","created_by":"Christoph Görn","metadata":"{}"}],"dependency_count":5,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-cpb","title":"Fix openspec change: forgejo-action-code-review has no deltas","description":"openspec/changes/forgejo-action-code-review/ fails validation:\n\n```\n✗ [ERROR] file: Change must have at least one delta. No deltas found.\nEnsure your change has a specs/ directory with capability folders containing .md files\nthat use delta headers (## ADDED/MODIFIED/REMOVED/RENAMED Requirements) and that each\nrequirement includes at least one \"#### Scenario:\" block.\n```\n\nAdd a `specs/\u003ccapability\u003e/spec.md` with `## ADDED Requirements` deltas and scenarios reflecting the change's intent. Probably has design.md but no spec delta.","status":"closed","priority":2,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-11T14:18:52Z","created_by":"Christoph Görn","updated_at":"2026-05-24T06:02:27Z","started_at":"2026-05-11T14:40:50Z","closed_at":"2026-05-11T14:42:00Z","close_reason":"Landed in commit a83a033. Added specs/action-code-review/spec.md with 8 capability requirements + scenarios. openspec validate forgejo-action-code-review --strict passes.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-517","title":"Fix openspec spec: pr-review-write missing Purpose/Requirements headers","description":"openspec/specs/pr-review-write/spec.md fails validation with the same missing-headers error as cli-mode and merge-pull-request. Add `## Purpose` and `## Requirements` sections.","status":"closed","priority":2,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-05-11T14:18:45Z","created_by":"Christoph Görn","updated_at":"2026-05-24T06:02:27Z","closed_at":"2026-05-11T14:30:43Z","close_reason":"Landed in commit c8a7883. Both specs now carry Purpose + Requirements headers; openspec validate --strict passes.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-a0p","title":"Fix openspec spec: merge-pull-request missing Purpose/Requirements headers","description":"openspec/specs/merge-pull-request/spec.md fails strict + non-strict validation with the same missing-headers error as cli-mode. Add `## Purpose` and `## Requirements` sections.","status":"closed","priority":2,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-05-11T14:18:41Z","created_by":"Christoph Görn","updated_at":"2026-05-24T06:02:27Z","closed_at":"2026-05-11T14:30:43Z","close_reason":"Landed in commit c8a7883. Both specs now carry Purpose + Requirements headers; openspec validate --strict passes.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-6un","title":"Fix openspec spec: cli-mode missing Purpose/Requirements headers","description":"openspec/specs/cli-mode/spec.md fails strict + non-strict validation:\n\n```\n✗ [ERROR] file: Spec must have a Purpose section.\nMissing required sections. Expected headers: \"## Purpose\" and \"## Requirements\"\n```\n\nAdd the two missing top-level section headers. Content already implies a purpose — promote it. Prerequisite for forgejo-mcp-NEW-workflow.","status":"closed","priority":2,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-05-11T14:18:36Z","created_by":"Christoph Görn","updated_at":"2026-05-24T06:02:27Z","closed_at":"2026-05-11T14:29:36Z","close_reason":"Landed in commit 23db899. cli-mode spec now has Purpose + Requirements headers; openspec validate cli-mode --strict passes.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-0ep","title":"Add MCP tools for Forgejo releases","description":"Codeberg issue #127: surface release operations (list, get, create, edit, delete, list assets) as MCP tools to help generate release notes and changelogs.\n\nUpstream: https://codeberg.org/goern/forgejo-mcp/issues/127","status":"closed","priority":2,"issue_type":"feature","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-11T13:26:17Z","created_by":"Christoph Görn","updated_at":"2026-05-12T14:56:12Z","started_at":"2026-05-11T13:26:22Z","closed_at":"2026-05-12T14:56:12Z","close_reason":"PR #134 merged (https://codeberg.org/goern/forgejo-mcp/pulls/134); 14 tools live","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-efo","title":"Fix update_issue tool: assignee field ignored by Forgejo API","description":"The mcp__codeberg__update_issue tool exposes a singular 'assignee' parameter, but Forgejo's EditIssueOption ignores the deprecated singular field in current API versions and only honors the 'assignees' array.\n\nObserved in issue goern/forgejo-mcp#127: calling update_issue with assignee=goern returned HTTP 200 but a follow-up GET still shows assignees:null.\n\nWhat needs to be done:\n- Locate the update_issue handler in operation/issue/ (or wherever EditIssue is wired)\n- Change the SDK call to pass assignees=[]string{assignee} (or expose an 'assignees' parameter directly)\n- Keep the singular 'assignee' param for backward compat, but convert to array before SDK call\n- Add an integration test that asserts the assignee actually persists after update\n\nAcceptance:\n- update_issue with assignee=\u003cuser\u003e results in assignees containing that user on subsequent GET\n- Upstream tracking: codeberg.org/goern/forgejo-mcp#\u003cTBD\u003e","status":"closed","priority":2,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-11T13:24:23Z","created_by":"Christoph Görn","updated_at":"2026-05-11T13:29:56Z","started_at":"2026-05-11T13:25:58Z","closed_at":"2026-05-11T13:29:56Z","close_reason":"Fix landed in commit 6291213. Singular 'assignee' now wired to opt.Assignees=[]string{assignee}. New 'assignees' CSV param overrides. Unit tests in operation/issue/issue_test.go cover singular, CSV, clear, and omit cases. Upstream: codeberg.org/goern/forgejo-mcp#128.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-e0j","title":"docs(design): codify output-bounding rule from #124","description":"Issue #124 surfaced unbounded MCP tool outputs (diffs, files, pull-files lists) blowing up context windows. Codify the rule derived in triage as a design doc and reference it from AGENTS.md so every new tool considers output bounding by default. Three sub-rules: no silent truncation, bound by domain shape (line/per-file/page), always resumable.","status":"closed","priority":2,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-10T14:09:42Z","created_by":"Christoph Görn","updated_at":"2026-05-10T14:12:04Z","started_at":"2026-05-10T14:09:45Z","closed_at":"2026-05-10T14:12:04Z","close_reason":"Landed in 1412cbe — docs/design/output-bounding.md + AGENTS.md checklist update.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-xv0","title":"OpenSpec change for org-label support in list_repo_labels","description":"Sub-task of forgejo-mcp-7ch. Author OpenSpec change covering:\n- New tool list_org_labels(org, page, limit)\n- Augmentation of list_repo_labels with include_org_labels bool (default true) and scope tag on each label\n- Use pkg/forgejo.DoJSONList against /orgs/{org}/labels (no SDK upgrade)\n- Test plan: httptest server fixtures for repo-only, org-only, merged, 404→empty\n\nOutput: artifacts under openspec/changes/\u003cchange-id\u003e/ following experimental workflow (proposal, design, tasks, deltas).","status":"closed","priority":2,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-05-09T20:38:32Z","created_by":"Christoph Görn","updated_at":"2026-05-24T06:02:27Z","closed_at":"2026-05-09T20:43:52Z","close_reason":"OpenSpec change add-org-label-support authored on branch issues/125","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-7ch","title":"list_repo_labels missing org-level labels (#125)","description":"Codeberg issue #125: list_repo_labels exposes only repo-scoped labels. Forgejo API also exposes /orgs/{org}/labels which SDK v3 does not bind. For org-owned repos, org labels are usable on issues but invisible to MCP — model cannot discover their IDs.\n\nImpl path:\n- Add new tool list_org_labels(org, page, limit) using pkg/forgejo.DoJSONList against /orgs/{org}/labels.\n- Augment list_repo_labels with bool include_org_labels (default true). When repo owner is org, merge org labels and tag each with scope=repo|org.\n- No SDK upgrade required — same pattern as attachments raw-HTTP path.\n- Tests via httptest server matching pkg/forgejo/*_test.go patterns.\n\nAcceptance:\n- list_repo_labels of an org-owned repo returns repo+org labels with scope tag.\n- list_org_labels callable standalone.\n- 404 from org endpoint maps to empty (no error).\n- include_org_labels=false suppresses merge.\n- Tests cover both tools.","acceptance_criteria":"list_repo_labels returns org labels when repo owner is org; new list_org_labels tool callable; tests cover both","notes":"Merged in PR #130 (squash, 2026-05-12). Closes Codeberg #125.","status":"closed","priority":2,"issue_type":"bug","owner":"goern@b4mad.net","created_at":"2026-05-09T20:38:27Z","created_by":"Christoph Görn","updated_at":"2026-05-12T08:41:22Z","closed_at":"2026-05-11T14:48:41Z","dependencies":[{"issue_id":"forgejo-mcp-7ch","depends_on_id":"forgejo-mcp-xv0","type":"blocks","created_at":"2026-05-09T20:38:35Z","created_by":"Christoph Görn","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-9y4","title":"Wire .mcpb build into release pipeline","description":"PR #118 adds extension/ scaffolding for Claude Desktop Extension (.mcpb) but does NOT produce .mcpb on release. Maintainer must extend release.yml so users get downloadable .mcpb per release.\n\nRequired:\n1. Inject release tag into extension/manifest.json version field (currently hardcoded 2.20.0). Use jq before mcpb pack.\n2. Build per-platform .mcpb archives OR single .mcpb with server.mcp_config.platform_overrides bundling all 4 binaries (linux/darwin x amd64/arm64).\n3. Attach resulting .mcpb file(s) to Codeberg release alongside existing tar.gz archives.\n4. Optional: sign with npx @anthropic-ai/mcpb sign.\n\nWhy: PR #118 leaves this explicitly as follow-up. Without it, end users on releases page see only tar.gz binaries, no drag-and-drop install artifact. Extension story incomplete from end-user POV.\n\nHow to apply: extend .forgejo/workflows/release.yml with post-goreleaser job. Use dist/ artifacts produced by goreleaser as input. See PR #118 review for concrete shell snippet.","acceptance_criteria":"- Each tagged release on codeberg.org/goern/forgejo-mcp/releases includes .mcpb artifact(s)\n- manifest.json version matches release tag at pack time (no hardcoded version drift)\n- .mcpb installs cleanly in Claude Desktop on at least linux-amd64 and darwin-arm64\n- Smoke test (extension/test_smoke.py) runs in CI before pack","status":"closed","priority":2,"issue_type":"feature","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-07T20:23:07Z","created_by":"Christoph Görn","updated_at":"2026-05-07T21:02:47Z","started_at":"2026-05-07T20:25:53Z","closed_at":"2026-05-07T21:02:47Z","close_reason":"Shipped in PR #122 (commit fdc6305): release.yml builds and attaches per-platform .mcpb (linux/darwin x amd64/arm64) with jq-based manifest version injection. Local make target added in commit 679d593.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-vsm","title":"E2E test script for attachment tools","description":"Shell script in test/e2e/attachments.sh that exercises ./forgejo-mcp --cli end-to-end against live Codeberg: create issue, upload attachment, list, get, verify browser_download_url, cleanup. Validates v2.19.0-alpha.1 attachment tools work in real deployment as referenced in issue #106.","status":"closed","priority":2,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-04-27T06:54:05Z","created_by":"Christoph Görn","updated_at":"2026-04-27T06:55:37Z","started_at":"2026-04-27T06:54:10Z","closed_at":"2026-04-27T06:55:37Z","close_reason":"Script at test/e2e/attachments.sh, passes live against Codeberg, committed 8ec35e5.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-zhi","title":"Amend issue-attachments spec: lower inline cap to 1 MiB and always include download URL","description":"Follow-up to heathen711's feedback on https://codeberg.org/goern/forgejo-mcp/issues/106. After discussion (comments 13562510, 13701827, 13703888), the agreed scope is two narrow changes to docs/plans/issue-attachments.md: (1) lower MaxInlineDownloadBytes from 10 MiB to 1 MiB, (2) always include browser_download_url in download_*_attachment responses regardless of size. Files under the cap return base64-encoded bytes inline (current MCP-protocol-native behavior); files over the cap return metadata + URL only, and the LLM is expected to fall through to a curl/Bash fetch using its existing token. Earlier proposals — save_to_path parameter and inline:true flag — dropped per heathen711's reasoning: file-path returns introduce tmpfile hygiene + cross-container permission problems, which is exactly why MCP standardised on pipe-based binary delivery; size-cap discrimination already gives the metadata-vs-bytes split without an extra flag. Must land before forgejo-mcp-ydg implementation starts.","design":"Two-line behavioural change: const MaxInlineDownloadBytes = 1 * 1024 * 1024 (was 10 * 1024 * 1024); download_*_attachment response shape always carries browser_download_url alongside metadata, with bytes only if size \u003c cap. No new tool-surface parameters. Open Question #2 in the spec (private-repo auth on browser_download_url) becomes load-bearing — the fall-through-to-curl pattern only works if the URL accepts Authorization: token $TOKEN; verify in Part 1 of the implementation.","acceptance_criteria":"docs/plans/issue-attachments.md updated with save_to_path parameter, 1 MiB cap, always-include-download-url rule, and metadata-default behavior. Parameter matrix reflects the new column. Acceptance criteria section includes save_to_path round-trip test. heathen711 notified of the amendment on issue #106.","status":"closed","priority":2,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-04-24T14:14:05Z","created_by":"Christoph Görn","updated_at":"2026-05-24T06:02:27Z","started_at":"2026-04-26T10:45:34Z","closed_at":"2026-04-26T10:46:59Z","close_reason":"Spec amended in docs/plans/issue-attachments.md: cap lowered to 1 MiB, browser_download_url always included, Open Question #2 promoted to load-bearing Part-1 verification step, acceptance criteria updated to cover both under-cap and over-cap paths. Implementation issue forgejo-mcp-ydg is now unblocked.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-ya6","title":"Issue/PR time tracking: tracked-time + stopwatch MCP tools","description":"Adds 10 MCP tools wrapping forgejo-sdk/v3's tracked-time and stopwatch APIs. Covers list/add/reset/delete tracked-time entries on issues and PRs (which share index space in Forgejo), plus start/stop/cancel/list_my stopwatches. No raw-HTTP helper needed — SDK has full coverage. Spec: docs/plans/issue-time-tracking.md.","design":"SDK-wrapping approach (not raw HTTP): forgejo-sdk/v3 exposes AddTime/ListIssueTrackedTimes/ResetIssueTime/DeleteTime + StartIssueStopWatch/StopIssueStopWatch/DeleteIssueStopwatch/GetMyStopwatches. Verbs mirror API primitives (chose option B over 'set' convenience wrapper to avoid non-atomic reset+add race on shared state). Duration parsing via stdlib time.ParseDuration — no extra dep. Issue/PR unified: single tool set covers both because Forgejo shares index namespace.","acceptance_criteria":"All 10 tools registered and callable; add_issue_time accepts either 'seconds' (int) or 'duration' (string like '15m'); list_issue_tracked_times returns entries with id/time/user; reset clears all entries; delete removes one; stopwatch start→stop produces a tracked-time entry visible via list; cancel discards without creating an entry; make build + go test ./... pass; both demo files run cleanly.","status":"closed","priority":2,"issue_type":"feature","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-04-21T20:38:06Z","created_by":"Christoph Görn","updated_at":"2026-04-21T20:48:54Z","started_at":"2026-04-21T20:42:04Z","closed_at":"2026-04-21T20:48:54Z","close_reason":"Implemented in commit (see git log); 10 MCP tools + tests + 2 showboat demos + README update.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-ydg","title":"Issue \u0026 comment attachments: full CRUD MCP tools","description":"Closes upstream Codeberg issue goern/forgejo-mcp#106: attachments on issues are invisible to the MCP because GET /issues/{index} does not embed them, and forgejo-sdk/v3 has zero issue-attachment methods. Spec: docs/plans/issue-attachments.md (amended per forgejo-mcp-zhi). Delivers 12 new tools (list/get/download/create/edit/delete × issue + comment), a raw-HTTP helper (pkg/forgejo/rawhttp.go), binary content return via mcp.BlobResourceContents with a 1 MiB inline cap, browser_download_url always included for over-cap fall-through, and two Showboat demos (demos/issue-attachments.md, demos/comment-attachments.md). Part 1 of implementation must verify private-repo auth on browser_download_url before Part 3 begins (load-bearing — see Open Question #2 in spec).","design":"Approach 2: raw HTTP inside forgejo-mcp (chosen over upstream-first and replace-directive hybrid). Rationale: attachment endpoints are stable Gitea/Forgejo routes, raw-HTTP surface is small and contained behind one helper package, shipping time beats SDK-consistency. Risk (field drift) mitigated by reusing forgejo_sdk.Attachment as DTO + demos as live-integration canaries.","acceptance_criteria":"All 12 tools registered and callable; list_issue_attachments on goern/forgejo-mcp#106 returns the uploaded PDF metadata; download_issue_attachment round-trips bytes sha256-identical; edit/delete round-trip works for both issues and comments; list on empty entity returns []; make build + go test ./... pass; both demo files run cleanly end-to-end.","status":"closed","priority":2,"issue_type":"feature","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-04-21T20:29:49Z","created_by":"Christoph Görn","updated_at":"2026-04-26T11:11:40Z","started_at":"2026-04-26T10:58:41Z","closed_at":"2026-04-26T11:11:40Z","close_reason":"Implemented in PR #109 (feature/issue-attachments). 12 tools, rawhttp helper, all tests green, live-verified against Codeberg API.","dependencies":[{"issue_id":"forgejo-mcp-ydg","depends_on_id":"forgejo-mcp-zhi","type":"blocks","created_at":"2026-04-24T14:14:10Z","created_by":"Christoph Görn","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-hc9","title":"chore: triage golangci-lint v2 backlog (207 findings)","description":"Updated local linters (staticcheck v0.4.6→v0.7.0/2026.1, golangci-lint 1.53.3→2.12.2) and migrated .golangci.yml to v2 config ('golangci-lint migrate'). Lint now runs again and surfaces pre-existing backlog:\n\n- 188 errorlint: fmt.Errorf with %v instead of %w for errors. Mechanical sweep BUT changes semantics — %w exposes wrapped errors to errors.Is/As in MCP clients/tests. Decide policy first (wrap everywhere vs keep %v + lint exclusion).\n- 14 staticcheck QF/ST hints: tagged switches, De Morgan, Fprintf-instead-of-WriteString, omit 'any' type. Pure style.\n- 2 govet inline: reflect.Ptr → reflect.Pointer (deprecated alias) in pkg/ptr/ptr.go.\n- 2 errcheck: fs.Parse (cmd/cmd.go:97, ExitOnError makes it moot — ignore or check), zap Logger.Sync deferred (conventional to ignore; add //nolint or _ =).\n\nS1039 (attachment.go:491) already fixed in tool-update commit.","status":"closed","priority":3,"issue_type":"chore","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-06-10T21:58:43Z","created_by":"Christoph Görn","updated_at":"2026-06-10T22:03:25Z","started_at":"2026-06-10T22:00:02Z","closed_at":"2026-06-10T22:03:25Z","close_reason":"Fixed entire lint backlog, not just errorlint. Method: 'golangci-lint run --fix' (auto-applied errorlint %v→%w in ~30 files, errors.Is for context.Canceled, staticcheck QF quickfixes, govet reflect.Ptr→reflect.Pointer, ST1023). Manual repairs after autofix: (1) missing 'errors' imports in cmd/cmd.go + 4 test files (goimports -w); (2) autofix BROKE 4 test assertions — dropped '\u0026\u0026 re.Code != X' from 'if re, ok := err.(*T); ok \u0026\u0026 re.Code != X' patterns, inverting test logic — restored as errors.As + explicit Code check, normalized 10 sites to 'var re *resource.ResourceError'; (3) 2 errcheck: '_ = fs.Parse' (ExitOnError) + deferred zap Sync wrapped; (4) 2 QF1001 De Morgan: hoisted hex checks into 'isHex' predicate (label.go normalizeColor, parse.go validateSHA). Final: golangci-lint 0 issues, staticcheck clean, vet ok, all tests pass. Policy: %w wrapping adopted — handler errors now expose wrapped SDK/HTTP errors to errors.Is/As.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-cv4","title":"fix: comment/review excerpts truncate at byte 200, can split UTF-8 rune","description":"operation/issue/resources.go:110-112 and operation/pull/resources.go:125-127,151-153 — excerpt[:200] slices bytes, not runes. Multibyte char straddling the boundary yields invalid UTF-8; json.Marshal replaces with U+FFFD.\n\nFix: truncate on rune boundary (e.g. convert through []rune or walk back with utf8.RuneStart).","status":"closed","priority":3,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-06-10T21:50:20Z","created_by":"Christoph Görn","updated_at":"2026-06-10T21:53:53Z","started_at":"2026-06-10T21:50:28Z","closed_at":"2026-06-10T21:53:53Z","close_reason":"Fixed: added resource.Excerpt(s, max) (operation/resource/excerpt.go) that truncates on rune boundary via utf8.RuneStart walk-back; replaced 3 byte-slice truncations in operation/issue/resources.go and operation/pull/resources.go. Unit tests added (excerpt_test.go) incl. multibyte-straddle case. Build/vet/tests pass.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-yea","title":"docs: stale/incorrect comments in pkg/forgejo/rawhttp.go and resource/parse.go","description":"1. pkg/forgejo/rawhttp.go DoJSON doc comment describes a 'boolean isList' parameter that does not exist (the 404-as-empty-list behavior lives in DoJSONList).\n2. operation/resource/parse.go validateSHA doc says 'exactly 40 lowercase hex characters' but the code (correctly) accepts uppercase A-F too; ParseCommit doc repeats the lowercase claim.\n\nFix doc comments to match behavior.","status":"closed","priority":3,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-06-10T21:50:20Z","created_by":"Christoph Görn","updated_at":"2026-06-10T21:53:54Z","started_at":"2026-06-10T21:50:28Z","closed_at":"2026-06-10T21:53:54Z","close_reason":"Fixed: DoJSON doc no longer references nonexistent isList param (points to DoJSONList); ParseCommit/validateSHA docs say '40 hex characters' instead of 'lowercase'. Comment-only change.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-aa6","title":"Migrate cosign attach sbom to cosign attest","description":"cosign-attach-sbom.yaml uses 'cosign attach sbom', which cosign deprecated (removal slated soon after 2024-02-22, see sigstore/cosign#2755) and which does NOT sign the SBOM. Migrate to 'cosign attest --predicate \u003csbom\u003e --type cyclonedx --key \u003ckey\u003e' so the SBOM is a signed attestation. Surfaced as a WARNING during v2.27.0-alpha.1 SBOM attach (2026-06-01).","status":"closed","priority":3,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-06-01T08:59:34Z","created_by":"Christoph Görn","updated_at":"2026-06-02T05:59:55Z","closed_at":"2026-06-02T05:59:55Z","close_reason":"Done in commit b2619fc. Migrated .tekton/release-tools/tasks/cosign-attach-sbom.yaml from deprecated 'cosign attach sbom' (unsigned) to 'cosign attest --predicate \u003csbom\u003e --type cyclonedx --key' (signed in-toto attestation, same key as image signing). README consumer block updated to verify-attestation. CI-pipeline task (used by on-tag-push-release.yaml attach-image-sbom). Governed spec update tracked in forgejo-mcp-3y1.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-hxv","title":"MCP tool get_forgejo_mcp_server_version may always report 'dev'","description":"operation/version/version.go reads pkg/flag.Version. cmd/cmd.go injects the build version into the user-agent and operation.Run, but verify whether pkg/flag.Version is ever assigned. If not, get_forgejo_mcp_server_version returns 'dev' even when the CLI version/--version command reports the real injected version (now fixed for containers via build-arg in PR feat/hummingbird-containers). Wire flag.Version from the injected main.Version if missing.","status":"open","priority":3,"issue_type":"bug","owner":"goern@b4mad.net","created_at":"2026-05-31T19:23:37Z","created_by":"Christoph Görn","updated_at":"2026-05-31T19:23:37Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-16t","title":"Reject empty/whitespace URI segments in operation/resource/parse.go:220","description":"splitPath silently collapses empty segments — forgejo://repo/foo//bar (double slash) and forgejo://repo/foo/bar/ (trailing slash) parse as the canonical forgejo://repo/foo/bar. PR promotes these URIs as content-addressable cache keys but multiple distinct URIs map to the same resource. URL-decoded whitespace-only segments (forgejo://repo/%20/%20/...) pass blank/whitespace owner/repo to the SDK, surfacing as 404 instead of -32602. Review: https://codeberg.org/goern/forgejo-mcp/pulls/172#issuecomment-16022165 (conf 80).","notes":"Fix: at operation/resource/parse.go:220, change splitPath to either (a) reject empty/whitespace segments (return error to parseForgejoURI which already returns error), OR (b) document canonicalisation explicitly. Recommend (a) — strictness preserves URI identity for caching. Add parse_test.go cases: double slash, trailing slash, percent-encoded whitespace owner/repo.","status":"closed","priority":3,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-28T13:47:09Z","created_by":"Christoph Görn","updated_at":"2026-05-28T13:58:38Z","started_at":"2026-05-28T13:57:03Z","closed_at":"2026-05-28T13:58:38Z","close_reason":"Fixed in 55a39f4. parseForgejoURI rejects empty/whitespace segments; test cases added; full suite green.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-91j","title":"Fix user→org fallback masking real errors + nil-userErr edge case in operation/user/resources_owner.go:96","description":"Two failure modes: (a) when GetOrg fails with orgResp==nil (network/DNS/context-cancel), handler returns MapForgejoError(uri, userErr) — surfacing original 404 instead of the real transport error; (b) if userErr is nil (u==nil err==nil SDK edge), MapForgejoError(nil)=nil and handler returns (nil, nil), violating MCP semantics. Review: https://codeberg.org/goern/forgejo-mcp/pulls/172#issuecomment-16022165 (conf 82).","notes":"Fix: at operation/user/resources_owner.go:90-97, restructure:\n if orgErr != nil {\n if orgResp != nil \u0026\u0026 orgResp.StatusCode == 404 {\n // both 404 — surface explicit not-found\n return nil, \u0026resource.ResourceError{URI: uri, Code: -32003, Message: \"owner not found: \" + req.Params.URI}\n }\n if orgResp != nil {\n return nil, resource.MapForgejoError(uri, fmt.Errorf(\"%d %s\", orgResp.StatusCode, orgErr.Error()))\n }\n return nil, resource.MapForgejoError(uri, orgErr) // prefer the real orgErr over original userErr\n }","status":"closed","priority":3,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-28T13:47:09Z","created_by":"Christoph Görn","updated_at":"2026-05-28T14:11:59Z","started_at":"2026-05-28T14:09:36Z","closed_at":"2026-05-28T14:11:59Z","close_reason":"Fixed in 19f1efd.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-g5s","title":"Map parse error via resource.MapForgejoError in operation/repo/resources_status.go:65","description":"Same parse-error inconsistency. Malformed status URIs (including short SHA) lose -32602. Review: https://codeberg.org/goern/forgejo-mcp/pulls/172#issuecomment-16022165 (conf 88).","notes":"Fix: at operation/repo/resources_status.go:64-65, replace the fmt.Errorf wrap with resource.MapForgejoError(uri, err).","status":"closed","priority":3,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-28T13:47:09Z","created_by":"Christoph Görn","updated_at":"2026-05-28T14:03:29Z","started_at":"2026-05-28T14:02:12Z","closed_at":"2026-05-28T14:03:29Z","close_reason":"Fixed in 10c8403.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-iqi","title":"Map parse error via resource.MapForgejoError in operation/user/resources_owner.go:56","description":"Same parse-error inconsistency. Malformed owner URIs lose -32602. Review: https://codeberg.org/goern/forgejo-mcp/pulls/172#issuecomment-16022165 (conf 88).","notes":"Fix: at operation/user/resources_owner.go:55-56, replace the fmt.Errorf wrap with resource.MapForgejoError(uri, err).","status":"closed","priority":3,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-28T13:47:09Z","created_by":"Christoph Görn","updated_at":"2026-05-28T14:05:07Z","started_at":"2026-05-28T14:03:29Z","closed_at":"2026-05-28T14:05:07Z","close_reason":"Fixed in 6cecf67.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-s2g","title":"Map parse error via resource.MapForgejoError in operation/repo/resources_repo.go:61","description":"Same parse-error inconsistency as commit handler. Malformed repo URIs lose -32602. Review: https://codeberg.org/goern/forgejo-mcp/pulls/172#issuecomment-16022165 (conf 88).","notes":"Fix: at operation/repo/resources_repo.go:60-61, replace the fmt.Errorf wrap with resource.MapForgejoError(uri, err).","status":"closed","priority":3,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-28T13:47:09Z","created_by":"Christoph Görn","updated_at":"2026-05-28T14:02:11Z","started_at":"2026-05-28T14:00:47Z","closed_at":"2026-05-28T14:02:11Z","close_reason":"Fixed in 0c177af. Same pattern as vzz.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-wgs","title":"Replace substring-based HTTP classification in operation/resource/errors.go:26","description":"MapForgejoError classifies HTTP results by substring search on the formatted error string. Two failure modes: (1) URIs/error bodies legitimately containing '404' or 'Forbidden' get misclassified; (2) parser errors of shape 'invalid URI: expected forgejo://...' do NOT match any -32602 substring so wrong-shape URIs fall through to -32603 internal-error instead of -32602 invalid-params. Review: https://codeberg.org/goern/forgejo-mcp/pulls/172#issuecomment-16022165 (conf 88).","notes":"Fix: change MapForgejoError signature to accept an HTTP status int (handlers already have resp.StatusCode at the call site) — e.g. MapForgejoError(uri string, status int, err error) — and dispatch on status, not substring. For parser errors, use a sentinel error type (var ErrInvalidParams = errors.New(\"invalid params\")) and errors.Is for the -32602 path. Update all 7 handler call sites.","status":"closed","priority":3,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-28T13:47:09Z","created_by":"Christoph Görn","updated_at":"2026-05-28T14:09:35Z","started_at":"2026-05-28T14:05:08Z","closed_at":"2026-05-28T14:09:35Z","close_reason":"Fixed in 1aa797a. ErrInvalidParams sentinel introduced; -32602 surfaces correctly.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-vzz","title":"Map parse error via resource.MapForgejoError in operation/repo/resources_commit.go:39","description":"Parse-error path uses fmt.Errorf instead of resource.MapForgejoError. Malformed commit URIs lose the -32602 invalid-params JSON-RPC code. Inconsistent with issue/pr handlers. Review: https://codeberg.org/goern/forgejo-mcp/pulls/172#issuecomment-16022165 (conf 88).","notes":"Fix: at operation/repo/resources_commit.go:38-39, replace\n if err != nil {\n return nil, fmt.Errorf(\"invalid commit resource URI: %w\", err)\n }\nwith\n if err != nil {\n return nil, resource.MapForgejoError(uri, err)\n }","status":"closed","priority":3,"issue_type":"bug","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-28T13:47:08Z","created_by":"Christoph Görn","updated_at":"2026-05-28T14:00:47Z","started_at":"2026-05-28T13:58:38Z","closed_at":"2026-05-28T14:00:47Z","close_reason":"Fixed in 81d1945. Parse errors now mapped via MapForgejoError; type-assertion surfaces *ResourceError. -32602 elevation pending forgejo-mcp-wgs.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-8ia","title":"Fix CommmentsTruncated typo in operation/pull/resources.go:79","description":"Rename prResourcePayload.CommmentsTruncated (three m's) to CommentsTruncated. JSON tag comments_truncated keeps wire format. Cosmetic but easy to mis-reference. Review comment: https://codeberg.org/goern/forgejo-mcp/pulls/172#issuecomment-16022165 (conf 95).","notes":"Fix: edit operation/pull/resources.go line 79 — replace 'CommmentsTruncated bool' with 'CommentsTruncated bool'. Also update the assignment site (search for CommmentsTruncated:). Run go build \u0026\u0026 go test ./operation/pull/...","status":"closed","priority":3,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-28T13:46:21Z","created_by":"Christoph Görn","updated_at":"2026-05-28T13:55:39Z","started_at":"2026-05-28T13:54:08Z","closed_at":"2026-05-28T13:55:39Z","close_reason":"Fixed in commit 683404c on PR #172 branch. Field renamed CommmentsTruncated → CommentsTruncated; JSON tag unchanged; tests pass.","dependency_count":0,"dependent_count":1,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-mzr","title":"Move beads-dashboard.html into .beads/ as dashboard.html","description":"Relocate the standalone dashboard from repo root into the .beads/ directory so the dashboard ships next to its data source. Update fetch path from '.beads/issues.jsonl' to 'issues.jsonl' (now sibling). No other consumers (CHANGELOG line is history).","acceptance_criteria":"File served at .beads/dashboard.html loads .beads/issues.jsonl successfully (HTTP 200, fetch resolves).","status":"closed","priority":3,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-26T13:44:56Z","created_by":"Christoph Görn","updated_at":"2026-05-26T13:45:33Z","started_at":"2026-05-26T13:45:01Z","closed_at":"2026-05-26T13:45:33Z","close_reason":"moved beads-dashboard.html → .beads/dashboard.html; fetch path updated to sibling issues.jsonl; HTTP 200 verified","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-gdz","title":"Decide Tekton release pipeline cutover after 2 successful runs","description":"Followup to forgejo-mcp-d4b. After 2 consecutive v* releases where the op1st Tekton pipeline succeeds end-to-end and produces assets matching the Forgejo Actions output, decide canonical release path per docs/design/release-pipeline-migration.md cutover criteria. If Tekton wins: open PR removing .forgejo/workflows/release.yml. If not: file follow-up bugs explaining why and revisit.","acceptance_criteria":"ADR addendum or new commit on docs/design/release-pipeline-migration.md recording the decision; redundant pipeline (.forgejo/workflows/release.yml OR the .tekton release pipeline) removed in a single PR","notes":"Validation state after first live run cycle:\n- v2.24.0: phantom tag, no Release on Codeberg (goreleaser exit 127)\n- v2.24.1: phantom tag, no Release on Codeberg (goreleaser dirty-tree)\n- v2.24.2: 13/14 assets on Codeberg, no .sig (cosign step distroless-no-shell). Counts as partial first Tekton release.\n\nCutover criteria require 2 consecutive end-to-end successes including .sig. v2.24.2 does not qualify. Next clean Tekton release must come AFTER forgejo-mcp-1b4 (release-tools image). Once that lands, need 2 clean releases before deleting .forgejo/workflows/release.yml. Until then: pipeline stays parallel-ready, Forgejo release.yml stays as workflow_dispatch fallback.","status":"closed","priority":3,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-05-25T11:27:33Z","created_by":"Christoph Görn","updated_at":"2026-05-26T09:30:22Z","closed_at":"2026-05-26T09:30:22Z","close_reason":"ADR addendum written in docs/design/release-pipeline-migration.md. Hard cutover executed after v2.25.1 (first clean end-to-end Tekton run). .forgejo/workflows/release.yml deleted commit 1777cca.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-02o","title":"Label Codeberg PR #145 via codeberg-label skill","description":"Test new codeberg-label skill end-to-end on https://codeberg.org/goern/forgejo-mcp/pulls/145. Sonnet subagent picks labels; main session applies via forgejo-mcp.","status":"closed","priority":3,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-25T07:23:23Z","created_by":"Christoph Görn","updated_at":"2026-05-25T07:24:59Z","started_at":"2026-05-25T07:23:30Z","closed_at":"2026-05-25T07:24:59Z","close_reason":"Labeled PR #145 with Kind/Security + Priority/Critical via codeberg-label skill; minutes posted.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-e8e","title":"CI: coverage report + pre-commit parity job","description":"Post coverage as PR comment (codecov-cli or go tool cover artifact). Add CI job that runs .pre-commit-config.yaml hooks so they're enforced beyond local dev.","status":"open","priority":3,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-05-24T07:06:47Z","created_by":"Christoph Görn","updated_at":"2026-05-24T07:06:47Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-zuh","title":"CI: container build sanity on PR + edge tag on main","description":"Containerfile builds only via Konflux currently. Add PR job that builds container image as sanity check (no push). On push to main, push :edge tag to registry.","status":"open","priority":3,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-05-24T07:06:45Z","created_by":"Christoph Görn","updated_at":"2026-05-24T07:06:45Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-1p1","title":"CI: add go-licenses + conventional commits PR title check","description":"Catch GPL contamination via go-licenses check. Gate Conventional Commits PR title earlier than .releaserc post-merge (use commitlint or equivalent action).","notes":"PR #166 opened: https://codeberg.org/goern/forgejo-mcp/pulls/166. Changes: go-licenses v1.6.0 in release-tools image + license-check step in go-ci (forbidden/restricted denied); new commit-title-check task validates PR title via PAC {{ body.pull_request.title }} AND all PR branch commits; on-pull-request pipeline wires it parallel to build-and-test.","status":"closed","priority":3,"issue_type":"task","assignee":"Christoph Görn","owner":"goern@b4mad.net","created_at":"2026-05-24T07:06:42Z","created_by":"Christoph Görn","updated_at":"2026-05-26T13:30:59Z","started_at":"2026-05-26T13:12:18Z","closed_at":"2026-05-26T13:30:59Z","close_reason":"PR #166 merged","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-td8","title":"CI: decide canonical PR gate (Tekton vs Forgejo Actions)","description":"After 2 weeks of parallel Forgejo Actions + Tekton PR gates, evaluate reliability/speed/contributor-visibility and pick one as canonical. Keep Tekton/Konflux only for signed container builds if Forgejo Actions wins.","acceptance_criteria":"ADR or design note in docs/design/ recording decision + rationale, redundant pipeline removed","status":"closed","priority":3,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-05-24T07:06:40Z","created_by":"Christoph Görn","updated_at":"2026-05-26T09:18:37Z","closed_at":"2026-05-26T09:18:37Z","close_reason":"Decision made: Tekton is canonical PR gate. Forgejo Actions workflows removed in commit 1777cca.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-p0y","title":"Cleanup C4 spike state on Codeberg","description":"Battle-test of forgejo-action-code-review created throwaway repos: goern/c4-spike-target and fork tinytalesshop/c4-spike-target. Both should be deleted once team confirms spike findings have been preserved in battle-test.md and design.md (already done). Also: PR #2 on goern/c4-spike-target is open; close it. Also: tag v0.0.1 not yet created on c5-spike-lib (and secrets not set on c5-spike-lib/c5-spike-consumer) — see related C5 spike issue. Delete all 3 c5 repos when C5 spike completes too.","status":"open","priority":3,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-05-13T06:33:26Z","created_by":"Christoph Görn","updated_at":"2026-05-13T06:33:26Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-7de","title":"Revisit EmbeddedListCap (currently 30) when resource usage telemetry is available","description":"Slice 1 of mcp-resource-templates set operation/resource.EmbeddedListCap = 30 per design.md D8. The cap was chosen by analogy to existing list_* tools, without telemetry. This follow-up tracks revisiting the constant once we have real usage data (issue/PR comment-count distribution, truncation hit rate). Likely outcomes: keep 30, raise to 50, or expose per-resource override.","status":"open","priority":4,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-05-28T13:18:35Z","created_by":"Christoph Görn","updated_at":"2026-05-28T13:18:35Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-7ra","title":"Revisit WithResourceCapabilities(subscribe=true) once a real subscription use case appears","description":"Slice 1 of mcp-resource-templates registered server.WithResourceCapabilities(false, false) per design.md D5 — read-on-demand only, no subscriptions. This follow-up tracks revisiting the subscribe=true path when a real consumer use case appears (e.g., dashboard pushing live updates). Out-of-scope for the initial 7-entity rollout; gating signal is concrete client demand, not telemetry.","status":"open","priority":4,"issue_type":"task","owner":"goern@b4mad.net","created_at":"2026-05-28T13:18:29Z","created_by":"Christoph Görn","updated_at":"2026-05-28T13:18:29Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||
{"_type":"issue","id":"forgejo-mcp-7g9","title":"Refactor release-tools image into smaller purpose-specific images","description":"release-tools image has grown to include goreleaser, syft, cosign, go, node, npm, mcpb, jq, curl, govulncheck, and openspec. This is a monolithic image that does not follow SRP. Refactor into smaller purpose-specific images: e.g. build-release (goreleaser+syft+go), sign-release (cosign), pack-release (node+npm+mcpb), validate (openspec), scan (govulncheck+syft). Each image should be smaller, faster to pull, and easier to audit. Coordinate with the release-pipeline-use-release-tools-image change and the forgejo-mcp-gdz cutover criteria. Do not start until at least 2 successful releases using the monolithic image confirm operational correctness.","status":"open","priority":4,"issue_type":"feature","owner":"goern@b4mad.net","created_at":"2026-05-25T21:17:18Z","created_by":"Christoph Görn","updated_at":"2026-05-25T21:17:18Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|