Skip to content

v0.6.0 — Agent proposal bridge

Choose a tag to compare

@EfeAydinalp EfeAydinalp released this 03 Jul 22:17
· 84 commits to master since this release
7afa1ab

vibe-council v0.6.0 — Agent-to-Workbench proposal bridge

Ready for the v0.6.0 tag — not yet tagged. The version bump (backend/__init__.py,
pyproject.toml, uv.lock) and the dated CHANGELOG.md section are done
(chore: prepare v0.6.0 release); the repo now reports 0.6.0. The git tag and the GitHub
Release are still a separate, manual step
— see §"Final release checklist" below and
docs/release-checklist.md.

The agent-to-Workbench proposal bridge release. AI agents (Claude Code, Codex, Fable, or custom
workers) can now propose a bounded code action into the local Workbench instead of acting
directly — a human still inspects, approves, and executes. It is local file/CLI intake only (no
network endpoint): an agent writes a schema-v1 proposal JSON, vibe workbench propose validates it
and mints ids + payload hash server-side, the panel shows a proposed-by-agent card, and nothing
runs
until a human approves it and explicitly executes it through the existing, unchanged
guarded executor. Still local-first and stdlib-only: no new runtime dependency, no new network
surface, no command-allowlist growth. Based on and crediting
karpathy/llm-council.

No commercial-clearance claim. License/provenance remains an unresolved "Question 0"
commercial gate; no LICENSE is added.

What this release adds

