Convert native directory separators only at Git patch argument production. Exercise fresh, applied and invalid dependency patches in private copies, preserving protectNTFS, and select the regression for Windows CI.
Replace the spelling-based mock inventory with one binding-aware Oxlint rule. Canonical test projects own isolation for both Vitest and lint; external temporary CLI probes avoid concurrent test discovery.
Validated actual local Git and Oxlint execution, resolved-policy parity, CI selection and report tests. Native Windows verification remains with CI. Refs: #7050
* 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>
* fix(reconstruction): dedupe residual unknown ids with uniqueSorted
Current main calls uniqueBy, which is not defined, so typecheck fails.
Residual unknown ids are strings, and the adjacent lists already use
uniqueSorted.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* feat(config): make the bridge request ceiling configurable
REA_BRIDGE_MAX_REQUEST_BYTES replaces the hard-coded 16 MiB Hopper and
Cutter request payload ceiling. The default stays 16777216 bytes. Values
outside 7464 to 268435456 bytes are configuration_invalid.
Part of #6176.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(cutter): keep cleanup ownership when a sent command's reply is oversized
An authenticated command may already have changed the Cutter document
when its reply exceeds the frame ceiling. Return the existing unknown
execution, with the ceiling diagnostic in the message, so receipt
cleanup still waits. A frame that overflows before the command is sent
remains a resource constraint.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* style: format the bridge request ceiling sources
oxfmt --check failed on the five files that set and test
REA_BRIDGE_MAX_REQUEST_BYTES. Formatting only; an oversized Cutter
reply still stays an unknown execution.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(cutter): exclude the LF from the response frame budget
REA_BRIDGE_MAX_REQUEST_BYTES counts payload bytes. The Cutter response
reader and authenticated encoder were reserving one byte for the
terminating LF, so an exact-limit response was rejected. A reply that
exceeds the ceiling after the command was sent still stays an unknown
execution.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(bridge): measure escaped JSON before allocating the request
A command of U+0001 characters can expand sixfold. JSON.stringify of
that expansion can throw past Node's string ceiling before the payload
check. Count the escaped size within REA_BRIDGE_MAX_REQUEST_BYTES
first and refuse it as a resource constraint.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(config): derive the bridge request maximum from JSON expansion
A 256 MiB ceiling still lets a shorter U+0001 command expand past Node's
536870888-character string limit. The maximum is now
floor((536870888 - 296) / 7) = 76695798, the longest such command whose
authenticated frame fits in one string. Requests are still measured
before JSON.stringify.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(bridge): size the Cutter frame deadline and send the measured Hopper payload
The authenticated Cutter command is encoded after the challenge, so a
one-second read rejected an in-budget frame. That read now allows one
second per mebibyte of the ceiling and never waits longer than 25
seconds. Hello stays at one second. Hopper writes the payload it already
measured instead of serializing the same request again.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(config): bound the bridge request maximum by the serialized string
The ceiling already measures escaped JSON, so dividing Node's string limit by the seven-byte expansion rejected encoded payloads that still fit. The maximum is 536870887, one byte under that string ceiling, leaving room for the framing LF.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(hopper): serialize a bridge request when it reaches the wire
The queue kept each encoded frame, plus the caller's params, until Hopper finished the active request. A raised ceiling made a few waiting calls enough to exhaust the heap. The FIFO now keeps the params, and the frame is encoded only for the request being written.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(cutter): hash the bridge proof prefix and payload separately
An exact-limit Cutter frame plus the HMAC prefix exceeds Node's single-string ceiling, so the client threw before sending an admitted command. The prefix and payload are now separate HMAC updates, including the response proof.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(cutter): keep recovery fields when a status path exceeds the frame
A long current_file made the status reply miss the ceiling, and the fallback then dropped session_id and the completion receipts. The status now omits the path and version and still returns the session, connection proof, and up to 64 receipts. That required recovery frame is smaller than the 7464 floor.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(cutter): report an unknown path when status identity does not fit
A bounded status kept the new document generation and omitted the path, so the client filled in the descriptor's older path. The observed path is sent when it fits. When it does not, current_file is null and is not replaced with that stale path.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(cutter): count structured replies by their encoded JSON size
The response guard charged 16 bytes per primitive and two bytes per list slot, so a dense array under the configured ceiling was replaced with output_truncated. Numbers, booleans, null, and container punctuation now use their JSON lengths.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(cutter): stream authenticated responses in bounded chunks
A fitting reply was signed from retained raw bytes, escaped bytes, and a
joined frame, so a ceiling near 512 MiB could exhaust Cutter before send.
Measure and sign JSON pieces, then write the same frame in 64 KiB chunks.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(bridge): keep Cutter admission from stalling or hiding sessions
Read an unauthenticated frame off the accept loop. A command reply that
does not fit keeps completion and generation and reports an oversized path
as null. Discovery reports a ceiling mismatch instead of an absent session.
The maximum HMAC proof is opt-in, and both bridges reject non-ASCII digits.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(cutter): bound frame scans and client response copies
Search only newly read bytes for the framing LF. Unescape each socket
chunk into one response string, check the proof, and then parse it.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(cutter): keep completion, admission, and dense replies bounded
Report completed_connection only through connections that have
terminated. Cap connection threads and keep the listener up if one
fails to start. Batch scalar JSON and fail discovery when any ceiling
mismatches.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(cutter): hash requests in parts and scan escapes once
Update the client-proof prefix and request separately. Stop the response
decoder at the first quote or backslash instead of rescanning the tail.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(cutter): confirm live ceiling mismatches and omitted output
A stale descriptor from a previous ceiling is not a discovery mismatch
until its hello proves a live authenticated bridge. A response discarded
for the frame ceiling after dispatch reports output_truncated.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* test(cutter): close the unauthenticated ceiling-mismatch fixture
The listener that fails the hello proof is destroyed after its challenge
so discovery cleanup does not wait on that socket.
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(mcp): escalate transient failures before asking for a restart
Give dropped connections and startup failures one bounded retry, then a
scripted handoff to the user. Point timeout recovery at a named request
field or REA_* setting instead of telling agents those limits are fixed.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(process): stop unexpected command failures from recommending a retry
The catch can already have launched the target, and the projection stays
non-retryable. Tell the user to check the inputs and run doctor instead.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(mcp): limit retries to safe calls and recommended settings
A dropped connection may already have changed the target, and a bad
catalog rejects the same startup every time. Retry only a repeatable
call, and change a setting only when the remediation recommends it.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* test(mcp): match recovery guidance across wrapped lines
Startup handoff capitalization and markdown wrapping still carry the
same sentences. Compare the prose with whitespace collapsed.
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>
* feat(python): inspect CPython pyc headers and marshal code objects
Add inspect_python_pyc / inspect-python-pyc to read one explicit local
CPython 3.7–3.13 .pyc without executing bytecode or recovering source.
* chore(python): drop unused PythonPycHeader export
Knip reported the type as unused after inspect_python_pyc landed.
* fix(python): bound pyc expansion and decode marshal like CPython
- Count a nested code object reached through TYPE_REF once per copy the
report carries, against max_objects and max_file_bytes, before counting
or validating the tree
- Charge long digits to max_string_bytes, reject out-of-range and
unnormalized digits, build the value in one pass, and report integers
above 256 bits by bit length only
- Decode TYPE_UNICODE with surrogatepass semantics and reject other
ill-formed UTF-8
- Map only 3.11 magics 3494-3495 to the py311 layout
- Report non-finite float and complex parts as inf, -inf or nan
- Allow an empty co_filename
- Require bytes for co_linetable and co_exceptiontable
- Bind cleanup-failure errors to their retained descriptor leases
* fix(python): list pyc code objects once instead of a recursive tree
Report each distinct code object once in code_objects, top-level first,
with nested_code as indexes. A child shared through TYPE_REF is no longer
copied per reference, and the MCP output schema is no longer recursive.
Names repeated through TYPE_REF still count against max_file_bytes for
each copy the report carries.
* fix(python): bound shared pyc constants and reject malformed tables
- Cache byte-string digests so a buffer shared through TYPE_REF is
hashed once instead of on every reference.
- Charge every reported co_consts entry, including tables shared
through TYPE_REF, against max_objects before summaries are built.
- Resolve the inspect-python-pyc path with absoluteCallerPath so
link/../file.pyc reads the file the filesystem selects.
- Reject TYPE_NULL inside marshal sequences, as CPython does.
- Reject a co_localspluskinds length that does not match
co_localsplusnames in the parser and the report schema.
* fix(python): bound shared pyc names and read CPython marshal graphs
Charge each reported code-constant name, keep integer bit lengths on the
decoded value, and list code objects nested inside constant containers.
Accept self-referential lists and dicts, marshal version 0 text floats,
empty code names, the original string byte count, and Python set and dict
lengths. Pass the CLI cancellation signal into command cleanup.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(python): bound pyc key expansion and shared nested code
Charge set and dictionary keys before a shared tuple doubles them, list each
nested code object once per owner, and accept code objects as CPython keys.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(python): correct pyc equality, counts, and nested walks
Summarize code objects only after the marshal graph is complete, and
collect nested code with an iterative walk that shares wrapper results
instead of copying every descendant list. Keep tuple boundaries and the
original string bytes in equality keys, and reject negative CPython counts.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(python): bound shared pyc names and keep the first dict key
Charge every copied name-table entry against the object budget before
building the report array, including empty strings that add no bytes.
When dictionary keys compare equal, keep the first key object and
replace only its value, matching CPython.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(python): walk each pyc dictionary child list once
Keep a container's child array on the nested-code frame so a wide
dictionary is not copied on every step of the synchronous marshal walk.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(python): reuse stored pyc dictionary children when combining
The nested walk keeps each container's child list on its frame.
Combining nested code rebuilt that list, and the 8,000-key regression
still accepted the old per-key copy. Use the stored list, and require
that dictionary to finish well under the copy's runtime while still
reporting a nested code object.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(python): keep distinct pyc code objects and reject corrupt ones
Encode each name table's length and entry boundaries in the equality
key so a different name list cannot share a memo key. Walk tuple and
frozenset keys on an explicit stack so a long TYPE_REF chain does not
overflow. Treat code objects CPython rejects for an odd co_code or an
undersized local table as malformed instead of complete coverage.
Co-authored-by: morluto <morluto@users.noreply.github.com>
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
* feat(erlang): inspect BEAM IFF chunks and tables
Replay the Erlang BEAM inspection workflow, including table bounds,
OTP 28+ atom layouts, the shared absolute-path policy, and empty-path
CLI coverage, without carrying GitHub workflow edits.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(erlang): use publicInputStrictObject for BEAM tool input
inspect_erlang_beam advertised a public input built with bare
z.strictObject, so later shared input-policy changes would miss it.
Result and internal objects stay on their own constructors.
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>
* feat(config): make the regex matching deadline configurable
REA_REGEX_MATCHING_DEADLINE_MS defaults to 5000 ms and refuses values
outside 1..2147483647. Recovery and capability text name the effective
deadline, its source, and how to change the setting.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(setup): preserve the regex matching deadline in registrations
Setup validated REA_REGEX_MATCHING_DEADLINE_MS but left it out of the
selected registration environment, so a caller override never reached
the launched server and matching fell back to 5000 ms.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* test(config): restore a stubbed regex matching deadline on failure
Kuna deadline assertions now unstub the environment in finally, so a
thrown construction or expectation cannot leave the setting stubbed.
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(android): name the JADX deadline and recover apktool decode
JADX operation timeouts now name REA_JADX_OPERATION_TIMEOUT_MS, the
effective milliseconds, the 1..2147483647 range, and that a change applies
on the next process start. Apktool decode accepts decode_timeout_ms,
omitted means 600000, and a timeout names that key. ADB deadlines and
apktool and Java version probes stay fixed and say there is no runtime
override.
Refs #5910
Co-authored-by: morluto <morluto@users.noreply.github.com>
* fix(android): derive capture recovery from the fixed allowance
Main now stores a fixed allowance instead of a prebuilt remediation
string. Apktool and adb capture refusals keep the no-runtime-override
sentence in that allowance name, including that decode_timeout_ms does
not raise the apktool output cap.
Co-authored-by: morluto <morluto@users.noreply.github.com>
* test(apktool): observe a real decode deadline and process cleanup
A hanging interpreter launcher and its pipe-holding child stay alive
until decode_timeout_ms elapses. The provider then reports
provider_timeout with completed cleanup, and both processes are gone.
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>
Refuse oversized database and WAL inputs before acquisition with exact observed bytes and export guidance. Keep initial path failures separate from file-set changes and retain cleanup and partial observations on late growth.
Refs #4208, #4188, #4141, #4127
Co-authored-by: hima <1ep23ic023@eastpoint.ac.in>
Co-authored-by: Royce <roycelam@umich.edu>
* perf(ci): start source feedback early and diagnose stalled runs
* fix(ci): verify workflow identities before main comparison limits
* fix(ci): preserve diagnostics across passing checks and install failures
* fix(ci): preserve ambiguous workflow run ordering
* fix(ci): preserve failure-report candidate and request budgets
* fix(ci): retain candidate errors while checking later main evidence
* fix(ci): retain partial reports and require complete health scans
* test(ci): prune stale fixtures and duplicated assumptions