feat(passthrough): generic RewriteFileFlag - gate-safe --X-file to --X off-argv spill #97

Closed
opened 2026-06-07 04:07:42 +00:00 by coilysiren · 1 comment
Owner

Extraction candidate from the coily cmd/coily/ generic-code audit (2026-06-06). Source pinned at coily commit c7c17cb (canonical: forgejo.coilysiren.me/coilyco-bridge/coily). cli-guard is mid-refactor, so the "suggested home" below is the pre-refactor package layout - land this in whatever the post-refactor equivalent is, not necessarily the named package. The durable principle: the classifiers / argv-transforms are generic and move; the policy decisions and message copy stay in coily.

Sources (one pattern, multiple copies):

  • cmd/coily/mcporter_rewrite.go - rewrites --args-file <path> -> --args <json-content>.
  • cmd/coily/gh_jq_inline.go (splitGHJQFlag, spillJQExpr) + rewriteJQFile in gh_rest_rewrite.go - spills inline --jq <expr>/-q to a temp --jq-file <path> before the metachar gate, expands it back after.
  • denial_reason.go enumerates a third instance (--change-batch).

What it does: the same security primitive in three places - route a metachar-heavy flag value off-argv past the shell-metachar gate (read the file named by --X-file, inline its trimmed contents under --X), so JSON/jq metacharacters don't trip the gate.

Proposal: one generic RewriteFileFlag(argv, fileFlag, targetFlag string) (plus the temp-spill + cleanup counterpart for the inline->file direction) that subsumes the mcporter, gh-jq, and change-batch cases.

Consumer seams to parameterize: the flag-name pairs; the temp-file name prefix; the command-position start index (coily's opsGHArgStart/ops gh hardcode).

Suggested home (pre-refactor): passthrough (it owns the metachar-gate boundary).

Done when:

  • generic logic lives in cli-guard with zero coily/Kai/Forgejo identifiers or defaults
  • behavior-covered tests (table tests where the source has them)
  • godoc-current.txt regenerated (scripts/check-godoc-current.sh --update)
  • coily migrated onto the extracted API, its local copy deleted, make test green both sides
  • closes this issue

Note: the gh-jq half lives next to the GitHub-specific gh_rest_rewrite.go (deliberately not extracted, too gh-specific) - lift only the generic file-flag-spill mechanism, not the gh REST rewriting.

> Extraction candidate from the coily `cmd/coily/` generic-code audit (2026-06-06). Source pinned at coily commit `c7c17cb` (canonical: `forgejo.coilysiren.me/coilyco-bridge/coily`). **cli-guard is mid-refactor**, so the "suggested home" below is the pre-refactor package layout - land this in whatever the post-refactor equivalent is, not necessarily the named package. The durable principle: **the classifiers / argv-transforms are generic and move; the policy decisions and message copy stay in coily.** **Sources (one pattern, multiple copies):** - `cmd/coily/mcporter_rewrite.go` - rewrites `--args-file <path>` -> `--args <json-content>`. - `cmd/coily/gh_jq_inline.go` (`splitGHJQFlag`, `spillJQExpr`) + `rewriteJQFile` in `gh_rest_rewrite.go` - spills inline `--jq <expr>`/`-q` to a temp `--jq-file <path>` before the metachar gate, expands it back after. - `denial_reason.go` enumerates a third instance (`--change-batch`). **What it does:** the same security primitive in three places - route a metachar-heavy flag value off-argv past the shell-metachar gate (read the file named by `--X-file`, inline its trimmed contents under `--X`), so JSON/jq metacharacters don't trip the gate. **Proposal:** one generic `RewriteFileFlag(argv, fileFlag, targetFlag string)` (plus the temp-spill + cleanup counterpart for the inline->file direction) that subsumes the mcporter, gh-jq, and change-batch cases. **Consumer seams to parameterize:** the flag-name pairs; the temp-file name prefix; the command-position start index (coily's `opsGHArgStart`/`ops gh` hardcode). **Suggested home (pre-refactor):** `passthrough` (it owns the metachar-gate boundary). **Done when:** - [ ] generic logic lives in cli-guard with zero coily/Kai/Forgejo identifiers or defaults - [ ] behavior-covered tests (table tests where the source has them) - [ ] `godoc-current.txt` regenerated (`scripts/check-godoc-current.sh --update`) - [ ] coily migrated onto the extracted API, its local copy deleted, `make test` green both sides - [ ] `closes` this issue **Note:** the gh-jq half lives next to the GitHub-specific `gh_rest_rewrite.go` (deliberately *not* extracted, too gh-specific) - lift only the generic file-flag-spill mechanism, not the gh REST rewriting.
Author
Owner

Backlog burndown 2026-06-17: closing low-priority (P3/P4) to bring the open count to a manageable level. Nothing lost — reopen if this resurfaces. Batch tag: burndown-2026-06.

Backlog burndown 2026-06-17: closing low-priority (P3/P4) to bring the open count to a manageable level. Nothing lost — reopen if this resurfaces. Batch tag: `burndown-2026-06`.
coilysiren 2026-06-17 08:23:22 +00:00
Sign in to join this conversation.
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
coilyco-flight-deck/cli-guard#97
No description provided.