Forgejo's /issues?labels= filter requires integer IDs, not label names.
The workflow was searching by name (returning 0 results) then creating
a new issue every run.
Fix: look up label first, only create if missing, then use the ID for
both issue search and issue creation. This prevents both duplicate
issues and duplicate labels.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add command execution rules to prompt (no env prefixes, no 2>&1)
- Document pre-existing test failures so Claude doesn't waste turns
- Add Bash(echo:*) and Bash(cat:*) to allowed_tools
- Delete stale remote branches before creating new ones
Addresses 24 permission denials in last run where Claude spent
~15 of 47 turns on blocked commands.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Forgejo's create-issue API expects `labels` as `[int64]` (label IDs),
not `[{"name": "..."}]` like GitHub. The previous format caused a JSON
unmarshal error, silently returning null instead of creating the issue.
Changes:
- Split label step to create-if-missing then look up the ID
- Pass label ID as integer to issue creation: `labels: [169]`
- Add error handling: log API response if issue creation returns null
- Also cleaned up another duplicate upstream-sync label
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add idempotency to the merge-upstream job:
1. Check for existing open PR from chore/upstream-sync-* branch
2. If PR exists and branch is up to date with upstream → skip
3. If PR exists but upstream has new commits → checkout existing
branch, merge new upstream commits, run Claude to review/test
4. If no PR exists → create new branch (existing behavior)
Also update Claude's prompt to handle both create and update PR
cases, so it knows to push to the existing PR branch instead of
creating a duplicate.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three fixes in the upstream-sync workflow:
1. Replace github.token with CLAUDE_BOT_TOKEN in the check-upstream
job. The default runner token on Forgejo doesn't have issue-write
permissions, so issues were silently failing to create.
2. Output the tracking issue number from check-upstream and pass it
to the merge-upstream job. Claude's prompt now includes the issue
reference and instructs it to add "Closes #N" in the PR body.
3. Capture the issue number from both create and update paths so
the merge job always has it available.
Also cleaned up 6 duplicate upstream-sync labels created by previous
runs that used the unprivileged token.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two fixes for the upstream-sync Claude workflow:
1. Add Bun install + bun install (deps) steps before Claude runs,
so tsc, prettier, and other devDependencies are available.
Previously node_modules/.bin/ didn't exist and typecheck/format
commands failed with "command not found".
2. Add Bash(bunx:*), Bash(npx:*), Bash(./node_modules/.bin/*:*)
to allowed_tools. The existing Bash(bun:*) only covers the `bun`
binary, not `bunx` which is a separate binary.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Picks up the allowed_tools fix from kcl-ci — claude.yml tag-mode
workflow now uses Bash(git:*),Bash(bun:*),Bash(curl:*) sub-patterns
instead of bare Bash, enabling auto-approval in CI.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bare `Bash` in allowed_tools makes the tool available but individual
commands still require interactive approval. In CI there's nobody to
approve, so git push, bun test, and curl all fail with
"Error: This command requires approval".
Changes:
- Switch to Bash(git:*), Bash(bun:*), Bash(curl:*) sub-patterns
- Add GITHUB_SERVER_URL env var so Claude doesn't need `export`
- Update prompt to reflect env var is pre-set
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add show_full_output: true to both claude.yml and upstream-sync.yml
- Add allowed_tools (Bash, Read, Write, etc.) to upstream-sync merge step
- Upgrade kcl-ci to v1.37.0 (defaults show_full_output and full tools)
Fixes: Claude was burning 38 turns hitting sandbox permission denials
trying to run bun test and git push during upstream sync.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New merge-upstream job: creates branch, merges upstream, runs Claude
agent mode to review, resolve conflicts, run tests, and create a PR
- Dynamic fork impact analysis: computes overlap between fork-modified
files and upstream-changed files to assess conflict risk
- Claude reviews ALL upstream changes for fork compatibility (renamed
imports, changed APIs, GitHub-only assumptions) not just conflicts
- Maintainability principle: minimize fork divergence, prefer adapters
- Remove ANTHROPIC_API_KEY (using OAuth token only)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add .forgejo/kcl-ci/ with kcl.mod, main.k, Taskfile.yaml
- claude.yml: use claude.k module (fixes #comment YAML validation error,
removes duplicate pull_request_comment trigger)
- ci.yml: add paths-ignore for kcl-ci paths, named jobs for check constants
- test-action.yml: regenerated from KCL (functionally identical)
- upstream-sync.yml: regenerated from KCL (functionally identical)
- kcl-ci-build.yml: new auto-regeneration workflow (waits for CI checks)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>