Skip to content

✨ [feat] install: guard hooks and permissions for Antigravity (agy) - #82

Draft
danielegaleazzi92 wants to merge 4 commits into
EricTechPro:mainfrom
danielegaleazzi92:feat/agy-install
Draft

danielegaleazzi92 wants to merge 4 commits into
EricTechPro:mainfrom
danielegaleazzi92:feat/agy-install

Conversation

@danielegaleazzi92

@danielegaleazzi92 danielegaleazzi92 commented Oct 23, 2026 •

Copy link
Copy Markdown

Note

⏳ Draft · slice 2 of #80 (Antigravity host) · stacked on #81: merge it first, the diff shows both until then

Problem

  • Where: install.sh, .agents/hooks.json, ~/.gemini/antigravity-cli/settings.json
    • a. install super-board in a project and open it with the Antigravity CLI (agy)
    • b. the skills are found (they live in .agents/skills/ since ♻️ [refactor] install: shared .agents/ folder with per-host links #71) but no guard hook runs: cat .env or a worktree next to the repo go through
    • c. start a headless lane: every shell command and non-workspace file write is auto-denied, because headless agy -p cannot ask and the board has written no permission rule
  • Who: anyone running the board, or just the skills, under Antigravity
  • What happened: the guards and the allowlist are Claude Code plumbing (settings.json, Bash(...) rules); Antigravity has its own dialect and nothing speaks it

Solution

  • hooks/agy-hook-adapter.py: translates an Antigravity PreToolUse payload (toolCall.name, toolCall.args.CommandLine / path keys, workspacePaths) into Claude's {tool_name, tool_input}, runs the guards settings-snippet.json would run for that tool, and answers {decision, reason}. The guards stay the single copy of every rule; no objection answers ask for commands and allow for workspace files, so Antigravity's own permission check still runs
  • hooks/agy-hooks.json: the super-board-guards entry (run_command, the file tools) running hooks/agy-hook-adapter.py relative to .agents/, which is the cwd Antigravity gives its hooks
  • install.sh --hosts agy: no folder of links (Antigravity reads .agents/ itself); merges the entry into .agents/hooks.json keeping other entries, adds --protect-push with --protect-main and keeps it on a later install, writes python instead of python3 on Windows (hooks run under cmd /c, where python3 is a Store alias), detects the host from a config host key, super-board-host.sh or an existing entry, and names the permissions step. The adapter is not counted as a guard
  • scripts/super-board-agy-permissions.py: reads the agy settings BOM-tolerant and rewrites them without one (agy 1.4.6 writes a BOM into its own file and then loads permissions=<nil>: every tool denied); writes the rules a headless lane needs into the agy settings file: by default command(*), read_file(*), write_file(*) plus deny rules for the dangerous forms (force pushes, gh repo delete, gh auth, rm -rf /, --dangerously-skip-permissions) and the secret paths (.env, ~/.ssh, ~/.gemini, ~/.gitconfig*, ~/.aws, ~/.config/gh); --from-allowlist converts the board's Claude allowlist to command(regex:(?s)<prefix>(\s.*)?) rules instead; --add, dry run by default, --apply with a backup, invalid JSON left untouched
  • Docs: install.sh header, CLAUDE.md installation contract, the scripts' docstrings. docs/hosts.md is ✨ [feat] host: detect Google Antigravity (agy) as a host #81's

Acceptance criteria

  • cat .env, rm -rf /, a worktree outside .claude/worktrees/, a key literal in a write are denied through the adapter; git status and a workspace write pass; the push guard only with --protect-push
    ↳ verified: tests/test-agy-hook-adapter.sh (21 checks), and live on agy 1.4.6: git worktree add ../elsewhere answered BLOCKED: tool call denied by pre-tool hook: Blocked: worktree path "../elsewhere" resolves to … outside …\.claude\worktrees/, no worktree created
  • install.sh --hosts agy --protect-main writes the entry with --protect-push, keeps my-hook, creates no .agy/, counts 6 guard hooks; a plain re-install keeps the push guard; a config host: "agy" wires it; a plain install writes no hooks.json
    ↳ verified: tests/test-install.sh scenario 25 (run on its own on Windows: the suite's symlink scenarios cannot run there)
  • The permissions helper offers the lane profile, applies it once with a backup and no duplicates, keeps other keys, converts Bash(gh pr view:*) to a regex rule with --from-allowlist, refuses a malformed --add (64) and an invalid file (2)
    ↳ verified: tests/test-agy-permissions.sh (6 scenarios)
  • End-to-end with this stack installed from the branches (install.sh --hosts agy --protect-main), agy 1.4.6 / gemini-3.8-flash on Windows 11, 2026-10-23: card feat: dynamic-workflow worker backend (worker_backend: "workflow") #3 of the playground went Ready → Done, ✨ [feat] cart: clearCart empties the cart and drops its discount danielegaleazzi92/super-board-agy-playground#4 (squash cc1b8ef), Build 8.5 min, QA + Review 19 min, every lane returning a valid structured result. The one lane that failed in between was denied on its first command because agy had rewritten its own settings file with a UTF-8 BOM and loaded no permissions from it; the helper now strips it (✨ [feat] install: guard hooks and permissions for Antigravity (agy) #82).
  • Why command(*) + deny rules and not a prefix allowlist: on agy 1.4.6 / Windows the rules match exactly, and a lane improvised a ;-chain, a multi-line python -c, a here-string and a mktemp write in four successive runs, each auto-denied; with this profile and the hooks a card went Ready → Done (✨ [feat] host: run the board on Google Antigravity (agy) #80, evidence link)

Iteration history

Lane Done Time Details
🔨 author ✅ Oct 23 adapter + hooks.json + installer + permissions helper · three suites green on Git Bash

Risk

🟡 Medium · security plumbing, additive.

  • Door: two-way · revert and .agents/hooks.json entries written by it stay inert (the adapter file is gone, the hook fails closed: remove the entry too)
  • Blast radius: projects installed with --hosts agy (new behaviour) · install.sh host parsing and the hook count for every host (covered by the existing suite) · the agy settings file only when the user runs the helper with --apply

Part of #80 (slice 2 of 4), stacked on #81.

🤖 Generated with Claude Code

danielegaleazzi92 and others added 3 commits October 23, 2026 17:52
…g host

- super-board-host.sh answers agy on ANTIGRAVITY_AGENT=1 (observed on agy 1.4.6), after the Codex ids and OPENCODE, before CLAUDECODE; SUPER_BOARD_HOST and config host take agy
- setup check accepts host agy; schema, onboard and run-workflow name it (no lane backend yet: the run halts like opencode)
- docs/hosts.md: agy row, detection step and env evidence; tests for the sign, the override, the config key and the empty/id-only cases

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…vity (--hosts agy)

- hooks/agy-hook-adapter.py translates Antigravity PreToolUse payloads, runs the unchanged guard-*.py and answers deny/ask/allow; hooks/agy-hooks.json wires it
- install.sh --hosts agy: entry merged into .agents/hooks.json (other entries kept, --protect-push with --protect-main and kept on re-install, python on Windows), host detected from config/host.sh/an existing entry, no link folder, adapter not counted as a guard
- scripts/super-board-agy-permissions.py writes the lane profile (command/read_file/write_file * + deny rules for dangerous forms and secret paths) or --from-allowlist regex rules; dry run, --apply with backup
- tests: test-agy-hook-adapter.sh, test-agy-permissions.sh, test-install.sh scenario 25; CLAUDE.md install contract

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- the agy install line names it, the SCRIPTS list did not carry it

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ithout one

- agy 1.4.6 rewrites its settings.json with a UTF-8 BOM and then loads permissions=<nil>: every lane tool call denied until the file is rewritten; --apply now strips it (test 7)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

1 participant