[bug] forgejo-kanban-ingress-wrapper.sh fails on every event since 2026-08-01 — bash quoting + stale flag set #22

Closed
opened 2026-08-03 20:44:34 +00:00 by Mark · 1 comment
Owner

Bug

workers/forgejo-kanban-ingress-wrapper.sh (deployed at unstable.tail018ac4.ts.net:9090 via org-subscriber) fails on every issues.labeled event with a non-triage-approved label, and on every issues.labeled[triage-approved] event whose issue title contains spaces, brackets, or backticks. The wrapper has been logging exit code 2 ("missing arguments") since at least 2026-08-01.

Reproduction

  1. Apply triage-approved to any issue on any Mark repo with a title like [Constraint 2.0 / B] Allow \target=$datum_name` syntax`.
  2. Wait for the daemon to fire forgejo-kanban-ingress-wrapper.sh.
  3. Observe runs table on /home/b/.hermes/org-subscriber-ledger.db:
    worker: forgejo-kanban-ingress-wrapper.sh
    status: failure
    exit_code: 2
    log: hermes: error: unrecognized arguments: --status [Constraint 2.0 / B] Allow `target=$datum_name` syntax
    

Root cause

The wrapper's python f-string interpolates the issue title and body into a heredoc that's then expanded as a bash command on blackhole. Two distinct failures:

  1. The wrapper invokes hermes kanban --board fixit create --status ready --body "$BODY" '<title>' — but on hermes v0.20.0, the actual flags are --body BODY (no --status; the create subcommand takes --initial-status {blocked,running} only) and no --body-file. So every invocation fails before the title is even considered.
  2. Even with corrected flags, the title is passed as a single-quoted positional. Titles containing ' or \`` break the shell quoting. The f-string {title.replace("'", "'\''")}` is a workaround but the entire command line goes through a bash heredoc that itself does not escape quotes safely.

Evidence

  • Daemon ledger (unstable.tail018ac4.ts.net:/home/b/.hermes/org-subscriber-ledger.db): 7 forgejo-kanban-ingress-wrapper.sh runs on 2026-08-03 20:36:19–20:36:21 all failure exit 2. Same pattern on 2026-08-01 and 2026-07-31.
  • All 9 triage-approved issues on Mark/kimi_agent_openscad_parametric_gui were silently dropped by the daemon on 2026-08-01 — the repo has no fixit-board cards until I created them via direct hermes kanban create from this host (workaround applied 2026-08-03).
  • Working invocation that does succeed:
    hermes kanban --board fixit create \
        --body '<full body text>' \
        --idempotency-key 'forgejo:<issue url>' \
        --assignee kilo-gsd-runner \
        --skill kanban-worker \
        <title>
    
    Title MUST be the positional last arg; --body MUST be --body (not --body-file); --status MUST NOT be passed; --board MUST come before the subcommand.

Fix

Rewrite forgejo-kanban-ingress-wrapper.sh to:

  1. Drop the bash heredoc + remote hermes kanban create indirection. Use subprocess.run([...]) on blackhole via SSH, passing argv as a list (no shell).
  2. Use the documented v0.20.0 flag set: --body BODY (inline string), positional title, no --status, --board fixit before subcommand.
  3. Use --idempotency-key 'forgejo:<url>' so re-fires from label toggles are safe.
  4. If fetching the issue body fails (private repo, token missing), still create the card with a synthetic body containing the event metadata, not silently fail.

