Skip to content

Releases

0.18.0 — Audit r5 hardening

Choose a tag to compare

@askwigconsulting askwigconsulting released this 30 Sep 15:23
a86f5e1

Cohort 0.18.0 — Audit r5 hardening

Installing

Clone this repo, then ./installer/bootstrap.sh --ide claude.

Or hand an AI agent AGENTS.md and ask it to install Cohort for you.

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 but won't install this software. There is no PyPI release of Cohort, by design; cloning this repository is the only supported path.

Highlights

  • Audit r5 remediated. A 15-worker crew closed the r5 findings and the actionable r4 leftovers (#305), and the residuals followed in #308:
    • my-office quarantine hardened against symlinked artifacts
    • ratchet evaluator jailed
    • dashboard token kept to the URL fragment, never sent to the server
    • staging swapped in under a lock
    • global --dry-run honoured by every command or refused
  • /consult-gpt is code, not prose. ChatGPT consults go through cohort engine consult gpt: the egress, secret and size gates run first, then codex runs inside a bubblewrap jail that can see only the prompt.
  • The grok doer is xAI's Grok Build (#307). The old community grok-cli's API path was retired. Grok now runs again under Cohort's jail, which no longer mounts your saved ~/.grok login.
  • Local records never reach an engine. .cohort/sessions, feedback, proposals and state (git author identity, private notes) are excluded from every engine worktree and refused by the agentic read tools (#308).

Known limitations

  • No PyPI package. Deliberate; see the warning above.
  • codex reads outside the prompt when bubblewrap is absent. The consult says so before it starts. Install bwrap for the jailed path.

Changelog

Changed

  • The grok CLI doer is now xAI's Grok Build. The community grok-cli Cohort used to
    drive is unmaintained and its API path was retired (every dispatch returned a 410), and
    Grok Build's installer takes over the grok command — so Cohort was building argv the
    new binary rejects outright. It now speaks Grok Build's flags (--cwd, --max-turns,
    --permission-mode bypassPermissions, --disable-web-search), invokes the resolved
    binary rather than a PATH lookup, and accepts either XAI_API_KEY (what Grok Build
    reads) or GROK_API_KEY (what Cohort's registry declares). Confinement is unchanged and
    still Cohort's bubblewrap jail, not the vendor's own sandbox.
  • Compiled project doers are labelled "(project doer — write-capable)" instead of "advisory
    office agent"; my-office help derives the gated kinds from GATED_KINDS; --layer and
    --to are accepted as aliases on the add-* and edit commands (#300).
  • Dashboard aggregate cache TTL is 30 s (above the poll), session/feedback feeds parse only the
    newest records, parity parses canonical once per poll, and the YAML loader uses libyaml when
    available (#295).
  • CI: bubblewrap can sandbox on ubuntu-24.04 (user namespaces unlocked), the confinement tests
    fail rather than skip there, and the real-venv bootstrap round-trip runs on Linux (#277).

Security

  • The grok jail no longer mounts the user's real ~/.grok. Grok Build stores its saved
    login there, so the previous read-only bind exposed that credential to the engine — and
    still broke it, since it writes session state to the same directory. The ephemeral HOME
    now gives the engine its own, and the API key reaches it through the scrubbed environment.
  • No engine path is handed Cohort's local records any more (#306, completing #275).
    .cohort/sessions, feedback, proposals and state (git author name and email, private
    notes) are excluded at the single worktree creation point, so one-shot and agentic
    propose and the ratchet get the same exclusion the CLI doers had; a worktree whose records
    could not be excluded is discarded. The agentic read tools refuse those paths by spelling
    (case-folded) and by symlink target, and hide them from listings, grep and find.
  • A quoted signed_by key is no longer read as absent (#306). 'signed_by' = [...] is
    valid TOML; the array reader now unquotes keys like the scalar reader (#276), so signature
    pinning no longer silently fails open.
  • A symlinked artifact no longer walks through the my-office quarantine (#285). Discovery
    (compile and quarantine alike) reads only <canonical>/<kind-dir>/*.md, refuses an entry
    whose own lstat is a symlink, never descends a linked directory, and a pull that touches a
    symlink falls back to a whole-tree record. my-office review --reset / office review --reset rebuild a corrupt pending store fail-closed from disk (#294); the office baseline
    now folds at approve time, and --reset --all withholds everything regardless of a legacy
    baseline. The remedy text no longer says "delete the file".
  • ratchet confines the evaluator (#286, #237). The evaluator executes engine-written
    code, so it now runs under the scrubbed environment with an ephemeral HOME and, where
    bubblewrap is present, inside a no-network jail; _git has a timeout, non-interactive git
    hardening and commit.gpgsign=false; the evaluator is killed as a process group; the codex
    path applies the wire cap and worktree secret scan; the egress opt-out is read from the repo.
  • /consult-gpt is gated in code (#266). OpenAI Codex is a registered engine
    (gpt/chatgpt/openai aliases; xai for grok) and cohort engine consult gpt runs the
    egress marker, size cap and secret scan on the assembled prompt before codex exec --sandbox read-only, jailed under bubblewrap to an empty scratch root and an ephemeral HOME
    holding only codex's auth; without bwrap it says so. The command file no longer runs codex exec itself. engine review checks the review role, so a consult-only engine cannot be
    routed to the xAI review transport.
  • Doer preflight refuses tracked symlinks (#288) before reading anything; the doer
    worktree no longer ships .cohort/sessions, feedback, proposals or state (#275).
  • Secret scanner catches escaped JSON, YAML block scalars, bracketed and prefixed literals,
    :=, lowercase bearer, AWS ASIA… and xai-… keys (#289).
  • The dashboard token is no longer served to any loopback client (#293): it travels only
    in the URL fragment the CLI prints and opens.
  • Executor refuses a destination whose parent escapes the declared root via a symlink
    (#276)
    ; [update] honours quoted TOML keys.

Fixed

  • cohort gc --scan-deadline SECONDS exposes the scan budget (finite, > 0) and reports how
    many candidates went unexamined, in text and --json; a timed-out scan no longer prints
    "Nothing to reclaim" (#306).
  • The dashboard says when the office feed is partial: "⚠ N projects unreadable", with the
    names on hover (#306).
  • Engine worktrees tolerate non-UTF-8 tracked file names instead of crashing the dispatch.
  • import cohort.cli no longer loads urllib.request; the xAI transport imports it on
    first use, trimming every hook invocation (#306).
  • The test suite no longer leaks cohort-proposal-* worktrees into the system temp dir;
    pytest keeps only failed runs' temp dirs (#306).
  • Global --dry-run is honoured by every command or refused with exit 2 (#267); status
    exits 1 when it printed a ! diagnostic and --json carries ok; my-office sync names a
    real remedy and exits non-zero on a failed recompile; /api/state lists skipped projects (#270).
  • Staging is swapped in under the manifest lock (#291); roster and adopt append under the
    lock (#292); the rollback ledger is locked and atomic; quarantine reconcile scans under the
    lock (#290).
  • Duplicate YAML keys are an E001; an unknown tools name is E021 (the vocabulary is declared
    in canonical/schema/agent.json); _SHARED_KEYS derives from the schema; the frontmatter
    delimiter is only recognised at column 0; docs/quick-reference.* shows each command's own
    description (#297, #299).
  • Unquoted YAML timestamps no longer drop records or 500 the dashboard; quoted auto_capture
    is read correctly; gc keeps the newest transcripts by number and has a scan budget;
    report says an issue may already exist on a timeout (#299, #268, #269).
  • Docs: AGENTS.md documents the comma form of --ide (repeats keep only the last);
    staleness-check always exits 0; the orchestration-cap lint scans README and docs; RFC
    0001's prerequisite is marked resolved; the autonomy memory states the machine-local truth;
    README qualifies "no phone-home" and lists report/update-check egress (#296, #271, #279, #280).
  • Dashboard: every dialog control has a label, --faint meets AA inside cards, action buttons
    carry aria-label, the three homes are OFFICE / MY OFFICE / PROJECT; --help uses plain
    formatting under NO_COLOR or TERM=dumb (#298, #300).
  • Secret scanner: quoted keys and label-glued assignments were exempt (#265). The
    generic-assignment rule required the separator to follow the identifier directly, so
    {"password": "..."} (JSON, the shape a config dump or API error body takes) and quoted
    YAML/TOML keys never matched. And because a harmless label's value token runs to the next
    whitespace, WARN: DB_PASSWORD=..., x=1;PASSWORD=... and a backticked PASSWORD=...
    were consumed as the label's value and skipped over. Every egress path that relies on the
    rule was affected: cohort report bodies, the CLI-doer tracked-file scan, the API toolbox
    per-read scan, and /consult-* prompts. The identifier may now be closed by a quote, and
    a consumed value is rescanned from its start so an embedded KEY=value is a candidate in
    its own right. Two escaped-source fixtures the old scanner missed in this repo's own tests
    are now declared in the suppression manifes...
Read more

0.16.0 — Agent-driven install

Choose a tag to compare

@askwigconsulting askwigconsulting released this 01 Aug 12:31
a066ebf

Cohort 0.16.0 — Agent-driven install

Installing

Clone this repo, then ./installer/bootstrap.sh --ide claude.

Or hand an AI agent AGENTS.md and ask it to install Cohort for you — that is a supported path as of this release, and it is how most people here actually install it.

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, by design; cloning this repository is the only supported path.

Why a minor bump for a mostly-fixes release

AGENTS.md establishes a supported install contract. Since Cohort is distributed by asking an agent to install it rather than through a package index, those instructions are part of the product surface rather than documentation about it — a new supported surface, not a bug fix.

Every step in it carries a check the agent must pass before continuing, because a step you can perform but cannot verify is not finished.

Known limitations, unchanged

  • The grok CLI still does not reach xAI. This release fixes the half that was ours — the bubblewrap jail never bound the launcher, so a grok installed the documented way (npm install -g --prefix ~/.local) was invisible to it and had, in fact, never worked. It now runs, authenticates, and reaches the API — where xAI rejects it with 410 Live search is deprecated. That part is upstream. Cohort detects the failure and announces the fallback to API-direct rather than serving you an error string as a review.
  • No PyPI package. Deliberate. See the warning above.

Added

  • AGENTS.md — the install contract for an AI agent. Cohort is distributed by asking an
    agent to install it, not via a package index, which makes the install instructions part of
    the product surface. Every step carries a check the agent must pass before continuing,
    because a step you can perform but cannot verify is not finished. It also states, up front,
    what an installer should tell the user before installing: that this writes into their home
    directory, and that consult commands send source to a third-party vendor by default.
  • A prominent warning that pip install cohort is a different project. The name on PyPI
    belongs to an unrelated multi-agent orchestration tool. Under a package-index model that is
    a naming annoyance; under agent-driven install it is a correctness bug — an agent told
    "install cohort" will plausibly run it, install the other package, and report success.
  • An inbound-licence statement in CONTRIBUTING.md. No CLA, no copyright assignment —
    opening a pull request is the agreement, and contributors keep their copyright. The clause
    that earns its place is right-to-license: work written on an employer's time may belong to
    the employer, and that cannot be undone after a merge and a release.

Fixed

  • The grok CLI is reachable inside its sandbox. The bubblewrap jail bound /usr but not
    the real home, so a grok installed the documented way (npm install -g --prefix ~/.local)
    was invisible and every run died at execvp. The CLI doer had therefore never worked for a
    user-local install. Binding the launcher alone is not enough — npm installs it as a symlink
    into a package tree — so the launcher's directory and the node_modules root above its
    target are both bound read-only, skipping anything already under /usr.
  • A grok CLI run that fails at the vendor is no longer served as a review. grok-cli reports
    API errors as an ordinary assistant turn and still exits 0, so a well-formed transcript could
    contain nothing but Sorry, I encountered an error: … 410 and be handed back as the answer.
    Only an entirely failed run counts, so a transient error followed by real analysis is still
    a review rather than discarded work.
  • cohort init no longer scaffolds repos that commit their engine transcripts. Transcripts
    record what an external engine read and was sent — excerpts of the repo's source plus the
    model's analysis. They are a local audit trail, and nothing else in the scaffold ignored
    them, so a routine git add -A committed them and a repo that later went public published
    the lot.
  • Office quarantine prunes records whose artifact no longer exists. office_reconcile was
    written for this and called from nowhere, so office pending records only ever grew and
    cohort office review listed identities a reviewer could not resolve — the artifact they
    would approve had been deleted upstream or superseded by a later pull.
  • Removed ToolPolicyError, an exception class defined once and never raised or caught, left
    behind when tool refusals became return values.

0.15.0 — Multi-vendor unblock

Choose a tag to compare

@askwigconsulting askwigconsulting released this 01 Aug 04:14
e16980b

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-report and monthly-report used 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 reasoning grok tier (grok-4.20-0309-reasoning), probed live and confirmed to
    serve back its own name. grok-4-heavy does not exist on the account, and
    grok-4.20-multi-agent-0309 is deliberately unregistered — chat/completions rejects it, so
    naming it would hand callers a model that fails at dispatch.
  • A vendor-reachability audit 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=deny marker 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 —
    a GITHUB_TOKEN: or DATABASE_PASSWORD= carrying a real value still trips. Two exemptions that
    went too far were caught by the audit and closed the same day: a name.surname password
    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 raises DoerFailedError and falls back to the vendor's API transport with a
    printed note
    — never silently. Gate refusals are still never retried elsewhere.
  • my-office sync no longer reports success when placement failed. A post-sync recompile
    failure returned the same empty list that means "nothing installed"; it now reports
    recompile_failed and says the IDE files are stale.
  • A corrupt manifest fails closed instead of crashing. load_manifest raised a raw
    JSONDecodeError out of whichever command touched it; it now raises a typed error naming
    the file and the recovery, and persist keeps a .json.bak so 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_tokens is 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-gpt no 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.md described a narrower quarantine scope than
    GATED_KINDS enforces, and consult-grok recommended grok-4-latest — an alias that
    resolves to grok-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 at supervised or
    autopilot could 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 fixtures read_file refused its own source
    and grep skipped 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.

v0.14.0 — Dashboard usability

Choose a tag to compare

@askwigconsulting askwigconsulting released this 31 Jul 03:49
602cb75

Changed

  • Dashboard UI/UX overhaul (from a multi-vendor UX /scout). The dashboard now
    answers "is anything wrong / what do I do?" at a glance: a "needs attention" strip
    under the header surfaces only the non-green states (source broken, IDE output behind,
    unmanaged files, commits behind, stale context, low-rated agents), each linking to its
    fix, and collapses to a quiet line when all's well. The static "Under the hood" explainer
    is demoted to a closed disclosure at the bottom (its "wire" now animates only during a
    pending recompile/update), and sections are reordered to the company/you/project mental
    model with telemetry last. Status vocabulary is now plain and actionable — parity →
    compiled ("IDE output is behind your source — recompile"), wiring → connected,
    not on roster → inactive — with explanatory role-chip tooltips (advisor / doer /
    router) and a plain-English Recompile tooltip. The trust-critical ⚡ doer flag is now
    amber and legible; kind-tag colours no longer collide with the green/amber/red state
    palette; the project switcher looks clickable; the sparkline grows from a true zero
    baseline; dialog dropdowns are themed.

Fixed

  • Dashboard no longer blanks on a degraded response (a regression from 0.13.0's
    /api/state failure-isolation): the client now detects the degraded 200, shows a
    persistent error banner, and keeps the last good view instead of throwing on the missing
    roster and rendering a blank page.
  • Keyboard focus and an open project switcher survive the 6-second poll — the auto-refresh
    no longer dumps a keyboard user back to the top of the page every poll (it was silently
    undercutting the accessibility work).
  • The dashboard "live" indicator now reflects real poll health — after a server restart
    (or any 401 / repeated poll failure) it flips to "disconnected — reload" with a one-time
    toast, instead of pulsing green while every request silently fails.

v0.13.0 — Sandbox & dashboard hardening

Choose a tag to compare

@askwigconsulting askwigconsulting released this 31 Jul 03:02
47a924f

Security

  • External-engine doers hardened (audit r2). Closed a TIOCSTI jail-to-host escape:
    the grok bubblewrap argv gains --new-session and both the grok and codex doers now run
    with stdin=DEVNULL + start_new_session=True, so a compromised sandboxed engine has no
    controlling TTY to inject host shell commands through. Narrowed the grok jail's readable
    /etc: instead of binding all of /etc, only the TLS + resolver paths are bound
    (existence-guarded), so machine secrets under /etc are no longer exposed to a model over
    the open network. The egress opt-out is now derived from repo_root/.cohort/project_context.md
    when a caller omits the context (fail-closed), so a doer can't silently ship an opted-out
    repo. (#225, #227, #229)

Fixed

  • Dashboard /api/state no longer re-scans everything every poll, and one bad file can't
    500 the whole dashboard (audit r2).
    A short-TTL aggregate cache memoizes the office-wide
    read-only scans (parity re-parse, cross-project activity/scorecards, list_projects) —
    invalidated on every mutating action — instead of O(projects × files) work every 6s; and
    per-project reads now skip+log a corrupt/non-UTF-8 file with a do_GET backstop that
    degrades gracefully rather than failing the whole response. (#226)
  • filelock stale-steal / token-release made atomic (audit r2). Every lock removal now
    goes through an atomic os.replace capture + verify + O_EXCL reinstate, so two waiters
    can no longer delete each other's fresh lock in a stale-gated race. (#230)
  • The agentic engine loop now has an overall wall-clock deadline (default 600s, checked
    each round) and a bounded retry backoff, so a slow vendor API can't pin a user-waited
    consult/propose for ~90 minutes. (#231)

Changed

  • Dashboard accessibility (audit r2): the feedback sparkline no longer conveys up/down by
    color alone (per-bar labels + direction), a prefers-reduced-motion path stops the
    continuous animations, low-contrast --faint text now meets WCAG AA, focusable cards show a
    visible focus ring, and the project switcher is labeled. (#232)
  • Raised the external-engine wire-byte cap 5 MB → 50 MB so engine review/propose grok
    isn't refused on ordinary repos (the cap targets runaway data blobs, not normal source);
    still fail-closed. Recorded the grok-cli-as-doer decision as an amendment to RFC 0004
    (it reversed the RFC's "grok is API-direct, never a doer" decision), and corrected stale
    in-code docstrings. (#233, #228)

v0.12.0 — CLI-first external engines

Choose a tag to compare

@askwigconsulting askwigconsulting released this 31 Jul 01:59
68cac12

Changed

  • External engines prefer the local sandboxed CLI over the API-direct path. When an
    engine's CLI is installed, agents now run it locally (real, worktree-scoped repo access)
    instead of packaging a payload to the vendor API — because a CLI-driven engine can read
    and edit the actual repo, while the API only ever sees what's sent. Codex was already
    CLI-first; grok was the gap. cohort engine review / consult / propose grok now prefer
    the bubblewrap-sandboxed local grok CLI (a new read-only run_grok_review runs grok
    in a throwaway worktree and keeps only its answer; propose emits the worktree diff,
    never auto-applied) and fall back to the xAI API-direct path with a printed note when
    grok/bwrap aren't present. The read and write paths share one gate helper, so both
    run the identical egress/secret/wire-byte gates before grok — and the API path is
    reachable only when the CLI is absent: a gate refusal on the CLI path never falls back to
    the API. A --footprint violation on the CLI propose path now exits non-zero, matching
    the API path's rejection. Security-reviewed; the "grok-cli is broken/unsandboxed"
    guidance (a pre-0.10.0 leftover) is removed.

v0.11.0 — Generative brainstorming

Choose a tag to compare

@askwigconsulting askwigconsulting released this 31 Jul 00:07
9beb6df

Added

  • /brainstorm — the generative sibling of /audit. A recurring, rotating,
    ledger-backed command for generating and pursuing new opportunities and ideas. Where
    /audit finds what's wrong with what exists, /brainstorm finds what could exist,
    running the same machinery (cross-vendor, coordinator-synthesized, read-only/advisory)
    inverted for creativity: diverge wide across ten creative lenses (jobs-to-be-done,
    cross-industry analogy, inversion, first-principles, constraint-shift, tech-leverage,
    moat/network-effect, adjacent-expansion, persona, timing) with judgment deferred and
    cross-vendor used for divergence not convergence; converge via cluster/score/
    red-team; then pursue — each survivor becomes a pursuit plan (riskiest assumption →
    cheapest validating experiment → hand-off to /scout, a spike, or /crew). Keeps
    docs/brainstorm/ledger.md so it compounds run over run and never re-generates a killed
    idea. Read-only and advisory — it points at what to build or learn next, never builds.

v0.10.0 — Recurring audit & the supervision dial

Choose a tag to compare

@askwigconsulting askwigconsulting released this 30 Jul 14:18
beb37f9

Added

  • Working memory: continuous mid-session capture, consolidated at boundaries.
    Context is now staged as you work, not only at a boundary. A new global
    working-memory memory prompts the model to stage durable context at task milestones
    (cohort working-note "…"), and a deterministic Stop hook (cohort working-capture)
    records what changed each turn as a backstop — both into a git-ignored, disposable
    .cohort/state/working-memory/. At the next compaction or session start,
    compact-recall/session-recall surface the staged notes so the durable ones are
    promoted into memory and the rest cleared. This captures the reasoning an exit can't
    (there's no model turn at exit) because it's written during turns. Adds a canonical
    stop hook event, mapped across all three adapters. Governed by the same auto_capture
    opt-out.
  • session-recall — the exit→next-session memory bridge. At SessionEnd the
    model gets no turn and its context is already gone, so nothing model-authored can be
    saved at exit — which is how a closed session lost its context. A new global
    session-recall hook closes the gap from the next session's side: on a
    non-compaction session_start it surfaces the prior session's auto-captured record
    once and injects a nudge to promote its key decisions, in-flight state, and open
    questions into durable memory before resuming. It writes nothing but a git-ignored
    marker (so each record surfaces at most once) and stays silent on the compact
    source, where post-compact-memory already owns the recall. The exit-time analog of
    the pre-compact-capture/post-compact-memory pair.
  • Grok can write code natively, sandboxed by bubblewrap. cohort engine work grok
    now dispatches grok-cli as a write doer that edits a throwaway worktree directly — the
    Codex-equivalent "native filesystem" path, so Grok can implement and review with real
    file access, not only propose a gated patch. Because grok-cli has no sandbox of its
    own, Cohort imposes one with bubblewrap: every write is kernel-confined to the
    worktree, the user's real home (SSH keys, other repos) is not mounted, and only the
    network for the xAI API is left up. The API key rides the environment, never argv.
    Requires bwrap (Linux); where it's absent the doer refuses rather than run grok
    unconfined, and engine propose grok --agentic remains the gated fallback.
  • Supervision dial: cohort autonomy (paired → autopilot). Choose how often Cohort
    stops to ask, from confirm-every-step to run-up-to-the-PR. It tunes discretionary
    friction over cheaply-reversible actions only, on a fixed safety floor no level can
    lower: the human PR-merge gate, the code egress/secret/footprint gates, verification of
    every foreign diff, and the operational hard-limits — and confirm-for-irreversible stays
    stop-and-ask at every level. "Full autopilot, no checks" is deliberately not offered
    (merge is human by construction; the honest ceiling is autopilot up-to-PR). The level
    is machine-local (stored under state/, never synced) and fail-closed, so a pulled
    config can never raise a machine's autonomy. A new autonomy-levels memory + a
    session-start hook make the current level ambient to the coordinator.
  • /audit — recurring, rotating whole-application adversarial audit. The recurring
    sibling of /scout: rather than reviewing a target you name, it audits the app you
    didn't, on a staleness rotation with a coverage ledger (docs/audit/ledger.md) so no
    dimension goes more than ~4 runs unlooked-at — and it sweeps the project's declared
    critical path (whatever can move money, write prod data, grant access, deploy, or
    act irreversibly) every run. Fourteen distinct dimensions, each with a diagnostic
    "tell" (critical-path, security, correctness, concurrency, resilience, dead-ends,
    honesty, performance, naming, docs, tests, supply-chain, accessibility, ops),
    cross-vendor fan-out, round-two refutation, and a close-the-loop step (file tickets,
    update the ledger, record per-dimension false-positive rate). Read-only and advisory,
    coordinator-verified — same posture as /scout. Generalized from a project-specific
    audit command so it fits any application, not one domain.
  • GitHub Copilot CLI renderer (--ide copilot, experimental). A fourth renderer
    alongside Claude/Codex/Cursor, doc-verified 2026-07-24 against the official Copilot
    CLI docs (docs.github.com/en/copilot). Agents compile to
    ~/.copilot/agents/<name>.md with a real tools: alias allow-list
    (read/search/web/edit/execute); advisory is enforced mechanically by
    restricting that list to the read-only aliases, the same invariant Claude/Codex/Cursor
    apply via their own mechanisms. Skills compile to ~/.copilot/skills/<name>/SKILL.md.
    Hooks compile to their own dedicated ~/.copilot/hooks/cohort-hooks.json — Copilot
    loads every *.json under hooks/ independently, so no merge op is needed there,
    unlike Codex/Cursor. Memory merges an @import into
    ~/.copilot/copilot-instructions.md, mirroring Claude's CLAUDE.md shape. command
    is a declared parity gap (Copilot CLI has no user-definable slash-command mechanism).
    Same experimental, doc-cited-but-not-live-verified caveat Codex/Cursor already carry.
  • /audit gains a business track (go-to-market, business-ops, privacy). The audit now
    reviews the business that ships the app, not only the code, as a second track with
    its own evidence standard — a named artifact or a searched-and-documented absence
    rather than file:line — budgeted separately so a business dimension never displaces a
    code one. Adds a privacy code dimension (are the rights the law grants actually
    executable in code — deletion, export, opt-out — with the deletion-vs-retention trap
    named), go-to-market and business-ops business dimensions, a business-context
    declaration in the ledger (stage, jurisdictions, entity/filings, data categories,
    regulatory posture), top-tier + web-search + two-vendor routing for the business track,
    and a hard "no legal/compliance conclusions" guardrail — reviewers frame questions
    and tag anything needing counsel REQUIRES PROFESSIONAL OPINION, and never touch personal
    data to test a privacy claim. Go-to-market joins critical-path as always-on.

Changed

  • Session capture is on by default now (opt-out, was opt-in). auto_capture
    flips from false to true in the scaffold and in the read default, so a session
    end writes its minimal record (branch, change summary, timestamp) to
    .cohort/sessions/ unless a repo sets auto_capture = false. This is what feeds the
    new session-recall bridge — exit context is no longer lost silently.
  • Orchestration cap raised to 20, with an optional federated three-tier mode. The
    global in-flight cap moves from 10 to 20, and /crew gains a Director→Manager→Agent
    mode for large work: the Director delegates task-groups to ephemeral manager
    sub-coordinators (≤5 agents per manager, ≤20 global), each verifying its own group while
    the Director re-verifies group contracts and every foreign-engine diff. It stays
    coordination discipline — no declared graph, no persisted status, no durable-session
    scheduler (that's the design a prior panel rejected). Requires the platform to permit
    nested agents (CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=2, or Agent Teams for the top
    tier); flat single-coordinator is the fallback. Both cap numbers are single-sourced in
    docs/model-tiers.md and lint-checked for drift. New docs/orchestration-patterns.md
    documents when federation pays off (and when it's over-engineering); ship.md's stale
    "subagents cannot spawn subagents" is corrected to "not by default."
  • Supply-chain hardened. Floating dependency ranges are bounded (PyYAML<7,
    pytest<10, jsonschema<5) so a build can't silently pull a new major; a new
    requirements.lock pins the exact runtime dependency closure for reproducible installs
    (pyproject.toml keeps the human-authored ranges); jsonschema moved to dev-only (it
    was an unused runtime dependency); and CI installs bubblewrap so the grok
    confinement test runs instead of silently skip-gating.

Fixed

  • Concurrent-writer races on all JSON state, closed with a portable file lock. A new
    stdlib filelock.py (an O_CREAT|O_EXCL lock-file — the one primitive identical on
    POSIX and Windows — plus a stale-steal and an acquire timeout) serializes every
    read-modify-write on the project registry, the install manifest, and the sync
    quarantine. Two concurrent cohort processes could previously lose a manifest op record
    (a placed file with no reversal entry, breaking uninstall) or drop a quarantine record
    (a gate bypass). The manifest guard covers every RMW call site, with the fresh-init
    bootstrap and the full-uninstall state/ teardown correctly left unlocked.
  • Sync quarantine no longer trusts a just-pulled artifact. cohort update seeds the
    trusted-office baseline from the pre-pull tree, so an artifact a pull introduces is
    measured as a delta and withheld for review instead of folded into "trusted" on the
    first update.
  • Python 3.10 floor restored. The tomllib import (3.11+) is guarded with a minimal
    fallback parser, so cohort no longer crashes at import on the declared 3.10 floor; CI
    now tests 3.10 alongside 3.12.
  • Assorted audit LOW fixes: the egress opt-out fails closed on any indentation and a
    .git path can't be smuggled past the gate via a Windows trailing-dot segment;
    dangling-symlink uninstall only removes a link still pointing at our recorded target;
    SCAFFOLD ops default to preserved on pre-migration manifests; --force hook restore
    replaces a diverged entry instead of duplicating it (it would otherwise fire twice).

Security

  • **External-engine egress ...
Read more

v0.9.0 — Project memory visibility

Choose a tag to compare

@askwigconsulting askwigconsulting released this 24 Jul 01:15
dadbda9

Added

  • cohort lint single-sources the orchestration in-flight cap. The "≤10 agents
    in flight" cap is restated across five canonical files; the lint now declares the
    number once in docs/model-tiers.md and fails if any canon file drifts to a
    different one — anti-drift only, not runtime enforcement. A DESIGN [S] note records
    that the orchestration invariants (the cap, footprint-disjointness, signoff) are
    coordinator discipline plus the human PR gate by design: a declared orchestration
    graph and a PreToolUse hook counter were both evaluated and rejected (static checks
    are vacuous/impossible/duplicate; a hook counter is install-global and deadlocks on a
    crashed subagent).
  • Dashboard surfaces each project's agent-memory store. Project cards now show a
    🧠 N memories chip for the Claude Code per-project memory store
    (~/.claude/projects/<slug>/memory/) — where a project's session memory actually
    accumulates at compaction — with the newest-write time in the tooltip. This is a
    different tier from Cohort's own .cohort/canonical/memories/, and was previously
    invisible, so an active project looked memory-less. Read-only and content-free (count
    and freshness only, never file contents — the same posture as the project-memory
    git-state chip).

v0.8.0 — External engines & guardrails

Choose a tag to compare

@askwigconsulting askwigconsulting released this 23 Jul 22:39
a1db8c6

Added

  • Grok as an agentic doer: cohort engine propose --agentic. The external engine
    now EXPLORES the repository read-only (list_dir/read_file/grep/find_files, each
    read egress-gated, the whole exploration recorded to an inspectable transcript) to
    gather its own multi-file context, then proposes a patch — instead of working from a
    Claude-packaged bundle. The trust boundary is unchanged: the proposed patch is parsed,
    re-gated (footprint + sensitive class + secret backstop), and applied only inside an
    isolated worktree by the same path the one-shot proposer uses. Grok writes real code
    that lands, coordinator-verified and PR-reviewed; it is never handed a write tool.

  • /crew is the single orchestration command (renamed from /orchestrate), carrying
    the full protocol plus the cross-vendor doer rule: Claude subagents write directly,
    external engines only ever propose gated patches.

  • External engines (RFC 0004): Grok, API-direct. /consult-grok brings xAI's
    Grok into the office as an advisory second opinion (a sibling of /consult-gpt), and
    cohort engine propose lets Grok act as a patch_proposal engine — Cohort, never the
    engine, parses its reply and applies it inside a throwaway git worktree behind
    code-enforced gates (egress opt-out block, fail-closed secret scan, footprint +
    sensitive-path denylist) and the unchanged human PR gate. Reached over the xAI HTTP API
    (stdlib urllib, GROK_API_KEY from the environment); the community grok-cli was
    rejected on security/privacy/procurement review (a 400-round agentic editor with no
    read-only mode conflicts with the untrusted-input invariant). Stdlib-only, no new deps.

  • Orchestration gains a worker kickback (escalation from below). A non-Fable
    worker that judges a task genuinely beyond its tier returns it — with a specific
    reason — instead of shipping a plausible-but-uncertain attempt; the coordinator
    escalates a tier immediately (skipping the same-tier retry), or raises a
    Fable-suited one to the user. Complements the coordinator's top-down routing and
    signoff so a tier mismatch is caught before the attempt, not only after. Lives in
    fable-mode's scope gate, with an abuse guard (name the mismatch, never "too hard").

  • Dashboard: project memories show their git state. A tracked / untracked /
    uncommitted / no git chip on project-memory cards, so "this instruction ships to
    everyone who clones" vs "local-only, no audit trail" reads at a glance. Batched git
    lookup (constant calls, not per-file) since the endpoint is polled. Informs, never
    gates (#182).

  • Project-scoped memories are authorable: cohort add-memory --to project.
    Writes a scope: project memory into <repo>/.cohort/canonical/memories/; the project
    tier compiles it and wires @import cohort/CLAUDE.cohort.md into the repo's CLAUDE.md
    (and unwires it when the last one goes) — the compile half already existed, only the
    authoring path was missing. A project memory loads in every session in the repo and
    travels with it
    , so Cohort surfaces the new git_state signal (tracked / untracked /
    uncommitted) at authoring time — tracked means changes are reviewable, untracked means no
    audit trail. It reports and never blocks: the choice is the user's (#182).

  • docs/model-tiers.md — the single tier→model mapping, lint-guarded. One
    documented home for both the agent model: tiers and /orchestrate's routing
    tiers; cohort lint fails if it drifts from the renderer's _MODEL_MAP or lists
    an orchestration tier the canon no longer uses, so a model-generation sweep is
    enumerable and can't miss a file.

  • cohort lint — documentation-parity check. Guards the drift the golden
    locks don't: counts stated in human docs (an "N-agent roster" line) must match
    the real number of canonical artifacts, derived from the filesystem. Runs in CI.

  • operational-hard-limits memory — blast-radius rules in every session.
    Non-negotiable limits (no destructive data ops, prod read-only, PR-only changes,
    no force-push, secrets never move) compiled into the memory corpus. Complements
    the advisory invariant (which governs tools) by governing actions; a coordinator
    restates them per fanned-out worker.

Fixed

  • RFC 0004 gate hardening (pre-merge review). Five defects found reviewing the
    Grok engine before merge, each with a regression test that fails without the fix:
    cohort engine consult ran no gates at all — the per-repo egress opt-out and the
    secret scan existed only as prose in the compiled command, so an opted-out repo still
    egressed; a proposed path could traverse a symlink to redirect an in-footprint
    write to a sensitive location inside the worktree while the manifest reported the
    lexical path, showing the reviewer a file that was not the one on disk; a footprint
    entry sensitive in one class laundered paths sensitive in another (authors/**
    granted .git writes, via prefix matching that also mis-classified innocuous names);
    a Windows drive-qualified path (C:\…) passed the scope gate on every platform; the
    proposal worktree leaked on any unanticipated exception or Ctrl-C, and is now
    created only once the reply is parsed and gated; and apply_patch wrote CRLF on
    Windows, violating the repo's eol=lf byte-stability invariant. Also: engine replies
    are now escaped before reaching the terminal on the consult path, and non-PatchError
    stdlib exceptions (UnicodeDecodeError, OSError) fold into PatchApplyError.
  • Dashboard: a project-scoped artifact in a focused project now loads. The
    detail pane rendered an agent's card from the focused project's inventory but then
    reported no agent '<name>' in project, because /api/artifact dropped the
    project param and resolved against the dashboard's launch directory instead of
    the switched-to repo. It now carries the focused project through, resolved via the
    registry index like /api/state and run_action already did (never a client path).