fix: unbreak label routes; source agent credentials from the runner #19

Closed
cloudcli wants to merge 1 commit from feat/runner-injected-credentials into main
Member

Fixes the root cause behind #18's agent/plan label doing nothing, and removes the need for per-org Forgejo Actions secrets.

1. The routes were unparseable (this is the actual bug)

plan.yaml, dev.yaml, test.yaml, coordinate.yaml and reflect.yaml all declared secrets: under on.workflow_call. Forgejo's parser accepts only inputs and outputs there, so every issue event produced five runs that failed before scheduling a single job:

preExecutionError: Unable to parse supported events in workflow:
invalid value on key "workflow_call": workflow_call only supports keys
"inputs" and "outputs", but key "secrets" was found

(Observed on runs 628–632 and 634–638 in this repo; dispatch.yaml never had the block, which is why routing looked healthy.) The declaration is removed — secrets: inherit at the call sites is what actually passes secrets.

2. Credentials now come from the runner

Previously every org needed its own CLAUDE_CODE_OAUTH_TOKEN / CLAUDE_PLAN_PAT / CLAUDE_DEV_PAT / LITELLM_KEY. valssi-ai had them, valssi-public did not.

New composite action lib/credentials resolves each credential in this order:

  1. the Forgejo Actions secret, passed in as an input — a per-org override;
  2. the environment variable the runner injected into the job container.

and exports TOKEN, CLAUDE_CODE_OAUTH_TOKEN, LITELLM_KEY to $GITHUB_ENV. dispatch's tick needs both PATs at once and overrides the export name via export-as.

The job-level env: mappings are deleted rather than reordered: ${{ secrets.X }} evaluates to the empty string in an org without that secret, which would shadow the injected value with nothing.

lib/preflight now fails fast on an empty token. Previously an unreadable label list would sail past the ai/off kill switch and fail obscurely deep in the route.

Ordering

Merge order does not matter — the fallback covers both directions:

  • merged before the runner redeploy: orgs with secrets (valssi-ai) keep working; valssi-public still can't run until the runner ships.
  • runner redeployed first: nothing changes until this merges.

Once both are in, the org secrets under valssi-ai → Settings → Actions → Secrets can be deleted.

Org variables are still per-org and still required — AGENTS_ENABLED must be exactly true or preflight no-ops green and leaves no trace on the issue at all.

Companion PRs

  • valssi-ai/forgejo-ai-dev-runner — renders the credentials into the job containers
  • valssi/komodo-resource-sync — passes them to the prod and dev runner stacks

Needs a manual Komodo apply after the two land.

🤖 Generated with Claude Code

Fixes the root cause behind #18's `agent/plan` label doing nothing, and removes the need for per-org Forgejo Actions secrets. ## 1. The routes were unparseable (this is the actual bug) `plan.yaml`, `dev.yaml`, `test.yaml`, `coordinate.yaml` and `reflect.yaml` all declared `secrets:` under `on.workflow_call`. Forgejo's parser accepts only `inputs` and `outputs` there, so every issue event produced five runs that failed before scheduling a single job: ``` preExecutionError: Unable to parse supported events in workflow: invalid value on key "workflow_call": workflow_call only supports keys "inputs" and "outputs", but key "secrets" was found ``` (Observed on runs 628–632 and 634–638 in this repo; `dispatch.yaml` never had the block, which is why routing looked healthy.) The declaration is removed — `secrets: inherit` at the call sites is what actually passes secrets. ## 2. Credentials now come from the runner Previously every org needed its own `CLAUDE_CODE_OAUTH_TOKEN` / `CLAUDE_PLAN_PAT` / `CLAUDE_DEV_PAT` / `LITELLM_KEY`. `valssi-ai` had them, `valssi-public` did not. New composite action `lib/credentials` resolves each credential in this order: 1. the Forgejo Actions secret, passed in as an input — a per-org override; 2. the environment variable the runner injected into the job container. and exports `TOKEN`, `CLAUDE_CODE_OAUTH_TOKEN`, `LITELLM_KEY` to `$GITHUB_ENV`. `dispatch`'s `tick` needs both PATs at once and overrides the export name via `export-as`. The job-level `env:` mappings are deleted rather than reordered: `${{ secrets.X }}` evaluates to the empty string in an org without that secret, which would shadow the injected value with nothing. `lib/preflight` now fails fast on an empty token. Previously an unreadable label list would sail past the `ai/off` kill switch and fail obscurely deep in the route. ## Ordering Merge order does not matter — the fallback covers both directions: - merged before the runner redeploy: orgs with secrets (valssi-ai) keep working; valssi-public still can't run until the runner ships. - runner redeployed first: nothing changes until this merges. Once both are in, the org secrets under `valssi-ai` → Settings → Actions → Secrets can be deleted. Org **variables** are still per-org and still required — `AGENTS_ENABLED` must be exactly `true` or preflight no-ops green and leaves no trace on the issue at all. ## Companion PRs - `valssi-ai/forgejo-ai-dev-runner` — renders the credentials into the job containers - `valssi/komodo-resource-sync` — passes them to the prod and dev runner stacks Needs a manual Komodo apply after the two land. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix: unbreak label routes and source agent credentials from the runner
All checks were successful
agent / tick (pull_request) Has been skipped
agent / resolve (pull_request) Successful in 15s
agent / dev (pull_request) Has been skipped
agent / implement (pull_request) Successful in 0s
agent / dev-bounce (pull_request) Successful in 0s
agent / dispatch (pull_request) Successful in 0s
agent / plan (pull_request) Successful in 0s
agent / test (pull_request) Successful in 0s
agent / coordinate (pull_request) Successful in 0s
agent / reflect (pull_request) Successful in 0s
aebdf0fa0b
Two independent defects kept `agent/plan` (and every other route) from ever
running:

1. plan/dev/test/coordinate/reflect declared `secrets:` under
   `on.workflow_call`. Forgejo's parser accepts only `inputs` and `outputs`
   there, so all five files were unparseable — every issue event produced five
   runs that failed with `preExecutionError: workflow_call only supports keys
   "inputs" and "outputs", but key "secrets" was found` and zero jobs. Removed;
   `secrets: inherit` at the call sites is what actually passes them.

2. Credentials had to be duplicated as Forgejo Actions secrets in every org.
   They now live only in Komodo, which injects them into every job container via
   the runner. New composite action `lib/credentials` resolves each one — org
   secret first (per-org override), runner-injected env second — and exports
   TOKEN / CLAUDE_CODE_OAUTH_TOKEN / LITELLM_KEY to $GITHUB_ENV. The job-level
   `env:` mappings are gone: `${{ secrets.X }}` is the empty string in an org
   without that secret, which would shadow the injected value.

preflight now fails fast on an empty token instead of sailing past the kill
switch with unreadable labels.

Requires forgejo-ai-dev-runner to be redeployed with the new Komodo secret
variables before the org secrets can be removed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ellen closed this pull request 2026-07-28 20:48:19 +00:00
All checks were successful
agent / tick (pull_request) Has been skipped
agent / resolve (pull_request) Successful in 15s
agent / dev (pull_request) Has been skipped
agent / implement (pull_request) Successful in 0s
agent / dev-bounce (pull_request) Successful in 0s
agent / dispatch (pull_request) Successful in 0s
agent / plan (pull_request) Successful in 0s
agent / test (pull_request) Successful in 0s
agent / coordinate (pull_request) Successful in 0s
agent / reflect (pull_request) Successful in 0s

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
valssi-public/agent-workflows!19
No description provided.