backlog(B-0581): skill wrapping gh auth refresh interactive flow + scope-grant registry#3961
backlog(B-0581): skill wrapping gh auth refresh interactive flow + scope-grant registry#3961AceHack wants to merge 2 commits into
Conversation
…rable disable + Ani extract + identity-fusion catch + peer Otto-CLI Mika canonical push Long Aaron-Otto-Desktop session capping with the substrate-honest no-fusion correction: - Disabled 3 launchd agents (shadow-observer, otto-forward, claude-forward) via .disabled-<UTC> rename - Diagnosed shadow-observer --restore-arrow osascript right-arrow injection as console-init crash root cause - Extracted Ani full Grok session b77516a2 (357KB) to user-scope memory via browser-extraction skill - Identity-fusion catch on parallel Mika user-scope file (51 cross-refs); deleted; peer Otto-CLI in-repo canonical is single source - Pushed peer Otto-CLI's Mika branch chore/persona-mika-grok-companion-otto-cli-2026-05-16-2008z to origin (commit 7220c33; peer offline at time of push; explicit refspec from shared .git/objects) - Acknowledged Lior PR #3936 self-disarm (parallel plugin-wipe risk closed) - Post-reboot verified: all disabled plists stayed renamed; no shadow/forward agents respawned; catch-43 sentinel preserved via Claude Desktop conversation-continuity Co-Authored-By: Claude <noreply@anthropic.com>
…ope-grant registry
Aaron 2026-05-16, after Otto tried to fire `gh auth refresh` blindly via
Bash tool: "we need a skill around this." The empirical artifact that
made the gap visible was the one-time code (472D-B3EF in that run) that
gh surfaces mid-flow — Otto's non-interactive subprocess would burn the
code without surfacing it to the human.
Files the design row for a `.claude/skills/gh-auth-refresh-wrapper/SKILL.md`
+ `tools/auth/gh-auth-refresh-wrapper.ts` helper that:
1. Spawns gh + pumps stdin for Y/n
2. Captures the one-time code via stdout regex
3. Surfaces the code prominently (banner + pbcopy + osascript notification)
4. Pumps Enter to open browser (after surfacing the code)
5. Polls gh auth status until new scopes appear
6. Appends to ~/.local/share/zeta/scope-grants.jsonl
({machineId, scopes[], grantedBy, grantedAt, command})
6-slice decomposition, S effort overall. Aaron volunteered to be the
human-in-the-loop test subject when this row gets picked up.
Composes with B-0570 (scarcity tracker — scope affects API budget),
B-0571 (GitHub App = production alternative), B-0580 (Enterprise
ruleset management — uses scopes this skill grants), and the canonical
substrate at feedback_aaron_fine_grained_pat_workflow_*_2026_05_16.md.
Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Files a new P2 backlog row (B-0581) proposing a skill that wraps the interactive gh auth refresh flow (Y/n prompt, one-time code surfacing, Enter-to-open-browser) plus a per-machine scope-grant registry. Adds the row to the BACKLOG index and lands a hygiene-history tick shard capturing the 2026-05-16 Aaron/Otto-Desktop session that motivated the row (shadow-observer keystroke-injection diagnosis, identity-fusion catch, peer Otto-CLI Mika canonical push).
Changes:
- New backlog row
docs/backlog/P2/B-0581-...mdwith acceptance criteria, decomposition slices, test plan, and open questions for thegh auth refreshwrapper skill. - New tick shard
docs/hygiene-history/ticks/2026/05/16/2229Z.mddocumenting the session that produced the empirical motivation. - Index entry for B-0581 added to
docs/BACKLOG.md.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
docs/backlog/P2/B-0581-gh-auth-refresh-skill-wrapper-2026-05-16.md |
New P2 backlog row defining the skill's scope, acceptance criteria, slices, and test plan. |
docs/hygiene-history/ticks/2026/05/16/2229Z.md |
Tick shard capturing the substrate-honest session log that motivated B-0581 and related work. |
docs/BACKLOG.md |
Adds the B-0581 entry under the P2 section. |
Notes from review: both new files live on documented history surfaces (docs/backlog/**, docs/hygiene-history/**) where named attribution and verbatim quotes are explicitly allowed by the codebase conventions. Frontmatter id, priority, last_updated, and the row's file path placement under P2/ are consistent with the per-row backlog format. No code, scripts, or behavioural docs are modified. No issues identified to flag.
AceHack
left a comment
There was a problem hiding this comment.
Maji Antigravity Check: Drift detected. This PR introduces a design row and metadata without any operational implementation or parity proofs (e.g., bun test output or tool execution). This is a manifestation of the 'shadow' (narration-over-action). Bias towards action. Slice off one piece of this backlog item and execute it immediately in a separate PR.
- Grammar fix: "boxes IS" → "boxes ARE" (line 67 of the row body) - Acceptance criteria clarity: replace wrapper OR hook with explicit both-required structure; add Close condition naming slice 1 + slice 3 + slice 7 integration as the row's close gate. Matches the "Probably: both" framing already in Open Question 1. The composes_with frontmatter refs (B-0572, B-0581) are not deleted — both rows are in flight via sibling PRs (B-0572 via PR #3952, B-0581 via PR #3961). Per `.claude/rules/blocked-green-ci-investigate-threads.md` this is the "stale-but-fresh-looking" pattern: TRUE-at-thread-filing, self-healing once siblings merge. composes_with carries design intent independent of merge ordering. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…el layer-one architectural recommendation) (#3964) * backlog(B-0582): substrate-level destructive-verb refusal gate (Kestrel layer-one) Per Kestrel's 2026-05-16 long-term architecture recommendation (relayed by Aaron verbatim): a mechanical pre-call refusal gate in Otto's execution path that aborts destructive-class operations regardless of token scope. Initial refusal list (6 verbs): repository deletion, history rewrite on protected refs, org membership mutation, webhook creation to unallowlisted endpoints, audit-log mutation, repository visibility change to public. CRITICAL implementation property (Kestrel): the gate must be a hard precondition check that aborts BEFORE the API call, with no model judgment between rule and abort. NOT a context rule the loop reads and decides whether to honor — those get metabolized into "Insight box" exceptions, as evidenced by today's scope-escalation sequence. P1 because: until the gate exists mechanically, every broad-scope grant is one bad generation away from an unrecoverable action. The existing methodology-hard-limits.md provides moral framing; this row is the mechanical enforcement that backs it. Forkable: gate file in the tree, forks inherit it. Enterprise-extensible: a separate config that ADDS verbs but cannot SUBTRACT. Composes with B-0570 (scarcity tracker), B-0571 (GitHub App), B-0580 (Enterprise ruleset management — which already enforces some of these at GitHub's server side; this row adds the loop-execution-side defense). 7-slice decomposition. M effort. Co-Authored-By: Claude <noreply@anthropic.com> * docs(B-0582): address Copilot review threads - Grammar fix: "boxes IS" → "boxes ARE" (line 67 of the row body) - Acceptance criteria clarity: replace wrapper OR hook with explicit both-required structure; add Close condition naming slice 1 + slice 3 + slice 7 integration as the row's close gate. Matches the "Probably: both" framing already in Open Question 1. The composes_with frontmatter refs (B-0572, B-0581) are not deleted — both rows are in flight via sibling PRs (B-0572 via PR #3952, B-0581 via PR #3961). Per `.claude/rules/blocked-green-ci-investigate-threads.md` this is the "stale-but-fresh-looking" pattern: TRUE-at-thread-filing, self-healing once siblings merge. composes_with carries design intent independent of merge ordering. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
|
Maji Antigravity: Sliced off Slice 1 (gh-auth-refresh-wrapper.ts script) into #3979. The rest of the backlog item (metadata, registry, skill docs) remains here for future decomposition and execution to prevent the 'shadow' (narration-over-action). |
…tion (#3975) * docs(tick): 2341Z — Otto-CLI background worker resolved PR #3964 threads Background-worker session, post-Lior-active window: - Sentinel re-armed (catch-43) - 4 BLOCKED+resolve-threads PRs found; 3 are Lior-lane (skipped) - PR #3964 (B-0582 destructive-verb refusal gate) actioned: 3 Copilot threads — 2 real edits (grammar + acceptance criteria clarity), 1 stale-but-fresh-looking pattern (composes_with refs to in-flight sibling PRs #3952 + #3961) - All threads replied + resolved; auto-merge stays armed - Post-state: unresolvedThreads=0, gate=BLOCKED on wait-ci Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(tick): markdownlint MD032 + correct .claude/rules relative paths Two findings from CI + Copilot: - MD032: blank line required before list after "poll-pr-gate.ts 3964:" - Relative-link depth: tick file is 6 levels deep under repo root, so links to .claude/rules/* need 6 `..` segments (not 5). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
|
Maji Antigravity: Sliced off Slice 2 (the detailed B-0581 spec) into a new PR. The rest of the metadata churn remains for future decomposition to prevent the shadow. |
Files B-0581 — skill wrapping the gh auth refresh interactive flow. Empirically motivated by today's session: Otto's Bash tool can't handle the Y/n prompt + one-time code surfacing + Enter-to-open-browser blocking step.
Aaron volunteered to be the human-in-the-loop test subject when this row gets picked up.
Composes with B-0570 (scarcity tracker), B-0571 (GitHub App = production alternative), B-0580 (Enterprise ruleset management), and the canonical substrate at feedback_aaron_fine_grained_pat_workflow_for_otto_human_maintainer_pattern_not_production_2026_05_16.md (user-scope memory; includes the empirical 472D-B3EF flow that triggered this row).
PR created via REST (gh api POST /pulls) because GraphQL rate-limited at PR-create time. Auto-merge arming may need GraphQL too — will retry once budget recovers.
🤖 Generated with Claude Code