feat(analysis): make resource budgets recoverable across CLI and MCP (#9706)

* refactor(analysis): centralize resource budgets and recovery facts

* feat(analysis): expose ASAR and Ghidra runtime admission controls

* feat(artifacts): expose reader admission and preserve limited recognition

* feat(javascript): expose recoverable semantic precision budgets

* feat(web): add recoverable source-map budgets and compact retained views

* feat(web): make historical capture decoding budgets recoverable

* fix(desktop): enforce selected view policies across capture and export

* feat(runtime): make Frida and LLDB retention budgets selectable

* feat(native): expose diagnostic budgets and preserve exhaustion causes

* feat(managed): expose recoverable snapshot and representation budgets

* feat(metadata): make Go and Rust inspection budgets recoverable

* feat(wasm): expose representation and producer admissions

* feat(evm): expose per-call worker resource budgets

* feat(android): make resource and string-pool omissions recoverable

* feat(producers): expose command and recorded-capture budgets

* docs(analysis): record recovery contracts and integrated validation

* fix(docs): link calibration oracle from published verification pages

* fix(docs): restore desktop task anchors and receipt links

* test(analysis): align fixtures with selectable budget contracts

* fix(analysis): remove source-location projector dependency cycle

* test(analysis): refresh budget recovery and verifier regressions

* test(analysis): preserve format and publication recovery expectations

* test(windows): align conformance with owned runtime admission

* fix(desktop): preserve selected alias kinds in exported state

* test(analysis): align provider fixtures with recoverable budgets

* test(desktop): validate emitted alias metadata structurally

* fix(ghidra): classify bounded Windows endpoint refusals

* test(cli): assert selectable artifact admission recovery

* fix(cli): preserve capture provenance in environment builds
This commit is contained in:
morluto authored and GitHub committed 2026-11-10 05:11:20 -05:00
1 parent 55b6d2ca20
commit cb4e5cfbff
515 files changed
+21066 -3637

No files matched your search

@@ -0,0 +1,214 @@
"""Observe one selected experiment's process group and descendant tree.
macOS has no cgroup peak counter. RSS is a sampled sum, not an exact kernel
peak or aggregate memory hard limit. Only the owned group is stopped early;
descendant-tree sampling is observational and does not confer signal authority.
"""
import argparse
import hashlib
import json
import os
from pathlib import Path
import platform
import signal
import subprocess
import time
def process_snapshot():
rows = subprocess.run(
["ps", "-axo", "pid=,ppid=,pgid=,rss="],
text=True, capture_output=True, check=True,
).stdout.splitlines()
return [tuple(map(int, row.split())) for row in rows]
def group_rss(group, snapshot=None):
if snapshot is None:
snapshot = process_snapshot()
return [(pid, kib * 1024) for pid, _, pgid, kib in snapshot if pgid == group]
def tree_rss(root, snapshot):
children = {}
for pid, ppid, _, _ in snapshot:
children.setdefault(ppid, []).append(pid)
pending = [root]
descendants = set()
while pending:
pid = pending.pop()
if pid not in descendants:
descendants.add(pid)
pending.extend(children.get(pid, []))
return [(pid, kib * 1024) for pid, _, _, kib in snapshot if pid in descendants]
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--output", required=True)
parser.add_argument("--cwd", required=True)
parser.add_argument("--timeout-seconds", type=float, default=90)
parser.add_argument("--memory-mib", type=int, default=1536)
parser.add_argument("command", nargs=argparse.REMAINDER)
options = parser.parse_args()
command = options.command
if command[:1] == ["--"]:
command = command[1:]
if not command or options.timeout_seconds <= 0 or options.memory_mib <= 0:
parser.error("Select an argv target and positive observation bounds")
output = Path(options.output).resolve()
output.parent.mkdir(parents=True, exist_ok=True)
stdout_path = output.with_suffix(".stdout")
stderr_path = output.with_suffix(".stderr")
peak = 0
maximum_members = 0
tree_peak = 0
maximum_tree_members = 0
samples = 0
stopped = None
usage = None
status = None
signal_errors = []
observer_error = None
started = time.monotonic()
with stdout_path.open("wb") as stdout, stderr_path.open("wb") as stderr:
process = subprocess.Popen(
command, cwd=options.cwd, stdout=stdout, stderr=stderr,
start_new_session=True,
)
def reap():
nonlocal status, usage
if process.returncode is not None:
return True
pid, observed_status, observed_usage = os.wait4(process.pid, os.WNOHANG)
if not pid:
return False
status, usage = observed_status, observed_usage
process.returncode = os.waitstatus_to_exitcode(status)
return True
def root_exited():
# Keep the session leader waitable until group cleanup finishes.
# Its reserved PID prevents our process-group identity being reused.
return os.waitid(
os.P_PID, process.pid, os.WEXITED | os.WNOHANG | os.WNOWAIT,
) is not None
def group_has_work():
exited = root_exited()
return any(
pid != process.pid or not exited
for pid, _ in group_rss(process.pid)
)
def signal_owned_group(selected_signal):
# A sample and the following signal are not atomic. A completed
# root may still own live children. Do not reap it before their
# cleanup, and preserve receipts when the OS refuses a signal.
if not group_has_work():
return
try:
os.killpg(process.pid, selected_signal)
except ProcessLookupError:
pass
except OSError as error:
signal_errors.append({
"signal": selected_signal.name,
"errno": error.errno,
"reason": str(error),
})
def stop_owned_group():
signal_owned_group(signal.SIGTERM)
time.sleep(0.2)
signal_owned_group(signal.SIGKILL)
deadline = time.monotonic() + 1
while group_has_work() and time.monotonic() < deadline:
time.sleep(0.02)
reap()
try:
while True:
if root_exited():
if group_has_work():
stopped = "target_exited_with_group_members"
stop_owned_group()
else:
reap()
break
# One OS snapshot supplies both scopes. Ancestry is an
# observation, never permission to signal detached children.
snapshot = process_snapshot()
members = group_rss(process.pid, snapshot)
tree_members = tree_rss(process.pid, snapshot)
samples += 1
peak = max(peak, sum(rss for _, rss in members))
maximum_members = max(maximum_members, len(members))
tree_peak = max(tree_peak, sum(rss for _, rss in tree_members))
maximum_tree_members = max(maximum_tree_members, len(tree_members))
elapsed = time.monotonic() - started
if peak > options.memory_mib * 1024 * 1024:
stopped = "sampled_group_rss_early_stop"
elif elapsed > options.timeout_seconds:
stopped = "wall_deadline"
if stopped:
stop_owned_group()
break
time.sleep(0.02)
except BaseException as error:
observer_error = {"type": type(error).__name__, "reason": str(error)}
stopped = stopped or "observer_error"
stop_owned_group()
remaining = group_rss(process.pid)
receipt = {
"schema": "rea-budget-calibration/v1",
"argv": command,
"cwd": options.cwd,
"platform": platform.platform(),
"elapsed_seconds": time.monotonic() - started,
"cpu_seconds_waited_subtree": usage.ru_utime + usage.ru_stime if usage else None,
"peak_process_group_rss_bytes_sampled": peak,
"maximum_group_members_sampled": maximum_members,
"peak_process_tree_rss_bytes_sampled": tree_peak,
"maximum_tree_members_sampled": maximum_tree_members,
"sample_count": samples,
"sample_interval_seconds": 0.02,
"memory_early_stop_bytes": options.memory_mib * 1024 * 1024,
"memory_early_stop_scope": "owned_process_group",
"wall_deadline_seconds": options.timeout_seconds,
"wall_deadline_signal_scope": "owned_process_group",
"stop_reason": stopped,
"signal_errors": signal_errors,
"observer_error": observer_error,
"exit_code": process.returncode,
"cleanup": "group_empty" if not remaining else "group_members_remaining",
"cleanup_scope": "owned_process_group",
"remaining_group_pids": [pid for pid, _ in remaining],
"stdout": str(stdout_path),
"stderr": str(stderr_path),
"stdout_sha256": hashlib.sha256(stdout_path.read_bytes()).hexdigest(),
"stderr_sha256": hashlib.sha256(stderr_path.read_bytes()).hexdigest(),
"limitations": [
"RSS scopes are simultaneous sums within each ps snapshot; short peaks can be missed.",
"Shared pages can be counted in multiple members' RSS.",
"Group RSS excludes descendants that leave this group; tree RSS includes detached descendants while PPID ancestry remains linked to the waitable root.",
"Tree samples can miss exited, reparented, or orphaned descendants; no cumulative PID list or descendant signal authority is inferred.",
"CPU is OS wait4 user+system usage of the waited subtree; sampler CPU is excluded.",
"CPU excludes descendants the target did not wait for, including orphaned children.",
"Memory early stop and cleanup signals apply only to the owned group, not the observed tree; neither RSS metric is a kernel hard limit.",
"Wall time includes observation overhead; OS caches are not flushed.",
],
}
output.write_text(json.dumps(receipt, indent=2) + "\n")
print(json.dumps({key: receipt[key] for key in [
"elapsed_seconds", "cpu_seconds_waited_subtree",
"peak_process_group_rss_bytes_sampled", "exit_code", "cleanup", "stop_reason",
"peak_process_tree_rss_bytes_sampled",
]}))
return process.returncode if not stopped and not remaining and process.returncode is not None else 1
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,45 @@
"""Join serial observer receipts with exact tokenization of every logical call.
Requires tiktoken 0.12.0 for comparison with the retained measurements.
Token counts exclude chat framing, catalogs, adapters, retained delivery and
model reasoning. Artifact and repository path spelling can affect tokens.
"""
import argparse
import json
from pathlib import Path
import tiktoken
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('receipts', type=Path)
parser.add_argument('output', type=Path)
options = parser.parse_args()
encoding = tiktoken.get_encoding('cl100k_base')
rows = []
for path in sorted(options.receipts.rglob('*.metrics.json')):
metrics = json.loads(path.read_text())
key = str(path.relative_to(options.receipts)).removesuffix('.metrics.json')
# The observer argv ends with the selected configuration file.
config = json.loads(Path(metrics['argv'][-1]).read_text())
reply = json.loads(Path(config['reply_receipt']).read_text())
assert metrics['exit_code'] == 0 and metrics['stop_reason'] is None, path
assert metrics['cleanup'] == 'group_empty' and reply['success'], path
tokens = sum(
len(encoding.encode(json.dumps(call[field], ensure_ascii=False, separators=(',', ':'))))
for call in reply['calls']
for field in ['request', 'reply']
)
rows.append({
'key': key,
'calls': reply['call_count'],
'tokens_cl100k_base': tokens,
'seconds': metrics['elapsed_seconds'],
'cpu': metrics['cpu_seconds_waited_subtree'],
'peak_mib': metrics['peak_process_group_rss_bytes_sampled'] / 1024**2,
'delivered': reply['package_uris_delivered_final'],
'cleanup': metrics['cleanup'],
'scope': reply['boundary'],
})
assert rows, 'No *.metrics.json receipts found'
options.output.write_text(json.dumps(rows, indent=2) + '\n')
@@ -0,0 +1,37 @@
"""Generate eight task configs after oracle.py has verified the pinned APKs."""
import argparse
import json
from pathlib import Path
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('inputs', type=Path)
parser.add_argument('output', type=Path)
options = parser.parse_args()
options.output.mkdir(parents=True, exist_ok=True)
manifest = json.loads((Path(__file__).parent / 'manifest.json').read_text())
cases = [
('inventory-default-retry', 'package-inventory', None, True),
('inventory-2048', 'package-inventory', 2048, False),
('overview-default', 'overview', None, False),
('overview-2048', 'overview', 2048, False),
]
for item in manifest['artifacts']:
stem = Path(item['file']).stem
oracle = (options.output / f'{stem}.oracle.json').resolve()
if not oracle.exists():
parser.error(f'Run oracle.py first: {oracle}')
for case, task, limit, recover in cases:
config = {
'artifact': str((options.inputs / item['file']).resolve()),
'oracle': str(oracle),
'task': task,
'recover': recover,
'recovery_uri_limit': 2048,
'reply_receipt': str((options.output / f'{stem}.{case}.replies.json').resolve()),
}
if limit is not None:
config['first_uri_limit'] = limit
(options.output / f'{stem}.{case}.config.json').write_text(
json.dumps(config, indent=2) + '\n'
)
@@ -0,0 +1,48 @@
{
"artifacts": [
{
"file": "flutter_gallery_Android.apk",
"url": "https://github.com/flutter-team-archive/gallery/releases/download/v2.9.2/flutter_gallery_Android.apk",
"bytes": 117817550,
"sha256": "659b5fc6a4319dfe4f117d00ad4e7ec004915ebcadcb96628797fb3544040e29",
"expected_libapp_sha256": "0ae30443b66dcf579d024d2f121f77204639bda9897116a8b2f66a6385189fd9",
"expected_package_count_1024": 756,
"expected_dart_count_1024": 201,
"expected_isolate_section": {
"name": "_kDartIsolateSnapshotData",
"offset": 10420224,
"size": 14263200
}
},
{
"file": "LocalSend-1.18.2-android-arm64v8.apk",
"url": "https://github.com/localsend/localsend/releases/download/v1.18.2/LocalSend-1.18.2-android-arm64v8.apk",
"bytes": 46558706,
"sha256": "82ec3568fba2aa5295b9aae8b76f701d7a4703d86b9f8bad749472038fbaeab3",
"expected_libapp_sha256": "8f46efd1f78d65ebc0ff630655f274f3c36be89aa13316fb7322a3dda8a497d6",
"expected_package_count_1024": 1407,
"expected_dart_count_1024": 216,
"expected_isolate_section": {
"name": "_kDartIsolateSnapshotData",
"offset": 19264,
"size": 6742144
}
}
],
"supporting_artifacts": [
{
"file": "qgis-world-map.gpkg",
"url": "https://raw.githubusercontent.com/qgis/QGIS/e1223b8e9e71fc50ee995ed556f711c54ccc101b/resources/data/world_map.gpkg",
"bytes": 12914688,
"sha256": "01d293159d1b77bd9212b5252587853f61aa9e25b2387135f34afaba8d057190",
"independent_sqlite_row_counts": {
"declared_tables_including_virtual_and_shadow": 26,
"countries": 240,
"states_provinces": 4556,
"disputed_borders": 46,
"layer_styles": 4
},
"role": "Supporting counts only, not a new timed desktop calibration"
}
]
}
@@ -0,0 +1,294 @@
{
"schema": "rea-flutter-budget-calibration/v1",
"baseline": {
"head": "e2a2ede5440df396e44b3406ef511a31a680290e",
"tracked_patch_sha256": "038b69c19bbd79a303c9ecd8d9d22a1251637e3886543ca4f5a4c1b70c724eec",
"description": "Frozen in-progress source snapshot; HEAD alone does not identify this runtime."
},
"host": "macOS-26.3-arm64-arm-64bit-Mach-O",
"node": "24.22.1",
"driver_original_sha256": "b696f10ddef5bab2dc966587bf362a4f93e7a5c662db1f4c12d107b090e78cba",
"oracle_original_sha256": "82e7e68bea71929ebfce3e607d13bea88fb6bd0259892bfa3655d2cd17a1a49a",
"tokenizer": {
"encoding": "cl100k_base",
"tiktoken_version": "0.12.0",
"scope": "logical request and reply JSON, including retries; no chat framing/catalog/adapters/model usage",
"serialization": "json.dumps(call[field], ensure_ascii=False, separators=(',', ':')) for request and reply separately on every call"
},
"method": {
"trials": 3,
"cases": 8,
"cache": "fresh process per case; OS caches not flushed; no cold-cache or warm-runtime-cache claims",
"process_group_rss_sample_seconds": 0.02,
"cpu": "wait4 waited-subtree user+system; sampler excluded",
"memory_early_stop_mib": 1536,
"wall_deadline_seconds": 90,
"memory_limit_note": "sampled early-stop threshold, not kernel hard limit"
},
"runs": [
{
"key": "r1-LocalSend-1.18.2-android-arm64v8.inventory-2048",
"calls": 1,
"tokens_cl100k_base": 16317,
"seconds": 0.299053416994866,
"cpu": 0.374338,
"peak_mib": 184.78125,
"delivered": 1407,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r1-LocalSend-1.18.2-android-arm64v8.inventory-default-retry",
"calls": 2,
"tokens_cl100k_base": 22360,
"seconds": 0.40635258400288876,
"cpu": 0.515262,
"peak_mib": 221.328125,
"delivered": 1407,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r1-LocalSend-1.18.2-android-arm64v8.overview-2048",
"calls": 1,
"tokens_cl100k_base": 27158,
"seconds": 0.29257937498914544,
"cpu": 0.388501,
"peak_mib": 189.515625,
"delivered": 1407,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r1-LocalSend-1.18.2-android-arm64v8.overview-default",
"calls": 1,
"tokens_cl100k_base": 16885,
"seconds": 0.2934171250090003,
"cpu": 0.413556,
"peak_mib": 189.625,
"delivered": 500,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r1-flutter_gallery_Android.inventory-2048",
"calls": 1,
"tokens_cl100k_base": 8631,
"seconds": 0.5524000000004889,
"cpu": 0.598673,
"peak_mib": 238.859375,
"delivered": 756,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r1-flutter_gallery_Android.inventory-default-retry",
"calls": 2,
"tokens_cl100k_base": 14488,
"seconds": 1.01431600000069,
"cpu": 1.250315,
"peak_mib": 299.453125,
"delivered": 756,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r1-flutter_gallery_Android.overview-2048",
"calls": 1,
"tokens_cl100k_base": 18764,
"seconds": 0.5649452920042677,
"cpu": 0.639156,
"peak_mib": 243.328125,
"delivered": 756,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r1-flutter_gallery_Android.overview-default",
"calls": 1,
"tokens_cl100k_base": 15995,
"seconds": 0.5576133750000736,
"cpu": 0.6388879999999999,
"peak_mib": 240.71875,
"delivered": 500,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r2-LocalSend-1.18.2-android-arm64v8.inventory-2048",
"calls": 1,
"tokens_cl100k_base": 16317,
"seconds": 0.2958210000069812,
"cpu": 0.36518599999999996,
"peak_mib": 183.703125,
"delivered": 1407,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r2-LocalSend-1.18.2-android-arm64v8.inventory-default-retry",
"calls": 2,
"tokens_cl100k_base": 22360,
"seconds": 0.4046505839942256,
"cpu": 0.530767,
"peak_mib": 216.390625,
"delivered": 1407,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r2-LocalSend-1.18.2-android-arm64v8.overview-2048",
"calls": 1,
"tokens_cl100k_base": 27158,
"seconds": 0.3230182090046583,
"cpu": 0.38625,
"peak_mib": 189.640625,
"delivered": 1407,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r2-LocalSend-1.18.2-android-arm64v8.overview-default",
"calls": 1,
"tokens_cl100k_base": 16885,
"seconds": 0.289660875001573,
"cpu": 0.400553,
"peak_mib": 189.765625,
"delivered": 500,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r2-flutter_gallery_Android.inventory-2048",
"calls": 1,
"tokens_cl100k_base": 8631,
"seconds": 0.47969675000058487,
"cpu": 0.606711,
"peak_mib": 241.25,
"delivered": 756,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r2-flutter_gallery_Android.inventory-default-retry",
"calls": 2,
"tokens_cl100k_base": 14488,
"seconds": 0.8361371669889195,
"cpu": 1.028465,
"peak_mib": 258.65625,
"delivered": 756,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r2-flutter_gallery_Android.overview-2048",
"calls": 1,
"tokens_cl100k_base": 18764,
"seconds": 0.5597699580102926,
"cpu": 0.633868,
"peak_mib": 241.53125,
"delivered": 756,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r2-flutter_gallery_Android.overview-default",
"calls": 1,
"tokens_cl100k_base": 15995,
"seconds": 0.4476122909982223,
"cpu": 0.641888,
"peak_mib": 245.84375,
"delivered": 500,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r3-LocalSend-1.18.2-android-arm64v8.inventory-2048",
"calls": 1,
"tokens_cl100k_base": 16317,
"seconds": 0.29069650000019465,
"cpu": 0.362932,
"peak_mib": 185.859375,
"delivered": 1407,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r3-LocalSend-1.18.2-android-arm64v8.inventory-default-retry",
"calls": 2,
"tokens_cl100k_base": 22360,
"seconds": 0.3999212499911664,
"cpu": 0.519303,
"peak_mib": 230.84375,
"delivered": 1407,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r3-LocalSend-1.18.2-android-arm64v8.overview-2048",
"calls": 1,
"tokens_cl100k_base": 27158,
"seconds": 0.2895570419932483,
"cpu": 0.388245,
"peak_mib": 189.984375,
"delivered": 1407,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r3-LocalSend-1.18.2-android-arm64v8.overview-default",
"calls": 1,
"tokens_cl100k_base": 16885,
"seconds": 0.29197387500607874,
"cpu": 0.402588,
"peak_mib": 190.25,
"delivered": 500,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r3-flutter_gallery_Android.inventory-2048",
"calls": 1,
"tokens_cl100k_base": 8631,
"seconds": 0.447617124998942,
"cpu": 0.600641,
"peak_mib": 238.6875,
"delivered": 756,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r3-flutter_gallery_Android.inventory-default-retry",
"calls": 2,
"tokens_cl100k_base": 14488,
"seconds": 0.8252949169982458,
"cpu": 1.0068,
"peak_mib": 254.765625,
"delivered": 756,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r3-flutter_gallery_Android.overview-2048",
"calls": 1,
"tokens_cl100k_base": 18764,
"seconds": 0.4492089169943938,
"cpu": 0.6431779999999999,
"peak_mib": 249.65625,
"delivered": 756,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
},
{
"key": "r3-flutter_gallery_Android.overview-default",
"calls": 1,
"tokens_cl100k_base": 15995,
"seconds": 0.44429433399636764,
"cpu": 0.6304479999999999,
"peak_mib": 241.921875,
"delivered": 500,
"cleanup": "group_empty",
"scope": "shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning"
}
]
}
@@ -0,0 +1,94 @@
"""Independently enumerate bounded printable runs in two pinned Flutter APKs.
This intentionally small ELF64LE parser is for these verified artifacts, not a
replacement for production parsing. It uses no REA implementation code.
"""
import argparse
import hashlib
import json
from pathlib import Path
import re
import struct
import zipfile
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('inputs', type=Path)
parser.add_argument('output', type=Path)
options = parser.parse_args()
options.output.mkdir(parents=True, exist_ok=True)
manifest = json.loads((Path(__file__).parent / 'manifest.json').read_text())
for item in manifest['artifacts']:
apk = options.inputs / item['file']
assert apk.stat().st_size == item['bytes'], apk
with apk.open('rb') as source:
artifact_digest = hashlib.file_digest(source, 'sha256').hexdigest()
assert artifact_digest == item['sha256'], apk
with zipfile.ZipFile(apk) as archive:
data = archive.read('lib/arm64-v8a/libapp.so')
assert data[:6] == b'\x7fELF\x02\x01', apk
section_offset = struct.unpack_from('<Q', data, 40)[0]
section_size, section_count = struct.unpack_from('<HH', data, 58)
sections = [
struct.unpack_from('<IIQQQQIIQQ', data, section_offset + i * section_size)
for i in range(section_count)
]
found = []
for section in sections:
if section[1] != 11: # SHT_DYNSYM
continue
strings = sections[section[6]]
names = data[strings[4]:strings[4] + strings[5]]
for at in range(section[4], section[4] + section[5], section[9]):
name, _, _, index, value, size = struct.unpack_from('<IBBHQQ', data, at)
end = names.find(b'\0', name)
if names[name:end] != b'_kDartIsolateSnapshotData':
continue
owner = sections[index]
offset = owner[4] + value - owner[3]
assert 0 <= offset <= len(data) - size
found.append((offset, size))
assert len(found) == 1, (apk, found)
offset, size = found[0]
runs = re.findall(rb'[\x20-\x7e]+', data[offset:offset + size])
oracle = {
'artifact': str(apk),
'artifact_sha256': artifact_digest,
'libapp_sha256': hashlib.sha256(data).hexdigest(),
'abi': 'arm64-v8a',
'section': {
'name': '_kDartIsolateSnapshotData',
'offset': offset,
'size': size,
},
'oracle': 'Independent Python ELF DYNSYM/section mapping and byte regex; no REA parser used',
'policies': {},
}
for run_bytes in [1024, 4096]:
selected = [run for run in runs if 5 <= len(run) <= run_bytes]
packages = sorted({run.decode('ascii') for run in selected if run.startswith(b'package:')})
darts = sorted({run.decode('ascii') for run in selected if run.startswith(b'dart:')})
oracle['policies'][str(run_bytes)] = {
'package_uris': packages,
'dart_uris': darts,
'package_count': len(packages),
'dart_count': len(darts),
'longest_printable_run': max(map(len, runs)),
'overflowed_runs': sum(len(run) > run_bytes for run in runs),
}
assert oracle['libapp_sha256'] == item['expected_libapp_sha256']
assert oracle['section'] == item['expected_isolate_section']
assert oracle['policies']['1024']['package_count'] == item['expected_package_count_1024']
assert oracle['policies']['1024']['dart_count'] == item['expected_dart_count_1024']
target = options.output / (apk.stem + '.oracle.json')
target.write_text(json.dumps(oracle, indent=2) + '\n')
print(json.dumps({
'oracle': str(target),
'artifact_sha256': artifact_digest,
'libapp_sha256': oracle['libapp_sha256'],
'section': oracle['section'],
'policies': {
key: {name: value for name, value in policy.items() if not isinstance(value, list)}
for key, policy in oracle['policies'].items()
},
}))
@@ -0,0 +1,103 @@
import { readFile, writeFile } from "node:fs/promises";
import { pathToFileURL } from "node:url";
import { join } from "node:path";
import assert from "node:assert/strict";
const [repository, configPath] = process.argv.slice(2);
const config = JSON.parse(await readFile(configPath, "utf8"));
const { FlutterBuildAnalysisService } = await import(
pathToFileURL(
join(repository, "src/application/flutter/FlutterBuildAnalysisService.ts"),
)
);
const { createFlutterBuildAnalysisProvider } = await import(
pathToFileURL(join(repository, "src/composition/flutter.ts"))
);
const { estimateTokenCount } = await import(
pathToFileURL(join(repository, "node_modules/tokenx/dist/index.mjs"))
);
const oracle = JSON.parse(await readFile(config.oracle, "utf8"));
const calls = [];
const provider = createFlutterBuildAnalysisProvider();
const service = new FlutterBuildAnalysisService(provider);
try {
let uriLimit = config.first_uri_limit;
for (let attempt = 0; attempt < 5; attempt++) {
const input = {
path: config.artifact,
abi: "arm64-v8a",
pool_policy: {
...(uriLimit === undefined ? {} : { uri_limit: uriLimit }),
...(config.task === "package-inventory"
? { contains: "package:" }
: {}),
},
};
const request = { operation: "inspect_dart_aot", input };
const reply = await service.execute(request.operation, request.input);
calls.push({
request,
reply,
request_token_estimate: estimateTokenCount(JSON.stringify(request)),
reply_token_estimate: estimateTokenCount(JSON.stringify(reply)),
});
assert.equal(reply.ok, true, JSON.stringify(reply));
const result = reply.value.normalized_result;
assert.equal(result.target.sha256, oracle.artifact_sha256);
assert.equal(result.libapp.sha256, oracle.libapp_sha256);
assert.equal(result.abi, oracle.abi);
assert.equal(result.string_pool.policy.run_bytes, 1024);
assert.equal(result.string_pool.policy.token_bytes, 128);
assert.equal(result.string_pool.policy.token_limit, 2000);
if (config.task === "package-inventory") {
const expected = oracle.policies["1024"].package_uris;
if (
result.string_pool.package_uris.length <
result.string_pool.package_uri_count_at_least
) {
assert.equal(
config.recover,
true,
"Candidate failed inventory completeness",
);
uriLimit = config.recovery_uri_limit;
continue;
}
assert.deepEqual([...result.string_pool.package_uris].sort(), expected);
} else {
// Overview controls verify identity, ABI and snapshot section identities;
// they deliberately do not require any printable string values.
assert.ok(result.libapp.sections.length > 0);
}
const tokenEstimate = calls.reduce(
(n, call) => n + call.request_token_estimate + call.reply_token_estimate,
0,
);
const receipt = {
task: config.task,
boundary:
"shared application service; excludes CLI/MCP discovery, adapter delivery, retained resource overhead and model reasoning",
token_estimator:
"tokenx 1.3.0, estimate only; all logical requests and replies including retries",
token_estimate: tokenEstimate,
call_count: calls.length,
success: true,
pool_coverage: result.string_pool.coverage,
package_uris_delivered_final: result.string_pool.package_uris.length,
package_uri_count_at_least_final:
result.string_pool.package_uri_count_at_least,
config,
calls,
};
await writeFile(
config.reply_receipt,
JSON.stringify(receipt, null, 2) + "\n",
);
process.stdout.write(
JSON.stringify({ ...receipt, calls: undefined }) + "\n",
);
break;
}
assert.ok(calls.length < 5, "Recovery did not complete");
} finally {
await provider.close();
}
@@ -0,0 +1,59 @@
"""Aggregate retained observer receipts and complete CLI records; needs tiktoken."""
import argparse
import json
from pathlib import Path
import statistics
import tiktoken
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('inputs', type=Path)
parser.add_argument('output', type=Path)
options = parser.parse_args()
encoder = tiktoken.get_encoding('cl100k_base')
def compact(value):
return json.dumps(value, ensure_ascii=False, separators=(',', ':'))
rows = []
for path in sorted(options.inputs.glob('*.metrics.json')):
metrics = json.loads(path.read_text())
record = json.loads(path.with_name(path.name.replace('.metrics.json', '.replies.json')).read_text())
summary = json.loads(path.with_suffix('.stdout').read_text())
tokens = {
'arguments': len(encoder.encode(compact(record['argv']))),
'reply': len(encoder.encode(compact(json.loads(record['stdout'])))),
'progress_stderr': len(encoder.encode(record['stderr'])),
}
rows.append({
'name': path.stem.removesuffix('.metrics'),
'task': summary['case'], 'budget': summary['budget'],
'verified_facts': summary['verified_facts'], 'unknowns': summary['unknowns'],
'wall_s': metrics['elapsed_seconds'],
'cpu_s': metrics['cpu_seconds_waited_subtree'],
'host_group_rss_bytes': metrics['peak_process_group_rss_bytes_sampled'],
'tokens': tokens, 'reply_bytes': summary['reply_bytes'],
'exit_code': metrics['exit_code'], 'cleanup': metrics['cleanup'],
'stop_reason': metrics['stop_reason'],
})
medians = []
for task in ['theme', 'ms']:
for budget in ['default', 'double']:
selected = [row for row in rows if row['task'] == task and row['budget'] == budget]
if not selected:
continue
medians.append({
'task': task, 'budget': budget, 'trials': len(selected),
'facts': selected[0]['verified_facts'], 'unknowns': selected[0]['unknowns'],
'wall_s': statistics.median(row['wall_s'] for row in selected),
'cpu_s': statistics.median(row['cpu_s'] for row in selected),
'host_group_rss_mib': statistics.median(row['host_group_rss_bytes'] / 1048576 for row in selected),
'tokens': statistics.median(sum(row['tokens'].values()) for row in selected),
'reply_bytes': selected[0]['reply_bytes'],
})
options.output.write_text(json.dumps({'rows': rows, 'medians': medians}, indent=2) + '\n')
if __name__ == '__main__':
main()
@@ -0,0 +1,16 @@
{
"theme": {
"url": "https://demo.actualbudget.org/static/js/theme.EvD-JhP6.chunk.js.map",
"map_sha256": "ceef8194eaca339e55f35cf2decf7ceffa121c7744ee1fffd976a07d39477b32",
"reported_source": "../../../../component-library/src/theme.ts",
"source_sha256": "05307dc6f927705a8c76e43579c910bf6415ce28b375eea19251dc51dd2b1726"
},
"ms": {
"version": "2.1.3",
"source": "locked installed node_modules/ms",
"files": {
"index.js": "e5f0b6a946a9b2b356a28557728410717df54ea2f599edb619f9839df6b7b0e9",
"package.json": "1a6b4d9739790c0b94ab96c8cc0507e281c164c311ff4fbf5e57fb8d26290b40"
}
}
}
@@ -0,0 +1,323 @@
{
"method": "tiktoken0.12.0 cl100k_base compactUnicodeJSON argv and full parsedstdoutEvidence plusliteralprogressstderr; no MCPcatalog/chat/modelbilling",
"runtime_hashes": {
"scripts/rea.mjs": "11120fdc741c2eeca9ce903de5fd18cd1c7c3fffa15ae2beccca750f161d9ee3",
"dist/cli.js": "acd23e0f186188c99fb905cba36f81e11f92d7f280acd684a9ee93ccc75eb9ce",
"dist/domain/javascript/javascriptSemanticResourceLimits.js": "567ecef0cdb593c75ac156075a43c0e3fc8fb6b5ade3991614f58feb256d075c",
"dist/domain/javascript/javascriptSemanticPrecision.js": "56cec74b6fbe0c2dd6e4fb058811f35635d63ae3235f74d2b408e1b7c6dcc366",
"dist/domain/javascript/javascriptSemanticAnalysis.js": "c21da46e866ce49f69a45e0b5ab923fcb8eb6746a50e8f6c8b77ee61d0ca0bbd",
"dist/javascript/analysis/JavaScriptAnalysisWorker.js": "132f199041291d70ae304474a86143fb4bba3e8df4d0114607bce0f5c3f2fe61",
"dist/cli-runtime/cli.js": "b24d2408a52483a8e9b93435110c243deb53bb7ef94757c802a0c6246d8df20c",
"dist/cli-runtime/cliBuiltinArguments.js": "7b0c81902f568cdd7f8003b7baadcb4f493828b1e472ee613940168213e15090",
"./dist/composition/javascriptAnalysisWorkerProcess.js": "ab927845ccfe917549198b5438d4d206c3ecfb087b0e79e431519bbf4ef1f9fd"
},
"rows": [
{
"name": "r1-ms-default",
"task": "ms",
"budget": "default",
"verified_facts": 1,
"unknowns": 133,
"wall_s": 0.9129875000071479,
"cpu_s": 1.239214,
"host_group_rss_bytes": 344621056,
"tokens": {
"arguments": 67,
"reply": 233873,
"progress_stderr": 673
},
"reply_bytes": 624004,
"exit_code": 0,
"cleanup": "group_empty",
"stop_reason": null
},
{
"name": "r1-ms-double",
"task": "ms",
"budget": "double",
"verified_facts": 1,
"unknowns": 133,
"wall_s": 0.9050752910115989,
"cpu_s": 1.2302469999999999,
"host_group_rss_bytes": 348717056,
"tokens": {
"arguments": 81,
"reply": 233914,
"progress_stderr": 673
},
"reply_bytes": 624244,
"exit_code": 0,
"cleanup": "group_empty",
"stop_reason": null
},
{
"name": "r1-theme-default",
"task": "theme",
"budget": "default",
"verified_facts": 237,
"unknowns": 0,
"wall_s": 0.9374774580064695,
"cpu_s": 1.221098,
"host_group_rss_bytes": 346652672,
"tokens": {
"arguments": 67,
"reply": 258656,
"progress_stderr": 673
},
"reply_bytes": 733950,
"exit_code": 0,
"cleanup": "group_empty",
"stop_reason": null
},
{
"name": "r1-theme-double",
"task": "theme",
"budget": "double",
"verified_facts": 237,
"unknowns": 0,
"wall_s": 0.9283738329977496,
"cpu_s": 1.236008,
"host_group_rss_bytes": 346423296,
"tokens": {
"arguments": 81,
"reply": 258721,
"progress_stderr": 673
},
"reply_bytes": 734190,
"exit_code": 0,
"cleanup": "group_empty",
"stop_reason": null
},
{
"name": "r2-ms-default",
"task": "ms",
"budget": "default",
"verified_facts": 1,
"unknowns": 133,
"wall_s": 0.8994753339939052,
"cpu_s": 1.211395,
"host_group_rss_bytes": 326647808,
"tokens": {
"arguments": 67,
"reply": 233873,
"progress_stderr": 673
},
"reply_bytes": 624004,
"exit_code": 0,
"cleanup": "group_empty",
"stop_reason": null
},
{
"name": "r2-ms-double",
"task": "ms",
"budget": "double",
"verified_facts": 1,
"unknowns": 133,
"wall_s": 0.9041235420008888,
"cpu_s": 1.206674,
"host_group_rss_bytes": 326893568,
"tokens": {
"arguments": 81,
"reply": 233914,
"progress_stderr": 673
},
"reply_bytes": 624244,
"exit_code": 0,
"cleanup": "group_empty",
"stop_reason": null
},
{
"name": "r2-theme-default",
"task": "theme",
"budget": "default",
"verified_facts": 237,
"unknowns": 0,
"wall_s": 0.9415311659977306,
"cpu_s": 1.231308,
"host_group_rss_bytes": 348160000,
"tokens": {
"arguments": 67,
"reply": 258656,
"progress_stderr": 673
},
"reply_bytes": 733950,
"exit_code": 0,
"cleanup": "group_empty",
"stop_reason": null
},
{
"name": "r2-theme-double",
"task": "theme",
"budget": "double",
"verified_facts": 237,
"unknowns": 0,
"wall_s": 0.9384306669962825,
"cpu_s": 1.228734,
"host_group_rss_bytes": 350060544,
"tokens": {
"arguments": 81,
"reply": 258721,
"progress_stderr": 673
},
"reply_bytes": 734190,
"exit_code": 0,
"cleanup": "group_empty",
"stop_reason": null
},
{
"name": "r3-ms-default",
"task": "ms",
"budget": "default",
"verified_facts": 1,
"unknowns": 133,
"wall_s": 0.8975688329956029,
"cpu_s": 1.2376939999999998,
"host_group_rss_bytes": 337887232,
"tokens": {
"arguments": 67,
"reply": 233873,
"progress_stderr": 673
},
"reply_bytes": 624004,
"exit_code": 0,
"cleanup": "group_empty",
"stop_reason": null
},
{
"name": "r3-ms-double",
"task": "ms",
"budget": "double",
"verified_facts": 1,
"unknowns": 133,
"wall_s": 0.9211560420080787,
"cpu_s": 1.22497,
"host_group_rss_bytes": 346587136,
"tokens": {
"arguments": 81,
"reply": 233914,
"progress_stderr": 673
},
"reply_bytes": 624244,
"exit_code": 0,
"cleanup": "group_empty",
"stop_reason": null
},
{
"name": "r3-theme-default",
"task": "theme",
"budget": "default",
"verified_facts": 237,
"unknowns": 0,
"wall_s": 0.9006596249964787,
"cpu_s": 1.225968,
"host_group_rss_bytes": 340787200,
"tokens": {
"arguments": 67,
"reply": 258656,
"progress_stderr": 673
},
"reply_bytes": 733950,
"exit_code": 0,
"cleanup": "group_empty",
"stop_reason": null
},
{
"name": "r3-theme-double",
"task": "theme",
"budget": "double",
"verified_facts": 237,
"unknowns": 0,
"wall_s": 0.9200200000050245,
"cpu_s": 1.2206029999999999,
"host_group_rss_bytes": 346898432,
"tokens": {
"arguments": 81,
"reply": 258721,
"progress_stderr": 673
},
"reply_bytes": 734190,
"exit_code": 0,
"cleanup": "group_empty",
"stop_reason": null
}
],
"medians": [
{
"task": "theme",
"budget": "default",
"trials": 3,
"facts": 237,
"unknowns": 0,
"wall_s": 0.9374774580064695,
"cpu_s": 1.225968,
"host_group_rss_mib": 330.59375,
"tokens": 259396,
"reply_bytes": 733950
},
{
"task": "theme",
"budget": "double",
"trials": 3,
"facts": 237,
"unknowns": 0,
"wall_s": 0.9283738329977496,
"cpu_s": 1.228734,
"host_group_rss_mib": 330.828125,
"tokens": 259475,
"reply_bytes": 734190
},
{
"task": "ms",
"budget": "default",
"trials": 3,
"facts": 1,
"unknowns": 133,
"wall_s": 0.8994753339939052,
"cpu_s": 1.2376939999999998,
"host_group_rss_mib": 322.234375,
"tokens": 234613,
"reply_bytes": 624004
},
{
"task": "ms",
"budget": "double",
"trials": 3,
"facts": 1,
"unknowns": 133,
"wall_s": 0.9050752910115989,
"cpu_s": 1.22497,
"host_group_rss_mib": 330.53125,
"tokens": 234668,
"reply_bytes": 624244
}
],
"baseline": {
"head": "e2a2ede5440df396e44b3406ef511a31a680290e",
"working_tree": "uncommitted runtime; relevant compiled entrypoint/owner hashes retained; HEAD alone does not identify it",
"original_task_sha256": "a17526f4b4325139896488b1d64106e5f955f7a5f998a062cb6d319425136782",
"original_oracle_sha256": "1f4070c8814a1cd45b5ab205efd9cbf797f4b82aff195abb41877f79642c5388"
},
"measurement_scope": {
"observer": "sampled simultaneous process-group RSS; not a kernel hard cap",
"excluded_memory": "isolated JavaScript worker launches detached into another process group; its peak memory is unmeasured",
"cpu": "wait4 waited-subtree user+system; sampler and unwaited descendants excluded",
"cache": "fresh CLI/worker per trial; OS caches not flushed; fixed default-then-double ordering",
"node": "24.22.1",
"host": "macOS26.3 arm64",
"heap_mib": "CLI and isolated worker both held512 via NODE_OPTIONS and --max-heap-mb",
"deadline_seconds": 90,
"group_early_stop_mib": 1536,
"calls_per_task": 1,
"retries": 0
},
"unknown_equivalence": {
"theme": {
"unknown_meaning_sha256": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945",
"equivalent_trials": 6
},
"ms": {
"unknown_meaning_sha256": "9868f30b3b2ffc97cea3b26908a54673ff0137970a41c8c6ab95356ae48a9f19",
"equivalent_trials": 6
}
}
}
@@ -0,0 +1,76 @@
"""Verify pinned inputs and prepare inert application directories and an oracle."""
import argparse
import hashlib
import json
from pathlib import Path
import re
import shutil
def sha256(path):
return hashlib.sha256(path.read_bytes()).hexdigest()
def theme_values(source):
prefix, suffix = 'export const theme = {', '};\n'
if not source.startswith(prefix) or not source.endswith(suffix):
raise ValueError('Expected the pinned literal-only theme declaration')
body = source[len(prefix):-len(suffix)]
pair = re.compile(r"\s*([A-Za-z_]\w*)\s*:\s*'([^'\\]*)'\s*,")
values = {}
position = 0
while body[position:].strip():
item = pair.match(body, position)
if item is None or item[1] in values:
raise ValueError('Oracle only accepts distinct literal CSS property declarations')
values[item[1]] = item[2]
position = item.end()
if len(values) != 237:
raise ValueError('The pinned source must declare 237 theme properties')
return values
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('repo', type=Path)
parser.add_argument('source_map', type=Path)
parser.add_argument('output', type=Path)
options = parser.parse_args()
manifest = json.loads((Path(__file__).parent / 'manifest.json').read_text())
pinned = manifest['theme']
if sha256(options.source_map) != pinned['map_sha256']:
parser.error('Source-map digest does not match the pinned artifact')
document = json.loads(options.source_map.read_text())
matching = [text for name, text in zip(document['sources'], document['sourcesContent'])
if name == pinned['reported_source']]
if len(matching) != 1 or matching[0] is None:
parser.error('Expected one embedded original theme source')
source = matching[0]
if hashlib.sha256(source.encode()).hexdigest() != pinned['source_sha256']:
parser.error('Embedded source digest mismatch')
theme = options.output / 'cases/theme'
control = options.output / 'cases/ms'
theme.mkdir(parents=True, exist_ok=True)
control.mkdir(parents=True, exist_ok=True)
(theme / 'theme.ts').write_text(source)
(theme / 'package.json').write_text(json.dumps({
'name': 'rea-captured-theme-calibration', 'type': 'module', 'main': 'theme.ts',
}))
for name, digest in manifest['ms']['files'].items():
path = options.repo / 'node_modules/ms' / name
if sha256(path) != digest:
parser.error(f'Installed ms input digest mismatch: {name}')
shutil.copyfile(path, control / name)
oracle = {
'theme': {'source_file': 'theme.ts', 'source_sha256': pinned['source_sha256'],
'expected': theme_values(source)},
'ms': {'source_file': 'index.js',
'source_sha256': manifest['ms']['files']['index.js'], 'expected': {'s': 1000}},
}
options.output.mkdir(parents=True, exist_ok=True)
(options.output / 'oracle.json').write_text(json.dumps(oracle, indent=2) + '\n')
if __name__ == '__main__':
main()
@@ -0,0 +1,68 @@
import { readFile, writeFile } from "node:fs/promises";
import { createHash } from "node:crypto";
import { parse } from "@babel/parser";
const [output, ...files] = process.argv.slice(2);
const rows = [];
for (const file of files) {
const text = await readFile(file, "utf8");
const ast = parse(text, { sourceType: "unambiguous" });
const strings = [];
let nodes = 0;
const stack = [ast];
while (stack.length) {
const n = stack.pop();
if (!n || typeof n !== "object") continue;
if (Array.isArray(n)) {
stack.push(...n);
continue;
}
if (typeof n.type === "string") nodes++;
if (n.type === "StringLiteral") {
let oracle = false;
try {
oracle = JSON.parse(text.slice(n.start, n.end)) === n.value;
} catch {}
strings.push({
start: n.start,
end: n.end,
units: n.value.length,
jsonBytes: Buffer.byteLength(JSON.stringify(n.value)),
oracle,
});
}
if (
n.type === "TemplateLiteral" &&
n.expressions.length === 0 &&
n.quasis[0].value.cooked !== null
) {
const value = n.quasis[0].value.cooked;
const raw = text.slice(n.start + 1, n.end - 1);
strings.push({
start: n.start,
end: n.end,
units: value.length,
jsonBytes: Buffer.byteLength(JSON.stringify(value)),
oracle: !raw.includes("\\") && raw === value,
template: true,
});
}
for (const [k, v] of Object.entries(n))
if (
!["loc", "extra", "comments", "tokens"].includes(k) &&
v &&
typeof v === "object"
)
stack.push(v);
}
strings.sort((a, b) => b.units - a.units);
rows.push({
file,
bytes: Buffer.byteLength(text),
sha256: createHash("sha256").update(text).digest("hex"),
nodes,
strings: strings.length,
largest: strings.slice(0, 5),
});
}
await writeFile(output, JSON.stringify(rows, null, 2));
console.log(JSON.stringify(rows));
@@ -0,0 +1,192 @@
[
{
"file": "/tmp/rea-source-map-calibration/theme.EvD-JhP6.chunk.js",
"bytes": 29718,
"sha256": "10ecf4c66ae103222a7c146ad9b945dc83e78b6c78ce05021296e3c2f799bd5b",
"nodes": 4022,
"strings": 349,
"largest": [
{
"start": 1434,
"end": 1589,
"units": 152,
"jsonBytes": 155,
"oracle": true
},
{
"start": 3123,
"end": 3227,
"units": 102,
"jsonBytes": 104,
"oracle": true,
"template": true
},
{
"start": 7255,
"end": 7330,
"units": 73,
"jsonBytes": 75,
"oracle": true,
"template": true
},
{
"start": 18225,
"end": 18297,
"units": 70,
"jsonBytes": 72,
"oracle": true,
"template": true
},
{
"start": 10083,
"end": 10154,
"units": 69,
"jsonBytes": 71,
"oracle": true,
"template": true
}
]
},
{
"file": "/tmp/rea-source-map-calibration/index.CMrE7aQb.js",
"bytes": 2078745,
"sha256": "937f792d1849b69a6e0741234428b22b4884ec0157ea31dd6949dd1bacc46456",
"nodes": 460754,
"strings": 15897,
"largest": [
{
"start": 78956,
"end": 79894,
"units": 936,
"jsonBytes": 938,
"oracle": true,
"template": true
},
{
"start": 104891,
"end": 105550,
"units": 657,
"jsonBytes": 659,
"oracle": true,
"template": true
},
{
"start": 1752523,
"end": 1753169,
"units": 644,
"jsonBytes": 662,
"oracle": true,
"template": true
},
{
"start": 1751921,
"end": 1752324,
"units": 401,
"jsonBytes": 413,
"oracle": true,
"template": true
},
{
"start": 583954,
"end": 584343,
"units": 387,
"jsonBytes": 391,
"oracle": true,
"template": true
}
]
},
{
"file": "/tmp/rea-source-map-calibration/DateSelect.BVYaCNUe.chunk.js",
"bytes": 2191517,
"sha256": "9e45139dd0b510ad7014188a5e9d11b307c2ac15dfdc761050388e76e94759bf",
"nodes": 363578,
"strings": 29000,
"largest": [
{
"start": 34808,
"end": 47930,
"units": 13120,
"jsonBytes": 13122,
"oracle": true,
"template": true
},
{
"start": 21787,
"end": 34790,
"units": 13001,
"jsonBytes": 13003,
"oracle": true,
"template": true
},
{
"start": 8827,
"end": 21772,
"units": 12943,
"jsonBytes": 12945,
"oracle": true,
"template": true
},
{
"start": 47947,
"end": 50426,
"units": 2477,
"jsonBytes": 2479,
"oracle": true,
"template": true
},
{
"start": 50458,
"end": 52394,
"units": 1934,
"jsonBytes": 1936,
"oracle": true,
"template": true
}
]
},
{
"file": "node_modules/ms/index.js",
"bytes": 3024,
"sha256": "e5f0b6a946a9b2b356a28557728410717df54ea2f599edb619f9839df6b7b0e9",
"nodes": 427,
"strings": 48,
"largest": [
{
"start": 702,
"end": 757,
"units": 53,
"jsonBytes": 55,
"oracle": false
},
{
"start": 1851,
"end": 1865,
"units": 12,
"jsonBytes": 14,
"oracle": false
},
{
"start": 1876,
"end": 1889,
"units": 11,
"jsonBytes": 13,
"oracle": false
},
{
"start": 1745,
"end": 1754,
"units": 7,
"jsonBytes": 9,
"oracle": false
},
{
"start": 1639,
"end": 1648,
"units": 7,
"jsonBytes": 9,
"oracle": false
}
]
}
]
@@ -0,0 +1,70 @@
"""Run one complete CLI task and independently check the required source facts."""
import argparse
import hashlib
import json
import os
from pathlib import Path
import subprocess
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('repo', type=Path)
parser.add_argument('node')
parser.add_argument('inputs', type=Path)
parser.add_argument('case', choices=['theme', 'ms'])
parser.add_argument('budget', choices=['default', 'double'])
parser.add_argument('output', type=Path)
options = parser.parse_args()
oracle = json.loads((options.inputs / 'oracle.json').read_text())[options.case]
target = options.inputs / 'cases' / options.case
source = target / oracle['source_file']
if hashlib.sha256(source.read_bytes()).hexdigest() != oracle['source_sha256']:
raise ValueError('Selected source digest does not match the oracle')
argv = [options.node, str(options.repo / 'scripts/rea.mjs'),
'analyze-javascript-application', str(target), '--max-heap-mb', '512',
'--format', 'json']
if options.budget == 'double':
argv += ['--semantic-precision', '{"primitive_bytes":2097152}']
environment = {**os.environ, 'NODE_OPTIONS': '--max-old-space-size=512'}
result = subprocess.run(argv, cwd=options.repo, env=environment, capture_output=True,
text=True, timeout=45)
options.output.parent.mkdir(parents=True, exist_ok=True)
options.output.write_text(json.dumps({
'argv': argv, 'stdout': result.stdout, 'stderr': result.stderr,
'exit_code': result.returncode,
}) + '\n')
if result.returncode != 0:
raise RuntimeError(f'CLI failed: {result.stderr[:500]}')
evidence = json.loads(result.stdout)
graph = evidence['normalized_result']['semantic_graph']
nodes = {node['node_id']: node for node in graph['nodes']}
if any(node['identity']['artifact_sha256'] != oracle['source_sha256']
for node in nodes.values()
if node['identity']['module_path'] == oracle['source_file']):
raise ValueError('Selected graph source identity differs from the oracle')
facts = {}
for edge in graph['relations']:
if edge['relation'] != 'defines':
continue
left, right = nodes[edge['source_node_id']], nodes[edge['target_node_id']]
if left['kind'] != 'literal':
continue
if options.case == 'theme' and right['kind'] == 'property-slot':
facts[right['properties']['name']] = left['properties']['value']
if options.case == 'ms' and right['kind'] == 'binding' and right['label'] == 's':
facts['s'] = left['properties']['value']
if facts != oracle['expected']:
raise ValueError('Required source facts differ from the independent oracle')
if any('primitive-bytes' in json.dumps(unknown) for unknown in graph['unknowns']):
raise ValueError('Selected byte allowance unexpectedly limited the task')
print(json.dumps({
'case': options.case, 'budget': options.budget, 'verified_facts': len(facts),
'source_sha256': oracle['source_sha256'],
'reply_bytes': len(result.stdout.encode()), 'unknowns': len(graph['unknowns']),
}))
if __name__ == '__main__':
main()
@@ -0,0 +1,199 @@
"""Validate and summarize bounded public source-location task receipts.
Requires tiktoken 0.12.0. Full replies stay in the caller-selected measurement
directory; the output retains only identities, hashes, numeric measurements and
per-call serialized JSON-RPC token/byte estimates.
"""
import argparse
import hashlib
import json
from pathlib import Path
import re
import statistics
import tiktoken
def compact(value, *, ordered=False):
return json.dumps(value, ensure_ascii=False, separators=(',', ':'), sort_keys=ordered)
def sha256(path):
digest = hashlib.sha256()
with path.open('rb') as stream:
for chunk in iter(lambda: stream.read(1024 * 1024), b''):
digest.update(chunk)
return digest.hexdigest()
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('measurement_dir', type=Path)
parser.add_argument('--repo-root', type=Path, required=True)
parser.add_argument('--output', type=Path, required=True)
args = parser.parse_args()
repo = args.repo_root.resolve()
assert tiktoken.__version__ == '0.12.0', 'Use the recorded tokenizer version'
encoder = tiktoken.get_encoding('cl100k_base')
token_cache = {}
def tokens(value, *, line=False):
document = compact(value) + ('\n' if line else '')
digest = hashlib.sha256(document.encode()).hexdigest()
if digest not in token_cache:
token_cache[digest] = len(encoder.encode(document, disallowed_special=()))
return token_cache[digest]
pins_path = repo / 'docs/verification/source-map-budgets-2026-11-09/artifacts.json'
artifacts = json.loads(pins_path.read_text())
records, semantic_answers, evidence_ids = [], {}, {}
definitions = None
input_only_definitions = None
artifact_cache = {}
receipts = sorted(args.measurement_dir.glob('r*-*.metrics.json'), key=lambda p: p.stat().st_mtime_ns)
assert len(receipts) == 18, f'Expected 18 final receipts, found {len(receipts)}'
for path in receipts:
name = path.name.removesuffix('.metrics.json')
selected = re.fullmatch(r'r([123])-(theme|index|DateSelect)-(complete|summary)', name)
assert selected, name
trial, case, detail = int(selected[1]), selected[2], selected[3]
metric = json.loads(path.read_text())
trace_path = path.with_name(name + '.replies.json')
trace = json.loads(trace_path.read_text())
assert metric['exit_code'] == 0 and metric['cleanup'] == 'group_empty'
assert metric['stop_reason'] is None and metric['observer_error'] is None
assert metric['signal_errors'] == [] and metric['remaining_group_pids'] == []
assert trace['config']['select'] == case + '.' and trace['config']['detail'] == detail
answer = trace['answer']
artifact = next(item for item in artifacts if case + '.' in item['path'])
assert answer['source_map_sha256'] == artifact['sha256']
assert answer['lookup']['requested'] == artifact['point']
assert answer['lookup']['matched_generated_position'] == artifact['point']
assert len(answer['matches']) == len(artifact['expected_matches'])
if case not in artifact_cache:
raw_path = Path(trace['config']['artifactDir']) / artifact['path']
assert sha256(raw_path) == artifact['sha256']
artifact_cache[case] = json.loads(raw_path.read_text())
raw = artifact_cache[case]
for index, (actual, expected) in enumerate(zip(answer['matches'], artifact['expected_matches'])):
assert actual['state'] == ('generated-only' if expected.get('generated_only') else 'mapped')
if expected.get('generated_only'):
continue
assert actual['match_index'] == index
assert actual['source_index'] == expected['source_index']
assert actual['reported_source'] == expected['source']
assert actual['original_position']['line'] == expected['original_line']
assert actual['original_position']['column'] == expected['original_column']
body = raw['sourcesContent'][expected['source_index']]
assert hashlib.sha256(body.encode()).hexdigest() == expected['content_sha256']
assert actual['content']['utf8_sha256'] == expected['content_sha256']
snippet = actual['content']['snippet']
encoded = body.encode('utf-16-le')
start, length = snippet['offset_utf16'], snippet['length_utf16']
assert snippet['text'] == encoded[start * 2:(start + length) * 2].decode('utf-16-le')
assert length == 512, 'These pinned tasks require a 512-unit snippet'
assert start <= actual['original_position']['offset'] <= start + length
assert actual['content']['code_units'] == len(encoded) // 2
semantic = {key: answer[key] for key in ['evidence_id', 'source_map_sha256', 'lookup', 'matches']}
semantic_digest = hashlib.sha256(compact(semantic, ordered=True).encode()).hexdigest()
if case in semantic_answers:
assert semantic_digest == semantic_answers[case], f'Answer mismatch in {name}'
assert answer['evidence_id'] == evidence_ids[case]
else:
semantic_answers[case], evidence_ids[case] = semantic_digest, answer['evidence_id']
catalog = next(call['reply']['result'] for call in trace['calls'] if call['request']['method'] == 'tools/list')
chosen_definitions = {tool: next(item for item in catalog['tools'] if item['name'] == tool) for tool in ['trace_web_source_location', 'inspect_analysis_view']}
definition_counts = {tool: tokens(definition) for tool, definition in chosen_definitions.items()}
input_only_counts = {tool: tokens({key: definition[key] for key in ['name', 'description', 'inputSchema']}) for tool, definition in chosen_definitions.items()}
if definitions is None:
definitions = definition_counts
input_only_definitions = input_only_counts
else:
assert definitions == definition_counts
assert input_only_definitions == input_only_counts
rows, seen_catalog = [], False
used_tools = set()
for call in trace['calls']:
request, reply = call['request'], call['reply']
operation = request.get('params', {}).get('name', request['method'])
request_count = tokens(request, line=True)
reply_count = tokens(reply, line=True) if reply is not None else 0
post_discovery = seen_catalog
if request['method'] == 'tools/list':
seen_catalog = True
if request['method'] == 'tools/call':
used_tools.add(operation)
if reply is not None and request['method'] == 'tools/call' and not reply['result'].get('isError'):
normalized = reply['result']['structuredContent']['normalized_result']
source_report = normalized.get('source_location', normalized.get('summary', normalized))
assert source_report['source']['sha256'] == artifact['generated_script']['sha256']
assert source_report['source_map']['sha256'] == artifact['sha256']
rows.append({
'operation': operation, 'post_discovery': post_discovery,
'request_tokens_estimated': request_count, 'reply_tokens_estimated': reply_count,
'request_bytes_compact_json_line': len((compact(request) + '\n').encode()),
'reply_bytes_observed_wire': call['wire_bytes'],
'reply_bytes_reserialized_json_line': len((compact(reply) + '\n').encode()) if reply is not None else 0,
'elapsed_ms': call['elapsed_ms'],
'is_error': reply is not None and reply.get('result', {}).get('isError', False),
})
if operation == 'trace_web_source_location' and reply is not None:
result = reply['result']
if not result.get('isError') and detail == 'complete':
text = result['structuredContent']['raw_result']['source_map_text']
assert hashlib.sha256(text.encode()).hexdigest() == artifact['sha256']
total = sum(row['request_tokens_estimated'] + row['reply_tokens_estimated'] for row in rows)
post = sum(row['request_tokens_estimated'] + row['reply_tokens_estimated'] for row in rows if row['post_discovery'])
assert used_tools <= chosen_definitions.keys()
records.append({
'name': name, 'trial': trial, 'artifact': case, 'detail': detail,
'evidence_id': answer['evidence_id'], 'map_sha256': artifact['sha256'], 'generated_script_sha256': artifact['generated_script']['sha256'], 'answer_sha256': semantic_digest,
'receipt_sha256': sha256(path), 'reply_trace_sha256': sha256(trace_path),
'task_tokens_catalog_included_estimated': total, 'post_discovery_tokens_estimated': post,
'used_tool_definitions_tokens_estimated': sum(definitions[tool] for tool in used_tools),
'post_discovery_plus_used_definitions_tokens_estimated': post + sum(definitions[tool] for tool in used_tools),
'hypothetical_used_input_only_definitions_tokens_estimated': sum(input_only_definitions[tool] for tool in used_tools),
'hypothetical_post_discovery_plus_used_input_only_definitions_tokens_estimated': post + sum(input_only_definitions[tool] for tool in used_tools),
'tool_calls': sum(call['request']['method'] == 'tools/call' for call in trace['calls']),
'elapsed_seconds': metric['elapsed_seconds'], 'cpu_seconds_waited_subtree': metric['cpu_seconds_waited_subtree'],
'peak_process_group_rss_bytes_sampled': metric['peak_process_group_rss_bytes_sampled'],
'peak_process_tree_rss_bytes_sampled': metric['peak_process_tree_rss_bytes_sampled'],
'maximum_group_members_sampled': metric['maximum_group_members_sampled'],
'maximum_tree_members_sampled': metric['maximum_tree_members_sampled'],
'sample_count': metric['sample_count'], 'exit_code': metric['exit_code'], 'cleanup': metric['cleanup'], 'stop_reason': metric['stop_reason'],
'calls': rows,
})
groups = {}
for record in records:
groups.setdefault(record['artifact'] + '-' + record['detail'], []).append(record)
fields = ['post_discovery_plus_used_definitions_tokens_estimated', 'hypothetical_used_input_only_definitions_tokens_estimated', 'hypothetical_post_discovery_plus_used_input_only_definitions_tokens_estimated', 'task_tokens_catalog_included_estimated', 'post_discovery_tokens_estimated', 'used_tool_definitions_tokens_estimated', 'tool_calls', 'elapsed_seconds', 'cpu_seconds_waited_subtree', 'peak_process_group_rss_bytes_sampled', 'peak_process_tree_rss_bytes_sampled']
medians = {name: {'runs': len(group), **{field: statistics.median(record[field] for record in group) for field in fields}} for name, group in groups.items()}
assert all(len(group) == 3 for group in groups.values()) and len(groups) == 6
recorded_runtime = json.loads((args.measurement_dir / 'runtime.json').read_text())
paths = ['scripts/verify/analysis/source-location-delivery/task.mjs', 'scripts/verify/analysis/budget-calibration-run.py', 'scripts/rea.mjs', 'dist/cli.js', 'dist/mcp/main.js', 'src/application/WebSourceLocationService.ts', 'src/domain/analysisView/webSourceLocationView.ts', 'src/application/analysisView/AnalysisViewService.ts', 'src/contracts/webScriptToolContracts.ts', 'src/server/ToolResultDelivery.ts', 'src/server/toolResult.ts', 'src/domain/sourceMapLimits.ts', 'src/server/registerWebSourceLocationTool.ts', 'src/cli/webSourceLocationCommands.ts', 'scripts/verify/analysis/source-location-delivery/aggregate.py', 'package-lock.json', 'docs/verification/source-map-budgets-2026-11-09/artifacts.json']
hashes = {path: sha256(repo / path) for path in paths}
assert hashes[paths[0]] == recorded_runtime['driver_sha256']
assert hashes[paths[1]] == recorded_runtime['observer_sha256']
if recorded_runtime.get('cli_sha256') is not None:
assert hashes['dist/cli.js'] == recorded_runtime['cli_sha256']
tree = [(path.relative_to(repo / 'dist').as_posix(), sha256(path)) for path in sorted((repo / 'dist').rglob('*')) if path.is_file()]
tree_digest = hashlib.sha256(''.join(path + '\0' + digest + '\n' for path, digest in tree).encode()).hexdigest()
output = {
'schema': 'rea-source-location-delivery-calibration/v1',
'token_accounting': {'library': 'tiktoken', 'version': tiktoken.__version__, 'encoding': 'cl100k_base', 'representation': 'compact Unicode JSON-RPC request/reply envelopes with trailing newline; initialized notification has no reply; estimates, not model billing', 'whole_catalog_included': 'initialize + initialized notification + tools/list + every trace/continuation/text call', 'post_discovery': 'all requests/replies after tools/list; excludes discovery only, not recovery', 'selected_definitions': 'complete serialized trace_web_source_location and inspect_analysis_view definitions counted separately; do not add them again to whole-catalog totals; client cached/deferred tool presentation may differ'},
'runtime': {'recorded_runtime': recorded_runtime, 'sha256': hashes, 'compiled_tree': {'root': 'dist', 'files': len(tree), 'sha256': tree_digest, 'encoding': 'sorted relative UTF-8 filename + NUL + lowercase SHA256 + newline for every regular file, then SHA256'}},
'conditions': {'host': metric['platform'], 'node': 'v24.22.1', 'runs': 'three fresh-process runs; second trial reverses variant order; OS caches not flushed; no disk-cold claim', 'task': 'all equal-position mappings and exact source/map identity plus 512 UTF-16 units around each mapped point', 'comparison': 'current complete delivery including bounded retained-view overflow recovery versus opt-in summary; not the older export-only fallback', 'profiles': {'tool_catalog': 'full', 'input_schema': 'compact', 'output_schema': 'full', 'response_budget_bytes': 10485760}, 'observer': {'interval_seconds': 0.02, 'wall_deadline_seconds': 90, 'memory_early_stop_bytes': 1536 * 1024 * 1024, 'signal_scope': 'owned process group only', 'rss': 'simultaneous ps-snapshot group/tree sums; tree includes linked-PPID codec descendants outside root PGID; can miss short peaks/exited/reparented/orphaned descendants and double-count shared pages', 'cpu': 'wait4 user+system waited subtree, excluding sampler and unwaited/orphaned descendants', 'memory_guard': 'group early stop; observational tree RSS is not signal authority or a hard/kernel peak limit'}},
'selected_definition_tokens_estimated': definitions,
'hypothetical_input_only_definition_tokens_estimated': input_only_definitions,
'hypothetical_input_only_definition_projection': 'Only {name, description, inputSchema} from captured definitions; not an observed client/model transformation or a measured alternate discovery workflow',
'observed_completion_order': [record['name'] for record in records],
'validation': {'completed_runs': len(records), 'same_answer_and_parent_id_across_variants_and_trials': True, 'independent_artifact_oracle_and_snippets_verified': True, 'successful_complete_initial_raw_map_sha256_verified': True, 'all_owned_groups_empty': True, 'all_resource_stops': None},
'medians': medians, 'records': records,
}
args.output.parent.mkdir(parents=True, exist_ok=True)
args.output.write_text(json.dumps(output, ensure_ascii=False, indent=2) + '\n')
print(json.dumps({'medians': medians, 'selected_definitions': definitions, 'compiled_tree': output['runtime']['compiled_tree']}, indent=2))
if __name__ == '__main__':
main()
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,426 @@
import { spawn } from "node:child_process";
import { readFile, writeFile } from "node:fs/promises";
import { createHash } from "node:crypto";
import assert from "node:assert/strict";
import { isAbsolute, join, relative, resolve, sep } from "node:path";
// Acquire artifactDir with docs/verification/source-map-budgets-2026-11-09/acquire.py.
// This driver runs the public compiled stdio workflow; no target application is executed.
const [rootArgument, configText, ...extra] = process.argv.slice(2);
assert(
rootArgument && configText && extra.length === 0,
"Usage: node task.mjs REPO_ROOT CONFIG_JSON",
);
const root = resolve(rootArgument);
const config = JSON.parse(configText);
assert(
config && typeof config === "object" && !Array.isArray(config),
"CONFIG_JSON must be an object",
);
const allowed = new Set([
"artifactDir",
"select",
"detail",
"resultPath",
"exportPath",
"maxResponseBytes",
]);
assert(
Object.keys(config).every((key) => allowed.has(key)),
"Unknown task configuration field",
);
assert(
typeof config.artifactDir === "string" && isAbsolute(config.artifactDir),
"artifactDir must be an absolute acquired-artifact directory",
);
assert(
typeof config.select === "string" &&
config.select.length > 0 &&
config.select.length <= 256,
"select must be a nonempty artifact filename selector, at most 256 characters",
);
assert(
config.detail === "complete" || config.detail === "summary",
"detail must be complete or summary",
);
for (const key of ["resultPath", "exportPath"]) {
assert(
config[key] === undefined ||
(typeof config[key] === "string" && isAbsolute(config[key])),
`${key} must be an absolute path when selected`,
);
}
const MAX_LINE_BYTES = 32 * 1024 * 1024;
const RPC_TIMEOUT_MS = 45000;
assert(
config.maxResponseBytes === undefined ||
(Number.isSafeInteger(config.maxResponseBytes) &&
config.maxResponseBytes >= 10 * 1024 * 1024 &&
config.maxResponseBytes <= MAX_LINE_BYTES),
"maxResponseBytes must fit the driver receive guard: integer 10..32 MiB",
);
const sources = JSON.parse(
await readFile(join(config.artifactDir, "artifacts.json"), "utf8"),
);
assert(
Array.isArray(sources),
"artifacts.json must be the retained artifact list",
);
const selected = sources.filter(
(source) =>
typeof source.path === "string" && source.path.includes(config.select),
);
assert.equal(
selected.length,
1,
"select must identify exactly one pinned artifact",
);
const source = selected[0];
assert(
source.generated_script,
"Selected point task requires an acquired generated script and analyst manifest",
);
const localFile = (path) => {
assert(
typeof path === "string" && !isAbsolute(path),
"Artifact manifest paths must be relative",
);
const resolved = resolve(config.artifactDir, path);
assert(
!relative(config.artifactDir, resolved).startsWith(".." + sep) &&
resolved !== resolve(config.artifactDir, ".."),
"Artifact path must stay within artifactDir",
);
return resolved;
};
const mapPath = localFile(source.path);
const bytes = await readFile(mapPath);
assert.equal(bytes.length, source.bytes);
assert.equal(createHash("sha256").update(bytes).digest("hex"), source.sha256);
const artifact = JSON.parse(bytes.toString("utf8"));
const manifestPath = localFile(source.generated_script.path + ".manifest.json");
const child = spawn(process.execPath, [join(root, "scripts/rea.mjs"), "mcp"], {
cwd: root,
env: {
...process.env,
REA_LOG_LEVEL: "silent",
REA_MCP_TOOL_CATALOG_PROFILE: "full",
REA_MCP_INPUT_SCHEMA_PROFILE: "compact",
REA_MCP_OUTPUT_SCHEMA_PROFILE: "full",
...(config.maxResponseBytes === undefined
? {}
: { REA_MCP_MAX_RESPONSE_BYTES: String(config.maxResponseBytes) }),
HOPPER_LAUNCHER_PATH: "/rea-unconfigured-deep-provider/hopper",
GHIDRA_INSTALL_DIR: process.execPath,
},
stdio: ["pipe", "pipe", "pipe"],
});
let buffer = "",
sequence = 0,
stderr = "";
const pending = new Map(),
calls = [];
const failPending = (error) => {
for (const request of pending.values()) request.reject(error);
pending.clear();
};
child.stdout.setEncoding("utf8");
child.stderr.setEncoding("utf8");
child.stderr.on("data", (chunk) => {
stderr = (stderr + chunk).slice(-8192);
});
child.once("error", failPending);
child.once("exit", (code, signal) =>
failPending(
new Error(
`MCP server exited (${String(code)}, ${String(signal)}): ${stderr}`,
),
),
);
child.stdin.on("error", failPending);
child.stdout.on("data", (chunk) => {
try {
buffer += chunk;
assert(
Buffer.byteLength(buffer) < MAX_LINE_BYTES,
"32 MiB RPC line guard exceeded",
);
let end;
while ((end = buffer.indexOf("\n")) >= 0) {
const line = buffer.slice(0, end);
buffer = buffer.slice(end + 1);
if (!line) continue;
const payload = JSON.parse(line),
request = pending.get(payload.id);
if (request) {
pending.delete(payload.id);
request.resolve({ payload, wireBytes: Buffer.byteLength(line) + 1 });
}
}
} catch (error) {
failPending(error);
}
});
const rpc = async (method, params = {}) => {
const request = { jsonrpc: "2.0", id: ++sequence, method, params },
start = performance.now();
const waiting = new Promise((resolveReply, rejectReply) => {
const timer = setTimeout(() => {
pending.delete(request.id);
rejectReply(new Error(`RPC timeout ${method}: ${stderr}`));
}, RPC_TIMEOUT_MS);
pending.set(request.id, {
resolve: (value) => {
clearTimeout(timer);
resolveReply(value);
},
reject: (error) => {
clearTimeout(timer);
rejectReply(error);
},
});
});
child.stdin.write(JSON.stringify(request) + "\n");
const { payload, wireBytes } = await waiting;
assert(!payload.error, JSON.stringify(payload.error));
calls.push({
request,
reply: payload,
wire_bytes: wireBytes,
elapsed_ms: performance.now() - start,
});
return payload.result;
};
const errorOf = (r) =>
r.isError
? JSON.parse(r.content.find((c) => c.type === "text").text).error
: undefined;
const contentOf = (r) => {
assert(!r.isError, JSON.stringify(errorOf(r)));
return r.structuredContent;
};
try {
await rpc("initialize", {
protocolVersion: "2025-03-26",
capabilities: {},
clientInfo: { name: "source-location-completed-task", version: "1" },
});
const initialized = { jsonrpc: "2.0", method: "notifications/initialized" };
child.stdin.write(JSON.stringify(initialized) + "\n");
calls.push({
request: initialized,
reply: null,
wire_bytes: 0,
elapsed_ms: 0,
});
const catalog = await rpc("tools/list");
const definition = catalog.tools.find(
(t) => t.name === "trace_web_source_location",
);
assert(definition);
const args = {
manifest_path: manifestPath,
script_index: 0,
source_map: { path: mapPath, url: source.url },
generated_position: source.point,
...(config.detail === "summary" ? { detail: "summary" } : {}),
};
const initial = await rpc("tools/call", {
name: "trace_web_source_location",
arguments: args,
});
const error = errorOf(initial);
let evidenceId,
report,
metadata = [],
coverage;
if (error) {
assert.equal(error.code, "resource_constraint");
const limits = error.details.reported_limits;
evidenceId = limits.evidence_id;
assert(evidenceId);
const continuation = limits.continuation;
assert(continuation, "new source-location continuation required");
const first = contentOf(
await rpc("tools/call", {
name: continuation.name,
arguments: continuation.arguments,
}),
).normalized_result;
report = first.source_location;
metadata = [...first.items];
coverage = first.coverage;
} else {
const evidence = contentOf(initial),
result = evidence.normalized_result;
if (config.detail === "summary") {
evidenceId = result.parent_evidence_id;
report = result.summary;
metadata = [...report.matches];
coverage = result.coverage;
} else {
assert.equal(
createHash("sha256")
.update(evidence.raw_result.source_map_text)
.digest("hex"),
source.sha256,
"Complete initial MCP response must preserve exact raw map bytes",
);
evidenceId = evidence.evidence_id;
report = result;
metadata = [...report.matches];
coverage = { exhausted: true };
}
}
const reference = { kind: "retained-evidence", evidence_id: evidenceId };
while (!coverage.exhausted) {
const page = contentOf(
await rpc("tools/call", {
name: "inspect_analysis_view",
arguments: {
source: reference,
view: {
kind: "source-location",
collection: "matches",
offset: coverage.next_offset,
limit: 64,
},
},
}),
).normalized_result;
metadata.push(...page.items);
coverage = page.coverage;
}
assert.equal(report.source_map.sha256, source.sha256);
assert.equal(metadata.length, source.expected_matches.length);
const answer = [];
for (let index = 0; index < metadata.length; index++) {
const match = metadata[index],
expected = source.expected_matches[index];
assert.equal(
match.state,
expected.generated_only ? "generated-only" : "mapped",
);
if (match.state === "generated-only") {
answer.push(match);
continue;
}
assert.equal(match.source_index, expected.source_index);
assert.equal(match.reported_source, expected.source);
assert.equal(match.original_position.line, expected.original_line);
assert.equal(match.original_position.column, expected.original_column);
assert.equal(match.content.utf8_sha256, expected.content_sha256);
const full = artifact.sourcesContent[expected.source_index],
point = match.original_position.offset;
assert(point !== null);
let offset = Math.max(0, point - 256);
if (
offset > 0 &&
full.charCodeAt(offset) >= 0xdc00 &&
full.charCodeAt(offset) <= 0xdfff
)
offset--;
let snippet;
if ("text" in match.content) {
assert.equal(
createHash("sha256").update(match.content.text).digest("hex"),
expected.content_sha256,
);
let end = Math.min(full.length, offset + 512);
if (
end < full.length &&
full.charCodeAt(end - 1) >= 0xd800 &&
full.charCodeAt(end - 1) <= 0xdbff
)
end--;
snippet = match.content.text.slice(offset, end);
} else {
const text = contentOf(
await rpc("tools/call", {
name: "inspect_analysis_view",
arguments: {
source: reference,
view: {
kind: "source-location",
collection: "source-text",
match_index: match.match_index,
offset,
limit: 512,
},
},
}),
).normalized_result;
assert.equal(text.match.content.utf8_sha256, expected.content_sha256);
snippet = text.item.text;
}
assert.equal(snippet, full.slice(offset, offset + snippet.length));
assert(offset <= point && offset + snippet.length >= point);
const { text: _text, ...identity } = match.content;
answer.push({
...match,
match_index: index,
content: {
...identity,
code_units: full.length,
snippet: {
offset_utf16: offset,
length_utf16: snippet.length,
text: snippet,
},
},
});
}
let exported = false;
if (config.exportPath) {
const result = await rpc("tools/call", {
name: "export_evidence_bundle",
arguments: { path: config.exportPath },
});
assert(!result.isError);
const bundle = JSON.parse(await readFile(config.exportPath, "utf8"));
const parent = bundle.records.find((r) => r.evidence_id === evidenceId);
assert(parent);
assert.equal(
createHash("sha256")
.update(parent.raw_result.source_map_text)
.digest("hex"),
source.sha256,
);
exported = true;
}
const result = {
config,
evidence_id: evidenceId,
source_map_sha256: source.sha256,
lookup: report.lookup,
matches: answer,
export_verified: exported,
calls: calls.map((c) => ({
method: c.request.method,
tool: c.request.params?.name,
wire_bytes: c.wire_bytes,
elapsed_ms: c.elapsed_ms,
isError: c.reply?.result?.isError ?? false,
})),
};
if (config.resultPath)
await writeFile(
config.resultPath,
JSON.stringify({ config, definition, calls, answer: result }),
{ flag: "wx" },
);
console.log(JSON.stringify(result));
} finally {
child.stdin.end();
if (child.exitCode === null && child.signalCode === null)
await new Promise((resolve, reject) => {
const timer = setTimeout(() => {
child.kill("SIGTERM");
reject(Error("MCP close timeout"));
}, 5000);
child.once("exit", () => {
clearTimeout(timer);
resolve();
});
});
}
+2 -2
View File
@@ -140,10 +140,10 @@ check(
// inputBytes values with a different policy (an overridable pwntools admission,
// historical capture intake) are not this budget.
check(
"inline resident-input budget (use BOUNDED_PRODUCER_LIMITS from src/process/LinuxResourceLimits)",
"inline resident-input budget (use BOUNDED_PRODUCER_LIMITS from src/domain/producerResourceLimits)",
files,
/input_bytes:\s*32 \* 1024 \* 1024/,
["src/process/LinuxResourceLimits.ts"],
["src/domain/producerResourceLimits.ts"],
);
// Fixed-arity backtick keys audited 2026-10-10: every prefix field is NUL-free
-49
View File
@@ -1,52 +1,3 @@
export const inspectionLimits = {
referenceOffset: 0,
referenceLimit: 100,
resourceOffset: 0,
resourceLimit: 100,
attributeOffset: 0,
attributeLimit: 100,
maxMetadataBytes: 1024 * 1024,
maxTableRows: 1_000,
maxHeapItemBytes: 1024 * 1024,
};
export const memberLimits = {
typeOffset: 0,
typeLimit: 100,
methodOffset: 0,
methodLimit: 100,
fieldOffset: 0,
fieldLimit: 100,
memberRefOffset: 0,
memberRefLimit: 100,
edgeOffset: 0,
edgeLimit: 100,
instructionAnchorLimit: 100,
maxMetadataBytes: 1024 * 1024,
maxTableRows: 1_000,
maxHeapItemBytes: 1024 * 1024,
maxMethodBodyBytes: 1024 * 1024,
maxMethodInstructions: 1_000,
};
export const nativeBoundaryLimits = {
moduleRefOffset: 0,
moduleRefLimit: 100,
importOffset: 0,
importLimit: 100,
implementationOffset: 0,
implementationLimit: 100,
maxMetadataBytes: 1024 * 1024,
maxTableRows: 1_000,
maxHeapItemBytes: 1024 * 1024,
};
export const comparisonLimits = {
max_method_matches: 100,
max_field_matches: 100,
max_candidates: 20,
};
export const defaultIlBody = Buffer.from([
0x32, 0x02, 0x7b, 0x01, 0x00, 0x00, 0x04, 0x28, 0x01, 0x00, 0x00, 0x0a, 0x2a,
]);
+4 -31
View File
@@ -19,13 +19,7 @@ import {
buildNativePeFixture,
} from "../../fixtures/managed/pe.mjs";
import { createManagedConformanceSupport } from "./support.mjs";
import {
comparisonLimits,
defaultIlBody,
inspectionLimits,
memberLimits,
nativeBoundaryLimits,
} from "./config.mjs";
import { defaultIlBody } from "./config.mjs";
import { createManagedCompletionReport } from "./completion-report.mjs";
import {
completeVerifierRun,
@@ -45,8 +39,6 @@ const {
sha256,
} = createManagedConformanceSupport({
workspace,
inspectionLimits,
memberLimits,
defaultIlBody,
});
@@ -58,7 +50,6 @@ try {
const modernArtifact = inspectManagedArtifactBytes(
modern.bytes,
modern.target,
inspectionLimits,
);
assert.equal(modernArtifact.classification.status, "managed");
assert.equal(modernArtifact.classification.runtime_family, "modern-dotnet");
@@ -83,7 +74,6 @@ try {
const frameworkArtifact = inspectManagedArtifactBytes(
framework.bytes,
framework.target,
inspectionLimits,
);
assert.equal(
frameworkArtifact.classification.runtime_family,
@@ -93,7 +83,6 @@ try {
const frameworkBoundaries = inspectManagedNativeBoundariesBytes(
framework.bytes,
framework.target,
nativeBoundaryLimits,
);
assert.equal(frameworkBoundaries.pinvoke_imports.length, 1);
assert.equal(
@@ -108,14 +97,13 @@ try {
const frameworkMembers = inspectManagedMembersBytes(
framework.bytes,
framework.target,
memberLimits,
);
const frameworkArtifactEvidence = createEvidence(
framework.target,
MANAGED_STATIC_PROVIDER,
{
operation: "inspect_managed_artifact",
parameters: inspectionLimits,
parameters: {},
result: frameworkArtifact,
rawResult: null,
limitations: frameworkArtifact.limitations,
@@ -127,7 +115,7 @@ try {
MANAGED_STATIC_PROVIDER,
{
operation: "inspect_managed_members",
parameters: memberLimits,
parameters: {},
result: frameworkMembers,
rawResult: null,
limitations: frameworkMembers.limitations,
@@ -139,7 +127,7 @@ try {
MANAGED_STATIC_PROVIDER,
{
operation: "inspect_managed_native_boundaries",
parameters: nativeBoundaryLimits,
parameters: {},
result: frameworkBoundaries,
rawResult: null,
limitations: frameworkBoundaries.limitations,
@@ -221,7 +209,6 @@ try {
const r2rArtifact = inspectManagedArtifactBytes(
readyToRun.bytes,
readyToRun.target,
inspectionLimits,
);
assert.equal(r2rArtifact.pe.architecture, "x86_64");
assert.equal(
@@ -231,7 +218,6 @@ try {
const r2rBoundaries = inspectManagedNativeBoundariesBytes(
readyToRun.bytes,
readyToRun.target,
nativeBoundaryLimits,
);
assert.equal(r2rBoundaries.summary.ready_to_run, true);
assert.equal(r2rBoundaries.native_implementations[0]?.code_type, "native");
@@ -248,7 +234,6 @@ try {
const obfuscatedMembers = inspectManagedMembersBytes(
obfuscated.bytes,
obfuscated.target,
memberLimits,
);
assert.equal(obfuscatedMembers.types[0]?.full_name, "Fixture.ꙮType");
assert.equal(obfuscatedMembers.methods[0]?.name, "λ⛧");
@@ -309,11 +294,6 @@ try {
const comparison = await compareManagedMemberPaths({
leftPath: left.path,
rightPath: right.path,
memberLimits: {
maxFileBytes: 1024 * 1024,
...memberLimits,
},
comparisonLimits,
});
assert.equal(comparison.ok, true);
const comparisonResult = comparison.value.normalized_result;
@@ -341,11 +321,6 @@ try {
const partialBodyComparison = await compareManagedMemberPaths({
leftPath: unavailableBodyLeft.path,
rightPath: unavailableBodyRight.path,
memberLimits: {
maxFileBytes: 1024 * 1024,
...memberLimits,
},
comparisonLimits,
});
assert.equal(partialBodyComparison.ok, true);
const partialBodyMethod =
@@ -363,7 +338,6 @@ try {
const nativeResult = inspectManagedArtifactBytes(
nativeOnly.bytes,
nativeOnly.target,
inspectionLimits,
);
assert.equal(nativeResult.classification.status, "not-managed");
@@ -373,7 +347,6 @@ try {
const malformedResult = inspectManagedArtifactBytes(
malformed.bytes,
malformed.target,
inspectionLimits,
);
assert.equal(malformedResult.classification.status, "malformed");
+10 -38
View File
@@ -14,13 +14,7 @@ import {
parseManagedAppManifest,
} from "./manifest-parser.mjs";
export const createManagedManifestVerifier = (context) => ({
verifyManagedAppManifest: (rawManifest, manifestPath) =>
verifyManagedAppManifest(context, rawManifest, manifestPath),
});
async function verifyManagedAppManifest(context, rawManifest, manifestPath) {
const { appManifestInspectionLimits } = context;
export async function verifyManagedAppManifest(rawManifest, manifestPath) {
const manifest = parseManagedAppManifest(rawManifest);
const targetPath = isAbsolute(manifest.target.path)
? manifest.target.path
@@ -36,25 +30,15 @@ async function verifyManagedAppManifest(context, rawManifest, manifestPath) {
`target sha256 mismatch: expected ${manifest.target.sha256}, observed ${target.sha256}`,
);
const bytes = await readFile(targetPath);
const artifact = inspectManagedArtifactBytes(
bytes,
target,
appManifestInspectionLimits,
);
const artifact = inspectManagedArtifactBytes(bytes, target);
verifyManifestTarget(manifest, artifact);
const methodVerification = verifyManifestMethods(
context,
manifest,
bytes,
target,
);
const methodVerification = verifyManifestMethods(manifest, bytes, target);
const { methods, inspectedMethods } = methodVerification;
let assertions = 1 + methodVerification.assertions;
const applicationGraph =
manifest.application_graph === undefined
? undefined
: verifyManagedAppManifestApplicationGraph({
context,
graphManifest: manifest.application_graph,
bytes,
target,
@@ -109,17 +93,12 @@ function verifyManifestTarget(manifest, artifact) {
);
}
function verifyManifestMethods(context, manifest, bytes, target) {
function verifyManifestMethods(manifest, bytes, target) {
const methods = [];
let assertions = 0;
const inspectedMethods = new Map();
for (const expectedMethod of manifest.methods) {
const method = inspectManagedMethodByToken(
context,
bytes,
target,
expectedMethod,
);
const method = inspectManagedMethodByToken(bytes, target, expectedMethod);
ensure(
method.signature.raw_sha256 === expectedMethod.signature_sha256,
`method ${expectedMethod.token} signature sha256 mismatch: expected ${expectedMethod.signature_sha256}, observed ${method.signature.raw_sha256}`,
@@ -154,7 +133,6 @@ function verifyManifestMethods(context, manifest, bytes, target) {
}
function verifyManagedAppManifestApplicationGraph({
context,
graphManifest,
bytes,
target,
@@ -164,7 +142,6 @@ function verifyManagedAppManifestApplicationGraph({
}) {
const graphByToken = new Map();
const projectionState = {
context,
graphByToken,
inspectedMethods,
bytes,
@@ -238,8 +215,6 @@ function verifyManagedAppManifestApplicationGraph({
}
const projectManifestMethod = (state, token) => {
const { appManifestInspectionLimits, appManifestMemberLimits } =
state.context;
const existing = state.graphByToken.get(token);
if (existing !== undefined) return existing;
const method = state.inspectedMethods.get(token);
@@ -248,7 +223,6 @@ const projectManifestMethod = (state, token) => {
`application graph method ${token} must also be declared in manifest.methods`,
);
const members = inspectManagedMethodPageByToken(
state.context,
state.bytes,
state.target,
token,
@@ -258,7 +232,7 @@ const projectManifestMethod = (state, token) => {
MANAGED_STATIC_PROVIDER,
{
operation: "inspect_managed_artifact",
parameters: appManifestInspectionLimits,
parameters: {},
result: state.artifact,
rawResult: null,
limitations: state.artifact.limitations,
@@ -268,7 +242,7 @@ const projectManifestMethod = (state, token) => {
const memberEvidence = createEvidence(state.target, MANAGED_STATIC_PROVIDER, {
operation: "inspect_managed_members",
parameters: {
...appManifestMemberLimits,
methodLimit: 1,
methodOffset: methodTokenRow(token) - 1,
},
result: members,
@@ -298,9 +272,8 @@ const projectManifestMethod = (state, token) => {
return projection;
};
function inspectManagedMethodByToken(context, bytes, target, expectedMethod) {
function inspectManagedMethodByToken(bytes, target, expectedMethod) {
const members = inspectManagedMethodPageByToken(
context,
bytes,
target,
expectedMethod.token,
@@ -319,11 +292,10 @@ function inspectManagedMethodByToken(context, bytes, target, expectedMethod) {
return method;
}
function inspectManagedMethodPageByToken(context, bytes, target, token) {
const { appManifestMemberLimits } = context;
function inspectManagedMethodPageByToken(bytes, target, token) {
const row = methodTokenRow(token);
return inspectManagedMembersBytes(bytes, target, {
...appManifestMemberLimits,
methodLimit: 1,
methodOffset: row - 1,
});
}
+7 -26
View File
@@ -10,13 +10,12 @@ import { inspectManagedMembersBytes } from "../../../dist/dotnet/ManagedMemberIn
import { importManagedReconstructionEvidence } from "../../../dist/application/managed/ManagedReconstructionService.js";
import { createEvidence } from "../../../dist/domain/evidence.js";
import { MANAGED_STATIC_PROVIDER } from "../../../dist/domain/investigationProviders.js";
import { createManagedManifestVerifier } from "./manifest.mjs";
import { verifyManagedAppManifest } from "./manifest.mjs";
const execFileAsync = promisify(execFile);
export const createManagedConformanceOracleSupport = (context) => {
const verifier = createManagedManifestVerifier(context);
const support = { ...context, ...verifier };
const support = { ...context, verifyManagedAppManifest };
return {
runManagedAppManifestSelfTest: () => runManagedAppManifestSelfTest(support),
runOptionalManagedAppManifest: () => runOptionalManagedAppManifest(support),
@@ -29,16 +28,8 @@ async function runManagedAppManifestSelfTest(context) {
methodName: "PinnedSemanticSlice",
ilBody: context.defaultIlBody,
});
const artifact = inspectManagedArtifactBytes(
sample.bytes,
sample.target,
context.inspectionLimits,
);
const members = inspectManagedMembersBytes(
sample.bytes,
sample.target,
context.memberLimits,
);
const artifact = inspectManagedArtifactBytes(sample.bytes, sample.target);
const members = inspectManagedMembersBytes(sample.bytes, sample.target);
const method = members.methods[0];
assert.ok(method);
const summary = await context.verifyManagedAppManifest(
@@ -132,16 +123,8 @@ async function runOptionalIlspyOracle(context) {
const sample = await context.fixture("ilspy-oracle.exe", {
methodName: "PinnedSemanticSlice",
});
const artifact = inspectManagedArtifactBytes(
sample.bytes,
sample.target,
context.inspectionLimits,
);
const members = inspectManagedMembersBytes(
sample.bytes,
sample.target,
context.memberLimits,
);
const artifact = inspectManagedArtifactBytes(sample.bytes, sample.target);
const members = inspectManagedMembersBytes(sample.bytes, sample.target);
const method = members.methods[0];
ensureIlspy(method !== undefined, "source-owned fixture has no method");
const listOutput = await runIlspy(
@@ -167,7 +150,6 @@ async function runOptionalIlspyOracle(context) {
"ilspycmd C# output exceeded the managed reconstruction import bound",
);
const reconstructionImport = importIlspyReconstruction({
context,
sample,
method,
members,
@@ -210,7 +192,6 @@ async function runOptionalIlspyOracle(context) {
}
function importIlspyReconstruction({
context,
sample,
method,
members,
@@ -223,7 +204,7 @@ function importIlspyReconstruction({
MANAGED_STATIC_PROVIDER,
{
operation: "inspect_managed_members",
parameters: context.memberLimits,
parameters: {},
result: members,
rawResult: null,
limitations: members.limitations,
-21
View File
@@ -17,32 +17,11 @@ export const createManagedConformanceSupport = (context) => {
const fixture = (name, options) =>
fixtureBytes(name, buildManagedPeFixture(options));
const sha256 = (bytes) => createHash("sha256").update(bytes).digest("hex");
const appManifestInspectionLimits = {
...context.inspectionLimits,
maxMetadataBytes: 64 * 1024 * 1024,
maxTableRows: 250_000,
maxHeapItemBytes: 16 * 1024 * 1024,
};
const appManifestMemberLimits = {
...context.memberLimits,
typeLimit: 1,
methodLimit: 1,
fieldLimit: 1,
memberRefLimit: 1,
edgeLimit: 1,
maxMetadataBytes: 64 * 1024 * 1024,
maxTableRows: 250_000,
maxHeapItemBytes: 16 * 1024 * 1024,
maxMethodBodyBytes: 4 * 1024 * 1024,
maxMethodInstructions: 20_000,
};
const base = {
...context,
fixture,
fixtureBytes,
sha256,
appManifestInspectionLimits,
appManifestMemberLimits,
};
return { ...base, ...createManagedConformanceOracleSupport(base) };
};