v0.8.2 — Preference schema and validator
vibe-council v0.8.2 — Preference schema v1 + read-only doctor validator
Ready for the v0.8.2 tag — not yet tagged. The version bump (
backend/__init__.py,
pyproject.toml,uv.lockself-version) and the datedCHANGELOG.mdsection are done
(chore: prepare v0.8.2 release); the repo now reports0.8.2. The git tag and the GitHub
Release are still a separate, manual step — see §"Final release checklist" below and
docs/release-checklist.md.
The preference-control slice of the v0.8.x "Solidify the core, local-first" line: a normative,
tighten-only preference schema v1 plus a read-only validator folded into vibe project doctor.
This is the "auditable before executable" gate — the schema is defined and validated but never
applied. No preference influences any behavior, no council/persona behavior changes, no new
command, no new dependency. Based on and crediting
karpathy/llm-council.
No commercial-clearance claim. License/provenance remains an unresolved "Question 0"
commercial gate; noLICENSEis added.
How v0.8.x was planned (council-backed + Fable architecture)
- Council-backed planning (docs-only):
v0.8.x-council-debate.md
weighed candidate directions;v0.8.x-phase-brief.mdcaptured the
resolved theme;v0.8.x-fable-input.mdwas the curated handoff. - Fable architecture plan (docs-only, version-line — architecture-only, no implementation):
v0.8.x-architecture-plan.mdresolved the open questions into
a 9-PR sequence. v0.8.2 is PR 7 (the schema) + PR 8 (the validator, at full review) plus
this release prep (PR 9).
What this release adds
Preference schema v1 (PR 7)
- A normative spec —
docs/fable/preference-schema-v1.md— and a
single bounded (≤ 4096-byte) fencedjsonblock in
docs/context/project/PREFERENCES.md(Markdown stays the source
of truth; the block is the machine-checkable region). - Exactly four tighten-only keys plus the required
schema: 1:default_review_preset— enumcheap | balanced | full(a review floor;premiumis not in
the enum and can never be named).extra_sensitive_paths— array of relative path prefixes (additive extra-guarding).never_stage_extra— array of relative paths (additive no-stage extension).require_usage_flag— boolean; onlytrueis meaningful (warn when--usageis absent).
- Tighten-only by construction: every legal value can only add friction/checks; the schema has
no vocabulary to loosen a safety/security/no-stage/trust rule, change the Workbench executor/trust
boundary, add shell/auto-execution/network/hosted behavior, override the review policy, or
hide/suppress dissenting council opinions. - Council personas (Cost Skeptic, Security Guardian, Product Strategist, Local-first Guardian,
UX/User Advocate, Risk Officer, Commercialization Lens) are documented as an illustrative, future
v0.9.x direction — curated presets of these tighten-only values, never a policy override. They are
not v1 fields and are not applied.
Read-only preference validator in vibe project doctor (PR 8, full review)
- New pure module
backend/preferences.pyvalidates the schema v1 block
and returns findings only (Finding(level, message)— never parsed settings; parse helpers are
private). It is read-only (reads exactly one file), writes nothing, creates no.council/, and
never reads a.council/profile.*store. vibe project doctorgains an advisoryPreferences (machine-readable, advisory):section:
a valid block →[ok ], a missing block → informational[note](prose-only is fine), an
invalid block →[warn]with the reason and "ignored (not applied to anything)".- READY/NOT-READY and exit code are unchanged — a missing or invalid block is never a doctor
failure (failure stays reserved for missing required docs + dangerous staged files). - Hardening (fail-closed on any anomaly): first/only fenced
```jsonblock, 4096-byte cap,
stdlibjson.loadsonly (nojsonschema/pydantic/YAML/TOML), key allowlist, strict per-key
types, relative-path checks (reject absolute / drive-letter /../ backslash / non-string;
traversal detected across both separators), empty-array + duplicate warnings, missing/unknown
schema version rejected (a JSONtruerejected as non-integer), realpath-inside-project-root
symlink defense (generic warn, no content/target leak), UTF-8-only (UnicodeDecodeError→ clean
warn). - The module exposes findings, not settings: a test asserts no module outside the doctor path
importsbackend.preferences, so a parsed value can never be wired into behavior.
Safety posture — unchanged from v0.8.1
- No preference application and no council/persona behavior application — the schema is
validated into a report, never routed into any command's logic. Application is deferred to v0.9.x. - No local
.council/profile.*store, no preference applier, no named-persona runtime. - No guide/context-export behavior change — those stay pointer-only (never inline the block).
- No Workbench trust-boundary/executor/proposal/importer/panel change, no command-allowlist growth.
- No model/provider/API call, no vector DB / database / hosted stack, no network/LAN/mobile
surface, no new dependency (stdlib-only; the onlyuv.lockchange is thevibe-council
self-version line). Redaction lint stays 0 critical (30 warnings);context checkand MCP health
stay 21/21.
Explicit non-goals (deferred, not started in this release)
No named persona runtime · no UI/dashboard persona controls · no local .council/profile.* store · no
preference applier · no Workbench/executor/trust changes · no hosted / network / LAN / mobile mode · no
vector DB / database stack · no /council real command. v0.8.2 is the schema + read-only validator
infrastructure only.
Release checklist (must be clean before tagging)
-
uv run python -m unittest discover -s tests -t .is green (919 tests). -
uv run python -m backend.cli --versionprintsvibe-council 0.8.2. -
vibe lint --redactionreports 0 critical (30 warnings, expected). -
vibe decisions lintpasses. -
vibe project doctorreports READY and shows thePreferences (machine-readable, advisory):
section. -
vibe context checkscores 21/21. -
vibe mcp inspect --context --healthscores 21/21. -
uv syncproduces nouv.lockdiff beyond the intentional self-version sync in this PR. - No
.council/artifact (incl..council/runtime/payloads/and.council/profile.*)
staged/committed; no rootCLAUDE.md/AGENTS.md/FABLE.md; no private/local plan file staged.
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.8.2 release) intomaster. - On the merged
master, re-confirm: tests green,vibe --versionreportsvibe-council 0.8.2,
redaction lint 0 critical (30 warnings), decisions lint passes,vibe project doctorREADY,
context check21/21, MCP health 21/21, anduv syncshows no drift. - Verify
git status --shortand the merged diff carry no private/local artifacts
(.council/,.council/profile.*, the two untracked private plan files,.env/.venv//data/,
secrets, generated packs/exports, rootCLAUDE.md/AGENTS.md/FABLE.md). - Create an annotated git tag:
git tag -a v0.8.2 -m "vibe-council v0.8.2"on the merge
commit, thengit push origin v0.8.2. - Create the GitHub Release for
v0.8.2manually, using this document
(docs/releases/v0.8.2.md) as the release-notes body.
Known limitations
- Validate-only. The validator reports on the block; nothing applies it. A valid block
changes no behavior — that is deliberate (application is v0.9.x behind its own reviewed design). - Personas are documentation. The named council personas are an illustrative future direction, not
defined, selected, or applied here. - No hosted/team/mobile/voice — deferred to later phases.
Next after v0.8.2
Cut the v0.8.2 tag/GitHub Release, closing the v0.8.x "Solidify the core, local-first" line
(v0.8.0 launcher, v0.8.1 vault polish, v0.8.2 preference schema + validator). The next version-line
architecture moment is v0.9.x — preference application (letting validated preferences influence a
command, and the council-persona model): a Fable architecture pass over council-produced planning, then
Opus/Sonnet implementation. Preference application, a .council/profile.* store, named
personas/persona UX, mobile/LAN/voice, and hosted/team all stay deferred behind their own gated designs.