Releases: blisspixel/primr
Release list
v1.34.50
Added
- A versioned, body-free
primr.job-statusv1.0 contract now normalizes job
lifecycle, progress, timestamps, artifact availability, and observation
errors across CLI, MCP, A2A, hosted, and application API status surfaces. primr --list-recent --jsonand job-scoped MCP metadata now use a bounded
artifact inventory that covers Markdown, TXT, DOCX, PDF, manifests, QA,
verification, calibration, trace, run-state, and recovery artifacts.
Fixed
- Deep Research background IDs are persisted at creation and acknowledged only
after the owning output boundary verifies all required files are nonempty.
Normal completion, recovery, strategy, vendor, MCP, runner, and Accordion
paths now retain recoverability when output finalization is partial. - Preflight no longer launches a billable background Deep Research job solely
to test connectivity.
v1.34.49
Fixed
primr --check-jobsis now a read-only cloud and local status view. Completed jobs remain recoverable until--resume-latestdurably finalizes their outputs, and provider-terminal or connectivity failures return a nonzero status instead of a false success.- Recovery output now derives a missing company name from the working path, omits absent fields instead of printing
unknown, and documents platform-neutral inspection, explicit finalization, and retry behavior consistently.
v1.34.48
Added
- Calibration baseline gate recommendations now report whether the per-report
Confirmed traceability floor is complete. A ready baseline with some reports
lacking decidable(Confirmed)claims remains report-only with the explicit
incomplete_confirmed_traceability_floorreason, report counts, and an
operator-review item documenting why the hard gate should stay unset. - Calibration baseline
next_actionsnow carries the same body-free hard-gate
action state as baseline inspection JSON. Ready-but-report-only baselines name
whether the Confirmed floor is absent, incomplete, or zero, including the
selected-report counts that explain whyPRIMR_EVAL_MIN_CONFIRMED_TRACEABILITY
stays unset. - Calibration baseline artifacts and inspection JSON now include a body-free
operator_decision_templatethat lists the allowed gate decisions,
required review items, and selected-report counts an operator must review
before documenting either a deliberate report-only decision or a manual hard
gate assignment. The template does not record a decision and still forbids
automatic gate arming. primr calibrate --baseline-decision-from ... --baseline-decision-out ...
now writes a body-freeprimr.calibration_gate_decision_record.v1artifact
after validating the requested decision against the inspected baseline's
allowed decisions. The command records reviewer, rationale, selected-report
evidence, and baseline fingerprint metadata, but never applies or exports the
hard-gate environment variable.primr calibrate --inspect-baseline-decision ...now prints a body-free
primr.calibration_gate_decision_inspection.v1readback that checks a saved
decision record against the current baseline fingerprint and allowed-decision
evidence before downstream loops trust it.
Fixed
- Release automation now accepts only an exact tag contained in
mainafter a
successful CI run for that commit. Same-tag runs are serialized, versioned
changelog notes are mandatory, release tooling is lockfile-backed, and PyPI
filenames and SHA-256 hashes must match the built wheel and source archive
before the GitHub release is created. - CI now builds the documentation site in strict mode, and the locally testable
release verifier rejects missing, extra, or mismatched distribution files. - The locked development toolchain now uses pip 26.1.2, and CI no longer carries
the obsolete pip advisory exception. - Python support is now consistent at 3.12+ across setup,
primr init,
primr doctor, both container images, AWS Lambda, Azure Functions, Ruff,
dependency guidance, CI, and release builds. New cross-surface integrity tests
derive their assertions from package metadata so unsupported runtimes cannot
silently return. - Human dry-runs now keep the recovery preview concise by default and end with
explicit launch, monitoring, interruption-recovery, and artifact-retrieval
steps.--verboseretains the serialized recovery policy, while--json
remains one machine-readable object. - Long-running phase banners now display caller-supplied duration expectations,
making existing 5-30 minute waits visible without changing quiet-mode output. primr init --helpandprimr doctor --helpnow show concise command-specific
options and examples instead of the full global research and evaluation flag
inventory. Root help remains unchanged as the complete reference.- Explicit local-only calibration dry runs and pack manifests now report zero
estimated cloud spend. Auto mode quotes its cloud fallback ceiling, while
cloud and cloud-vs-local comparison plans retain their bounded paid-call
estimate. Nonzero sub-cent estimates no longer render as$0.00. - Release integrity now pins the editable Primr version in
uv.lockto the
canonical package version. Every CI install and the release SBOM export use
uv's locked mode, so stale project metadata cannot be silently installed or
published. - The source-distribution manifest no longer requests removed dependency and
pytest configuration files or absent documentation example formats, reducing
avoidable packaging warnings while preserving the existing agent, test, log,
output, and build-artifact exclusions. CI now builds and inspects the actual
source archive to enforce that inventory rather than trusting manifest text.
v1.34.47
Fixed
- Final Markdown shipping now normalizes long dash punctuation at the artifact
boundary, including the old Deep Research runner path. Long dash characters
in prose are converted before write, while source URLs percent-encode long
dash code points instead of mutating URL semantics. - DOCX conversion now removes the fast report header metadata line before
rendering subtitles, so the Strategic Overview date and website appear once
instead of once in the generated subtitle and again in the body.
Added
- Calibration baseline artifacts and inspections now include a
measurement
status block. Ready operator-curated multi-report baselines report
measured_operator_curated_multi_report_baselinewith representative
coverage, evidence review, and judge agreement checks made explicit in JSON
and Markdown. - Roadmap and next-step docs now track the MCP
2026-07-28release candidate
as a post-final compatibility review item for Primr's HTTP MCP transport,
task lifecycle, schema handling, trace propagation, Apps extension posture,
and authorization model.
v1.34.46
Changed
- Internal refactor (no behavior change): the deep-research run's finalization
stage - cost reconciliation, the estimated-vs-actual summary, the report
trust row, usage recording, and the job summary - moved out of
research_agent.pyinto a dedicated, unit-testeddeep_run_summarymodule,
mirroring the existing fast-run seam. Output, cost, and usage behavior are
identical; this keeps the orchestrator under its size ceiling and gives the
deep path a tested home for future trust and cost surfaces.
v1.34.45
Fixed
- Cost estimates now price
--verify(post-QA claim verification) on all three
surfaces that price a run for approval - the interactiveProceed?confirm
prompt,--dry-run, and the--budgetpre-flight gate. Previously none of
the three priced it, so a--verifyrun was approved against a number that
omitted its verification overhead. The two CLI-config surfaces (--dry-run
and the--budgetgate) now share a single estimate-shaping helper so they
cannot drift apart again. - The interactive confirm prompt now also prices
--grok-tier, which it
ignored while--dry-runand the--budgetgate already accounted for it; a
--grok-tier maxrun no longer confirms against a hybrid-tier price.
Added
- A deterministic, judge-free label-citation coverage signal: how many
(Confirmed)/(Reported)claims carry a resolvable citation (the
no_sourceslice). It is the always-on, zero-cost complement to the opt-in
paid label-honesty pass (which judges whether a source supports a claim) -
a(Confirmed)claim citing nothing is a structural honesty defect
regardless of phrasing. It is computed once in the fast-run QA metrics
(traceable_labeled_claims,traceable_labeled_claims_cited,
label_citation_coverage_rate) so it is machine-readable for eval, and the
report trust summary renders it as a "Label Citations" row. Report-only (a
signal, never a gate), reusing existing label/citation extraction with no
LLM calls and no network requests. - The deep and
--premiumDeep-Research paths now show the same report trust
summary the fast path does - an always-on "Label Citations" row counting how
many(Confirmed)/(Reported)claims cite a resolvable source. Previously
only fast-mode runs surfaced any trust signal; a deep or premium run finished
with no label-traceability visibility at all. Both paths render the identical
row through a single shared formatter (label_citations_trust_row), so they
cannot describe the signal differently. Report-only, no LLM calls, no network.
v1.34.44
Security
- The hiring-signal block inside
insights.txtis now fenced as data. It
carries verbatim scraped posting titles/locations (raw on the triage and
extraction fallback paths), andinsights.txtis read unfenced by the
AI-strategy prompt and becomes the analysis workbook on the
workbook-fallback section-writing path - so it was the one hiring→prompt
boundary still reaching the model unfenced and unsanitized.docs/SECURITY.md
T1 updated accordingly.
Fixed
- The interactive cost-confirmation gate (
display_cost_estimate) now prices
--strategy-typedocuments, like--dry-runand the--budgetpre-flight
gate already do. It previously understated fast-mode runs (a whole strategy
bundle) and overstated non-fast placeholder/multi-vendor runs, so the number
the user approved diverged from both the dry-run and the actual spend. (The
confirm gate still omits--premium/--verify/--grok-tiershaping that
the--budgetgate passes; full parity is tracked on the roadmap.) - Cost estimates that list
aialongside another--strategy-typeno longer
silently drop the AI-strategy cost: when the explicit list namesai, the
runtime runs it too, so it stays priced instead of being replaced.
Documentation
- Fixed two
docs/API.mdhook examples that importedCostGuardHookfrom
primr.agentic.hooksafter it moved toprimr.agentic.cost_guard
(re-exported from theprimr.agenticpackage). - Refreshed docs for the 1.34.43 "hiring signals on the Deep Research paths"
change: RUN_MODES deep/premium rows, the deep-mode architecture diagram,
and the CLI epilog now reflect the hiring pre-stage and its time bump, and
theshow-usagecost-variability section is documented in RUN_MODES.
v1.34.43
Security
- Fast-mode prompts now fence scraped text as data at these previously
unfenced boundaries: the analysis-workbook and section-writer
corpus/external-source blocks, hypothesis-tree inputs, gap-analysis
summaries, report and strategy regeneration evidence, hiring-signal triage
and extraction prompts (raw titles and job-description bodies were
interpolated unfenced), and the verbatim scraped-external block inside
insights.txt- which also covers the workbook-fallback and strategy
context paths that embed it. Strategy context additionally fences the
scraped-adjacent working artifacts (hiring signals, recon context).
Fencing happens once per run after slicing, so the byte-identical cached
prompt prefix is preserved.docs/SECURITY.mdT1 now enumerates fenced vs
sanitize-only boundaries instead of claiming blanket coverage, and
documents the laundered-injection residual explicitly.
Fixed
-
Long-lived server processes (MCP, A2A) no longer bleed a prior job's
Gemini spend into later jobs: every job now starts with a full usage
accounting reset (Grok session + Gemini client) via a single seam, so
budget checkpoints stop tripping early on inherited spend and persisted
per-run costs stop inflating. -
--dry-runand the--budgetpre-flight gate now price--strategy-type
documents, mirroring the runtime exactly: fast mode adds one writing bundle
per document on top of the AI strategy, non-fast modes replace the AI
strategy with the explicit type and add a flat Deep Research task for the
types that consume one, and placeholder types the run would skip are
called out in the estimate notes instead of being priced. A YAML strategy
previously appeared nowhere in the estimate, so a run could be approved
under a ceiling it would predictably exceed. The post-run
estimate-vs-actual summary uses the same pricing. -
Multi-vendor AI-strategy runs now re-check an active
--budgetceiling at
each vendor dispatch instead of only at stage entry, so spend that accrues
while other vendors run can no longer push the run past the ceiling by a
full strategy per remaining vendor. -
Session token counters are now mutated under a lock; the parallel section
writers and strategy vendor threads could previously lose a call's tokens
to a read-modify-write race, silently understating the spend that budget
checkpoints read. -
show-usagehistory no longer duplicates records when one process saves
after multiple runs (MCP server, batch evals): each session record is
flushed intousage_history.jsonexactly once, and a failed save can be
retried without duplication. -
Fast-mode usage records no longer price free DDG searches at the paid
grounding rate (a typical run persisted about $1 of phantom search cost,
more than doubling the recorded spend of a sub-$0.80 run). Search cost is
now priced by the active provider; query counts are still recorded, and
show-usagesums the recorded per-run search cost instead of projecting
all historical queries at the paid rate. -
RunBudget.sync_spendis now a single atomic write. The per-vendor budget
checkpoints run from parallel strategy threads, and the previous
reset-then-record pair could interleave to double the recorded spend and
falsely skip strategies that had headroom.
Added
- Hiring signals now ride into the CLI Deep Research paths (
--premiumand
--mode deep), not just fast mode: the same ATS/careers-page stage runs
before the deep phase and its block joins the stage-1 context the
comprehensive report call consumes - fenced as data, recorded in run state
and_hiring/artifacts, still reaching the deep call when a run
continues past a failed structured phase, and skipped for strategy-only
and legacy hybrid runs (hybrid never consumes stage-1 context). Deep and
complete dry-run estimates note the hiring stage and carry its 1-2 minute
duration bump; MCP/A2A jobs run the orchestrator directly and are not yet
wired (tracked on the roadmap). output/andworking/now document themselves: primr writes a top-level
README.mdinto each when it creates them (once; user edits are never
overwritten) explaining what lives there and what is safe to delete -
working/holds resumable per-run intermediates including
_run_state.json, whileoutput/holds finished deliverables plus the
MCP/A2Arun_manifest.jsonaudit records, with no resume state.primr show-usagenow includes a "Cost Variability" section per observed
mode: prior-history average cost with lifetime standard deviation, recent-5
average with percent delta, and prior-vs-recent cache hit rates, with a
report-only SIGNAL line when recent runs cost >25% more or cache >10 points
less than prior history - the continuous-reasoning / prompt-cache
regression surface the sub-$1 default depends on. Fast runs also persist
cache_hit_rateinto_run_state.jsonfor post-hoc analysis.
Changed
-
Strategy generation prompts are now split into a run-shared cached prefix
(company report + working-folder artifacts, built once per stage loop) and a
per-strategy volatile suffix (vendor research docs + strategy prompt),
extending roadmap #8's prompt-cache preparation from section writing to the
strategy stage. The assembled prompts are byte-identical to before, so
providers' implicit prefix caching keys on the shared context across
multi-vendor and multi-strategy runs; artifacts are also read once per run
instead of once per strategy. -
Windows working-directory hardening (roadmap #14): all temp-write + rename
state-persistence paths now go through the singleatomic_replaceseam that
retries transient sync-client/antivirus file locks - run-state checkpoints,
pending Deep Research jobs, the update-check cache, and host-marker state
previously carried their own rename logic.
primr doctornow probes that same atomic write path againstoutput/and
working/, so OneDrive-style lock contention surfaces in doctor before it
bites a live run.docs/CONFIG.mddocuments keeping high-churnworking/
andlogs/paths outside synced folders.
v1.34.42
Changed
- Explicit
agentprofile unavailability now fails closed for the remaining
routed utility stages that do not yet have host adapters.fast.scrape_summary
writes deterministic source excerpts,fast.hiring_signalsuses deterministic
triage plus posting metadata, both stages record body-free
agent_profile_unavailableroute fallbacks, and neither stage silently calls
a cloud LLM when no official host runner qualifies. - Hiring-signal deterministic selection helpers now live in a focused
hiring_signal_selectionmodule so the orchestration file stays below its
architecture ratchet while preserving existing triage behavior.
v1.34.41
Security
- Hardened security-scan posture for current code scanning: CodeQL now uses a
production-scope config forsrc/,deploy/, andscripts/instead of
raising alerts from test fixtures; URL allow/deny checks now parse hostnames;
JavaScript-only page detection uses the HTML parser rather than a tag regex;
console output now redacts secret-shaped values; rate-limit logging no longer
emits caller bucket identifiers; role-plan and stage-eval artifacts mask
accidental secrets before persistence through a shared redacted-write helper;
helper scripts no longer print or write generated search API keys directly to
.env; the user key store now uses the same low-level restrictive write path
across platforms; Cosmos status queries are parameterized; and API-key
fingerprints use deterministic PBKDF2-HMAC-SHA256 digests where compatibility
allows. GitHub Actions workflows now default to read-only token permissions,
CI checkouts no longer persist credentials, and Dependabot is configured for
uv and GitHub Actions dependency updates. Azure Functions deployment
requirements now enforce the same secure Azure SDK floors as the main project. - Cleaned up credential-shaped test fixtures and public Azure role-definition
literals so local secret scanning now passes on currentsrc/,docs/,
tests/, anddeploy/paths without masking real leaks. GitHub secret
scanning remains at zero open alerts.
Added
- Added a body-free operator-review block to calibration baseline artifacts and
baseline inspection output. Ready baselines now state that automatic gate
arming is disallowed, list the measured review items an operator must check,
surface cloud-vs-local disagreement counts, and distinguish gate candidates
from report-only recommendations without exposing report bodies or raw claims. - Added dedicated public-board hiring-signal adapters for iCIMS and BambooHR.
Because their official job APIs require authenticated customer or partner
access, Primr now probes their public hosted career portals through bounded
SSRF-safe HTML fetches and feeds the resulting postings through the existing
triage/body-fetch/extraction path. - Added a canonical protected-site page-access eval corpus at
tests/fixtures/page_access/protected_site_trace_corpus.json. The corpus is
built from sanitized traceaccess_assessmentrecords only, covers major
challenge and recovery tags, and includes known false-positive and
false-negative historical cases without committing raw HTML, URLs, page
bodies, company names, or provider payloads. - Added
primr --eval --eval-page-access-fixture <fixture.json>for
operator-facing page-access classifier evals. The command reads labeled
sanitized HTML cases or trace-derivedaccess_assessmentpredictions, then
writes false-positive/false-negative JSON, Markdown, and scorecard-input
quality evidence underoutput/evals/<eval-id>/page_access_stage/without
copying raw HTML, URLs, or page bodies. - Added a body-free offline page-access classifier eval helper. Labeled local
fixtures or trace-derived predictions now produce true/false positive and
false-negative metrics, tag-level breakdowns, and JSON/Markdown review
artifacts without copying raw HTML, URLs, or page bodies. - Added first-party PDF recovery to the blocked-origin fallback fan-out. The
new source discovers same-site PDFs from priority investor/news/about/help
landing pages, adds bounded direct PDF probes, ranks likely annual reports,
fact sheets, overviews, media kits, and guides first, and extracts text
locally with PyMuPDF only assource="first_party_pdf". - Added first-party JSON-LD structured-data recovery to the blocked-origin
fallback fan-out. The new source probes bounded priority same-site pages,
extracts Organization / NewsArticle / Product / Event / Person facts with
stdlib parsing, filters same-site URLs, caps HTML/entity/output budgets, and
returnssource="structured_data"through the existing SSRF-safe HTTP seam
without invoking any paid AI provider. - Added durable host-level positive-marker learning for verified page access.
Once a confirmed real first-party page matches explicit company or host
markers, Primr persists a bounded, filtered marker set underPRIMR_DATA_DIR
and reuses it to classify later pages on the same host without provider calls. - Added clearer blocked-site CLI summaries when live first-party scraping and
same-site recovery both fail. The summary now shows sanitized evidence,
same-site recovery count, and the next fallback action before public-data
recovery starts. - Added A2A
read_report_by_job, an explicit report-scoped owned-job report
read backed by the same MCPprimr://output/report/by_job/{job_id}helper,
withcontent_mode,artifact_type, andmax_charsoutput negotiation.
Changed
- Added browser render-snapshot comparison to page-access classification.
Playwright, DrissionPage, and Patchright browser tiers now compare initial
and final rendered DOM text as compact evidence, so cleared challenges and
stable real pages are less likely to be mistaken for thin interstitials while
persistent challenge templates still escalate. - Updated the Anthropic balanced model to Claude Sonnet 5 (
claude-sonnet-5)
with conservative post-intro price estimates, 128k max output, Sonnet 4.6
back-compat registration, request guards for models that reject sampling
parameters, Sonnet 5output_config.effortsupport, and validation for the
current adaptive-thinkingdisplayvalues. - Expanded Anthropic Messages request shaping for current adaptive-thinking
models:output_config.effortnow acceptsmaxandxhigh, Sonnet 5 can
explicitly disable adaptive thinking, adaptive display config is preserved,
and legacy manual thinking budgets are omitted on tiers that reject them. - Rejected assistant-prefill-shaped Anthropic requests locally for current
Claude model families that return provider-side 400s, including Sonnet 5,
Sonnet 4.6, Opus 4.6 and later, Fable 5, Mythos 5, and Mythos Preview. - Applied a 30% tokenizer safety factor to dry-run estimates for any routed
cost bucket that uses Claude Sonnet 5, matching Anthropic's migration
guidance that the same text can tokenize larger than Sonnet 4.6. - Raised the optional Anthropic SDK floor to
anthropic>=0.109.1so installed
Claude support matches the current Messages API request shape. - Redacted xAI browse/search logs to scheme and host only, and stopped logging
provider error-body snippets on failed browse calls so customer URL paths,
query strings, userinfo, and provider diagnostics do not enter logs. - Made Cowork skill-pack icon generation local by default. Remote image
providers, including xAI Grok Imagine, now require the explicit CLI
--remote-iconsflag or MCPremote_iconsargument so configured provider
keys cannot silently create image API spend. Skill-pack estimates now include
a conservative remote-icon allowance when that opt-in is set, and MCP
approval tokens bind theremote_iconschoice. - Closed two additional hidden-spend paths: missing or stale vendor-research
cache no longer triggers Deep Research unless explicitly enabled, and Gemini
PDF extraction is disabled by default in favor of local PyMuPDF parsing unless
PRIMR_PDF_LLM_MAX_CALLSis set. - Kept authenticated MCP
check_jobs,primr://output/latest, and
primr://output/by_job/{job_id}metadata-first even forreport-scoped
callers, and made A2Acheck_jobsreturn explicit compact resource URIs
instead of raw output paths. - Added body-free OpenTelemetry span projections and stable
request_id
fields to MCP tool, MCP resource, and A2A skill audit events. - Added runtime budget visibility to run manifests and compact usage-summary
readback, including the approved ceiling, active checkpoint status, and
non-interruptible required provider tasks without exposing manifest bodies. - Moved default research memory storage to the per-user data directory
(PRIMR_DATA_DIRoverride) and reject secret-like memory payloads before
durable writes. - Added local
primr company track,company list, andcompany show
commands backed by per-user JSON company profiles with URL/userinfo and
secret-like payload rejection. - Added
primr company exportto write local JSON and Markdown profile bundles
with persisted hypothesis confidence tags and explicit run-history/claim-store
gap markers. - Added bounded body-free run pointers to tracked company profiles so exports
include run history when local run metadata has been recorded.