Skip to content

Address final attachment review feedback - #14262

Merged
BagToad merged 2 commits into
bagtoad/update-gh-skillfrom
bagtoad/sturdy-funicular
Aug 25, 2026
Merged

Address final attachment review feedback#14262
BagToad merged 2 commits into
bagtoad/update-gh-skillfrom
bagtoad/sturdy-funicular

Conversation

@BagToad

@BagToad BagToad commented Aug 25, 2026

Copy link
Copy Markdown
Member

Related review feedback:

Description

Two non-blocking review comments arrived after the final attachment stack layers were approved. Numeric Retry-After values did not name their unit, and the installable gh skill did not explain how attachment paths are resolved.

This adds a seconds suffix only when Retry-After is numeric, preserving valid HTTP-date values unchanged. It also documents that --attach paths and local Markdown destinations may be absolute or relative to the directory where gh runs.

How did you test this change?

Given an upload response with Retry-After: 120
When gh renders the rate-limit error
Then it says retry after 120 seconds

Given the header contains an HTTP date
When gh renders the rate-limit error
Then it preserves the date without adding a unit

I also previewed the installable skill package with gh skill publish --dry-run ..

Key points

  • Numeric retry windows gain an explicit unit without changing the empty-header or HTTP-date cases.
  • The path guidance matches the existing absolute-path normalization used for attachment arguments and Markdown destinations.
  • Each review thread has its own commit.

Notes for reviewers

Review the commits in order:

  1. Clarify rate limit retry units updates the error and its existing table coverage.
  2. Document attachment path resolution updates the installable skill.

Authorship and follow-up

Who wrote this:

  • A human wrote it.
  • An agent wrote it under close human direction.
  • An agent wrote it independently, and no human has guided the implementation beyond the initial prompt.

Who answers review comments:

  • @BagToad will read and reply directly. Name the account.
  • An agent will draft replies and @username will read them before they are posted.
  • Nobody has explicitly committed to replying.

