Skip to content

1.2.44 - Deliver the 2026-10-29/30 upstream synchronization (Strix 1.7.0 + 64 commits) - #45

Merged
samirhvbr merged 118 commits into
masterfrom
feat/upstream-sync-delivery-20261029
Oct 30, 2026
Merged

samirhvbr merged 118 commits into
masterfrom
feat/upstream-sync-delivery-20261029

Conversation

@samirhvbr

@samirhvbr samirhvbr commented Oct 30, 2026 •

Copy link
Copy Markdown
Owner

Summary

Delivers fork 1.2.44: the fork moves onto upstream main at 6b7ae2eb (Strix 1.7.0 + 64 commits) and carries 20 open upstream pull requests. It is a pure fast-forward of master (116 commits ahead, 0 behind) and contains the heads of #38–#44, so merging it closes those seven PRs too.

Validation

  • Full suite on the merged tree d3d221b9: 3612 passed, 12 skipped, 3 xfailed, 0 failed (LITELLM_MODE=PRODUCTION LITELLM_LOCAL_MODEL_COST_MAP=True). Ruff format and lint, Mypy (176 files) and Bandit pass.
  • With LiteLLM's live price map one pricing test fails on 2026-10-30 (kyma/grok-4.5 makes bare grok-4.5 ambiguous): data drift, not code. CLAUDE.md now says to run the suite with the bundled map.
  • Pyright is not a gate here: make check-all stops at it, as before.
  • Not done: remote CI (the fork's Actions account is billing-locked, so the checks on this PR will not run), a full external scan, and new pentest-<triple> binaries. The binaries on the 1.2.43 Release predate this synchronization.

Needs the owner before merging

  1. fix(api-spec): preserve referenced Postman environment values usestrix/strix#1635 puts enabled Postman environment values, credentials included, into the staged collection that the agent reads (the host's Postman API key stays out). It is a contract upstream has not agreed to. If it is not wanted, drop its two commits (e219e11a, 41be416c) before the merge.
  2. Accepting the brotli CVE staying in the sandbox image until upstream publishes 1.3.1.

Merge and release steps (owner)

Merge with a merge commit (--no-ff; not squash or rebase, so #38–#44 show as merged). Then create the annotated tag shvia-v1.2.44 and publish the Release SHVIA 1.2.44 (Strix 1.7.0). The main mirror was already fast-forwarded to upstream/main (6b7ae2eb). Nothing in this PR tags, releases or deploys.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TavwVMH7PvrD68JTDfd6Hb

J0kkeR and others added 30 commits October 9, 2026 22:44
certutil -N only skips its password prompt when it creates a fresh
database. When the sandbox container is restarted, the NSS DB from the
first run already exists, so certutil -N asks for the existing password
and - with no TTY attached - spins forever in an "Invalid password. Try
again." loop, burning a full core and blocking the rest of the entrypoint
(the CA trust import never runs).

Guard the call with a cert9.db existence check, the same approach mkcert
uses (FiloSottile/mkcert#558). certutil -A re-import under the same
nickname is safe to repeat, so restarts now complete cleanly.
…t_store

- Replace char-by-char iterative string loops in _take_prefix and _take_suffix with direct UTF-8 byte slicing and boundary-safe decoding (errors='ignore').
- Eliminate eager text.split('\n') heap allocations in _head_tail, checking line thresholds lazily via text.count('\n') + 1 and bounded splits.
- Prevent intermediate Python byte/string allocations on oversized command and scan tool outputs.
- Add unit tests for multi-byte boundary cuts, lazy line splitting, and scaling.
- Replace ambiguous length-only assertion with a peak memory check via tracemalloc.
- Clarify test comments regarding character loop iterations and allocation behavior on large budgets.
…sion when create_or_reuse is called with defer=True
…d discard a sandbox created after a cancelled deferred bring-up
…trix#1327)

* fix(models): replay malformed tool-call arguments as valid JSON

A model that emits a tool call with truncated or otherwise invalid JSON
arguments fails that one call, but the raw string is recorded in the
session. Strict OpenAI-compatible servers (vLLM, SGLang) validate every
assistant tool call in the request, so each later turn is rejected with
"Assistant tool call function.arguments must be valid JSON" and the agent
never recovers. The turn guard now rewrites such arguments on the way out
to a JSON object carrying the original text, alongside the existing
duplicate call-id repair.

* fix(agents): tell the model to re-issue tool calls whose arguments are not valid JSON

A streamed turn that ends mid-tool-call leaves the client with a JSON prefix
as the arguments. Instead of the SDK's generic parse-error result, the tool
wrapper now short-circuits with a clear 'not executed, re-issue with complete
arguments' message so the model recovers in one turn.

* fix(models): treat NaN/Infinity tool-call arguments as malformed

* test(cost): pin model resolution in the provider-prefixed cost test

* fix(models): treat over-nested tool-call arguments as malformed
* feat(llm): extra request-body fields via LLM_EXTRA_BODY

Some provider parameters, such as OpenAI's service_tier and
safety_identifier, are read only from the request body, so
LLM_EXTRA_HEADERS can't set them. LLM_EXTRA_BODY merges a JSON object
into the body of every request to the configured model, on both routing
paths. A dedicated dedupe model gets its own DEDUPE_LLM_EXTRA_BODY
instead, as with headers.

* fix(config): decode saved JSON-object settings when loading

persist_current() saves env values verbatim, so LLM_EXTRA_HEADERS,
LLM_EXTRA_BODY and their DEDUPE_ variants land in cli-config.json as JSON
text. The loader passed that text unchanged to the dict fields, so a later
launch without the env var failed validation. Decode saved strings for
dict fields, as pydantic-settings does for env vars.

---------

Co-authored-by: Szymon Nastaly <szymon.nastaly@autoform.ch>
…ssages on resume

BudgetPausedError carries whether the operator pause caused it, so a resume that lands between the hook's refusal and the loop's handler still parks and continues instead of exiting under the stop policy. After the resume the agent drains its mailbox into the session before retrying the call, so a message queued while it was held is not skipped.
* feat(agents): let callers remove base tools from scan agents

* feat(agents): let callers choose the report tool instead of removing tools

* refactor(agents): name the report tool via the prompt template, not string replacement
… verify ids (usestrix#1551)

Verifying http_exchange_ids fetched every request with its full raw
request and response bodies, serially, and timed out on busy proxy
projects; the ids were then dropped and the finding lost its evidence.

Check existence with an id-only GraphQL query, retry once, and when the
proxy still does not answer keep the ids with a warning instead of
discarding them.
usestrix#1559)

* feat(skills): expand XSS coverage for HTML injection and normalization

* Update xss.md

---------

Co-authored-by: alex s <46074070+bearsyankees@users.noreply.github.com>
…trix#1569)

- aiohttp 3.14.3 -> 3.14.5 and graphql-core 3.2.11 -> 3.2.13 in uv.lock
- viewer frontend: vite 6.4.3 -> 6.4.4
- sandbox image: trufflehog 3.95.9 -> 3.99.2 (updates its embedded go-git,
  go-billy, amqp091-go and mongo-driver)
POST /uploads/complete answers 202 with status "processing" until the upload record is ready. _upload_scan_source called it once, so the 202 shape failed validation as a malformed response and the just-uploaded archive was deleted, failing 'scans start --source' for most real repositories.

Poll the completion endpoint every 5s on a bounded 300s loop (house monotonic-deadline style). If processing outlasts the bound, keep the upload and report its id with the --upload-ids resume command instead of deleting it as a rejection.

Fixes usestrix#1570
samirhvbr and others added 27 commits October 29, 2026 16:58
The upstream resume path drains the mailbox before retrying inference.
Without an SDK session, consume_pending cannot persist those messages;
ignoring its returned items silently loses messages sent during a pause.

Request the pending input items for sessionless runners and append them to
their existing input. Keep SQLite-backed replay empty because the messages
are already persisted there. Cover text/list initial input with and without
a real SQLite session, including ordering and exactly-once persistence.

This is an integration compatibility fix for the no-session delivery
contract retained by the fork when carrying upstream PR usestrix#1161. The previous
fork retained the queued message; the merged resume path discarded it.

Validation: two new sessionless cases fail before the fix; 249 focused
budget/pause/message/execution/retry tests pass afterward. Ruff check and
format, Mypy and Bandit pass for changed files with frozen dependencies,
Python 3.12.14, an isolated HOME/environment and no provider calls.

(cherry picked from commit c18f03eab00812cd8fc17a59fa8a85a1e6aa1ad0)
…s stable

Three regressions from adding client_side_path_traversal as a stored
finding_class:

- update_vulnerability_report gated revisions on `class == "dynamic"`,
  so a CSPT finding was handled as a dependency finding: endpoint, PoC
  and http_exchange_ids edits were rejected and a cvss_breakdown change
  went through the dependency re-rating path. Gate on dependency_cve
  instead, so every PoC-backed class revises like a dynamic finding.
- SARIF's _class_token used any non-dynamic finding_class, including
  the dependency_cve marker every dependency report carries. Unrelated
  locationless CVEs under one CWE collapsed onto one alert and existing
  dependency alerts changed fingerprints. Only registry sub-classes now
  override the title keyword.
- create_vulnerability_report accepted the reserved dependency_cve
  class and rejected a nullish finding_class. It now accepts dynamic or
  a registry sub-class, and treats "none"/"null"/blank as dynamic.

Adds regression tests for each.
- Add a Reporting section: file with finding_class
  client_side_path_traversal and CWE-22, give an endpoint + method or a
  repo-relative code_location, and when to leave a server-built
  traversal as dynamic. The tool docstring already pointed here.
- Count scriptless HTML injection as CSPT impact, matching the HTML
  injection guidance main added to xss.
- Close a checked, harmless decode as ruled_out and keep
  open_proof_gap for undecided cases, consistently across the skill.
- Widen sources to referrer, postMessage and storage, as the tool
  docstring and fixtures already do.
- Log the right path when fetch is called with a URL object, here and
  in browser_security.
…rface

The scan routes client-side path traversal to an agent carrying the
client_side_path_traversal skill, but browser_security's CSPT surface
only counted rows by browser_security carriers. coverage.json and
finish_scan then called CSPT unexamined next to the CSPT finding the
same scan filed, and nothing the root recorded could clear it.

A sub-topic can now name the dedicated class that owns it; such a
surface is matched like that class, by any row naming it. Also drop the
"client side path" alias: matched as a word set, any client-side row
on a path parameter counted as CSPT coverage.
…arget

The CSPT discriminator told agents to set endpoint to the path their
payload reached. One bug demonstrated against two destinations then
got two SARIF identities. Point endpoint at the page route carrying the
attacker-controlled source, in the validator message, the tool
docstring and the skill.

Also in the skill: the worked example used two ../ segments, which
resolve to /admin/settings rather than /api/admin/settings, and a
false-positive rule would have closed a state-changing request sent
with the victim's session.

SARIF: a titled locationless finding whose title yields no class
keyword (e.g. a non-English title) kept an empty synth_class segment on
main; keep it so its fingerprint does not change.
…tches

Whole-word matching opened false "unexamined" gaps that main did not
report: "Open redirection", "NoSQLi" and "Information leakage" no
longer counted. A phrasing term of four or more letters now also
matches a ledger word it starts; short tokens such as rce and xs stay
whole-word, so rce still never matches inside force.

browser_security: rows named after the skill's own headings ("Navigation
and Redirect Control", "CSP and Browser Parsing") now cover those
surfaces, and a carrier's generic "Browser security" row yields
per-surface gaps instead of claiming nothing was recorded.
0d3f259 keeps the earlier author's agent_id on a superseded coverage
row so bundled-skill surfaces stay attributed, but this existing test
still expected the old history shape and failed.
…box image delivery blocker

Second pass over the review branch, with both remotes fetched. Upstream main did not move (still 6b7ae2e, the
synchronized base), so no code checkpoint advances.

Known items: all 530 upstream ledger records and the 44 fork PRs were compared with the live API on state, updated
date and head SHA. Only usestrix#1393 changed (rebased onto 6b7ae2e with four commits of its own); it is re-reviewed in depth
and stays deferred, with the reasons recorded. Open inventory is unchanged at 320 PRs + 203 issues.

Discovery: the 48-hour-overlap update query returned 29 items. Four closed items were not in the ledger and now are:
PRs usestrix#1616, usestrix#1617 and usestrix#1603, merged upstream and already ancestors of the branch through the base synchronization, and
issue usestrix#1529, a usage question. The ledger has 574 records; coverage totals are recomputed from it.

Version and releases rechecked and unchanged: 1.2.43 equals the tag, the Latest Release and remote master; upstream's
latest release is still v1.7.0.

New delivery blocker: the synchronized source defaults to ghcr.io/usestrix/strix-sandbox:1.3.1, which is not
published (manifest 404; 1.3.0 answers 200 as the control). master pins the published 1.3.0. Recorded in
release-audit.json, the checkpoints, the round report, the continuity guide and version.md. No tag, release, mirror or
master change.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TavwVMH7PvrD68JTDfd6Hb
…publishes 1.3.1

The synchronized source defaults to ghcr.io/usestrix/strix-sandbox:1.3.1 (upstream
usestrix#1617, the brotli CVE-2026-111497 patch), but that tag is not in the registry: the
anonymous manifest request returns 404 for 1.3.1 and 200 for 1.3.0. A scan or an
engine binary built from the synchronized source could not pull its default image.

Both places that carry the tag, RuntimeSettings.image and scripts/install.sh, go
back to 1.3.0. A test now fails when they drift apart. Until 1.3.1 exists the image
keeps the brotli decoder unpatched; STRIX_IMAGE still overrides the default.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TavwVMH7PvrD68JTDfd6Hb
… + 64 commits)

Bumps .fork-version and version.md to 1.2.44, records the new upstream base
(6b7ae2e, Strix 1.7.0 + 64 commits) and adds the FORK.md row. The row replaces the
"Pending integration" section the review branch carried. The sandbox image decision
(pin 1.3.0 until upstream publishes 1.3.1) is written into the continuity record, the
round report, release-audit.json, checkpoints.json and CLAUDE.md.

Nothing is tagged or released by this commit; merge, tag shvia-v1.2.44, the Release and
the main mirror push stay with the owner.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TavwVMH7PvrD68JTDfd6Hb
Fixes usestrix#1629. Keep the raw enumeration bound while packaging each working-tree path once.

(cherry picked from commit 5c57940)
Fixes usestrix#1629. Keep the raw enumeration bound while packaging each working-tree path once.

(cherry picked from commit 5c57940)
…to date

The delivery now carries nineteen upstream pull requests: usestrix#1627 (a mixed-case
model id no longer loses its own catalog row), usestrix#1631 (a working tree with an
unresolved merge stages one file once) and usestrix#1634 (a malformed dedupe verdict
cannot suppress a finding) join the sixteen from the first pass. The ledger
records eleven new items (585 records, 533 open items triaged), closes usestrix#1370
and usestrix#1607, and keeps usestrix#1625, usestrix#1626, usestrix#1632, usestrix#1633 and usestrix#1635 deferred with their
reasons. FORK.md lists the eight third-party and five own pull requests that
were missing from its tables; CLAUDE.md now says to run the full suite with
the bundled LiteLLM price map, because the live one drifted on 2026-10-30.

Validated at 111a34e: 3604 passed, 12 skipped, 3 xfailed, 0 failed.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TavwVMH7PvrD68JTDfd6Hb
…delivery

The review branch gained six commits from a parallel session on 2026-10-30:
usestrix#1631 and usestrix#1634 (the same upstream heads this branch had already carried, so the
code merges as one change), the Postman environment fix usestrix#1635 with its cleanup
follow-up, and a per-record ledger re-fetch with its reports. The ledger of the
review branch is the base (597 records); this branch overlays only what it
established itself: usestrix#1627 carried and verified, usestrix#1607 solved by it, and usestrix#1628
answered by the fork's own pin of the sandbox image to 1.3.0. The round report
of this branch becomes the delivery consolidation record.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TavwVMH7PvrD68JTDfd6Hb
…merged tree

The delivery now carries twenty upstream pull requests, usestrix#1635 included. The
merged tree passes the full suite (3612 passed, 12 skipped, 3 xfailed, 0 failed
with the bundled LiteLLM price map) and Ruff, Mypy and Bandit. The new
consolidation record explains how the delivery and review branches were joined,
what each session established, which carry needs the owner's confirmation (usestrix#1635
puts environment credentials in the agent workspace), and why none of the open
upstream pull requests can be merged yet.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TavwVMH7PvrD68JTDfd6Hb
@samirhvbr
samirhvbr merged commit e2ec6f9 into master Oct 30, 2026
0 of 15 checks passed
@samirhvbr
samirhvbr deleted the feat/upstream-sync-delivery-20261029 branch November 2, 2026 16:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.