Releases: tombaldwin/candor-agents
Release list
candor-agents v0.23.1
Changelog
All notable changes to candor-agents are recorded here. Format loosely follows
Keep a Changelog and the family convention (candor-rust's CHANGELOG):
candor is pre-1.0, so minor versions may include behavioural changes — always in the
soundness-increasing direction (the §4 trust contract) — and a ⚠ marks an entry that affects
report bytes, drift results, or gate verdicts (regenerate baselines / expect verdict changes across it).
candor-agents is the family's domain engine (SPEC §4): its units are agents, not functions, and it
rides the spec ladder on its own schedule (it never holds the four code engines' floor back). Its
major.minor tracks the spec it declares — 0.15.x declares spec 0.15.
[0.23.1] — 2026-07-20
Version-aligned with the family's 0.23.1 patch (engine performance + classifier-soundness fixes in the
code engines; spec unchanged at 0.23). No functional change to candor-agents itself — it reads the same
0.23 report schema and drift semantics.
[0.23.0] — 2026-07-20
Spec floor → 0.23 (lockstep with the family). Reads the 0.23 report schema (interfaceUnion field
tolerated; the declared-vs-observed drift analysis is unchanged). No agent-facing behaviour change.
[0.22.0] — 2026-07-18
Spec floor → 0.22 (the verify oracle rung, shipped on the java/ts arms). candor-agents declares 0.22; the
report and verdict schema are unchanged from 0.21, so this engine's output is byte-identical across the bump. No
functional change to the agents engine.
[0.19.0] — 2026-07-17
Floor ratchet to spec 0.19. The 0.19 rung is reason-scoped Unknown policies (SPEC §6.2) — a
§6.2 policy-gate tool-surface feature for the effect engines (rust/java/ts/swift); it adds no report-schema
or drift-surface change, so candor-agents' declared-vs-observed report is byte-identical under 0.19 (the
declared spec string bumps to keep the family floor uniform).
[0.18.0] — 2026-07-16
spec 0.18 — the trust-trio
candor-agents now declares spec 0.18 (SPEC; version agents-0.18.0). Tracks the family floor bump —
the pinned-tool-surface rung (--strict advisory-verb CI gate; the surface/tour mostly-Unknown
disclosure). No report-schema or verdict change; the drift-gate and --gate-json verdict are unchanged.
[0.15.0] — 2026-07-15
spec 0.15 — floor alignment
candor-agents now declares spec 0.15 (SPEC in scan.py; the envelope + --gate-json verdict carry
it): the floor ratchets to the coverage-envelope + host-resolution rung — the coverage envelope is a
code-engine report field and host-resolution recall is a code-engine classifier improvement (see the
candor-spec 0.15 CHANGELOG for the spec-side detail). This is a declared-version alignment only,
keeping the floor consistent across the family — the fleet's reports COULD carry an uncovered
tool-surface coverage envelope in a future rung, but no such field lands here, and host resolution has no
fleet-side analogue (its leaves are tool grants, not call sites).
No fleet-surface behaviour change: report bytes, drift results, and gate verdicts are byte-identical to
0.14.0 — only the declared spec string moves 0.14→0.15. A consumer pinning spec == "0.14" must
accept 0.15.
No engine-local change accompanies this rung — the v0.14.0..HEAD range was empty; this version bump is
the entire delta.
[0.14.0] — 2026-07-14
spec 0.14 — floor alignment
candor-agents now declares spec 0.14 (SPEC in scan.py; the envelope + --gate-json verdict carry
it): the floor ratchets to the top-level-initializer rung — a code-engine fix where a module's
top-level effects were dropped as false-pure (see the candor-spec 0.14 CHANGELOG for the spec-side detail).
This is a declared-version alignment only, keeping the floor consistent across the family — the
top-level-initializer fix is a code-engine surface (call sites / top-level code) and the domain engine has
no such surface (its leaves are tool grants, not call sites), so no new surface lands here.
No fleet-surface behaviour change: report bytes, drift results, and gate verdicts are byte-identical to
0.13.0 — only the declared spec string moves 0.13→0.14. A consumer pinning spec == "0.13" must
accept 0.14.
No engine-local change accompanies this rung — the v0.13.0..HEAD range is the version bump alone.
[0.13.0] — 2026-07-14
spec 0.13 — floor alignment
candor-agents now declares spec 0.13 (SPEC in scan.py; the envelope + --gate-json verdict carry
it): the floor ratchets to the Llm-effect rung — the new §6.1 boundary effect for a call whose sink
is a model API (a data-exfiltration surface, always alongside Net, gate-able / watchable / tour-able;
see the candor-spec CHANGELOG for the spec-side detail). This is a declared-version alignment only,
keeping the floor consistent across the family — Llm is a code-engine sink classification and the domain
engine has no Llm surface (its leaves are tool grants, not call sites), so no new surface lands here.
No fleet-surface behaviour change: report bytes, drift results, and gate verdicts are byte-identical to
0.12.0 — only the declared spec string moves 0.12→0.13. A consumer pinning spec == "0.12" must
accept 0.13.
No engine-local change accompanies this rung — the v0.12.0..HEAD range is the version bump alone.
[0.12.0] — 2026-07-14
spec 0.12 — floor alignment
candor-agents now declares spec 0.12 (SPEC in scan.py; the envelope + --gate-json verdict carry
it): the floor ratchets to the gains-origin rung — the §3.1 gains origin field, the supply-chain
existing/new/unknown split (see the candor-spec CHANGELOG for the spec-side detail). This is a
declared-version alignment only, keeping the floor consistent across the family — candor-agents does
not expose a gains verb, so no new surface lands here. No fleet-surface behaviour change: report
bytes, drift results, and gate verdicts are byte-identical to 0.11.0 — only the declared spec string
moves 0.11→0.12. A consumer pinning spec == "0.11" must accept 0.12.
Added
statsaggregatesdeepestPropagationfrom the activity log's newmaxHopsrecord field — the
companion tolargestBlastRadius. The review scripts now log the change's graph-depth asmaxHops,
andstatsreports the maximum with the human linedeepest propagation seen: N hop(s) from a new source. Records with an absent or non-integermaxHopsare ignored (the established junk-tolerance
pattern).
[0.11.0] — 2026-07-13
spec 0.11 — floor alignment
candor-agents now declares spec 0.11 (SPEC in scan.py; the envelope + --gate-json verdict carry
it): the floor ratchets to the surprising-reach + corrupt-report-loudness rung (see the candor-spec
CHANGELOG for the spec-side detail). This is a declared-version alignment only, keeping the floor
consistent across the family. No fleet-surface behaviour change: report bytes, drift results, and gate
verdicts are byte-identical to 0.10.0 — only the declared spec string moves 0.10→0.11. A consumer
pinning spec == "0.10" must accept 0.11.
Note: this is also the first tagged release to carry the coverage-ledger marker rename
(κ doesn't know → classifier doesn't cover) — that change landed on main after the v0.10.0 tag was
cut, so its entry sits under 0.10.0 below but ships here.
[0.10.0] — 2026-07-12
coverage-ledger marker renamed κ doesn't know → classifier doesn't cover
The per-scan item-14 coverage-ledger line now carries the cross-engine marker classifier doesn't cover (the grep target every candor engine shares) and drops the Greek κ from its
user- and agent-facing output — the glyph was unexplained and confusing in the receipt. The line
keeps its fleet domain nouns (uncurated MCP servers / unknown tools / unlisted command heads) and its
INVISIBLE-not-a-purity-claim framing; the reviewed-pure disclosure now reads "the classifier relies
on…". AGENTS.md, README.md, and the embedded --agents contract are re-synced to the new wording.
κ remains internal maintainer vocabulary only — the kappa_ledger/collect_kappa identifiers,
the κ = TOOL_EFFECTS/… classifier shorthand in docstrings, and this CHANGELOG's history are
unchanged. No report bytes / drift / gate-verdict change — receipt text only.
spec 0.10 — floor alignment to the §3.3.1 rung
candor-agents now declares spec 0.10 (SPEC in scan.py; the envelope + --gate-json verdict carry
it), following the ratcheting family floor. 0.10 pins the §3.3.1 query-grammar rung — which candor-agents
satisfies vacuously: it is a fleet surface (scan/observe/drift/guard) and exposes no §3.1
report-query verbs, so there is no query grammar to conform. This is a declared-version alignment only,
keeping the floor consistent across the family. No fleet-surface behaviour change: report bytes, drift
results, and gate verdicts are byte-identical to 0.9.0 — only the declared spec string moves 0.9→0.10.
A consumer pinning spec == "0.9" must accept 0.10.
[0.9.0] — 2026-07-11
spec 0.9 — rides the remedial-loop rung
candor-agents now declares spec 0.9 (SPEC in scan.py; the envelope + --gate-json verdict carry
it). 0.9 is a tier-2 (pinned-tool-surface) rung (candor-spec §"Conformance tiers") led by the code
engines — the remedial loop (fix/unverified/gate auto-disclosure) becomes the pinned §3.1/§3.3 contract
for the code engines; the domain engine rides the rung for floor alignment (its units are agents, not the
functions those tools operate on). No behaviour change here: report bytes, drift results, and gate
verdicts are byte-identical to 0.8.3 — only the declared spec string moves 0.8→0.9. A consumer
pinning spec == "0.8" must accept 0.9.
[0.8.3] ...
candor-agents v0.23.0
Changelog
All notable changes to candor-agents are recorded here. Format loosely follows
Keep a Changelog and the family convention (candor-rust's CHANGELOG):
candor is pre-1.0, so minor versions may include behavioural changes — always in the
soundness-increasing direction (the §4 trust contract) — and a ⚠ marks an entry that affects
report bytes, drift results, or gate verdicts (regenerate baselines / expect verdict changes across it).
candor-agents is the family's domain engine (SPEC §4): its units are agents, not functions, and it
rides the spec ladder on its own schedule (it never holds the four code engines' floor back). Its
major.minor tracks the spec it declares — 0.15.x declares spec 0.15.
[0.23.0] — 2026-07-20
Spec floor → 0.23 (lockstep with the family). Reads the 0.23 report schema (interfaceUnion field
tolerated; the declared-vs-observed drift analysis is unchanged). No agent-facing behaviour change.
[0.22.0] — 2026-07-18
Spec floor → 0.22 (the verify oracle rung, shipped on the java/ts arms). candor-agents declares 0.22; the
report and verdict schema are unchanged from 0.21, so this engine's output is byte-identical across the bump. No
functional change to the agents engine.
[0.19.0] — 2026-07-17
Floor ratchet to spec 0.19. The 0.19 rung is reason-scoped Unknown policies (SPEC §6.2) — a
§6.2 policy-gate tool-surface feature for the effect engines (rust/java/ts/swift); it adds no report-schema
or drift-surface change, so candor-agents' declared-vs-observed report is byte-identical under 0.19 (the
declared spec string bumps to keep the family floor uniform).
[0.18.0] — 2026-07-16
spec 0.18 — the trust-trio
candor-agents now declares spec 0.18 (SPEC; version agents-0.18.0). Tracks the family floor bump —
the pinned-tool-surface rung (--strict advisory-verb CI gate; the surface/tour mostly-Unknown
disclosure). No report-schema or verdict change; the drift-gate and --gate-json verdict are unchanged.
[0.15.0] — 2026-07-15
spec 0.15 — floor alignment
candor-agents now declares spec 0.15 (SPEC in scan.py; the envelope + --gate-json verdict carry
it): the floor ratchets to the coverage-envelope + host-resolution rung — the coverage envelope is a
code-engine report field and host-resolution recall is a code-engine classifier improvement (see the
candor-spec 0.15 CHANGELOG for the spec-side detail). This is a declared-version alignment only,
keeping the floor consistent across the family — the fleet's reports COULD carry an uncovered
tool-surface coverage envelope in a future rung, but no such field lands here, and host resolution has no
fleet-side analogue (its leaves are tool grants, not call sites).
No fleet-surface behaviour change: report bytes, drift results, and gate verdicts are byte-identical to
0.14.0 — only the declared spec string moves 0.14→0.15. A consumer pinning spec == "0.14" must
accept 0.15.
No engine-local change accompanies this rung — the v0.14.0..HEAD range was empty; this version bump is
the entire delta.
[0.14.0] — 2026-07-14
spec 0.14 — floor alignment
candor-agents now declares spec 0.14 (SPEC in scan.py; the envelope + --gate-json verdict carry
it): the floor ratchets to the top-level-initializer rung — a code-engine fix where a module's
top-level effects were dropped as false-pure (see the candor-spec 0.14 CHANGELOG for the spec-side detail).
This is a declared-version alignment only, keeping the floor consistent across the family — the
top-level-initializer fix is a code-engine surface (call sites / top-level code) and the domain engine has
no such surface (its leaves are tool grants, not call sites), so no new surface lands here.
No fleet-surface behaviour change: report bytes, drift results, and gate verdicts are byte-identical to
0.13.0 — only the declared spec string moves 0.13→0.14. A consumer pinning spec == "0.13" must
accept 0.14.
No engine-local change accompanies this rung — the v0.13.0..HEAD range is the version bump alone.
[0.13.0] — 2026-07-14
spec 0.13 — floor alignment
candor-agents now declares spec 0.13 (SPEC in scan.py; the envelope + --gate-json verdict carry
it): the floor ratchets to the Llm-effect rung — the new §6.1 boundary effect for a call whose sink
is a model API (a data-exfiltration surface, always alongside Net, gate-able / watchable / tour-able;
see the candor-spec CHANGELOG for the spec-side detail). This is a declared-version alignment only,
keeping the floor consistent across the family — Llm is a code-engine sink classification and the domain
engine has no Llm surface (its leaves are tool grants, not call sites), so no new surface lands here.
No fleet-surface behaviour change: report bytes, drift results, and gate verdicts are byte-identical to
0.12.0 — only the declared spec string moves 0.12→0.13. A consumer pinning spec == "0.12" must
accept 0.13.
No engine-local change accompanies this rung — the v0.12.0..HEAD range is the version bump alone.
[0.12.0] — 2026-07-14
spec 0.12 — floor alignment
candor-agents now declares spec 0.12 (SPEC in scan.py; the envelope + --gate-json verdict carry
it): the floor ratchets to the gains-origin rung — the §3.1 gains origin field, the supply-chain
existing/new/unknown split (see the candor-spec CHANGELOG for the spec-side detail). This is a
declared-version alignment only, keeping the floor consistent across the family — candor-agents does
not expose a gains verb, so no new surface lands here. No fleet-surface behaviour change: report
bytes, drift results, and gate verdicts are byte-identical to 0.11.0 — only the declared spec string
moves 0.11→0.12. A consumer pinning spec == "0.11" must accept 0.12.
Added
statsaggregatesdeepestPropagationfrom the activity log's newmaxHopsrecord field — the
companion tolargestBlastRadius. The review scripts now log the change's graph-depth asmaxHops,
andstatsreports the maximum with the human linedeepest propagation seen: N hop(s) from a new source. Records with an absent or non-integermaxHopsare ignored (the established junk-tolerance
pattern).
[0.11.0] — 2026-07-13
spec 0.11 — floor alignment
candor-agents now declares spec 0.11 (SPEC in scan.py; the envelope + --gate-json verdict carry
it): the floor ratchets to the surprising-reach + corrupt-report-loudness rung (see the candor-spec
CHANGELOG for the spec-side detail). This is a declared-version alignment only, keeping the floor
consistent across the family. No fleet-surface behaviour change: report bytes, drift results, and gate
verdicts are byte-identical to 0.10.0 — only the declared spec string moves 0.10→0.11. A consumer
pinning spec == "0.10" must accept 0.11.
Note: this is also the first tagged release to carry the coverage-ledger marker rename
(κ doesn't know → classifier doesn't cover) — that change landed on main after the v0.10.0 tag was
cut, so its entry sits under 0.10.0 below but ships here.
[0.10.0] — 2026-07-12
coverage-ledger marker renamed κ doesn't know → classifier doesn't cover
The per-scan item-14 coverage-ledger line now carries the cross-engine marker classifier doesn't cover (the grep target every candor engine shares) and drops the Greek κ from its
user- and agent-facing output — the glyph was unexplained and confusing in the receipt. The line
keeps its fleet domain nouns (uncurated MCP servers / unknown tools / unlisted command heads) and its
INVISIBLE-not-a-purity-claim framing; the reviewed-pure disclosure now reads "the classifier relies
on…". AGENTS.md, README.md, and the embedded --agents contract are re-synced to the new wording.
κ remains internal maintainer vocabulary only — the kappa_ledger/collect_kappa identifiers,
the κ = TOOL_EFFECTS/… classifier shorthand in docstrings, and this CHANGELOG's history are
unchanged. No report bytes / drift / gate-verdict change — receipt text only.
spec 0.10 — floor alignment to the §3.3.1 rung
candor-agents now declares spec 0.10 (SPEC in scan.py; the envelope + --gate-json verdict carry
it), following the ratcheting family floor. 0.10 pins the §3.3.1 query-grammar rung — which candor-agents
satisfies vacuously: it is a fleet surface (scan/observe/drift/guard) and exposes no §3.1
report-query verbs, so there is no query grammar to conform. This is a declared-version alignment only,
keeping the floor consistent across the family. No fleet-surface behaviour change: report bytes, drift
results, and gate verdicts are byte-identical to 0.9.0 — only the declared spec string moves 0.9→0.10.
A consumer pinning spec == "0.9" must accept 0.10.
[0.9.0] — 2026-07-11
spec 0.9 — rides the remedial-loop rung
candor-agents now declares spec 0.9 (SPEC in scan.py; the envelope + --gate-json verdict carry
it). 0.9 is a tier-2 (pinned-tool-surface) rung (candor-spec §"Conformance tiers") led by the code
engines — the remedial loop (fix/unverified/gate auto-disclosure) becomes the pinned §3.1/§3.3 contract
for the code engines; the domain engine rides the rung for floor alignment (its units are agents, not the
functions those tools operate on). No behaviour change here: report bytes, drift results, and gate
verdicts are byte-identical to 0.8.3 — only the declared spec string moves 0.8→0.9. A consumer
pinning spec == "0.8" must accept 0.9.
[0.8.3] — 2026-07-10
digest dogfood fixes (report wording — no data/verdict change)
Found running the owner digest over real engine output (candor-java's own bytecode) for the first time:
- "Held the line" now itemizes every caught change. The header counted all blocked ...
candor-agents v0.21.0 — spec 0.21
spec 0.21 — the completeness manifest. The report envelope carries analyzed: {count, digest} (distinguish provably-pure from never-seen: pure count = analyzed.count − |functions|) and unanalyzed: [{path, reason}] (the target source candor could not parse). The sharp fix: a configured gate over incompletely-analyzed source now fails closed — exit 2 with a machine-legible {ok:false, incomplete:true, unanalyzed} verdict, instead of a green report a CI/agent read as an all-clear over unseen code. Additive; pinned four-way in gen_completeness.py.
candor-agents v0.20.1
0.20.1 engine patch (spec stays 0.20) — grew the curated TELEMETRY_HOSTS set from a real-repo dogfood of 0.20: adds posthog.com, plausible.io, usefathom.com, heapanalytics.com, fullstory.com, hotjar.com, logrocket.com, cloudflareinsights.com (single-purpose analytics / session-replay / RUM). These now classify known-telemetry, so deny Net[unknown-host] tolerates them instead of false-flagging. Shared verbatim four-way; no vocabulary/schema change.
candor-agents v0.20.0 — spec 0.20
spec 0.20 — the Net destination-class rung: a per-function netClass field (known-telemetry/known-partner/unknown-host) and a deny Net[unknown-host] security gate (egress only to known destinations; fail-closed on a masked/runtime host). Plus a reason-class query surface (blindspots --stats/--class, unverified --class). Additive over 0.19. Pinned four-way in conformance (parsepolicy netClasses + the net-destination-class differential).
candor-agents 0.19.0 — spec 0.19
spec 0.19 — reason-scoped Unknown policies (deny E Unknown[class], the reasonClass verdict field, config unknown-alias). Additive tool-surface rung; no report-schema change. See CHANGELOG.md.
v0.18.0 — spec 0.18 (the trust-trio)
candor spec 0.18 — the trust-trio floor.
A pinned-tool-surface rung (no report/verdict change), pinned four-way in the conformance suite:
--strictadvisory-verb CI gate —fix-gate/gains/unverifiedare advisory (exit 0);--strictmakes each a CI gate (exit 1 while a finding remains). A typo'd flag is rejected loud (exit 2), never a swallowed disarmed gate;gainshas no--policy(a passed one names the scan-timedeny <E> gainedgate, AS-EFF-005).- surface/
tourmostly-Unknown disclosure — never "nothing hidden" (nor atour --json{"reaches":[]}) over a ≥⅓-Unknown graph. - Hardened by a Fable-model code review (caught two latent cardinal-sin edges: an un-gated scan opener; a single-dash flag swallow).
See CHANGELOG.md for the per-engine detail.
v0.17.0
candor 0.17 — the UX-audit engine round + spec floor bump. Query target validation (where/callers fail loud on a bad target, TIER-2 conformance), candor-ts node-fetch recall + prose-at-TTY output, empty-scope remedy text, and the /code-review fixes. Full four-way conformance: OK. See the spec §8 changelog + each CHANGELOG.
candor-agents 0.16.0
Floor-uniformity bump to spec 0.16 (the callgraph-aware baseline guard rung). Install: pipx install git+https://github.com/tombaldwin/candor-agents@v0.16.0.
candor-agents 0.15.0 — spec 0.15 floor alignment
candor-agents 0.15.0 — declares spec 0.15 (floor alignment).
The 0.15 rung (the coverage envelope + host-resolution recall) lives in the code engines; the agent-fleet domain engine has no change — reports and gate verdicts are byte-identical with 0.14.x.