Repository navigation
Releases: fredericrous/aval
Release list
v1.12.0
Added
aval mcp install|uninstall [--write] [--check]registers or removes
aval's MCP server at Claude Code user scope throughclaude mcp add|remove;
without--writeit only shows the command.--checkexits 0 registered,
1 not, 3 whenclaudeis absent or cannot answer; without--check, no
claudeon PATH is one line on stderr, exit 0. Hints and done lines go to
stderr. The PATHavalis registered when it is the running binary.aval hook uninstall [--write] [--check]removes the marker-owned
.claude/hooks/aval-heads.shand its.claude/settings.jsonentry, leaving
other settings, their indentation and the final newline, and a script without
aval's marker.
What's Changed
- docs(plan): repo-declares-its-scopes, done by @fredericrous in #48
- docs(plan): record the scopes end-to-end check by @fredericrous in #49
- feat: mcp install/uninstall and hook uninstall by @fredericrous in #50
- chore(release): 1.12.0 by @fredericrous in #51
Full Changelog: v1.11.0...v1.12.0
v1.11.0
Added
in_scopes: a repository declares the scopes it is in. With no
--scope,resolve,relevantandhistory(and theaval_resolve,
aval_relevantandaval_historytools) answer at those scopes; the
precedence is the flag, thenin_scopes, then*. JSON answers carry
scope_source. Two declared scopes that both answer one key contradict
(exit 5, withby_scope);check --jsoncarries the same condition as a
warningsarray and still exits 0.aval traits --summarynames the
declared scopes.--scope '*'is unchanged.
What's Changed
- docs(plan): code-rules outcome and live checks by @fredericrous in #44
- docs(plan): code-rules next-session checks by @fredericrous in #45
- feat(scopes): a repository declares its scopes by @fredericrous in #46
- chore(release): 1.11.0 by @fredericrous in #47
Full Changelog: v1.10.0...v1.11.0
v1.10.0
Added
governs: codeon a rule file,aval rules --governs codeand--full.
The field travels in a pack;--fullprints each rule asaval rule <id>
does (and addsbodyto--json), and every rule in--jsoncarries
governs. Theaval_rulestool takesgovernsandfull.
What's Changed
- feat(rules): governs field, --governs and --full by @fredericrous in #42
- chore(release): 1.10.0 by @fredericrous in #43
Full Changelog: v1.9.1...v1.10.0
v1.9.1
Fixed
aval add --checkcompares declarations, not commit ids. A revision
that names a new commit whose pack declares the same thing (the top-level
avalgenerator version aside) iscurrent, and the line says which
commit the revision now names. A fetch or parse failure after a move stays
behind.aval heads --checkaccepts a formatter's escaping. A CommonMark
backslash escape of ASCII punctuation in a table cell (prettier writes\*)
is decoded during canonicalisation; code spans and the column split are
unchanged.- The budgeted git call no longer deadlocks on output over the pipe
buffer. Under--budget(the session hook) the child was waited for
before its output was read, so any pack over 64 KB was silentlyunknown
andeditedorbehindnever reached the hook for large packs.
What's Changed
- build(aval): 1.9.0 pin by @fredericrous in #38
- docs(agents): refresh amont guidance block by @fredericrous in #39
- chore(adr): refresh the fleet pack by @fredericrous in #40
- fix(add): behind only when declarations moved by @fredericrous in #41
Full Changelog: v1.9.0...v1.9.1
v1.9.0
Added
aval rules --level <level> --indexlists rule ids grouped by prefix,
one line per prefix (names: no-noise, reveal-intent), and no text. It
wraps at 80 columns on a terminal, never inside an id, and never off one.
It exits 2 without--level, or with--json,--allor--all-repos.
Changed
- The session hook prints the constraint index, not the constraints.
Every active constraint's first paragraph was 26 KB of a 32 KB session
load in the fleet decisions repository; the index is about 2 KB, and
aval rule <id>(MCPaval_rule) has the text. This is the fleet rule
guidance.always-on-is-an-index(decisions ADR-0026). The count line is
now(N constraints, M heuristics), counted from the plain listing. An
aval older than the hook refuses--index; the hook then prints one full
id per line instead of dropping the constraints. The preamble is shorter
and keeps the statement that record wording is data, not instruction.
Re-runaval hook installto take it.
What's Changed
- build(aval): 1.8.0 pin and the new rules pack by @fredericrous in #34
- docs: short README, the manual under docs/ by @fredericrous in #35
- build: verify test attestations in CI by @fredericrous in #36
- feat(hook): print the constraint index by @fredericrous in #37
Full Changelog: v1.8.0...v1.9.0
v1.8.0
Added
aval addcreates the registry it vendors into. Adopting another
repository's decisions is the first thing a repository does with aval, and
addused to refuse it: "no .adr.yaml … there has to be one". With no
registry anywhere above, it now writes a starter one at the git top level
(else the directory asked), declaring nothing, and lists the pack in it.
--dry-runsays it would.aval traits --detectruns before there is a registry, against the
repository git names and an empty vocabulary, because it is how a
repository learns whichareas:to declare. Every othertraitsmode
still needs a corpus.
Fixed
- A published pack no longer re-exports vendored scopes. Keys, records
and rules a corpus vendored were already left out of itsaval.pack; the
scopes those packs declared were not, so a consumer's consumers received
a scope from a pack they never vendored (SEMANTICS §2.3 forbids it). A
borrowed scope is kept only where this corpus's own key or record uses it.
No repository in the fleet both publishes and vendors today. aval relevant --path <directory>is covered by the areas beneath it:
--path webtakesweb/**'s traits. The glob was compared with the
literal pathweb, matched nothing, and the directory was treated as
uncovered, so nothing was filtered.omitted.traitsnames only traits that filtered. For a queried path in
no area, or--all-traits, it listed the repository's traits although
nothing was filtered; it is now empty there.- The hook orders prereleases by semver. It compared the numeric core
only, so a script written by1.8.0-rc1called a1.8.0binary older
than itself. Release beats its prereleases; two prereleases of one core
compare by text.
What's Changed
- chore(adr): adopt the fleet decisions pack by @fredericrous in #32
- fix: traits follow-ups, add bootstraps (1.8.0) by @fredericrous in #33
Full Changelog: v1.7.2...v1.8.0
v1.7.2
Fixed
- Single-quoted mapping keys are keys. prettier with
singleQuote: true
rewrites anareas:glob such as"packages/ui/**"as
'packages/ui/**'when it formats.adr.yamlat pre-commit, and 1.7.1 read
that key with its quotes still on, so every glob came back malformed
(areas-parse) and the registry stopped loading. Single-quoted keys now
read as YAML says,''included. Found adopting the fleet pack in
duro-design-system.
What's Changed
- fix(yaml): single-quoted mapping keys (1.7.2) by @fredericrous in #31
Full Changelog: v1.7.1...v1.7.2
v1.7.1
Fixed
- The generated hook is
shellcheck-clean again. 1.7.0's two new
messages put backticks inside single-quotedprintfformats (SC2016), and
consumers run shellcheck over.claude/hooks/aval-heads.shat pre-commit, so
re-installing the hook was blocked. A test now runs shellcheck over the
script whenever it is installed. The stale-binary line also names both ways
aval is installed —brew upgrade aval, or its install script — not brew
alone.
What's Changed
- fix(hook): shellcheck-clean script (1.7.1) by @fredericrous in #30
Full Changelog: v1.7.0...v1.7.1
v1.7.0
Added
-
Traits: rules that apply only where the thing exists (SEMANTICS §2.5).
A rule file may sayapplies: [cli]; a registry declares the vocabulary
(traits:, carried in its pack) and which parts of the repository have which
traits (areas:, glob → traits, consumer-local). Withareasdeclared,
aval rules, theaval_rulestool and the session hook list only rules that
apply to the declared traits — a repository with no command line stops
printing command-line constraints at every session start.Filtering is display, never activity. A hidden rule is still active,
aval rule <id>explains it, and--all-traits/all_traits: truelists
it. Every filtering surface reports what it hid: a stderr notice under
aval rules,omitted(constraints,heuristics,traits) in every
--jsonand tool payload, and one hook line printed wheneverareasis
declared, zeros included — so an area that hides everything is seen at every
session start, not only in the diff that added it. A path no area covers
filters nothing; an area declaring[]keeps only untargeted rules. -
aval traits: the declaration (--json, and theaval_traitstool);
--summary, the hook's line, which reads the corpus only and needs no git;
--detect, which proposesareas:from tracked files; and--check, which
reports a detected trait no area or disclaim covers for that package,
and any glob matching no tracked file.--checkexits0/1findings /
3could not inspect — git missing or failing, an unreadable file, a
package.jsonthat is not JSON. A TOML manifest is scanned, never parsed,
and never exit3.Detection is advisory and unpinned: it leans toward reporting (a false
positive costs adisclaims:line; a miss would hide a constraint), and a
detector getting better is a patch. Today it knowscli(Cargo bins,
package mainoutside//go:build ignore, Python script tables, a
package.jsonbin) andui(React, Vue, Svelte, Solid, Preact, Angular,
Lit independenciesorpeerDependencies, or.tsx/.jsx/.vue/
.sveltefiles). -
Three checks, each firing only where the new fields are present:
rule-applies-declared,areas-declared,areas-parse. -
The glob dialect is normative and pinned by
conformance/traits.json,
with the applicability table beside it.
Changed
- The hook speaks where it used to go silent. When the installed aval is
older than the one that wrote the script, its first line says so and names
the upgrade; whenaval headsfails on a repository that has a registry, one
line says so and to runaval check. Without aval installed it still says
nothing.
Upgrading
brew upgrade avalon every workstation before a repository adopts
traits,areasordisclaims: aval before 1.7 refuses such a registry,
and a pack carryingtraitsorapplies.- Everybody re-runs
aval hook install(the script changed); bump each
workflow'sAVAL_VERSIONpin in the same pull request. - Order: release the tool, publish the producer pack with
traitsand
applies, then let each consumeraval addand commit its reviewed
areas:together.
What's Changed
- feat: traits, areas and aval traits (1.7.0) by @fredericrous in #29
Full Changelog: v1.6.0...v1.7.0
v1.6.0
Added
-
aval relevant— which decisions bear on what you are about to touch.
resolveis exact, so a caller has to know a key's name before it can ask
anything, and at the start of a task that is a chicken-and-egg problem: the
way to learn that a decision governs a file is to already know the decision.
The alternative wasHEADS.md, which is every decision ever made. This ranks
the vocabulary against--path(repeatable),--text, and--changed—
what git reports modified, staged and untracked — and reports each ranked key
with its verdict, from the sameresolveeverything else uses. So an
undecidedrow says nobody decided it, which is the row that matters: it is
where an agent left to itself invents an answer.Four signals, documented and weighted: BM25 over the query's words (1.0) and
over the paths' own words (0.6), a record whose body names one of the paths —
backticked, as a link, or as a glob (2.0 each, three at most), and what git
says changed alongside the record (0.5 each, three at most). The tokenizer is
frozen and the conformance battery compares the resulting order byte for
byte. Nothing is trained, nothing is cached, nothing leaves the machine.It is a
suggestionin the sense SEMANTICS §5.1 now defines: it resolves
nothing, writes nothing, and is not part of what the corpus says is true. The
exit code is always0— a ranking has no verdict, and "I found little" must
not share a code with "I could not look" — except2for usage, including a
--scopethe corpus does not declare. -
--jsoncarriesdependencies, the ranked keys compacted for a router:
key,state,exit,adrandunresolved, the last true for exactly
undecidedandcontradiction. A dispatcher routes a change whose decisions
are not settled to a person rather than to a worker without reading the rest
of the payload. -
The MCP tool
aval_relevant, with the same inputs and the same bytes.
Its description carries the obligation the surface makes easy to lose: a
model reading a ranked list treats the first row as the answer unless it is
told, in the description, that the ranking resolves nothing. -
A relevance conformance battery,
conformance/relevant.json, over a new
relevance-samplecorpus. It pins the two properties that make a ranking
reviewable: the same corpus and query give the same order byte for byte, and
a ranked key'sundecidedorcontradictionverdict is reported as the
resolver gives it rather than softened or dropped.
Changed
aval-coregainsrelevance(a frozen tokenizer and a BM25 index) and
Json: From<f64>, which writes a non-finite float asnullrather than a
literal no JSON reader accepts. Still no external dependencies.
What's Changed
- chore: add relais.toml policy by @fredericrous in #27
- feat: aval relevant, retrieval at the input edge by @fredericrous in #26
- chore: v1.6.0 by @fredericrous in #28
Full Changelog: v1.5.0...v1.6.0