Skip to content

feat: add consult plugin, harden council, tighten CI checks - #4

Merged
Droniu merged 4 commits into
mainfrom
feat/consult-plugin-and-council-hardening
Sep 12, 2026
Merged

Droniu merged 4 commits into
mainfrom
feat/consult-plugin-and-council-hardening

Conversation

@Droniu

@Droniu Droniu commented Sep 12, 2026

Copy link
Copy Markdown
Owner

Summary

bro-code had one second-opinion tool, council, which convenes every model and runs a rebuttal round even when you only want one model's read on the problem in front of you. This PR adds consult for that single-model case, repairs council invocations that could not succeed against current provider CLIs, and widens the CI checks that let those problems ship in the first place.

Context

consult asks one named model — Codex, Grok, or a Claude subagent — and hands it the same access this session has, rather than council's read-only seats. The session's permission mode maps onto each provider: plan stays read-only, acceptEdits confines writes to the workspace, auto auto-approves inside a sandbox, bypass stays bypass. Where the session would stop and ask the user, a headless consultant is denied rather than silently upgraded, since nobody is there to approve. Anything it changes in the working tree is diffed against a pre-run snapshot and reported back, and follow-ups resume the same provider session.

Council's codex path could not succeed against codex-cli 0.153.2: codex exec review rejects -C, refuses --base alongside a positional prompt, and ignores --output-schema entirely, while find-schema.json omitted properties that OpenAI strict structured output requires in required. Review seats now use plain codex exec with the diff target in the brief against a strict-compatible schema, verified with a live call. The grok guidance was wrong in the same way: quota exhaustion was diagnosed as auth (advising a grok login that fixes nothing), --permission-mode plan was accepted and silently ignored, and effort was announced even when the model's catalog reports it unsupported. Seats are now preflighted with a one-turn smoke call before any roster is announced, capped so one runaway seat cannot swallow a run, and gated on file:line evidence before their output counts as a position.

CI listed plugins by hand, so a plugin could be registered in the marketplace and never validated — marketplace --strict passes over a missing source directory and never opens skills. Validation targets now come from marketplace.json, with parity enforced in both directions. The portability scan covered plugins/ only, leaving README, CHANGELOG and workflow content unchecked; it now scans the whole repo.

Test plan

  • claude plugin validate .claude-plugin/marketplace.json --strict
  • claude plugin validate <each plugin from marketplace.json> --strict — 5/5 pass
  • marketplace ↔ plugins/ parity check, both directions
  • Portability scan across the whole repo — clean
  • markdownlint-cli2 "**/*.md" — 0 issues
  • Live codex call against the corrected find-schema.json — valid JSON, no schema rejection
  • consult dry runs across the codex, grok and claude paths, plus one live end-to-end consult
  • /plugin update on a machine running the published marketplace

https://claude.ai/code/session_01XZZYvBMcU3Q57jF1C4mA7x

Council convenes every model and runs a rebuttal round, which is the wrong
shape when you want one specific model's read on the problem in front of you.
consult asks one named model — Codex, Grok, or a Claude subagent — and hands
it the same access this session has, rather than council's read-only seats.

The session's permission mode is mapped onto each provider: plan stays
read-only, acceptEdits confines writes to the workspace, auto auto-approves
inside a sandbox, bypass stays bypass. Where the session would stop and ask
the user, a headless consultant is denied rather than silently upgraded.
Anything the consultant changes in the working tree is reported back, and
follow-ups resume the same provider session.

Claude-Session: https://claude.ai/code/session_01XZZYvBMcU3Q57jF1C4mA7x
The documented codex calls could not succeed: `codex exec review` rejects
-C, refuses --base alongside a positional prompt, and ignores
--output-schema, while find-schema.json omitted properties that OpenAI
strict structured output requires in `required`. Review seats now use plain
`codex exec` with the diff target in the brief, against a strict-compatible
schema.

Grok failures were diagnosed as auth when they are almost always quota, so
the skill advised re-running `grok login`, which fixes nothing. The seat is
invoked by name so a shell wrapper's API key still applies, quota errors are
named as quota, and effort is reported as n/a when the model's catalog marks
it unsupported instead of claiming a level that was never applied. The no-op
`--permission-mode plan` is gone; `--sandbox read-only` always was the
enforcement.

Seats are now preflighted with a one-turn smoke call before the roster is
announced, capped so one runaway seat cannot swallow a run, and gated on
file:line evidence before their output counts as a position.

Claude-Session: https://claude.ai/code/session_01XZZYvBMcU3Q57jF1C4mA7x
The validate step listed plugins by hand, so a plugin could be registered in
the marketplace and never validated — marketplace --strict passes over a
missing source directory and never opens skills. Targets now come from
marketplace.json itself, a listed plugin without a directory fails, and a
plugin directory nobody registered fails too.

The portability scan covered plugins/ only, leaving README, CHANGELOG and
workflow content unchecked, which is exactly where machine-specific paths
tend to land. It now scans the whole repo, with temp-directory patterns
added.

Claude-Session: https://claude.ai/code/session_01XZZYvBMcU3Q57jF1C4mA7x
Adds the consult section to the README — what it is, how its access model
differs from council's read-only seats — and notes council's new seat
preflight. Records both plugins in the changelog.

Claude-Session: https://claude.ai/code/session_01XZZYvBMcU3Q57jF1C4mA7x
@Droniu
Droniu merged commit e2dceae into main Sep 12, 2026
2 checks passed
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