skip to content →
[ CHANGELOG / FIELD_LOG ]Auto-recorded on merge to main

What we shipped.

One line per merged pull request, dated by merge day. Generated by the same automation that pushes the code, so the only delay between "we shipped it" and "it appears here" is a CI run.

What changed most recently in VectraSEO?

The changelog lists the latest merged pull requests by release date, with the newest shipped change first and older releases kept in the project archive.

Last updated·675 shipped changes across 102 releases

last_update2026-09-29
total_releases102
total_changes675
elapsedtoday
[ RELEASE / 2026-09-29 ]
6 changesTuesday, September 29, 2026
  1. PR_1703
    CHANGEDci: changelog checks also post commit statuses the PR can see

    After #1699 merged, its dispatched run put green backend / frontend / infrastructure check runs on changelog PR #1702's head commit. Once the ruleset required those names,...

    @cigan1
  2. PR_1701
    CHANGEDbuild(deps): Bump undici from 7.29.0 to 7.30.0 in /frontend

    Bumps undici from 7.29.0 to 7.30.0.

    @dependabot[bot]
  3. PR_1700
    CHANGEDfix(writer): other companies' products need their vendor's docs, never untested steps

    Iceland Photo Map (proj_ab5ead538b5947e7) has 3 held drafts with 21, 12 and 4 blocking claims. Almost none are about its own product. They are claims about apps it doesn't com...

    @cigan1
  4. PR_1699
    CHANGEDci: report main's required checks on the changelog PR

    The goal is to require backend, frontend and infrastructure on main. Today gh pr merge --auto merges instantly because the "Protect Main" ruleset requires a PR but no...

    @cigan1
  5. PR_1697
    CHANGEDfix(truth): prose about the business's own API reaches its own evidence

    post_37b7fa16b58641e9 (Emcognito) is still held after #1695 on:

    @cigan1
  6. PR_1695
    CHANGEDfix(truth): prose about the business's own plans reaches its own evidence

    After #1693, Emcognito's replacement draft post_8ee09bd403f4404c was still held. A fresh re-verify plus the owner claim strip ran in prod on 2026-09-28. **8 of its 9 blocking...

    @cigan1
