Repository navigation
Releases: TAIPANBOX/scopyx
Release list
v1.1.1
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
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
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 isdeny_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 byscripts/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=screenshotandwait_forare accepted by thebrowsetool and
not rendered by the chromium backend: a screenshot request returns the
page's HTML, andwait_foris not waited for. Both stay frozen names, and
both are listed as experimental incompat/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
externalbackend is unchanged and alwaysnavigation_only.
v1.0.0
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.jsondeclares 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-gov1.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_blockedhigh: 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 andpolicy-r0.yaml; on
R1 the stand's releasedscopyx:v0.1.2withwardryx: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 refusesdeny_policy_unreachableand records
web_blockedhigh while the gateway, by its own design, fails open (R0)
or closed (R1, the stand'sTOKENFUSE_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 CDPFetch.authRequired) and is not
built. - The
browsetool'swait_forandextractare frozen names; what the
chromium backend renders for them depends on the browser it drives, which
compat/1.0.jsonlists as experimental. - The
externalbackend'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
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.