Skip to content

chore(deps): bump the npm-minor-patch group across 1 directory with 10 updates - #131

Closed
dependabot[bot] wants to merge 151 commits into
mainfrom
dependabot/npm_and_yarn/npm-minor-patch-faa6c22944
Closed

dependabot[bot] wants to merge 151 commits into
mainfrom
dependabot/npm_and_yarn/npm-minor-patch-faa6c22944

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Oct 3, 2026

Copy link
Copy Markdown
Contributor

Bumps the npm-minor-patch group with 10 updates in the / directory:

Package From To
prettier 3.9.7 3.9.9
@tanstack/react-query 5.103.1 5.104.0
lucide-react 1.47.0 1.49.0
next 16.3.5 16.3.8
yjs 13.6.32 13.6.33
@types/node 26.6.1 26.6.3
eslint-config-next 16.3.5 16.3.8
jsdom 30.0.1 30.1.1
vite 8.3.0 8.3.1
vitest 5.0.1 5.0.3

Updates prettier from 3.9.7 to 3.9.9

Release notes

Sourced from prettier's releases.

3.9.9

  • Markdown: Fix text with $ been incorrectly parsed as math syntax (#20140 by @​fisker)

🔗 Changelog

3.9.8

  • Markdown: Don't let Liquid objects interrupt paragraphs (#20087 by @​seiyab)

🔗 Changelog

Changelog

Sourced from prettier's changelog.

3.9.9

diff

Markdown: Fix text with $ been incorrectly parsed as math syntax (#20140 by @​fisker)

<!-- Input -->
**Uses $FOO** from `a.sh` and `b.sh`, plus `$BAR` from `c.sh`, before anything else runs here.
<!-- Prettier 3.9.8 -->
Uses $FOO from a.sh and b.sh, plus $BARfromc.sh, before anything else runs here.
<!-- Prettier 3.9.9 -->
Uses $FOO from a.sh and b.sh, plus $BAR from c.sh, before anything else runs here.

3.9.8

diff

Markdown: Don't let Liquid objects interrupt paragraphs (#20087 by @​seiyab)

<!-- Input -->
If `module` is not a [`WebAssembly.Module`](https://github.com/prettier/prettier/blob/main/en-US/docs/WebAssembly/Reference/JavaScript_interface/Module) object instance, a
{{jsxref("TypeError")}} is thrown.
<!-- Prettier 3.9.7 -->
If module is not a WebAssembly.Module object instance, a
{{jsxref("TypeError")}} is thrown.
<!-- Prettier 3.9.8 -->
If module is not a WebAssembly.Module object instance, a
{{jsxref("TypeError")}} is thrown.

Commits

Updates @tanstack/react-query from 5.103.1 to 5.104.0

Release notes

Sourced from @​tanstack/react-query's releases.

@​tanstack/react-query-devtools@​5.104.0

Minor Changes

Patch Changes

  • Updated dependencies [5279b05]:
    • @​tanstack/query-devtools@​5.104.0
    • @​tanstack/react-query@​5.104.0

@​tanstack/react-query-next-experimental@​5.104.0

Minor Changes

Patch Changes

  • Updated dependencies [5279b05]:
    • @​tanstack/react-query@​5.104.0

@​tanstack/react-query-persist-client@​5.104.0

Minor Changes

Patch Changes

  • Updated dependencies [5279b05]:
    • @​tanstack/react-query@​5.104.0
    • @​tanstack/query-persist-client-core@​5.104.0

@​tanstack/react-query@​5.104.0

Minor Changes

Patch Changes

  • Updated dependencies [5279b05]:
    • @​tanstack/query-core@​5.104.0

@​tanstack/react-query-devtools@​5.103.3

Patch Changes

@​tanstack/react-query-next-experimental@​5.103.3

... (truncated)

Changelog

Sourced from @​tanstack/react-query's changelog.

5.104.0

Minor Changes

Patch Changes

  • Updated dependencies [5279b05]:
    • @​tanstack/query-core@​5.104.0

5.103.3

Patch Changes

  • #11647 1c9693e - fix(codemods): avoid copying unnecessary files from codemods project
  • Updated dependencies []:
    • @​tanstack/query-core@​5.103.3

5.103.2

Patch Changes

  • Updated dependencies [8a28904]:
    • @​tanstack/query-core@​5.103.2
Commits
  • d4033eb ci: Version Packages (#11651)
  • 5279b05 chore(deps): update Vite from v6 to v8 (#11650)
  • fe053bf ci: Version Packages (#11612)
  • 1c9693e fix(codemods): update codemods build script (#11647)
  • f00aad6 chore(deps): update dev dependencies (#11640)
  • 2443290 test(*): rename 'console.error' spies to 'consoleErrorMock' (#11646)
  • fcab29f test({query-core,react-query,preact-query}): restore the previous 'isServer' ...
  • e8dacbe docs({react-query,preact-query,solid-query,svelte-query}/README): point the C...
  • 57f40eb chore(deps): update non-major dependencies (#11625)
  • 397ad07 test({query-core,react-query,preact-query,solid-query}): pass 'unhandledRejec...
  • Additional commits viewable in compare view

Updates lucide-react from 1.47.0 to 1.49.0

Release notes

Sourced from lucide-react's releases.

Version 1.49.0

What's Changed

New Contributors

Full Changelog: lucide-icons/lucide@1.48.0...1.49.0

Version 1.48.0

What's Changed

New Contributors

Full Changelog: lucide-icons/lucide@1.47.0...1.48.0

Commits
  • e042fec fix(packages): declare @types/react as an optional peer dependency (#4892)
  • f06ac67 chore(typchecking): More typecheck jobs for all packages (#4885)
  • See full diff in compare view

Updates next from 16.3.5 to 16.3.8

Release notes

Sourced from next's releases.

v16.3.8

This release contains security fixes for the following advisories:

High:

Medium:

Low:

v16.3.7

[!NOTE] This release is backporting bug fixes. It does not include all pending features/changes on canary.

Core Changes

  • turbo-tasks-backend: fix strongly consistent read hanging on a canceled task (#98931)

Credits

Huge thanks to @​lukesandberg for helping!

v16.3.6

This release contains a security fix for GHSA-vcvr-r3jv-pc5j: Remote Code Execution in next/og ImageResponse

Commits
  • b0fad0d v16.3.8
  • 719e4c6 [lts-active] Scope response cache keys to their source route (#218)
  • e92db45 [lts-active] Fix metadata propagation for deduplicated nested caches (#223)
  • 40c2ba9 [lts-active] Match Next data paths case-sensitively (#196)
  • 2d9f50a [lts-active] Fix MCP middleware DNS rebinding (#213)
  • bd9214f [lts-active] Fix draft mode leaks through cross-request 'use cache' dedupli...
  • 8db4a62 [lts-active][webpack] Ensure dynamicParams is respected in `opengraph-image...
  • e002ad6 [lts-active] fix(next/image): Pin DNS resolution when fetching external image...
  • 4c20699 v16.3.7
  • 2521aec [backport] turbo-tasks-backend: fix strongly consistent read hanging on a can...
  • Additional commits viewable in compare view

Updates yjs from 13.6.32 to 13.6.33

Release notes

Sourced from yjs's releases.

v13.6.33

  • set currentTarget of deep events right before calling observers - fixes #768, closes #801 713a2895

Thanks to @​aartrost & @​dikshit-n for the fixes!


yjs/yjs@v13.6.32...v13.6.33

Commits

Updates @types/node from 26.6.1 to 26.6.3

Commits

Updates eslint-config-next from 16.3.5 to 16.3.8

Release notes

Sourced from eslint-config-next's releases.

v16.3.8

This release contains security fixes for the following advisories:

High:

Medium:

Low:

v16.3.7

[!NOTE] This release is backporting bug fixes. It does not include all pending features/changes on canary.

Core Changes

  • turbo-tasks-backend: fix strongly consistent read hanging on a canceled task (#98931)

Credits

Huge thanks to @​lukesandberg for helping!

v16.3.6

This release contains a security fix for GHSA-vcvr-r3jv-pc5j: Remote Code Execution in next/og ImageResponse

Commits

Updates jsdom from 30.0.1 to 30.1.1

Release notes

Sourced from jsdom's releases.

v30.1.1

  • Fixed spurious window blur and focusout events and incorrect event.relatedTarget values when focusing an element after removing the previously focused element, which regressed in v30.1.0. (@​asamuzaK)
  • Fixed focus and blur behavior across frames, and focusing the document's viewport through document.documentElement.focus(). (@​asamuzaK)
  • Fixed focus targets removed or disabled by blur listeners becoming active, and text selections made by focus and blur listeners being overwritten. (@​asamuzaK)
  • Fixed element.focus() incorrectly focusing disabled form controls and <input type="hidden"> elements with tabindex="". (@​scttcper)
  • Fixed invalid style.setProperty() calls changing existing !important priorities, serialized styles, or mutation records. (@​FedgeNo)
  • Fixed !important handling when updating CSS longhands after shorthands, using variables or CSS-wide keywords, and assigning style properties directly. (@​FedgeNo)
  • Fixed <noscript> parsing with includeNodeLocations: true or inside frames to honor the runScripts option.
  • Fixed the storageQuota option being ignored by frames.
  • Fixed encoding detection of HTML and XML byte input to honor XML encoding declarations and detect UTF-16 without a byte order mark.
  • Fixed exceptions caused by truncated charset parameters in <meta> elements, and encoding detection incorrectly using incomplete <meta> tags. (@​FedgeNo)
  • Fixed XML serialization errors for namespaces named constructor, toString, __proto__, or "null", and incorrect reuse of namespace prefixes declared on sibling elements.
  • Fixed element.innerHTML and element.outerHTML in XML documents to reject invalid characters in attribute values and avoid stack overflows on large strings.
  • Fixed selector matching for :lang(), :nth-child(... of ...) after mutations, and :has() with duplicate IDs or nested logical pseudo-classes. (@​asamuzaK)

v30.1.0

jsdom is feeling the AGI!

This release is dedicated to @​scttcper, who unleashed @​codex upon jsdom and found tons of performance improvements. Along the way, he found and fixed many correctness issues as well.

We really appreciate his thoughtful PRs, which did a great job following the project's contribution guidelines, and were clearly human-curated, with their PR descriptions edited to be brief and respectful of the maintainers' time.

Thanks to @​scttcper, as well as all the other contributors of this release (most of whom were AI-assisted).

  • Added named access to elements on document, such as document.myForm for <form name="myForm">. (@​vojtisprime11)
  • Added QuotaExceededError, including its use for storage quota errors and oversized crypto.getRandomValues() requests.
  • Added support for the relaxed DOM naming rules when creating elements, attributes, and document types.
  • Improved performance of DOM construction, tree mutations, range operations, and live collection access, especially on large documents. (@​scttcper, @​erezrokah)
  • Improved performance of getComputedStyle(), style changes, and CSS serialization. (@​scttcper, @​jhult)
  • Improved performance of event dispatch, form control and label lookups, and updates to <select> elements and radio button groups. (@​scttcper)
  • Reduced memory use when creating and working with DOM nodes, attributes, event listeners, and mutation observers. (@​scttcper)
  • Changed window.close() to preserve access to the document and its DOM through retained references.
  • Fixed element.querySelectorAll() returning no matches when the first part of the selector matches the element itself, which regressed in v30.0.0. (@​asamuzaK)
  • Fixed case sensitivity in CSS attribute selectors, including selectors matching data-state="", title="", and other case-sensitive values. (@​asamuzaK)
  • Fixed document.querySelector() failing to find a matching element when an earlier element has the same ID but does not match the rest of the selector. (@​vojtisprime11)
  • Fixed :focus matching in shadow trees. (@​asamuzaK)
  • Fixed DOM insertion and replacement, including valid document.replaceChildren() calls, invalid document element and doctype placements, and mutations during element.replaceWith().
  • Fixed the ordering of script execution, custom element callbacks, iframe loading, and mutation observer notifications during DOM insertion, including in shadow trees.
  • Fixed queued events and navigation continuing after window.close() or iframe removal, and prevented new scripts, resource loads, timers, and animation frames from starting in destroyed documents. (@​scttcper)
  • Fixed parent documents waiting indefinitely for loading to finish when a child iframe removes itself during loading.
  • Fixed request cancellation across redirects, during pending requestInterceptor() callbacks, and when reusing an XMLHttpRequest after aborting it.
  • Fixed resource loading and JSDOM.fromURL() potentially hanging when response handling throws and response stream cleanup does not finish.
  • Fixed successful cached resource loads being treated as aborted.
  • Fixed getComputedStyle() and document.styleSheets using the wrong stylesheet order after inserting or updating <style> elements.
  • Fixed getComputedStyle() ignoring nested @import and @media rules in imported stylesheets, and returning stale results after imports finish loading.
  • Fixed style invalidation, stylesheet removal, and frame source updates in shadow trees.
  • Fixed repeated getComputedStyle() calls changing case-sensitive background URLs, and inconsistent resolution of border shorthands containing system colors. (@​scttcper)
  • Fixed computed border widths, including borderless elements incorrectly reporting 16px, which regressed in v30.0.0. (@​Alberto-BaseNet)
  • Fixed getComputedStyle() to resolve 'font-weight' keywords to numeric values. (@​tianrking)
  • Fixed getComputedStyle() to convert lengths to pixels inside CSS math functions containing percentages, and to resolve percentages in 'font-size' math functions. (@​soroushm)

... (truncated)

Commits
  • 0a117f4 30.1.1
  • 103f67d Remove unnecessary window cleanup from API tests
  • cdda00a Test HTTP/2 document and subresource loading
  • 7ab92ce Update @​asamuzakjp/dom-selector to v9.2.1
  • d940c20 Share jsdom settings across descendant windows
  • 6ba40cb Fix and simplify option propagation
  • 3b3be70 Preserve CSS priorities across declaration updates
  • 97b2758 Align focusing and unfocusing with HTML
  • b7b460b Update w3c-xmlserializer to v6
  • 71d562f Update html-encoding-sniffer to v7
  • Additional commits viewable in compare view

Updates vite from 8.3.0 to 8.3.1

Release notes

Sourced from vite's releases.

v8.3.1

Bug Fixes

  • deps: update all non-major dependencies (#23482) (3c752c8)
  • deps: update all non-major dependencies (#23537) (e8990c4)
  • deps: update rolldown-related dependencies (#23483) (9aecbbf)
  • handle server.ws: false in mergeConfig (#23511) (f68c0d5)
  • merge build.rolldownOptions.output.comments correctly (#23514) (4aba8d8)
  • optimizer: don't skip imports whose binding starts with type (#23540) (39330f4)
  • optimizer: resolve pending discovered dep processing on close before init (#23567) (5f89433)
  • server: avoid reinitializing watcher when adding file after server close (#23572) (6f831f9)
  • sourcemap: skip URL source roots when injecting sources content (#23519) (04fc30a)

Miscellaneous Chores

Code Refactoring

Changelog

Sourced from vite's changelog.

8.3.1 (2026-09-24)

Bug Fixes

  • deps: update all non-major dependencies (#23482) (3c752c8)
  • deps: update all non-major dependencies (#23537) (e8990c4)
  • deps: update rolldown-related dependencies (#23483) (9aecbbf)
  • handle server.ws: false in mergeConfig (#23511) (f68c0d5)
  • merge build.rolldownOptions.output.comments correctly (#23514) (4aba8d8)
  • optimizer: don't skip imports whose binding starts with type (#23540) (39330f4)
  • optimizer: resolve pending discovered dep processing on close before init (#23567) (5f89433)
  • server: avoid reinitializing watcher when adding file after server close (#23572) (6f831f9)
  • sourcemap: skip URL source roots when injecting sources content (#23519) (04fc30a)

Miscellaneous Chores

Code Refactoring

Commits
  • 39ddf7c release: v8.3.1 (#23573)
  • f68c0d5 fix: handle server.ws: false in mergeConfig (#23511)
  • 6f831f9 fix(server): avoid reinitializing watcher when adding file after server close...
  • 04fc30a fix(sourcemap): skip URL source roots when injecting sources content (#23519)
  • 5f89433 fix(optimizer): resolve pending discovered dep processing on close before ini...
  • 63567c7 chore(optimizer): add debug log when waiting for dep before init (#23566)
  • e8990c4 fix(deps): update all non-major dependencies (#23537)
  • af7cdf6 refactor: replace find with some (#23554)
  • 39330f4 fix(optimizer): don't skip imports whose binding starts with type (#23540)
  • 9abd99b refactor: remove duplicate configurations (#23532)
  • Additional commits viewable in compare view

Updates vitest from 5.0.1 to 5.0.3

Release notes

Sourced from vitest's releases.

v5.0.3

   🐞 Bug Fixes

    View changes on GitHub

v5.0.2

   🐞 Bug Fixes

QuintinBotes and others added 30 commits June 26, 2026 21:23
Approved design for the autonomous overnight Forge build:
- Maximize V1 breadth, Knowledge/RAG as the deep spine
- TDD + green gates, max overnight burn
- Pre-partition + frozen contracts so parallel work integrates

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase-ordered, contract-first plan the swarm builds against:
Phase 0 architect (data model + frozen contracts + pre-stubbed integration points),
Phase 1 parallel feature fan-out (TDD + 3-vote verify), Phase 2 integration, Phase 3 report.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…mit cutoff)

Automated safety checkpoint. Build swarm wf_7e48b881-b69 stopped at session limit
before its 'commit phase 1' step ran. This snapshots all on-disk work (Phase 1
package code/tests + the 39 implementation slices) so nothing is lost. Verification
(uv sync / pytest) and Phase 2/3 still pending on resume.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- requires-python >=3.13 across all 17 members; .python-version=3.13; CI + Dockerfiles -> 3.13
- uv lock --upgrade -> latest of all 79 deps (pydantic 2.13.4, sqlalchemy 2.0.51,
  fastapi 0.138.1, starlette 1.3.1, httpx 0.28.1, alembic 1.18.5, ...)
- uv.lock now tracked (was gitignored) for reproducible builds
- Verified green: 941 passed/3 skipped (no PG) -> 944 passed/0 skipped on real pgvector;
  ruff clean; alembic 0001_baseline applies on real Postgres
- Python 3.14 deferred: only 3.14.0rc1 available here and latest pydantic breaks on it (PEP 649)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…int 9, vite 8, vitest 4, TS 6

- Tailwind v3->v4 migration (@tailwindcss/postcss, @import tailwindcss, @config, tw-animate-css)
- Next 16: flat eslint.config.mjs (next lint removed); dropped next.config eslint key; TS6 fixes
- eslint held at ^9 (eslint-config-next@16 caps <=9; 10 deferred), vite ^8 added for vitest 4
- CI pnpm 9->10 (lockfile regenerated with pnpm 10)
- Verified green: pnpm build/test(28)/lint/typecheck; python 944 passed on real pgvector

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
QuintinBotes and others added 24 commits July 12, 2026 14:01
…replay of agent runs (#62)

* feat(runtime): record-replay cassette + recording model/tool wrappers

* feat(runtime): deterministic replayer (substitution) + divergence canary

* feat(db): RunRecording table + migration 0037 + gated worker recorder sink

* feat: run replay API + forge-replay CLI + run-trace replay control

* feat(runtime): counterfactual fork — replay to a point, then diverge to a different model

---------

Co-authored-by: Forge Swarm <quintinbotes@outlook.com>
… change in-sandbox before the human gate (#63)

* feat(coordinator): ADVERSARY sub-agent role + tools + artifact kind

* feat(coordinator): in-sandbox adversary attack harness (executed failing-test proof + heterogeneity)

* feat: red-team gate wired into the feature workflow before the human gate + RedTeamRecord (migration 0038)

* feat: red-team verdict API + approval-gate badge

---------

Co-authored-by: Forge Swarm <quintinbotes@outlook.com>
…s private per-repo suite (trust-layer 4/4) (#64)

* feat(db): per-repo private benchmark suites + hidden-test SweCase fields (migration 0039)

* feat(eval): mint private benchmark cases from merged PRs (fail-to-pass/pass-to-pass)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(eval): sandboxed fail-to-pass/pass-to-pass runner + agent.fail_to_pass_rate metric

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(eval): Self-Eval run aggregation over a private suite (resolution rate + baseline check)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(eval): Self-Eval Gate — block config changes that regress the private-suite resolution rate

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(self-eval): keep private per-repo suites off the public surface (slice 6/6)

A workspace's Self-Eval suite is minted from its own private repo and is
published so the workspace can rank against its recorded baseline — but it must
never leak to the unauthenticated /public/* API. Enforce that at every public
read path (defence in depth):

* BenchmarkService.list_suites(public_only=True) — filters to global,
  non-private suites only; wired into GET /public/benchmarks.
* BenchmarkService.leaderboard(public_only=True) — 404s a published-but-private
  suite as if it did not exist.
* BenchmarkService.public_submission — same guard on the submission-detail /
  bundles routes, closing the back-door leak.
* BenchmarkService.is_public_suite(suite) — the single predicate all three share.

Tests: parametrized over the `private` flag and `workspace_id` scoping, asserting
a published private suite is invisible via listing, leaderboard, and submission
detail. Renamed the colliding tests/sweval/test_runner.py -> test_swe_runner.py
(basename clash with tests/test_runner.py broke collection).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(eval): rename sweval/test_gate.py -> test_self_eval_gate.py to avoid basename clash

CI runs 'uv run pytest -q' over the whole repo with the default (prepend)
import mode, where two flat test files sharing a basename import as the same
top-level module. sweval/test_gate.py collided with deploy-core/tests/test_gate.py,
breaking collection (exit 2) for both the main pytest job and the realeval job.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* ci(security): document-ignore PYSEC-2026-2132 (unreachable click.edit)

pip-audit flags click 8.1.8 for PYSEC-2026-2132 (command injection in
click.edit(), CVSS 8.8). Forge imports click nowhere, so the vulnerable path is
unreachable, and click<8.2 is transitively pinned by the semgrep dev/CI
dependency — click>=8.3.3 cannot be resolved without dropping semgrep. Add a
justified, documented --ignore-vuln to both pip-audit invocations (VEX
'vulnerable_code_not_present'); revisit and remove once semgrep lifts the cap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Forge Swarm <quintinbotes@outlook.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
… (Phase A substrate) (#65)

* feat(self-eval): persist the per-(workspace, suite) baseline resolution rate (A2)

The Self-Eval Gate refuses a config change that regresses a workspace's private
suite below a frozen baseline. This adds where that baseline lives:

* SelfEvalBaseline model + migration 0040 — one row per (workspace, suite),
  NOT NULL workspace_id (tenant-scoped), unique(workspace_id, benchmark_suite_id),
  storing baseline_rate + resolved/total provenance + a redacted config snapshot.
  Deferred from 0001_baseline like benchmark_suite (its FK target), so the
  metadata baseline never creates it before benchmark_suite exists.
* SelfEvalService — workspace_baseline() (the gate's baseline_for lookup),
  baseline_for_suite(), and record_baseline(overwrite=) with cold-start
  establish semantics so a regressing run can never lower the bar it defends.

Storage-only: the promotion policy lives in the run/enforcement layer, and
callers pass an already-redacted config. Registered in models/__init__ +
EXPECTED_MODELS. Migration round-trips clean on the Postgres stepwise walk.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(self-eval): live agent-backed ProductionEvalRunner over the sandbox (A3)

The real EvalRunner the Self-Eval Gate blocks on, in the worker (the only layer
that may depend on both forge_agent and forge_eval, keeping forge_eval
agent-free):

* build_coder_tools — a path-safe read/write/list repo tool set for the agent.
* agent_solve — checks out a case's base_commit into a scratch worktree, runs a
  coding AgentRunner (config under test) that only sees the public query, and
  diffs the worktree into the SolveFn file-map the sandboxed runner re-applies
  before the HIDDEN tests. The agent never sees fail_to_pass/pass_to_pass.
* ProductionEvalRunner — resolves the workspace's private suite, loads its
  minted cases, and scores via run_self_eval over LocalSandboxProvider; returns
  None on any cold-start (no suite / no cases / no BYOK model) so the gate no-ops
  rather than fabricating a score.

Tested fully offline: a scripted model writes the fix, real git worktrees are
checked out from a temp repo, hidden tests run in the local sandbox, and a
correct config scores 1.0 while a still-broken one scores 0.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Forge Swarm <quintinbotes@outlook.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…un (Phase A wiring) (#66)

* feat(self-eval): enforce the Self-Eval Gate on AO config changes (A1)

The AO config-change endpoints (PUT /ao/role-config/{role}, PUT /ao/settings)
now consult the Self-Eval Gate before applying a change:

* self_eval_enforce setting (default OFF) gates the whole path — an unconfigured
  instance is never affected, and the gate is additionally a no-op on cold start
  (no baseline / no private suite).
* On a regression the change is refused with 409, the block is written to the
  tamper-evident audit log ("ao.config.self_eval_blocked"), and the mutation is
  never applied.
* ?force=true lets an admin override; the override is audited
  ("ao.config.self_eval_forced") and commits atomically with the change.
* The gate is injected via Depends(get_self_eval_gate) — real baseline lookup
  (SelfEvalService) + an eval runner. The default runner is a no-op because a
  live private-suite eval is minutes-long, agent-driven, and worker-owned
  (apps/api cannot import forge_worker without a cycle); establishing a baseline
  is the worker path (A4). The gate MECHANISM is fully wired and tested by
  injecting a runner.

Tests: regression blocked + audited + not-applied, passing allowed, force
overrides + audits, flag-off and cold-start no-op, settings endpoint gated too.
Existing AO router tests still green after the sync->async endpoint change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(self-eval): worker-driven self-eval run + baseline recording (A4)

Un-parks the internal agent-driven benchmark run for the Self-Eval Gate — as a
worker task, not an inline endpoint, since a private-suite run is minutes-long
and agent-driven:

* execute_self_eval_run — the run -> record loop: drives the (injected) live
  runner and, on a real score, persists it as the workspace baseline via an
  injected record_baseline. Returns None (records nothing) when the runner has
  nothing to score, so a failed/offline run never writes a bogus baseline.
* forge.self_eval.run Celery task — wires the real ProductionEvalRunner (A3) +
  SelfEvalService.record_baseline (A2), resolving the workspace's published
  private suite + its on-disk case dir + a local repo clone. An honest no-op
  (scored: false, with the missing-prereq reason) until an operator provisions
  FORGE_BENCHMARK_DIR + FORGE_SELF_EVAL_REPO_ROOT/<repo_id> + a BYOK model —
  the foundation ships no repo-clone manager, and nothing is faked.
* Updated the benchmarks router docstring: the parked "no EvalRunner substrate"
  rationale is gone (A3 provides it); the public F35 router stays the external
  submit/verify/rank path for shared community suites.

Tests: execute_self_eval_run records a baseline (fake + real in-memory
SelfEvalService), records nothing on a None score; the task registers under
forge.self_eval.run.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(self-eval): cover the worker task no-op path + exclude infra-gated branches

The forge_worker coverage floor (>=90%) tripped because the A4 Celery task file
was 0%-covered. Add a test exercising the honest no-op path (no provisioning env
-> scored:false) and isolate the genuinely infra-gated logic (DB suite resolve,
BYOK client, live run) into # pragma: no cover helpers that need a real repo
clone + provider to run. Worker coverage back to 91%.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Forge Swarm <quintinbotes@outlook.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* fix(self-host): make a fresh install start, sign in, and work

Closes F1-F7 from EVALUATION-FINDINGS-2026-09-17, plus three blockers found
while verifying them against a real stack.

F2 blocker - docker.io/minio/minio is no longer anonymously pullable (the
repository itself 401s), so the stack could not start. Repinned both compose
files and the build manifest to quay.io/minio/minio (arm64 + amd64 + ppc64le).

F1 blocker - a fresh install had no credential at all. The seed now mints and
prints an admin API key behind FORGE_SEED_ADMIN_KEY (dev-only, on in the dev
compose), retiring the previous one so re-running never leaves two live admin
keys. The UI gains a Connect dialog that verifies the key against /auth/me
before storing it, a session gate that names the missing credential instead of
rendering skeletons that never resolve, and a masked identity + Disconnect in
the top bar.

F3 high - all nine FORGE_*_BACKEND selectors defaulted to memory and were
forwarded by neither compose file, so dev *and production* kept API keys, board
rows, audit entries, approvals and BYOK ciphertext in the API process. Both
files now select db for every Python service, overridably.

F4 medium - the docs led to :3000, bypassing Caddy. They now lead to the edge
on :8080, the dev web service talks to the API through it, Caddy proxies the
realtime sockets, and the connection indicator names the URL it could not
reach.

F5 medium - POST /spec/specs returned "SPEC-1" and GET rejected it. The path
now accepts either the uuid or the key; SpecManifest is untouched.

F6 low - spec keys were hardcoded to SPEC-<n>. POST /spec/specs takes an
optional key, so MOD-893 can be the spec id; numbering is per-prefix so an
imported key does not shift Forge's own allocation.

F7 low - documented why browser storage on localhost is shared with every other
app on that origin; the pasted key is held per-tab unless explicitly remembered.

Found while verifying, all pre-existing:

- The CSP declared no script-src, so default-src 'self' blocked Next's inline
  self.__next_r bootstrap and hydration never ran. This, not the missing
  credential, is why every list stayed a skeleton and New task was inert. Fixed
  with a per-request nonce rather than 'unsafe-inline'.
- ForgeApiClient stored globalThis.fetch unbound and called it as a method, so
  a browser rejected every request with "Illegal invocation". jsdom does not
  enforce the receiver, so no existing test could see it.
- task.project_id is a required FK but the create path allows no project and
  the seed created none, so every task create 500'd once the board moved to db.
  The service resolves the workspace default, the seed creates a project, and a
  workspace with none returns 422.

Verified end to end on a real stack: all eight services healthy, the printed key
authenticates through Caddy and survives an API restart, and the UI drives
connect -> board -> task list with realtime Live.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* chore(deps): clear every dependency CVE and upgrade the workspace

Both audit gates were failing, and `main` had been red since 2026-07-14 — long
enough for 42 advisories to accumulate on the default branch. Neither failure
was caused by the preceding commit: it changed no dependency manifest.

Python (`pip-audit --strict` was reporting 10 vulnerabilities in 3 packages):

  cryptography 49.0.0 -> 50.0.1   PYSEC-2026-3552
  mcp          1.23.3 -> 1.29.0   PYSEC-2026-3481/3482/3483
  pip          26.1.2 -> 26.2.1   PYSEC-2026-3721
  semgrep    1.169.0 -> 1.177.0   (the cap holding mcp and click back)

Upgrading semgrep also lifts its click<8.2 pin, so click moves 8.1.8 -> 8.4.2
and PYSEC-2026-2132 resolves on its own terms. The `--ignore-vuln` both
workflows carried for it is therefore deleted rather than left to rot.

Web (`pnpm audit --audit-level=high` was reporting 37, 2 critical): next,
sharp, postcss, nanoid, brace-expansion, browserslist, js-yaml and undici all
resolve within their declared ranges.

Then, as asked, everything else: `uv lock --upgrade` across the workspace and
`pnpm update -r`. Notable moves are starlette 1.3.1 -> 1.6.0, sqlalchemy
2.0.51 -> 2.0.54, websockets 15 -> 16, torch 2.12 -> 2.14, next 16.2 -> 16.3
and react 19.2 -> 19.3. No major-version jumps: eslint stays on 9, which
eslint-config-next@16 still requires (the cap package.json documents).

Also fixes a flaky test this upgrade run exposed, in the previous commit's own
suite. `test_the_default_is_the_oldest_project` inserted two projects in one
transaction, so they shared a `created_at` and the `(created_at, id)` ordering
fell through to a random uuid4 — it passed about half the time. The fixture now
sets explicit, minute-apart timestamps so "oldest" is well defined.

Verified: `pip-audit --strict` and `pnpm audit --audit-level=high` both report
no known vulnerabilities; 4310 Python and 790 web tests pass; ruff, mypy and
tsc clean; `pnpm -r build` succeeds. The 11 remaining Python failures are
byte-identical on `main` with the same upgraded lock (diffed), and the upgrade
in fact *fixes* the two OpenTelemetry span-redaction failures.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* chore(ci): keep the click ignore for now (token lacks workflow scope)

The previous commit removed `--ignore-vuln PYSEC-2026-2132` from both audit
jobs, since upgrading semgrep lifts its click<8.2 cap and click 8.4.2 resolves
the advisory on its own terms. Pushing a workflow change needs the `workflow`
OAuth scope, which this token does not have, so the flag is restored here.

It is now a no-op — pip-audit reports no known vulnerabilities with or without
it — so this costs nothing but a stale line. Remove it in a follow-up with a
`workflow`-scoped token (`gh auth refresh -s workflow`).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* style: reformat a README code block for ruff 0.16

`ruff format` gained stricter handling of Python code blocks inside markdown
between 0.15 and 0.16, and the dependency upgrade moved ruff 0.15.21 -> 0.16.8.
CI runs `ruff format --check .` over the whole repo, so this previously-passing
file started failing the gate. Reformatting is the whole change; no prose moved.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(security): record W-007 — the seed prints its bootstrap key

CodeQL raises py/clear-text-logging-sensitive-data on seed.py:108. It is a true
positive: the freshly minted admin key is written to stdout, which on the
compose stack is the seed container's log.

It is also the intended behaviour, and there is no design that avoids it. Only
the token's HMAC is stored, so the plaintext is unrecoverable after minting — a
one-time bootstrap credential is shown once or it is lost. Writing it to a file
instead would trade this finding for py/clear-text-storage-sensitive-data
without reducing the exposure, since the file would have to live on a shared
volume to be readable at all.

The exposure is bounded instead: the print is gated behind FORGE_SEED_ADMIN_KEY,
which is unset by default and set only by the dev compose, so a production seed
emits nothing unless an operator explicitly opts in. The output states the key
is local-development only, the self-hosting quickstart tells operators to revoke
it once per-person keys exist, and re-running the seed retires the previous key
so at most one is ever live.

Recorded as a dated, owned, expiring waiver per the HARD-09 convention and
dismissed on GitHub with the same justification. It expires 2027-03-17, and the
right time to revisit is when OIDC lands and this stops being the only way in.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…#100)

`compose up --wait` counts a one-shot service that has exited as a failed
service, even when it exited 0. The dev stack has two — `migrate` and `seed` —
so waiting on the whole project returned non-zero and `make dev` ended in
`make: *** [dev-up] Error 1` with every service healthy and the admin key
printed. A first run therefore looked like it had failed when it had not.

Start everything first (so the one-shots still run), then wait for health on
the long-running services by name. The health gate is unchanged; only the set
of services it is asserted over is.

Verified from an empty machine — `down -v` then `make dev` — exit 0, all eight
services healthy, and the seeded key authenticates through the edge.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Bumps the python-minor-patch group with 1 update in the / directory: [temporalio](https://github.com/temporalio/sdk-python).


Updates `temporalio` from 1.30.0 to 1.32.0
- [Release notes](https://github.com/temporalio/sdk-python/releases)
- [Changelog](https://github.com/temporalio/sdk-python/blob/main/CHANGELOG.md)
- [Commits](temporalio/sdk-python@1.30.0...1.32.0)

---
updated-dependencies:
- dependency-name: temporalio
  dependency-version: 1.32.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: python-minor-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* fix(api): answer instead of 500 on an omitted project and a bad manifest

Closes #102, closes #103. Both are the same shape — a request the server can
reason about arriving as an unhandled exception, so the caller gets a bare 500
and the reason exists only in the container log.

**#102 — omitted `project_id`.** `project_id` is optional on the DTO and NOT
NULL on the column for *every* project-scoped entity, so omitting it produced a
NotNullViolation. This was latent while the board ran in memory, where nothing
enforces the FK; selecting the durable backend made it reachable.

The earlier fix resolved the workspace default for tasks only, which left epics,
sprints, milestones and incidents — eight call sites across their create and
update paths — still failing. `POST /board/epics` with just a title is close to
the first write anyone makes over the API, so that is the one that got reported.

There is now a single `_resolve_project_id` used by all five entities: the
supplied id when there is one, else the workspace's oldest project, else
`NoProjectError` → 422 naming the cause. The task path was rewritten to call it
too, so there is one rule rather than two implementations that can drift.

**#103 — a manifest that fails validation.** Both spec write endpoints take a
whole document as a string, so a caller's first attempt often fails validation;
returning nothing they can act on makes the endpoint unusable without server
access. `_spec_errors` now maps `ValidationError` to 422 carrying pydantic's own
error list (the same shape FastAPI returns for a bad body, so a client parses
one format either way), `SpecParseError` to 422 with its source line, and
`yaml.YAMLError` to 422. `SpecKeyError` is caught ahead of these on purpose: it
subclasses `ValueError`, and "that key is taken" is a conflict, not a parse
failure.

Both verified against a running stack with the reporters' exact reproductions:
`POST /board/epics -d '{"title":"probe"}'` → 201 attached to the demo project
(sprints and milestones and incidents likewise), and the `constraints`-as-objects
manifest → 422 naming `constraints[0]`. The new board tests were confirmed to
fail (8 of them) with the fix reverted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix: close the remaining reported issues (#104-#110)

**#110 — specs were stored on the container's writable layer (data loss).**
`spec_root` defaults to the relative path `specs`, and no service mounted a
volume over it, so every spec died with the container. Worse, the key allocator
derives the next ordinal from what is on disk: an emptied store restarts at
`SPEC-1` and hands back a key already in use, and writing it folded the new spec
into the existing one as another version. A create silently became an update.

The reporter attributed this to `spec_document`. That table is indeed dead —
nothing constructs a `SpecDocument` — but it is not what reissued the key, and
populating it would not have stopped the loss.

Both compose files now mount a shared `forge-specs` volume into api, worker and
mcp-gateway with `FORGE_SPEC_ROOT` pointing at it — which also fixes the worker
being unable to see a spec the API wrote, each container having had its own
copy. The images create that directory owned by `forge` first, because a volume
mounted onto a path absent from the image is created root-owned and these
containers run non-root. `spec_create` now validates the key it is about to use
whether allocated or supplied, so a collision is refused rather than merged.

**#104 — no way to list projects.** `project_id` is required to create an epic,
a sprint or a milestone, and the only way to obtain one was reading the
`project` table. `GET /projects` returns the caller's workspace projects,
filtered through the same resolver a single-project read uses so a listing never
leaks a project whose direct read 404s.

**#105 — the manifest could not round-trip.** GET returns `text/plain` YAML;
PUT accepted only `{"content": "..."}`, so piping one into the other failed with
a 422 about a dictionary. Both write endpoints now take the document as a raw
body, keeping the JSON wrapper for clients that prefer it.

**#106 — docs described a status the engine never sets.** `clarifying` comes
only from an explicit `POST /clarify`; open questions do not move a spec there.
The guide said otherwise, which made a correct gate refusal look like a bug.

**#108 — generated acceptance criteria restated their requirement.**
"Implementation satisfies R1: <R1 verbatim>" cannot fail, and a dashboard
counting 7/7 present reported the spec as well specified. None are generated
now; the traceability projection already flags the gap, and an empty list the
author must fill is the honest state. The traceability tests that used these as
fixture data now carry criteria an author would actually write.

**#109 — the planner asserted an architectural decision nobody took.** The
placeholder ADR carried `status: accepted` over three fields recording nothing,
so an auditor would read the architecture as settled — most misleading exactly
when the real questions sit unanswered in `open_questions`. It is `proposed`
now, with fields naming what is missing.

Verified against a running stack and covered by tests that were checked to fail
without each fix.

Closes #104, closes #105, closes #106, closes #108, closes #109, closes #110.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs: the spec store is a fourth backup target, and update the spec workflow

The spec-store fix (#110) introduced a new stateful volume, and a volume absent
from the backup procedure is the same data-loss trap in slower motion. Worse,
`backup.md` already claimed specs were in Postgres — "Relational data … Boards,
specs, runs" — which was never true: Postgres holds the version history in
`spec_version`, while the live document every read and the implementation gate
go through is a file.

So `backup.sh` now copies the spec documents out of the volume, `restore.sh`
puts them back, and the docs name it as a fourth store alongside Postgres,
MinIO and the secrets. A database-only restore brings back every spec's history
while every live spec 404s — and the key allocator, which reads the documents,
starts over at SPEC-1 and reissues keys already in use. The restore guide's
verification step now checks a known spec reads back through the API rather than
merely existing on disk.

Also documents this release's behaviour changes where an author meets them:

- `acceptance_criteria` starts empty and is the author's to write, with the
  reason it is no longer generated (a criterion that restates its requirement
  cannot fail, and counting it as present overstates the spec).
- The manifest round-trip — `GET` to a file, edit, `PUT` it straight back — now
  that raw bodies are accepted, plus `GET /projects`, since needing a
  `project_id` with no way to list one was the first wall a new API user hit.
- `FORGE_SPEC_ROOT` in `.env.example`, saying what goes wrong when it is left
  on its relative default.

Verified end to end: a spec created through the API survived a full container
recreate, the worker read the same store, and `backup.sh` produced an archive
containing its manifest.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* feat(spec): give constraints citable ids, keeping bare strings valid

Closes #107.

`constraints` was the one collection in `SpecManifest` shaped as bare strings
while every sibling — requirements, acceptance criteria, open questions,
decisions — is an identified object. Constraints are exactly what you want to
cite: an ADR recording "rejected because it violates C2", or a criterion
carrying `constraint_refs`, has nothing to point at when a constraint is only
its own text.

`SpecManifest` is also the on-disk YAML schema, so a hard change would have
invalidated every manifest already written and every `spec_version` row — the
same silent-data-loss shape as the bugs this release is fixing. Instead a bare
string is coerced to `{id: "C<n>", text: ...}` at its position, so:

- old `manifest.yaml` files load unchanged,
- old `spec.md` files parse unchanged (`- <text>` as well as `- **C1**: text`),
- mixed lists work, which is what a hand-edited manifest looks like,
- new writes emit the object form, and an explicit id round-trips.

Two things worth noting for a reader:

`diff_manifest` compares constraints by **text**, not id. Ids are positional for
any manifest still written as bare strings, so removing the first constraint
renumbers the rest — an id-based diff would report every later constraint as
changed. Diffing text keeps the output identical to its pre-id behaviour.

The Spec Studio editor and YAML validator accept both shapes; editing an
identified constraint preserves its id, so anything citing it still resolves.
`tsc` caught six render sites that had assumed a string, which are now routed
through a shared helper rather than per-file casts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…om non-goals (#114)

Closes #112, closes #113. Both are the same failure: Forge emitting an artefact
that looks like the work happened.

**#112 — a run reported `succeeded` having done nothing.** With no provider
configured the API substituted the offline `ScriptedModelClient`, whose every
objective "finishes cleanly", and attached `confidence: 0.9` to the canned
string. Downstream nothing could tell that run apart from one that did the work:
the board moved, the task closed, the trace showed two clean steps.

A run that cannot reach a model has not succeeded. It is now refused with 503,
naming what is missing — including that the dev stack reads deploy/.env.dev and
not the repo-root .env, which is the likely path into this state after following
the getting-started guide. The offline client is still available but only behind
an explicit FORGE_ALLOW_SCRIPTED_AGENT, so it can never be reached by accident;
it states plainly that no model was called, and claims no confidence. The
counterfactual-fork path carried the same `confidence=0.9` on a canned answer
and is fixed with it.

The dev stack also passed no model variables at all, so it could never run an
agent whatever you set. They are passed through now, and `make dev` says so at
startup rather than leaving a fully-healthy stack to fail on first use.

**#113 — task generation mechanically wrapped every requirement.** A requirement
phrased as a scope exclusion came back as a task marked `ready_for_agent`,
instructing an agent to do the thing the spec ruled out — in the reported case a
schema migration the spec said needed sizing against a live table first.

`non_goals` is now a first-class manifest field and generation iterates
`requirements` only, so an exclusion cannot become a work item.

Two further defects in the same output:

- Titles were the requirement's full text, so every board row was a paragraph.
  A title is now the first sentence, truncated on a word boundary; the full text
  is still the description.
- Generated tasks had no epic and no project. The cause was upstream:
  `SpecManifest` never stored `epic_id` — `spec_create` took it and dropped it —
  so the link was lost before generation ran. The manifest carries it now and
  tasks inherit it.

Both new fields are optional and round-trip through spec.md and manifest.yaml,
so manifests written before this keep loading.

The new tests were checked against the old behaviour: 3 of the 4 agent tests
fail with the refusal removed.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…, trust-layer completion (#72)

* docs(plan): audit remediation implementation plan

* docs(plan): keep FORGE_RERANK_MODEL — live via pydantic FORGE_ prefix

* fix(config): document real FORGE_MODEL_* env vars and warn on scripted-client fallback

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

* docs: fix stale feature status, secret var name, package maps, compose tables

* docs(web): align notImplemented docstring with implemented-routes reality

* docs(release): regenerate changelog and readiness snapshot at current HEAD

* docs(plan): correct G-ATTEST expectation — production-bar-only gate

* docs: document trust layer, realtime co-editing, and adaptive orchestration

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

* docs(plan): Task 21 — no /ao/self-eval/runs endpoint exists; prefer thin trigger endpoint

* feat(deploy): add nginx reverse-proxy config and reverse-proxy doc

* fix(deploy): nginx body-size and websocket-upgrade parity with Caddy

* docs(spec): realign FORGE_SPEC with shipped reality

* docs(spec): correct F32/F33 shipping attributions in roadmap

* ci(web): run vitest suite and tsc typecheck on every PR

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

* ci(types): bring deploy-core, auth-sdk, marketplace-sdk, observability under mypy

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

* test(infra): guard against test-basename collisions (importlib evaluated, reverted)

--import-mode=importlib breaks whole-repo collection (exit 2, 51 errors):
importlib mode does not put each test dir on sys.path, so bare sibling
imports fail (41x conftest, _provider_fakes, _sandbox_fakes, mcp_fakes,
cost_support, helm_chart_lib, _helpers, _mp_helpers). Guard test ships
with prepend-mode semantics matching CI. Full importlib migration needs
repackaging ~50 sibling-helper imports first.

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

* chore(ci): remove dead ui-kit excludes, orphaned board_v1 dir, wire release draft input

* test(db): gate model/migration schema drift via autogenerate compare

Add packages/db/tests/test_schema_drift.py: upgrade a fresh Postgres to
head and assert alembic.autogenerate.compare_metadata() returns an empty
diff against Base.metadata, using the exact autogenerate settings env.py
configures (compare_type=True; compare_server_default unset; no
include_object). Mirrors test_migration.py's @pytest.mark.postgres
fixture/skip conventions (scratch throwaway DB, FORGE_TEST_DATABASE_URL).
A second sanity test proves the comparison is drift-sensitive by diffing
against an empty MetaData().

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

* fix(db): align model with migrations and scope drift-gate exclusions

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

* test(db): unit-test drift-gate exclusion filter without postgres

* fix(helm): wire real FORGE_MODEL_* env contract, drop dead MinIO knobs

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

* fix(helm): render-contract test, blank-key install warning, provider enum

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

* fix(deploy): mcp-gateway edge network membership and websocket route parity

Item 1 (websocket routing through Caddy) — INVESTIGATED, real gap, fixed.
Outcome: the web client opens a BARE /ws (never /api/ws). The WS URL is built
purely from NEXT_PUBLIC_WS_URL (default ws://localhost:8000/ws) with no /api
prefix and no same-origin/window.location derivation
(apps/web/src/lib/realtime/use-board-realtime.ts:55-56,
use-spec-collab.ts:133-136); the API mounts them rootless
(apps/api/forge_api/main.py:138-140 -> routers/realtime.py:75,109). NEXT_PUBLIC_WS_URL
is set in no compose/env/Dockerfile/doc, so a same-origin operator value is
wss://<domain>/ws. The pre-fix Caddyfile had no /ws route, so bare /ws fell
through to the web:3000 catch-all -> realtime silently dead behind Caddy. Added
`handle /ws` + `handle /ws/spec/*` -> api:8000, mirroring deploy/nginx/forge.conf;
documented the canonical route + NEXT_PUBLIC_WS_URL contract in
docs/self-hosting/reverse-proxy.md.

Item 2 (mcp-gateway unreachable via proxies) — verified, fixed. mcp-gateway was
on [backend, mcp] while caddy is on [edge] only: no shared network, so /mcp/*
would 502. Added `edge` to mcp-gateway (now [edge, backend, mcp]; mcp/backend
preserved). docker-compose.dev.yml has no networks block (single default net),
so no gap there. `docker compose config -q` passes for both files; deploy/tests
green (103 passed, 2 pre-existing skips), incl. two new regression tests.

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

* fix(deploy): assert ws proxy upstream in tests; document proxied github webhook url

* fix(web): derive same-origin websocket url when NEXT_PUBLIC_WS_URL unset

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

* fix(web): resolve api base url same-origin when NEXT_PUBLIC_API_URL is unset or relative

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

* feat(slack): wire /forge status to live run lookup

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

* test(slack): real cross-tenant coverage and threat-model residual for slash surfaces

* refactor(api): retire legacy in-memory /approval router in favor of DB-backed /approvals

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

* docs(api): state dead-writer status in relocated ApprovalStore docstring

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

* fix(worker): register deployment tasks with celery

The deployment task module defined `forge.deployments.advance` and
`forge.deployments.request` but was absent from `celery_app`'s `include`
list, so nothing imported it at worker boot — the tasks were unregistered
dead code. Add `forge_worker.tasks.deployments` to `include`.

Decision rule (kept the sync path — no enqueue wired): `forge.deployments.request`
merely duplicates what `DeploymentService.request_deployment` already does
synchronously in-process (create + `DeploymentOrchestrator.advance()`). Evidence
of no surfaced retry/backoff benefit: no `.delay`/`.apply_async` call-site for
these tasks anywhere, no beat-schedule entry references them, and no code
references the task-name constants outside the task module. So we register +
test the tasks so they drive `DeploymentOrchestrator.advance()` correctly when
invoked, and leave the synchronous API path untouched.

TDD: RED — the module was not in `celery_app.conf.include`, so the tasks did
not resolve via the worker's boot path (`loader.import_default_modules()`).
GREEN after registration. Added behaviour tests that invoking
`request_deployment_task` / `advance_deployment` drives
`DeploymentOrchestrator.advance()` on the target deployment.

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

* fix(web): mark SAML single logout as not yet supported in SSO settings

* fix(web): separate slo helper from label for clean name/description a11y

* feat(spec): persist reject and request-changes review decisions end-to-end

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

* fix(web): clear stale review error when a sibling review mutation fires

* feat(worker): dispatch supervised multi-agent runs through forge_coordinator

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

* docs(config): document MULTI_AGENT_ENABLED gate in .env.example

* feat(pm): wire webhook intake to board-write sync task

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

* fix(pm): real retry semantics for sync task and honest failure docs

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

* fix(pm): classify httpx transport faults as transient for sync retries

* feat(attest): expose attested changesets over REST with approvals UI panel

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

* feat(red-team): trigger endpoint and V1 worker gate parity

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

* fix(red-team): state spine persistence asymmetry honestly; loud mint guards

* feat(self-eval): settings panel for suite, baseline, runs, and gate status

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

* fix(web): attempt-language for self-eval run-accepted message

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

* fix(deploy): pass model-provider and multi-agent env contract into containers

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

* docs(release): re-pin readiness snapshot at branch tip

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

* fix(self-host): make a fresh install start, sign in, and work

Closes F1-F7 from EVALUATION-FINDINGS-2026-09-17, plus three blockers found
while verifying them against a real stack.

F2 blocker - docker.io/minio/minio is no longer anonymously pullable (the
repository itself 401s), so the stack could not start. Repinned both compose
files and the build manifest to quay.io/minio/minio (arm64 + amd64 + ppc64le).

F1 blocker - a fresh install had no credential at all. The seed now mints and
prints an admin API key behind FORGE_SEED_ADMIN_KEY (dev-only, on in the dev
compose), retiring the previous one so re-running never leaves two live admin
keys. The UI gains a Connect dialog that verifies the key against /auth/me
before storing it, a session gate that names the missing credential instead of
rendering skeletons that never resolve, and a masked identity + Disconnect in
the top bar.

F3 high - all nine FORGE_*_BACKEND selectors defaulted to memory and were
forwarded by neither compose file, so dev *and production* kept API keys, board
rows, audit entries, approvals and BYOK ciphertext in the API process. Both
files now select db for every Python service, overridably.

F4 medium - the docs led to :3000, bypassing Caddy. They now lead to the edge
on :8080, the dev web service talks to the API through it, Caddy proxies the
realtime sockets, and the connection indicator names the URL it could not
reach.

F5 medium - POST /spec/specs returned "SPEC-1" and GET rejected it. The path
now accepts either the uuid or the key; SpecManifest is untouched.

F6 low - spec keys were hardcoded to SPEC-<n>. POST /spec/specs takes an
optional key, so MOD-893 can be the spec id; numbering is per-prefix so an
imported key does not shift Forge's own allocation.

F7 low - documented why browser storage on localhost is shared with every other
app on that origin; the pasted key is held per-tab unless explicitly remembered.

Found while verifying, all pre-existing:

- The CSP declared no script-src, so default-src 'self' blocked Next's inline
  self.__next_r bootstrap and hydration never ran. This, not the missing
  credential, is why every list stayed a skeleton and New task was inert. Fixed
  with a per-request nonce rather than 'unsafe-inline'.
- ForgeApiClient stored globalThis.fetch unbound and called it as a method, so
  a browser rejected every request with "Illegal invocation". jsdom does not
  enforce the receiver, so no existing test could see it.
- task.project_id is a required FK but the create path allows no project and
  the seed created none, so every task create 500'd once the board moved to db.
  The service resolves the workspace default, the seed creates a project, and a
  workspace with none returns 422.

Verified end to end on a real stack: all eight services healthy, the printed key
authenticates through Caddy and survives an API restart, and the UI drives
connect -> board -> task list with realtime Live.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* chore(deps): clear every dependency CVE and upgrade the workspace

Both audit gates were failing, and `main` had been red since 2026-07-14 — long
enough for 42 advisories to accumulate on the default branch. Neither failure
was caused by the preceding commit: it changed no dependency manifest.

Python (`pip-audit --strict` was reporting 10 vulnerabilities in 3 packages):

  cryptography 49.0.0 -> 50.0.1   PYSEC-2026-3552
  mcp          1.23.3 -> 1.29.0   PYSEC-2026-3481/3482/3483
  pip          26.1.2 -> 26.2.1   PYSEC-2026-3721
  semgrep    1.169.0 -> 1.177.0   (the cap holding mcp and click back)

Upgrading semgrep also lifts its click<8.2 pin, so click moves 8.1.8 -> 8.4.2
and PYSEC-2026-2132 resolves on its own terms. The `--ignore-vuln` both
workflows carried for it is therefore deleted rather than left to rot.

Web (`pnpm audit --audit-level=high` was reporting 37, 2 critical): next,
sharp, postcss, nanoid, brace-expansion, browserslist, js-yaml and undici all
resolve within their declared ranges.

Then, as asked, everything else: `uv lock --upgrade` across the workspace and
`pnpm update -r`. Notable moves are starlette 1.3.1 -> 1.6.0, sqlalchemy
2.0.51 -> 2.0.54, websockets 15 -> 16, torch 2.12 -> 2.14, next 16.2 -> 16.3
and react 19.2 -> 19.3. No major-version jumps: eslint stays on 9, which
eslint-config-next@16 still requires (the cap package.json documents).

Also fixes a flaky test this upgrade run exposed, in the previous commit's own
suite. `test_the_default_is_the_oldest_project` inserted two projects in one
transaction, so they shared a `created_at` and the `(created_at, id)` ordering
fell through to a random uuid4 — it passed about half the time. The fixture now
sets explicit, minute-apart timestamps so "oldest" is well defined.

Verified: `pip-audit --strict` and `pnpm audit --audit-level=high` both report
no known vulnerabilities; 4310 Python and 790 web tests pass; ruff, mypy and
tsc clean; `pnpm -r build` succeeds. The 11 remaining Python failures are
byte-identical on `main` with the same upgraded lock (diffed), and the upgrade
in fact *fixes* the two OpenTelemetry span-redaction failures.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* chore(ci): keep the click ignore for now (token lacks workflow scope)

The previous commit removed `--ignore-vuln PYSEC-2026-2132` from both audit
jobs, since upgrading semgrep lifts its click<8.2 cap and click 8.4.2 resolves
the advisory on its own terms. Pushing a workflow change needs the `workflow`
OAuth scope, which this token does not have, so the flag is restored here.

It is now a no-op — pip-audit reports no known vulnerabilities with or without
it — so this costs nothing but a stale line. Remove it in a follow-up with a
`workflow`-scoped token (`gh auth refresh -s workflow`).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* style: reformat a README code block for ruff 0.16

`ruff format` gained stricter handling of Python code blocks inside markdown
between 0.15 and 0.16, and the dependency upgrade moved ruff 0.15.21 -> 0.16.8.
CI runs `ruff format --check .` over the whole repo, so this previously-passing
file started failing the gate. Reformatting is the whole change; no prose moved.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(security): record W-007 — the seed prints its bootstrap key

CodeQL raises py/clear-text-logging-sensitive-data on seed.py:108. It is a true
positive: the freshly minted admin key is written to stdout, which on the
compose stack is the seed container's log.

It is also the intended behaviour, and there is no design that avoids it. Only
the token's HMAC is stored, so the plaintext is unrecoverable after minting — a
one-time bootstrap credential is shown once or it is lost. Writing it to a file
instead would trade this finding for py/clear-text-storage-sensitive-data
without reducing the exposure, since the file would have to live on a shared
volume to be readable at all.

The exposure is bounded instead: the print is gated behind FORGE_SEED_ADMIN_KEY,
which is unset by default and set only by the dev compose, so a production seed
emits nothing unless an operator explicitly opts in. The output states the key
is local-development only, the self-hosting quickstart tells operators to revoke
it once per-person keys exist, and re-running the seed retires the previous key
so at most one is ever live.

Recorded as a dated, owned, expiring waiver per the HARD-09 convention and
dismissed on GitHub with the same justification. It expires 2027-03-17, and the
right time to revisit is when OIDC lands and this stops being the only way in.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* ci: give the python job a Redis service

Several tests on this branch talk to a real Redis rather than a fake — the
supervised multi-agent dispatch tests and the MCP token bucket among them — and
the job declared Postgres but never a broker. They failed with ECONNREFUSED
rather than skipping, which is why `python (lint + types + tests)` was red while
the same tests pass locally against a running Redis.

Also drops `--ignore-vuln PYSEC-2026-2132` from both audit jobs. Upgrading
semgrep lifted its click<8.2 cap, so click resolves to 8.4.2 and the advisory no
longer applies; pip-audit passes on its own terms, and a waiver nobody needs is
one more thing to mislead a reader later.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix: deduplicate the yaml-schema constants left by the main merge

My earlier merge of main into this branch resolved `yaml-schema.ts` by
concatenating both sides of the conflict. Both sides declared
`STRING_ARRAY_FIELDS` and `NULLABLE_STRING_FIELDS`, so the result declared each
twice — which failed `tsc`, failed the Turbopack production build, and so failed
three CI jobs (`web`, `build`, and `python` on an unrelated format check).

Resolved properly this time: one declaration each, carrying both intents.
`constraints` is out of `STRING_ARRAY_FIELDS` because it is no longer a plain
string list (it has its own dual-shape check since #107), and `review_note` is
in `NULLABLE_STRING_FIELDS` because this branch adds it.

A mechanical union is the right resolution when each side only adds new lines;
it is the wrong one when both sides edit the same declaration, and I should have
read this hunk rather than applying the same rule to all four conflicts.

Verified locally: `tsc` clean, `pnpm -r build` succeeds, 852 web tests pass,
ruff check and format clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(compose): deduplicate the model-provider env block

The same merge mistake as the yaml-schema constants: this branch and #114 both
added the BYOK model-provider passthrough to the shared dev env anchor, and my
union resolution kept both copies. A duplicate mapping key is a hard YAML parse
error, so `docker compose config` failed outright:

    line 87: mapping key "FORGE_MODEL_PROVIDER" already defined at line 70

One block now, keeping the detail from both comments: why the passthrough is
needed at all (this env map has no env_file, so a value only arrives via an
explicit ${VAR}, and the stack does not read the repo-root .env), and what
happens when it is unset (agent runs are refused rather than faked).

Also swept the rest of the merge for the same fault — duplicate mapping keys in
both compose files, duplicate top-level declarations in the TypeScript files,
duplicate keys in .env.example and the compose doc. None remained.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Forge Swarm <quintinbotes@outlook.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…th 8 updates (#93)

Bumps the actions-minor-patch group with 8 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `7.0.0` | `7.0.1` |
| [pnpm/action-setup](https://github.com/pnpm/action-setup) | `6.0.9` | `6.1.0` |
| [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) | `4.37.0` | `4.38.0` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `4.2.0` | `4.4.0` |
| [github/codeql-action/init](https://github.com/github/codeql-action) | `4.37.0` | `4.38.0` |
| [github/codeql-action/analyze](https://github.com/github/codeql-action) | `4.37.0` | `4.38.0` |
| [helm/kind-action](https://github.com/helm/kind-action) | `1.14.0` | `1.15.0` |
| [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) | `4.1.1` | `4.2.2` |



Updates `actions/checkout` from 7.0.0 to 7.0.1
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@9c091bb...3d3c42e)

Updates `pnpm/action-setup` from 6.0.9 to 6.1.0
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](pnpm/action-setup@0ebf471...ea17c68)

Updates `github/codeql-action/upload-sarif` from 4.37.0 to 4.38.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@99df26d...b96794f)

Updates `docker/setup-buildx-action` from 4.2.0 to 4.4.0
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](docker/setup-buildx-action@bb05f3f...594f3bf)

Updates `github/codeql-action/init` from 4.37.0 to 4.38.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@99df26d...b96794f)

Updates `github/codeql-action/analyze` from 4.37.0 to 4.38.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@99df26d...b96794f)

Updates `helm/kind-action` from 1.14.0 to 1.15.0
- [Release notes](https://github.com/helm/kind-action/releases)
- [Commits](helm/kind-action@ef37e7f...06c1ae1)

Updates `actions/attest-build-provenance` from 4.1.1 to 4.2.2
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](actions/attest-build-provenance@0f67c3f...4d10147)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-version: 4.2.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-minor-patch
- dependency-name: actions/checkout
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-minor-patch
- dependency-name: docker/setup-buildx-action
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-minor-patch
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-minor-patch
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-minor-patch
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-minor-patch
- dependency-name: helm/kind-action
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-minor-patch
- dependency-name: pnpm/action-setup
  dependency-version: 6.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-minor-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.4.0 to 7.0.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](actions/setup-node@48b55a0...8207627)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…115)

`make dev` was broken on main. The API exited at import with:

    ValidationError: 1 validation error for Settings
    allow_scripted_agent
      Input should be a valid boolean, unable to interpret input
      [type=bool_parsing, input_value='', input_type=str]

My own fault, from #114. Compose writes `VAR: ${VAR:-}` to make a variable
optional, and an unset one then arrives as `""` rather than being absent. That
is harmless for a string field and intended, but for a bool it is a hard
ValidationError raised at import time — so one line took the whole stack down
with every other service healthy.

Two changes, because the immediate fix alone leaves the trap set:

- `FORGE_ALLOW_SCRIPTED_AGENT` defaults to `false` in the dev compose, matching
  how `MULTI_AGENT_ENABLED` and the other booleans there are already written.
- `Settings` now drops an empty value for any non-string field before
  validation, so it falls back to that field's default. An empty value means the
  operator expressed no preference, and the same trap is one `${VAR:-}` or one
  blanked line in `.env` away for the seven other bool settings.

Verified: `make dev` exits 0 from a clean slate, all eight services healthy, the
seeded key authenticates, and an agent run with no provider returns the 503 from
#112 rather than a fake success. The new tests were checked against the old
behaviour — 4 of 6 fail with the guard removed.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Bumps the python-minor-patch group with 1 update: [temporalio](https://github.com/temporalio/sdk-python).


Updates `temporalio` from 1.32.0 to 1.33.0
- [Release notes](https://github.com/temporalio/sdk-python/releases)
- [Changelog](https://github.com/temporalio/sdk-python/blob/main/CHANGELOG.md)
- [Commits](temporalio/sdk-python@1.32.0...1.33.0)

---
updated-dependencies:
- dependency-name: temporalio
  dependency-version: 1.33.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: python-minor-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
….5 (#122)

Updates the requirements on [psycopg[binary]](https://github.com/psycopg/psycopg) to permit the latest version.
- [Changelog](https://github.com/psycopg/psycopg/blob/master/docs/news.rst)
- [Commits](psycopg/psycopg@3.3.4...3.3.5)

---
updated-dependencies:
- dependency-name: psycopg[binary]
  dependency-version: 3.3.5
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [uvicorn[standard]](https://github.com/Kludex/uvicorn) to permit the latest version.
- [Release notes](https://github.com/Kludex/uvicorn/releases)
- [Changelog](https://github.com/Kludex/uvicorn/blob/main/docs/release-notes.md)
- [Commits](Kludex/uvicorn@0.51.0...0.53.0)

---
updated-dependencies:
- dependency-name: uvicorn[standard]
  dependency-version: 0.53.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 8.3.2 to 10.1.0.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](astral-sh/setup-uv@11f9893...bec219d)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: 10.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [@testing-library/jest-dom](https://github.com/testing-library/jest-dom) from 6.9.1 to 7.0.1.
- [Release notes](https://github.com/testing-library/jest-dom/releases)
- [Changelog](https://github.com/testing-library/jest-dom/blob/main/CHANGELOG.md)
- [Commits](testing-library/jest-dom@v6.9.1...v7.0.1)

---
updated-dependencies:
- dependency-name: "@testing-library/jest-dom"
  dependency-version: 7.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [jsdom](https://github.com/jsdom/jsdom) from 29.1.1 to 30.0.1.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Commits](jsdom/jsdom@v29.1.1...v30.0.1)

---
updated-dependencies:
- dependency-name: jsdom
  dependency-version: 30.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [@tanstack/react-table](https://github.com/TanStack/table/tree/HEAD/packages/react-table) from 8.21.3 to 9.2.4.
- [Release notes](https://github.com/TanStack/table/releases)
- [Changelog](https://github.com/TanStack/table/blob/main/packages/react-table/CHANGELOG.md)
- [Commits](https://github.com/TanStack/table/commits/@tanstack/react-table@9.2.4/packages/react-table)

---
updated-dependencies:
- dependency-name: "@tanstack/react-table"
  dependency-version: 9.2.4
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
`pnpm install --frozen-lockfile` failed on main:

    This issue is probably caused by a badly resolved merge conflict.

Seven Dependabot PRs merged in sequence, six of them touching pnpm-lock.yaml.
Each was mergeable against main as it stood when GitHub computed it, but
squash-merging them one after another left the lockfile three lines out of step
with package.json. CI installs with --frozen-lockfile, so every web job on main
would have failed at the install step, before running a single test.

Regenerating is the whole change: 3 insertions, 3 deletions.

Verified afterwards, because five of those seven were major bumps (jsdom 29->30,
vitest's peer set, @testing-library/jest-dom 6->7, @tanstack/react-table 8->9,
astral-sh/setup-uv 8->10): tsc clean, 852 web tests pass, `pnpm -r build`
succeeds, eslint at its usual 15 warnings and 0 errors, and 4636 Python tests
pass with no new failures against the last known-good baseline.

Worth noting the green CI on each individual PR did not catch this — the
inconsistency only exists once they are combined.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.1.11 to 5.0.1.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v5.0.1/packages/vitest)

---
updated-dependencies:
- dependency-name: vitest
  dependency-version: 5.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…0 updates

Bumps the npm-minor-patch group with 10 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [prettier](https://github.com/prettier/prettier) | `3.9.7` | `3.9.9` |
| [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) | `5.103.1` | `5.104.0` |
| [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) | `1.47.0` | `1.49.0` |
| [next](https://github.com/vercel/next.js) | `16.3.5` | `16.3.8` |
| [yjs](https://github.com/yjs/yjs) | `13.6.32` | `13.6.33` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `26.6.1` | `26.6.3` |
| [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) | `16.3.5` | `16.3.8` |
| [jsdom](https://github.com/jsdom/jsdom) | `30.0.1` | `30.1.1` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `8.3.0` | `8.3.1` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `5.0.1` | `5.0.3` |



Updates `prettier` from 3.9.7 to 3.9.9
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](prettier/prettier@3.9.7...3.9.9)

Updates `@tanstack/react-query` from 5.103.1 to 5.104.0
- [Release notes](https://github.com/TanStack/query/releases)
- [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md)
- [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.104.0/packages/react-query)

Updates `lucide-react` from 1.47.0 to 1.49.0
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.49.0/packages/lucide-react)

Updates `next` from 16.3.5 to 16.3.8
- [Release notes](https://github.com/vercel/next.js/releases)
- [Commits](vercel/next.js@v16.3.5...v16.3.8)

Updates `yjs` from 13.6.32 to 13.6.33
- [Release notes](https://github.com/yjs/yjs/releases)
- [Commits](yjs/yjs@v13.6.32...v13.6.33)

Updates `@types/node` from 26.6.1 to 26.6.3
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `eslint-config-next` from 16.3.5 to 16.3.8
- [Release notes](https://github.com/vercel/next.js/releases)
- [Commits](https://github.com/vercel/next.js/commits/v16.3.8/packages/eslint-config-next)

Updates `jsdom` from 30.0.1 to 30.1.1
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Commits](jsdom/jsdom@v30.0.1...v30.1.1)

Updates `vite` from 8.3.0 to 8.3.1
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.3.1/packages/vite)

Updates `vitest` from 5.0.1 to 5.0.3
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v5.0.3/packages/vitest)

---
updated-dependencies:
- dependency-name: prettier
  dependency-version: 3.9.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-minor-patch
- dependency-name: "@tanstack/react-query"
  dependency-version: 5.104.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-minor-patch
- dependency-name: lucide-react
  dependency-version: 1.49.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-minor-patch
- dependency-name: next
  dependency-version: 16.3.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-minor-patch
- dependency-name: yjs
  dependency-version: 13.6.33
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-minor-patch
- dependency-name: "@types/node"
  dependency-version: 26.6.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-minor-patch
- dependency-name: eslint-config-next
  dependency-version: 16.3.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-minor-patch
- dependency-name: jsdom
  dependency-version: 30.1.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-minor-patch
- dependency-name: vite
  dependency-version: 8.3.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-minor-patch
- dependency-name: vitest
  dependency-version: 5.0.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-minor-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot @github

dependabot Bot commented on behalf of github Oct 3, 2026

Copy link
Copy Markdown
Contributor Author

Labels

The following labels could not be found: web. Please create it before Dependabot can add it to a pull request.

Please fix the above issues or remove invalid values from dependabot.yml.

@QuintinBotes
QuintinBotes force-pushed the dependabot/npm_and_yarn/npm-minor-patch-faa6c22944 branch from 6439579 to c04ae9e Compare October 5, 2026 07:12
@dependabot @github

dependabot Bot commented on behalf of github Oct 5, 2026

Copy link
Copy Markdown
Contributor Author

This pull request was built based on a group rule. Closing it will not ignore any of these versions in future pull requests.

To ignore these dependencies, configure ignore rules in dependabot.yml

@dependabot
dependabot Bot deleted the dependabot/npm_and_yarn/npm-minor-patch-faa6c22944 branch October 5, 2026 07:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant