gh shim: typed -F field=@file on governed api writes reads the file
A governed gh api comment edit with a typed file field, gh api -X PATCH repos/<o>/<r>/issues/comments/<id> -F body=@/tmp/file.md, posted the literal text @/tmp/file.md as the comment body, replacing real comments (reported by MC on cortexkit/magic-context).
- Cause: a legacy own-comment PATCH decoder (
own_comment_patch_payload/api_payload_argumentin gh_shim.rs) treated typed-Fand raw-ffields the same, so it never read@file. The shared REST payload parser already read it correctly. - Fix: that duplicate decoder is gone, and legacy PATCH goes through the shared parser. Typed fields follow upstream gh (cli/cli pkg/cmd/api/fields.go and iostreams.go):
@pathreads the file,@-reads stdin, and file contents aren't retyped. Raw-f body=@literalstays literal. For prose-only governed fields, a typed scalar (true,false,null, an integer) is refused by field name instead of being stringified. Unrepresentable mixes (--inputplus fields, typed{owner}placeholders, repeated typed@-) are refused before anything is sent. - Refusal text: existing texts reused:
could not read body file {path}: {error}andcould not read body from stdin: {error}. - Audit: every governed REST/GraphQL row and every governed CLI body or file flag is inventoried with coverage. Real-binary relay goldens now cover PATCH and POST with typed file and stdin fields, raw fields, missing or unreadable files, JSON input, scalar refusal and mixed-input refusal, plus file, stdin and missing-file cases for seven governed CLI body commands.
--jqon governed writes stays unsupported. Upstream filters locally with embedded gojq, so matching it is a separate job.
A test-only commit reproduces the corruption first (the golden showed the literal path as the body). Verified on the build server: 548 gh_shim library tests, 101 serial gh_shim end-to-end tests, and the Windows target check.
Summary by cubic
A governed gh api write with a typed file field now reads the file, so a comment edit like -F body=@/tmp/file.md posts the file contents instead of the literal path. The duplicate legacy comment-PATCH decoder that treated -F and -f identically is removed; those writes go through the shared REST payload parser.
Typed-field behavior now matches upstream gh
- Typed fields read
@pathfiles and@-stdin;-fstays literal, and file contents aren't retyped. - Typed scalars (
true,false,null, integers) on prose-only fields are refused rather than stringified. --inputcombined with fields, typed{owner}-style placeholders, and repeated@-are refused before anything is sent.- Stack
pull_requests[]accepts only typed JSON integers; string numbers now refuse instead of being silently coerced.