BagToad and others added 2 commits August 25, 2026 15:09
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@BagToad
BagToad requested a review from a team as a code owner August 25, 2026 21:13
@BagToad
BagToad requested review from tidy-dev and removed request for a team August 25, 2026 21:13
@BagToad BagToad changed the title bagtoad/sturdy funicular Address final attachment review feedback Aug 25, 2026
@BagToad
BagToad merged commit cc83172 into trunk Aug 25, 2026
25 checks passed
@BagToad
BagToad deleted the bagtoad/sturdy-funicular branch August 25, 2026 21:30
@BagToad BagToad mentioned this pull request Aug 25, 2026
AceHack added a commit to Lucent-Financial-Group/Zeta that referenced this pull request Aug 26, 2026
…act the person authored (#15619)

* book(consent): GitHub-review sign-off — the ledger row cites an artifact the person authored

`CONSENT-LEDGER.md` records consent as prose, and most rows are honestly
labelled "relayed by Aaron". A row that says Aaron says they said yes has no
artifact under it, and a row that said yes to text which has since changed is
worse than no row: it looks like a live permission and covers a sentence nobody
agreed to. Both are the vacuity class applied to consent.

The property enforced: they produced the artifact with a credential they
control, and verification does not route through Aaron. A grant cites a GitHub
pull-request review; the audit re-fetches it and requires it to exist, be
APPROVED, and be authored by the declared account — matched on the numeric user
id as well as the login, because a deleted login can be re-registered and the id
never is.

Consent is given to TEXT, not to a name, so a grant also carries the sha256 of
the passage between `<!-- consent:begin/end -->` markers. A one-character edit
goes STALE and refuses publication. Branch protection's dismiss-stale-reviews
covers only the PR's own lifetime, not an edit months after merge, which is the
case that matters during revision. A person may instead grant over their whole
footprint (spanId "*") so re-consent is a delta naming the member that moved.

Two tiers, because the maintainer draws a gradient rather than a binary: repo
drafts are public, disclosed and disputable, so gate.yml fails only on false
claims in the ledger; the publish gate in pages-deploy.yml additionally refuses
STALE text, an unclaimed named passage, and a revoked passage still present.
`mode=deidentified` is first-class — it needs no consent event and fails in both
tiers if it still contains the name, which is the maintainer's own live practice
made checkable.

Grant and revoke are asymmetric on purpose: a grant may not be "relayed" and is
refused at parse time, while a revoke may arrive on any channel. Privacy is hard
money — one-way to more privacy is free. Both events are kept; the fold is the
state, ordered by the artifact's own timestamp so no local clock enters.

Proven failing, live, against a real APPROVED review (cli/cli#14262/5024289867):
mutate one word -> STALE exit 1; bad review id -> REVIEW_MISSING exit 1; wrong
login -> REVIEW_WRONG_AUTHOR exit 1; relayed revoke -> REVOKED_PASSAGE_PRESENT
exit 1; no review source -> UNCHECKED exit 3, never 0; relayed grant -> exit 2.
42 tests, each negative paired with the positive control it mutates from.

Not a legal instrument, and section 11 says so: it proves an account clicked
Approve on that text at that time, not who holds the account or that they read
it. E-signature is the instrument; DKIM-signed email is the archival channel.

The ledger ships with an empty roster and zero events. Nobody has been asked.

Agency-Signature-Version: 1
Agent: shadow
Agent-Runtime: claude-code
Agent-Model: claude-opus-5
Credential-Identity: AceHack
Credential-Mode: shared
Human-Review: not-implied-by-credential
Human-Review-Evidence: none
Action-Mode: autonomous-fail-closed
Task: none
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

* fix(hygiene): close two check-then-use races in audit-consent-signoff

`cross-verify (check-then-use-races)` was red on this branch with two findings,
both in the file this PR adds:

  [check-then-use]    audit-consent-signoff.ts:678  existsSync -> readFileSync
  [readdir-then-stat] audit-consent-signoff.ts:239  readdirSync -> statSync

Both are TOCTTOU: between the check and the use the path can be created,
deleted, or replaced -- by a concurrent agent in this fleet, by a `git
checkout`, by a background clone -- so the answer the check returned is
already stale when the use runs. (Bishop & Dilger 1996; CWE-367.)

  - walkMarkdown now uses `readdirSync(dir, { withFileTypes: true })`, so the
    kind arrives WITH the name and the two answers cannot disagree. One
    syscall instead of two.
  - the ledger read performs the read and interprets ENOENT, rather than
    asking `existsSync` first. Same LedgerError, same message.

`existsSync` and `statSync` became unused and were dropped from the import.

Verified with the CI-exact invocation, not a bare run -- the bare whole-repo
form is red on `main` too, because CI passes a baseline:

  lint-check-then-use-file-races.ts src/Core.TypeScript --min-files 1500 \
    --baseline .../lint-check-then-use-file-races.baseline.json

  before: rc=1, naming exactly these two sites
  after:  rc=0
  tsc --noEmit: rc=0, 0 errors
  audit-consent-signoff.test.ts: 42 pass, 0 fail

The baseline is untouched -- these are removed, not grandfathered.

Resolving a failing check on another agent's branch is authored work, so this
carries my own signature rather than the branch's.

Agency-Signature-Version: 1
Agent: shadow
Agent-Runtime: claude-code
Agent-Model: claude-opus-5
Credential-Identity: AceHack
Credential-Mode: shared
Human-Review: not-implied-by-credential
Human-Review-Evidence: none
Action-Mode: autonomous-fail-closed
Task: none
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

* fix(hygiene): escape the two raw NUL bytes in the span composite key

`cross-verify (no-raw-nul-in-source)` was the last red on this branch. Line 517
built a NUL-delimited composite key using the literal byte rather than an escape.

Raw NULs read as BINARY to grep/rg, so every text audit silently SKIPS the file
-- a file that looks scanned and is not. Replaced each with the six-character
escape U+0000 (backslash-u-zero-zero-zero-zero): identical runtime value, and
the file stays searchable.

Reproduced with a control before changing anything:
  branch      -> rc=1, "audit-consent-signoff.ts:517  2 raw NUL byte(s)"
  origin/main -> rc=0

After:
  audit-no-raw-nul-in-source:    rc=0
  tsc --noEmit:                  rc=0, 0 errors
  audit-consent-signoff.test.ts: 42 pass, 0 fail

The composite key's behaviour is unchanged -- the escape and the raw byte are
the same character; only the source encoding differs.

Resolving a failing check on another agent's branch is authored work, so this
carries my own signature rather than the branch's.

Agency-Signature-Version: 1
Agent: shadow
Agent-Runtime: claude-code
Agent-Model: claude-opus-5
Credential-Identity: AceHack
Credential-Mode: shared
Human-Review: not-implied-by-credential
Human-Review-Evidence: none
Action-Mode: autonomous-fail-closed
Task: none
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
esh2n added a commit to esh2n/dotfiles that referenced this pull request Aug 30, 2026
Restyle only .wu-figure svg exports, never a .wu-shot copy that happens
to be svg too (to-md now reports a figure/shot manifest); sanitize a
diagram id and a shot's copied file name against path traversal; quote
every path attachHint interpolates into a shell command; restrict
--internal to --to github (usage error elsewhere); print the gh --attach
hint as a cd-wrapped relative command so gh actually rewrites the
Markdown references (cli/cli#14262); escape alt/caption text for the
![]() position; add coverage for the no-figure path and a gated pdf
success-path test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants