Releases: easyvibecoding/vibe-resume
Release list
v0.35.0 — gate-mode emit guard + detailed-variant review budget + remote-less dedup
Fixed
- Gate-mode
run --continuesilently rendered UN-enriched groups when G4
wasn't armed (#94, silent-corruption class). The enrich emit only fired when
the pending gate was G4; arming e.g.--gates G1,G2,G7,G8skipped emit, ingested
nothing, and rendered raw/curated groups (a contentless résumé) with no error.
Now, on--continuewith G4 not armed and no enrich manifest present, the run
emits the manifests and stops with a process-then-continue message instead
of rendering un-enriched. reviewscored the_detailedvariant against the fixed locale page budget
→ misleading C / "Page 2/10" (#95). #88 made the detailed variant uncapped at
render, butreviewstill judged it against the ATS/locale target (≤2.0). Now a
_detailedfile is scored against a detailed-appropriate budget — the configured
config.render.variantsdetailedmax_pagesif set, else 2.5× the locale target
— and the budget used is disclosed in the header.--max-pagesstill overrides.
Applies per-file, soreview --variantsscores each variant on its own budget.
Added
- Remote-less local dirs are now matched against the same-named remote repo at
curate(#93, residual of #37). A working dir with no git remote
(canonical_key: None) whose basename uniquely matches the repo basename of
a remote-keyed group (e.g. localvibecoding↔ a repo…/vibecoding) is
surfaced as aneeds_decisionmerge_intosuggestion — never a silent
auto-merge (basename collisions are possible; 0 or >1 matches → left as-is, and
auto_dropprecedence is preserved).
v0.34.1 — review --file crash + locale inference fix (#92)
Fixed
review --file <relative path>crashed withValueError(#92, regression
from the #86Scored:print). The new header printedmd_path.relative_to(ROOT),
which raises when--fileis a relative or out-of-repo path. Now resolves first
and guardsrelative_to, falling back to the absolute path.review --filemis-inferreden_USfor a locale-tagged filename (#92). The
filename→locale regex([a-zA-Z_]+)greedily captured the persona/variant
suffix too (zh_TW_agentic_atsfromresume_v012_zh_TW_agentic_ats.md),
yielding an invalid locale that fell back toen_US— so a non-English résumé
under-scored AI-proficiency. Now captures only thexx_YYlocale token. Affects
every suffixed filename, not just--file.
v0.34.0 — agent-operation batch: silent-corruption fixes + disclosure
A batch of agent-operation fixes surfaced by a real interactive run (#82–#91):
silent-corruption bugs first, then disclosure/ergonomics.
Fixed
- Stale enrich YAML ingested by POSITION after re-aggregate → scrambled
bullets (#84, silent corruption).ingest_jobsmatched the old manifest to
the current groups by list index; afteraggregatereordered/added/dropped
groups, each entry's bullets landed on whatever now sat at that index (only a
soft "name mismatch … Using raw[N]" warning). Now keyed by group identity
(name→canonical_keyfallback, each group consumed once); an entry that
matches no current group is skipped + warned loudly, never written onto an
unrelated group. - AI-proficiency human-gate detection scored 0 for every non-English locale
(#82).gate_termsmatched only an exact locale key, but
human_gate_verbs_by_localeis keyed by base family (zh/ja/…), sozh_TW
/ja_JP/de_DEmissed and a résumé that honestly paired a tool with a
human gate was structurally pinned at 0/10. Now normalizes to the base family. - Detailed render silently truncated each group to 2 achievements (#88).
Thedetailedvariant inherited the globalconfig.render.page_budgetand got
floored — hiding woven content with no warning. Variants no longer inherit the
global budget (only their ownmax_pagescaps them), and any per-group
truncation now prints a warning. Newrender --bullets-per-group Nhard cap. curate --applysilently ignored the editedaction(#87). A human edit
settingaction: dropwith a non-standardtier(e.g.manual_drop) failed
tierLiteral validation, so the whole record fell back to the auto-only
classification.tieris now a freestr(actionis authoritative).reviewscored a stale non-suffixed version and never said which file
(#86, #63). The persona+locale default glob excluded_ats/_detailed
variants and picked the highest non-suffixed file (often stale). Now includes
variant suffixes, selects by version number (not lexical order), and
always prints the resolved target path.run --continuereplayed the fullextract(~4min) on every resume (#83).
AG1=reextractdecision re-fired each--continue. Once the extract cache is
fresh (the reextract already ran this session), it now honors--max-age-days
and skips the redundant extract (still re-aggregates).- Gate recompute bypassed
curate --applycleanup (#85). The G2/recompute
aggregateregenerated raw groups and left the curated cache stale, silently
dropping the human's curation. Now re-applies_curation.yamlafter any
recompute aggregate so curation survives--continue.
Added
enrich --candidatesevidence-aware first pass (#89). Each group's enrich
prompt now carries anEVIDENCE DISCLOSUREblock — the human-gate phrasing and
safe_to_surfacemetrics the evidence layer mines from the activity record —
so a faithful first-pass bullet can pair tool + gate and surface real numbers
without the manual evidence→re-edit loop. Anti-fabrication contract intact.curate --drop/--merge/--keepverbs (#87) — set actions without hand-editing
YAML; unknown names are reported, not silently ignored.review --jsonandreview --variants(#91) — structured scorecard (with
resolved target path) on stdout, and one-call scoring of every rendered variant
keyed by variant, for agent consumption.gates state [--json](#90) — machine-readable run state: armed gates,
fully-wired vs emit-only, the pending gate, each recorded decision, and per-gate
recompute suffix, so an agent drives the gate machine deterministically instead
of parsing console prose. (Thefull_reviewG3 stall noted in #90 was already
fixed in 0.32.3.)
v0.33.1 — document v0.33.0 commands + Interactive Gate Mode (#81)
Documentation
- v0.33.0 exploration commands + Interactive Gate Mode were undocumented in
the canonicalSKILL.md/AGENTS.md(#81) — invisible to skill-discovery
hosts that never run--help. Added Quick Reference rows forexplore,
jd-check --explain,enrich --candidates+bullets-compare,
personas-compare --with-scores,run --branch/--branches/--adopt, plus
curate/emphasis/review-diff; a new Interactive Gate Mode procedure
subsection (presetsautopilot/checkpoints/full_review, the G1–G8 model,
therun --interactive→ decide gate file →run --continueloop); and a
Pitfalls note on the truthful-lever guarantees. Mirrored intoAGENTS.md.
A newtests/test_skill_spec.pydrift guard asserts every top-level CLI
command (and the v0.33.0 sub-flags) appears inSKILL.md, so a future command
fails CI until documented.
v0.33.0 — exploration & disclosure backlog
Added — exploration & disclosure backlog
The unifying design principle (per the project goal): give the agent disclosure
capability to self-mine what it needs to see, and turn single-shot choices into
visible explorations. None of these rewrite bullets or fabricate — they surface
real signals and let the human pick.
jd-check --explain(#80). For each MISSING JD keyword, classify it
groundable(real supporting snippets exist in the activity — shown with source
refs) vsabsent("honest gap — leave it"). Reuses the evidence-disclosure layer;
advisory only, never auto-inserts. Newcore/jd_explain.py.explorecommand (#76). Sweeps atop_n × page_budgetgrid, renders+reviews
each cell, and surfaces the Pareto front (configs not dominated on score↑ /
pages↓) so the layout sweet-spot is found deliberately instead of by hand. Pure
layout/selection — same truthful-lever guarantee asiterate. Newcore/explore.py.personas-compare --with-scores(#78). Joins the per-group bullet diff with a
per-persona review-score table for the same locale + JD, and highlights the persona
that maximizes JD fit — turning persona choice from an up-front guess into a
data-driven comparison. Newcore/persona_compare.py.run --branch <Gn> --decision <json>+--branches+--adopt(#77). Forks
the gate ledger to a named branch (original kept intact), applies the alternative
decision, recomputes only that gate's invalidation suffix, and auto review-diffs the
branch vs the original — making the gate flow a tree instead of a line. New
core/run_branch.py(pure, deterministic branch ids; no clock/RNG).enrich --candidates <angles>+bullets-compare(#75). Generates N
angle-biased candidate bullet-sets per group (impact_first/breadth_first/
depth_first— each a prompt PREFIX; the anti-fabrication rules are untouched) and
shows them side by side so the user picks the best framing per group. New
core/candidates.py; the angle threads throughenricher._build_prompt→emit_jobs.- G5 per-metric selection (#79 part 2). The G5 metrics gate is no longer
all-or-nothing: the decision recordspick: [{group, value}]to weave a SUBSET, and
the gate file scaffolds an emptypick.g5_selected_metricsalways intersects the
pick withsafe_to_surfacevalues, so a pick can never smuggle an unsafe/unlisted
value past the P1 guard (closes #79; part 1 shipped in 0.32.4).
v0.32.4 — evidence classifier hardening (#79 part 1)
Fixed
-
G5 evidence classifier surfaced secret-key fragments and other noise as
real metrics (#79, part 1 — classifier hardening). The metric classifier
now markssafe_to_surface: falsefor five additional noise contexts so they
can never be woven into a résumé:- secret/key fragments —
487Blifted fromCWA-BF1B60DA-2A68-487B-…
(alsosk-,ghp_,gho_,github_pat_,AIza…,x-access-token,
bearer, and dash-delimited hex/UUID groups). This is a genuine
privacy/secret-leak fix, not just noise reduction. - hash digests —
256 hfromSHA-256(md5,sha1,digest,
checksum,hash). - ANSI / stack-trace markers —
0m/4mfrom colour codes,line 42. - path / UUID fragments —
4d/8dfrom~/.claude/image-cache/<uuid>. - enricher prompt-template self-reference —
40%lifted from the
enricher's own template text (寫「…壓縮約 40%」,e.g. …,範例:…).
Genuine plainly-stated metrics (
壓縮資料前置處理約 40%,handled 2k req/s)
are unaffected. Part 2 of #79 (per-metric pick-list selection at G5) remains
open. New rules ordered ahead of the existing kind rules; 6 regression tests
added. - secret/key fragments —
v0.32.3 — full_review G3 pause fix (#74)
Fixed
run --preset full_reviewskipped the enrich emit and rendered from raw
output while reporting success (#74, silent failure).full_reviewis the
only preset that armsG3(overwrite), andG3sits before theG4enrich
emit but had no pause handler in therunstate machine. AfterG1+G2were
decided,first_pending_gatereturnedG3, thepending is G4emit branch
never fired, ingest found no jobs, and render fell back to raw aggregator output
(no bullets) — then the run printed "gated run complete". Fixed by givingG3
an emit+pause branch (symmetric withG5/G6/G7) sofull_reviewrecords
the overwrite decision and advances to theG4emit instead of swallowing it.
Added regression tests drivingfull_reviewG1→G2→continue (pauses atG3,
emits nothing, never claims completion) and G3-decided→continue (emits enrich,
pauses atG4).GUARD_PHASEnow mapsG3 → "overwrite".
v0.32.2 — fix claude_code_archive signature drift
Fixed
claude_code_archiveextractor crash → silent data loss (#73). It reused
claude_code._process_sessionbut still called it with the old 2-arg signature
after that function grew to 6 args (sample_n/per_chars/capture_args/
git_cache). Per-extractor failure isolation masked theTypeErroras silent
data loss — newly-archived sessions were never re-ingested andstatuskept the
stale count. Fixed by mirroringclaude_code.extract's session-config read +
per-run git cache and passing the full signature. Added archive-extractor tests
(happy-path + missing-path) so future signature drift fails at CI, not at a
user'sextract.
v0.32.1 — self-documenting gate-file decision shape
Fixed
- Self-documenting gate-file decisions (#72). The emitted
*.gate.jsonshowed
"decision": nullwith no shape hint, and the obvious fill ("decision": "reuse")
was silently coerced toNoneand mislabeled "no decision filled in" — stalling
the documented happy path. Now the gate-file scaffolds"decision": {"choice": null}
plus a_hint; a bare string is accepted and normalized to{"choice": "reuse"};
andread_gate_decisiondistinguishes a genuinely-empty decision from a wrong-shape
one (decision must be an object like {"choice": ...}; got [...]). The engine was
already correct — only the affordance is fixed.
v0.32.0 — Interactive Gate Mode wired into run
Added
- Interactive Gate Mode — wired into
run(#71, Phase 2 of #70). The tested
gate core is now a usable flow:run --interactive/--preset <autopilot|checkpoints|full_review>/
--gates G1,G2,...arm a gate set (defaultcheckpoints= G1/G2/G8),
persisted todata/run_ledger.json.- A ledger-driven multi-stop pause: before a stage an armed-undecided gate
guards,runemits a*.gate.json(decision context from the #62–#69
disclosure) and stops;run --continuereads the decision, records it,
and advances to the next gate. Fully-wired apply: G1 (reuse vs re-extract),
G2 (top-N → enrich limit, drop-noise), G8 (terminal acceptance); G3–G7
emit+record (MVP). run --resume-from Gn→resume_plan→ re-runs only the affected stage
suffix (e.g. G5 →render → review), then prints an automatic review-diff.- Backward compatible: with no gate flags (or
--preset autopilot),run
andrun --continuebehave exactly as before — no ledger, no pauses. The G5
fabrication guard (assert_g5_safe) stays active on the run path, with the
gate context filtered tosafe_to_surfacemetrics only.