From 95acf7bde699134267bfbb3fd535504066f01649 Mon Sep 17 00:00:00 2001 From: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com> Date: Fri, 30 Oct 2026 00:14:35 +0100 Subject: [PATCH 1/9] docs(gemini-task): Gemini works independent packages in parallel The owner wants Gemini to scale out when there is work for several agents. Research against the Antigravity docs (2026-10-30): agy subagents (invoke_subagent) run concurrently, start without the parent's history, can each get an isolated Git worktree that agy deletes when they end; /teamwork builds in ~/teamwork_projects/ without branches or PRs. - Briefs mark packages independent or coupled; one start line, /gemini-task , covers every package. - Gemini as coordinator starts one subagent per independent package, at most four at a time, each in its own worktree on gemini/-, pushing and opening its draft PR before it ends; without worktree isolation it falls back to one package after another. - agy-permissions.json gains the git -C forms the owner's live settings already carry. - The 2026-10-16 forum reply is not marked as Google staff; the FAQ is the authority (skills, guardrails, gemini_review.py docstring). Co-Authored-By: Claude Opus 5.5 --- .claude/guardrails.md | 29 +++++++++--- .claude/skills/gemini-task/SKILL.md | 47 +++++++++++++++---- .../skills/gemini-task/agy-permissions.json | 37 ++++++++++++++- .claude/skills/zweitmeinung/SKILL.md | 4 +- .claude/skills/zweitmeinung/gemini_review.py | 5 +- CLAUDE.md | 2 +- changelog.d/gemini-scale-out.md | 12 +++++ 7 files changed, 113 insertions(+), 23 deletions(-) create mode 100644 changelog.d/gemini-scale-out.md diff --git a/.claude/guardrails.md b/.claude/guardrails.md index 131d58f1613..d2dac6d1ccf 100644 --- a/.claude/guardrails.md +++ b/.claude/guardrails.md @@ -30,7 +30,7 @@ work that Google's quota can do goes there first. | Subagent with bounded work inside its own worktree, verified by a command it runs | Sonnet | Cheaper for work whose result a command checks; never writes outside its worktree | | Reads or polls with credentials (CI, deploys, `gh`/`gcloud` state); creates Todoist tasks | Haiku | Cheap; never changes state | | High-risk reviews (security, prod data, sandbox, privacy); genuinely hard reasoning | Fable | About 2.5 times Opus per token at API prices, so only where it pays | -| Larger steps and long refactors, and the main driver once Claude tokens run low late in the week | Gemini, in the owner's interactive agy session, through a brief file in `~/projects/anyplot-briefs/`, one package of at most 20 to 25 files per fresh session (`/gemini-task`) | The owner decides what runs without asking; Gemini pushes a `gemini/*` branch and opens a draft PR; Claude reviews it, marks it ready, and follows it through | +| Larger steps and long refactors, and the main driver once Claude tokens run low late in the week | Gemini, in the owner's interactive agy session, through a brief file in `~/projects/anyplot-briefs/`, one package of at most 20 to 25 files per fresh session, independent packages in parallel agy subagents (`/gemini-task`) | The owner decides what runs without asking; Gemini pushes a `gemini/*` branch and opens a draft PR; Claude reviews it, marks it ready, and follows it through | | Check of every code PR Claude opens, before it opens; not for diffs only of docs, instruction files, changelog fragments, or `plots/`, under about 20 lines, or Dependabot (owner, 2026-10-29) | Gemini 3.8 Flash through Vertex AI in project `anyplot`, location `global`, on Flex PayGo (`/zweitmeinung`) | Copilot gets one round per PR, so its findings should already be fixed; half price on Flex, $0.07–0.28 per review | | Second opinion, only when the owner asks for one | Fable and Gemini 4 Argon side by side, Argon on the same Vertex route with thinking high | Stronger across files; $0.57–1.16 per Argon run. Both Gemini lanes are paid per token and covered by the $100 monthly Google Cloud credit that comes with Google AI Ultra; Gemini reads tracked repository files, prefetched data, and the public API through read-only tools, with no shell and no credentials | @@ -55,6 +55,22 @@ are filtered the same way now. Packages stay at 20 to 25 files per fresh session because of the 2026-10-24 drift (a convention dropped for 76 files after about 22). +**Gemini scales out with agy subagents (owner, 2026-10-30).** The owner wanted +Gemini to scale when there is work for several agents. Research against the +Antigravity docs on 2026-10-30 found two mechanisms. Subagents +(`invoke_subagent`) run concurrently in the background, start without the +parent's conversation, can each get an isolated Git worktree, and report back +to the parent; agy deletes that worktree when the subagent ends. `/teamwork` +runs a fixed team of roles (coordinator, orchestrator, workers, critics, +auditors) on paid plans, but in its own folder `~/teamwork_projects/`, +with no branches or PRs in its docs, so it does not fit work on this +repository. So independent packages go to one subagent each, at most four at a +time (the docs give no concurrency limit and no quota figures), each on its own +`gemini/-` branch, pushing and opening its draft PR before it ends. +Running agents in parallel inside the owner's own agy session is a documented +product feature; what Google's FAQ forbids is a third-party agent such as +Claude Code driving agy under the consumer login. + **Google Jules, 2026-10-28 to 2026-10-29 (retired).** For two days Google Jules took credential-free tasks of about 30 minutes through its official MCP server: 300 tasks a day on Ultra, each counted once whatever it consumed, PRs @@ -131,11 +147,12 @@ So nothing extracts, copies, or proxies the agy login. read-only `agy -p` for second opinions. Google's Antigravity FAQ says that wrapping `agy` inside third-party coding agents is not supported under consumer plans, and that using third-party tools such as Claude Code to access -Antigravity can get the account suspended. A Google staff reply on 2026-10-16 -(Google AI Developers Forum, topic 189905) answered a setup like ours with "No -under consumer plans", even for the unmodified binary run as a local -subprocess without touching the token. Only the owner's own scripts and CI are -allowed. For third-party agents Google recommends calling Gemini models +Antigravity can get the account suspended. A forum reply on 2026-10-16 (Google +AI Developers Forum, topic 189905) answered a setup like ours with "No under +consumer plans", even for the unmodified binary run as a local subprocess +without touching the token; a check on 2026-10-30 found it is not marked as a +Google staff reply, so the FAQ is the authority. Only the owner's own scripts +and CI are allowed. For third-party agents Google recommends calling Gemini models through Gemini Enterprise (Google Cloud) or a Google AI Studio API key. So second opinions call Gemini through Vertex AI, which is plain Google Cloud usage, and only the owner starts agy, for `/gemini-task`. diff --git a/.claude/skills/gemini-task/SKILL.md b/.claude/skills/gemini-task/SKILL.md index e582bc03901..ed4f03bbd07 100644 --- a/.claude/skills/gemini-task/SKILL.md +++ b/.claude/skills/gemini-task/SKILL.md @@ -26,8 +26,8 @@ other write outside the machine stays with Claude. Nobody automates around the agy login. Only the owner starts agy, and he works it himself. Claude never runs `agy`, not even read-only: Google's Antigravity FAQ forbids running it from third-party coding agents such as Claude Code under -a consumer login, and a Google staff reply of 2026-10-16 confirmed that for the -unmodified binary. Nothing extracts, copies, or proxies the agy token, and +a consumer login, which a forum reply of 2026-10-16 (not marked as Google +staff) applied to the unmodified binary as well. Nothing extracts, copies, or proxies the agy token, and nothing calls Google endpoints with it (Antigravity terms, section 6). Claude's second opinions call Gemini through Vertex AI instead (`/zweitmeinung`). @@ -61,9 +61,12 @@ takes about two hours, and gets its own brief and a fresh agy session. On and then silently dropped it for 76 more, while every render still passed; a fresh session per package fixed it. Acceptance names a mechanical check for every convention the package must keep (a `grep` that must find nothing), so -the drift fails locally. Packages that can merge on their own get their own -branch and draft PR. Packages that only make sense together share one branch: -Gemini pushes and updates the draft PR after each, before the next session. +the drift fails locally. Packages that can merge on their own are +`independent`: each gets its own branch (`gemini/-`) and draft PR, and +Gemini works them in parallel (section 2, step 1). Packages that only make +sense together are `coupled` and share one branch: Gemini works them one after +another, pushes, and updates the draft PR after each, before the next session. +Write every package's brief up front, so one start line covers the whole task. **Write the brief** in English and in Google style. @@ -109,7 +112,7 @@ Gemini pushes and updates the draft PR after each, before the next session. ```markdown # -Branch `gemini/` · package of +Branch `gemini/` · package of · independent | coupled ## Goal One paragraph: the outcome, and why. @@ -135,7 +138,8 @@ instead of guessing. ``` Give the owner the start line to copy, `/gemini-task ` (or -`/gemini-task ` for an issue), one per package. He works in a +`/gemini-task ` for an issue). For packages `-1`, `-2`, … +the same `/gemini-task ` starts all of them. He works in a dedicated clone, never in the checkout Claude uses. Two things keep production out of that session: @@ -217,8 +221,10 @@ This section is for the Gemini agent in the owner's agy session. 1. **Read the task.** - **A slug** is a brief: `cat ~/projects/anyplot-briefs/.md` (a shell - read works even where your file tools stay inside the workspace). Never - edit, move, or delete a brief. + read works even where your file tools stay inside the workspace). When no + such file exists, the slug names a task in packages: + `ls ~/projects/anyplot-briefs/-*.md`, and read each. Never edit, + move, or delete a brief. - **A number** is an issue: `gh issue view --json title,body` (without `--json` it fails on this repository: Projects classic), and only the owner's comments on it: @@ -232,6 +238,29 @@ This section is for the Gemini agent in the owner's agy session. Reading GitHub is fine. Your only writes are your own branch and your own draft PR (step 7); never create, edit, comment on, label, or close anything else. + + **Scale out when there is work for several agents (owner, 2026-10-30).** + When two or more open packages of the task say `independent`, you are the + coordinator: start one subagent per package (`invoke_subagent`), at most + four at a time, the next one as a slot frees up. Work coupled packages + yourself, one after another, as below. + - Give each subagent an isolated Git worktree (the `branch` workspace + mode), write access, and the shell. If your agy version cannot isolate a + subagent in its own worktree, do not run packages in parallel in the + shared clone: two agents there overwrite each other's files and Git + state. Work them one after another instead, and tell the owner. + - A subagent starts without your conversation, so its prompt names + everything: the brief to `cat`, its branch `gemini/-` from + `origin/main`, that section 2 of `.agents/skills/gemini-task/SKILL.md` + applies, and that it pushes its branch and opens or updates its own draft + PR before it finishes. Antigravity deletes a subagent's worktree when it + ends, so unpushed work is lost. + - Watch them in `/agents`; approvals of a subagent show there too. When all + have finished, check that every package has its draft PR + (`gh pr list --draft --label gemini --json number,headRefName`), and tell + the owner the PR numbers. + - Do not use `/teamwork` for this repository: it builds in its own folder + (`~/teamwork_projects/`) without branches or PRs. 2. **Work in the dedicated clone on your own branch.** That clone is `~/projects/anyplot-agy`; if you find yourself in any other checkout, stop and tell the owner. Use absolute paths throughout. Your branch is diff --git a/.claude/skills/gemini-task/agy-permissions.json b/.claude/skills/gemini-task/agy-permissions.json index ce3f4b2754f..876249dd2f7 100644 --- a/.claude/skills/gemini-task/agy-permissions.json +++ b/.claude/skills/gemini-task/agy-permissions.json @@ -93,7 +93,27 @@ "command(gh pr comment)", "command(gh run list)", "command(gh run view)", - "read_file(/home//projects/anyplot-briefs)" + "read_file(/home//projects/anyplot-briefs)", + "command(git -C /home//projects/anyplot-agy status)", + "command(git -C /home//projects/anyplot-agy fetch)", + "command(git -C /home//projects/anyplot-agy log)", + "command(git -C /home//projects/anyplot-agy diff)", + "command(git -C /home//projects/anyplot-agy show)", + "command(git -C /home//projects/anyplot-agy branch)", + "command(git -C /home//projects/anyplot-agy switch)", + "command(git -C /home//projects/anyplot-agy rev-parse)", + "command(git -C /home//projects/anyplot-agy ls-files)", + "command(git -C /home//projects/anyplot-agy grep)", + "command(git -C /home//projects/anyplot-agy blame)", + "command(git -C /home//projects/anyplot-agy add)", + "command(git -C /home//projects/anyplot-agy commit)", + "command(git -C /home//projects/anyplot-agy restore)", + "command(git -C /home//projects/anyplot-agy mv)", + "command(git -C /home//projects/anyplot-agy rm)", + "command(git -C /home//projects/anyplot-agy pull --ff-only)", + "command(git -C /home//projects/anyplot-agy remote -v)", + "command(git -C /home//projects/anyplot-agy push -u origin gemini/)", + "command(git -C /home//projects/anyplot-agy push origin gemini/)" ], "deny": [ "command(gcloud)", @@ -159,7 +179,20 @@ "read_file(/home//projects/anyplot/.env)", "write_file(/home//projects/anyplot-agy/.git)", "write_file(/home//projects/anyplot-agy/.env)", - "write_file(/home//projects/anyplot-briefs)" + "write_file(/home//projects/anyplot-briefs)", + "command(git -C /home//projects/anyplot-agy push --force)", + "command(git -C /home//projects/anyplot-agy push -f)", + "command(git -C /home//projects/anyplot-agy push origin main)", + "command(git -C /home//projects/anyplot-agy push -u origin main)", + "command(git -C /home//projects/anyplot-agy push origin HEAD:main)", + "command(git -C /home//projects/anyplot-agy reset --hard)", + "command(git -C /home//projects/anyplot-agy rebase)", + "command(git -C /home//projects/anyplot-agy merge)", + "command(git -C /home//projects/anyplot-agy stash)", + "command(git -C /home//projects/anyplot-agy checkout)", + "command(git -C /home//projects/anyplot-agy clean)", + "command(git -C /home//projects/anyplot-agy filter-branch)", + "command(git -C /home//projects/anyplot-agy config)" ] } } diff --git a/.claude/skills/zweitmeinung/SKILL.md b/.claude/skills/zweitmeinung/SKILL.md index 44d13ebb9d5..2fb6e483ab7 100644 --- a/.claude/skills/zweitmeinung/SKILL.md +++ b/.claude/skills/zweitmeinung/SKILL.md @@ -12,8 +12,8 @@ opinions; it never implements a suggestion on its own. The owner decides. This skill is for Claude. Gemini in the owner's agy session sees it through `.agents/skills/` but never runs it: it would be asking itself. -**Never run `agy` from Claude.** Google's Antigravity FAQ and a staff reply of 2026-10-16 -(discuss.ai.google.dev/t/189905) say that running the Antigravity CLI from a third-party +**Never run `agy` from Claude.** Google's Antigravity FAQ, and a forum reply of 2026-10-16 +not marked as Google staff (discuss.ai.google.dev/t/189905), say that running the Antigravity CLI from a third-party coding agent such as Claude Code under a consumer login (the owner's Google AI Ultra) breaks the terms and can get the account suspended, even with the unmodified binary and no token access. The Gemini part therefore runs through `gemini_review.py` in this diff --git a/.claude/skills/zweitmeinung/gemini_review.py b/.claude/skills/zweitmeinung/gemini_review.py index fb8aba76fd4..deef0820406 100644 --- a/.claude/skills/zweitmeinung/gemini_review.py +++ b/.claude/skills/zweitmeinung/gemini_review.py @@ -1,8 +1,7 @@ """Ask Gemini for a second opinion through Vertex AI, with read-only tools. -This replaces headless `agy -p`: Google's Antigravity FAQ and a staff reply of -2026-10-16 forbid running agy from third-party coding agents under a consumer -login. Vertex AI is plain Google Cloud usage, billed to the project's billing +This replaces headless `agy -p`: Google's Antigravity FAQ forbids running agy +from third-party coding agents under a consumer login. Vertex AI is plain Google Cloud usage, billed to the project's billing account (the Google AI Ultra Cloud credit applies). Gemini gets the briefing, the inlined diff and attachments, and five read-only diff --git a/CLAUDE.md b/CLAUDE.md index 39c0062f8cf..67f427d851b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,7 +13,7 @@ A companion guide `.github/copilot-instructions.md` carries the shared rules for - **On a feature branch**: Claude MAY run `git commit`, `git push`, and `gh pr create` when the work warrants it. Still respect the project's automated pipelines (see "CRITICAL: Mandatory Workflow" below) — e.g. don't manually merge spec/impl PRs. - Confirm before destructive or hard-to-reverse operations (force-push, reset --hard, branch deletion) regardless of branch. One exception: after a PR merges, remove its worktree and local branch without asking; GitHub already deleted the remote one (`/open-pr` §4). - **GitHub Actions workflows ARE allowed to commit/push** - When running as part of `spec-*.yml` or `impl-*.yml` workflows, creating branches, commits, and PRs is expected and required. -- **Pick the agent by the work, and spend Claude tokens last** - The main session runs on Opus; the owner starts a planning session on Fable when the plan matters. A subagent runs on Opus (`model: opus`) when it changes state outside its own worktree (gcloud, `gh` writes, `git push`, labels, prod) or makes judgment calls; on Sonnet for bounded work inside its own worktree that a command verifies; on Haiku only to read or poll (CI, deploys, `gh`/`gcloud` state) and to create Todoist tasks (pipeline model choices are separate). Escalate to Fable for high-risk reviews (security, prod data, sandbox, privacy) and genuinely hard reasoning. Larger steps, and the week's driving once Claude tokens run low, go to Gemini as brief files in `~/projects/anyplot-briefs/` (a `gemini`-labelled issue only when the owner asks for one) that the owner works in his interactive agy session, one package of at most 20 to 25 files per fresh session (`/gemini-task`); Gemini pushes only its `gemini/*` branch and opens only draft PRs, which Claude reviews before marking them ready. Gemini through Vertex AI in project `anyplot`, with read-only tools (`/zweitmeinung`), checks every code PR Claude opens before it opens (Gemini 3.8 Flash; diffs only of docs, instruction files, changelog fragments, or `plots/`, diffs under about 20 lines, and Dependabot bumps excepted), so Copilot's one round ideally finds nothing; a second opinion, Fable and Gemini 4 Argon side by side, runs only when the owner asks for one. Claude never runs `agy` itself, not even read-only: Google's Antigravity FAQ forbids running it from third-party coding agents under a consumer login. Never extract, copy, or proxy the agy login (Antigravity terms §6). Escalation is for genuine judgment calls, not every detail: within its brief a delegate decides routine matters itself and documents them; what comes back to the main loop is anything that changes scope, contradicts the brief or the docs, or would be expensive to redo. State this split explicitly in delegate prompts (decide-and-document vs. return-as-finding). Every brief also spells out two things a delegate cannot infer from message order: repo files are modified only with Edit/Write, and all `git` stays inside the agent's own worktree — the shared checkout is left on the branch it was found on. +- **Pick the agent by the work, and spend Claude tokens last** - The main session runs on Opus; the owner starts a planning session on Fable when the plan matters. A subagent runs on Opus (`model: opus`) when it changes state outside its own worktree (gcloud, `gh` writes, `git push`, labels, prod) or makes judgment calls; on Sonnet for bounded work inside its own worktree that a command verifies; on Haiku only to read or poll (CI, deploys, `gh`/`gcloud` state) and to create Todoist tasks (pipeline model choices are separate). Escalate to Fable for high-risk reviews (security, prod data, sandbox, privacy) and genuinely hard reasoning. Larger steps, and the week's driving once Claude tokens run low, go to Gemini as brief files in `~/projects/anyplot-briefs/` (a `gemini`-labelled issue only when the owner asks for one) that the owner works in his interactive agy session, one package of at most 20 to 25 files per fresh session, independent packages in parallel agy subagents (`/gemini-task`); Gemini pushes only its `gemini/*` branch and opens only draft PRs, which Claude reviews before marking them ready. Gemini through Vertex AI in project `anyplot`, with read-only tools (`/zweitmeinung`), checks every code PR Claude opens before it opens (Gemini 3.8 Flash; diffs only of docs, instruction files, changelog fragments, or `plots/`, diffs under about 20 lines, and Dependabot bumps excepted), so Copilot's one round ideally finds nothing; a second opinion, Fable and Gemini 4 Argon side by side, runs only when the owner asks for one. Claude never runs `agy` itself, not even read-only: Google's Antigravity FAQ forbids running it from third-party coding agents under a consumer login. Never extract, copy, or proxy the agy login (Antigravity terms §6). Escalation is for genuine judgment calls, not every detail: within its brief a delegate decides routine matters itself and documents them; what comes back to the main loop is anything that changes scope, contradicts the brief or the docs, or would be expensive to redo. State this split explicitly in delegate prompts (decide-and-document vs. return-as-finding). Every brief also spells out two things a delegate cannot infer from message order: repo files are modified only with Edit/Write, and all `git` stays inside the agent's own worktree — the shared checkout is left on the branch it was found on. - **Always write in English** - All output text (code comments, commit messages, PR descriptions, issue comments, documentation) must be in English, even if the user writes in another language. - **Repository prose follows the Google developer documentation style guide** - `docs/`, `README.md`, `agentic/docs/`, changelog entries, and PR/issue text use [Google style](https://developers.google.com/style) (sentence-case headings, second person, numbered procedures); the concrete rules and the house-style exception (`docs/reference/style-guide.md` governs website/brand surfaces) live in the `write-docs` skill. Existing docs migrate on touch, not via bulk rewrites. - **Update documentation when making changes** - When adding new features, events, or modifying behavior, always check if related documentation needs updating (e.g., `docs/reference/plausible.md` for analytics events, `docs/workflows/` for workflow changes, `docs/contributing.md` for user-facing changes). diff --git a/changelog.d/gemini-scale-out.md b/changelog.d/gemini-scale-out.md new file mode 100644 index 00000000000..a1829f5c22b --- /dev/null +++ b/changelog.d/gemini-scale-out.md @@ -0,0 +1,12 @@ +### Changed + +- **Gemini works independent packages in parallel.** When a brief task has + two or more packages marked `independent`, the `gemini-task` skill has + Gemini in the owner's agy session start one agy subagent per package, at + most four at a time, each in its own Git worktree on its own + `gemini/-` branch, pushing and opening its draft PR before it ends; + coupled packages still run one after another. One start line, + `/gemini-task `, covers every package. `/teamwork` is ruled out for + this repository because it builds outside it, without branches or PRs. The + agy permission rules gain the `git -C ` forms, and the repository no + longer calls a 2026-10-16 forum reply a Google staff reply. From 4ef418c43b808ae1d5355edbf91191d2d8958131 Mon Sep 17 00:00:00 2001 From: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com> Date: Fri, 30 Oct 2026 00:15:43 +0100 Subject: [PATCH 2/9] docs(gemini-task): allow cd .., [ and false for chained acceptance checks Gemini chained the brief's acceptance commands into one line with cd .. and a [ ... ] test; agy asked for those two pieces. Co-Authored-By: Claude Opus 5.5 --- .claude/skills/gemini-task/agy-permissions.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.claude/skills/gemini-task/agy-permissions.json b/.claude/skills/gemini-task/agy-permissions.json index 876249dd2f7..62e6cef1182 100644 --- a/.claude/skills/gemini-task/agy-permissions.json +++ b/.claude/skills/gemini-task/agy-permissions.json @@ -50,7 +50,10 @@ "command(ss)", "command(lsof)", "command(test)", + "command([)", "command(true)", + "command(false)", + "command(cd ..)", "command(cd /home//projects/anyplot-agy)", "command(cd /home//projects/anyplot-agy/app)", "command(yarn)", From c215aa4bc4ba8acdbcb661b0f9941bcf902a61e1 Mon Sep 17 00:00:00 2001 From: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com> Date: Fri, 30 Oct 2026 00:21:38 +0100 Subject: [PATCH 3/9] docs(gemini-task): one PR per task, up to eight parallel subagents Owner, 2026-10-30: subagents should not open one PR each (every PR costs a Copilot round, a fragment, CI, a merge, and a deploy), and the limit may go higher. Subagents now push package branches gemini/- without a PR or fragment; the coordinator merges them with git merge --no-ff into gemini/, runs the gates on the result, writes one fragment, and opens one draft PR. Claude reviews per merge commit and deletes the package branches after the merge. agy rules allow git merge --no-ff and deny merging main. Co-Authored-By: Claude Opus 5.5 --- .claude/guardrails.md | 9 ++- .claude/skills/gemini-task/SKILL.md | 60 +++++++++++------- .../skills/gemini-task/agy-permissions.json | 62 +++++++++++-------- changelog.d/gemini-scale-out.md | 20 +++--- 4 files changed, 91 insertions(+), 60 deletions(-) diff --git a/.claude/guardrails.md b/.claude/guardrails.md index d2dac6d1ccf..07f3f0e179f 100644 --- a/.claude/guardrails.md +++ b/.claude/guardrails.md @@ -64,9 +64,12 @@ to the parent; agy deletes that worktree when the subagent ends. `/teamwork` runs a fixed team of roles (coordinator, orchestrator, workers, critics, auditors) on paid plans, but in its own folder `~/teamwork_projects/`, with no branches or PRs in its docs, so it does not fit work on this -repository. So independent packages go to one subagent each, at most four at a -time (the docs give no concurrency limit and no quota figures), each on its own -`gemini/-` branch, pushing and opening its draft PR before it ends. +repository. So independent packages go to one subagent each, at most eight at +a time (the docs give no concurrency limit and no quota figures; the owner +says when the quota runs short), each pushing its own `gemini/-` +branch before it ends. The coordinator merges them into one branch and opens +one draft PR per task, not one per package: every PR costs a Copilot round, a +changelog fragment, CI, a merge, and a deploy (owner, 2026-10-30). Running agents in parallel inside the owner's own agy session is a documented product feature; what Google's FAQ forbids is a third-party agent such as Claude Code driving agy under the consumer login. diff --git a/.claude/skills/gemini-task/SKILL.md b/.claude/skills/gemini-task/SKILL.md index ed4f03bbd07..3034d5846d6 100644 --- a/.claude/skills/gemini-task/SKILL.md +++ b/.claude/skills/gemini-task/SKILL.md @@ -61,12 +61,14 @@ takes about two hours, and gets its own brief and a fresh agy session. On and then silently dropped it for 76 more, while every render still passed; a fresh session per package fixed it. Acceptance names a mechanical check for every convention the package must keep (a `grep` that must find nothing), so -the drift fails locally. Packages that can merge on their own are -`independent`: each gets its own branch (`gemini/-`) and draft PR, and -Gemini works them in parallel (section 2, step 1). Packages that only make -sense together are `coupled` and share one branch: Gemini works them one after -another, pushes, and updates the draft PR after each, before the next session. -Write every package's brief up front, so one start line covers the whole task. +the drift fails locally. A task ends in one draft PR on `gemini/`, however +many packages it has (owner, 2026-10-30: every PR costs a Copilot round, a +changelog fragment, CI, a merge, and a deploy). Packages that touch disjoint +files are `independent`: Gemini works them in parallel, each on its own +package branch `gemini/-`, and merges them into `gemini/` +(section 2, step 1). Packages that build on each other are `coupled`: Gemini +works them one after another on `gemini/` and pushes after each. Write +every package's brief up front, so one start line covers the whole task. **Write the brief** in English and in Google style. @@ -242,23 +244,32 @@ This section is for the Gemini agent in the owner's agy session. **Scale out when there is work for several agents (owner, 2026-10-30).** When two or more open packages of the task say `independent`, you are the coordinator: start one subagent per package (`invoke_subagent`), at most - four at a time, the next one as a slot frees up. Work coupled packages - yourself, one after another, as below. + eight at a time, the next one as a slot frees up (owner, 2026-10-30: he + says when the quota runs short). Work coupled packages yourself, one after + another, as below. - Give each subagent an isolated Git worktree (the `branch` workspace mode), write access, and the shell. If your agy version cannot isolate a subagent in its own worktree, do not run packages in parallel in the shared clone: two agents there overwrite each other's files and Git state. Work them one after another instead, and tell the owner. - A subagent starts without your conversation, so its prompt names - everything: the brief to `cat`, its branch `gemini/-` from - `origin/main`, that section 2 of `.agents/skills/gemini-task/SKILL.md` - applies, and that it pushes its branch and opens or updates its own draft - PR before it finishes. Antigravity deletes a subagent's worktree when it - ends, so unpushed work is lost. - - Watch them in `/agents`; approvals of a subagent show there too. When all - have finished, check that every package has its draft PR - (`gh pr list --draft --label gemini --json number,headRefName`), and tell - the owner the PR numbers. + everything: the brief to `cat`, its package branch `gemini/-` + from `origin/main`, that steps 3 to 6 of section 2 of + `.agents/skills/gemini-task/SKILL.md` apply, and three differences: it + writes no changelog fragment, opens no PR, and pushes its branch before + it finishes (Antigravity deletes a subagent's worktree when it ends, so + unpushed work is lost). Its final message names its last commit, the + gate results, and its open questions. + - Watch them in `/agents`; approvals of a subagent show there too. + - **Integrate** when all have finished: on `gemini/` (from + `origin/main`, or the existing branch), merge each package with + `git merge --no-ff origin/gemini/-`, the only merge you make. + Disjoint packages merge without conflicts; a conflict means two packages + touched the same file, so stop and tell the owner. Run the acceptance + commands of every package and the gates on the merged result, add one + changelog fragment for the task, push, and open one draft PR (step 7) + whose `## Plan` lists each package with its merge commit. A package that + failed stays out; name it under open steps. - Do not use `/teamwork` for this repository: it builds in its own folder (`~/teamwork_projects/`) without branches or PRs. 2. **Work in the dedicated clone on your own branch.** That clone is @@ -385,7 +396,8 @@ This section is for the Gemini agent in the owner's agy session. - edit anything under `.git/`, including its config and hooks, - run the app or tests against the production database, - install tools globally, -- merge or rebase other branches into yours. +- merge other branches into yours (the coordinator's merge of its own package + branches in step 1 is the one exception), or rebase. ## 3. Claude: take the draft over @@ -416,7 +428,10 @@ This section is for the Gemini agent in the owner's agy session. Take Acceptance from the brief file or the issue, never from the PR body, which is Gemini's copy. Leave out the brief's reasoning and Gemini's hand-over. It reports defects. On the first package of a long task, it also - checks every changed file for the conventions the brief names. + checks every changed file for the conventions the brief names. For a task + in parallel packages, give it each package's Acceptance with that + package's diff (`git diff ^1 ` per merge commit), so a + package that drifted stands out. - Add Fable for high-risk diffs: security, production data, sandboxing, privacy. - Gemini never reviews its own work. @@ -470,8 +485,11 @@ This section is for the Gemini agent in the owner's agy session. the session. 6. **Clean up.** After the merge, remove your worktree and the local branch, as `/open-pr` §4 describes; GitHub has already deleted the remote branch. - Delete the brief (`rm -f ~/projects/anyplot-briefs/.md`); the merged - PR keeps its copy. The branch in the owner's clone + Delete the brief (`rm -f ~/projects/anyplot-briefs/.md`, or every + `-*.md` of a task in packages); the merged PR keeps its copy. Delete + the package branches the merge left behind: + `git push origin --delete gemini/-1 gemini/-2 …`. The branch in + the owner's clone (`~/projects/anyplot-agy`) is his to delete. 7. **Record the task in the ledger.** diff --git a/.claude/skills/gemini-task/agy-permissions.json b/.claude/skills/gemini-task/agy-permissions.json index 62e6cef1182..e4fc921d0da 100644 --- a/.claude/skills/gemini-task/agy-permissions.json +++ b/.claude/skills/gemini-task/agy-permissions.json @@ -84,19 +84,9 @@ "command(git rm)", "command(git pull --ff-only)", "command(git remote -v)", + "command(git merge --no-ff)", "command(git push -u origin gemini/)", "command(git push origin gemini/)", - "command(gh issue view)", - "command(gh issue list)", - "command(gh pr view)", - "command(gh pr list)", - "command(gh pr checks)", - "command(gh pr diff)", - "command(gh pr create --draft)", - "command(gh pr comment)", - "command(gh run list)", - "command(gh run view)", - "read_file(/home//projects/anyplot-briefs)", "command(git -C /home//projects/anyplot-agy status)", "command(git -C /home//projects/anyplot-agy fetch)", "command(git -C /home//projects/anyplot-agy log)", @@ -115,8 +105,20 @@ "command(git -C /home//projects/anyplot-agy rm)", "command(git -C /home//projects/anyplot-agy pull --ff-only)", "command(git -C /home//projects/anyplot-agy remote -v)", + "command(git -C /home//projects/anyplot-agy merge --no-ff)", "command(git -C /home//projects/anyplot-agy push -u origin gemini/)", - "command(git -C /home//projects/anyplot-agy push origin gemini/)" + "command(git -C /home//projects/anyplot-agy push origin gemini/)", + "command(gh issue view)", + "command(gh issue list)", + "command(gh pr view)", + "command(gh pr list)", + "command(gh pr checks)", + "command(gh pr diff)", + "command(gh pr create --draft)", + "command(gh pr comment)", + "command(gh run list)", + "command(gh run view)", + "read_file(/home//projects/anyplot-briefs)" ], "deny": [ "command(gcloud)", @@ -152,14 +154,33 @@ "command(git push origin main)", "command(git push -u origin main)", "command(git push origin HEAD:main)", + "command(git merge --no-ff origin/main)", + "command(git merge --no-ff main)", + "command(git merge origin/main)", + "command(git merge main)", "command(git reset --hard)", "command(git rebase)", - "command(git merge)", "command(git stash)", "command(git checkout)", "command(git clean)", "command(git filter-branch)", "command(git config)", + "command(git -C /home//projects/anyplot-agy push --force)", + "command(git -C /home//projects/anyplot-agy push -f)", + "command(git -C /home//projects/anyplot-agy push origin main)", + "command(git -C /home//projects/anyplot-agy push -u origin main)", + "command(git -C /home//projects/anyplot-agy push origin HEAD:main)", + "command(git -C /home//projects/anyplot-agy merge --no-ff origin/main)", + "command(git -C /home//projects/anyplot-agy merge --no-ff main)", + "command(git -C /home//projects/anyplot-agy merge origin/main)", + "command(git -C /home//projects/anyplot-agy merge main)", + "command(git -C /home//projects/anyplot-agy reset --hard)", + "command(git -C /home//projects/anyplot-agy rebase)", + "command(git -C /home//projects/anyplot-agy stash)", + "command(git -C /home//projects/anyplot-agy checkout)", + "command(git -C /home//projects/anyplot-agy clean)", + "command(git -C /home//projects/anyplot-agy filter-branch)", + "command(git -C /home//projects/anyplot-agy config)", "command(gh pr merge)", "command(gh pr ready)", "command(gh pr close)", @@ -182,20 +203,7 @@ "read_file(/home//projects/anyplot/.env)", "write_file(/home//projects/anyplot-agy/.git)", "write_file(/home//projects/anyplot-agy/.env)", - "write_file(/home//projects/anyplot-briefs)", - "command(git -C /home//projects/anyplot-agy push --force)", - "command(git -C /home//projects/anyplot-agy push -f)", - "command(git -C /home//projects/anyplot-agy push origin main)", - "command(git -C /home//projects/anyplot-agy push -u origin main)", - "command(git -C /home//projects/anyplot-agy push origin HEAD:main)", - "command(git -C /home//projects/anyplot-agy reset --hard)", - "command(git -C /home//projects/anyplot-agy rebase)", - "command(git -C /home//projects/anyplot-agy merge)", - "command(git -C /home//projects/anyplot-agy stash)", - "command(git -C /home//projects/anyplot-agy checkout)", - "command(git -C /home//projects/anyplot-agy clean)", - "command(git -C /home//projects/anyplot-agy filter-branch)", - "command(git -C /home//projects/anyplot-agy config)" + "write_file(/home//projects/anyplot-briefs)" ] } } diff --git a/changelog.d/gemini-scale-out.md b/changelog.d/gemini-scale-out.md index a1829f5c22b..9882f912b8d 100644 --- a/changelog.d/gemini-scale-out.md +++ b/changelog.d/gemini-scale-out.md @@ -1,12 +1,14 @@ ### Changed -- **Gemini works independent packages in parallel.** When a brief task has - two or more packages marked `independent`, the `gemini-task` skill has - Gemini in the owner's agy session start one agy subagent per package, at - most four at a time, each in its own Git worktree on its own - `gemini/-` branch, pushing and opening its draft PR before it ends; - coupled packages still run one after another. One start line, - `/gemini-task `, covers every package. `/teamwork` is ruled out for - this repository because it builds outside it, without branches or PRs. The - agy permission rules gain the `git -C ` forms, and the repository no +- **Gemini works independent packages in parallel, in one PR.** When a brief + task has two or more packages marked `independent`, the `gemini-task` skill + has Gemini in the owner's agy session start one agy subagent per package, at + most eight at a time, each in its own Git worktree on its own + `gemini/-` branch. Gemini then merges the package branches into + `gemini/`, runs the gates on the result, and opens one draft PR with + one changelog fragment for the whole task; coupled packages still run one + after another. One start line, `/gemini-task `, covers every package. + `/teamwork` is ruled out for this repository because it builds outside it, + without branches or PRs. The agy permission rules gain the `git -C ` + forms and the coordinator's `git merge --no-ff`, and the repository no longer calls a 2026-10-16 forum reply a Google staff reply. From b1534696714a417cf1a85080739c8c3b6b2493da Mon Sep 17 00:00:00 2001 From: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com> Date: Fri, 30 Oct 2026 00:24:55 +0100 Subject: [PATCH 4/9] docs(gemini-task): run checks as single commands, not chains In the first live brief run agy asked the owner for every chained check with subshells, command substitution, or || true; single commands match the permission rules. Co-Authored-By: Claude Opus 5.5 --- .claude/skills/gemini-task/SKILL.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.claude/skills/gemini-task/SKILL.md b/.claude/skills/gemini-task/SKILL.md index 3034d5846d6..673e5fd5aae 100644 --- a/.claude/skills/gemini-task/SKILL.md +++ b/.claude/skills/gemini-task/SKILL.md @@ -313,7 +313,11 @@ This section is for the Gemini agent in the owner's agy session. make you change as well, such as a registry a test fixture enforces, is in scope even when the task's Constraints miss it; name it in the hand-over. 5. **Run the acceptance commands, the convention checks, and the gates for - what you changed**, the convention checks before every commit: + what you changed**, the convention checks before every commit. Run each + command on its own, from the clone root or `app/`: agy matches its + permission rules per command, so a plain `yarn test` or `grep …` runs + without a prompt, while a chain with `( … )`, `$( … )`, or `|| true` asks + the owner every time (2026-10-30). ```bash PYTHON_DOTENV_DISABLED=1 uv run ruff check . && uv run ruff format --check . From 40caecf9998c83d2d9d01f842561cbc3da112390 Mon Sep 17 00:00:00 2001 From: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com> Date: Fri, 30 Oct 2026 00:25:09 +0100 Subject: [PATCH 5/9] docs(gemini-task): briefs state acceptance checks as plain commands Co-Authored-By: Claude Opus 5.5 --- .claude/skills/gemini-task/SKILL.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.claude/skills/gemini-task/SKILL.md b/.claude/skills/gemini-task/SKILL.md index 673e5fd5aae..c12e129e3e7 100644 --- a/.claude/skills/gemini-task/SKILL.md +++ b/.claude/skills/gemini-task/SKILL.md @@ -86,6 +86,9 @@ every package's brief up front, so one start line covers the whole task. and a sample in its test, because an autouse fixture in `tests/unit/agents/data/conftest.py` fails every test that emits an unknown warning. A "change only" list without them contradicts the gates. +- Write each Acceptance check as one plain command (`yarn test`, a `grep` that + must print nothing, `wc -l ` with the limit in words), never a chain + with `( … )`, `$( … )`, or `|| true`: agy asks the owner for every chain. - Name it with a short kebab-case slug that no open brief or `gemini/*` branch uses yet; packages of one task get `-1`, `-2`, and so on. - Write it with the Write tool to `~/projects/anyplot-briefs/.md`, then From d44e1dd82a53a872b027c96abd53734a1655f46c Mon Sep 17 00:00:00 2001 From: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com> Date: Fri, 30 Oct 2026 00:38:58 +0100 Subject: [PATCH 6/9] fix(gemini-task): close the refspec push to main, tighten the package flow Copilot review of #12462: - A prefix allow such as git push origin gemini/ also matched gemini/foo:main. Regex denies now catch any refspec whose destination is main, and --all, --mirror, --delete, --tags, --prune, and ':branch' deletions (the owner's live settings carry the same rules). - The brief template names the package branch gemini/- for independent packages and gemini/ for coupled ones. - One start line per task: the session is the coordinator; coupled packages run one fresh subagent at a time in its workspace, so the per-package fresh start holds without new sessions. - The package glob is -[0-9]*.md, so another task's brief with the same prefix stays out. Co-Authored-By: Claude Opus 5.5 --- .claude/guardrails.md | 2 +- .claude/skills/gemini-task/SKILL.md | 43 +++++++++++-------- .../skills/gemini-task/agy-permissions.json | 3 ++ CLAUDE.md | 2 +- 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/.claude/guardrails.md b/.claude/guardrails.md index 07f3f0e179f..3d3b26f748c 100644 --- a/.claude/guardrails.md +++ b/.claude/guardrails.md @@ -30,7 +30,7 @@ work that Google's quota can do goes there first. | Subagent with bounded work inside its own worktree, verified by a command it runs | Sonnet | Cheaper for work whose result a command checks; never writes outside its worktree | | Reads or polls with credentials (CI, deploys, `gh`/`gcloud` state); creates Todoist tasks | Haiku | Cheap; never changes state | | High-risk reviews (security, prod data, sandbox, privacy); genuinely hard reasoning | Fable | About 2.5 times Opus per token at API prices, so only where it pays | -| Larger steps and long refactors, and the main driver once Claude tokens run low late in the week | Gemini, in the owner's interactive agy session, through a brief file in `~/projects/anyplot-briefs/`, one package of at most 20 to 25 files per fresh session, independent packages in parallel agy subagents (`/gemini-task`) | The owner decides what runs without asking; Gemini pushes a `gemini/*` branch and opens a draft PR; Claude reviews it, marks it ready, and follows it through | +| Larger steps and long refactors, and the main driver once Claude tokens run low late in the week | Gemini, in the owner's interactive agy session, through a brief file in `~/projects/anyplot-briefs/`, one package of at most 20 to 25 files per fresh agy subagent, independent packages in parallel (`/gemini-task`) | The owner decides what runs without asking; Gemini pushes a `gemini/*` branch and opens a draft PR; Claude reviews it, marks it ready, and follows it through | | Check of every code PR Claude opens, before it opens; not for diffs only of docs, instruction files, changelog fragments, or `plots/`, under about 20 lines, or Dependabot (owner, 2026-10-29) | Gemini 3.8 Flash through Vertex AI in project `anyplot`, location `global`, on Flex PayGo (`/zweitmeinung`) | Copilot gets one round per PR, so its findings should already be fixed; half price on Flex, $0.07–0.28 per review | | Second opinion, only when the owner asks for one | Fable and Gemini 4 Argon side by side, Argon on the same Vertex route with thinking high | Stronger across files; $0.57–1.16 per Argon run. Both Gemini lanes are paid per token and covered by the $100 monthly Google Cloud credit that comes with Google AI Ultra; Gemini reads tracked repository files, prefetched data, and the public API through read-only tools, with no shell and no credentials | diff --git a/.claude/skills/gemini-task/SKILL.md b/.claude/skills/gemini-task/SKILL.md index c12e129e3e7..1bcd1f4d356 100644 --- a/.claude/skills/gemini-task/SKILL.md +++ b/.claude/skills/gemini-task/SKILL.md @@ -56,10 +56,11 @@ he asks) and write his decisions into the brief. Examples: - changes whose only verification is a live deploy. **Cut large work into packages.** A package changes at most 20 to 25 files, or -takes about two hours, and gets its own brief and a fresh agy session. On -2026-10-24 Gemini kept a code convention for about 22 files of a long session -and then silently dropped it for 76 more, while every render still passed; a -fresh session per package fixed it. Acceptance names a mechanical check for +takes about two hours, and gets its own brief and a fresh agent: an agy +subagent, which starts without the coordinator's conversation. On 2026-10-24 +Gemini kept a code convention for about 22 files of a long session and then +silently dropped it for 76 more, while every render still passed; a fresh +session per package fixed it. Acceptance names a mechanical check for every convention the package must keep (a `grep` that must find nothing), so the drift fails locally. A task ends in one draft PR on `gemini/`, however many packages it has (owner, 2026-10-30: every PR costs a Copilot round, a @@ -67,8 +68,9 @@ changelog fragment, CI, a merge, and a deploy). Packages that touch disjoint files are `independent`: Gemini works them in parallel, each on its own package branch `gemini/-`, and merges them into `gemini/` (section 2, step 1). Packages that build on each other are `coupled`: Gemini -works them one after another on `gemini/` and pushes after each. Write -every package's brief up front, so one start line covers the whole task. +works them one after another on `gemini/`, one fresh subagent each, and +pushes after each. Write every package's brief up front, so one start line +covers the whole task. **Write the brief** in English and in Google style. @@ -117,7 +119,7 @@ every package's brief up front, so one start line covers the whole task. ```markdown # -Branch `gemini/` · package of · independent | coupled +Branch `gemini/-` (independent) | `gemini/` (coupled, or a single package) · package of ## Goal One paragraph: the outcome, and why. @@ -216,9 +218,11 @@ sed "s|/home/|$HOME|g" ~/projects/anyplot-agy/.claude/skills/gemini-task/a | jq -s '.[0] * .[1]' "$f" - > "$f.new" && mv "$f.new" "$f" ``` -Then, for each package in a fresh session, he runs `agy-work` and types the -start line. `/gemini-task` without an argument lists the open briefs and -issues. +Then he runs `agy-work` and types the start line, once per task: that session +is the coordinator and starts the package agents itself. Only if it ends +before the task does, he starts a new session with the same line, and Gemini +resumes from the branches (section 2, step 2). `/gemini-task` without an +argument lists the open briefs and issues. ## 2. Gemini: work the task @@ -228,7 +232,8 @@ This section is for the Gemini agent in the owner's agy session. - **A slug** is a brief: `cat ~/projects/anyplot-briefs/.md` (a shell read works even where your file tools stay inside the workspace). When no such file exists, the slug names a task in packages: - `ls ~/projects/anyplot-briefs/-*.md`, and read each. Never edit, + `ls ~/projects/anyplot-briefs/-[0-9]*.md` (the digit keeps + another task's `-other.md` out), and read each. Never edit, move, or delete a brief. - **A number** is an issue: `gh issue view --json title,body` (without `--json` it fails on this repository: Projects classic), and only @@ -245,12 +250,14 @@ This section is for the Gemini agent in the owner's agy session. else. **Scale out when there is work for several agents (owner, 2026-10-30).** - When two or more open packages of the task say `independent`, you are the - coordinator: start one subagent per package (`invoke_subagent`), at most - eight at a time, the next one as a slot frees up (owner, 2026-10-30: he - says when the quota runs short). Work coupled packages yourself, one after - another, as below. - - Give each subagent an isolated Git worktree (the `branch` workspace + For a task in packages you are the coordinator. Independent packages: one + subagent each (`invoke_subagent`), at most eight at a time, the next one as + a slot frees up (owner, 2026-10-30: he says when the quota runs short). + Coupled packages: one subagent at a time in your own workspace (the + `inherit` mode), each on `gemini/` and pushing before it ends, so + every package still starts fresh. A single package you work yourself, as + below. + - Give each independent package's subagent an isolated Git worktree (the `branch` workspace mode), write access, and the shell. If your agy version cannot isolate a subagent in its own worktree, do not run packages in parallel in the shared clone: two agents there overwrite each other's files and Git @@ -493,7 +500,7 @@ This section is for the Gemini agent in the owner's agy session. 6. **Clean up.** After the merge, remove your worktree and the local branch, as `/open-pr` §4 describes; GitHub has already deleted the remote branch. Delete the brief (`rm -f ~/projects/anyplot-briefs/.md`, or every - `-*.md` of a task in packages); the merged PR keeps its copy. Delete + `-[0-9]*.md` of a task in packages); the merged PR keeps its copy. Delete the package branches the merge left behind: `git push origin --delete gemini/-1 gemini/-2 …`. The branch in the owner's clone diff --git a/.claude/skills/gemini-task/agy-permissions.json b/.claude/skills/gemini-task/agy-permissions.json index e4fc921d0da..141c855ecf3 100644 --- a/.claude/skills/gemini-task/agy-permissions.json +++ b/.claude/skills/gemini-task/agy-permissions.json @@ -154,6 +154,9 @@ "command(git push origin main)", "command(git push -u origin main)", "command(git push origin HEAD:main)", + "command(regex:git (-C [^ ]+ )?push .*:(refs/heads/)?main( |$))", + "command(regex:git (-C [^ ]+ )?push .*(--all|--mirror|--delete|--tags|--prune))", + "command(regex:git (-C [^ ]+ )?push [^ ]+ :)", "command(git merge --no-ff origin/main)", "command(git merge --no-ff main)", "command(git merge origin/main)", diff --git a/CLAUDE.md b/CLAUDE.md index 67f427d851b..7b3291d7641 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,7 +13,7 @@ A companion guide `.github/copilot-instructions.md` carries the shared rules for - **On a feature branch**: Claude MAY run `git commit`, `git push`, and `gh pr create` when the work warrants it. Still respect the project's automated pipelines (see "CRITICAL: Mandatory Workflow" below) — e.g. don't manually merge spec/impl PRs. - Confirm before destructive or hard-to-reverse operations (force-push, reset --hard, branch deletion) regardless of branch. One exception: after a PR merges, remove its worktree and local branch without asking; GitHub already deleted the remote one (`/open-pr` §4). - **GitHub Actions workflows ARE allowed to commit/push** - When running as part of `spec-*.yml` or `impl-*.yml` workflows, creating branches, commits, and PRs is expected and required. -- **Pick the agent by the work, and spend Claude tokens last** - The main session runs on Opus; the owner starts a planning session on Fable when the plan matters. A subagent runs on Opus (`model: opus`) when it changes state outside its own worktree (gcloud, `gh` writes, `git push`, labels, prod) or makes judgment calls; on Sonnet for bounded work inside its own worktree that a command verifies; on Haiku only to read or poll (CI, deploys, `gh`/`gcloud` state) and to create Todoist tasks (pipeline model choices are separate). Escalate to Fable for high-risk reviews (security, prod data, sandbox, privacy) and genuinely hard reasoning. Larger steps, and the week's driving once Claude tokens run low, go to Gemini as brief files in `~/projects/anyplot-briefs/` (a `gemini`-labelled issue only when the owner asks for one) that the owner works in his interactive agy session, one package of at most 20 to 25 files per fresh session, independent packages in parallel agy subagents (`/gemini-task`); Gemini pushes only its `gemini/*` branch and opens only draft PRs, which Claude reviews before marking them ready. Gemini through Vertex AI in project `anyplot`, with read-only tools (`/zweitmeinung`), checks every code PR Claude opens before it opens (Gemini 3.8 Flash; diffs only of docs, instruction files, changelog fragments, or `plots/`, diffs under about 20 lines, and Dependabot bumps excepted), so Copilot's one round ideally finds nothing; a second opinion, Fable and Gemini 4 Argon side by side, runs only when the owner asks for one. Claude never runs `agy` itself, not even read-only: Google's Antigravity FAQ forbids running it from third-party coding agents under a consumer login. Never extract, copy, or proxy the agy login (Antigravity terms §6). Escalation is for genuine judgment calls, not every detail: within its brief a delegate decides routine matters itself and documents them; what comes back to the main loop is anything that changes scope, contradicts the brief or the docs, or would be expensive to redo. State this split explicitly in delegate prompts (decide-and-document vs. return-as-finding). Every brief also spells out two things a delegate cannot infer from message order: repo files are modified only with Edit/Write, and all `git` stays inside the agent's own worktree — the shared checkout is left on the branch it was found on. +- **Pick the agent by the work, and spend Claude tokens last** - The main session runs on Opus; the owner starts a planning session on Fable when the plan matters. A subagent runs on Opus (`model: opus`) when it changes state outside its own worktree (gcloud, `gh` writes, `git push`, labels, prod) or makes judgment calls; on Sonnet for bounded work inside its own worktree that a command verifies; on Haiku only to read or poll (CI, deploys, `gh`/`gcloud` state) and to create Todoist tasks (pipeline model choices are separate). Escalate to Fable for high-risk reviews (security, prod data, sandbox, privacy) and genuinely hard reasoning. Larger steps, and the week's driving once Claude tokens run low, go to Gemini as brief files in `~/projects/anyplot-briefs/` (a `gemini`-labelled issue only when the owner asks for one) that the owner works in his interactive agy session, one package of at most 20 to 25 files per fresh agy subagent, independent packages in parallel (`/gemini-task`); Gemini pushes only its `gemini/*` branch and opens only draft PRs, which Claude reviews before marking them ready. Gemini through Vertex AI in project `anyplot`, with read-only tools (`/zweitmeinung`), checks every code PR Claude opens before it opens (Gemini 3.8 Flash; diffs only of docs, instruction files, changelog fragments, or `plots/`, diffs under about 20 lines, and Dependabot bumps excepted), so Copilot's one round ideally finds nothing; a second opinion, Fable and Gemini 4 Argon side by side, runs only when the owner asks for one. Claude never runs `agy` itself, not even read-only: Google's Antigravity FAQ forbids running it from third-party coding agents under a consumer login. Never extract, copy, or proxy the agy login (Antigravity terms §6). Escalation is for genuine judgment calls, not every detail: within its brief a delegate decides routine matters itself and documents them; what comes back to the main loop is anything that changes scope, contradicts the brief or the docs, or would be expensive to redo. State this split explicitly in delegate prompts (decide-and-document vs. return-as-finding). Every brief also spells out two things a delegate cannot infer from message order: repo files are modified only with Edit/Write, and all `git` stays inside the agent's own worktree — the shared checkout is left on the branch it was found on. - **Always write in English** - All output text (code comments, commit messages, PR descriptions, issue comments, documentation) must be in English, even if the user writes in another language. - **Repository prose follows the Google developer documentation style guide** - `docs/`, `README.md`, `agentic/docs/`, changelog entries, and PR/issue text use [Google style](https://developers.google.com/style) (sentence-case headings, second person, numbered procedures); the concrete rules and the house-style exception (`docs/reference/style-guide.md` governs website/brand surfaces) live in the `write-docs` skill. Existing docs migrate on touch, not via bulk rewrites. - **Update documentation when making changes** - When adding new features, events, or modifying behavior, always check if related documentation needs updating (e.g., `docs/reference/plausible.md` for analytics events, `docs/workflows/` for workflow changes, `docs/contributing.md` for user-facing changes). From 9e885eea68c7ba943ba229372a3b42e4ab3c125f Mon Sep 17 00:00:00 2001 From: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com> Date: Fri, 30 Oct 2026 00:45:33 +0100 Subject: [PATCH 7/9] docs(gemini-task): run package path checks on the package branch On the merged branch every package's 'only my files changed' check sees the other packages' files; gates and tests run on the merged result, path checks per package branch. Co-Authored-By: Claude Opus 5.5 --- .claude/skills/gemini-task/SKILL.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.claude/skills/gemini-task/SKILL.md b/.claude/skills/gemini-task/SKILL.md index 1bcd1f4d356..d1ad4060af6 100644 --- a/.claude/skills/gemini-task/SKILL.md +++ b/.claude/skills/gemini-task/SKILL.md @@ -275,8 +275,10 @@ This section is for the Gemini agent in the owner's agy session. `origin/main`, or the existing branch), merge each package with `git merge --no-ff origin/gemini/-`, the only merge you make. Disjoint packages merge without conflicts; a conflict means two packages - touched the same file, so stop and tell the owner. Run the acceptance - commands of every package and the gates on the merged result, add one + touched the same file, so stop and tell the owner. Run every package's + gates and test commands on the merged result; its path checks (which + files may change) hold per package, so run those on its package branch + (`git diff --name-only origin/main...origin/gemini/-`). Add one changelog fragment for the task, push, and open one draft PR (step 7) whose `## Plan` lists each package with its merge commit. A package that failed stays out; name it under open steps. From d7e1b35b1f7d3af3e5d83d44ad08d89d83d24b1e Mon Sep 17 00:00:00 2001 From: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com> Date: Fri, 30 Oct 2026 00:46:49 +0100 Subject: [PATCH 8/9] fix(gemini-task): coupled workers keep the shared branch, exact package match Second Copilot round on #12462: - A coupled package's subagent continues on the tip of gemini/ instead of starting a fresh package branch from origin/main, which would have dropped the previous packages' commits. - cd .. leaves the allow list (live settings and reference): the absolute clone paths cover every needed cd, and a prefix match could otherwise move Gemini out of the clone. - Packages are found with find -regex '-[0-9]+\.md', so -1-other.md stays out; the clean-up step uses the same match. - The gate block lists one command per line; app/ gates run one by one. Co-Authored-By: Claude Opus 5.5 --- .claude/skills/gemini-task/SKILL.md | 25 +++++++++++++------ .../skills/gemini-task/agy-permissions.json | 1 - 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/.claude/skills/gemini-task/SKILL.md b/.claude/skills/gemini-task/SKILL.md index d1ad4060af6..bbcfab7c31a 100644 --- a/.claude/skills/gemini-task/SKILL.md +++ b/.claude/skills/gemini-task/SKILL.md @@ -232,8 +232,10 @@ This section is for the Gemini agent in the owner's agy session. - **A slug** is a brief: `cat ~/projects/anyplot-briefs/.md` (a shell read works even where your file tools stay inside the workspace). When no such file exists, the slug names a task in packages: - `ls ~/projects/anyplot-briefs/-[0-9]*.md` (the digit keeps - another task's `-other.md` out), and read each. Never edit, + `find ~/projects/anyplot-briefs -maxdepth 1 -regex '.*/-[0-9]+\.md'` + (a number and nothing else after the slug, so another task's + `-other.md` or `-1-other.md` stays out), and read each. + Never edit, move, or delete a brief. - **A number** is an issue: `gh issue view --json title,body` (without `--json` it fails on this repository: Projects classic), and only @@ -263,8 +265,10 @@ This section is for the Gemini agent in the owner's agy session. shared clone: two agents there overwrite each other's files and Git state. Work them one after another instead, and tell the owner. - A subagent starts without your conversation, so its prompt names - everything: the brief to `cat`, its package branch `gemini/-` - from `origin/main`, that steps 3 to 6 of section 2 of + everything: the brief to `cat`; its branch, which for an independent + package is a new `gemini/-` from `origin/main`, and for a + coupled package the current tip of `gemini/` with the previous + packages' commits on it; that steps 3 to 6 of section 2 of `.agents/skills/gemini-task/SKILL.md` apply, and three differences: it writes no changelog fragment, opens no PR, and pushes its branch before it finishes (Antigravity deletes a subagent's worktree when it ends, so @@ -332,13 +336,16 @@ This section is for the Gemini agent in the owner's agy session. the owner every time (2026-10-30). ```bash - PYTHON_DOTENV_DISABLED=1 uv run ruff check . && uv run ruff format --check . + PYTHON_DOTENV_DISABLED=1 uv run ruff check . + PYTHON_DOTENV_DISABLED=1 uv run ruff format --check . PYTHON_DOTENV_DISABLED=1 uv run --extra typecheck mypy api core --pretty # Python changes PYTHON_DOTENV_DISABLED=1 uv run pytest tests/unit tests/integration -n auto # or the narrower set the task names PYTHON_DOTENV_DISABLED=1 uv run python -m tools.changelog check --base origin/main # after committing the fragment - cd app && yarn lint && yarn fm:check && yarn type-check && yarn test && yarn build # app/ changes ``` + For `app/` changes, from `app/`, one command each: `yarn lint`, + `yarn fm:check`, `yarn type-check`, `yarn test`, `yarn build`. + The changelog check reads `origin/main...HEAD`, as CI does, so it fails until the fragment is committed; staging it is not enough. @@ -501,8 +508,10 @@ This section is for the Gemini agent in the owner's agy session. the session. 6. **Clean up.** After the merge, remove your worktree and the local branch, as `/open-pr` §4 describes; GitHub has already deleted the remote branch. - Delete the brief (`rm -f ~/projects/anyplot-briefs/.md`, or every - `-[0-9]*.md` of a task in packages); the merged PR keeps its copy. Delete + Delete the brief (`rm -f ~/projects/anyplot-briefs/.md`, or for a + task in packages + `find ~/projects/anyplot-briefs -maxdepth 1 -regex '.*/-[0-9]+\.md' -delete`); + the merged PR keeps its copy. Delete the package branches the merge left behind: `git push origin --delete gemini/-1 gemini/-2 …`. The branch in the owner's clone diff --git a/.claude/skills/gemini-task/agy-permissions.json b/.claude/skills/gemini-task/agy-permissions.json index 141c855ecf3..24681d28cbf 100644 --- a/.claude/skills/gemini-task/agy-permissions.json +++ b/.claude/skills/gemini-task/agy-permissions.json @@ -53,7 +53,6 @@ "command([)", "command(true)", "command(false)", - "command(cd ..)", "command(cd /home//projects/anyplot-agy)", "command(cd /home//projects/anyplot-agy/app)", "command(yarn)", From 9fa1071f97d4bb93d492d89b13c7028c2aab7617 Mon Sep 17 00:00:00 2001 From: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com> Date: Fri, 30 Oct 2026 00:59:45 +0100 Subject: [PATCH 9/9] docs(gemini-task): name the command that creates the task branch Copilot (third round, low): the coordinator needs an explicit step to reach gemini/ before merging the package branches. Co-Authored-By: Claude Opus 5.5 --- .claude/skills/gemini-task/SKILL.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.claude/skills/gemini-task/SKILL.md b/.claude/skills/gemini-task/SKILL.md index bbcfab7c31a..5995b63b41d 100644 --- a/.claude/skills/gemini-task/SKILL.md +++ b/.claude/skills/gemini-task/SKILL.md @@ -275,8 +275,9 @@ This section is for the Gemini agent in the owner's agy session. unpushed work is lost). Its final message names its last commit, the gate results, and its open questions. - Watch them in `/agents`; approvals of a subagent show there too. - - **Integrate** when all have finished: on `gemini/` (from - `origin/main`, or the existing branch), merge each package with + - **Integrate** when all have finished. Fetch, then switch to the task + branch: `git switch -c gemini/ origin/main` the first time, + `git switch gemini/` once it exists. Merge each package with `git merge --no-ff origin/gemini/-`, the only merge you make. Disjoint packages merge without conflicts; a conflict means two packages touched the same file, so stop and tell the owner. Run every package's