Commit Graph
43 Commits
Author SHA1 Message Date
morluto 599a8ee11d fix(process): preserve cleanup ownership and normalize captures once
Retain unresolved process identity and launch evidence through retryable cleanup. Share capture path normalization and preserve failed filesystem observations. Bound child output and drain Windows pipes without one-chunk throttling.

Reviewed fixes include #1628, #2632, #2644, #2784, #2928, #2931, #2965, #2992, and #3011.

Validation: 92 focused source tests passed; four platform-specific skips. Real Windows and Hopper lifecycle coverage was not rerun.
2026-10-14 08:19:07 +08:00
Kaoru0822andClaude Opus 5.5 ce748be2f3 fix(process): order interaction differences by their dispatch time (#2739)
* fix(process): order interaction differences by their dispatch time

first_divergence ranks candidate differences by the earliest recorded
time of the differing observations, but eventTime read only `at_ms`.
Interaction events record their time as `dispatched_at_ms`
(and `scheduled_at_ms`), so a changed interaction always ranked as
untimed. An interaction outcome that differed at 6 ms therefore lost to
a process sample that differed at 500 ms.

Give each comparison dimension its recorded time field. Interactions use
the dispatch time, when their outcome was observed; the other
dimensions keep `at_ms`. An earlier process difference still wins.

Fixes #2645

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(process): require ordered interaction dispatch times in captures

Comparison ranks a changed interaction by its dispatch time, while
firstCollectionDivergence returns the first differing interaction by
sequence. The capture parser checked only that interaction sequences are
contiguous, so an imported capture whose dispatch times decrease could
make that first-by-sequence difference later than another differing
interaction.

Interactions are dispatched in sequence and their times come from the
monotonic capture clock, so require non-decreasing dispatch times at
parsing, as frames, rendered frames, process samples and filesystem
checkpoints already require for their timestamps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 07:02:28 -07:00
morluto a0317cf732 fix(ci): align FAT fixtures and consolidate duplicated workflow helpers
Declare the synthetic 4 KiB Mach-O slice alignment accurately while preserving the IDA thinning scenario. Share web cleanup aggregation and process-trace fixture facts instead of duplicating them across consumers and tests; keep the 3% duplication threshold unchanged.

Validation: npm run check:ci, test discovery, and 42 focused IDA, process-trace, web workflow and cleanup boundary tests. Duplication falls from 3.01% to 2.99%.
2026-10-13 16:16:31 +08:00
morluto e802441bce Merge remote-tracking branch 'origin/main' 2026-10-13 15:12:34 +08:00
morluto 9049dbaf0c fix(process): preserve monotonic capture timing and observed wall dates 2026-10-13 15:12:08 +08:00
Rudy Mizrahi Celekli b9ee921560 fix(process): preserve nested path identities during normalization (#2468) 2026-10-13 15:54:18 +09:00
吴佳浩Albenand吴佳浩 2c6a4fac4f fix(process): accept a trace identifier the comparison result can represent (#2488)
The trace specification owns the declared identifier vocabulary and the
comparison result echoes those identifiers verbatim into raw_trace[].event_id,
matched_variant and diagnostic event_ids. The result module restated the shared
IDENTIFIER_PATTERN by hand with a 64-character cap, so a specification with a
longer identifier validated and then its own comparison result failed to parse:
compareProcessTraces threw a raw ZodError at the caller instead of returning a
comparison.

Export the identifier schema from the specification as the single owner and
reuse it in the evaluation module, removing the capped copy. IDENTIFIER_PATTERN
has no length bound and every other consumer uses it unbounded, so the
duplicate was the outlier. Removing the bound rather than adding one keeps the
advertised trace_spec input contract unchanged; identifiers of 64 characters or
fewer behave exactly as before.

Verified with 48 process tests, 24 boundary CLI/MCP trace tests, check:fast and
verify:test-discovery on macOS arm64. The regression test failed with the
ZodError before the change and passes after it.

Co-authored-by: 吴佳浩 <wujiahao@supremind.com>
2026-10-13 14:48:26 +08:00
morluto 63e796d50e fix(process): bound retained trace ordering state
Prove total orders with Kahn traversal and use ranks; stream forward and reverse reachability for general partial orders instead of retaining every closure. Aggregate unordered conflicts by declaration while preserving missing-pair counts and independent malformed-input diagnostics.

Validation: 33 focused trace domain and CLI/MCP boundary tests passed. Six bounded Flameox executions preserved answer digests and cycle rejection; combined median peak RSS fell from 391.13 to 127.72 MiB. General partial-order traversal costs more CPU; the experiment records that tradeoff. Full suite and real-provider lanes were not run.
2026-10-13 13:17:44 +08:00
morluto 10935b7b11 fix(process): reject deep trace cycles without recursive expansion
Use iterative cycle detection, memoized reachability and compact unordered-group membership. Preserve declaration diagnostics on cyclic input while skipping checks requiring a valid partial order. Report duplicate group declarations once instead of repeating pair errors.

Replace redundant source cycle/missing-pair assertions with public CLI/MCP coverage including 6000 events, dense not-before constraints and a large unordered group. Validate acyclic branching and mixed relation semantics. Document bounded Flameox CPU/latency gains and higher observed peak memory; agent/model costs remain unmeasured.
2026-10-13 13:00:39 +08:00
Ysopwnable 857a1b7b04 fix(process): aggregate incomplete trace-spec diagnostics
Summarize incomplete trace-specification pair declarations with exact counts and the first undeclared pair. Preserve complete pair coverage, successful Evidence and independent validation errors; remove temporary pair-scan copies and sorting.

Closes #1753.
2026-10-11 16:04:46 +08:00
Kaoru0822andClaude Opus 5.5 0ecf3f2438 perf(mcp): keep Playwright and type-only imports off MCP startup (#1691)
* fix(build): emit no runtime imports for type-only bindings

Under verbatimModuleSyntax, an import whose specifiers all carry inline
`type` modifiers compiles to `import {} from "..."`, a side-effect import
that still resolves and evaluates the module. 78 compiled modules carried
one, including `import {} from "playwright-core"` in the browser scenario
session, which loaded Playwright's module graph at MCP startup.

Use top-level `import type` for these bindings and enable oxlint's
typescript/no-import-type-side-effects rule so the pattern cannot return.

Refs #1685

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* perf(mcp): load Playwright when a scenario launches, not at startup

The browser scenario and Electron active providers are constructed before
the stdio server serves, and both bound Playwright's launchers at module
load. Resolve `chromium` and `_electron` from playwright-core when a
capture opens instead, as the web module resolver already does.

MCP startup now resolves 1,312 modules (4,902 resolutions) instead of
1,598 (6,076) before reading the first request, and no longer loads
playwright-core. Provider construction, the tool catalog, and capability
inventory are unchanged.

A boundary test spawns the stdio server, initializes, lists tools, and
asserts playwright-core and isomorphic-git were not resolved; the CLI
probe now exercises the real launch path to prove detection.

Closes #1685

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 21:04:05 -07:00
c1efa6467d feat(process): bound a finalization interval before forced capture timeout
Add optional finalization_ms to keep observing a captured root after SIGTERM, record the actual finalizer exit and each signal attempt, and escalate once when needed. Bind the initial root identity to captured ownership and preserve observations through cleanup uncertainty.

Fixes #1253.

Co-authored-by: Mykola Dementiev <16836724+nikolay-dementiev@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-11 09:55:43 +08:00
morluto f9ea9a9268 fix(process)!: bound terminal buffers before capture
Validate columns × (rows + scrollback) against a 1,000,000-cell xterm working-buffer budget, including every resize with the selected scrollback. Document the budget in the advertised MCP input and process-capture guide; never clamp caller dimensions.

Validation: default/exact-boundary schema cases, prelaunch MCP rejection, compiled CLI capture, terminal rendering, normalization, cancellation, and lifecycle checks pass on macOS. This is resource admission, not a measured serializer throughput improvement; Linux-only and real deep-analysis providers were not exercised.

BREAKING CHANGE: process scenarios whose initial or resized terminal exceeds 1,000,000 combined visible-plus-scrollback cells are now rejected before launch.
2026-10-11 03:19:29 +08:00
N0zoM1z0 2b6f14f528 fix(process)!: version literal scenario replacement semantics
Keep caller-selected replacement text literal with a callback, preserving
empty-search positions instead of changing their split/join behavior.
Commit the replacement interpretation for captures using custom patterns so
legacy records cannot report this producer correction as a target change.

BREAKING CHANGE: Captures with custom normalization patterns use
literal-replacements-v1 and cannot be compared with legacy unversioned
pattern captures. Capture both sides with the same replacement semantics;
legacy captures remain readable and captures without patterns are unaffected.
2026-10-10 16:57:06 +08:00
Kaoru0822andClaude Opus 5.5 2781cad201 perf(process): stop padding rendered terminal lines to full width (#1450)
Rendered frames padded every visible row with trailing spaces to the
terminal width. Blank rows cost a full row each and every frame repeats
them, so the padding made up 14-39% of capture Evidence (2 KB of sparse
output produced 228 KB). The padding carried no information: columns is
recorded and serialized_state keeps the exact terminal state.

Lines are now trimmed after normalization, so line.padEnd(columns)
restores the previous value. The comparison contract commits
rendered_line_format so older padded captures do not compare as the
same contract.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 23:18:13 -07:00
morluto 415145d04f fix(process)!: retain per-file digest open failures
BREAKING CHANGE: Filesystem digest omission entries now require system_code; budget and changed-file omissions use null, and unavailable-file omissions preserve the operating-system error code.
2026-10-10 03:52:35 +08:00
yi111andYi-111-a 3f59a84bd1 fix(contracts): advertise NUL with a portable hex escape
Use the equivalent hex NUL spelling in named public contracts while preserving current path and reserved-name validation. Verify converted JSON Schema and real stdio catalog consumers.

Closes #1329

Co-authored-by: Yi-111-a <97448247+Yi-111-a@users.noreply.github.com>
2026-10-10 01:54:42 +08:00
morluto 070339af50 refactor(process): remove duplicate observation and trace entry points 2026-10-10 00:49:14 +08:00
morluto 3283a45d09 refactor(captures)!: require canonical producer metadata
Require process retention accounting, browser network transaction identity, and all web comparison dimensions. Remove obsolete omission repairs and derive completeness from the owning producer facts.

BREAKING CHANGE: Historical captures without current producer accounting or transaction identity, and web diffs missing accessibility or storage dimensions, are rejected.
2026-10-09 23:35:19 +08:00
Kaoru0822 1f099a6fc0 Merge pull request #1299 from morluto/fix/schema-patterns-without-lookaround
fix(mcp): advertise input patterns without look-around
2026-10-09 07:58:51 -07:00
Kaoru0822andClaude Opus 5.5 a8701eaf48 fix(mcp): advertise input patterns without look-around
trace_dylib_resolution roots and capture_process_scenario environment
names still advertised negative look-ahead patterns. RE2 and Rust schema
validators reject look-around, so a client using one refuses the whole
tools request, as #1282 reported for the NUL escape. Spell both
constraints as equivalent look-around-free patterns and assert that no
advertised pattern uses look-around or backreferences.

Closes #1282

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:49:22 +00:00
morluto ad59531a96 refactor: remove forwarding exports and redundant aliases 2026-10-09 22:46:09 +08:00
Kaoru0822 098d76900e Merge pull request #1291 from morluto/fix/process-port-normalization-sentence-period
fix(process): normalize ports that end a sentence
2026-10-09 07:34:54 -07:00
Kaoru0822andClaude Opus 5.5 39eb0587c9 fix(process): validate terminal byte totals against retained frames
parseProcessCapture accepted terminal retention accounting that its
retained frames contradict: any retained_bytes within budget, and
observed_bytes above retained_bytes with no omitted frame. A malformed
capture could therefore report truncated: false while its terminal
evidence was incomplete. Recompute retained raw and rendered bytes from
the frames, and require equal observed and retained bytes when no frame
was omitted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:12:05 +00:00
Kaoru0822andClaude Opus 5.5 db98a51dd1 fix(process): normalize ports that end a sentence
Contextual port normalization refused any port followed by a period, so
common log lines such as "Listening on port: 8080." or
"http://localhost:8080." kept their run-specific port and equivalent
captures compared as changed. Accept a sentence-ending period while
still refusing a period that continues a decimal, version, or host name,
and bump the committed port-normalization version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:06:41 +00:00
Ysopwnable 33bf585185 fix(process): localize capture truncation diagnostics (#1284)
Report per-source capture coverage and existing file-hash omissions while preserving comparable observations in unaffected dimensions. Keep legacy truncated captures conservative and retain known partial trace events.

Closes #1250
Partially addresses #1251; independent hashing remains out of scope.
2026-10-09 21:56:43 +08:00
morluto 5eb0049a9f fix(process): retain known events from incomplete captures 2026-10-09 21:01:52 +08:00
morluto b71a591a60 test: consolidate redundant assertions into boundary workflows
Remove getter, enum, cloned-projection, cache-identity, and obsolete profile assertions along with the shadow JSON Schema engine and dead test-only APIs. Retain producer, filesystem, SDK, lifecycle, integrity, and malformed-format coverage.

Document the priority of real end-to-end workflows, boundary integration, and producer goldens.
2026-10-09 20:26:46 +08:00
morluto 2a7746998d fix(process)!: require current captures and preserve cleanup failures
Remove v3 capture conversion and require explicit executable identity and event journals. Preserve cancellation, execution diagnostics, snapshots, and cleanup outcomes from preparation through CLI delivery.
2026-10-09 20:12:07 +08:00
Ysopwnable c8544b1574 fix(process): preserve unknown filesystem absence in partial captures
Separate exhausted path enumeration from hash coverage and preserve known
effects outside incomplete roots or unfollowed symlink subtrees. Return
explicit unknown effects through capture Evidence and comparison workflows.

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-09 12:09:24 +00:00
N0zoM1z0 00d8e44cbf fix(process): preserve numeric output and original PTY evidence 2026-10-09 17:55:28 +08:00
Ysopwnable aa5750c263 fix(mcp): emit portable Unicode NUL patterns (#1230)
Preserve NUL rejection while avoiding the short escape rejected by strict
schema consumers. Guard the entire advertised input/output catalog and all
three JavaScript regexp modes.

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-09 17:18:17 +08:00
morlutoandfelipeatp 954badbaaa refactor(schemas): share portable identifier and base64 patterns (#1227)
* refactor(schemas): share identifier and canonical base64 patterns

* test: hold the offset datetime schema to the validator it replaces

The module documents that its accepted set matches z.string().datetime({ offset: true }), and nothing in the suite checked that claim. Adds table-driven accept and reject cases (leap years including the 1900/2000 century pair, month, day, hour and offset ranges, fractional and omitted seconds, missing offset, basic format) plus a differential assertion that classifies every case exactly as the replaced validator does, and asserts the emitted pattern compiles under u and v while the replaced pattern does not compile under v.

---------

Co-authored-by: felipeatp <felipe.troncosopt@gmail.com>
2026-10-09 16:47:09 +08:00
felipeatp f0da05f67f fix: emit v-mode-compatible patterns for tool schemas (#1220)
* fix: emit v-mode-compatible patterns for tool schemas

Character classes in emitted patterns carried unescaped '-', '/' and '['. Annex-B and u-mode accept them, so REA's own Zod validation (u) and every u-based validator never saw a defect, but v-mode rejects ClassSetSyntaxCharacters and Ruby rejects [^s[]]. With 6.1.0 tools/list, 117 pattern fields across 11 tools were rejected under v.

The characters are escaped as \x2d, \x2f, \x5b and \x5d rather than \-/\//\[, because oxlint --fix removes an escaped '-' inside a character class as a useless escape, so an escape-only change does not survive the pre-commit hook. \x2d-style escapes are valid under Annex B, u and v, are matched identically, and are not useless-escape candidates.

22 pattern literals in 18 files are touched; no other token changes.

* fix: replace the Zod offset pattern and guard the advertised catalog

The offset datetime site projected Zod's offset class as [ +- ], which no escape in this repository's sources can reach, so evaluate_reconstruction_coverage stayed unreachable for exactly the clients this change targets. It now uses offsetDateTimeSchema in src/domain/offsetDateTime.ts: the same accepted set with the offset class escaped as [ +\x2d ].

Adds tests/boundary/mcp/advertisedPatternsVMode.test.ts, which performs the real tools/list projection, traverses every advertised input and output schema, compiles each pattern under v, and asserts the inventory it walked so a silent traversal collapse fails instead of passing vacuously.
2026-10-09 16:20:57 +08:00
morluto 70e8a8f860 fix(contracts): preserve local inputs and comparison uncertainty 2026-10-09 06:49:02 +08:00
morluto 5945915f91 test: prune redundant cases and promote configuration lifecycle coverage 2026-10-09 02:58:03 +08:00
Kaoru0822andClaude Opus 5.5 eb69763d27 fix(process): name the reason two captures cannot be compared (#1080)
* fix(process): name the reason two captures cannot be compared

compare-process-captures rejected captures whose comparison contracts
differ, but the reason never reached the caller. The CLI printed
"Process command could not complete... run `rea doctor`". MCP wrapped
the error in an AnalysisInputError with no issues ("Analysis input is
invalid. Check the arguments"). A stale capture under
max_capture_age_ms got the same treatment.

Throw typed input issues that name the differing contract fields, or
the stale side with its completion time and age, and let
runDerivedOperation pass AnalysisInputError through unchanged. Document
what the comparison contract covers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(process): report CLI trace-spec issues under the MCP input path

The CLI reported an invalid trace specification under operation
"compare-process-captures" with root-relative issue paths such as
["events"]. MCP reports the same input as compare_process_captures with
paths under trace_spec. Use the canonical operation name and prefix
trace_spec so both surfaces describe the same input identically.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(process): name the side and constraint for unusable capture Evidence

Adjacent compare_process_captures failures still lost their reason.
Over MCP, Evidence from another workflow, tampered Evidence and an
invalid capture result all became "Evidence is invalid or has changed".
The CLI said only "Capture evidence is malformed".

Parse each side separately. Evidence from another workflow is an input
issue on left or right that names the operation and predicate it has.
Tampered Evidence and invalid capture results stay integrity
mismatches, and their message now carries the validation detail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 00:04:35 +08:00
morluto 2af12a18a3 fix(process): preserve observations after successful cleanup 2026-10-08 23:29:43 +08:00
muhammad-luayandN0zoM1z0 5547c1e697 fix(process): stop failing captures on tokens macOS cannot expose (#1057)
* fix(process): stop failing captures on tokens macOS cannot expose

On a busy macOS 26 host the residual process sweep fails every capture:
KERN_PROCARGS2 omits the environment of Apple platform binaries for any
caller and fails with EINVAL for processes owned by another account, so an
unrelated process created after the capture baseline escalates to a hard
cleanup failure with cleanup_incomplete.

Report environment withholding distinctly from the Darwin token reader by
reading the platform-binary flag through csops, carry the effective uid in
the process table, and re-read unresolved tokens with a bounded retry plus a
final liveness confirmation so transient exec and exit states settle.
Candidates whose token the OS provably withholds, foreign-uid candidates,
and candidates that exited during validation are now recorded as unverified
processes instead of failing an otherwise clean capture or being signaled.
Related candidates and every other unreadable candidate stay fail-closed.

* test(process): align ownership lanes with the uid-aware process table

The Darwin sweep reads the effective uid through ps, so the offline
verification lanes' syscall allowlists must accept the new argv in
verify-binary-layout and verify-evm-interface. The foreign-uid ownership
test requires POSIX process uids; skip it where the platform has none
(the curated Windows lane).

* fix(verify): recognize UID-bearing ownership process tables

---------

Co-authored-by: N0zoM1z0 <1705004398@qq.com>
2026-10-08 22:01:05 +08:00
morluto 63cf28fd8f fix(process): preserve partial evidence and verify detached cleanup (#1011)
* test(ci): allow transport delivery in source identity regression

* fix(process): preserve partial evidence and verify detached cleanup

* fix(process): scope Linux token sweeps by stable process identity

* fix(process): retain environment permission failure codes

* fix(process): wait for signaled processes before verifying cleanup

* fix(process): verify sampled detached groups during cleanup

* fix(electron): preserve prelaunch identities through cleanup

* fix(process): retry growing Darwin process table snapshots

* fix(process): retain compatibility with saved v3 capture evidence

* fix(process): migrate saved v3 captures during reconstruction verification

* fix(process): preserve cancellation during Darwin helper compilation

* fix(process): propagate cancellation through ownership baselines

* perf(javascript): cache canonical export comparison sort keys

* fix(process): cancel provider ownership preparation before spawn

* fix(process): isolate native compiler waiter cancellation
2026-10-08 04:46:46 +08:00
morluto f8a53a8c06 test: consolidate service and process fixtures 2026-10-08 04:03:24 +08:00
morluto c93422a898 refactor: remove abandoned test-only analysis scaffolding 2026-10-08 04:03:23 +08:00
Ysopwnable 6aa9afb549 refactor(process): separate capture implementation from analyst workflows (#988)
* refactor(process): separate capture implementation from analyst workflows

* fix(ci): generate source catalog before shard tests
2026-10-08 00:46:21 +08:00