Repository navigation
1.2.44 - Deliver the 2026-10-29/30 upstream synchronization (Strix 1.7.0 + 64 commits) - #45
Merged
Merged
Conversation
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.
…and always count hidden targets
…sion when create_or_reuse is called with defer=True
…d discard a sandbox created after a cancelled deferred bring-up
…the sandbox create does not wait for it
…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>
…g non-TTY process cannot be polled
…rs keep stripping the metadata block
… header, never in command output
… resume_budget lifts it
…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.
… and tokens in llm_requests
…only with STRIX_RUN_RECORD_TIMINGS
* 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
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)
(cherry picked from commit 3f79c10)
(cherry picked from commit beb55e8)
(cherry picked from commit beb55e8)
Fixes usestrix#1629. Keep the raw enumeration bound while packaging each working-tree path once. (cherry picked from commit 5c57940)
(cherry picked from commit 34e67e5)
(cherry picked from commit 5f65feb)
…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
…quest Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TavwVMH7PvrD68JTDfd6Hb
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TavwVMH7PvrD68JTDfd6Hb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Delivers fork 1.2.44: the fork moves onto upstream
mainat6b7ae2eb(Strix 1.7.0 + 64 commits) and carries 20 open upstream pull requests. It is a pure fast-forward ofmaster(116 commits ahead, 0 behind) and contains the heads of #38–#44, so merging it closes those seven PRs too.strix-sandbox:1.3.0. Upstream's default moved to1.3.1(fix(image): patch brotli decoder (CVE-2026-111497) in sandbox, bump t… usestrix/strix#1617, the brotli CVE-2026-111497 patch) but that tag is not in the registry (404 on 2026-10-29 and 2026-10-30;1.3.0answers 200).RuntimeSettings.imageandscripts/install.shgo back to the published tag and a test keeps them equal. The engine runs unchanged against1.3.0; the cost is that libbrotli stays unpatched in that image until1.3.1is published.Validation
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.kyma/grok-4.5makes baregrok-4.5ambiguous): data drift, not code. CLAUDE.md now says to run the suite with the bundled map.make check-allstops at it, as before.pentest-<triple>binaries. The binaries on the 1.2.43 Release predate this synchronization.Needs the owner before merging
e219e11a,41be416c) before the merge.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 tagshvia-v1.2.44and publish the ReleaseSHVIA 1.2.44 (Strix 1.7.0). Themainmirror was already fast-forwarded toupstream/main(6b7ae2eb). Nothing in this PR tags, releases or deploys.🤖 Generated with Claude Code
https://claude.ai/code/session_01TavwVMH7PvrD68JTDfd6Hb