Repository navigation
0.15.0 — Multi-vendor unblock
·
15 commits
to master
since this release
Cohort 0.15.0 — Multi-vendor unblock
Install by cloning this repo, then ./installer/bootstrap.sh --ide claude.
Do not
pip install cohort. That name on PyPI belongs to a different project by different authors — an unrelated multi-agent orchestration tool. Installing it will look like it worked and will not install this software. There is no PyPI release of Cohort; cloning this repository is the only supported path.
⚠️ Behaviour changes — read before upgrading
This release changes things people rely on. That is why it is a minor bump rather than a patch, quite apart from 1.0.0 being deliberately postponed.
- A secret-scan suppression can no longer authorise its own egress. Entries reachable from the default branch apply silently; entries committed only on your current branch now require an interactive confirmation on a TTY. CI, git hooks and agent shells are refused — none of them has one.
- The API reviewer enforces the same gate as the CLI doer, and reads the manifest from a committed ref rather than your working tree.
- A vendor CLI that is present but broken now fails loudly and falls back to the API transport with a printed note, instead of reporting success with an empty body.
If you script against cohort engine …, read the Security section below first.
Known limitations in this release
- The grok CLI does not work. The bundled grok CLI is rejected by xAI's current API (
410 Live search is deprecated), so grok runs API-direct. Cohort detects this and announces the fallback rather than failing silently. Fixes for the sandbox reachability side landed after this tag. - Python 3.10 is genuinely supported again.
weekly-reportandmonthly-reportused to crash there, and the feedback trend silently discarded every record. Both are fixed in this release.
Added
/barney— explain a complex topic so simply nobody can get it wrong. Encodes the
method (name the one idea, decide what to omit, say where the analogy breaks, order steps
so each uses only what is already explained) rather than just asking for simpler words.
Bans "it's simple" and "just", and holds accuracy above simplicity: a danger or an
irreversible step survives the simplification.- A declared, digest-bound secret-scan manifest (
.cohort/secret-scan-allow.txt). A repo
whose fixtures are credential-shaped by construction — any secret scanner, this one
included — could not send itself to an external engine at all. Each entry binds a value
digest to a path, so exempting a file is not a blind spot: a real credential added beside
a declared fake still blocks. Refusals print the exact declaration lines, so unblocking
never means guessing a digest. - A
reasoninggrok tier (grok-4.20-0309-reasoning), probed live and confirmed to
serve back its own name.grok-4-heavydoes not exist on the account, and
grok-4.20-multi-agent-0309is deliberately unregistered — chat/completions rejects it, so
naming it would hand callers a model that fails at dispatch. - A
vendor-reachabilityaudit dimension, always-on, whose only acceptable evidence is a
command that ran and the output it produced (#243). Reading the dispatch path and
concluding a vendor works is the exact failure it exists to catch. - Model-tier rotation across audit runs —
balanced→complex-heavy→simple-heavy,
with the tier recorded per dimension in the ledger so the false-positive rate becomes
tier-aware (#240). - A README section stating what leaves your machine, to whom, per command, and the exact
cohort:egress=denymarker that stops it — with the warning that prose does not work,
only the literal marker.
Fixed
- The secret scanner no longer flags ordinary code. Self-referential keyword arguments
(max_tokens=max_tokens), forwarded attribute references (token=srv.token) and type
annotations (token: bytes) read as credential assignments. Detection is unchanged —
aGITHUB_TOKEN:orDATABASE_PASSWORD=carrying a real value still trips. Two exemptions that
went too far were caught by the audit and closed the same day: aname.surnamepassword
and any value merely starting with a type name both slipped through, the latter in:
form — which is how YAML, the dominant secrets-config format, writes every assignment. - A failing vendor CLI no longer reports success. No doer path checked the exit code, so a
broken engine read as "reviewed your repo, had nothing to say". A CLI that is present but
broken now raisesDoerFailedErrorand falls back to the vendor's API transport with a
printed note — never silently. Gate refusals are still never retried elsewhere. my-office syncno longer reports success when placement failed. A post-sync recompile
failure returned the same empty list that means "nothing installed"; it now reports
recompile_failedand says the IDE files are stale.- A corrupt manifest fails closed instead of crashing.
load_manifestraised a raw
JSONDecodeErrorout of whichever command touched it; it now raises a typed error naming
the file and the recovery, andpersistkeeps a.json.bakso there is something to
restore from. "Absent" remains a legitimate state, distinct from unreadable. - Concurrent engine reviews no longer overwrite each other's transcripts. Slots are
reserved atomically instead of computed; five parallel reviews previously produced four
transcripts, losing the record of what was egressed exactly when the fan-out was widest. - A timed-out doer now takes its whole process group with it. Only the direct child was
killed, so helpers an agentic CLI spawned outlived the wall-clock cap — still spending
against the vendor API, still writing into a worktree about to be deleted. - Bounded work that was unbounded: a 32MB client-side cap on the response body both xAI
transports buffer (max_tokensis a request hint, not a resource bound), and timeouts on
the worktree and post-doer git calls, which sit on paths a user waits on. - A failed rollback-ledger write is reported. It was swallowed, so the advertised one-shot
undo silently did not exist until someone reached for it. - Dashboard controls are keyboard-operable — the "create" cards were click-wired
<div>s
and the reload chip a bare<span>; action results and errors now announce via a live
region instead of being silent visual toasts. /consult-gptno longer appears to hang. Codex was never the problem: the command
lacked a stdin redirect and a timeout budget, so a slow consult looked identical to a hung
one.- Documentation that asserted something false:
(no local file access)was printed on paths
that do send file contents,DESIGN.mddescribed a narrower quarantine scope than
GATED_KINDSenforces, andconsult-grokrecommendedgrok-4-latest— an alias that
resolves togrok-4.3, not the flagship.
Security
- A secret-scan suppression can no longer authorise its own egress. The refusal prints
paste-ready declaration lines into the caller's context, so an agent atsupervisedor
autopilotcould commit them and re-dispatch with nobody looking — and egress is
irreversible. Entries reachable from the default branch apply silently; entries
committed only on the current branch require an interactive confirmation on a TTY, so
an agent's shell, CI and hooks are refused. Confirmation authorises declared fixtures
only — a credential nothing declares is never waved through. - The API reviewer honours the same gate as the CLI doer. Its toolbox scanned without the
manifest, so on a repo with credential-shaped fixturesread_filerefused its own source
andgrepskipped it silently — a review could look complete while missing exactly the
files it was asked to check. It also read the live tree, letting an uncommitted edit widen
what may be sent; it now reads a committed ref, like the doer.