Skip to content

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 11 Jul 23:33
· 42 commits to main since this release

v0.4.0 (2026-07-11)

This release is published under the MIT License.

Bug Fixes

  • ci: Re-sync to current main before semantic-release runs (23f1bc7)

The shared concurrency group only serializes execution with graphify.yml

  • it doesn't stop that job's push from landing on main first while this job's checkout stays pinned to the original trigger SHA. Add a git fetch + reset --hard origin/main immediately before invoking semantic-release so it always computes/commits/pushes against the actual current tip, not a stale snapshot.

Co-Authored-By: Claude Fable 5 noreply@anthropic.com

  • ci: Serialize release and graphify pushes to stop a real race (24de086)

release.yml's semantic-release push and graphify.yml's graph-commit push both fire on every push to main but lived in separate concurrency groups, so they could run in parallel and race for the same ref — observed twice today: the Bolt 10 feat commit's release run was rejected non-fast-forward because graphify's push landed on main first, mid-run, and a plain gh run rerun couldn't fix it (it replays the original stale checkout, not current main).

Both workflows now share one concurrency group (main-writers, cancel-in-progress: false) so they queue instead of racing.

Co-Authored-By: Claude Fable 5 noreply@anthropic.com

Features

  • backend: Cover letter rendering with deterministic candidate identity (7163d29)

Bolt 10 of add-job-matcher-cli (revision 7) - offline suite now 109 passed (13 new tests), live smoke on openai:gpt-5.4-mini renders the full header with zero operator configuration:

  • candidate.py: deterministic regex extraction of name/email/phone/ github/linkedin/website from the already-extracted resume text - no third LLM call, no grounding guard needed (a regex match is definitionally a literal substring of the source). Computed once per run, reused across every job in the fan-out. - job_matcher/templates/cover_letter.txt ships as package data; load_template() gains the same package-default fallback load_prompt() already has, so cover-letter rendering activates with no operator setup (correction to the earlier "no package default, missing template degrades to plain text" design) - pipeline.py: identity + a run-level date threaded through _job_task -> _cover_letter_text(), which builds the Re: <title> [at ] line and renders through the template - Real bug caught and fixed during implementation: the URL scanner's email-exclusion lookbehind blocked matching a domain AFTER an email's @, but not the email's own local-part before it (e.g. "sam.lee" in
    "sam.lee@example.com" briefly misread as a website) - fixed by blanking email matches out of the text before URL scanning

Proposal status: all ten bolts now implemented; VERIFIED still awaits only the two owner manual evidence items (Claude Desktop mount, chatbot UI run).

Co-Authored-By: Claude Fable 5 noreply@anthropic.com


Detailed Changes: v0.3.2...v0.4.0