Built across four PRs (#95#98), designed in
docs/fable/05-v0.6-agent-bridge.md /
docs/fable/06-proposal-schema.md.

Proposal schema + validation (PR #95)

  • A pure, stdlib-only validation module (backend/workbench_proposals.py) defining proposal envelope
    schema v1strict: unknown keys are rejected at every level (envelope/agent/action/
    payload/scope), never silently dropped.
  • Allowed kinds: write_file, edit_file, and run_command by exact command_label only.
  • Rejected outright (fail-closed): freeform/mutated commands; argv/env/cwd/timeout/
    shell; payload_hash; action_id/approval_id/task_id/status/risk/verdict/blocked/
    findings; cloud_call (and read_file/unknown kinds); and absolute, ..-traversal, or
    denylisted paths (.env, .git, .council, private plans, key files). File payloads have exact
    per-kind shapes, reject NUL bytes, and honor early size caps mirroring the executor bounds (the
    executor remains the final authority at execution time).
  • proposal_id is strictly charset-validated ([A-Za-z0-9._-], 1–120) — rejected, never
    sanitized
    — because it is the importer's dedup key.

Proposal importer + CLI intake (PR #96)

  • backend/workbench_proposal_importer.py turns a validated proposal into a runtime Task + pending
    ApprovalRequest + pending Action
    that flows into the existing, unchanged trust/auditor/panel/
    executor path.
  • Server mints everything: task/approval/action ids come from the runtime store; the payload
    hash is computed server-side
    from the submitted content; the internal kind:target convention is
    constructed server-side (agents never author it).
  • File payloads are stored in a local, gitignored, write-once payload artifact — never in the
    task/approval/action JSON and never in the dedup record.
  • Dedup by proposal_id (global, never agent-scoped): an identical re-import returns the original
    ids and creates nothing; the same id with materially different content is a conflict and
    fails closed (a corrupt dedup record also fails closed). No auto-execution.
  • CLI: vibe workbench propose <proposal.json | -> (stdin supported). A JSON result is printed to
    stdout (machine-readable, never raw payload); a human summary + panel next-step goes to stderr;
    failure exits non-zero and creates no runtime files.

Panel proposed-by-agent visibility (PR #97)

  • Imported agent-proposed tasks show a "proposed by agent: <name>" badge with the agent role and
    proposal_id (all HTML-escaped), so they are visually distinct from demo/manual tasks.
  • Display-only — derived from the task's existing agent:<name> source plus a read-only
    importer lookup. No raw payload content appears in the panel HTML or the /api/state JSON, and
    no tokens are exposed. XSS-safe (agent name / title are escaped).

Documentation (PR #98)

  • docs/workbench-agent-bridge.md — the end-to-end guide: overview
    and flow, safety model, CLI usage/output, safe write_file/edit_file/run_command examples,
    rejected-example/common-mistake cases, and the agent + human operator workflows.
  • docs/agent-quickstart.md gained a §10 pointer; the README gained a short
    pointer + minimal usage example.

Security posture — unchanged from v0.5.2 (only extended upstream of approval)

The bridge sits entirely upstream of the approval, so none of the v0.5 guarantees move:

  • No network endpoint — file/CLI intake only; no new HTTP API, no CORS, no LAN/mobile/remote.
  • Approval is separate from execution — importing a proposal only records a pending approval; it
    never writes a file or runs a command. Approval records a decision; execution is a further,
    separate, explicit step.
  • The existing guarded executor is the only execution path, and it re-validates the
    deterministic trust boundary at execution time
    — a stored audit or a cached preview cannot
    authorize anything.
  • The trust boundary remains the deterministic authority; the Approval Auditor remains
    advisory
    and can never relax a block.
  • Commands are exact allowlisted labels only (no command-allowlist expansion in this release), no
    arbitrary shell, no dynamic argv/env/cwd/timeout.
  • Server mints ids + hash; agents never submit them. Raw payload content stays in the local
    write-once artifact and is never rendered anywhere.
  • The v0.5.2 hardening remains in force — the panel binds 127.0.0.1, POSTs and GET /api/state
    are token-gated, and every request's Host header is validated (DNS-rebinding defense).
  • Redaction lint remains 0 critical; context check and MCP health remain 21/21.

Explicit non-goals (deferred, not started in this release)

No autonomous execution · no LAN/mobile/hosted/voice · no personalization · no project-vault
implementation · no onboarding/session-launcher implementation · no website · no new provider/model/
network call from the executor · no dependency changes. The docs/fable/ pack plans these; this
release implements none of them.

Release checklist (must be clean before tagging)

  • python -m unittest discover -s tests -t . is green (672 tests).
  • uv run python -m backend.cli --version prints vibe-council 0.6.0.
  • vibe lint --redaction reports 0 critical findings.
  • vibe decisions lint passes.
  • vibe context check scores 21/21.
  • vibe mcp inspect --context --health scores 21/21.
  • uv sync produces no uv.lock diff beyond the intentional self-version sync in this PR.
  • No .council/ artifact (including .council/runtime/payloads/) staged/committed.
  • No private/local plan file staged/committed.

Final release checklist (manual steps, after this PR merges)

These are not automated by this PR — a maintainer performs them once the checklist above is clean
on master:

  • Merge this PR (chore: prepare v0.6.0 release) into master.
  • On the merged master, re-confirm: tests green, redaction lint 0 critical, decisions lint
    passes, context check 21/21, MCP health 21/21.
  • Verify git status --short and the merged diff carry no private/local artifacts
    (.council/, the two untracked private plan files, .env/.venv//data/, secrets,
    generated packs/exports).
  • vibe --version on master prints vibe-council 0.6.0.
  • Create an annotated git tag: git tag -a v0.6.0 -m "vibe-council v0.6.0" on the merge
    commit, then git push origin v0.6.0.
  • Create the GitHub Release for v0.6.0 manually, using this document
    (docs/releases/v0.6.0.md) as the release-notes body.

Known limitations

  • Intentionally local-only — no LAN/mobile/remote access; the panel binds 127.0.0.1 only, and
    proposal intake is local file/CLI only (no network endpoint).
  • Intentionally tiny command allowlistrun_command proposals accept only the fixed
    verification/status labels; the allowlist did not grow for the bridge.
  • The demo still seeds no executable Action (a deliberate v0.5.0/PR #77 safety choice) — real
    execution dogfood requires an imported or manually-seeded action in a temp/safe project.
  • No hosted/team/mobile/voice yet — deferred to a later phase.

Next after v0.6.0

Cut the v0.6.0 tag/GitHub Release, then scope the next roadmap phase per
docs/fable/04-roadmap.md: v0.6.1 (agent session launcher / onboarding),
v0.6.2 (Obsidian-like project vault), v0.6.3 (cross-project onboarding). Personalization (v0.7),
mobile/LAN/voice (v0.8), and hosted/team (v0.9+) stay deferred behind the local core.