Skip to content

Releases: TAIPANBOX/scopyx

v1.1.1

Choose a tag to compare

@github-actions github-actions released this 26 Oct 00:07
91ebdb0

What's Changed

  • chore(deps): bump agent-stack-go to v2.0.1 by @TAIPANBOX in #66
  • build: Go 1.27.3 for GO-2026-6809 in crypto/x509 by @TAIPANBOX in #67
  • chore(release): scopyx 1.1.1, built on Go 1.27.3 by @TAIPANBOX in #68

Full Changelog: v1.1.0...v1.1.1

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 04:11
b23266e

What's Changed

  • fix: implement extract=screenshot and wait_for on the chromium backend by @TAIPANBOX in #47
  • deps: agent-stack-go v1.0.1 by @TAIPANBOX in #46
  • chore(deps): update agent-stack-go to v1.0.2 by @TAIPANBOX in #48
  • ci: bump the actions group with 3 updates by @dependabot[bot] in #49
  • ci: bump github/codeql-action/upload-sarif from 4.38.0 to 4.38.2 in the actions group by @dependabot[bot] in #50
  • chore(deps): bump agent-stack-go to v1.1.0 by @TAIPANBOX in #51
  • docs(readme): current image tags, test count and two missing env vars by @TAIPANBOX in #52
  • build: move the Go toolchain to go1.27.2 by @TAIPANBOX in #53
  • ci: the estate secret scan on every pull request and push to main by @TAIPANBOX in #54
  • docs(readme): the address gate, redirects, the browser status line and the figures' record by @TAIPANBOX in #56
  • docs: paraphrase the owner-attributed decisions in release.yml and CLAUDE.md by @TAIPANBOX in #57
  • ci: bump the actions group with 3 updates by @dependabot[bot] in #55
  • chore(deps): bump agent-stack-go to v1.2.0 by @TAIPANBOX in #58
  • chore(deps): bump agent-stack-go to v1.3.0 by @TAIPANBOX in #59
  • feat(robots): record every allow or refusal on an unreadable robots.txt by @TAIPANBOX in #60
  • chore(deps): move agent-stack-go to the v2 module, v2.0.0 by @TAIPANBOX in #62
  • ci(release): sign the image in the legacy format policy-controller reads by @TAIPANBOX in #63
  • chore(release): scopyx 1.0.2, the image signed in the legacy format by @TAIPANBOX in #64
  • chore(release): scopyx 1.1.0, the stream file rule first by @TAIPANBOX in #65

Full Changelog: v1.0.1...v1.1.0

v1.0.1

Choose a tag to compare

@github-actions github-actions released this 16 Sep 11:01
9f3b068

Scopyx 1.0.1

A patch release with one fix: on the chromium backend, every subresource is
now decided against the policy plane. Nothing frozen in compat/1.0.json
moves.

Since 1.0.0

  • The chromium backend decided each subresource against the address rules
    and an allow-set the policy plane never sends, so a subresource on an
    approved page reached any public host while the record said
    per_request. Under it, the proxy that is the browser's only way out asked
    the decider on a context of its own, so nothing the fetch had established
    reached that question. Now each subresource host is one question to the
    policy plane through the fetch's own memo (once per host, not once per
    request), a plane that cannot be asked is deny_policy_unreachable, and a
    question asked outside a governed fetch is refused. Run red first with a
    real browser: the refused host's server reached once, the policy plane
    never asked about it (#44).
  • features/subresources.feature: seven scenarios, each bound to a test and
    held by scripts/features-are-bound.sh, the ninth gate.

Upgrade note, 1.0.0 to 1.0.1

Nothing to migrate. A page whose subresource host the policy refuses now
renders without that subresource and the record counts it; a page that
rendered whole under 1.0.0 and renders with a blocked count under 1.0.1 was
reaching a host the policy never allowed, and that is the fix. A rendered
page now costs the policy plane one /v1/decide per distinct subresource
host it names. The image tags are v1.0.1 and v1.0.1-chromium.

Not in this release, said plainly

  • The loopback proxy under a chromium fetch is still usable by a process on
    the same machine that guesses its port for the length of the fetch; the fix
    shape is unchanged from the 1.0.0 notes and not built.
  • extract=screenshot and wait_for are accepted by the browse tool and
    not rendered by the chromium backend: a screenshot request returns the
    page's HTML, and wait_for is not waited for. Both stay frozen names, and
    both are listed as experimental in compat/1.0.json.
  • The browser's own background traffic (component updates, despite the flag
    that disables them) reaches the proxy, is refused there, and is counted as
    blocked; a page's blocked count can therefore be one higher than the page
    itself explains.
  • The external backend is unchanged and always navigation_only.

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 13 Sep 20:29
51a8c39

Scopyx 1.0.0

The web-egress enforcement point of the TAIPANBOX stack: an agent's browsing
goes through it, every destination and every redirect hop is decided against
Wardryx before a backend fetches it, and what happened is written to the
shared agent-event bus. It decides; it does not fetch anything the operator's
own backend could not.

What 1.0 promises

compat/1.0.json, rendered as COMPATIBILITY.md and held by
scripts/compat-surface.sh on every push: the three MCP methods, the
browse tool with its three arguments and three extract values, the
X-Scopyx-Key header, the seventeen SCOPYX_* names with the backend and
robots values they accept, and the two event types this plane emits
(web_fetch, web_blocked). A frozen name is not removed or renamed within
this major; a new tool, a new optional argument, a new event type under this
source, or a new SCOPYX_* name with a default that keeps today's behaviour
is additive. The two image variants (scopyx:<tag> and
scopyx:<tag>-chromium) stay. Support line: the newest minor gets every fix;
the previous minor gets security-relevant fixes for 90 days after the newer
one is tagged.