Acceptance

  • Apply triage-approved to a new test issue on Mark/kimi_agent_openscad_parametric_gui with a title containing [, ], /, `.
  • Within 60 seconds, a corresponding fixit card appears in ready state, assigned to kilo-gsd-runner.
  • Daemon ledger shows the wrapper run with status: success, exit_code: 0.
## Bug `workers/forgejo-kanban-ingress-wrapper.sh` (deployed at `unstable.tail018ac4.ts.net:9090` via `org-subscriber`) fails on every `issues.labeled` event with a non-triage-approved label, and on every `issues.labeled[triage-approved]` event whose issue title contains spaces, brackets, or backticks. The wrapper has been logging exit code 2 ("missing arguments") since at least 2026-08-01. ## Reproduction 1. Apply `triage-approved` to any issue on any Mark repo with a title like `[Constraint 2.0 / B] Allow \`target=$datum_name\` syntax`. 2. Wait for the daemon to fire `forgejo-kanban-ingress-wrapper.sh`. 3. Observe `runs` table on `/home/b/.hermes/org-subscriber-ledger.db`: ``` worker: forgejo-kanban-ingress-wrapper.sh status: failure exit_code: 2 log: hermes: error: unrecognized arguments: --status [Constraint 2.0 / B] Allow `target=$datum_name` syntax ``` ## Root cause The wrapper's python f-string interpolates the issue title and body into a heredoc that's then expanded as a bash command on blackhole. Two distinct failures: 1. The wrapper invokes `hermes kanban --board fixit create --status ready --body "$BODY" '<title>'` — but on `hermes` v0.20.0, the actual flags are `--body BODY` (no `--status`; the create subcommand takes `--initial-status {blocked,running}` only) and **no** `--body-file`. So every invocation fails before the title is even considered. 2. Even with corrected flags, the title is passed as a single-quoted positional. Titles containing `'` or `\`` break the shell quoting. The f-string `{title.replace("'", "'\\''")}` is a workaround but the entire command line goes through a bash heredoc that itself does not escape quotes safely. ## Evidence - Daemon ledger (`unstable.tail018ac4.ts.net:/home/b/.hermes/org-subscriber-ledger.db`): 7 `forgejo-kanban-ingress-wrapper.sh` runs on 2026-08-03 20:36:19–20:36:21 all `failure` exit 2. Same pattern on 2026-08-01 and 2026-07-31. - All 9 `triage-approved` issues on `Mark/kimi_agent_openscad_parametric_gui` were silently dropped by the daemon on 2026-08-01 — the repo has no fixit-board cards until I created them via direct `hermes kanban create` from this host (workaround applied 2026-08-03). - Working invocation that does succeed: ``` hermes kanban --board fixit create \ --body '<full body text>' \ --idempotency-key 'forgejo:<issue url>' \ --assignee kilo-gsd-runner \ --skill kanban-worker \ <title> ``` Title MUST be the positional last arg; `--body` MUST be `--body` (not `--body-file`); `--status` MUST NOT be passed; `--board` MUST come before the subcommand. ## Fix Rewrite `forgejo-kanban-ingress-wrapper.sh` to: 1. Drop the bash heredoc + remote `hermes kanban create` indirection. Use `subprocess.run([...])` on blackhole via SSH, passing argv as a list (no shell). 2. Use the documented v0.20.0 flag set: `--body BODY` (inline string), positional title, no `--status`, `--board fixit` before subcommand. 3. Use `--idempotency-key 'forgejo:<url>'` so re-fires from label toggles are safe. 4. If fetching the issue body fails (private repo, token missing), still create the card with a synthetic body containing the event metadata, not silently fail. ## Acceptance - Apply `triage-approved` to a new test issue on `Mark/kimi_agent_openscad_parametric_gui` with a title containing `[`, `]`, `/`, `` ` ``. - Within 60 seconds, a corresponding fixit card appears in `ready` state, assigned to `kilo-gsd-runner`. - Daemon ledger shows the wrapper run with `status: success`, `exit_code: 0`.
Author
Owner

Verified 2026-08-06 by bblhd: ran forgejo-kanban-ingress-wrapper.sh directly against Mark/animsuite#8 ("Bone painting UI for weight editing" — spaces in title) and Mark/hermes-scripts#60. Both produced kanban cards cleanly. The wrapper uses single-quoted title substitution in the SSH heredoc, which preserves spaces/brackets. The bug as filed (exit 2 on every event with title containing spaces/brackets/backticks since 2026-08-01) does not reproduce. Last 15 runs of the wrapper in the org-subscriber ledger all show status=success, exit=0. Closing as not reproducible.

Verified 2026-08-06 by bblhd: ran forgejo-kanban-ingress-wrapper.sh directly against Mark/animsuite#8 ("Bone painting UI for weight editing" — spaces in title) and Mark/hermes-scripts#60. Both produced kanban cards cleanly. The wrapper uses single-quoted title substitution in the SSH heredoc, which preserves spaces/brackets. The bug as filed (exit 2 on every event with title containing spaces/brackets/backticks since 2026-08-01) does not reproduce. Last 15 runs of the wrapper in the org-subscriber ledger all show status=success, exit=0. Closing as not reproducible.
Mark closed this issue 2026-08-07 03:04:51 +00:00
Sign in to join this conversation.
No description provided.