* fix(javascript): report empty Electron coverage instead of silent zeroes
`analyze_javascript_application` reported `browser_windows: 0` and
`ipc.operations: 0` with only generic partial/unknown flags, so a bundle that
imports `electron` but whose Electron facts were not recovered read exactly like
an application with no IPC at all. Issue #8201 is that false negative on a real
Rolldown bundle.
Two additions, both scoped to "Electron is referenced but nothing was recovered":
**A machine-readable indicator.** `electron_summary` gains
`electron_semantics: "recovered" | "empty"`. It is absent when no analyzed source
links an Electron module, so its presence distinguishes "not an Electron
application" from "Electron coverage is empty". It follows the existing
`protocol_registrations.exactOptional()` precedent, so previously captured
evidence stays valid.
**A graph limitation.** The limitation list already carried a note when at least
one Electron fact was recovered but said nothing when zero were. It now states
that zero IPC operations and zero BrowserWindows mean empty coverage rather than
absence.
`electronModuleReferenced` is the single owner of the module test. It reuses
`ELECTRON_MODULE`, which matches exactly the supported entry points (`electron`,
`electron/common`, `/main`, `/renderer`, `/utility`), so `electron-helper` does
not count, and it ignores type-only links because importing Electron types
promises no boundary fact.
Five tests cover recovered, empty, not-referenced, type-only, and supported
subpath versus unrelated package. The empty, recovered and type-only cases fail
on unmodified `main`.
* chore: retrigger title and readiness checks after the title was corrected
* fix(javascript): report Electron coverage from retained facts
Four review findings on the coverage indicator.
**A rejected application projection hid the reference.** A file whose expanded
relationships exceed the result budget is replaced by a placeholder with no
module links before the summary runs, while `graphLimitations` reads the raw
analysis. The same response could then warn in prose and omit the field. The
summary now takes the retained analysis for coverage only, and both outputs
read one `electronSemanticsState`, so they cannot disagree.
**A skipped semantic analysis hid the reference too.** `electronModuleReferenced`
read only `semantic.ir.moduleLinks`, which is absent when semantic analysis is
skipped for a budget and drops `import("electron")` or `module.require("electron")`
forms. It now falls back to the retained `javascript.references`, which the static
producer records for those inputs, while still excluding `type-import` links when
the richer owner is available.
`electronBoundaryFactCount` is now the single owner of the fact total, replacing a
duplicate inline reduce in the graph builder.
**Omission no longer claims absence.** The schema comment said a missing
`electron_semantics` means the application does not use Electron. The predicate
only establishes that no retained fact names one, and unread sources, failed
analysis, and dynamic module names can hide its use, so the contract now says
unknown.
Two regressions cover a rejected projection and a skipped semantic analysis; both
fail on the previous commit.
* fix(javascript): count a dynamic Electron import as coverage
Review finding: `electronModuleReferenced` returned as soon as module links
existed, so a literal dynamic import was ignored. Verified against the two fact
owners:
import("electron") -> references: [dynamic-import electron]
moduleLinks: []
require("electron") -> references: [require electron]
moduleLinks: [require electron]
An application that only loads Electron through `import("electron")` therefore
got neither `electron_semantics: "empty"` nor the empty-coverage warning, and the
zero counts stayed unexplained.
The two owners now answer their own half instead of one short-circuiting the
other. Module links answer a runtime static import or require and keep excluding
`type-import`; the retained reference is read for every kind except
`static-import`, which is exactly the type-only risk. A dynamic specifier is
still never counted by either owner, so this remains an observed-reference claim
rather than an absence claim.
The regression uses `import("electron")` and fails on the previous commit.
* fix(javascript): read only module-loading Electron references
Two review findings, both verified against the static reference producer.
**A retained runtime static import was skipped.** The excluded kind was meant to
protect the type-only distinction, but the static analyzer records a whole
`import type { IpcMain } from "electron"` declaration as no reference at all:
import type { IpcMain } from "electron" -> references: []
import { app } from "electron" -> references: [static-import electron]
require("electron") -> references: [require electron]
import("electron") -> references: [dynamic-import electron]
new Worker(new URL("electron", m)) -> references: [worker electron]
When semantic analysis is skipped for a budget the module links are absent, so
that exclusion dropped a real runtime ESM import and left the zero counts
unexplained.
**A worker URL path is not an Electron module.** `new Worker(new
URL("electron", import.meta.url))` records a `worker` reference whose specifier is
a path relative to the importing source, so counting it reported an ordinary
worker file as `electron_semantics: "empty"`.
`ELECTRON_REFERENCE_KINDS` is now an explicit allowlist of the kinds that load a
module by package specifier — `static-import`, `dynamic-import` and `require` —
so `worker` and `service-worker` URL paths are excluded. Module links are still
read first for the type-only distinction.
Three regressions cover a skipped-semantics ESM import, a skipped-semantics whole
type-only import, and a worker URL path; two of them fail on the previous commit.
* fix(javascript): own Electron applicability in the static producer
Review finding. A `worker` reference records a URL relative to the importing
source, so `new Worker(new URL("electron", import.meta.url))` names a local file
and is not an Electron module. The boundary owner already read only module-loading
reference kinds, but `finalizeStaticAnalysis` still treated every matching static
reference as `analysis_coverage.applicability.electron: "observed"`, which
`javascriptStaticSourceCoverageSummary` publishes. One response could therefore
say Electron was observed in its coverage view while the Electron summary omitted
`electron_semantics`.
`ELECTRON_REFERENCE_KINDS` now lives next to `ELECTRON_MODULE` in the domain owner
and is consumed by both the static producer and the Electron boundary owner, so the
two outputs cannot disagree. A worker URL path is `unknown` for both, while a
`require("electron")` is `observed` for both.
The regression asserts the domain applicability fact and the boundary summary agree
for a worker URL path; it fails when the producer stops filtering by kind.
* fix(javascript): require a loaded Electron module for applicability
Review finding. A CommonJS `require.resolve("electron")` records a `require`
reference with `operation: "resolve"`: it locates the module without loading it,
so no Electron boundary fact is expected. Both predicates dropped the operation,
so such a source reported `electron_semantics: "empty"` and the missing-coverage
warning even though Electron was never loaded.
Measured on the static producer:
require.resolve("electron") -> references: [require resolve electron]
applicability.electron: unknown
require("electron") -> references: [require load electron]
applicability.electron: observed
import("electron") -> references: [dynamic-import load electron]
applicability.electron: observed
`electronModuleReferenced` and `finalizeStaticAnalysis` now both require
`operation === "load"`, so the boundary summary and the coverage view stay aligned
and reachability-only references no longer claim missing coverage.
The regression asserts a resolve-only source produces neither the field nor the
warning, and it fails when the operation check is removed.
* fix(javascript): classify Electron loads in the static fact owner
Review finding, and the correct home for the previous two rounds of the same
complaint. A Webpack/Rspack factory may name a local module `"electron"`, and the
static producer then records a loaded `require` reference whose specifier is that
bundle module key. Treating the key as a package specifier reported
`electron_semantics: "empty"` plus the missing-coverage warning for a bundle that
never loads Electron.
Three changes, all in the domain owner, so no consumer re-derives the question:
- `JavaScriptModuleRangeIndex.hasKey` answers whether a specifier is a recovered
bundle module key. A `require` whose specifier is such a key loads a module
inside the artifact.
- `electronObserved` in `finalizeStaticAnalysis` now requires a loaded module-load
reference whose specifier is not a bundle key. The published
`analysis_coverage.applicability.electron` therefore owns every exclusion:
`type-import`, `require.resolve`, `worker`/`service-worker` URL paths, and
bundle-local keys.
- `electronModuleReferenced` consumes that owned fact instead of re-deriving it,
keeping the boundary summary and the coverage view from disagreeing. Historical
evidence without the field still falls back to the retained references.
Measured:
bundle-local module ID "electron" -> applicability unknown
require("electron") -> applicability observed
webpack external n(45840) -> applicability observed
The regression covers both the local key and the real external in the same
factory shape; it fails without the bundle-key exclusion.
* fix(javascript): identify a bundle module by its loader, not its key
Both review findings were right, and they show why the previous key-set approach
was wrong: bundle-key membership is a property of the file, but whether a
specifier names a module inside the artifact is a property of the reference.
`JavaScriptStaticReference` now records the loader that produced it, and
`electronObserved` excludes `factory-loader` references instead of every specifier
that happens to match a recovered module key. Measured on Node 24.22.1:
local module keyed "electron" -> unknown (factory-loader)
external 45840 = require("electron") -> observed (commonjs-loader)
factory keyed "electron" that loads the pkg -> observed (commonjs-loader)
The third case is the regression: a bundle whose factory is *named* `"electron"`
but whose body does `e.exports = require("electron")` is a real Electron load, and
the old key-set check suppressed it. The real load keeps its `commonjs-loader`
identity even when the same specifier also names a factory, so one response can
rely on the loader while the other relies on the key without either lying.
`JavaScriptModuleRangeIndex.hasKey` is removed; it answered the wrong question.
One regression covers all three shapes and fails when the `factory-loader`
exclusion is dropped.
* fix(javascript): carry the reference loader across the worker boundary
The worker schema is strict, so the new `loader` field broke the worker handshake:
`unrecognized_keys` on every `references` entry. That surfaced in CI as both a
worker-schema test failure and a package-baseline failure reporting
`worker_failure_reason: "io"` for a one-file Electron app.
`referenceShape` now accepts the same three loader identities as the domain type, so
the fact survives the worker boundary instead of collapsing every analysis to an
execution failure.
Verified: `JavaScriptAnalysisWorkerSchemas.test.ts` 10 passed, and the full
domain/application/javascript suite is 5484 passed | 10 skipped. The remaining
`SourceMapCommand` and `DarwinHelperCache` findings are present on unmodified
`main` and are not from this change.
* fix(javascript): remove the superseded key set and forward a deferred loader
Two review findings.
**The `keys` set is dead.** `JavaScriptModuleRangeIndex.keys` is left over from the
abandoned key-membership approach: the loader-identity refactor removed `hasKey` and
the write in `add`, so nothing reads it. Removed.
**The deferred require path dropped the loader identity.** `requireCallSpecifier`
returns a `loader` for `commonjs-loader`, `factory-loader` and `create-require`, and the
direct `addReference` call forwards it, but `finishModuleRequireCalls` did not. A
`createRequire` loader saved under a member literally named `require` therefore lost
its identity:
import { createRequire } from "node:module";
const holder = { require: createRequire(import.meta.url) };
holder.require("x");
before: require "x" with loader undefined
after: require "x" with loader "create-require"
Three regressions cover it; one fails without the change.
I did **not** change the inline-type-only import case. `isTypeOnlyImportDeclaration`
deliberately keeps a declaration whose bindings are all inline type-only, because
`hasUncertainTypeOnlyModuleSideEffect` reports that decision as
`type-only-module-side-effect` uncertainty: whether TypeScript emits the import depends
on the consumer's compiler options. Narrowing it to erased broke
`javascriptStaticCoverage.test.ts` and `javascriptSemanticAnalysis.require_links.test.ts`,
which assert exactly that contract. If Electron applicability should ignore that
reference, the decision belongs where applicability is derived, not in the shared
declaration predicate — say the word and I will do it there instead.
* fix(javascript): keep a commonjs-loader reference out of the bundle module index
Review finding. `finalizeLocatedFindings` attaches `module_runtime` to every finding
that sits inside a factory module range, whoever produced it. `resolveReference` then
sent every reference carrying `module_runtime` through the bundle-module lookup, so a
real CommonJS load inside a factory body resolved to the local module key that shared
its name:
"electron": (e, t, n) => { e.exports = require("electron") }
fact: specifier "electron", loader "commonjs-loader", module_key "electron"
before: resolved through the bundle module index to `#module:electron`
after: resolves as an external package specifier
Only a `factory-loader` specifier names a recovered bundle module key, which is what
`loader` already records after the loader-identity change. The module lookup is now
gated on it, and an absent `loader` keeps the previous behaviour for older findings.
* fix(javascript): transient Windows private-runtime source-transfer
Parent source-transfer into the Windows private runtime root failed with
EPERM on path-based exclusive create. Write through a native transient
private-runtime path that closes the handle after flush so per-job rm
still works, and yield around the sync write so abort deadlines can fire.
* fix(javascript): yield timer phase before Windows source-transfer write
Static checkpoints were admitted against the same budget as semantic and
application results, half of the parent's free heap. Once those charges used
it, the next checkpoint stopped the analysis and every remaining source lost
its static facts, with most of the parent heap still free.
Semantic and application results still stop at that budget. Static checkpoints
may now continue to three quarters of the free heap while the live heap also
has room for another copy of what it holds. Without that room, admission falls
back to the result budget. The live condition is needed because the limit V8
reports counts young-generation capacity that retained objects cannot use:
without it, the parent aborted on heap exhaustion at small heap limits.
Reserved relationships are given up only when the larger share runs short. A
stop still fails with a typed error, which now reports the limit that applied,
what was available, the live heap in use and what the checkpoint needed.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Bind typed service creation, observed availability and retryable cleanup in one composition owner. Reuse selected CLI/MCP factories and canonical contract groups without copying provider operation inventories.
Closes#8429. Refs #740.
Validated paired real application workflows, actual local Codex CLI Terra/high use, complete Evidence and Unknown checkpoint parity, compiler-backed import boundaries, SDK schemas and final real mixed routing. Automated review findings were fixed at their producing owners. Existing exact-base CodeQL alerts are documented on the PR under the owner-authorized unrelated-check exception; no global alerts or security rules were changed.
Assisted-by: Suika (gensokyo-skills:suika-scatter-gather-planning)
Expose static Electron protocol call facts through the shared application graph and existing CLI/MCP Evidence views. Preserve canonical case-insensitive scheme identity, original spellings, exact source provenance and explicit unknowns; keep registration success and runtime routing unproven.
Integration fixes also enforce module-only privileged API ownership, reuse the shared finding-key owner, and align the owning type documentation with the Evidence semantics. Validation and bounded real Obsidian CLI/MCP measurements are recorded in the PR.
Co-authored-by: UnknownHacker1 <35694178+UnknownHacker1@users.noreply.github.com>
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
* fix(electron): keep literal IPC sends ambiguous beside unresolved handlers
A main handler on an unresolved channel can receive any literal renderer
send of a compatible mode, but pairing ignored it unless it had a scoped
receiver. The send was then reported unpaired, or paired with another
handler. Treat an unresolved-channel handler as a competitor that never
pairs.
The wrapper pass seeds only calls with a literal first argument, so it now
records which invocations of a dynamic site it traced. The syntax finding
gains `invocation_channels: "literal"` only when every invocation is a
traced direct call of an unexported local function supplying a literal
channel. Such a site is already represented by its per-invocation findings
and does not compete.
Fixes#8118
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(electron): keep guarded wrapper registrations competing in IPC pairing
A guarded wrapper registration keeps its predicate on a call path and has
no IPC finding. It still counted toward `invocation_channels: "literal"`,
so pairing lost it: a send on that channel was reported unpaired, or
paired uniquely with a direct handler. The enumerated site now carries
these channels as `guarded_invocation_channels`, and each one competes for
its own channel without pairing.
Index each binding's direct call sites by appending in place. Spreading
the earlier calls on every reference was quadratic in a file's call count.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(admission): own inspector, web, and CLI state per host
Replace the process-global inspector, web-bundle, guidance, and JavaScript
counters with objects a host passes in, so independent instances do not
share admission or cleanup.
* fix(admission): keep worker and file cleanup on the host
Web-bundle and JavaScript workers retry only their host registry, and
each Inspector admission authorizes and closes its own file scope.
Browser providers can share one web-bundle admission.
* test(inspector): gate one admission's file cleanup
The isolation test delayed the first ArtifactResourceScope.retryCleanup
call, so a second call on a shared ElectronFileScope still finished.
Hold first.files.retryCleanup until the other admission's close
finishes, then release and join before restoring the method.
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* docs(apk): clarify rotated signer agreement
* test(mcp): assert bundle path issues by field
compare_bundles reports each relative path as an invalid_format issue
instead of one joined diagnostic sentence.
* fix(javascript): ignore worker frames for a different source job
A failure frame for another job was dequeued as an output error, so a
later caller abort lost the race and was not reported as cancellation.
* test(flutter): assert ABI selector refusals as structured issues
inspect_dart_aot reports the ABI label as an issue on path abi. The
message is the selector contract, without an abi: prefix.
* fix(javascript): check each worker frame condition once
A ready frame is rejected on its own. A non-ready frame for another job
keeps waiting. The following id comparison repeated that skip, so it
never ran.
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Capture one environment snapshot per admitted WABT, JADX, firmware and Wakaru operation. Use it for tool selection, session identity and child launches while preserving configuration updates between operations.
Regressions reproduce changed JVM options under an old session key, mixed engine/limiter selection and environment drift between subprocesses. Keep selected-wrapper and cleanup coverage in a shared fixture with separate scenarios.
Validation: 115 distinct focused tests passed across the final five-file selection, including seven selected-command cases after refactoring. Fresh build, typecheck, lint and formatting passed. Tests use real subprocess fixtures; no real JADX/WABT/Binwalk/Wakaru engine or native Windows verification is claimed.
* feat: add FreeBuff agent support for REA setup
Register FreeBuff as a supported setup client using the shared user
agents directory (~/.agents/mcp.json with mcpServers, skills in
~/.agents/skills), which matches what FreeBuff Desktop loads. Adds the
client definition, boundary tests, supported-agent docs, and the skill
reference client list.
* fix(freebuff): detect FreeBuff from its profile directory, not shared .agents
The ~/.agents marker made FreeBuff appear installed for any home where
REA had installed shared skills (the default skill destination, also
Gemini CLI's), producing false doctor failures. Detect FreeBuff from
its own fixed profile directory ~/.config/freebuff-desktop instead,
and add a regression test covering a home with only the shared agents
skill directory.
* fix(setup): require product evidence for FreeBuff discovery
Address review findings at their producing boundaries and preserve directly affected consumers. Source inspection and git diff --check completed. Tests and automated checks were not run at the user’s explicit request.
* fix(uninstall): retain unverified shared client configuration
* fix(clients): preserve scoped removal evidence
* fix(doctor): omit undefined selectedClientIds under exactOptionalPropertyTypes
Passing selectedClientIds explicitly as undefined fails typecheck on this
branch (TS2379), which blocks the focused test workflow before any test
can run. Spread the option only when defined.
* fix(update): separate ownership evidence from product applicability
rea update's maintenance scope inspected only product applicability
evidence, so when a FreeBuff profile was absent but REA already owned a
version-pinned row in the shared ~/.agents/mcp.json, the plan omitted
freebuff and left the integration stale. FreeBuff now declares its
registration storage as shared, which proves ownership of an owned row
but never product applicability, and maintenance requests ownership
evidence through that declaration instead of reinterpreting the shared
paths. Doctor and setup keep readiness evidence, foreign rows stay out
of maintenance, and the Doctor exactOptionalPropertyTypes fix makes the
focused test workflow runnable.
* test(dotnet): split oversized operand extent diagnostics describe
The describe callback reached 162 lines (max 150), failing
max-lines-per-function and blocking the pre-push check for this branch.
Move the single-case extent scenarios into their own describe; no test
content or order changes.
* fix(update): preserve ZCode's disabled shared registration during maintenance
The shared user agents file doubles as ZCode's fallback, where
`enable: false` disables the registration. Ownership-based maintenance
read that row as a FreeBuff registration, whose format does not
recognize the flag, so the row was selected and the emitted setup
command rewrote it, dropping the flag and silently re-enabling a
registration the user had disabled.
registrationActivation now honors `enable: false` for any client whose
registration storage is shared, because the activation fact binds every
reader of that storage. Maintenance leaves such rows out; doctor
reports them as stale, matching ZCode's own treatment.
* fix(doctor): let explicit client selection authorize the config read
When an ACL or an inaccessible shared parent made every access probe
fail, a client selected by name was omitted before the configuration
read could return its unreadable-config detail, so doctor reported it
as not detected with installation remediation: an unresolved selected
path collapsed to absence.
An explicit selection now authorizes the read outright and the probes
serve automatic discovery only. A selected client with an unreadable
config reports invalid with the read failure; one with no config
reports missing; automatic discovery still probes before inspecting.
* fix(uninstall): share shared-storage checks between ZCode and FreeBuff
clients() queued ~/.agents/mcp.json twice: once as zcode_fallback and once
as freebuff. ZCode has no discoveryPaths, so its strict read still blocked
uninstall on malformed shared text, despite FreeBuff's new retain-and-continue
behavior. For a valid owned entry, ZCode removed it first, so FreeBuff reported
skipped rather than removed.
Make the shared file's checks and removal one shared decision:
- Add zcodeDiscoveryPaths to ZCode so it has its own applicability evidence.
- Gate zcode_fallback push on applicable, not just zcodeFallbackPath presence.
- Report shared storage ownership as one decision for both clients:
FreeBuff and ZCode now use clientOwnershipEvidencePaths together, so a
recognizable REA-owned row proves ownership once for the shared storage, and
both clients report the same result consistently.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(uninstall): merge duplicated host and prove shared ownership from owned rows
Uninstall.ts declared systemUninstallHost twice, preventing module load,
with the exported copy returning only clients and the second copy missing
clientWriteBlocker. Merge into one exported host carrying both blockers.
hasOwnershipEvidence used access() existence, so an unrelated malformed
~/.agents/mcp.json established ownership and blocked every removal.
Ownership now requires a readable, recognizable REA-owned row via the
injected filesystem, so unrelated shared data stays retained.
Also cover ZCode discoveryPaths in its path test.
* fix(uninstall): keep denied product-local configurations fail-closed
Unproven product applicability marked every configuration path of that client unverified, so a denied ZCode profile turned an unreadable product-local config into a retained item: uninstall continued and could report complete with REA still registered. The retain-and-continue exception now applies only to storage REA does not own, classified once by clientSharedRegistrationPaths (shared configuration plus another product's same-scope fallback).
Covers the Greptile P1 on Uninstall.ts. Validation: the new test fails on the pre-fix Uninstall and passes after it; freebuff/zcode/updateMaintenance/bom/dsh suites green; clientLifecycle, clientRegistrationStatus and claudeDesktop keep the same 8 host failures as the pre-merge baseline (symlink EPERM, stale-vs-aligned on Windows).
* fix(update): retain FreeBuff when ZCode reads the shared fallback
Maintenance deduplicated clients on the path each inspection read, so ZCode's fallback view of ~/.agents/mcp.json marked that file "covered" and dropped FreeBuff from the scope. ZCode setup writes ~/.zcode/cli/config.json and deliberately leaves the fallback untouched (docs/client-configuration.md), so the emitted command refreshed only ZCode while the shared row both products load stayed pinned to the old package version. Each setup action rewrites only its own configuration path and no other action rewrites the shared row, so every selected client keeps its own maintenance action; the read-path covered/deduped filter is removed.
Covers the Codex P2 on UpdateMaintenance.ts:104. Validation: the new regression fails on e2fdec384 with {clients:["zcode"]} and passes with {clients:["freebuff","zcode"]}; updateMaintenance 31/31, setupClientConfigCleanupOwnership, cliUpdateAlias, updateOutput, cliStartupImports green; tsc --noEmit, oxlint (0 errors) and oxfmt --check clean; clientRegistrationStatus keeps the same 4 symlink/stale-vs-aligned failures this Windows host has on base e2fdec384 (verified by stashing the change).
🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
* fix(uninstall): preserve completed reads as shared ownership evidence
hasOwnershipEvidence caught every read failure and kept scanning, so a handle-close failure after a successful read — a RegularFileCleanupFailure whose completed outcome still contains the exact shared-file text — was discarded as "no proof". FreeBuff's applicability-unverified storage therefore never got its ownership fact, and once the retained handle blocked later reads, readClientConfiguration downgraded them to retained: inspection passed, removals soft-failed, and runUninstall(true) could purge REA data while the active shared registration remained. The catch now parses the completed outcome for the ownership text while missing or unreadable storage and malformed data keep their proves-nothing semantics, so ownership holds and every later read failure stays blocking.
Covers the Codex P2 on Uninstall.ts:252. Validation: the new regression fails on 4dbfdf1a9 (freebuff reports no blocking failure while the poisoned-scope error lands on claude_code) and passes after; setupClientConfigCleanupOwnership 25/25; the other 21 Uninstall-consumer suites are byte-identical to base 4dbfdf1a9 (61 pre-existing Windows-host failures: symlink EPERM, stale-vs-aligned); tsc --noEmit, oxlint (0 errors, same 6 warnings) and oxfmt --check clean.
🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
* fix(uninstall): keep owned-row proof through removal refusals
hasOwnershipEvidence treated any clientRegistrationRemoval refusal as no ownership: an effective REA-owned rea member shadowed by an earlier foreign duplicate (shadowed_unowned_member), or an owned native row beside a foreign V1 fallback (foreign_legacy_fallback), discarded the already-parsed positive row fact. With FreeBuff unverified and close failures recurring on the preflight/removal rereads, those failures were then downgraded to retained, so runUninstall(true) removed the skill and purged REA data while the active owned row remained. The refusal now carries the owned rows that motivated it — the refusal only refuses the edit — and hasOwnershipEvidence evaluates that fact on both paths; preflight and removal keep refusing the unsafe edit exactly as before.
Covers the Codex P2 on Uninstall.ts:269. Validation: the new regression fails on 225cb214a (freebuff reports no blocking failure while the poisoned-scope error lands on claude_code) and passes after; setupClientConfigCleanupOwnership 26/26; the 21 Uninstall-consumer suites are byte-identical to the recorded 225cb214a baseline (61 pre-existing Windows-host failures: symlink EPERM, stale-vs-aligned); tsc --noEmit, oxlint (0 errors, same 6 warnings) and oxfmt --check clean.
🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
* fix(uninstall): keep unresolved discovery probes from softening shared failures
The discovery probe swallowed every stat failure, so a FreeBuff profile denied with EACCES/EIO was indistinguishable from an absent profile: shared storage was marked applicability-unverified and, when ~/.agents/mcp.json also remained unreadable, the ownership and removal reads softened to retained. runUninstall(true) then removed the skill and purged REA data while an installed FreeBuff could still hold an active registration — the regression even reports complete. Absence (ENOENT) is now the only state that leaves shared paths unverified; any other probe failure leaves applicability unresolved, and shared-config failures stay blocking.
Covers the Codex P2 on Uninstall.ts:318. Validation: the new regression fails on 7572a7082 with status complete and purged data and passes after; freebuffClientConfiguration 13/13; the Uninstall-consumer batches are byte-identical to the recorded baselines (61 pre-existing Windows-host failures: symlink EPERM, stale-vs-aligned); tsc --noEmit, oxlint (0 errors, same warning rules) and oxfmt --check clean.
🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
* fix(uninstall): retain completed configuration reads as removal evidence
A close failure after a completed read discarded the text that read
produced, so an owned registration row the text proves softened to
retained. The completed text now drives removal, keeping shared-config
failures blocking when ownership evidence exists.
Co-Authored-By: Anthropic <noreply@anthropic.com>
* fix(uninstall): stop removal when a cleanup retry leaves a handle unreleased
A completed reread whose handle the cleanup retry cannot release now fails
blockingly instead of serving the text: with no owned row, the soft path
let removeAll purge managed data before close() reported the incomplete
cleanup. The completed text is served only after the retry releases the
handle; an unreleased handle is REA's own failure, never applicability
uncertainty, so it bypasses the retained softening.
Co-Authored-By: Anthropic <noreply@anthropic.com>
* fix(uninstall): keep the ZCode fallback when its profile probe is unresolved
A denied or failed profile probe leaves ZCode's applicability unresolved,
never absent, but the fallback branch dropped the shared row on
applicability alone: with the native config and FreeBuff's profile both
absent, an installed ZCode kept its uninspected registration while
uninstall purged skill and data. Unresolved probes now keep the fallback
in scope with the same fail-closed treatment as other unresolved shared
paths; definitive absence still keeps ZCode out of another product's
primary storage.
Co-Authored-By: Anthropic <noreply@anthropic.com>
* fix(setup): preserve a shared row's enable:false during FreeBuff repair
The shared agents file doubles as ZCode's fallback, so its `enable: false`
binds every reader: doctor now reports the disabled row as stale for
FreeBuff, but following that remediation rebuilt the generic JSON entry
without the flag and silently re-enabled a registration ZCode disabled.
Repairs of shared storage now carry the activation fact forward, while a
client's own native storage keeps its established single-reader repair
contract; the denied-profile uninstall regression also pins the
fallback's new fail-closed inspection beside the denied read.
Co-Authored-By: Anthropic <noreply@anthropic.com>
* test(uninstall): retarget the completed-reread regression to a released retry
The concurrent-writer regression held the reread handle open forever,
which the fail-closed path now serves: it duplicated the unreleased-handle
regression while documenting the opposite contract. The fixture's close
spy gains a failure limit so the cleanup retry releases the handle, and
the test again proves the completed text drives removal of the
concurrently added owned row, with purge verified against the cache
layout purge actually removes.
Co-Authored-By: Anthropic <noreply@anthropic.com>
* fix(doctor): report a preserved shared disable as a manual conflict
Preserving a shared row's enable:false left doctor recommending a setup
run that registrationCurrent correctly treats as already current, so the
scoped doctor returned needs_human forever. The shared-enable
interpretation now has one owner, sharedEnableFlagBinds, used by both
the activation rule and the remediation: a row disabled through the
shared flag reports the manual conflict and states that rea setup will
not change it, instead of an endlessly ineffective repair.
Co-Authored-By: Anthropic <noreply@anthropic.com>
* fix(doctor): keep a native ZCode disable on the setup repair path
The manual-conflict remediation matched a native zcode row through
sharedEnableFlagBinds, but setup drops enable:false on single-reader
storage, so a native disabled registration was told setup would not
change it. The remediation now reads setup's own writer rule,
exported as setupPreservesDisabledActivation: shared storage and the
zcode fallback view keep the manual-conflict message, while a native
row keeps the working rea setup instruction. Regressions pin both
remediations.
🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
* revert: drop the unrelated managed-CIL describe split
The split does not belong to FreeBuff client support and only widens this
PR's diff.
🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
* fix(uninstall): remove the shared agent registration once for both clients
ZCode's ~/.agents/mcp.json fallback and FreeBuff's own configuration queued the
same physical file twice, so ZCode removed the row and FreeBuff then reported
it absent, losing the outcome for the client that owns the file.
Resolve every configuration path to one owner -- the client whose
configuration it is -- and project that single inspection and removal to each
client that loads it. A fallback reader still contributes its discovery probe,
so an installed or unresolved reader keeps the shared file fail-closed.
Discovery also accepted a dangling ~/.config/freebuff-desktop link, which setup
and doctor reject because they follow the target, so an unrelated malformed
shared file blocked every other removal. Resolve the link before treating the
profile as installation evidence, keeping lstat for removal safety.
Also date the FreeBuff release wording against the published 6.7.0 package.
* fix(uninstall): keep a row per client when two clients own one file
OPENCODE_CONFIG can point OpenCode at FreeBuff's configuration file, where
OpenCode writes `mcp.rea` and FreeBuff writes `mcpServers.rea`. Grouping by
filename gave that path a single owner, so uninstall removed only OpenCode's
row, reported that removal for FreeBuff, and could purge managed data with
FreeBuff's registration still active.
Share the decision only through a fallback view of another client's row: every
client that declares the path as its own configuration keeps its own
inspection and removal, and the fallback reader reports each of them.
* fix(clients): preserve discovery and fallback registration identity
Follow product discovery link targets without losing configuration entry
presence or explicitly selected inspections. Associate fallback readers with
the format owner's registration table and project outcomes by owner and path,
so OpenCode removal cannot be reported as a ZCode fallback removal.
All three new boundary regressions fail against the previous source and pass
with the fixes. Validation: check:fast; 217 focused tests passed; the two
changed test files were rerun with 50 passing tests. No installed FreeBuff
client was launched.
---------
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: Codebuff <noreply@codebuff.com>
Separate syntax, semantic uncertainty, examination limits and observed Electron applicability at the static producer, then preserve them through worker, graph and retained/inline summary views. Derive the established parse_status from the same facts and leave historical measurements unknown. Give semantic resource-limit classifications one schema owner.
Replace repeated block-prefix searches and copies with collector-scoped syntax indexes. Keep invocation environments separate, charge indexing/replay to the existing work budget and yield during prefix work. Remove the superseded synchronous collector entrypoint.
Validated producer, worker, CLI/MCP, historical and partial-coverage regressions, plus actual cancellation during indexing. Bounded authored 128/256-call controls preserved all prior facts while replacing repeated search/copy work with one index pass; this is not a throughput or agent-token benchmark.
Return the validated descriptor and its original metadata from regular-file
admission. Propagate that contract through owned reads, hashes, snapshots,
artifact inventory and provider file workflows instead of replacing initial
facts with another stat. Keep arbitrary output-handle operations separate.
Preserve final descriptor/path identity proofs, borrowed-source verification,
BigInt precision, cancellation provenance and failed-close ownership. Remove
the obsolete source and owned-ZIP baseline stages and update their consumers
and regressions. Tie read completion faults to actual reads instead of the
retired duplicate stat; instrument real handles without fake handle wrappers.
Validation: fresh runtime/catalog build; focused source, lifecycle, filesystem,
CLI/MCP and authored provider-fixture tests; full static checks; docs checks;
test discovery; duplication check. Platform-specific cases remain skipped on
macOS. No installed provider or device behavior was verified.
* feat(javascript): link assignment right-hand sides to their writes
A declaration carries its value forward, but a later assignment to a
variable, a property or through a compound operator stopped the forward
trace at the right-hand-side read. The semantic IR now records one
syntactic assignment flow per simple assignment target (ranges, operator,
owning callable), and the graph projection connects each retained read
of the right-hand side to the write occurrence through a defines
relation. Compound assignments also consume the previous value of the
target; the written value itself stays unknown, keeping the boundary of
#4342 intact.
Fixes#6193
* fix(javascript): preserve computed key assignment ownership
* test(javascript): retain nested callback assignment ownership
* docs(javascript): record assignment influence verification
* test(mcp): isolate mocks and acknowledge cancellation boundaries
* test(javascript): retain CLI diagnostics and current-main verification
---------
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Share incremental replacement UTF-8 decoding across web and JavaScript workers, bound content before complete-line allocation and handle split CRLF consistently. Keep named schemas, request versus checkpoint failures, worker reuse and stream cleanup authority in their servers. Cover real server recovery and deterministic byte boundaries.
Preserve load and resolve operations through semantic facts, worker transfer and graph Evidence. Only loads propagate executable ownership. Project ambient member writes and escapes through the shared path- and site-aware mutation owner; retain source literals, bases and uncertainty. Cover ownership and mutation boundaries through CLI and MCP.
Share embedded-map version admission and derive indexed overlap from represented mappings. Carry createRequire filename bases through worker facts and graph identity. Select factory export bindings at each bundler owner.
Validated accepted and malformed source maps through real CLI and stdio MCP codec workflows; verified loader and esbuild graph output against Node runtime controls. Rebased consumer checks passed.
Fixes#6803Fixes#6614Fixes#6798Fixes#6797
Normalize parsed facts at their owning boundaries across PE exports and certificates, ELF section names, GPU bundles, IL2CPP generic types, dyld slice selection, source maps, environment replay, and JavaScript mapped arguments. Preserve partial facts and explicit unsupported cases; clarify the corresponding documentation.
Validation: 831 affected tests passed with one existing skip across 23 files; build, typecheck/lint, documentation, formatting, and 2133-file test discovery passed. Format controls are synthetic; real Unity, GPU, and ARM-device execution is unverified.
Fixes#6709Fixes#6688Fixes#6719Fixes#6718Fixes#6704Fixes#6703Fixes#6692Fixes#6723Fixes#6687Fixes#6726Fixes#6696Fixes#6691Fixes#6727
Use shared owned-file and directory primitives throughout Wakaru discovery,
snapshots, report parsing and publication. Preserve primary read failures and
completed fingerprints when final close fails or receives cancellation.
Retain exact cleanup capabilities before retiring workspaces, block new work
while cleanup is unresolved, and bind error status to the aggregate owner so
partial cleanup and later retry keep resource attribution current.
* fix(javascript): report recovery inputs that collide on a case-insensitive filesystem
* test(javascript): cover a recovery input selected twice on any filesystem
* test(javascript): cover snapshot collision causes and unrelated write failures
* fix(mcp): report Linux-only integrations as unsupported_host off their hosts
Session discovery folded the host check into each optional integration's
enabled flag, so on macOS or Windows the Linux-only packet, signal,
firmware, pwntools, EVM and Wakaru tools reported provider_missing.
Their execution guards refuse those hosts whatever is configured, so
installing a provider there could never make them available.
The server now records, per integration, when the host is outside its
verified host and no service is injected. Discovery checks that before
configuration and reports unsupported_host with the existing
remediation. Injected services and supported hosts behave as before.
Fixes#5730
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(mcp): share provider host checks with session discovery
Discovery restated each Linux-only integration's host rule in
createServer while its provider kept a separate execution check, so the
two could drift apart again. Each provider now exports its host
predicate, uses it in its execution guard, and composition hands the
same predicate to createServer for both the host restriction and the
enabled flag.
Observed host restrictions now also apply when an embedder supplies its
own availability policy, as provider load failures already do, because
no policy lets the default providers pass their host checks.
The MCP regression moves to tests/process-global and emulates darwin
arm64, linux arm64 and linux x64 through the real createServer, so CI on
Linux x64 exercises the unsupported-host branch. It also covers a
configured policy and the matching execution refusals.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(mcp): keep caller host restrictions beside observed ones
The observed host restriction replaced a configured policy's whole
hostUnsupported map. For an injected service the observed value is
false, so a caller's own restriction was lost and the tool was reported
available. Combine both per integration: either the caller or the
observed host can mark it unsupported.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(pcap): expect unsupported_host for packet tools off Linux
The host-independent PATH case asserted provider_missing on every host.
Off Linux the packet tools are unavailable because of the host, so
discovery now reports unsupported_host there; Linux still reports
provider_missing for an unusable PATH.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(process): share paired prlimit ceiling ownership
Route firmware, Wakaru, and pcap paired ceilings through
LinuxResourceLimits without changing their byte or CPU budgets.
Keep EVMole's soft-only limits as a dated architecture-guard exception.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* test(pcap): admit capture limits without host prlimit
The ceiling test only checks the shared argument prefix, so it uses a
temporary executable instead of /usr/bin/prlimit.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* style(pcap): format the capture ceiling test
oxfmt rejected the object literal wrapping in PcapNativeBound.test.ts.
Co-authored-by: morluto <morluto@users.noreply.github.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(windows): report missing native launch controls as unavailable capabilities
An admitted Windows native artifact may predate the optional protocol stdin
or Job Object memory limit controls. WindowsOwnedProcess correctly refused
such launches, but threw a plain Error, so providers projected the refusal
as execution_failure with generic `rea doctor` advice and left the package
remedy in nested diagnostics.
Introduce RuntimeControlUnavailableError as the shared owner of expected
host-control refusals. PrivateRuntimeRootUnavailableError and the new
WindowsNativeControlUnavailableError (which records the missing control)
extend it, and the six provider adapters that hand-built the same
AnalysisCapabilityUnavailableError now project any subtype through one
helper. The refusal still precedes every native launch.
Fixes#6050
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(errors): drop capability imports superseded by the shared helper
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Construct integer formats directly while preserving bounds, refinements, metadata and current shared schema owners. Keep Incur-dependent CLI numeric coercion declarations unchanged.
Verify canonical advertisements, 126 numeric boundary cases, 974 actual CLI parser cases, broad source tests and real public-artifact SDK workflows. Record 72 normal tasks and 12 separate owned-inspector heap diagnostics with whole-family resource bounds; distinguish SDK spans and asymmetric audit overhead. Generate numerical report sections from receipts and reject stale tables through documentation conformance checks.
Closes#6236. Current-head CI and Greptile pass; actionable review findings are addressed. Codex review was unavailable due repository usage limits.
* fix(browser): name web-bundle budgets and recover web deadlines
Name the existing heap, per-script, and total web-bundle phases, and reject a per-script deadline above the total. Promote capture, CDP command, source-map decode, and source-map fetch deadlines at today's defaults. Name DevTools timeoutMs, and state that discovery, cleanup grace, byte budgets, and Electron hook retention have no runtime override.
Refs #5910
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(browser): apply selected web deadlines to the owning phase
Keep HTTP and browser-socket discovery on the fixed discovery deadline so a
short command_timeout_ms starts at the handshake. Apply scenario
command_timeout_ms to launch startup and the primary connect session, and
keep service-worker restoration on the fixed 5000 ms grace. Omit
command_timeout_ms from recovery text when the operation does not accept it.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(browser): retain scenario commands that finish after their deadline
A timed-out scenario command stays owned so cleanup can close a late
browser or context and restore a mutation that lands after the deadline.
Child storage replies use that deadline, scenario recovery names
command_timeout_ms in the capture JSON, and the session test connection
implements beginCleanupGrace.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(browser): keep child command timeouts as the public failure
A nested command such as Page.enable that is delivered but never answered
was stored as protocol_error, hiding the command name, selected deadline,
and recovery. Store the typed timeout and assert that public error.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(browser): keep runtime cleanup on the fixed grace
Switch runtime restoration to the cleanup grace before the first send so a
short command_timeout_ms cannot fail an otherwise successful observation.
Stop advertising command_timeout_ms on list_browser_targets, which never
bounds a post-discovery command.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* test(browser): prove a short command deadline cannot fail runtime cleanup
Drive restoration through the runtime fixture. A cleanup command that
outlives command_timeout_ms still succeeds, and a stalled restoration
names the fixed 5000 ms grace.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(browser): name the effective source-map decode deadline
codecBudgetLimitation reported a fixed 20-second deadline after a
caller selected decode_timeout_ms. Result and Evidence limitations
now name that effective millisecond deadline.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(browser): separate handshake and target-attach deadlines
A browser-level Target.attachToTarget no longer shares the WebSocket
handshake budget. Blocked service-worker attachment keeps discovery on
its fixed deadline and applies command_timeout_ms to the later handshake
and attach.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(browser): name the web-bundle resource each runtime exhausts
Bun ignores the V8 old-space flag. A Windows Job reports the process
commit limit, and other Bun hosts no longer suggest raising max_heap_mb.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(browser): cite the browser-socket discovery message budget
WebSocket discovery enforces the 64 MiB protocol budget. Timeout
recovery no longer advertises the 8 MiB HTTP document budget.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(browser): bound the blocked service-worker check before discovery
The first registration check has its own fixed 10s deadline. Discovery,
handshake, and Target.attachToTarget stay on their separate deadlines.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(browser): name the operand that stopped web-bundle admission
Host heap pressure no longer claims the fixed result budget is exhausted.
A Windows Bun allocation before the commit limit still names that limit.
Co-authored-by: morluto <morluto@users.noreply.github.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>