Since 0.1.2

  • The SSRF address gate refuses the ranges the first sweep missed: IETF
    protocol-assignment space, benchmarking space, 240.0.0.0/4, limited
    broadcast, deprecated IPv6 site-local, and both families' unspecified
    address; every one was confirmed reachable under the unfixed code first
    (#31).
  • components.json declares the open-bind refusal matrix, all seventeen
    environment names, and the two images; a test starts the real binary four
    ways to prove the matrix, and refuses a name read by the code that the
    manifest does not declare, in both directions (#24).
  • agent-stack-go v1.0.0, the contract at 1.0 (#35); Go 1.27 (#26).
  • Every release is signed and attested by digest, both images, with SBOMs
    and a provenance bundle on the release page (#36); workflows run read-only
    except where they publish (#38), actions are pinned to commits (#32), and
    an OpenSSF Scorecard is published (#34); SECURITY.md written.
  • Nothing on the wire moved: the same two event types under schema v0.2, the
    same tool schema, the same door.

Proven, by the 1.0 proving run (estate-gates PROVEN.md, section "The 1.0 proving run")

  • POL-3, R0 and R1. The five gates in order, each refusal on the bus as
    web_blocked high: the address rule (deny_address), an allowed origin
    fetched, a denied origin (deny_policy), an allowed origin redirecting into
    a denied one refused on the target host, robots (deny_robots, github.com
    /search$), and the policy plane killed (deny_policy_unreachable). On R0
    a stack-up build of that day's main with Wardryx and policy-r0.yaml; on
    R1 the stand's released scopyx:v0.1.2 with wardryx:v0.1.0, the same
    five answers.
  • INT-3, R0. An MCP client on browse: the allowed destination fetched,
    the denied one refused.
  • FAIL-2, R0 and R1. Wardryx killed under a running gateway and this
    plane: this plane refuses deny_policy_unreachable and records
    web_blocked high while the gateway, by its own design, fails open (R0)
    or closed (R1, the stand's TOKENFUSE_WARDRYX_FAILMODE: closed); both
    recover when the policy plane is back.

Upgrade note, 0.1.x to 1.0.0

Nothing to migrate: this plane keeps no state beyond the optional NDJSON
journal, which 1.0.0 appends to in the same envelope (prev_hash chain
continues), and the hourly cap, which resets on every restart as before.
Every SCOPYX_* name and default is unchanged. An address that 0.1.2
fetched and 1.0.0 refuses is in one of the ranges #31 added; that is the fix,
not a regression. The image tags are v1.0.0 and v1.0.0-chromium.

Not in this release, said plainly

  • During a chromium fetch the loopback proxy this process owns is usable by
    any process on the same machine that guesses its ephemeral port; such a
    request is decided against the same policy as the fetch, not refused
    outright. The fix shape is written beside the code (Proxy-Authorization
    with a per-fetch secret, answered over CDP Fetch.authRequired) and is not
    built.
  • The browse tool's wait_for and extract are frozen names; what the
    chromium backend renders for them depends on the browser it drives, which
    compat/1.0.json lists as experimental.
  • The external backend's request shape is experimental and always
    navigation_only: subresources of a page fetched by the operator's own
    service are not decided here.
  • No health path, on purpose: nothing in the estate polls this plane.

Full changelog: v0.1.2...v1.0.0

v0.1.2

Choose a tag to compare

@TAIPANBOX TAIPANBOX released this 12 Sep 20:47
867cf47

v0.1.2

The browser variant could not render on a real node. This is the fix.

WHAT WAS WRONG WITH v0.1.1

HOME pointed at /home/nonroot, which useradd -M never created. Chromium died
before opening a page, with an error about a crash-handler database that names
nothing about a home directory. Every fetch through the chromium backend failed
on a k3s node; a local kind cluster had not shown it, because kind answers the
admission question and this was not that.

HOME is /tmp now, the one path guaranteed writable in every deployment of this
image: a tmpfs in compose, an emptyDir in Kubernetes under a read-only root
filesystem, and the container's own writable layer under a plain docker run.

Measured on a t3.xlarge running k3s, 2026-08-10. NOT reproduced under docker
run locally in any shape tried, so the precise trigger is not isolated and the
fix stands on its own merit rather than on a diagnosis.

ALSO IN THIS TAG

Gates for the last three invariants that were prose: no decision delegated to a
backend, nothing outliving a fetch, nothing claiming compliance. Writing the
first moved a verdict out of the chromium backend, which now takes one decision
function supplied from above and constructs none of its own.

TWO SIZE NUMBERS, BECAUSE ONE MISLEADS

scopyx:v0.1.2 3.5 MB to pull, 15.4 MB on disk
scopyx:v0.1.2-chromium 267 MB to pull, 1.03 GB on disk

Commits

  • 867cf47 fix(image): HOME named a directory that does not exist, and v0.1.1 could not render (#17)
  • b5553e6 gate: the last three invariants that were prose, and one moved the code (#16)

Support

A 0.x release: only main is supported and fixes are not backported. This Release object was created on 2026-09-12 for a tag cut earlier; the signed checksums, provenance attestation and SBOM that later releases carry start with the next tag.