[ RELEASE / 2026-09-28 ]
3 changesMonday, September 28, 2026
  1. PR_1693
    CHANGEDfix(truth): own pricing-table cells and over-budget own claims reach the business's evidence

    Emcognito's held draft post_8ee09bd403f4404c was blocked by 27 claims. Each one is a plan fact that Emcognito's capability file states.

    @cigan1
  2. PR_1691
    CHANGEDfix(truth): own-product facts stated by the business reach the verifier

    After #1689, Tovin's and FolioInbox's held drafts still blocked on own-product claims that their pricing page, Content Brief and capability file all state (e.g. "Folio has n...

    @cigan1
  3. PR_1689
    CHANGEDfix(truth): stop holding drafts on competitor pricing; name blocking claims on retry

    "Posts not generating" (2026-09-28): schedules fired and 152 drafts were created in 7 days, but the truth checker held 37 (24%) in review_required. 34 of those involved `curre...

    @cigan1
[ RELEASE / 2026-09-25 ]
9 changesFriday, September 25, 2026
  1. PR_1687
    CHANGEDfix(claims): repair a destination claim rejection on a metadata field

    Sendant post_bd801e12ca4d4052 is parked in publish_failed (redrive_exhausted). The destination 422'd matched_claim: "onion routing" on field: meta_description ("…o...

    @cigan1
  2. PR_1685
    CHANGEDfix(deepseek-canary): outline reverts on fallbacks only; publish/truth breach is reported

    The outline DeepSeek canary started 2026-09-25 ~19:11 UTC (SSM deepseek_canary_tasks now has outline next to post_metadata). Its guardrail is publish rate + truth first-pa...

    @cigan1
  3. PR_1683
    CHANGEDfix(held-post): stale re-check spinner, spent-allowance button, no 'edit it yourself' copy; two flaky tests

    No prod writes and no model calls.

    @cigan1
  4. PR_1681
    CHANGEDfix(truth): unsupported on own-site-evidenced claims must quote a contradiction

    > Built on #1679 (fix/truth-own-business-evidence). This branch was cut from it. #1679 was merged into main before this PR opened, so the base is main and the diff con...

    @cigan1
  5. PR_1679
    CHANGEDfix(truth): own-site evidence for claims naming the business; bind citations to their sentence

    Two held drafts, post_57bcd3b58653449a (tovin.io) and post_e2121d6e2be04935 (icelandphotomap.com), stayed held after their flagged sentences were edited. Each re-check flagged t...

    @cigan1
  6. PR_1678
    CHANGEDfix(truth): treat the business's own comparison-table column as first-party

    Tovin post post_57bcd3b58653449a was held on a cell in its own column, "Tovin — Pricing Model: …". The extractor had not restated that cell. Under #1587 a cell is first-party...

    @cigan1
  7. PR_1676
    CHANGEDfix(truth): re-check an unconfirmed current capability once before it holds a post

    vectraseo-prod-stranded-posts went to ALARM on 2026-09-25 for two held drafts (post_57bcd3b58653449a Tovin, post_e2121d6e2be04935 Iceland Photo Map). A paid manual strip a...

    @cigan1
  8. PR_1674
    CHANGEDfix(alarms): count pipeline losses from each post's current state

    vectraseo-prod-pipeline-loss-rate went into ALARM at 2026-09-25 01:33 UTC (62.5 / 72.2 / 42.9%). Of the 20 posts it counted as lost from 09-22 to 09-25, 15 were published...

    @cigan1
  9. PR_1672
    CHANGEDfix(deepseek): judge canaries over 7 pooled days on what each task affects

    The per-day rollback rule (PRD §10) breached 18 of 19 pre-canary days on unchanged operator traffic (~6 truth-checked posts a day). The post_metadata canary was going to rev...

    @cigan1
[ RELEASE / 2026-09-24 ]
16 changesThursday, September 24, 2026
  1. PR_1670
    CHANGEDfix(citations): stop draining real sources below the source floor

    Three EchoThread drafts on one topic (post_44024259, post_dc601cb6, post_0e75f61c) sat at review_required, the only held posts in prod, each at **1 of 3 external sources...

    @cigan1
  2. PR_1668
    CHANGEDfix(ladder): re-check exhausted rejection parks with today's free remediation

    A never-published post that used up its publish_reject_repair_attempts stayed at publish_failed permanently, even after a later repair fix could clear it. `post_0e3fccfcb9f6...

    @cigan1
  3. PR_1666
    CHANGEDfix(content): flag findings credited to a site's home page (report-only)

    "According to research from X" linked only to X's home page cites nobody. EchoThread post_dc601cb63efd4c0c credited a "chilling effect" finding to cyber.harvard.edu/ and new...

    @cigan1
  4. PR_1664
    CHANGEDfix(ladder): a provider outage never advances or archives a post

    Gemini returned 503 "high demand" after 5 retries, the Anthropic fallback timed out, and OpenAI returned 429 insufficient_quota. During that window the Publish-Readiness ladde...

    @cigan1
  5. PR_1663
    CHANGEDfeat(ladder): auto-replace drafts held at review_required, one grant per topic

    A draft parked at review_required had no automatic exit unless a later claim-guard change happened to clear it. EchoThread post_44024259deae4f97 shows the full failure. Its...

    @cigan1
  6. PR_1661
    CHANGEDfix(generation): re-plan sources when a draft falls below the source floor

    post_44024259deae4f97 (EchoThread, gap gap_41fef2cf163e4ec8) is parked at review_required because it cites 1 of 3 required sources.

    @cigan1
  7. PR_1659
    CHANGEDfix(phase-scheduler): recovery-stranded posts mid-ladder are still advanced

    _automatic_recovery_jobs put every recovery-marked post, and every post for which sweep_action returned *any* action including "stranded", into recovery_ids. `process_du...

    @cigan1
  8. PR_1657
    CHANGEDfix(truth): a table row ordinal is not a pricing tier; retire the advice-scope filter

    post_44024259deae4f97 (EchoThread, "Hostile Comment Threads") was held on five product_capability claims such as *"Observed Behavior — Tier 1: Robust Debate: Robust debate c...

    @cigan1
  9. PR_1656
    CHANGEDfix(recovery): apply the citation-floor lite rescue in automatic recovery

    EchoThread post_8dc207b034f542ba has been parked at review_required since 2026-09-23. Its fact-check is verified (truth 100, 19/19 claims supported), and metadata, lint and...

    @cigan1
  10. PR_1655
    CHANGEDfix(truth): no space before punctuation in capability claim text

    The "It is free on every plan ." claims on the EchoThread drafts did not come from inserted text. The body is correct: <a href="…/pricing/">free on every plan</a>. (read-only...

    @cigan1
  11. PR_1654
    CHANGEDfix(sitemap): follow same-host Sitemap: lines in robots.txt

    Tempkey's configured /sitemap.xml listed only marketing pages, and its blog sitemap was declared only in robots.txt. As a result, the GSC index check flagged 118 published p...

    @cigan1
  12. PR_1651
    CHANGEDfix(held-post): only offer "Remove unconfirmed claims" when it can clear the hold

    The held-draft button (#1646) was offered on drafts that also fail content quality. Stripping sentences only removes text, so it can never lift a draft that is already below the...

    @cigan1
  13. PR_1652
    CHANGEDfix: stop demanding outside sources for a business's own limits

    Content quality's uncited-claim check (_sentences_with_unsourced_claims, backend/app/services/blog_quality.py; trigger _HIGH_RISK_CLAIM_RE at line 55) flags any sentence c...

    @cigan1
  14. PR_1649
    CHANGEDfix(truth): stop gluing question headings onto the claims that follow them

    The truth layer merged an FAQ question heading into the claim that follows it. The merged claim can't be matched to any source, so it comes back unverifiable and holds the post.

    @cigan1
  15. PR_1648
    CHANGEDfix: stop flagging a budget-blocked scheduled run as a missed window

    On 2026-09-23 UTC, Tovin, DNSCove and Tempkey were each flagged Scheduled post overdue even though each had published a post that UTC day. Their scheduled full_seo_run job...

    @cigan1
  16. PR_1646
    CHANGEDfix: give owners a way out of a draft held by checks

    A draft held by the truth gate reached review_required and then had nowhere to go. The detail page hid every action and said "No manual flag review is needed", but automatic r...

    @cigan1
[ RELEASE / 2026-09-23 ]
29 changesWednesday, September 23, 2026
  1. PR_1644
    CHANGEDtest: stop test_sc_004 flaking on a loaded runner

    test_typesafe_jev::test_sc_004 failed intermittently in full-suite runs (passed alone every time).

    @cigan1
  2. PR_1643
    CHANGEDfix: ordinary CLAIM_STRIP keeps the business's own call to action

    1. Before stripping, it runs partition_protected over claim_strip.strip_target_claims. That is the stripper's own verdict filter (unsupported, plus unverifiable unde...

    @cigan1
  3. PR_1641
    CHANGEDfix(truth): accept the project's own capability file as first-party evidence

    Tempkey's operator post keeps getting held on claims that are true and about Tempkey itself: "public REST API covering grants, extension, revocation…", "administrative sign-in i...

    @cigan1
  4. PR_1640
    CHANGEDfix(publish-lint): detect and salvage writer-directed phrasing rules

    A capability contract's preferred_wording put a writer-directed sentence into Tempkey post bodies, and publish lint let it through:

    @cigan1
  5. PR_1639
    CHANGEDfix: never strip the business's own call to action during recovery

    The automatic-recovery strip step from #1638 deletes every sentence that carries an unconfirmed claim. That includes the business's own promotion. In a prod re-drive it was abou...

    @cigan1
  6. PR_1638
    CHANGEDAutomatic recovery: remove unconfirmed claims and publish the rest

    Automatic recovery publishes only when every claim in a fresh truth report is supported. Drafts held by a few claims no source could confirm (Tempkey, Marry Math) stayed held...

    @cigan1
  7. PR_1636
    CHANGEDdocs: 2026-09-22 QA evidence and TypeSafe/Jev decision report

    Commits QA reports that were sitting uncommitted in the main checkout. Docs only, no code or config changes.

    @cigan1
  8. PR_1635
    CHANGEDfeat: daily DeepSeek canary evaluator with automatic revert (REQ-canary-auto)

    The DeepSeek canary now polices itself (PRD section 10, new REQ-canary-auto).

    @cigan1
  9. PR_1634
    CHANGEDfix: convert floats before the ladder's conditional phase write

    PostRepository.conditional_advance_phase builds its own update_item call and never converts floats; BaseRepository.update does. Any payload carrying a fresh verify_post...

    @cigan1
  10. PR_1633
    CHANGEDfeat: DeepSeek phase 3 — routable writer path + decisive writer/truth eval

    DeepSeek phase 3 (docs/prd/cost-optimized-content-pipeline.md, DL-003 "all ungrounded tasks"). The scheduled writer path can now be routed. Before this, routing saved almost not...

    @cigan1
  11. PR_1632
    CHANGEDdocs: correct the draft-loss counts behind #1630

    Corrects two numbers in the docs and a docstring that #1630 merged. They were found when the terminal-outcome rows were recounted by archive reason.

    @cigan1
  12. PR_1630
    CHANGEDfix: repair capability truth holds at CLAIM_STRIP instead of regenerating

    The current-capability truth gate shipped in 084ac618 on 2026-09-22. Since then, a post held on an unconfirmed third-party plan or file-format claim had no repair:

    @cigan1
  13. PR_1628
    CHANGEDfix: never cap free recovery releases; paid recovery longest-held first

    Production caps recovery at one dispatch per 15-minute sweep (automatic_recovery_batch_size=1). After #1623 shipped, FolioInbox post_1d1c98f23ad24610 was a release candidate...

    @cigan1
  14. PR_1626
    CHANGEDfix: treat DeepSeek nulls on optional schema properties as absent; record 2026-09-23 eval

    Follow-up to #1624.

    @cigan1
  15. PR_1624
    CHANGEDfeat: DeepSeek phase 2 — route eval, cost KPI + admin view, off-peak deferral, canary gate

    Phase 2 of docs/prd/cost-optimized-content-pipeline.md (phase 1: #1621). Nothing changes in production at merge: no task is routed, the canary lists are empty, off-peak de...

    @cigan1
  16. PR_1623
    CHANGEDfix: un-strand automatic recovery; two bounded automatic retries; claim-keyed replacement futility

    Once deployed, the recovery sweep releases the stuck post on its first run. Unresolved backlog posts become eligible for retry #1, dispatched at automatic_recovery_batch_size...

    @cigan1
  17. PR_1620
    CHANGEDScope recovery advice checks and preserve prices during softening

    Scheduled posts are parked on truth-gate holds with 1-3 residual claims. One source: the product-capability backstop read a moderation row labelled Tier 1: Robust Debate as a...

    @cigan1
  18. PR_1621
    CHANGEDfeat: DeepSeek task routing core with Gemini fallback, customer gate and Jev first-pass

    P0 core of the cost-optimized content pipeline (docs/prd/cost-optimized-content-pipeline.md, tdd/cost-optimized-content-pipeline.tdd.yaml).

    @cigan1
  19. PR_1618
    CHANGEDdocs: spec + TDD for DeepSeek/TypeSafe cost-optimized pipeline

    Clarified spec and red-phase TDD artifact for moving model spend to the cheapest provider that passes each task's quality bar.

    @cigan1
  20. PR_1616
    CHANGEDPreserve source evidence during held-post recovery

    Held-post recovery could hide the strongest evidence when reserving space for supplemental sources, and its grounded-response formatter could discard source URLs. Rank passages...

    @cigan1
  21. PR_1614
    CHANGEDReserve recovery Jev allowance for fresh verification

    Correction hints and fresh verification currently spend the same eight-request Jev allowance. Two recovery canaries exhausted it and left 14 later source-backed claim records ea...

    @cigan1
  22. PR_1613
    CHANGEDFix repeated-claim repairs and missing evidence in held-post recovery

    Held-post recovery skipped repeated current assertions, missed fresh product-contract evidence, and could introduce failed citation links. It now binds repeated prose to individ...

    @cigan1
  23. PR_1612
    CHANGEDFinish correcting unresolved claims in legacy verified reports

    A truth report can have legacy status verified while still containing generic unverifiable claims. Recovery requires supported evidence for every claim, so checking only that...

    @cigan1
  24. PR_1610
    CHANGEDFix held-post recovery and let Jev lead bounded evidence decisions

    Held posts could skip AI repair despite unresolved claims, exhaust Gemini's old allowance, or spend extra resolution calls solely because Jev abstained. This change fixes that r...

    @cigan1
  25. PR_1609
    CHANGEDfix: keep stale scheduler checks from interrupting recovery

    A production scheduler recheck read Tempkey before automatic recovery claimed it, then moved the already-running recovery back to gate_check. Recovery correctly refused to ove...

    @cigan1
  26. PR_1608
    CHANGEDfix: restore first-party evidence and recover missing citations

    Held posts could not verify their own product claims when a legacy project stored a bare domain: first-party fetching rejected it and internal links were classified as external....

    @cigan1
  27. PR_1606
    CHANGEDCorrect held posts before rechecking and preserve negative facts

    Held drafts could spend the six-call recovery allowance re-investigating saved findings, leaving no room to correct them. Recovery now corrects exact, unique flagged sentences f...

    @cigan1
  28. PR_1604
    CHANGEDPreserve claim citations and recovery allowance for final checks

    Held drafts could lose an extracted citation when the literal capability backstop replaced the claim; the first automatic recovery trial also spent its six Gemini calls before r...

    @cigan1
  29. PR_1602
    CHANGEDRecover held posts with Gemini and Jev instead of manual review

    Held posts currently leave the owner with manual flag reviews and no automatic next step. This adds one bounded Gemini/Jev investigation per post and policy: retrieve relevant s...

    @cigan1
[ RELEASE / 2026-09-22 ]
9 changesTuesday, September 22, 2026
  1. PR_1600
    CHANGEDfix: allow guarded post feedback transactions

    Saving post review feedback returned HTTP 500 because the API execution role lacked dynamodb:ConditionCheckItem. The transaction checks both the current post snapshot and proj...

    @cigan1
  2. PR_1598
    CHANGEDfix: clarify what to review in post feedback

    The post review panel asked users to judge “valid” or “mistaken” flags without explaining what was uncertain. It now asks “Does this sentence need fixing?” with visible Needs fi...

    @cigan1
  3. PR_1596
    CHANGEDfix: separate unresolved posts from replacement history

    The evaluation page offered review links for every project, including projects with no problematic posts, and mixed replaced originals with unresolved work. It now shows counted...

    @cigan1
  4. PR_1594
    CHANGEDAdd assisted feedback for problematic posts and explain experiment progress

    Held and automatically archived posts currently expose automated flags but provide no way to record whether those flags were valid. This adds an admin-only Problematic filter an...

    @cigan1
  5. PR_1592
    CHANGEDAdd admin status and review-gated TypeSafe evaluation campaign

    Admins currently have no persistent indication that the Jev evidence-selection comparison needs label review or has produced results. Add an admin-only status page, sidebar atte...

    @cigan1
  6. PR_1590
    CHANGEDDisable default Jev routing and retain a bounded evidence pilot

    Jev made no accepted decisions in the observed production cycles, so default traffic was paying for Jev and still falling back to Gemini. Make all three stages default to off,...

    @cigan1
  7. PR_1588
    CHANGEDfix: preserve first-party ownership in capability tables

    Fixes #1587.

    @cigan1
  8. PR_1585
    CHANGEDfix: verify current product claims against fetched evidence

    A production tutorial was marked truth-verified despite an obsolete free-plan allowance and a CSV import promise that extraction omitted. Current product promises now retain tab...

    @cigan1
  9. PR_1582
    CHANGEDAdd selective Jev verification, capability checks, and evidence selection

    Citation verification, product-capability checks, and evidence selection currently send every semantic decision to Gemini. This adds TypeSafe Jev as a selective first pass: conf...

    @cigan1
[ RELEASE / 2026-09-21 ]
4 changesMonday, September 21, 2026
  1. PR_1576
    CHANGEDFix blocked Search Console refresh feedback and expand access-warning tests

    Search Console settings showed “Synced” after a refresh was skipped because property access was blocked. Only completed, non-skipped refreshes now show that success message; the...

    @cigan1
  2. PR_1573
    CHANGEDFix hosted blog metadata, conversion tracking and sitemap hygiene

    Hosted blog publishes ignored the adapter's seo_title and meta_description, and those pages lacked the site's GA4 tag and a clear next step. Honor the search metadata and in...

    @cigan1
  3. PR_1571
    CHANGEDRestore acquisition visibility and align signup analytics with site design

    The signup dashboard omitted anonymous audits entirely and scanned roughly 347,000 unrelated shared-table records to find 25 accounts. Existing users could appear missing behind...

    @cigan1
  4. PR_1568
    CHANGEDAdd audit onboarding, owner signup analytics, and Search Console access alerts

    Visitors who request a sign-in link after a free audit currently lose the path to monitoring, while the owner cannot distinguish requests from completed sign-ins. Search Console...

    @cigan1
[ RELEASE / 2026-09-20 ]
4 changesSunday, September 20, 2026
  1. PR_1561
    CHANGEDfix(pipeline): give phase_advance a per-post FIFO lane

    run_phase_advance re-raises so SQS redelivers, and the comment above that raise accepted the cost explicitly:

    @cigan1
  2. PR_1559
    CHANGEDops(api): raise burst limit off first-party traffic, alarm on saturation

    Two changes to the API's burst posture, both from live evidence gathered while re-checking the 2026-09-19 scanner incident.

    @cigan1
  3. PR_1557
    CHANGEDfix(pagination): admin leads cursor onto the shared codec

    Follow-up to #1555. The admin inbox (GET /api/v1/admin/leads) was the last paginated endpoint still handing out a raw DynamoDB sort key as its cursor.

    @cigan1
  4. PR_1555
    CHANGEDfix(pagination): opaque, validated cursors — the gaps 500

    vectraseo-prod-api-gateway-5xx fired 2026-09-19 23:33 UTC. The

    @cigan1
∎94 older releases kept in CHANGELOG.md