mirror of
https://github.com/morluto/rea.git
synced 2026-11-12 09:52:27 +00:00
aa017c61ff3803dea3b823664ae255c4059c19d4
102
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0909d89c96 |
fix(native): list ELF initializers of images with COPY relocations (#10084)
* fix(native): list ELF initializers of images with COPY relocations inspect-native-initializers reported every init_array and fini_array slot of a non-PIE executable as unresolved, and ordinary PIE executables as incomplete, when the image carried a COPY relocation such as the one for stdout. The shared dynamic relocation reader had no write extent for COPY or TLS descriptor relocations, so one such record made pointer coverage unknown. It now sizes a COPY from the image's own dynamic symbol and a TLS descriptor as two words. COPY sizes are accepted up to the file byte count in total, so repeated records cannot multiply consumer work. The section relocation fallback also treated a record whose destination has no file bytes, as COPY into .bss does, as an unread table. A linked image's record now affects only the slots it overlaps in memory. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT2WLf5G9AnLKF3bZtNLwf * test(native): cover a COPY relocation against symbol index 0 Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT2WLf5G9AnLKF3bZtNLwf * fix(native): size section COPY records and keep write extents opt-in Address two review findings on the COPY relocation change. The shared dynamic relocation reader yields COPY and TLS descriptor records as writes only to a consumer that asks for whole extents. The initializer walk asks. IL2CPP and the Android JNI overlay do not, so both see these kinds as not decoded, exactly as before this branch. IL2CPP finds unknown bytes by looking one pointer back from a read, so a wider write of unknown value was read as stored zeros. The section fallback takes a COPY record's span from the symbol its table links to instead of assuming one word. A table counts as not fully read when that size is not established, or when a record of unknown extent writes memory that has no file bytes. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT2WLf5G9AnLKF3bZtNLwf * refactor(native): size section COPY records in one helper Move the symbol lookup, the allowance and the unread-table note out of the record loop, so the loop only asks for the extent a record is known to write. Behavior is unchanged. Cover the allowance across two section records, and keep the new test code within the lint thresholds the base already meets. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT2WLf5G9AnLKF3bZtNLwf --------- Co-authored-by: thunderq10 <195775442+thunderq10@users.noreply.github.com> Co-authored-by: Claude Fable 5.2 <noreply@anthropic.com> |
||
|
|
7aca4cef64 |
feat(audit): report what a shipped app exposes to static analysis (#8525)
* feat(audit): report what a shipped app exposes to static analysis
Adds `audit_release_exposure` and `rea audit-release-exposure` to report
source maps, Electron fuse implications, extractable payloads, debug
information, build metadata, and credential markers. Checks carry stable
IDs, observations, statuses, and fixed remediation, while incomplete and
unassessed checks remain visible without implying a security verdict.
Credential findings include only rule IDs and locations. The CLI
supports `--fail_on` severity thresholds and exits 3 when an exposed
check meets the threshold.
* fix(audit): keep incomplete coverage unknown across text, fuses, Go flags and cancellation
Probe files with unrecognized names as text, keep undecided fuse slices
unknown, forward opaque container coverage, read paths from Go build flags,
and compare inventoried digests before accepting owner facts.
Keep typed cleanup failures and attach the partial report when a later owner
is cancelled. Pin the verifier's @electron/fuses version and move the tests
to the named contract family.
* fix(audit): match package members by source spelling and close remaining coverage gaps
Reopen package members by their source spelling and keep caller path
traversal in directory reads. Parse quoted and attached Go build flags, bind a
native image fuse read to its own digest, and keep reader resources and the
audit's partial report when cleanup or cancellation combine failures.
* fix(release-exposure): bind package members by ordinal and follow named map references
Package members were matched to container entries by sourcePath, which is
not unique in a PyInstaller executable, through a queue that only moved when
a member was reopened. Bind by container-relative path and duplicate ordinal,
the numbering inventory uses, so read order cannot change which bytes a
member gets.
A sourceMappingURL naming a file without a map extension was ignored. Local
targets are now examined as maps whatever their name, and a target already
scanned as plain text leaves coverage unknown.
* fix(release-exposure): match data: source map scheme case-insensitively
URL schemes are case-insensitive, so an inline declaration such as
//# sourceMappingURL=DATA:application/json;base64,... was routed to the
local-reference path, which ignores scheme URLs. Its embedded sources were
silently dropped and source_map_sources reported not_observed.
* fix(release-exposure): normalize declared map targets and count unreached ones
A sourceMappingURL that decodes to a decomposed name (cafe%CC%81.json)
never matched the inventoried member, whose logical path is NFC, so the
map was scanned as ordinary text and its sourcesContent went uncounted.
Map-target lookups now use an NFC key on both the record and lookup
side; the declared URL is left as written.
A declared map target that is never reached is now counted as a skipped
map, so the source-map checks read as unknown coverage instead of
not_observed.
* fix(release-exposure): recover indexed leaves after any map format failure
An indexed map whose one leaf has malformed mappings (such as AA) threw a
format failure that only recovered leaves for unsupported sections, so a
valid sibling leaf with sourcesContent was dropped and
javascript.source_map_sources read unknown instead of exposed. Leaves are
now recovered for any format failure, with the envelope parse guarded so
invalid JSON still falls through to the unparsed count.
A nested package that inventory recognized but did not expand was probed
as a plain binary and left the source-map checks at not_observed. It now
marks coverage unknown and records a limitation.
Reader tests assert the javascript.source_map_sources status for the NFC
map-name cases as well.
* fix(release-exposure): count an unexpanded nested package as a readable member
An unencrypted nested package that inventory recognized but did not
expand is still a member its parent package already read. Count it as
readable so packaging.extractable_payload reports exposed, while its
own contents keep coverage unknown.
* fix(release-exposure): bound the indexed leaf fallback by decoder limits
The fallback walk after a map format failure expanded every section and
built a full ancestor path per leaf, so a map refused for nesting depth
could still allocate far past the decoder budgets. Walk only to the
64-level section depth and the shared record budget, keeping leaf maps
without materializing section paths.
* fix(release-exposure): collect UNC roots from Go flag paths
A flag such as -I\\buildhost\sdk\include matched none of the path roots
in GO_FLAG_PATH, so a network path that was the only one in complete
build info left go.build_paths at not_observed. Accept \\host\share
roots alongside the slash-rooted, dot-relative and drive-letter forms.
* fix(release-exposure): keep Electron undecided without positive proof
The desktop owner names Electron only from an ASAR layout, so an asar: false
build has no candidate. A complete scan with no candidate was reported as
not_electron, which outranks unresolved and safe fuse outcomes and hid them
as not_applicable.
Leave the family unknown unless the fuse holder rules Electron out: an app
bundle with no Electron Framework, or a directory with complete coverage
whose native images were all read and hold no sentinel. A directory with no
native image is not proof, so its fuse checks now report unknown.
* fix(release-exposure): decode wide text members before scanning
A member's kind bypassed the NUL guard, so a UTF-16 plist was decoded as
UTF-8, matched nothing and still counted as scanned. A directory holding
only that member reported text.credential_markers as not_observed.
Decode by byte order mark at one boundary instead. UTF-16 is scanned in
either byte order, and inline maps read the same text. UTF-32 and NULs no
mark explains count as skipped, whatever the member's kind. A binary
plist keeps its raw scan. Unnamed members with a mark now reach the
scanner, and the plist decoder shares the same mark detection.
* fix(release-exposure): follow file: URL source map declarations
The scheme guard in noteLocalMapReference returned on every URL scheme, so
a declaration such as file:///release/debug.json was dropped with the remote
ones. A member without a .map name was then scanned as ordinary text and
javascript.source_map_sources reported not_observed.
Convert file: URLs with fileURLToPath and record them in mapTargets through
the same step as relative declarations. A target that is never reached, or
that was already scanned as text, counts as skipped, and so does a malformed
file: URL. A file: URL names one absolute location, so a .map target outside
the inventory stays unassessed rather than being trusted by its name. Remote
schemes stay ignored.
* fix(release-exposure): match backslash-relative Go flag paths
GO_FLAG_PATH accepted dot-relative roots only with a forward slash, so
`-I..\sdk\include` and `-I.\sdk` produced no path and go.build_paths came
back not_observed. Accept either separator after the dots.
The CLI acceptance test now expects unknown for electron.run_as_node on a
directory with no native images, matching the service.
* fix(release-exposure): keep fuses unknown on incomplete inventory
A directory inventory that stops at an acquisition limit never reports
the images it did not reach, so the native image sample has no omission
and safe fuses on an included helper settled to not_observed even though
scan coverage was unknown.
Treat unknown coverage like a truncated sample until the Electron
executable is accounted for. A selected native file is that executable,
so it keeps its decided fuse result.
* fix(release-exposure): decode binary plists before scanning
A binary plist stores each string as ASCII or UTF-16BE. Scanning the raw
bytes as UTF-8 missed any string the encoder kept in UTF-16, such as one
with a non-ASCII character, and still counted the member as fully
scanned, so text.credential_markers read not_observed.
Decode through the plist owner and scan its strings, dictionary keys and
data. A plist that cannot be decoded keeps its raw bytes in the scan and
counts as skipped, so coverage stays unknown.
* fix(release-exposure): keep UTF-8 members that hold a NUL
Any NUL in a member's first 512 bytes made the decoder give up, so a script
with a literal NUL in a string never reached the credential or inline-map
checks. An exposed marker in it read as unknown, and --fail_on high exited 0.
Validity alone cannot tell wide text from UTF-8, since ASCII in UTF-16 is
valid UTF-8. Treat a header that is an eighth or more NUL bytes as wide text
and anything not UTF-8 as undecoded, and scan the rest.
The docs now separate BOM-marked UTF-16, which is scanned, from wide text
with no byte order mark, which is not.
* fix(audit): scan every string a binary plist stores
The plist scan read only the decoded value, which drops objects the root no
longer references and entries a later duplicate key replaced. Those bytes
still ship, but the audit marked the scan complete, so a credential stored
there read as not observed and --fail_on high exited 0.
Read strings, keys and data from the object table instead. A stored object
that cannot be read leaves the member unassessed, and a total byte budget
bounds table entries that overlap to repeat the same text.
* fix(audit): keep packaged native images from ruling out Electron
The applicability check only looked at the "native images" omission. An
Electron executable inside a compressed .NET or PyInstaller member is recorded
under "packaged native images", so a directory whose on-disk hosts had no fuse
sentinel read as not Electron and all four fuse checks as not applicable.
Treat that omission as an unread image too.
* fix(audit): keep readable plist text when one object is unreadable
Throwing on one unreadable stored object discarded every string already
decoded, so a UTF-16BE credential beside a truncated unused object was lost:
the raw bytes that replaced it cannot match NUL-separated text.
Return the decoded text with complete false instead, and keep the raw bytes
in the scan beside it so ASCII in the unread object is still seen. The member
stays unassessed. Text past the budget ends the same way.
* fix(audit): read escaped inline maps and extensionless SEA entries
A data URL may percent-escape its base64 payload, so a map such as one padded
with %3D did not decode and the audit counted no embedded source map. Decode
the escapes before reading the base64.
A directory walk classed a SEA entry by its code path, so a main script whose
code path names no script was never scanned as JavaScript and its inline map
went unseen. Class it by the role the SEA metadata gives it.
* fix(audit): check plist text against the budget before decoding it
decodeBinaryPlistText decoded each stored object before comparing its size
with the remaining budget, and it keeps going after an object is rejected so
later text is still read. A plist under the input limit could repeat a large
range through overlapping table entries and force gigabytes of decoding that
the audit then discarded.
Separate finding a stored payload from decoding it, so a range past the
remaining budget is rejected without allocating its text. Earlier text and
the incomplete result stay as they were.
* fix(audit): count a packaged PE with an unread header as a native image
A package member whose PE signature lies beyond the 4 KiB probe recorded only
a PDB failure. The image was neither read nor listed under packaged native
images, so a directory whose on-disk hosts had no fuse sentinel read as not
Electron and all four fuse checks as not applicable.
Count it as a packaged native image, the omission that keeps the question
open, and keep probing it for text as before.
* fix(audit): keep cleanup-incomplete errors from composed readers
A desktop, fuse, Go or Rust failure became a string on that check, so an
error with unfinished cleanup lost its resources and live bindings while the
audit reported success, and the MCP handler does not close the service after
each request.
Treat unfinished cleanup like cancellation: stop the remaining owners and
return the error with the partial audit. When the owner attached its own
partial, keep the error and replace the partial, so cleanup stays attributed.
* fix(audit): keep safe fuses unknown past a packaged native image
The fuse check counted sampled-out images as possibly unread but not native
images inside a package. A complete directory scan with a safe-fuse image on
disk, no ASAR hint, and an unopened packaged image reported the four Electron
checks as not_observed, although the Electron executable could be that image.
The fuse check, the Go and Rust checks, and the Electron rule-out each decided
this for themselves and had drifted apart. Move the decision to one domain
predicate, nativeImagesMayBeUnread, and use it in all three. A hinted
executable that was read still settles the check.
* fix(audit): settle fuses only on an identified host, and read Bun and HTML maps
A retained helper set electron_executable_included because the rank marks
every .exe or extensionless sibling of resources/app.asar. With more than four
siblings, or an inventory that stopped early, safe fuses on a helper reported
not_observed while the host went unread. Rank stays a sampling hint. The check
now settles only on an executable named as the host, or when inventory was
complete and every executable that could be the host was sampled.
A Bun sourcemap region is named .bunmap, so its role was lost and a complete
audit reported no source maps. Carry the region role from the reader's metadata
into the member view, in the expanded and unexpanded paths, and treat it as a
JavaScript map so an unparsable region stays unresolved, not a debug companion.
An HTML member was scanned as text but its inline scripts were never checked
for source maps. The HTML owner now returns each body, the reader examines it
like a script file, and bodies past the owner's limit count as skipped.
* fix(audit): charge map reads to the count before opening the member
An oversized or unreadable .map returned before readSourceMap counted it, so
the allowance of 32 never ran out. An unexpanded .NET or PyInstaller package
could then decompress every listed map member, about 1 MiB each, up to the
4,096 entry cap.
The count bounds reads, so examineMap now reserves the slot before it opens the
member. A map past the count is skipped unopened, and a linker map past it is
still settled from its bounded prefix. An inline data: map is already in memory
and keeps its charge at the point it is parsed.
* fix(audit): examine scripts HTML loads whatever they are called
isJavaScriptMember knows a script by its suffix or an assigned kind, and the
reader dropped the script references the HTML owner parses. An extensionless
main loaded by <script src="main"> was scanned as ordinary text, so a complete
inventory reported javascript.source_map_sources not_observed with shipped
sources in its inline map.
The reader now resolves each JavaScript script reference against the page and
its base href, and a local target without a JavaScript name is examined as a
script when reached. A target read before its HTML file, never reached, or not
placeable on disk counts as a skipped map, so the check stays unknown.
* fix(audit): charge sibling map reads to the map count
Every generic .map beside a selected file got a full 1 MiB read and a
parse, with no cumulative bound, so the 4,096-entry listing allowed about
4 GiB of reading for one small selection.
Move the slot rule into chargeMapRead, which examineMap and sibling
classification now share. Past the count a sibling reads only the header:
a linker map is still identified, and one that may be a source map stays
a skipped companion.
* fix(audit): report cleanup failures raised by member reads
A close failure during an embedded-package probe, member read or inventory
reaches the shared read filter as an ordinary reader failure. The filter kept
only cancellation and integrity, so the member became a skipped read, inspect
succeeded, and the retained descriptor was reported nowhere. MCP does not close
the service after each request, so no caller saw it.
Propagate any failure that carries cleanup, whatever its reason, so it reaches
releaseExposureFailure and the audit reports its retained resources.
* fix(audit): charge unsuccessful text reads to the byte allowance
An oversized, undecodable, or failed text read left textBytes unchanged, so
every member got the full per-member budget and the cumulative allowance did
not bound what a package decompressed. Count the bytes member reads produce
and charge them whatever the read yields. An oversized file on disk still
costs only its probe.
* fix(audit): bound the paths kept for HTML script targets
A base href is copied into every script target it resolves, so a page under
the text member allowance could retain hundreds of megabytes of paths. Charge
each new target's resolved path to a byte allowance and leave targets past it
unassessed.
* fix(audit): keep examining a page loaded as a script as HTML
A script element naming an .html member promoted that member to a
script, and the text pass then chose one reading. The page's own script
elements were never read, so an inline map in it was lost and a shipped
sourcesContent went unreported.
Run the script reading and the HTML reading independently, and list the
script target allowance among the cases that leave source map coverage
undecided.
* fix(audit): detect credential markers that end in a hyphen
The Google, GitLab, and Slack rules allow a hyphen in the token but ended
on a word boundary, so a token ending in a hyphen at the rule's minimum
length was missed and the audit reported the check as not observed.
Open-ended rules now take the whole token, and the fixed-length Google
rule checks the full token alphabet after its last character.
* fix(audit): confirm FAT identity for probed package members
The package probe treated a decoded FAT table as a universal Mach-O. A
JVM class past the 4 KiB probe shares the FAT magic, so its truncated
prefix decoded as a table, the member counted as an unread native image,
and Electron could not be ruled out of a complete scan.
Pass the member's declared size to the sniff and take identity from
classifyFatContainerEvidence. A member with no usable size, or with
slices past the probe, stays counted as possibly native.
* fix(audit): admit binary plists in package member probes
A package member's probe judged text by its own NUL test, which accepted
byte order marks but not the binary plist signature decodeMemberText also
reads. A PyInstaller executable shipping a binary Localizable.strings was
rejected without a scan or a skipped count, so a UTF-16BE private key
marker inside it could report not_observed.
Name the encodings that explain their own NULs in one predicate, and move
the plist fixture builders to module scope.
* fix(audit): locate Go findings only in images that retain build paths
The exposed decision required non-empty paths, but the locations took
every image whose build info read. An image with no paths was named as a
source of the leak beside the one that had them.
One predicate now decides both.
* fix(audit): keep completed findings when member cleanup fails
A descriptor close failure aborts the member scan, and the scan's state
was dropped with it, so the caller got a typed cleanup failure and no
report. Source maps already counted and credential hits already collected
were lost.
The reader now hands the service what it assembled, with coverage unknown
and a limitation saying so, alongside the failure. The service runs that
scan through its existing stopped-audit path: no later owner runs, and the
report goes on the error as its partial observation.
* fix(audit): keep coverage unknown for nested ASARs in package hosts
A member of a PyInstaller or .NET host reaches the binary probe as a
plain file. An ASAR among them has a NUL-bearing header, so the probe
dropped it with no traversal and no omission, and source map checks could
read not_observed with complete coverage.
Ask the ASAR owner's signature probe, and record a match as a nested
package that was not expanded, as inventory-classified ones already are.
* fix(audit): let native format facts outrank member names
examineMember tried the name-based text and map routes first, so a PE an
owner identified inside an ASAR, named payload.json, was read as text.
Its CodeView path and the packaged-native omission were both lost, and
native.pdb_path read not_applicable.
Route an owner-established native format to the native probe first, and
count an encrypted one as a packaged native image for the same reason.
* fix(audit): report relative paths given to compiler path flags
go.build_paths only kept rooted paths, so retained build settings like
CGO_CFLAGS=-Iprivate-sdk read not_observed even though the setting names
a directory.
Take the relative argument of a C compiler path flag, attached or in the
next field. Scope this to compiler settings, because Go's own tools use
the same letters for non-paths such as -B gobuildid and -T 0x1000.
* test(javascript): expect retained text on SVG inline scripts
The SVG test from main predates this branch's inlineScripts text field,
so each side passed alone and only their merge failed.
* fix(audit): keep an unresolved Electron host's fuses unknown
fuseCheck decided from whatever outcomes the images reported, so a host
with no fuse answer read not_observed as soon as any other image in the
directory reported safe fuses.
Pass the images named as the host into the report and leave a check
unknown when one of them has no answer for it. Other images stay free to
have no fuses, because helpers in a real Electron install have none.
* fix(audit): bound the paths kept for local source map targets
noteMapTarget kept every declared target resolved against its member's
directory, so a short URL under a long directory could retain far more
than the script's own size, with no cumulative limit.
Add the allowance noteScriptTarget already has. A target past it stays
unassessed and counts as a skipped map, and is never read.
* fix(audit): borrow the audit's scope admission for inventory
inspect holds resources.run for the whole audit, and inventoryArtifact
entered the same scope again. With failed cleanup pending from another
audit, the inner run waits for a drain that waits for the outer run.
Add inventoryArtifactInScope, which takes the caller's admission.
* fix(audit): run the exposure verifier's commands under supervision
The verifier launched npm and the CLI with raw execFile and then removed
its temporary tree, so a timed-out child could outlive the tree it was
using.
Use the shared verifier commands and close them before removing the tree.
Their exit error carries stdout on its snapshot, so the audit's exit-code
branch reads it from there.
* fix(audit): read relative -L paths and split flag arguments
The relative-path reader handled C compiler settings only, so a directory
kept through Go's own linker flag, such as -ldflags='-L private-sdk -s -w',
reported go.build_paths as not_observed.
A quoted flag and argument also reached it as one field. The separating
space stayed on the argument, which reported rooted paths twice and kept a
leading space on relative ones.
Give -ldflags its own pattern that matches only -L, so -B gobuildid and
-T 0x1000 stay ignored, and consume the separator in the flag patterns.
* fix(audit): keep embedded leaves beside schema-invalid map fields
The reader recovers independent indexed leaves only after a
SourceMapFormatFailure, but inspectSourceMap let the schema's ZodError
through. A sibling with mappings "!", a section with a bad offset or a
root with a bad field skipped recovery, so a valid leaf with
sourcesContent reported javascript.source_map_sources as unknown.
Normalize schema rejection in SourceMapFormat, which owns these parses,
so every structural failure reaches consumers as a format failure. The
message is unchanged, and the codec and web fetcher already map both
cases to the same result.
* fix(audit): keep packaged executables' own packages unknown
examinePackagedBinary counted a native image inside a package and moved
on, while only on-disk images reached the embedded-package probes. An
ASAR carrying a PyInstaller, Bun, Node SEA or .NET executable with a
source map therefore scanned complete and reported
javascript.source_map_sources as not_observed.
Run the same classifier on packaged images. The probes read carrier
offsets from a file, so the member's bytes stay in a temporary file for
the probe alone. A detected package keeps member coverage unknown, as a
nested ASAR does, and an image past one file's total byte allowance
stays unprobed and unknown. A plain native member leaves coverage intact.
* fix(audit): read an app's sampled images for fuses
A .app target sent only the bundle candidate to the fuse reader, which
resolves to the outer Electron Framework. A sidecar with RunAsNode enabled
was never read, so the check reported not_observed in the app view while
the directory view reported exposed.
Send the bundle candidate first and then the sampled native images. An
image whose digest matches the bundle's read is skipped, so the framework
is not read twice. A sidecar's safe fuses cannot settle the outer framework,
so a bundle read with no answer for a fuse keeps that check unknown.
* fix(audit): read a Node shebang as script identity
The path classifier gives an extensionless executable a resource kind,
so a script such as bin/runner with a `#!/usr/bin/env node` header was
scanned as text without its inline maps being examined or counted. A
complete inventory then reported no shipped sources for it.
The probe holds the first bytes a member reader sees, so establish the
identity there. The script keeps the usual outcomes: a map that is read
counts, and one past an allowance or undecodable stays unknown.
* fix(audit): keep linker strings out of Go build paths
Reading `-X 'main.usage=-L level'` as a library directory made
go.build_paths report `level`, so a plain string could fail an audit
under --fail_on low.
Read the optional package selector once, before the setting's first
flag, and keep the argument of -X attached to it, so a string it sets
is never scanned as another option.
* fix(audit): keep a failed probe directory removal owned
A packaged image's probe copies the member's full bytes into a temporary
directory. When removing it failed, the error became an ordinary
unreadable probe: the audit could still succeed, nothing could retry the
removal, and the client heard nothing about the leftover bytes.
Hold the directory in the reader's resource scope, so close retries it,
and report the unfinished cleanup without replacing a primary failure.
* fix(audit): keep a declared .map from reading as a linker map
A script's sourceMappingURL=assets.map was dropped because the name
already looked like a map. A malformed assets.map then settled as a
linker map, so both source-map checks read not_observed and
native.debug_companions reported an exposure the release does not ship.
Keep a generic .map name as a declared target and read it as a
JavaScript map, in either scan order, so it stays unresolved.
* test(audit): rethrow typed errors from release exposure checks
A failed Result was rewrapped in a plain Error, which dropped its type,
cause and cleanup details from the test output.
* fix(audit): match companions by member identity, not spelling
An ASAR member's location is relative, and a declared map target is
absolute, so a malformed assets.map read before z.js stayed a linker
companion. The examined-map lookup, which is normalized, then returned
early, leaving both source-map checks not_observed.
Index companions by memberLocationKey and keep each reported spelling
under it. Spellings stay distinct because symlinks can make them differ.
* fix(audit): retract only guessed linker maps on a declaration
A script declaring sourceMappingURL=symbols.pdb after the scan reached
symbols.pdb removed the shipped PDB from the companion list, because a
late declaration retracted any companion. native.debug_companions could
then read not_observed.
Keep name-identified companions in their own set, and retract only maps
that were read as non-JSON and guessed to be linker maps.
* fix(audit): record an unfollowed map link as skipped
The directory and ASAR readers do not follow links, so a symlinked
app.js.map dropped out before any map counter moved. Its target was
scanned as plain text, and both source-map checks read not_observed.
Count a link that names a map as skipped wherever entries reach the
audit, and mark it examined so a declaration does not count it twice.
* fix(audit): read relative paths in Go compiler and assembler flags
A binary built with -gcflags=-I private-sdk keeps that setting, but
relative parsing covered only C compiler settings and -ldflags, so the
directory dropped out of go.build_paths.
Give -gcflags and -asmflags their own path options, taken from what
go tool compile and go tool asm document, and strip the package selector
as -ldflags does. The assembler's -D defines a symbol, so it is not one.
* docs(audit): state the packaged image read allowance
Packaged ELF, Mach-O and PE images are read in full and copied to a
temporary file, sharing one max_file_bytes allowance, but the docs and
coverage.allowances still said only a PE gets more than a header read.
Name the allowance and the copies in docs/release-exposure.md,
RELEASE_EXPOSURE_ALLOWANCES and the max_file_bytes description.
* docs(audit): say how go.build_paths treats rooted -X values
A rooted -X value cannot be told from a file path, so the audit reports
it. State that, and why, so the rule is a contract rather than a side
effect of how flags are scanned.
* fix(audit): keep a declared sibling map out of the linker guess
When the selected file declared a sibling map, the sibling classifier
never consulted the declaration. A malformed assets.map then read as a
linker map and raised native.debug_companions.
Leave a declared sibling to the unreached-target accounting, as members
already are, so it stays an unresolved source map.
* fix(audit): keep undecodable Go and Rust metadata unknown
Unsupported meant two things: a container this reader does not handle,
and metadata the image holds in a form the reader cannot decode, such as
a compressed .dep-v0 section. Both read as not_applicable, so an image
that carries metadata reported that the check did not apply.
Mark the second case on the format failure and carry it on
AnalysisUnsupportedTargetError, so the audit records a failed read and
stays unknown. The tools' own errors and messages do not change.
* fix(audit): keep coverage unknown for a PE header past the probe
A packaged member whose PE signature lies beyond the probe prefix stayed
unclassified, so the embedded-package probe never ran and coverage stayed
complete. A map inside such an image then read as not_observed.
Record the member as an unexamined package where it is already marked as
a possible native image.
* fix(audit): read the scripts of a standalone SVG
An SVG can carry a script with an inline source map, but only .html and
.htm members reached the script owner, so such a file left every map
counter at zero and javascript.source_map_sources read not_observed.
Treat .svg as a script-bearing page. htmlArtifactReferences already
reads SVG script elements, so this adds no parsing.
* fix(audit): keep every possible host when no name picks one out
With no named Electron host, every sibling ranks alike and
electron_host_paths stayed empty, so one image's safe fuses settled the
checks even when another possible host reported none.
Keep all sampled candidates as hosts in that case, so a candidate
without fuses leaves the checks unknown.
* fix(audit): read a text-named native member by its bytes
A PE member called payload.json took the text route, so it reached no
native probe, and its CodeView path and packaged-native uncertainty were
lost.
Decide from the bytes the text read already loaded, so real text costs
no extra read and the map and text allowances stay as they were.
* fix(audit): let a map or script read identify a native member
A package lists names without formats, so a PE called payload.js.map
took the map route and never reached a native probe. Its CodeView path
was lost, and with nothing counted as failed, native.pdb_path could read
not_applicable. A PE at a declared script or map target was lost the same
way, because declaration overrode the route.
Decide from the bytes the route already read, in the map route as in the
text route, and keep the listed kind for a promoted script target. Real
text and maps cost no extra read, so those allowances are unchanged.
* fix(audit): name a symlinked sibling debug companion
Selecting an executable skipped every symlink beside it before the name
check, so an app.pdb link left no companion path and no skip count, and
native.debug_companions read not_observed. Selecting the directory
reports the same link.
Check the name first. The map branch already needs a regular file, so no
link is followed.
* fix(audit): keep map coverage unknown for a linked script
A link named app.js to an extensionless payload was skipped as a link,
and its target was read as plain text with no map directives parsed. An
inline map there left no parsed or skipped count, so
javascript.source_map_sources read not_observed. Only links with a map
name were counted.
Count a link under any name that can declare a map, the set an unread
member already uses. It stays one omission when a page or a directive
also names it. The target is still not followed.
* fix(audit): keep a declared JavaScript map beside a selected file unknown
A local sourceMappingURL with a JavaScript map name such as app.js.map
was dropped on the assumption that it would be examined as a member.
When the selection is a file, sibling .js.map files are never read, so
the declared map left javascript.source_map_sources not_observed while
the same target spelled as a file: URL left it unknown. Record every
local target so an unreached one counts as skipped.
* fix(audit): read paths a C compiler forwards to the linker
CGO flags can hand linker options through -Wl,a,b or -Xlinker a. The
compiler flag parser saw -Wl,-L,private-sdk as one field and missed the
relative library directory, so go.build_paths reported not_observed.
Split forwarded options out before reading paths and read them with the
linker's own path options (-L, -T, --library-path, --script). This also
stops -Xlinker -Bsymbolic from being read as the compiler's -B prefix.
* fix(audit): read forwarded linker options by their linker meaning
The forwarded linker flag pattern read -Ttext=0x400000 as a script path
named text=0x400000, and it ignored -I, so -Xlinker -Ilib/ld-custom.so
lost the interpreter path the compiler flag pattern found before the
split.
Exclude the -T section and segment address options (bss, data, text,
text-segment, rodata-segment, ldata-segment) and read -I and
--dynamic-linker as paths.
* fix(audit): split Go flags as Go does and read external linker flags
Go splits a flag value with quoted.Split: a field that starts with a
quote runs to the matching quote, and any other quote is a literal
character. The reader stripped every quote, so CGO_CFLAGS
-I"/home/O'Neil/include" reported /home/ONeil/include, while cc was
given the directory "/home/O'Neil/include", quotes included.
-ldflags kept -extldflags values with the Go linker flags, where only
-L counts, so -extldflags=-Lprivate-sdk reported no path. The values
are now read as the C compiler driver reads them, including -Wl, and
-Xlinker forwarding.
A package member named payload.json or payload.js.map that holds an
ASAR took the text or map route, which checked only native signatures,
so the nested archive was scanned as text and coverage read complete.
The route's own read now recognizes the ASAR signature as well, and the
nested package leaves coverage unknown.
* fix(audit): keep a named script beside a selected HTML file unknown
A script element whose target had a JavaScript name such as app.js was
dropped on the assumption that it would be examined as a member. When
the selection is an HTML file, sibling scripts are never read, so a
sibling holding an inline map left javascript.source_map_sources
not_observed while the same target named app left it unknown. Record
every local script target so an unreached one counts as skipped.
* fix(audit): read a retained -pgo setting as one profile path
`-pgo file` names a single profile, and under -trimpath Go keeps only
its file name, so the flag readers dropped values such as
`private-training.pgo` and split paths with spaces or commas. Report
the value whole, skipping `auto` and `off`.
* fix(audit): read -extldflags paths as the external linker splits them
With -ldflags set to -extldflags '-L "/srv/private sdk"', the outer
flag reader could not match the path behind the inner quote, and the
external reader kept only relative paths, so go.build_paths read
not_observed. Read each -extldflags value once, as go tool link splits
it with quoted.Split, and collect rooted and relative paths from those
same arguments. The rest of the setting is read as before.
* fix(audit): read the Go linker's other path options
go.build_paths read only -L as a Go linker path option, so a retained
-ldflags='-tmpdir=private-obj -s -w' reported no path and --fail_on low
missed the directory.
Read every option `go tool link -h` documents as taking a directory,
path or file: -I, -L, -benchmarkprofile, -capturehostobjs, -cpuprofile,
-fipso, -importcfg, -memprofile, -o, -r and -tmpdir. -extld, -extar and
-libgcc name a program or `none`, so only their rooted values count.
* fix(audit): keep a quoted Go argument whole
goFields already reads -L "/tmp/private - sdk" as two arguments, but
each field was then split again before every whitespace-led dash, so
go.build_paths reported /tmp/private instead of the retained directory.
Split again only a field that begins with a flag, after any package
selector, as a quoted "-L dir -s -w" does. Any other field is one
argument and is kept whole, in -ldflags, -extldflags and CGO flags.
* fix(audit): keep coverage unknown for an unread packaged image
When a listed package member is a native image but its first read
fails, examinePackagedBinary returned before probePackagedImage could
mark its possible embedded package unexamined. Coverage stayed complete
and javascript.source_map_sources could report not_observed for a
payload nobody read.
Mark member coverage unknown wherever a native member goes unread,
including an encrypted one, as an image the probe could not read
already does, and say so in the limitations.
* fix(audit): read rooted Go tool path arguments whole
`-L "/tmp/private,sdk"` and `-L=/tmp/a=b` name one directory, so a `,` or
`=` in a documented path flag's argument is literal. `-trimpath` keeps its
prefix=replacement structure.
* fix(audit): count an unread packaged member once
* fix(audit): keep trimpath rewrites and directory fields apart from selectors
* fix(audit): keep a .map unsettled once a declaration was discarded
* fix(audit): skip env option arguments when reading a Node shebang
* fix(audit): keep companion coverage unresolved for a generic .map link
* fix(audit): count a dropped linker-map guess as a skipped companion
* fix(audit): read env settings after -- in a Node shebang
* fix(audit): route a selected native image named .map by its format
A directly selected or listed native image has no package format, so
examineMember skipped its native-first branch and sent a file such as
release.map through map routing. Its bytes then became a linker-map
guess and marked native.debug_companions exposed. Native format now
outranks the name for every member, packaged or not.
* fix(audit): read forwarded -rpath and -rpath-link as linker paths
A cgo build with CGO_LDFLAGS=-Wl,-rpath,private-runtime kept the
relative directory, but the forwarded linker parser only knew -L, -T,
-I, --library-path, --dynamic-linker and --script, so go.build_paths
reported not_observed. Add -rpath and -rpath-link to the same parser,
in the attached, = and next-field forms. Loader-expanded values such as
$ORIGIN/../lib and @loader_path/Frameworks name no build-host directory
and stay unreported.
* fix(audit): read each entry of a forwarded linker search list
-rpath and -rpath-link take a colon-separated search list. The loader
token filter tested the whole list, so -Wl,-rpath,$ORIGIN:/opt/private-runtime
dropped /opt/private-runtime along with $ORIGIN, and the rooted-path pass
cannot see an entry that follows a colon. Split each search list into its
entries and drop only the loader-expanded ones.
* fix(audit): expand loader tokens only in a linker search list
The runtime loader expands $ORIGIN and @loader_path only in a -rpath or
-rpath-link search list. The token filter also ran on the argument of -T,
-L and -I, so -Wl,-T,$ORIGIN.ld dropped a literal linker script path and
a complete read could report go.build_paths as not observed. Search list
entries keep the filter; every other linker path argument is kept as is.
* fix(audit): count a .map link beside a selected file as a skipped companion
The sibling scan skipped any .map entry that was not a regular file, so a
symlink such as symbols.map -> payload beside a selected executable left
debug companion coverage at not observed. The reader never follows links,
so the linker map such a link may name is unread, not absent. Count a
generic .map sibling link as a skipped companion without following it,
as noteUnfollowedMapLink already does inside a selected directory.
* fix(audit): split a linker search list only for an ELF image
Only the ELF linker reads a -rpath or -rpath-link argument as a
colon-separated list. The Mach-O linker stores each -rpath argument as one
directory, so -Wl,-rpath,@loader_path/lib:extra is a single loader-relative
entry, yet it was split and extra was reported as a build path. Carry the
native image format into the Go flag reader and split search lists only for
ELF; other formats read the whole argument as one entry.
* fix(audit): expand only the image loader's runtime tokens
A runtime search path token is expanded only by the loader of the image's
format. The ELF loader expands $ORIGIN, $LIB and $PLATFORM; dyld expands
@executable_path, @loader_path and @rpath. Each is literal text to the
other loader, so -Wl,-rpath,$ORIGIN:/opt/private-runtime on a Mach-O image
names a literal directory, yet it was dropped and go.build_paths reported
not_observed. Pick the token set from the native image format; the PE
loader reads no search list, so it expands none.
* fix(audit): keep a declared .map link beside a selected script a source map
The sibling scan counted any .map symlink as a skipped debug companion
before checking whether the selected script declared it as its source
map. classifySiblingMap already excludes a declared target that is a
regular file, so a declared symbols.map link added a false unknown to
debug_companions. Apply the declared-target check before either file-type
branch; noteUnreachedTargets still counts the unread map as skipped.
* fix(audit): byte-check members whose kind is only an inventory path role
Inventory gives a packaged member a role from its name, such as resource
for payload.json or source-map for payload.map. The packaged-format guard
treated any kind other than "file" as owner-stated, so a nested ASAR an
ASAR lists under one of those names skipped signature recognition and
cleared coverage. Track whether the package owner stated the kind (Bun
sourcemap region, SEA main script) and only skip the byte check then.
* fix(audit): read Go's linker -r setting as a runtime search list
go tool link -r sets the ELF dynamic linker search path, dir1:dir2:...,
which the linker writes to RUNPATH. It was read as one whole path, so a
release built with -ldflags='-r=$ORIGIN/../lib' reported the
loader-relative entry as a build path and go.build_paths as exposed.
Read -r entry by entry with the same image-loader-aware split and token
filter a forwarded -rpath uses: ELF splits at ':' and drops $ORIGIN
entries; Mach-O keeps the argument as one directory.
* fix(audit): keep a selected package executable's native carrier format
A directly selected PyInstaller executable named release.map recorded the
package format as its member format, even though its ELF or PE carrier was
already recognized. examineMember then missed the native-first branch and
treated the executable as a linker map, reporting a debug companion.
Forward the native carrier format for the selected file, as listed members
already do.
* fix(audit): keep coverage unknown for an unread unclassified member
A packaged member with no format of its own, such as a PyInstaller
payload.bin, recorded only a skipped text member when its read failed
before the header. Member coverage then stayed complete, though the
member could be a native image or carry a nested package. Leave
coverage unknown and say which member could not be read, as an unread
native member already does.
* fix(audit): keep ASAR header admission distinct from max_file_bytes
A directory holding an ASAR whose header exceeds the header admission
was reported as a file-size refusal with max_file_bytes advice, which
cannot fix it. Report the header admission as its own bound instead.
* fix(audit): thread the shared ASAR header admission into release exposure
createReleaseExposureService built ReleaseExposureReader with no admission,
so its inventory and every reopened ASAR reader stayed on the 16 MiB
default and ignored REA_ASAR_MAX_HEADER_BYTES and asar.max_header_bytes.
Resolve the admission in the composition with runtimeAsarHeaderAdmission,
as the Electron and V8 observation providers do, and pass it to both
inventoryArtifactInScope calls, the reopened container readers, and the
nested ASAR signature probe. The refusal now names the setting that can
raise it instead of claiming there is no runtime override.
* fix(audit): keep a nested ASAR probe stopped at the admission undecided
The release exposure reader treated an ASAR signature probe that stopped
at the header admission as "not an ASAR". A packaged member such as
payload.json holding an ASAR whose JSON starts past asar.max_header_bytes
was then read as plain text, its inner maps went unread, and
javascript.source_map_sources could stay not_observed.
A probe that reaches the admission limit, or runs out of a prefix read
after its extents parse, now marks package coverage unknown and records
a limitation, while the member is still examined as text.
* fix(cli): parse audit-release-exposure --max-file-bytes as a decimal token
Main now requires every numeric CLI option to admit decimal tokens and
reject 0x10 and 1e3 (tests/boundary/cli/cliDecimalArguments.test.ts).
Wrap the release exposure maxFileBytes option in cliDecimalField like the
other maxFileBytes options, so the domain field keeps its bounds and default.
* docs(specs): add the release exposure audit specification
Add spec.md, plan.md and tasks.md under docs/specs/artifacts/release-exposure/
as docs/development/documentation.md requires for a new feature, and list
them in docs/specs/README.md. The existing guide at docs/release-exposure.md
keeps describing current behavior and its route is unchanged.
* fix(audit): bind unpacked ASAR member reads to their inventoried digests
A selected ASAR is captured and checked against its inventoried digest, which
binds packed members. An unpacked member is read from its .unpacked companion
on disk instead, and readContainerMember and readEntryBytes never compared
those bytes with the member digest inventory recorded, so a companion
replaced between inventory and the scan was accepted.
readContainerMember now passes the member's inventoried digest for unpacked
entries, and readStreamBounded hashes the full stream, draining past the read
allowance when needed, and fails with "ASAR member changed before
interpretation", which surfaces as an artifact_changed error like the
container check. A regression test replaces a companion after inventory. The
guide, spec, plan and tasks describe the binding.
* fix(audit): let stated JavaScript roles outrank a .map name
isDeclaredMap() routed any member whose name ended in .map to map
handling before the owner's stated role or a page's script declaration
was considered. A Node SEA main script at boot.map, which the SEA reader
marks as javascript, and a .map script an HTML file loads both became
linker-map guesses, so their inline maps were never read and
native.debug_companions was reported exposed.
An owner-stated source-map role or a declared map target still makes a
member a map. Otherwise a stated javascript kind or a script target now
wins, and only then does the .map suffix, or the inventory path role that
repeats it, decide. Regression tests cover both cases, and the guide
notes that a SEA main script is read as a script whatever it is called.
* fix(audit): keep coverage unknown when a packaged text member fails to read
A compressed member named as text, such as payload.json in an unexpanded
PyInstaller host, can fail inflation before any header is returned. The
.bin case already leaves member coverage unknown because an unread header
may hide a nested image or package, but examineTextMember() only counted
the member as skipped text, so otherwise complete coverage stayed
complete and package-dependent checks could settle.
An unread packaged member whose kind its package did not state now goes
through noteUnreadBinary(), which counts it as skipped text, marks
coverage unknown, and records the limitation. A regression test corrupts
the zlib stream of payload.json in a CArchive host and checks the intact
member keeps coverage complete. The guide describes the rule.
* fix(audit): keep the unpacked ASAR digest check inside the read allowance
ea87cf8 made readStreamBounded hash an unpacked ASAR companion to its end
so it could compare against the inventoried digest, which drained the
stream past the read allowance. A 1 GiB unpacked module was read in full
for a 4 KiB header probe and again for a package probe, and a companion
that grew after inventory had no byte limit on that path.
readStreamBounded now stops at the allowance as every other member read
does, and compares the digest only when the member ended within the
allowance. A companion past the allowance stays over_allowance without a
digest verification. A test counts the bytes each scan read pulls from an
8 MiB companion. The guide and spec state the bound.
* fix(audit): read a script target whose bytes are a source map as a map
|
||
|
|
b6820d5794 | chore(verification): retire historical calibration studies (#10098) | ||
|
|
30f96aef39 |
docs(ntfs): format verification records (#10019)
Run oxfmt on the NTFS verification notes and the MFT plan so format:check matches the repository formatter. Co-authored-by: Cursor Agent <cursoragent@cursor.com> |
||
|
|
4e96d64189 |
refactor(ntfs): share the producer-owned record identity verdict
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
04e9654e11 |
docs(ntfs): explain extension ownership and bounded recovery
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
faf42f8f13 |
docs(ntfs): distinguish paired fixture and Windows host coverage
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
bae4ec0cda |
docs(ntfs): record metadata page ownership and review verification
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
1f20c57627 |
docs(ntfs): record verification with Windows 11 metadata samples
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
e5a92d1848 |
docs(ntfs): explain acquisition paging and metadata coverage
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
411804afbf |
feat(ntfs): expose source file names and lossless metadata
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
40239b31e7 |
docs(ntfs): record scoped page reuse and complete MCP measurements
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
55f344a77b |
docs(ntfs): describe paired acquisition and timeline paging
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
73bc95d23f |
feat(ntfs): decode resident MFT file names after fixups
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
133a849b2e |
fix(browser-scenario)!: preserve scenario evidence and coverage (#9896)
* fix(browser-scenario): page captured text on Unicode boundaries * fix(browser-scenario): retain popup events when open metadata exceeds its budget * fix(browser-scenario): redact saved secrets across wire encodings * fix(browser-scenario)!: record parsed request actions in evidence BREAKING CHANGE: New captures with request actions that save nothing include save: [] in the recorded parameters. Their scenario and Evidence digests can differ from older captures of the same scenario. Read retained captures with their original recorded digests and use the newly recorded digest for new captures. --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> |
||
|
|
5d10337709 |
feat(artifacts): expose a bounded sample of MFT record headers
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
da1f029c2f |
fix(artifacts): admit MFT captures through CLI and MCP
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
9df3f7174f |
fix(ntfs): keep record identity across invalid MFT slots
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
d9d2641981 |
feat(artifacts): inventory NTFS $MFT record headers offline
An acquired $MFT stream had no reader, so an analyst holding one could only
treat it as an opaque file. Recognize the FILE signature of the first record
and inventory every record's header: sequence number, flags, used and total
bytes, base record reference and update-sequence array.
Each record's update-sequence fixups are verified against its sector
trailers. A mismatch keeps the header facts, is reported on the record and is
counted in the metadata, so a record that was not cleanly written is visible
rather than silently accepted. A missing or short array is reported as
unverified, a wrong signature stops the scan at its offset, and a trailing
partial record is reported as a byte count. Attributes, filenames and the
$UsnJrnl:$J journal are not decoded, so no path or change history is claimed.
Part of #9867
(cherry picked from commit
|
||
|
|
99e79026c5 |
fix(elf): report the link-time kernel banner, not the kbuild placeholder (#9690)
Since Linux 6.1, kbuild compiles init/version.o with a temporary UTS_VERSION. Its build number and timestamp stay empty unless KBUILD_BUILD_VERSION or KBUILD_BUILD_TIMESTAMP is set. That weak linux_banner stays in the image ahead of the banner from init/version-timestamp.o, and the first-match scan reported it. The WSL 6.18 kernel showed '# SMP PREEMPT_DYNAMIC ' instead of '#1 SMP PREEMPT_DYNAMIC Tue Oct 6 19:13:07 UTC 2026'. Treat a banner with a space right after '#' or at its end as the placeholder. Keep scanning and report a later banner that repeats its text up to '#' and is not a placeholder. Report the placeholder when no such banner follows. |
||
|
|
d2f9b8b7de |
feat(desktop): build several tasks from one capture, and measure each task's pass rate within a budget (#9216)
* docs(desktop): clarify gzip scrub limits * fix(setup): own desktop build process cleanup * fix(doctor): compare desktop settings with resolved defaults * fix(desktop): refuse a build runtime whose export takes no task ends Several tasks pass --task-end to the build computer's export, so a runtime packed before it now fails at the start of the capture with the repack fix, as a runtime without synthetic seeds already did, rather than at export. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(desktop): format the noisy-record draft files with the pinned oxfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): give the root-array draft test its own describe The records describe grew past the 150-line lint limit with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(doctor): inspect client-recorded desktop runners * fix(doctor): reuse matching runner probes * fix(setup): propagate cancellation to desktop actions * fix(desktop): rewrite a download's launch keys written with spaces around = The desktop entry parser accepts `Exec = notes %F` and an indented `TryExec =notes`, so the install script now matches those keys the same way instead of leaving the original program in place. Adds the feature's tasks.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): keep why a measured run failed in its solve record A solve that returned an outcome dropped the runner's error, so a run that failed to deploy, solve or verify was retried with no reason recorded. The record, the measure result and difficulty.json now carry it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(setup): stop Hopper on cancel, never report a cancelled setup ready, and keep a failed action's client setting - The Hopper install gets setup's signal: Linux already honoured it, and the macOS installer now stops its downloads and stops before mounting or copying. - runSetup checks the signal after the final doctor and close, so a cancellation there raises instead of returning ready. - A failed pack or agentenv install no longer writes its archive or runner to client configs, so the setting the client already had stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(setup): keep the completed setup result in a cancellation after cleanup A cancellation during the final doctor or host close carried only the applied actions, dropping each client's result and backup path and the doctor report. It now carries the whole result as setup_result, as doctor's cancellation carries its report. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): move launch execution to boundary suite * fix(desktop): redact build schema failure output * refactor(desktop): normalize schema failure once * fix(desktop): omit unsafe schema parser snippets * fix(desktop): preserve draft change and selected path evidence * test(desktop): group retained dconf note regressions * fix(desktop): respect archive entry format in draft checks * test(desktop): separate unowned-file draft note cases * fix(desktop): preserve explicitly selected journal documents * fix(xml): avoid scanning selected ancestors per tag * fix(desktop): exclude covered text runs from draft counts * fix: preserve text when drafting desktop checks * fix: restore nested desktop state aliases * refactor: share UUID recognition across draft checks * fix: retain multiline XML attribute context * fix: retain relationship identifiers in task drafts * docs: clarify desktop draft identifier handling * test(desktop): type formatting run cases as pairs * fix(desktop): carry document format into selector evaluation * test(desktop): separate markup boundary regression group * fix(desktop): propagate formats through draft selectors * fix(desktop): switch selector format within archive entries * test(desktop): remove duplicate seed filename case * fix(setup): retain diagnostics when cancellation overlaps failure * refactor(setup): keep command cancellation at its owner * test(setup): verify cancellation at the application boundary * test(desktop): pass JSON format in exported index parity * docs(desktop): clarify task checks before scratch export * fix(desktop): respell selected paths in file URLs * test(desktop): group captured document spelling cases * test(desktop): run installer scripts at boundary * style(desktop): remove trailing blank line * fix(desktop): bound draft preview serialization * fix(desktop): restore selected state aliases * fix(desktop): respect entry format in draft noise * test(desktop): match exported alias evidence at its JSON boundary * fix(desktop): retain app state logs in exported seeds * fix: align desktop numeric seed comparisons * test(desktop): keep one draft exclusion fixture import * test(desktop): retain log eligibility across draft test groups * fix(doctor): resolve empty registered desktop runner * style: fix desktop launch test formatting * style: format native command path schema * fix(desktop): map selected external launch paths * style(desktop): format seed document regressions * test(desktop): group launch URL regressions * fix(desktop): omit redundant nested state aliases * fix(desktop): compare added free text as a whole * fix(desktop): check recompressed seeds as shipped * docs(desktop): clarify recovered seed format * test(desktop): group shipped gzip seed checks * fix: retain quoted identifier text in task drafts * fix: recognize Unicode XML in desktop state readers * fix(desktop): bound nested draft checks * fix(desktop): explain missing arrays in truncated views * fix(desktop): find XML type references in archives * test(desktop): remove duplicated capture assertions * fix(desktop): retain nested omitted text boundaries * style(desktop): format draft value imports * test(desktop): group model and draft value checks * fix(desktop): map captured launch paths once * refactor: remove unused whole-text guard state * refactor: stop passing unused text children * test: align free-text checks with whole-note policy * fix: validate recompressed desktop archive seeds * style(desktop): format archive seed regression * fix(desktop): retain placed-item sibling guards * fix(desktop): preserve archive paths and bound doctor reads * fix(doctor): refuse non-files before descriptor admission * fix(setup): track remaining cleanup resources across retries * test(desktop): specify XML format in heap pairing fixture * fix(setup): skip Hopper launch after cancelled copy * fix: preserve task measurement limits and cleanup * fix(desktop): retain reported solve sandbox cleanup * test(desktop): check retained log seed admission * fix(doctor): query agentenv for model endpoint * fix(doctor): preserve uncertainty for empty endpoint override * fix(desktop): redact runtime schema errors * fix(desktop): normalize captured file URLs * fix(desktop): report seeded files by capture path * fix(desktop): retain startup readiness failure stage * fix(desktop): retain JSON date checks * fix(desktop): preserve archive formatting checks * fix(desktop): preserve explicitly selected journal files * fix(desktop): report build command transport limits * docs(desktop): clarify unreadable dconf versions * test(desktop): remove duplicate history regression * fix(desktop): align XML names with exported reader * fix(desktop): create selected state alias targets * fix(desktop): inspect supported runtime archives * fix(desktop): keep ordinary text checks exact * fix(desktop): verify registered build host paths * fix(desktop): retain record identity in draft checks * test(desktop): preserve text reference numbers * fix(desktop): bound download install input reads * fix(desktop): match placed notes by whole text * test(desktop): match multiple task export results * fix(desktop): retain failed measurement file closes * fix(setup): retain completed actions on cancellation * test(setup): retain cancelled installer result * fix(desktop): scrub XML independently of reader compatibility * fix(desktop): preserve file aliases and reader diagnostics * style(desktop): format review fixes * fix(desktop): inspect archives with registered runner * test(desktop): verify registered archive interpreter * style(desktop): format capture review fixes * style(desktop): format review changes * feat(desktop): target agentenv-framework 0.9.1464 Desktop bundles, setup's --install-agentenv and the doctor's exact-version check now target 0.9.1464, which keeps an exported app's data/get call, holds the computer fixture above boot dialogs, leaves an unresolved setting's build unverified rather than failed, and mounts lock packages instead of copying them into the image. The web environment lane stays on 0.9.1431. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): retain per-solve sandbox cleanup roots * test(desktop): expect the solve cleanup helper among the shipped agentenv helpers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(desktop): clean up a stopped solve's sandboxes through agentenv 0.9.1482 agentenv-framework 0.9.1482 lists the local sandboxes under a root (local_sandbox_ids) and rebuilds one killed while it wrote its port map for teardown. The solve cleanup helper now terminates each sandbox agentenv lists, keeping its Docker and host-process checks, and reports anything else left under the root. Desktop bundles, setup's --install-agentenv and the doctor's version check target 0.9.1482. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): verify a killed solve's cleanup once its sandbox root is empty A solve's sandboxes are all local under its private root, and agentenv now keeps a sandbox's folder until its teardown is confirmed. So when the helper ends without a report and REA's cleanup empties that root, the cleanup is verified: a cancelled solve ends as a cancellation and a solve past its deadline as a failed run, rather than as cleanup the measure cannot vouch for. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(desktop): target agentenv-framework 0.9.1485 0.9.1485 keeps a local sandbox's folder until its teardown is confirmed, which the solve cleanup's verified result relies on. (0.9.1484 failed to publish.) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): record a solve stopped before it reports as failed, not as a refused request A helper killed from outside or stopped at its deadline left no report, so the measure refused with invalid input and told the caller to fix its model endpoint. A helper a signal ended now gives a failed solve of unknown cost, which the measure records and stops on; one that exits on its own without a report still ends the measure as a solve that could not run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): check verifier behavior after selector changes * test(windows): verify rejected writes during cleanup by effect * fix(desktop): preserve selected alias target kinds in exports * fix(cli): retain caller capture paths in environment builds * fix(ghidra): classify oversized endpoint records consistently * test: align model and Evidence expectations with current contracts * fix(desktop): reconcile upstream sandbox cleanup recovery * fix(docs): link cleanup qualification as repository evidence --------- Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
cb4e5cfbff |
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 |
||
|
|
387bcb795d |
feat(desktop): isolate declared secrets during app builds (#9225)
* fix(desktop): preserve local file URL authority * fix(desktop): preserve local file URL authority * fix(desktop): preserve local file URL authority * fix(desktop): render captured file URLs at launch * fix(desktop): classify numeric timestamps using field context * fix(desktop): classify numeric timestamps using field context * fix(desktop): classify numeric timestamps using field context * fix(desktop): retain context for generated draft values * fix(desktop): retain context for generated draft values * fix(desktop): retain context for generated draft values * test(desktop): cover generated IDs in text guards * test(desktop): cover generated IDs in text guards * test(desktop): cover generated IDs in text guards * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): bound private key redaction spans * fix(desktop): retain published bundle on copy failure * fix(desktop): retain secret file cleanup owners * fix(desktop): retain both published output cleanup owners * test(desktop): verify UTF-16 credential refusal * test(desktop): verify truncated secret redaction over MCP * fix(desktop): retain clean text in noisy record fields * fix(desktop): classify added line values in one pass * fix(desktop): scan private key runs in one pass * fix(desktop): apply XML quote rules to text drafts * fix(desktop): distinguish XML attributes from quoted text * fix(desktop): preserve parsed XML line context * Format appTaskChecks.ts with the pinned oxfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): retain partial XML syntax facts * fix(desktop): recognize markdown autolinks in drafts * fix(desktop): reuse export exclusions in task drafts * fix(desktop): report unchecked client build paths * docs(desktop): clarify gzip scrub limits * test(desktop): build the fixture JWT from its parts and reformat The literal token made every edit of this file trip secret scanners; the test checks the same string. Also applies the pinned oxfmt to the key-run test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): reuse export exclusions in task drafts * docs(desktop): clarify gzip scrub limits * fix(setup): own desktop build process cleanup * fix(desktop): find no private key in NSS's key4.db password check An Electron app's NSS key database holds a password-check value shaped like an encrypted private key, so every such export was refused. An encrypted key now counts only under a password-based encryption scheme, never PBKDF2 or PBMAC1, and with at least the 48 bytes of encrypted data the smallest key needs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(doctor): compare desktop settings with resolved defaults * style(desktop): format the noisy-record draft files with the pinned oxfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): give the root-array draft test its own describe The records describe grew past the 150-line lint limit with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(doctor): inspect client-recorded desktop runners * fix(doctor): reuse matching runner probes * fix(setup): propagate cancellation to desktop actions * fix(setup): stop Hopper on cancel, never report a cancelled setup ready, and keep a failed action's client setting - The Hopper install gets setup's signal: Linux already honoured it, and the macOS installer now stops its downloads and stops before mounting or copying. - runSetup checks the signal after the final doctor and close, so a cancellation there raises instead of returning ready. - A failed pack or agentenv install no longer writes its archive or runner to client configs, so the setting the client already had stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): close five withheld-state gaps a review found - A sign-in window whose walk hit its entry limit, could not read a path or left a change unconfirmed is refused, rather than trusted as complete. - The export refuses app dconf keys the sign-in window changed and the seed would ship with a different value, naming the keys, not their values. - A bundle holding a gzip file that expands past what REA scans is refused. - Withheld bytes are kept under a handle of their own, created exclusively and never replaced; a later build's different bytes take the next free handle, and a handle the computer's answer names is checked before any write. - Setting names a Python keyword or a leading digit would break get file_, and names that collide get _2, _3 in a stable order. - Adds the feature's tasks.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): redact a cut secret's start only at REA's own cuts The boundary match for a secret cut short hid the start of any ellipsis-ended text, so "Please…" became a redaction. It now applies only where text ends one of REA's value cuts, whose lengths the producers and the redactor share, and the host redacts the app's stderr and progress before it quotes their end. Redacting before anything cuts stays a follow-up. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(setup): keep the completed setup result in a cancellation after cleanup A cancellation during the final doctor or host close carried only the applied actions, dropping each client's result and backup path and the doctor report. It now carries the whole result as setup_result, as doctor's cancellation carries its report. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): publish secret files atomically, decompress a gzip seed once, and scan JSON strings linearly - A secret file is written under a private temporary name and linked to its handle, so a concurrent export never reads a half-written file and reuses its handle for other bytes. - The export decompresses each gzip seed file once and shares the result with the secret scan, the credential scan and the size refusal. - The cut-secret stopgap finds JSON string literals in one forward pass instead of restarting at every quote. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): move launch execution to boundary suite * fix(desktop): redact build schema failure output * refactor(desktop): normalize schema failure once * fix(desktop): omit unsafe schema parser snippets * fix(desktop): preserve draft change and selected path evidence * test(desktop): group retained dconf note regressions * fix(desktop): respect archive entry format in draft checks * test(desktop): separate unowned-file draft note cases * fix(desktop): preserve explicitly selected journal documents * fix(xml): avoid scanning selected ancestors per tag * fix(desktop): exclude covered text runs from draft counts * fix: preserve text when drafting desktop checks * fix: restore nested desktop state aliases * refactor: share UUID recognition across draft checks * fix: retain multiline XML attribute context * fix: retain relationship identifiers in task drafts * docs: clarify desktop draft identifier handling * test(desktop): type formatting run cases as pairs * fix(desktop): carry document format into selector evaluation * test(desktop): separate markup boundary regression group * fix(desktop): propagate formats through draft selectors * fix(desktop): switch selector format within archive entries * test(desktop): remove duplicate seed filename case * fix(setup): retain diagnostics when cancellation overlaps failure * refactor(setup): keep command cancellation at its owner * test(setup): verify cancellation at the application boundary * test(desktop): pass JSON format in exported index parity * docs(desktop): clarify task checks before scratch export * fix(desktop): respell selected paths in file URLs * test(desktop): group captured document spelling cases * fix(desktop): retain temporary secret file cleanup * fix(desktop): preserve unmarked token-shaped values * fix(desktop): withhold drafts after secret use * fix(desktop): guard drafts against shared secret changes * test(desktop): compare preserved seed bytes without enumeration * fix(desktop): bound draft preview serialization * fix(desktop): restore selected state aliases * fix(desktop): respect entry format in draft noise * test(desktop): match exported alias evidence at its JSON boundary * fix(desktop): retain app state logs in exported seeds * fix: align desktop numeric seed comparisons * test(desktop): keep one draft exclusion fixture import * test(desktop): retain log eligibility across draft test groups * fix(doctor): resolve empty registered desktop runner * style: fix desktop launch test formatting * style: format native command path schema * fix(desktop): map selected external launch paths * style(desktop): format seed document regressions * test(desktop): group launch URL regressions * fix(desktop): omit redundant nested state aliases * fix(desktop): compare added free text as a whole * fix(desktop): check recompressed seeds as shipped * docs(desktop): clarify recovered seed format * test(desktop): group shipped gzip seed checks * fix: retain quoted identifier text in task drafts * fix: recognize Unicode XML in desktop state readers * fix(desktop): bound nested draft checks * fix(desktop): explain missing arrays in truncated views * fix(desktop): find XML type references in archives * test(desktop): remove duplicated capture assertions * fix(desktop): retain nested omitted text boundaries * style(desktop): format draft value imports * test(desktop): group model and draft value checks * fix(desktop): map captured launch paths once * refactor: remove unused whole-text guard state * refactor: stop passing unused text children * test: align free-text checks with whole-note policy * fix: validate recompressed desktop archive seeds * style(desktop): format archive seed regression * fix(desktop): retain placed-item sibling guards * fix(desktop): preserve archive paths and bound doctor reads * fix(doctor): refuse non-files before descriptor admission * fix(setup): track remaining cleanup resources across retries * test(desktop): specify XML format in heap pairing fixture * fix(doctor): query agentenv for model endpoint * fix(doctor): preserve uncertainty for empty endpoint override * fix(desktop): protect host controls and quote withheld paths * fix: redact declared form-encoded secrets * fix(desktop): redact runtime schema errors * fix(desktop): normalize captured file URLs * fix(desktop): report seeded files by capture path * fix(desktop): retain startup readiness failure stage * fix(desktop): retain JSON date checks * fix(desktop): preserve archive formatting checks * fix(desktop): preserve explicitly selected journal files * fix(desktop): report build command transport limits * docs(desktop): clarify unreadable dconf versions * test(desktop): remove duplicate history regression * fix(desktop): align XML names with exported reader * fix(desktop): create selected state alias targets * fix(desktop): inspect supported runtime archives * fix(desktop): retain record identity in draft checks * fix(desktop): refuse unchecked declared secrets * fix(desktop): retain partial withheld export receipts * fix(desktop): detect escaped secrets in JSON state * fix(desktop): scrub XML independently of reader compatibility * fix(desktop): preserve file aliases and reader diagnostics * fix(desktop): scan escaped secrets in UTF-16 JSON * style(desktop): format secret scan changes * style(desktop): format review fixes * style(desktop): format capture review fixes * style(desktop): format review changes --------- Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
e5ddbe8909 |
feat(native): decode Android .note.android.ident ELF notes (#9502)
* feat(native): decode Android .note.android.ident ELF notes Decode Android NDK NT_ANDROID_TYPE_IDENT (.note.android.ident, owner Android, type 1) notes in inspect_elf_notes across legacy 4-byte and modern >=132-byte descriptors with bounded TextBudget accounting. * fix(native): isolate Android note scan budget test, scope contract import, and add feature spec * test(native): use domain tool contract in elfNotesMcp boundary test |
||
|
|
018f19d8c8 |
feat(desktop): target agentenv-framework 0.9.1464 (#9302)
* fix(desktop): preserve document URLs and value formats * fix(desktop): bound added checks and omit noisy text guards * fix(desktop): exclude unseeded locks from task checks * fix(desktop): preserve draft bounds and launch URLs * fix(desktop): render draft values using their source format * fix(desktop): preserve launch URLs and JSON draft values * fix(desktop): recognize captured file URL documents * fix(desktop): render captured file URLs for runtime home * fix(desktop): distinguish phone numbers from save metadata * fix(desktop): preserve launch URLs and user text * fix(desktop): preserve captured URLs and user text * fix(desktop): preserve local file URL authority * fix(desktop): preserve local file URL authority * fix(desktop): preserve local file URL authority * fix(desktop): render captured file URLs at launch * fix(desktop): classify numeric timestamps using field context * fix(desktop): classify numeric timestamps using field context * fix(desktop): classify numeric timestamps using field context * fix(desktop): retain context for generated draft values * fix(desktop): retain context for generated draft values * fix(desktop): retain context for generated draft values * test(desktop): cover generated IDs in text guards * test(desktop): cover generated IDs in text guards * test(desktop): cover generated IDs in text guards * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): retain clean text in noisy record fields * fix(desktop): classify added line values in one pass * fix(desktop): apply XML quote rules to text drafts * fix(desktop): distinguish XML attributes from quoted text * fix(desktop): preserve parsed XML line context * Format appTaskChecks.ts with the pinned oxfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): retain partial XML syntax facts * feat(desktop): target agentenv-framework 0.9.1464 Desktop bundles, setup's --install-agentenv and the doctor's exact-version check now target 0.9.1464, which keeps an exported app's data/get call, holds the computer fixture above boot dialogs, leaves an unresolved setting's build unverified rather than failed, and mounts lock packages instead of copying them into the image. The web environment lane stays on 0.9.1431. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): recognize markdown autolinks in drafts * fix(desktop): reuse export exclusions in task drafts * fix(desktop): reuse export exclusions in task drafts * fix(desktop): report unchecked client build paths * docs(desktop): clarify gzip seed scrubbing * fix(desktop): report unchecked client build paths * docs(desktop): clarify gzip scrub limits * fix(desktop): reuse export exclusions in task drafts * docs(desktop): clarify gzip scrub limits * fix(setup): own desktop build process cleanup * fix(setup): own desktop build process cleanup * fix(doctor): compare desktop settings with resolved defaults * fix(doctor): compare desktop settings with resolved defaults * style(desktop): format the noisy-record draft files with the pinned oxfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): give the root-array draft test its own describe The records describe grew past the 150-line lint limit with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(doctor): inspect client-recorded desktop runners * fix(doctor): inspect client-recorded desktop runners * fix(doctor): reuse matching runner probes * fix(doctor): reuse matching runner probes * fix(setup): propagate cancellation to desktop actions * fix(setup): propagate cancellation to desktop actions * fix(setup): stop Hopper on cancel, never report a cancelled setup ready, and keep a failed action's client setting - The Hopper install gets setup's signal: Linux already honoured it, and the macOS installer now stops its downloads and stops before mounting or copying. - runSetup checks the signal after the final doctor and close, so a cancellation there raises instead of returning ready. - A failed pack or agentenv install no longer writes its archive or runner to client configs, so the setting the client already had stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(setup): keep the completed setup result in a cancellation after cleanup A cancellation during the final doctor or host close carried only the applied actions, dropping each client's result and backup path and the doctor report. It now carries the whole result as setup_result, as doctor's cancellation carries its report. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): move launch execution to boundary suite * fix(desktop): redact build schema failure output * refactor(desktop): normalize schema failure once * fix(desktop): omit unsafe schema parser snippets * fix(desktop): preserve draft change and selected path evidence * test(desktop): group retained dconf note regressions * fix(desktop): respect archive entry format in draft checks * test(desktop): separate unowned-file draft note cases * fix(desktop): preserve explicitly selected journal documents * fix(xml): avoid scanning selected ancestors per tag * fix(desktop): exclude covered text runs from draft counts * fix: preserve text when drafting desktop checks * fix: restore nested desktop state aliases * refactor: share UUID recognition across draft checks * fix: retain multiline XML attribute context * fix: retain relationship identifiers in task drafts * docs: clarify desktop draft identifier handling * test(desktop): type formatting run cases as pairs * fix(desktop): carry document format into selector evaluation * test(desktop): separate markup boundary regression group * fix(desktop): propagate formats through draft selectors * fix(desktop): switch selector format within archive entries * test(desktop): remove duplicate seed filename case * fix(setup): retain diagnostics when cancellation overlaps failure * refactor(setup): keep command cancellation at its owner * test(setup): verify cancellation at the application boundary * test(desktop): pass JSON format in exported index parity * docs(desktop): clarify task checks before scratch export * fix(desktop): respell selected paths in file URLs * test(desktop): group captured document spelling cases * fix(desktop): bound draft preview serialization * fix(desktop): restore selected state aliases * fix(desktop): respect entry format in draft noise * test(desktop): match exported alias evidence at its JSON boundary * fix(desktop): retain app state logs in exported seeds * fix: align desktop numeric seed comparisons * test(desktop): keep one draft exclusion fixture import * test(desktop): retain log eligibility across draft test groups * fix(doctor): resolve empty registered desktop runner * test(desktop): use the framework pin in doctor fixtures * style: fix desktop launch test formatting * style: format native command path schema * fix(desktop): map selected external launch paths * style(desktop): format seed document regressions * test(desktop): group launch URL regressions * fix(desktop): omit redundant nested state aliases * fix(desktop): compare added free text as a whole * fix(desktop): check recompressed seeds as shipped * docs(desktop): clarify recovered seed format * test(desktop): group shipped gzip seed checks * fix: retain quoted identifier text in task drafts * fix: recognize Unicode XML in desktop state readers * fix(desktop): bound nested draft checks * fix(desktop): explain missing arrays in truncated views * fix(desktop): find XML type references in archives * test(desktop): remove duplicated capture assertions * fix(desktop): retain nested omitted text boundaries * style(desktop): format draft value imports * test(desktop): group model and draft value checks * fix(desktop): map captured launch paths once * refactor: remove unused whole-text guard state * refactor: stop passing unused text children * test: align free-text checks with whole-note policy * fix: validate recompressed desktop archive seeds * style(desktop): format archive seed regression * fix(desktop): retain placed-item sibling guards * fix(desktop): preserve archive paths and bound doctor reads * fix(doctor): refuse non-files before descriptor admission * fix(setup): track remaining cleanup resources across retries * test(desktop): specify XML format in heap pairing fixture * fix(doctor): query agentenv for model endpoint * fix(doctor): preserve uncertainty for empty endpoint override * style(desktop): format framework pin fixture * fix(desktop): redact runtime schema errors * fix(desktop): normalize captured file URLs * fix(desktop): report seeded files by capture path * fix(desktop): retain startup readiness failure stage * fix(desktop): retain JSON date checks * fix(desktop): preserve archive formatting checks * fix(desktop): preserve explicitly selected journal files * fix(desktop): report build command transport limits * docs(desktop): clarify unreadable dconf versions * test(desktop): remove duplicate history regression * fix(desktop): align XML names with exported reader * fix(desktop): create selected state alias targets * fix(desktop): inspect supported runtime archives * fix(desktop): retain record identity in draft checks * fix(desktop): inspect supported runtime archives * fix(setup): retain completed actions on cancellation * docs(desktop): clarify document lock exclusion * fix(desktop): scrub XML independently of reader compatibility * fix(desktop): preserve file aliases and reader diagnostics * style(desktop): format review fixes * style(desktop): format capture review fixes * fix(desktop): retain merged installer behavior --------- Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
fe2985a0b4 |
feat(desktop): check apps whose files REA can't read, through the app's own headless mode or a screen judge (#9217)
* fix(desktop): preserve document URLs and value formats * fix(desktop): bound added checks and omit noisy text guards * fix(desktop): exclude unseeded locks from task checks * fix(desktop): preserve draft bounds and launch URLs * fix(desktop): render draft values using their source format * fix(desktop): preserve launch URLs and JSON draft values * fix(desktop): recognize captured file URL documents * fix(desktop): render captured file URLs for runtime home * fix(desktop): distinguish phone numbers from save metadata * fix(desktop): preserve launch URLs and user text * fix(desktop): preserve captured URLs and user text * fix(desktop): preserve local file URL authority * fix(desktop): preserve local file URL authority * fix(desktop): preserve local file URL authority * fix(desktop): render captured file URLs at launch * fix(desktop): classify numeric timestamps using field context * fix(desktop): classify numeric timestamps using field context * fix(desktop): classify numeric timestamps using field context * fix(desktop): retain context for generated draft values * fix(desktop): retain context for generated draft values * fix(desktop): retain context for generated draft values * test(desktop): cover generated IDs in text guards * test(desktop): cover generated IDs in text guards * test(desktop): cover generated IDs in text guards * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): retain clean text in noisy record fields * fix(desktop): classify added line values in one pass * fix(desktop): apply XML quote rules to text drafts * fix(desktop): distinguish XML attributes from quoted text * fix(desktop): preserve parsed XML line context * Format appTaskChecks.ts with the pinned oxfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): retain partial XML syntax facts * fix(desktop): recognize markdown autolinks in drafts * fix(desktop): reuse export exclusions in task drafts * fix(desktop): report unchecked client build paths * docs(desktop): clarify gzip scrub limits * fix(desktop): reuse export exclusions in task drafts * docs(desktop): keep the judge command on one line Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(desktop): clarify gzip scrub limits * fix(setup): own desktop build process cleanup * fix(doctor): compare desktop settings with resolved defaults * style(desktop): format the noisy-record draft files with the pinned oxfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): give the root-array draft test its own describe The records describe grew past the 150-line lint limit with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(doctor): inspect client-recorded desktop runners * fix(doctor): reuse matching runner probes * fix(setup): propagate cancellation to desktop actions * fix(setup): stop Hopper on cancel, never report a cancelled setup ready, and keep a failed action's client setting - The Hopper install gets setup's signal: Linux already honoured it, and the macOS installer now stops its downloads and stops before mounting or copying. - runSetup checks the signal after the final doctor and close, so a cancellation there raises instead of returning ready. - A failed pack or agentenv install no longer writes its archive or runner to client configs, so the setting the client already had stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(setup): keep the completed setup result in a cancellation after cleanup A cancellation during the final doctor or host close carried only the applied actions, dropping each client's result and backup path and the doctor report. It now carries the whole result as setup_result, as doctor's cancellation carries its report. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): move launch execution to boundary suite * fix(desktop): redact build schema failure output * refactor(desktop): normalize schema failure once * fix(desktop): omit unsafe schema parser snippets * fix(desktop): preserve draft change and selected path evidence * test(desktop): group retained dconf note regressions * fix(desktop): respect archive entry format in draft checks * test(desktop): separate unowned-file draft note cases * fix(desktop): preserve explicitly selected journal documents * fix(xml): avoid scanning selected ancestors per tag * fix(desktop): exclude covered text runs from draft counts * fix: preserve text when drafting desktop checks * fix: restore nested desktop state aliases * refactor: share UUID recognition across draft checks * fix: retain multiline XML attribute context * fix: retain relationship identifiers in task drafts * docs: clarify desktop draft identifier handling * test(desktop): type formatting run cases as pairs * fix(desktop): carry document format into selector evaluation * test(desktop): separate markup boundary regression group * fix(desktop): propagate formats through draft selectors * fix(desktop): switch selector format within archive entries * test(desktop): remove duplicate seed filename case * fix(setup): retain diagnostics when cancellation overlaps failure * refactor(setup): keep command cancellation at its owner * test(setup): verify cancellation at the application boundary * test(desktop): pass JSON format in exported index parity * docs(desktop): clarify task checks before scratch export * fix(desktop): respell selected paths in file URLs * test(desktop): group captured document spelling cases * test(desktop): pin reader-free verifier to selector parent * fix(desktop): bound draft preview serialization * fix(desktop): restore selected state aliases * fix(desktop): respect entry format in draft noise * test(desktop): match exported alias evidence at its JSON boundary * fix(desktop): retain app state logs in exported seeds * fix: align desktop numeric seed comparisons * test(desktop): keep one draft exclusion fixture import * test(desktop): retain log eligibility across draft test groups * fix(doctor): resolve empty registered desktop runner * test(desktop): check retained log seed admission * style: fix desktop launch test formatting * style: format native command path schema * fix(desktop): map selected external launch paths * style(desktop): format seed document regressions * test(desktop): group launch URL regressions * fix(desktop): omit redundant nested state aliases * fix(desktop): compare added free text as a whole * fix(desktop): check recompressed seeds as shipped * docs(desktop): clarify recovered seed format * test(desktop): group shipped gzip seed checks * fix: retain quoted identifier text in task drafts * fix: recognize Unicode XML in desktop state readers * fix(desktop): bound nested draft checks * fix(desktop): explain missing arrays in truncated views * fix(desktop): find XML type references in archives * test(desktop): remove duplicated capture assertions * fix(desktop): retain nested omitted text boundaries * style(desktop): format draft value imports * test(desktop): group model and draft value checks * fix(desktop): map captured launch paths once * refactor: remove unused whole-text guard state * refactor: stop passing unused text children * test: align free-text checks with whole-note policy * fix: validate recompressed desktop archive seeds * style(desktop): format archive seed regression * fix(desktop): retain placed-item sibling guards * fix(desktop): preserve archive paths and bound doctor reads * fix(doctor): refuse non-files before descriptor admission * fix(setup): track remaining cleanup resources across retries * test(desktop): specify XML format in heap pairing fixture * fix(desktop): compare screen task views by value * fix(desktop): reject inexact reader numbers * fix(desktop): budget export for both reader passes * fix(desktop): bound reader runner argument size * test(desktop): verify chunked reader payloads and parent output * fix(doctor): query agentenv for model endpoint * style(desktop): format reader payload assertion * fix(doctor): preserve uncertainty for empty endpoint override * fix(desktop): redact runtime schema errors * fix(desktop): normalize captured file URLs * fix(desktop): report seeded files by capture path * fix(desktop): retain startup readiness failure stage * fix(desktop): retain JSON date checks * fix(desktop): preserve archive formatting checks * fix(desktop): preserve explicitly selected journal files * fix(desktop): report build command transport limits * docs(desktop): clarify unreadable dconf versions * test(desktop): remove duplicate history regression * fix(desktop): align XML names with exported reader * fix(desktop): create selected state alias targets * fix(desktop): inspect supported runtime archives * fix(desktop): retain record identity in draft checks * fix(desktop): align timestamp selector digits * fix(desktop): scrub XML independently of reader compatibility * fix(desktop): preserve file aliases and reader diagnostics * fix(desktop): retain remote reader cleanup ownership * style(desktop): format capture review fixes * fix(desktop): retain reader leases across verifier reloads * test(desktop): overlap reader cleanup retries * fix(desktop): run long exports within exec limits --------- Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
26d81afedd |
feat(desktop): install an app from an AppImage or an upstream tarball, pinned by its SHA-256 (#9215)
* fix(desktop): recognize captured file URL documents * fix(desktop): render captured file URLs for runtime home * fix(desktop): distinguish phone numbers from save metadata * fix(desktop): preserve launch URLs and user text * fix(desktop): preserve captured URLs and user text * fix(desktop): preserve local file URL authority * fix(desktop): preserve local file URL authority * fix(desktop): preserve local file URL authority * fix(desktop): render captured file URLs at launch * fix(desktop): classify numeric timestamps using field context * fix(desktop): classify numeric timestamps using field context * fix(desktop): classify numeric timestamps using field context * fix(desktop): retain context for generated draft values * fix(desktop): retain context for generated draft values * fix(desktop): retain context for generated draft values * test(desktop): cover generated IDs in text guards * test(desktop): cover generated IDs in text guards * test(desktop): cover generated IDs in text guards * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): retain clean text in noisy record fields * fix(desktop): classify added line values in one pass * fix(desktop): apply XML quote rules to text drafts * fix(desktop): distinguish XML attributes from quoted text * fix(desktop): preserve parsed XML line context * Format appTaskChecks.ts with the pinned oxfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): retain partial XML syntax facts * fix(desktop): recognize markdown autolinks in drafts * fix(desktop): reuse export exclusions in task drafts * fix(desktop): report unchecked client build paths * docs(desktop): clarify gzip scrub limits * fix(desktop): reuse export exclusions in task drafts * docs(desktop): clarify gzip scrub limits * fix(setup): own desktop build process cleanup * fix(doctor): compare desktop settings with resolved defaults * style(desktop): format the noisy-record draft files with the pinned oxfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): give the root-array draft test its own describe The records describe grew past the 150-line lint limit with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(doctor): inspect client-recorded desktop runners * fix(doctor): reuse matching runner probes * fix(setup): propagate cancellation to desktop actions * fix(desktop): rewrite a download's launch keys written with spaces around = The desktop entry parser accepts `Exec = notes %F` and an indented `TryExec =notes`, so the install script now matches those keys the same way instead of leaving the original program in place. Adds the feature's tasks.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(setup): stop Hopper on cancel, never report a cancelled setup ready, and keep a failed action's client setting - The Hopper install gets setup's signal: Linux already honoured it, and the macOS installer now stops its downloads and stops before mounting or copying. - runSetup checks the signal after the final doctor and close, so a cancellation there raises instead of returning ready. - A failed pack or agentenv install no longer writes its archive or runner to client configs, so the setting the client already had stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(setup): keep the completed setup result in a cancellation after cleanup A cancellation during the final doctor or host close carried only the applied actions, dropping each client's result and backup path and the doctor report. It now carries the whole result as setup_result, as doctor's cancellation carries its report. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): move launch execution to boundary suite * fix(desktop): redact build schema failure output * refactor(desktop): normalize schema failure once * fix(desktop): omit unsafe schema parser snippets * fix(desktop): preserve draft change and selected path evidence * test(desktop): group retained dconf note regressions * fix(desktop): respect archive entry format in draft checks * test(desktop): separate unowned-file draft note cases * fix(desktop): preserve explicitly selected journal documents * fix(xml): avoid scanning selected ancestors per tag * fix(desktop): exclude covered text runs from draft counts * fix: preserve text when drafting desktop checks * fix: restore nested desktop state aliases * refactor: share UUID recognition across draft checks * fix: retain multiline XML attribute context * fix: retain relationship identifiers in task drafts * docs: clarify desktop draft identifier handling * test(desktop): type formatting run cases as pairs * fix(desktop): carry document format into selector evaluation * test(desktop): separate markup boundary regression group * fix(desktop): propagate formats through draft selectors * fix(desktop): switch selector format within archive entries * test(desktop): remove duplicate seed filename case * fix(setup): retain diagnostics when cancellation overlaps failure * refactor(setup): keep command cancellation at its owner * test(setup): verify cancellation at the application boundary * test(desktop): pass JSON format in exported index parity * docs(desktop): clarify task checks before scratch export * fix(desktop): respell selected paths in file URLs * test(desktop): group captured document spelling cases * test(desktop): run installer scripts at boundary * style(desktop): remove trailing blank line * fix(desktop): bound draft preview serialization * fix(desktop): restore selected state aliases * fix(desktop): respect entry format in draft noise * test(desktop): match exported alias evidence at its JSON boundary * fix(desktop): retain app state logs in exported seeds * fix: align desktop numeric seed comparisons * test(desktop): keep one draft exclusion fixture import * test(desktop): retain log eligibility across draft test groups * fix(doctor): resolve empty registered desktop runner * style: fix desktop launch test formatting * style: format native command path schema * fix(desktop): map selected external launch paths * style(desktop): format seed document regressions * test(desktop): group launch URL regressions * fix(desktop): omit redundant nested state aliases * fix(desktop): compare added free text as a whole * fix(desktop): check recompressed seeds as shipped * docs(desktop): clarify recovered seed format * test(desktop): group shipped gzip seed checks * fix: retain quoted identifier text in task drafts * fix: recognize Unicode XML in desktop state readers * fix(desktop): bound nested draft checks * fix(desktop): explain missing arrays in truncated views * fix(desktop): find XML type references in archives * test(desktop): remove duplicated capture assertions * fix(desktop): retain nested omitted text boundaries * style(desktop): format draft value imports * test(desktop): group model and draft value checks * fix(desktop): map captured launch paths once * refactor: remove unused whole-text guard state * refactor: stop passing unused text children * test: align free-text checks with whole-note policy * fix: validate recompressed desktop archive seeds * style(desktop): format archive seed regression * fix(desktop): retain placed-item sibling guards * fix(desktop): preserve archive paths and bound doctor reads * fix(doctor): refuse non-files before descriptor admission * fix(setup): track remaining cleanup resources across retries * test(desktop): specify XML format in heap pairing fixture * fix(setup): skip Hopper launch after cancelled copy * fix(doctor): query agentenv for model endpoint * fix(doctor): preserve uncertainty for empty endpoint override * fix(desktop): redact runtime schema errors * fix(desktop): normalize captured file URLs * fix(desktop): report seeded files by capture path * fix(desktop): retain startup readiness failure stage * fix(desktop): retain JSON date checks * fix(desktop): preserve archive formatting checks * fix(desktop): preserve explicitly selected journal files * fix(desktop): report build command transport limits * docs(desktop): clarify unreadable dconf versions * test(desktop): remove duplicate history regression * fix(desktop): align XML names with exported reader * fix(desktop): create selected state alias targets * fix(desktop): inspect supported runtime archives * fix(desktop): keep ordinary text checks exact * fix(desktop): verify registered build host paths * fix(desktop): retain record identity in draft checks * test(desktop): preserve text reference numbers * fix(desktop): bound download install input reads * fix(desktop): match placed notes by whole text * fix(desktop): scrub XML independently of reader compatibility * fix(desktop): preserve file aliases and reader diagnostics * style(desktop): format review fixes * fix(desktop): inspect archives with registered runner * test(desktop): verify registered archive interpreter * style(desktop): format capture review fixes --------- Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
61ab3f0c4f |
feat(desktop): name a record by a nested field or a child's attribute (#9185)
* fix(desktop): keep a selected folder that is named like a database log A folder the caller selected stays a selected root when its name ends in -journal or -wal. A generated log beside a database file still does not. * fix(desktop): refuse a build command that exceeds the argument vector Splitting one argument still leaves the whole command under Linux's E2BIG limit. A request past that budget is refused before the process starts. * fix(desktop): remap a captured path in an env assignment The program word stays the program. A NAME=value assignment keeps its name and follows a captured path value when that path's spelling moves. * fix(desktop): keep oversized text out of draft guards A value or line longer than the draft's text bound is not copied into a guard, so one large frame cannot fill the task by itself. * docs(desktop): correct dconf and check-preview guidance A dconf version kept without its bytes is unreadable, not an empty key list. A values preview is copied into a check only when it is an uncut scalar. * fix(desktop): keep an empty env value empty An empty assignment is not a path. Resolving it named the working directory and rewrote the value when that directory's spelling moved. * fix(desktop): keep a run's font on the run, not the frame's text A formatting attribute such as Scribus FONT is not the document's words. Joining it across runs made a frame-wide text check of ItalicBold that failed when a run was split. The font stays a value check on its own run. * fix(desktop): do not pair JSON records by a selector-shaped field A field named @record_id matched the id suffix and became [@record_id=one], which reads an XML attribute. Records paired while their pointers matched nothing. Names that start with @ or > are not id fields. * fix(desktop): count a save-numbered id once when pairing members xml:id and draw:id values such as id123456 were both generated and numbered, so the same selector was counted twice and refused. A text edit of two elements keyed only by those ids now keeps its check. * fix(desktop): count members of root JSON arrays * fix(desktop): preserve selected state directory aliases * docs(desktop): explain tool and skill refresh prerequisites * fix(desktop): align nested state selections with aliases * fix(desktop): check build runtime export capability * fix(desktop): provide complete runtime repack command * fix(desktop): retain runtime probe failures * test(desktop): identify capture independently of schema preflight * fix(desktop): preserve document URLs and value formats * fix(desktop): bound added checks and omit noisy text guards * fix(desktop): exclude unseeded locks from task checks * fix(desktop): preserve draft bounds and launch URLs * fix(desktop): render draft values using their source format * fix(desktop): preserve launch URLs and JSON draft values * fix(desktop): recognize captured file URL documents * fix(desktop): render captured file URLs for runtime home * fix(desktop): distinguish phone numbers from save metadata * fix(desktop): preserve launch URLs and user text * fix(desktop): preserve captured URLs and user text * fix(desktop): preserve local file URL authority * fix(desktop): preserve local file URL authority * fix(desktop): preserve local file URL authority * fix(desktop): render captured file URLs at launch * fix(desktop): classify numeric timestamps using field context * fix(desktop): classify numeric timestamps using field context * fix(desktop): classify numeric timestamps using field context * fix(desktop): retain context for generated draft values * fix(desktop): retain context for generated draft values * fix(desktop): retain context for generated draft values * test(desktop): cover generated IDs in text guards * test(desktop): cover generated IDs in text guards * test(desktop): cover generated IDs in text guards * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): retain clean text in noisy record fields * fix(desktop): classify added line values in one pass * fix(desktop): apply XML quote rules to text drafts * fix(desktop): distinguish XML attributes from quoted text * fix(desktop): preserve parsed XML line context * Format appTaskChecks.ts with the pinned oxfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): retain partial XML syntax facts * fix(desktop): recognize markdown autolinks in drafts * fix(desktop): reuse export exclusions in task drafts * docs(desktop): clarify gzip scrub limits * style(desktop): format the noisy-record draft files with the pinned oxfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): give the root-array draft test its own describe The records describe grew past the 150-line lint limit with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): move launch execution to boundary suite * fix(desktop): redact build schema failure output * refactor(desktop): normalize schema failure once * fix(desktop): omit unsafe schema parser snippets * fix(desktop): preserve draft change and selected path evidence * test(desktop): group retained dconf note regressions * fix(desktop): respect archive entry format in draft checks * test(desktop): separate unowned-file draft note cases * fix(desktop): preserve explicitly selected journal documents * fix(xml): avoid scanning selected ancestors per tag * fix(desktop): exclude covered text runs from draft counts * fix: preserve text when drafting desktop checks * fix: restore nested desktop state aliases * refactor: share UUID recognition across draft checks * fix: retain multiline XML attribute context * fix: retain relationship identifiers in task drafts * docs: clarify desktop draft identifier handling * test(desktop): type formatting run cases as pairs * fix(desktop): carry document format into selector evaluation * test(desktop): separate markup boundary regression group * fix(desktop): propagate formats through draft selectors * fix(desktop): switch selector format within archive entries * test(desktop): remove duplicate seed filename case * test(desktop): pass JSON format in exported index parity * docs(desktop): clarify task checks before scratch export * fix(desktop): respell selected paths in file URLs * test(desktop): group captured document spelling cases * fix(desktop): bound draft preview serialization * fix(desktop): restore selected state aliases * fix(desktop): respect entry format in draft noise * test(desktop): match exported alias evidence at its JSON boundary * fix(desktop): retain app state logs in exported seeds * fix: align desktop numeric seed comparisons * test(desktop): keep one draft exclusion fixture import * test(desktop): retain log eligibility across draft test groups * style: fix desktop launch test formatting * style: format native command path schema * fix(desktop): map selected external launch paths * style(desktop): format seed document regressions * test(desktop): group launch URL regressions * fix(desktop): omit redundant nested state aliases * fix(desktop): compare added free text as a whole * fix(desktop): check recompressed seeds as shipped * docs(desktop): clarify recovered seed format * test(desktop): group shipped gzip seed checks * fix: retain quoted identifier text in task drafts * fix: recognize Unicode XML in desktop state readers * fix(desktop): bound nested draft checks * fix(desktop): explain missing arrays in truncated views * fix(desktop): find XML type references in archives * test(desktop): remove duplicated capture assertions * fix(desktop): retain nested omitted text boundaries * style(desktop): format draft value imports * test(desktop): group model and draft value checks * fix(desktop): map captured launch paths once * refactor: remove unused whole-text guard state * refactor: stop passing unused text children * test: align free-text checks with whole-note policy * fix: validate recompressed desktop archive seeds * style(desktop): format archive seed regression * fix(desktop): retain placed-item sibling guards * test(desktop): specify XML format in heap pairing fixture * fix(desktop): redact runtime schema errors * fix(desktop): normalize captured file URLs * fix(desktop): report seeded files by capture path * fix(desktop): retain startup readiness failure stage * fix(desktop): retain JSON date checks * fix(desktop): preserve archive formatting checks * fix(desktop): preserve explicitly selected journal files * fix(desktop): report build command transport limits * docs(desktop): clarify unreadable dconf versions * test(desktop): remove duplicate history regression * fix(desktop): align XML names with exported reader * fix(desktop): retain record identity in draft checks * fix(desktop): scrub XML independently of reader compatibility * style(desktop): format review fixes * style(desktop): format capture review fixes --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
012861ce1d |
feat(desktop): draft child-text selectors, member counts and attribute text, and fold in a third batch's findings (#9132)
* fix(desktop): follow a database mapping and own limitation text A selected database keeps its log when a parent folder moves or the file sits outside the home. Trash and seed-lock tests compare the owning notice with the paths, and launch options that are not captured paths stay as written. * test(desktop): pass the selected log into the draft The export's selected home paths decide which log stays in the draft. The line-guard test now names that log instead of relying on its reason. * fix(desktop): retarget a settings folder that holds captured files A nested profile directory is a captured path when a seeded file is inside it. An option value that only resolves under the home stays as written. * fix(desktop): keep a program word and a directory's neighbor The program after env stays the program even when a captured file sits in a folder of that name. A selected directory is not a database, so a neighboring file keeps the parent folder's spelling. * fix(desktop): record whether a selected path is a directory Capture stores the walked path's kind. A neighboring file of a selected directory keeps the parent folder's spelling even when that directory never changes and its children are not content roots. * fix(desktop): mark containing paths without a pairwise scan A recorded path marks its known ancestors as directories in one walk up the path, instead of comparing every recorded path with every other. * fix(desktop): keep a selected folder that is named like a database log A folder the caller selected stays a selected root when its name ends in -journal or -wal. A generated log beside a database file still does not. * fix(desktop): refuse a build command that exceeds the argument vector Splitting one argument still leaves the whole command under Linux's E2BIG limit. A request past that budget is refused before the process starts. * fix(desktop): remap a captured path in an env assignment The program word stays the program. A NAME=value assignment keeps its name and follows a captured path value when that path's spelling moves. * fix(desktop): keep oversized text out of draft guards A value or line longer than the draft's text bound is not copied into a guard, so one large frame cannot fill the task by itself. * docs(desktop): correct dconf and check-preview guidance A dconf version kept without its bytes is unreadable, not an empty key list. A values preview is copied into a check only when it is an uncut scalar. * fix(desktop): keep an empty env value empty An empty assignment is not a path. Resolving it named the working directory and rewrote the value when that directory's spelling moved. * fix(desktop): keep a run's font on the run, not the frame's text A formatting attribute such as Scribus FONT is not the document's words. Joining it across runs made a frame-wide text check of ItalicBold that failed when a run was split. The font stays a value check on its own run. * fix(desktop): do not pair JSON records by a selector-shaped field A field named @record_id matched the id suffix and became [@record_id=one], which reads an XML attribute. Records paired while their pointers matched nothing. Names that start with @ or > are not id fields. * fix(desktop): count a save-numbered id once when pairing members xml:id and draw:id values such as id123456 were both generated and numbered, so the same selector was counted twice and refused. A text edit of two elements keyed only by those ids now keeps its check. * fix(desktop): preserve selected state directory aliases * fix(desktop): align nested state selections with aliases * fix(desktop): check build runtime export capability * fix(desktop): provide complete runtime repack command * fix(desktop): retain runtime probe failures * test(desktop): identify capture independently of schema preflight * fix(desktop): preserve document URLs and value formats * fix(desktop): bound added checks and omit noisy text guards * fix(desktop): exclude unseeded locks from task checks * fix(desktop): preserve draft bounds and launch URLs * fix(desktop): render draft values using their source format * fix(desktop): preserve launch URLs and JSON draft values * fix(desktop): recognize captured file URL documents * fix(desktop): render captured file URLs for runtime home * fix(desktop): distinguish phone numbers from save metadata * fix(desktop): preserve launch URLs and user text * fix(desktop): preserve captured URLs and user text * fix(desktop): preserve local file URL authority * fix(desktop): preserve local file URL authority * fix(desktop): preserve local file URL authority * fix(desktop): render captured file URLs at launch * fix(desktop): classify numeric timestamps using field context * fix(desktop): classify numeric timestamps using field context * fix(desktop): classify numeric timestamps using field context * fix(desktop): retain context for generated draft values * fix(desktop): retain context for generated draft values * fix(desktop): retain context for generated draft values * test(desktop): cover generated IDs in text guards * test(desktop): cover generated IDs in text guards * test(desktop): cover generated IDs in text guards * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): retain clean text in noisy record fields * fix(desktop): classify added line values in one pass * fix(desktop): apply XML quote rules to text drafts * fix(desktop): distinguish XML attributes from quoted text * fix(desktop): preserve parsed XML line context * fix(desktop): retain partial XML syntax facts * fix(desktop): recognize markdown autolinks in drafts * fix(desktop): reuse export exclusions in task drafts * docs(desktop): clarify gzip scrub limits * style(desktop): format the noisy-record draft files with the pinned oxfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): move launch execution to boundary suite * fix(desktop): redact build schema failure output * refactor(desktop): normalize schema failure once * fix(desktop): omit unsafe schema parser snippets * fix(desktop): preserve draft change and selected path evidence * test(desktop): group retained dconf note regressions * fix(desktop): respect archive entry format in draft checks * test(desktop): separate unowned-file draft note cases * fix(desktop): preserve explicitly selected journal documents * fix(xml): avoid scanning selected ancestors per tag * fix(desktop): exclude covered text runs from draft counts * fix: preserve text when drafting desktop checks * fix: restore nested desktop state aliases * refactor: share UUID recognition across draft checks * fix: retain multiline XML attribute context * fix: retain relationship identifiers in task drafts * docs: clarify desktop draft identifier handling * test(desktop): type formatting run cases as pairs * test(desktop): separate markup boundary regression group * docs(desktop): clarify task checks before scratch export * fix(desktop): respell selected paths in file URLs * test(desktop): group captured document spelling cases * fix(desktop): bound draft preview serialization * fix(desktop): restore selected state aliases * fix(desktop): respect entry format in draft noise * test(desktop): match exported alias evidence at its JSON boundary * fix(desktop): retain app state logs in exported seeds * fix: align desktop numeric seed comparisons * test(desktop): keep one draft exclusion fixture import * test(desktop): retain log eligibility across draft test groups * style: fix desktop launch test formatting * style: format native command path schema * fix(desktop): map selected external launch paths * style(desktop): format seed document regressions * test(desktop): group launch URL regressions * fix(desktop): omit redundant nested state aliases * fix(desktop): compare added free text as a whole * fix(desktop): check recompressed seeds as shipped * docs(desktop): clarify recovered seed format * test(desktop): group shipped gzip seed checks * fix: retain quoted identifier text in task drafts * fix: recognize Unicode XML in desktop state readers * fix(desktop): bound nested draft checks * fix(desktop): explain missing arrays in truncated views * fix(desktop): find XML type references in archives * test(desktop): remove duplicated capture assertions * fix(desktop): retain nested omitted text boundaries * style(desktop): format draft value imports * test(desktop): group model and draft value checks * fix(desktop): map captured launch paths once * refactor: remove unused whole-text guard state * refactor: stop passing unused text children * test: align free-text checks with whole-note policy * fix: validate recompressed desktop archive seeds * style(desktop): format archive seed regression * fix(desktop): retain placed-item sibling guards * fix(desktop): redact runtime schema errors * fix(desktop): normalize captured file URLs * fix(desktop): report seeded files by capture path * fix(desktop): retain startup readiness failure stage * fix(desktop): retain JSON date checks * fix(desktop): preserve archive formatting checks * fix(desktop): preserve explicitly selected journal files * fix(desktop): report build command transport limits * docs(desktop): clarify unreadable dconf versions * style(desktop): format capture review fixes --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
0dcd0dfc20 |
feat(desktop): check text kept in attributes, name a record by a child's text, and count members (#9114)
* fix(desktop): keep a lone lock a document and drop one beside its file A selected name such as notes.lck stays a document, so launch and the draft still treat it as the caller's file. A lock beside a recorded sibling is left out of the seed unless that lock path itself was selected. * fix(desktop): require the added record and leave save times out of list checks A record a selector names is checked itself, so its words have to be in that record. When an unnamed record only repeats words the seed already has, a list that holds a save time is checked by the text around that time. A later save of the same records still passes, and a missing or rewritten record fails. * fix(desktop): judge the older index helper by pointer segments only A leading zero in a file name or a URL does not change how the older index helper reads a pointer. The witness still rejects that helper when a pointer segment is a number such as 01. * fix(desktop): keep a document whose name ends in .lock A lock beside a recorded file still stays out of the seed unless that lock was selected. A document such as Cargo.lock in the home is the user's file, so the seed keeps it. An application lock in the home, such as poedit.lock, stays out. * fix(desktop): do not suggest list text the seed already passes A repeated record is shown by text the seed does not hold. The seed's own text is not a check. A pointer inside a check value is not a pointer segment for the older index helper. * fix(desktop): do not let a left-out lock hide settings checks A sibling lock the seed omits is not the document the draft follows. Settings changes stay suggested. The unused sibling-lock name helper is removed. * fix(desktop): keep a linked settings file in the folder the link points at A selected ~/.config alias no longer moves MuseScore settings to that alias. The seed keeps settings/MuseScore or Documents, which is the path the export opens the note from. * fix(desktop): split home fetches by answer size and keep a size refusal A batch of tiny files stops before each path's envelope exceeds the host answer budget. A capture output past that ceiling stays a resource error instead of becoming a generic exit. * fix(desktop): seed a selected link under the path the app uses The selected spelling wins, so ~/.config/MuseScore is not rewritten to the folder it points at and the note stays the one launched document. A database wal and journal follow that database. A launch argument is respelled the same way. Teardown signals a detached PID only when its start identity still matches. * fix(desktop): keep a witness's actions and an incomplete checkpoint A failed witness save retries the action log it first recorded. A deletion left unconfirmed between the seed and the end is not reported as no change. Windows packs npm through a shell, which can start npm.cmd. * fix(desktop): read verifier pointers from the parsed checks A brace inside a check value is not an object boundary. A leading-zero pointer after that value still rejects the older index helper. * fix(desktop): leave out a sibling lock under a selected folder A file under a selected folder inherits selected_path. That does not make the lock beside its map a chosen document, so a settings change stays drafted. * fix(desktop): prefer the most specific home spelling and retarget launch files A selected parent directory no longer hides a settings folder walked through a link. A launch filename under that folder is replaced with the seeded file's absolute path. * fix(desktop): pack the build runtime through npm's JavaScript entry npm pack and npm ci no longer spawn npm.cmd through a shell, so a temporary directory whose path contains spaces stays one argument. * fix(desktop): spell launch settings and keep a database log exact A database log matches only that file, so a neighboring folder is not moved. A launch option and the working directory use the same home spelling as the seed. * fix(desktop): draft a lock the export selected exactly The draft uses the same selected paths as the export. A lock chosen by itself stays in the draft. A lock under a selected folder stays out. * fix(desktop): move a state database's logs with the database The write-ahead log and journal follow the spelling the database received, including a walked state link. A neighboring folder stays put. A separate --config argument uses that spelling too. * fix(desktop): keep a selected file ahead of a database-log guess A file selected as itself keeps that spelling even when its name ends in -journal. Relative launch arguments are resolved in the captured working directory before that directory moves. * fix(desktop): keep outside-home database logs and option values A selected database outside the home keeps its write-ahead log. Launch options are rewritten only when they name a captured file or settings path. * fix(desktop): follow a database mapping and own limitation text A selected database keeps its log when a parent folder moves or the file sits outside the home. Trash and seed-lock tests compare the owning notice with the paths, and launch options that are not captured paths stay as written. * fix(desktop): retarget a settings folder that holds captured files A nested profile directory is a captured path when a seeded file is inside it. An option value that only resolves under the home stays as written. * fix(desktop): keep a program word and a directory's neighbor The program after env stays the program even when a captured file sits in a folder of that name. A selected directory is not a database, so a neighboring file keeps the parent folder's spelling. * fix(desktop): record whether a selected path is a directory Capture stores the walked path's kind. A neighboring file of a selected directory keeps the parent folder's spelling even when that directory never changes and its children are not content roots. * fix(desktop): mark containing paths without a pairwise scan A recorded path marks its known ancestors as directories in one walk up the path, instead of comparing every recorded path with every other. * fix(desktop): keep a selected folder that is named like a database log A folder the caller selected stays a selected root when its name ends in -journal or -wal. A generated log beside a database file still does not. * fix(desktop): refuse a build command that exceeds the argument vector Splitting one argument still leaves the whole command under Linux's E2BIG limit. A request past that budget is refused before the process starts. * fix(desktop): remap a captured path in an env assignment The program word stays the program. A NAME=value assignment keeps its name and follows a captured path value when that path's spelling moves. * fix(desktop): keep oversized text out of draft guards A value or line longer than the draft's text bound is not copied into a guard, so one large frame cannot fill the task by itself. * docs(desktop): correct dconf and check-preview guidance A dconf version kept without its bytes is unreadable, not an empty key list. A values preview is copied into a check only when it is an uncut scalar. * fix(desktop): keep an empty env value empty An empty assignment is not a path. Resolving it named the working directory and rewrote the value when that directory's spelling moved. * fix(desktop): check build runtime export capability * fix(desktop): provide complete runtime repack command * fix(desktop): retain runtime probe failures * test(desktop): identify capture independently of schema preflight * fix(desktop): preserve document URLs and value formats * fix(desktop): bound added checks and omit noisy text guards * fix(desktop): preserve launch URLs and JSON draft values * fix(desktop): recognize captured file URL documents * fix(desktop): render captured file URLs for runtime home * fix(desktop): distinguish phone numbers from save metadata * fix(desktop): preserve launch URLs and user text * fix(desktop): preserve local file URL authority * fix(desktop): preserve local file URL authority * fix(desktop): render captured file URLs at launch * fix(desktop): classify numeric timestamps using field context * fix(desktop): classify numeric timestamps using field context * fix(desktop): retain context for generated draft values * fix(desktop): retain context for generated draft values * test(desktop): cover generated IDs in text guards * test(desktop): cover generated IDs in text guards * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): retain clean text in noisy record fields * style(desktop): format the noisy-record draft files with the pinned oxfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): move launch execution to boundary suite * fix(desktop): redact build schema failure output * refactor(desktop): normalize schema failure once * fix(desktop): omit unsafe schema parser snippets * fix(desktop): preserve draft change and selected path evidence * test(desktop): group retained dconf note regressions * fix(desktop): respect archive entry format in draft checks * test(desktop): separate unowned-file draft note cases * fix(desktop): preserve explicitly selected journal documents * fix(xml): avoid scanning selected ancestors per tag * docs(desktop): clarify task checks before scratch export * fix(desktop): respell selected paths in file URLs * test(desktop): group captured document spelling cases * fix(desktop): bound draft preview serialization * fix(desktop): restore selected state aliases * fix(desktop): respect entry format in draft noise * test(desktop): match exported alias evidence at its JSON boundary * fix(desktop): retain app state logs in exported seeds * style: fix desktop launch test formatting * style: format native command path schema * fix(desktop): map selected external launch paths * style(desktop): format seed document regressions * test(desktop): group launch URL regressions * fix(desktop): omit redundant nested state aliases * fix(desktop): compare added free text as a whole * fix(desktop): check recompressed seeds as shipped * docs(desktop): clarify recovered seed format * test(desktop): group shipped gzip seed checks * fix(desktop): map captured launch paths once * refactor: remove unused whole-text guard state * refactor: stop passing unused text children * test: align free-text checks with whole-note policy * fix: validate recompressed desktop archive seeds * style(desktop): format archive seed regression * fix(desktop): redact runtime schema errors * fix(desktop): normalize captured file URLs * fix(desktop): report seeded files by capture path * fix(desktop): retain startup readiness failure stage * fix(desktop): retain JSON date checks * fix(desktop): preserve archive formatting checks * fix(desktop): preserve explicitly selected journal files * fix(desktop): report build command transport limits * docs(desktop): clarify unreadable dconf versions * style(desktop): format capture review fixes --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
35f1c3517f |
feat(desktop): install extra packages beside an archive app, and keep a package file's dependencies at export (#9112)
* fix(desktop): keep added-record checks off ids, dates, and joined timestamps A position-named record's fields keep their paths, so an identifier, a stamped date, and text past the limit are not suggested checks. A whole-text check does not climb into an ancestor whose text joins a timestamp. * fix(desktop): bound home fetches and keep unsettled edits readable Split home-folder reads by the guest answer budget, keep a capacity error from the capture output, and drop the superseded task-argument refusal. Grade kept text per line, leave unretained dconf unread, and reserve by-position notes for XML children. Map a linked database's sidecars through the selected spelling and stop a detached capture only when its start identity still owns the pid. * fix(desktop): describe unretained dconf as unread The key comparison treats a missing copy as unknown. The comment still said that copy counted as an empty key list. * test(desktop): keep a capture capacity error through endedCapture An output past the guest answer ceiling stays the resource constraint, with its heap recovery and non-retryable status, instead of a generic capture-exit message. * fix(desktop): keep nested save times and formatting runs out of checks A field check drops save-time leaves before it joins the field, so a nested timestamp is not part of the suggested text. A text check beside a save time uses the paragraph when the diff names a formatting run. * test(desktop): read paragraph pointers from checks that have them * test(desktop): expect a large task to export intact The 96 KiB refusal is gone. A prompt past that size reaches the computer and comes back unchanged, instead of failing before export. * fix(desktop): keep real edits that save-side heuristics were dropping Repeated unnamed fields stay content checks. A formula that still has text is not renumbered with its ExprID. One gained style attribute is the edit; a repeated fill-in stays upkeep. Phone numbers and plain clock times stay text, and a decimal is the element's whole text. An older verifier matches on the task it states, not its evaluator source. * fix(desktop): cover repeated records and keep timestamps out of checks An added record whose words are already in the seed still gets the list's text when that text fits. Readiness is a start reason, so a final check names seed locks without matching the message. Field text split by a timestamp stays separate, and a timestamp line is not offered as a guard. * fix(desktop): compare a cell's joined decimal within tolerance The whole-element check keeps numeric tolerance, so 437.80 and a long float still match 437.8, including when a run splits the digits. A different number or other text does not. Both evaluators read an element's text for that comparison. * fix(desktop): keep selected logs and stop treating unknown walks as complete Match an app name as a whole token, treat an omitted unchecked_paths count as incomplete, seed Chromium user_prefs.json, and keep a caller-selected log even when that path is also a state directory. A log inside the app's own folder still marks that folder so settings beside it stay seeded, while a lock in the home does not. Sibling locks under a selected folder stay out unless that lock was the selected path. * fix(desktop): grade a number from a complete XML element only A tolerance check joins an element's text only in an XML file or an XML archive entry, and leaves that check undecided when the view is cut, so a dropped descendant cannot turn the kept runs into a passing number. A JSON object with the same shape stays the value itself. Equivalent decimals and a split run on a whole cell still match. * fix(desktop): accept an older grader only when its index helper agrees The witness still matches a bundle whose evaluator is this REA's, or the older index expression alone when no path segment is a leading-zero number. A truncated verifier, a changed grader, or that older helper beside a segment such as 01 no longer counts as the same task. * fix(desktop): keep a lone lock a document and drop one beside its file A selected name such as notes.lck stays a document, so launch and the draft still treat it as the caller's file. A lock beside a recorded sibling is left out of the seed unless that lock path itself was selected. * fix(desktop): require the added record and leave save times out of list checks A record a selector names is checked itself, so its words have to be in that record. When an unnamed record only repeats words the seed already has, a list that holds a save time is checked by the text around that time. A later save of the same records still passes, and a missing or rewritten record fails. * fix(desktop): judge the older index helper by pointer segments only A leading zero in a file name or a URL does not change how the older index helper reads a pointer. The witness still rejects that helper when a pointer segment is a number such as 01. * fix(desktop): keep a document whose name ends in .lock A lock beside a recorded file still stays out of the seed unless that lock was selected. A document such as Cargo.lock in the home is the user's file, so the seed keeps it. An application lock in the home, such as poedit.lock, stays out. * fix(desktop): do not suggest list text the seed already passes A repeated record is shown by text the seed does not hold. The seed's own text is not a check. A pointer inside a check value is not a pointer segment for the older index helper. * fix(desktop): do not let a left-out lock hide settings checks A sibling lock the seed omits is not the document the draft follows. Settings changes stay suggested. The unused sibling-lock name helper is removed. * fix(desktop): keep a linked settings file in the folder the link points at A selected ~/.config alias no longer moves MuseScore settings to that alias. The seed keeps settings/MuseScore or Documents, which is the path the export opens the note from. * fix(desktop): split home fetches by answer size and keep a size refusal A batch of tiny files stops before each path's envelope exceeds the host answer budget. A capture output past that ceiling stays a resource error instead of becoming a generic exit. * fix(desktop): seed a selected link under the path the app uses The selected spelling wins, so ~/.config/MuseScore is not rewritten to the folder it points at and the note stays the one launched document. A database wal and journal follow that database. A launch argument is respelled the same way. Teardown signals a detached PID only when its start identity still matches. * fix(desktop): keep a witness's actions and an incomplete checkpoint A failed witness save retries the action log it first recorded. A deletion left unconfirmed between the seed and the end is not reported as no change. Windows packs npm through a shell, which can start npm.cmd. * fix(desktop): read verifier pointers from the parsed checks A brace inside a check value is not an object boundary. A leading-zero pointer after that value still rejects the older index helper. * fix(desktop): leave out a sibling lock under a selected folder A file under a selected folder inherits selected_path. That does not make the lock beside its map a chosen document, so a settings change stays drafted. * fix(desktop): prefer the most specific home spelling and retarget launch files A selected parent directory no longer hides a settings folder walked through a link. A launch filename under that folder is replaced with the seeded file's absolute path. * fix(desktop): pack the build runtime through npm's JavaScript entry npm pack and npm ci no longer spawn npm.cmd through a shell, so a temporary directory whose path contains spaces stays one argument. * fix(desktop): spell launch settings and keep a database log exact A database log matches only that file, so a neighboring folder is not moved. A launch option and the working directory use the same home spelling as the seed. * fix(desktop): draft a lock the export selected exactly The draft uses the same selected paths as the export. A lock chosen by itself stays in the draft. A lock under a selected folder stays out. * fix(desktop): move a state database's logs with the database The write-ahead log and journal follow the spelling the database received, including a walked state link. A neighboring folder stays put. A separate --config argument uses that spelling too. * fix(desktop): keep a selected file ahead of a database-log guess A file selected as itself keeps that spelling even when its name ends in -journal. Relative launch arguments are resolved in the captured working directory before that directory moves. * fix(desktop): keep outside-home database logs and option values A selected database outside the home keeps its write-ahead log. Launch options are rewritten only when they name a captured file or settings path. * fix(desktop): follow a database mapping and own limitation text A selected database keeps its log when a parent folder moves or the file sits outside the home. Trash and seed-lock tests compare the owning notice with the paths, and launch options that are not captured paths stay as written. * fix(desktop): retarget a settings folder that holds captured files A nested profile directory is a captured path when a seeded file is inside it. An option value that only resolves under the home stays as written. * fix(desktop): keep a program word and a directory's neighbor The program after env stays the program even when a captured file sits in a folder of that name. A selected directory is not a database, so a neighboring file keeps the parent folder's spelling. * fix(desktop): record whether a selected path is a directory Capture stores the walked path's kind. A neighboring file of a selected directory keeps the parent folder's spelling even when that directory never changes and its children are not content roots. * fix(desktop): mark containing paths without a pairwise scan A recorded path marks its known ancestors as directories in one walk up the path, instead of comparing every recorded path with every other. * fix(desktop): keep a selected folder that is named like a database log A folder the caller selected stays a selected root when its name ends in -journal or -wal. A generated log beside a database file still does not. * fix(desktop): refuse a build command that exceeds the argument vector Splitting one argument still leaves the whole command under Linux's E2BIG limit. A request past that budget is refused before the process starts. * fix(desktop): remap a captured path in an env assignment The program word stays the program. A NAME=value assignment keeps its name and follows a captured path value when that path's spelling moves. * fix(desktop): keep oversized text out of draft guards A value or line longer than the draft's text bound is not copied into a guard, so one large frame cannot fill the task by itself. * fix(desktop): keep an empty env value empty An empty assignment is not a path. Resolving it named the working directory and rewrote the value when that directory's spelling moved. * fix(desktop): check build runtime export capability * fix(desktop): provide complete runtime repack command * fix(desktop): retain runtime probe failures * test(desktop): identify capture independently of schema preflight * fix(desktop): preserve document URLs and value formats * fix(desktop): bound added checks and omit noisy text guards * fix(desktop): preserve launch URLs and JSON draft values * fix(desktop): recognize captured file URL documents * fix(desktop): render captured file URLs for runtime home * fix(desktop): distinguish phone numbers from save metadata * fix(desktop): preserve launch URLs and user text * fix(desktop): preserve local file URL authority * fix(desktop): preserve local file URL authority * fix(desktop): render captured file URLs at launch * fix(desktop): classify numeric timestamps using field context * fix(desktop): classify numeric timestamps using field context * fix(desktop): retain context for generated draft values * fix(desktop): retain context for generated draft values * test(desktop): cover generated IDs in text guards * test(desktop): cover generated IDs in text guards * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): retain clean text in noisy record fields * style(desktop): format the noisy-record draft files with the pinned oxfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): move launch execution to boundary suite * fix(desktop): redact build schema failure output * refactor(desktop): normalize schema failure once * fix(desktop): omit unsafe schema parser snippets * fix(desktop): preserve draft change and selected path evidence * test(desktop): group retained dconf note regressions * fix(desktop): respect archive entry format in draft checks * test(desktop): separate unowned-file draft note cases * fix(desktop): preserve explicitly selected journal documents * docs(desktop): clarify task checks before scratch export * fix(desktop): respell selected paths in file URLs * test(desktop): group captured document spelling cases * fix(desktop): bound draft preview serialization * fix(desktop): restore selected state aliases * fix(desktop): respect entry format in draft noise * test(desktop): match exported alias evidence at its JSON boundary * fix(desktop): retain app state logs in exported seeds * style: fix desktop launch test formatting * style: format native command path schema * fix(desktop): map selected external launch paths * style(desktop): format seed document regressions * test(desktop): group launch URL regressions * fix(desktop): omit redundant nested state aliases * fix(desktop): compare added free text as a whole * fix(desktop): check recompressed seeds as shipped * docs(desktop): clarify recovered seed format * test(desktop): group shipped gzip seed checks * fix(desktop): map captured launch paths once * refactor: remove unused whole-text guard state * refactor: stop passing unused text children * test: align free-text checks with whole-note policy * fix: validate recompressed desktop archive seeds * style(desktop): format archive seed regression * fix(desktop): redact runtime schema errors * fix(desktop): normalize captured file URLs * fix(desktop): report seeded files by capture path * fix(desktop): retain startup readiness failure stage * fix(desktop): retain JSON date checks * fix(desktop): preserve archive formatting checks * fix(desktop): preserve explicitly selected journal files * fix(desktop): report build command transport limits * docs(desktop): clarify unreadable dconf versions * style(desktop): format capture review fixes --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
8bc01b48b4 |
feat(native): list ELF and Mach-O initializer and finalizer functions (#9574)
* feat(native): list ELF and Mach-O initializer and finalizer functions inspect_native_initializers and inspect-native-initializers list the functions an ELF or Mach-O image runs before and after main: ELF DT_INIT, DT_FINI, preinit, init and fini arrays and .ctors/.dtors, and Mach-O __mod_init_func, __mod_term_func and __init_offsets, with slot addresses, resolved targets, symbols where available and relocation facts for relocatable objects. Nothing is executed. Slot, symbol, relocation and note budgets are shared across tables, sentinels are matched at the image width, and target-derived names are bounded and marked untrusted. * fix(native): keep ELF initializer slots unresolved when relocation coverage is partial A skipped, unreadable or over-budget section relocation table now keeps every slot it could reach unresolved instead of reading the stored word as raw or dropping a .ctors slot as a sentinel. Dynamic writes that only partly overlap a slot, or write it twice, leave it unresolved. Linked images no longer reapply retained non-SHF_ALLOC link-time records. The dynamic relocation walk now pauses at the shared reader's step boundaries and observes cancellation there, resolved targets need only their first byte mapped, and unreadable symbol names make the report incomplete. * fix(native): stop reporting unchecked Mach-O initializer words as resolved Object files now apply their own section relocations: an UNSIGNED entry against a defined symbol gives symbol_addend, one against an undefined symbol gives unresolved_import, and any other entry leaves the slot unresolved. Linked images without a fixup decoder, such as 32-bit ones, keep pointer slots unresolved when an LC_DYLD_INFO bind stream or LC_DYSYMTAB external relocations could replace the stored word. LC_DYLD_INFO rebases now report dyld_info_rebase instead of chained_fixup, and unreadable symbol names make the report incomplete. Section headers keep their declared reloff and nreloc for this. * docs(native): move initializer guide under docs/guides/native The documentation guide assigns analyst workflows to docs/guides/<domain>/. Move the guide there, place its navigation and directory entries in the Native binaries group, and update links from the docs index, CLI guide, spec and authored skill. The public /native-initializers route is unchanged. The guide and spec also describe per-slot relocation coverage, retained link-time records, Mach-O object relocations, undecoded bind streams, the dyld_info_rebase resolution and unreadable names. * fix(native): keep IFUNC and partly relocated ELF initializer slots unresolved An absolute relocation against an STT_GNU_IFUNC symbol no longer reports the resolver address as the target. Section relocation records now use their real write width, so a record that writes only part of a slot, starts inside it or repeats it leaves the slot unresolved instead of reading a raw zero or dropping a .ctors slot as a sentinel. On 32-bit ARM the Thumb bit is cleared when locating a target's section and file offset, while value_va keeps the stored callable value. * fix(native): locate Thumb Mach-O initializer targets and reject arm64_32 with a 64-bit header On CPU_TYPE_ARM the Thumb bit is cleared when locating and naming a target, since nlist values do not carry it. An arm64_32 image that declares a 64-bit header is rejected as malformed rather than read with 8-byte slots. The guide and spec describe IFUNC relocations, partly relocated section slots, Thumb targets and this rejection. * fix(native): index initializer address lookups and keep ambiguous mappings unknown ELF and Mach-O initializer lookups now build the shared file mapping index once per image, so each slot and target lookup is logarithmic in the number of load segments rather than a scan of every mapping. An address that load segments map ambiguously no longer falls back to a section header offset. Its file offset is reported as unknown and the report is incomplete; only genuinely unmapped spans use the section fallback. * fix(native): report Mach-O bind names over the name budget A bound import name longer than the 1024-byte name budget was dropped without a trace, although it is the only identity of an unresolved initializer target. It now counts toward the over-long name limitation and makes the report incomplete. * test(native): count mapping lookups instead of timing the load index regression The load-mapping regression asserted a wall-clock bound, which is sensitive to machine load. It now spies on the shared mapping module and requires the same number of mapping scans and index builds for 8 and 64 slots, so a per-slot scan of every load segment fails deterministically on a small fixture. * fix(native): yield while decoding legacy rebase runs * fix(native): preserve initializer mapping and coverage * fix(native): index legacy fixup spans * fix(native): preserve relocation uncertainty and bound bind lookup work * fix(native): validate ELF slot mappings and yield section relocation scans --------- Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> |
||
|
|
deae5fbe6d |
docs: correct workflow claims and clarify historical specifications (#9655)
* docs: correct lifecycle and analysis workflow claims * docs: distinguish historical specifications from current guides * docs: align translated setup and MCP recovery guidance |
||
|
|
22f28644fe |
feat(artifacts): inventory and extract Deno compile executables (#8527)
* feat(artifacts): inventory and extract Deno compile executables Adds Deno standalone artifact support for Mach-O, ELF, and PE carriers, exposing virtual files, entry points, recorded options, and file digests without running the executable. Extraction uses the existing safe output tree, preserves symlink targets as metadata, and assigns indexed paths to unsafe or oversized names. Environment-file values and certificate bytes remain in local Evidence; npm snapshots are reported by length without decoding. The documentation describes supported layouts, parsing limits, and refusal behavior. * fix(artifacts): resolve nested Intel Deno carriers to the enclosing app The backward trailer search stopped at the first confirmed sentinel, so an Intel app storing another Intel Deno executable as a virtual file reported the inner app. Search to the slice start, drop sentinels inside a confirmed payload, and fail closed on side-by-side trailers that differ. Correct the docs on retained environment values and generated regions. * fix(artifacts): keep Deno coverage, remote paths and PE resources truthful Report unknown coverage when the virtual filesystem cannot be listed, keep resolved specifiers when another remote ID is missing, and percent-encode characters in remote paths that a Windows destination would refuse. Reject a directory at the PE resource language level, and correct the guide's description of colliding generated regions. * fix(artifacts): normalize Deno remote escapes so hex case cannot collide Uppercase every percent escape in a generated remote path, so specifiers that differ only in escape case reach the path registry as one name and the second gets an indexed path instead of colliding on a case-insensitive disk. * fix(artifacts): fail closed on truncated enclosing Deno trailers and encode reserved remote path characters The Intel trailer scan rejected an overlong sentinel before reading its marker, so a truncated enclosing app vanished and the nested app was reported. Read the marker first and fail closed when a confirmed overlong trailer encloses another trailer. encodeURIComponent leaves `*` alone and the sanitizer covered only part of the Windows reserved set. remoteDestination now encodes the whole set once as uppercase percent hex; source_path keeps the original. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KuWHGvzJkrhCqjtEHUwqyH * fix(artifacts): defer truncated Intel Deno trailer failure until enclosing trailers resolve A damaged Intel asset stored before a valid one inside a valid app made the backward trailer search fail before it reached the outer trailer. Hold that failure until the search ends and drop it when a confirmed enclosing trailer holds the sentinel as data. * fix(pe): fail closed when a resource type branch is unreadable beside a found name namedResourceTargets skipped a type branch whose names directory, or a name entry whose string, could not be read. A duplicate RT_RCDATA entry pointing out of bounds therefore vanished once another branch matched, and locatePeResourcePayloads returned only the readable ranges while parsePeResources rejected the same tree. The walk now records unresolved branches. hasPeResourceName still reports false for a tree that never reaches the name, but once locatePeResourcePayloads finds the name it raises a format failure if any branch was left unresolved. * fix(artifacts): skip Intel Deno sentinels that a native segment maps A non-Deno x86_64 Mach-O that stores an Intel Deno executable in __DATA had the asset's trailer promoted to the root application, because the backward sentinel search never checked who owned the bytes it scanned. locateMachOSlice now records the file ranges of every segment other than __SUI and __LINKEDIT (libsui extends __LINKEDIT over the trailer), and the Intel search skips any sentinel inside one of them. A slice whose load commands do not frame stays with native inventory, since ownership cannot be shown there. * fix(artifacts): reject a universal Deno image with an unreadable sibling slice The universal Mach-O locator skipped any slice whose load commands could not be read or framed, and any slice with a FAT range issue. When another slice confirmed Deno, that slice was reported as the whole image, so a sibling declaring a different Deno application went unexamined. locateMachOSlice now reports why part of a slice was not examined (unreadable or unframed load commands, a truncated slice, or the Intel sentinel allowance). locateMachO collects those reasons for every declared and hidden slice and fails closed once any slice confirms a Deno section. With none confirmed, the image stays with native inventory as before. * fix(scripts): supervise the Deno verifier version check Run `deno --version` through the verifier command owner with a deadline instead of raw execFile, and close the owner when the version is refused. * fix(artifacts): keep unconfirmed Deno carriers native and fail truncated Intel trailers An ELF SUI note whose descriptor is too short for the full d3n0l4nd name now stays unconfirmed instead of failing closed; failures after the name matches still fail closed. Every marker-confirmed Intel trailer whose payload runs past the slice is now kept until the backward search ends and fails unless an enclosing payload contains it, so an Intel Deno app missing its last byte reports a Deno failure instead of native inventory. The Deno MCP boundary test now calls open_binary and inspect_artifact through artifactMcpCall, as docs/testing.md requires. * test(deno): drop source-text checks from verifier pin test Keep the wrong-version subprocess check, which covers the pinned release through behavior, and stop asserting on the verifier script's source spelling. * test(deno): close readers in finally in symlink and cancellation tests A failed assertion or read error in either test skipped reader.close(), leaving the file open while temp-directory cleanup ran. Both tests now close the reader in finally, as CONTRIBUTING.md requires. The closed-reader assertion in the symlink test stays after the finally. * docs(specs): add deno-standalone spec, plan and tasks Add docs/specs/artifacts/deno-standalone/ with spec.md, plan.md and tasks.md for the Deno compile executable reader, as AGENTS.md requires for a feature, and list them in the specifications index. * docs: list the Deno compile guide in the documentation sidebar * fix(deno): confirm the d3n0l4nd section before claiming Mach-O damage A __SUI segment alone no longer makes later load-command damage Deno's. A Mach-O whose __SUI segment holds only a differently named section now stays absent and keeps native inventory, while damage seen before or beside a confirmed d3n0l4nd section still fails closed. * fix(deno): keep a slice with an unparsed segment command unread A Mach-O segment command that frames but cannot be parsed may be the __SUI segment, so the slice is no longer treated as fully examined. A universal image whose other slice confirms Deno now fails closed instead of letting that sibling supply the whole inventory, and with no confirmed sibling the image still keeps native inventory. * fix(deno): confirm an ELF SUI note before rejecting its length A SUI note whose descsz runs past its note table was recorded as plain damage before its descriptor name was read, so a malformed Deno carrier fell back to native inventory. The owner and the d3n0l4nd name prefix are now read within the table apart from the claimed extent, and a confirmed note with an oversized extent fails closed. * fix(deno): confirm a truncated __SUI section record by its name A section record cut short after its 16-byte name was skipped, so a damaged Deno carrier fell back to native inventory. The name is now read apart from the rest of the record, and a truncated record that names d3n0l4nd fails closed. The range checks for a confirmed record move into their own helper. * fix(deno): reject nonzero bytes after the last ELF note When fewer than 12 bytes remained in a note table after its last note, the walk stopped without looking at them, so a Deno note was selected with complete coverage beside unaccounted data. The remainder is now read: zero padding is accepted, and nonzero bytes are recorded as damage, which fails closed once a SUI note is confirmed and otherwise leaves the ELF to native inventory, matching the native note parser. * fix(deno): validate FAT slice identity before choosing the search The locator took a universal slice's CPU type from its FAT row, so a row that called an x86_64 slice arm64 skipped that slice's Intel trailer and let the arm64 payload stand for the whole image. Each slice's header is now checked against its row with validateFatSliceIdentity. A mismatch leaves the slice unread, so a universal image whose other slice confirms Deno fails closed. The Intel fixture header now states CPU_SUBTYPE_X86_64_ALL so its FAT rows can match it exactly. * fix(deno): check the Intel trailer marker before judging its length A trailer length word of 2^53 or more was dropped before its d3n0l4nd marker was read, so an enclosing app with that length was skipped and a nested app's range stood for the whole image. The marker is now read first, and a marker-confirmed trailer whose length runs past the slice, safe or not, joins the deferred truncated candidates and fails closed unless an enclosing trailer holds it as data. * fix(deno): count short ELF note tables against the note allowance A note table shorter than one note header made a read of its trailing bytes but counted no note, so many distinct tiny tables could force one sequential read each past the 256-note allowance. Every nonempty table now counts at least one entry, both in the up-front estimate and while scanning, so an image past the allowance records the limit instead of reading every table. The trailing-byte check moves into its own helper. * fix(deno): fail closed on ELF extended section numbering beside a SUI note A zero e_shnum with a nonzero e_shoff moves the section count into section zero, so the section table was skipped and its SHT_NOTE tables were never compared. Record it as damage, as PN_XNUM already is, so a confirmed SUI note fails closed instead of reporting full coverage. * fix(deno): keep undersized Intel trailers until enclosing ownership is known A trailer length word below 8 was dropped before its d3n0l4nd marker was read, so an enclosing app with a length of 0 to 7 was skipped and a nested app's trailer was selected as the root. The marker is now read first, and a marker-confirmed trailer too short to hold it is kept as malformed and fails closed unless an enclosing trailer holds it as data. * fix(pe): treat non-directory RT_RCDATA branches as unresolved A duplicate typeId root entry whose target is a data entry was skipped without marking the walk unresolved, so locatePeResourcePayloads returned the readable named resource as complete. Route non-directory type branches through the same unresolved path as unreadable names directories so the Deno reader fails closed. * fix(deno): fail closed on a zero-fill d3n0l4nd Mach-O section denoSectionRange admitted the declared offset and size of a confirmed __SUI,d3n0l4nd record without checking its section type, so a S_ZEROFILL, S_GB_ZEROFILL or S_THREAD_LOCAL_ZEROFILL section could be read as a file payload while MachoImage reports it as not file backed. Reject zero-fill types with the shared isMachoZeroFillSection predicate before assigning a physical range. * fix(deno): bound the d3n0l4nd Mach-O section by its segment file extent denoSectionRange checked a confirmed __SUI,d3n0l4nd record only against the slice and file bounds, so a section reaching past its segment's fileoff/filesize was still read as a complete payload while MachoImage reports the same section as not file backed. Reject a section outside its enclosing segment's file extent before admitting the physical range. * style(deno): apply oxfmt to the DenoStandaloneLocation embedding union * fix(artifacts): preserve Deno carrier ownership * fix(artifacts): admit Deno parent segments * fix(deno): preserve native segment ownership * test(deno): cover mismatched Mach-O segment widths --------- Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> |
||
|
|
43f06eb1e8 |
feat(native): recover ELF function ranges from unwind tables (#9585)
* feat(native): recover ELF function ranges from unwind tables inspect_elf_unwind_ranges and inspect-elf-unwind-ranges read .eh_frame and .eh_frame_hdr from one local ELF32 or ELF64 image and list the function ranges its FDEs name, with CIE facts, LSDA and personality, the containing section and an exact symbol where one starts at the address. Nothing is executed and no disassembler is needed. Pointer encodings follow the DW_EH_PE rules with raw zero as null, discarded FDEs are counted and skipped, the .eh_frame_hdr search table is compared with the decoded FDEs, and record, row and symbol budgets are bounded. verify:elf:unwind-ranges compares the reported starts with llvm-dwarfdump or readelf on a compiled C++ program. * fix(elf): keep unresolved unwind facts out of reported ranges Skip FDEs whose initial location is indirect and do not locate .eh_frame through an indirect eh_frame_ptr, since pointer slots are not functions. Stop an unbounded header-located scan at a CIE with an unrecognized augmentation, report ignored duplicate PT_GNU_EH_FRAME headers as incomplete coverage, and accept a null personality stored under an indirect encoding. Keep only symbols at decoded FDE starts, cache name observations per string-table offset, and decode names only for the returned page under a fixed 16 MiB text allowance, so repeated or long names no longer grow memory with the symbol count. * fix(scripts): run the ELF unwind verifier under owned process trees Launch probes, compiler drivers, the stripper, the frame dump and the inspection through createVerifierCommands, as verify-binary-hardening does, so a timeout or interrupt stops the whole tree. The temporary directory is removed only after the owned commands have closed. * docs(elf): move ELF unwind ranges guide under docs/guides/native The documentation guide assigns analyst workflows to docs/guides/<domain>/. Move the guide there, place its navigation and directory entries in the Native binaries group, and update links from the docs index, CLI guide, spec and authored skill. The public /elf-unwind-ranges route is unchanged. * fix(elf): give unwind text limits their own recovery and skip indirect tables Throw a dedicated failure when a page's symbol names exceed the 16 MiB text allowance, and map it to a resource error that tells the caller to request a smaller limit rather than raise max_ranges. Read a CIE augmentation with one bounded NUL search and keep it as a byte view, decoded only for returned CIEs, so a long augmentation is never built up character by character. Leave an .eh_frame_hdr search table with an indirect encoding unread: the header is incomplete, the comparison is unavailable, and the table no longer bounds a header-located .eh_frame scan. * fix(elf): resolve header count and table forms and name IFUNC resolvers Leave a non-zero .eh_frame_hdr FDE count under an indirect encoding unresolved, since it is the address of a slot that is not followed, and mark the header incomplete without reading the table. Treat a DW_EH_PE_omit table encoding as an omitted search table before testing the indirect bit, so a header that declares a count without a table stays present with complete coverage, and accept that form in output validation. Match STT_GNU_IFUNC symbols at exact FDE starts after function symbols, with a limitation that the name is the resolver, not the implementation it selects at run time. * fix(elf): require allocated unwind pointer bases * fix(elf): map unwind header relative base * fix(elf): validate unwind load mappings * test(elf): cover mapped nonallocated frame agreement --------- Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> |
||
|
|
f21fda0fc0 |
feat(elf): report a Linux kernel image's version banner and embedded build config (#9573)
* feat(elf): report a Linux kernel image's version banner and embedded build config inspect_kernel_build_config and inspect-kernel-build-config read one local vmlinux, raw arm64 Image, gzip bzImage or zImage, or configs.ko and report its Linux version banner and the IKCONFIG .config embedded between IKCFG_ST and IKCFG_ED, without executing it. A config is present only when a gzip member ends exactly at IKCFG_ED, passes its CRC-32 and ISIZE checks and parses as .config text; framing that fails is reported malformed, never absent. bzImage gzip payloads are inflated within a budget and other codecs are named as unsupported, using codec detection now shared with the kernel module parser. The config search, inflate sizes and option counts are bounded, scans honor cancellation, and target-derived text is marked untrusted. * fix(elf): reject a gzip member whose header checksum fails When FHCRC is set, compare the low 16 bits of the header CRC-32 before inflating, so a damaged header no longer yields a present config or an inflated bzImage payload. * fix(elf): detect the bzImage codec inside the declared payload Codec detection now reads the same payload_offset/payload_length slice that is inflated, so bytes past a short payload cannot name its codec. * fix(elf): report a framed config that does not decode as malformed A damaged or cut-off deflate stream between IKCFG_ST and IKCFG_ED was skipped and could end as an absent config with complete coverage. It is now malformed with config_gzip_invalid, and a later valid config still wins. * fix(elf): scan config lines in place and accept long string values Config text is read one line at a time instead of split into an array, and a quoted value is validated before it is decoded once. The 4096-character string cap is removed: Kconfig has no such limit and max_config_bytes already bounds every line, so a long CONFIG_EXTRA_FIRMWARE list is no longer reported as malformed. * fix(elf): let a live cancellation reach the kernel config parser The parser ran synchronously, so an abort raised during parsing could not change the signal before it returned. Inflation now runs on the zlib thread pool and each scan yields to the event loop once per MiB, so the existing cancellation checks observe a real abort. * refactor(elf): carry the refused kernel config budget as a typed fact Budget failures are now KernelBuildConfigBudgetFailure with a knob field, and the provider builds its recovery advice from that field instead of searching the diagnostic message for an option name. * docs(elf): move the kernel build config guide under docs/guides/native The documentation guide assigns analyst workflows to docs/guides/<domain>/. Move the guide there, place its navigation and directory entries in the Native binaries group, and update links from the docs index, CLI guide, spec and authored skill. The public /kernel-build-config route is unchanged. * fix(elf): yield while checking one long config line A config made of one long quoted value never reached the per-line yield, so the control-byte check, value validation and SHA-256 ran in one synchronous block. Each now works one MiB window per event-loop turn, and the line patterns match only a bounded name prefix instead of the whole value. * fix(elf): return paged config entries that do not pin the decoded text Entry names and values were V8 slices of the whole decoded config, so a one-entry page kept the full text alive. Entries in the returned page are now standalone copies, so retained memory follows the page size. * fix(elf): yield while kernel marker searches find nothing IKCFG_ST, IKCFG_ED and banner searches used one Buffer.indexOf over the rest of the image, so a large image with no marker never yielded. They now search overlapping one MiB windows and yield after each window without a match. * fix(elf): preserve long kernel config names * fix(elf): frame kernel configs by gzip member boundaries --------- Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> |
||
|
|
df2d018b30 |
feat(desktop): read gzip documents as the document inside (#9111)
* fix(desktop): release a capture when its start is cancelled after launch Cancelling start_build_capture during the opened app's screenshot left the capture running, so the next start was refused. The capture is now kept for the owner's cleanup, and the next start stops it first. * fix(desktop): keep a published witness error and tag an app data refusal A second failure to close a published witness returns the original error, so its record and cleanup lease stay bound. A reset the app itself refuses is an AppDataRefusal; only a reply that is not that refusal stays unsettled. A missing child of a cut view is undecided with the same description in both evaluators, and the shared cases cover it. * fix(desktop): align a cut view's missing text with the Python check A missing child of a truncated view is undecided for the same sentence in both evaluators, including the pointer the view does not contain. * fix(desktop): keep one published witness cleanup across retries A published record and its bound cleanup error stay together. A later close failure returns that error, and the unused path that built a fresh adapter error is gone. * fix(desktop): keep a bundle task read inside the witness result A cancelled, refused, or failed read of the bundle's task files returns the witness's Result, including a cleanup lease when a handle would not close. * test(desktop): pass the settle timing when reading a witness bundle The witness takes the settle timing before the bundle path, so the bundle-read tests keep the path in its own argument. * fix(desktop): bound a guest file answer and split a long controller argument A data/get whose base64 answer would exceed a quarter of the V8 heap is refused before it is read. Controller JSON that exceeds Linux's single-argument limit travels as several arguments the controller joins. * fix(desktop): keep an underreported guest file from raising its read A data/get answer is admitted only when its base64 body fits in the heap quarter after the copies held during parse. Decoded bytes larger than the computer reported are dropped. * fix(desktop): grade shipped seeds and keep selected settings and sqlite logs Seed checks follow the files the bundle ships, so an omitted lock is absent. An incomplete checkpoint is not reported as no change. A selected link keeps its spelling, and a database's wal and journal stay supporting state. Closing the fake computer stops a detached capture. * fix(desktop): keep added-record checks off ids, dates, and joined timestamps A position-named record's fields keep their paths, so an identifier, a stamped date, and text past the limit are not suggested checks. A whole-text check does not climb into an ancestor whose text joins a timestamp. * fix(desktop): bound home fetches and keep unsettled edits readable Split home-folder reads by the guest answer budget, keep a capacity error from the capture output, and drop the superseded task-argument refusal. Grade kept text per line, leave unretained dconf unread, and reserve by-position notes for XML children. Map a linked database's sidecars through the selected spelling and stop a detached capture only when its start identity still owns the pid. * fix(desktop): describe unretained dconf as unread The key comparison treats a missing copy as unknown. The comment still said that copy counted as an empty key list. * test(desktop): keep a capture capacity error through endedCapture An output past the guest answer ceiling stays the resource constraint, with its heap recovery and non-retryable status, instead of a generic capture-exit message. * fix(desktop): keep nested save times and formatting runs out of checks A field check drops save-time leaves before it joins the field, so a nested timestamp is not part of the suggested text. A text check beside a save time uses the paragraph when the diff names a formatting run. * test(desktop): read paragraph pointers from checks that have them * test(desktop): expect a large task to export intact The 96 KiB refusal is gone. A prompt past that size reaches the computer and comes back unchanged, instead of failing before export. * fix(desktop): keep real edits that save-side heuristics were dropping Repeated unnamed fields stay content checks. A formula that still has text is not renumbered with its ExprID. One gained style attribute is the edit; a repeated fill-in stays upkeep. Phone numbers and plain clock times stay text, and a decimal is the element's whole text. An older verifier matches on the task it states, not its evaluator source. * fix(desktop): cover repeated records and keep timestamps out of checks An added record whose words are already in the seed still gets the list's text when that text fits. Readiness is a start reason, so a final check names seed locks without matching the message. Field text split by a timestamp stays separate, and a timestamp line is not offered as a guard. * fix(desktop): compare a cell's joined decimal within tolerance The whole-element check keeps numeric tolerance, so 437.80 and a long float still match 437.8, including when a run splits the digits. A different number or other text does not. Both evaluators read an element's text for that comparison. * fix(desktop): grade a number from a complete XML element only A tolerance check joins an element's text only in an XML file or an XML archive entry, and leaves that check undecided when the view is cut, so a dropped descendant cannot turn the kept runs into a passing number. A JSON object with the same shape stays the value itself. Equivalent decimals and a split run on a whole cell still match. * fix(desktop): accept an older grader only when its index helper agrees The witness still matches a bundle whose evaluator is this REA's, or the older index expression alone when no path segment is a leading-zero number. A truncated verifier, a changed grader, or that older helper beside a segment such as 01 no longer counts as the same task. * fix(desktop): require the added record and leave save times out of list checks A record a selector names is checked itself, so its words have to be in that record. When an unnamed record only repeats words the seed already has, a list that holds a save time is checked by the text around that time. A later save of the same records still passes, and a missing or rewritten record fails. * fix(desktop): judge the older index helper by pointer segments only A leading zero in a file name or a URL does not change how the older index helper reads a pointer. The witness still rejects that helper when a pointer segment is a number such as 01. * fix(desktop): do not suggest list text the seed already passes A repeated record is shown by text the seed does not hold. The seed's own text is not a check. A pointer inside a check value is not a pointer segment for the older index helper. * fix(desktop): keep a linked settings file in the folder the link points at A selected ~/.config alias no longer moves MuseScore settings to that alias. The seed keeps settings/MuseScore or Documents, which is the path the export opens the note from. * fix(desktop): split home fetches by answer size and keep a size refusal A batch of tiny files stops before each path's envelope exceeds the host answer budget. A capture output past that ceiling stays a resource error instead of becoming a generic exit. * fix(desktop): seed a selected link under the path the app uses The selected spelling wins, so ~/.config/MuseScore is not rewritten to the folder it points at and the note stays the one launched document. A database wal and journal follow that database. A launch argument is respelled the same way. Teardown signals a detached PID only when its start identity still matches. * fix(desktop): keep a witness's actions and an incomplete checkpoint A failed witness save retries the action log it first recorded. A deletion left unconfirmed between the seed and the end is not reported as no change. Windows packs npm through a shell, which can start npm.cmd. * fix(desktop): read verifier pointers from the parsed checks A brace inside a check value is not an object boundary. A leading-zero pointer after that value still rejects the older index helper. * fix(desktop): prefer the most specific home spelling and retarget launch files A selected parent directory no longer hides a settings folder walked through a link. A launch filename under that folder is replaced with the seeded file's absolute path. * fix(desktop): pack the build runtime through npm's JavaScript entry npm pack and npm ci no longer spawn npm.cmd through a shell, so a temporary directory whose path contains spaces stays one argument. * fix(desktop): spell launch settings and keep a database log exact A database log matches only that file, so a neighboring folder is not moved. A launch option and the working directory use the same home spelling as the seed. * fix(desktop): move a state database's logs with the database The write-ahead log and journal follow the spelling the database received, including a walked state link. A neighboring folder stays put. A separate --config argument uses that spelling too. * fix(desktop): keep a selected file ahead of a database-log guess A file selected as itself keeps that spelling even when its name ends in -journal. Relative launch arguments are resolved in the captured working directory before that directory moves. * fix(desktop): keep outside-home database logs and option values A selected database outside the home keeps its write-ahead log. Launch options are rewritten only when they name a captured file or settings path. * fix(desktop): follow a database mapping and own limitation text A selected database keeps its log when a parent folder moves or the file sits outside the home. Trash and seed-lock tests compare the owning notice with the paths, and launch options that are not captured paths stay as written. * fix(desktop): retarget a settings folder that holds captured files A nested profile directory is a captured path when a seeded file is inside it. An option value that only resolves under the home stays as written. * fix(desktop): keep a program word and a directory's neighbor The program after env stays the program even when a captured file sits in a folder of that name. A selected directory is not a database, so a neighboring file keeps the parent folder's spelling. * fix(desktop): record whether a selected path is a directory Capture stores the walked path's kind. A neighboring file of a selected directory keeps the parent folder's spelling even when that directory never changes and its children are not content roots. * fix(desktop): mark containing paths without a pairwise scan A recorded path marks its known ancestors as directories in one walk up the path, instead of comparing every recorded path with every other. * fix(desktop): keep a selected folder that is named like a database log A folder the caller selected stays a selected root when its name ends in -journal or -wal. A generated log beside a database file still does not. * fix(desktop): refuse a build command that exceeds the argument vector Splitting one argument still leaves the whole command under Linux's E2BIG limit. A request past that budget is refused before the process starts. * fix(desktop): remap a captured path in an env assignment The program word stays the program. A NAME=value assignment keeps its name and follows a captured path value when that path's spelling moves. * fix(desktop): keep oversized text out of draft guards A value or line longer than the draft's text bound is not copied into a guard, so one large frame cannot fill the task by itself. * fix(desktop): keep an empty env value empty An empty assignment is not a path. Resolving it named the working directory and rewrote the value when that directory's spelling moved. * fix(desktop): check build runtime export capability * fix(desktop): provide complete runtime repack command * fix(desktop): retain runtime probe failures * test(desktop): identify capture independently of schema preflight * fix(desktop): preserve document URLs and value formats * fix(desktop): bound added checks and omit noisy text guards * fix(desktop): preserve launch URLs and JSON draft values * fix(desktop): recognize captured file URL documents * fix(desktop): render captured file URLs for runtime home * fix(desktop): distinguish phone numbers from save metadata * fix(desktop): preserve launch URLs and user text * fix(desktop): preserve local file URL authority * fix(desktop): preserve local file URL authority * fix(desktop): render captured file URLs at launch * fix(desktop): classify numeric timestamps using field context * fix(desktop): classify numeric timestamps using field context * fix(desktop): retain context for generated draft values * fix(desktop): retain context for generated draft values * test(desktop): cover generated IDs in text guards * test(desktop): cover generated IDs in text guards * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): isolate launcher URL encoding * fix(desktop): retain clean text in noisy record fields * style(desktop): format the noisy-record draft files with the pinned oxfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): move launch execution to boundary suite * fix(desktop): redact build schema failure output * refactor(desktop): normalize schema failure once * fix(desktop): omit unsafe schema parser snippets * fix(desktop): preserve draft change and selected path evidence * test(desktop): group retained dconf note regressions * fix(desktop): respect archive entry format in draft checks * test(desktop): separate unowned-file draft note cases * docs(desktop): clarify task checks before scratch export * fix(desktop): respell selected paths in file URLs * test(desktop): group captured document spelling cases * fix(desktop): bound draft preview serialization * fix(desktop): restore selected state aliases * fix(desktop): respect entry format in draft noise * test(desktop): match exported alias evidence at its JSON boundary * style: fix desktop launch test formatting * style: format native command path schema * fix(desktop): map selected external launch paths * style(desktop): format seed document regressions * test(desktop): group launch URL regressions * fix(desktop): omit redundant nested state aliases * fix(desktop): compare added free text as a whole * fix(desktop): check recompressed seeds as shipped * fix(desktop): map captured launch paths once * refactor: remove unused whole-text guard state * refactor: stop passing unused text children * test: align free-text checks with whole-note policy * fix: validate recompressed desktop archive seeds * style(desktop): format archive seed regression * fix(desktop): redact runtime schema errors * fix(desktop): normalize captured file URLs * fix(desktop): report seeded files by capture path * fix(desktop): retain startup readiness failure stage * fix(desktop): retain JSON date checks * fix(desktop): preserve archive formatting checks * fix(desktop): preserve explicitly selected journal files * fix(desktop): report build command transport limits * style(desktop): format capture review fixes --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
645735fc0f |
feat(windows): inspect Shell Link (.lnk) shortcut files (#7859)
* feat(windows): inspect Shell Link (.lnk) shortcut files Add inspect_windows_shortcut / inspect-windows-shortcut to read one local Shell Link without resolving or executing the target. The report keeps header flags and FILETIMEs, IDList items, LinkInfo volume and network names, StringData, ExtraData including Tracker droid facts labelled derived, and derived observations such as argument length and a minimized ShowCommand. * fix(windows): tighten Shell Link string reads and coverage - Decode counted StringData over its full CountCharacters payload. - Locate LinkInfo string terminators before charging max_string_bytes and before decoding; an unterminated string is a coverage issue. - Mark an IDList without a TerminalID and an out-of-range LinkInfoHeaderSize as partial coverage. - Report arguments_present and argument_length as null when HasArguments is set but the field could not be read. - Derive target_extension from the joined base path and suffix. - Keep ISO dates for FILETIME and UUIDv1 timestamps before 1970. - Retain the completed file snapshot on parse failures. - Reject an empty CLI path before normalization. - Select the shortcut contract from its family in focused tests. - Fixture StringData no longer writes a NUL into the counted payload. * style: format docs index and Shell Link boundary type Apply oxfmt to the two files format:check reports so Static checks passes. * fix(windows): reject network share paths for Shell Link reads inspect_windows_shortcut is advertised as offline, but the Windows path schema admits UNC paths, and lstat on one can contact an SMB server and offer the caller's credentials. Reject UNC, extended UNC, and other host-prefixed device paths in the provider before any filesystem call. Extended drive paths such as \\?\C:\x stay allowed. A mapped network drive cannot be told from a local drive by its path, and the docs say so. * fix(windows): decode Unicode Shell Link file-entry names File-entry items with bit 0x04 of the type byte, such as 0x36, store a UTF-16LE name, but the parser always read it as Latin-1. The read stopped at the first zero byte, so report.exe became r and an IDList-only shortcut reported the wrong target_extension. Read those names as UTF-16LE. * fix(windows): read volume labels by exact Shell Link discriminator VolumeLabelOffset 0x14 selects VolumeLabelOffsetUnicode and is not itself a label offset, and that Unicode field exists for no other value. The parser treated any offset of 0x14 or more as having both, so a Unicode-only label such as "OS" also produced a false ANSI label "O", and an ANSI label stored past 0x14 had its own bytes read as a Unicode offset. Branch on the exact value in parseVolume, the one place that interprets it, and report a VolumeID too short to hold the selected field. The fixture wrote both encodings for a Unicode volume, which hid the false label, so it now writes one. * fix(windows): limit network share rejection to Windows hosts POSIX hosts read repeated leading slashes as one local root, so an accepted selection such as ///tmp/shortcut.lnk is a local file there. Apply the host-prefixed path check only on Windows, and take the platform through the provider constructor so the Windows path forms stay covered on every test host. * fix(windows): compare shortcut icons only against full paths A stored IDList filename or relative path cannot show that an icon at a full path is elsewhere, so the comparison reported a false difference. Report null unless the icon and a recorded target are both full paths, and assert the missing TerminalID issue by code and offset instead of its message. * fix(windows): keep unread ExtraData blocks unknown A walk that stopped before or inside ExtraData still reported the blocks that HasExpString and HasExpIcon expect as absent, though they were never checked for. Report a block as absent only after the TerminalBlock shows the section was read in full. Without one the block stays unknown and coverage stays partial. * fix(native): ignore LNK network provider type unless ValidNetType is set CommonNetworkRelativeLink NetworkProviderType is only meaningful when the ValidNetType flag (0x2) is set. Return null otherwise. * fix(native): accept any ExtraData TerminalSize below 4 as the terminal MS-SHLLINK requires TerminalSize to be less than 4, not exactly 0. Treat 1, 2 and 3 as the terminal block instead of a malformed block. * fix(native): derive shortcut target facts from the stored environment target Include the EnvironmentVariableDataBlock literal target among the target candidates for target_extension and the icon comparison. Variables are not expanded and the target is not opened. * fix(windows-shortcut): keep unexpanded variable paths unresolved in icon comparison A stored environment target such as C:\Users\%USERNAME%\app.exe could be compared as different from C:\Users\Alice\app.exe. Variable-bearing paths are never expanded, so the icon comparison now returns null unless a fixed target matches the icon exactly. * test: drop redundant ok assertion before typed error guard The testing guide asks for the typed error to be thrown before asserting a successful Result value, and says a preceding .ok assertion adds no coverage. * fix(windows): point out-of-range LinkInfo offsets at their field A LinkInfo, VolumeID or CommonNetworkRelativeLink offset that points past its structure was reported at base + offset. With an offset such as 0xffffffff that position exceeds uint32, so the report failed its schema and the service discarded the whole partial result. Report such issues at the offending offset field instead, which keeps every issue offset and coverage.failing_offset inside the file. Cover each LinkInfo offset field in the parser tests and the LocalBasePathOffset case through the stable filesystem service. * fix(windows): require RFC 4122 variant before deriving Tracker UUID facts A version nibble of 1 alone does not identify a version-1 UUID. Also require the clock_seq_hi_and_reserved top bits to be 10, so other GUID layouts keep their raw value and derive no MAC or timestamp. * fix(windows): ignore DeviceNameOffset fields unless ValidDevice is set MS-SHLLINK 2.3.2 says DeviceNameOffset and DeviceNameOffsetUnicode are ignored when the ValidDevice flag is clear. parseNetwork read both regardless, so garbage in those fields became device-name facts or malformed_structure issues. Read the flags once and only read the device name fields when ValidDevice is set. * fix(windows): keep unsupported Tracker headers as raw data Check TrackerDataBlock Length (0x58) and Version (0) before decoding. A block with any other header is retained as raw bytes with a malformed_structure issue, so it no longer yields MAC and timestamp facts under complete coverage. * fix(windows): compare shortcut icon paths by normalized location Collapse "." and ".." segments and repeated separators in the icon comparison as text only, never opening a path. ".." stops at the drive or UNC share root, and \\?\ and \\.\ paths stay verbatim. Join LocalBasePath with CommonPathSuffix as the target and use the bare base only when the suffix is empty, as the network share branch does. Read the selected shortcut with lstat and open only, so a rejected symlink's destination is never resolved. * fix(windows): keep the UNC share in the root after repeated separators normalizePath took the host and the next split part as the UNC root, so \\server\\share\..\app.exe kept an empty share and let .. remove the real share. Drop empty parts before picking the root so paths on different shares stay different. * fix(cli): parse windows shortcut limits as decimals The four inspect-windows-shortcut limit options now go through cliDecimalField like the other inspection commands, so values such as 0x10 are rejected and cliDecimalArguments.test.ts passes. * fix(native): reject linked parents of windows shortcuts A parent directory symlink or junction pointing at a UNC share was followed by the first lstat, since the network check reads only the path text and the symlink rejection covers only the final component. On Windows, lstat each ancestor from the drive root down and reject the path at the first link, before anything follows it. * docs(native): move Windows shortcut guide and add its feature spec Move the Shell Link guide to docs/guides/native/windows-shortcut.md and list it under Native binaries in the site navigation, keeping the /windows-shortcut public route. Update README, translated README, CLI page and authored skill links to the new physical path. Add docs/specs/native/windows-shortcut/ with spec.md, plan.md and tasks.md, as required by docs/development/documentation.md. * fix(native): admit the windows shortcut parent walk On Windows the ancestor link walk ran before the provider's resource admission, so close() could finish while the walk kept calling lstat. Run the walk inside the same admission as the read, and check the caller's signal before each ancestor lstat. * fix(native): walk the effective parents of windows shortcuts The ancestor link walk checked every prefix of the path as written, so C:\alias\..\real\a.lnk was refused when C:\alias is a directory link, although Windows removes alias\.. before opening the file. Walk the ancestors left after removing . and .. components, keeping the caller's spelling, never climbing above an absolute root, and leaving \\?\ paths as written since Windows does not normalize them. * test(native): assert the linked parent as a structured fact The parent link regression matched the phrase "junction, which" in the refusal message, so a wording edit would fail it. Report the linked ancestor as observed.linked_ancestor on the input issue and assert that fact instead of the explanatory text. * test(native): bound the shortcut close gate and release it in finally Race the parent walk lstat acknowledgement against inspection settling with awaitAcknowledgement, then release the gate and join the inspect and close work in finally so a failure reports its cause instead of waiting for the Vitest timeout. * fix(native): walk Windows shortcut parents lazily windowsAncestors built and kept every parent prefix before the first lstat, so a path with thousands of components allocated memory quadratic in its length. It now keeps only the normalized components and yields each parent from a running prefix as the walk reaches it. --------- Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> |
||
|
|
25885b05c0 |
feat(v8): inspect V8 code cache containers and retained byte patterns (#8993)
* feat(v8): inspect V8 code cache containers and their retained byte patterns Bytenode-compiled `.jsc` files — the V8 code cache container that `vm.Script`, `vm.compileFunction` and bytenode 2.x write, and that Node single-executable applications and Electron apps ship — had no format-native reader. `inspect_binary_layout` shows the surrounding ELF/PE and `inspect_artifact` inventories the file, but neither decodes the V8 structures, so an agent could not tell which V8 line produced the file, could not learn the container is metadata rather than source, and had nothing to point at a version-pinned decompiler. Issue #8543. `inspect_v8_code_cache` joins the format-native family with `inspect_python_pyc`, `inspect_erlang_beam` and `inspect_kernel_module`: one explicit local file, bounded parsing, no execution, no installation, no child process. **The container is version-dependent, so the reader reports roles with confidence instead of assuming an ABI.** All eight header words are reported with byte offset, observed value, the role this reader believes the word has, and whether that role is `confirmed`, `inferred`, or `unconfirmed`. Only three facts gate admission: the header size this reader pins, the V8 code cache magic high half `0xc0de` (the low half is `ExternalReferenceTable::kSize` and varies per build, so it is a build fingerprint rather than a constant), and a declared payload length that reaches exactly the end of the file. I derived the field semantics from the producer rather than assuming them, and two findings changed the design: - **The word V8 calls the source hash holds the source length on the measured producers.** A 54-code-unit source stored `54`, and sources with the same code-unit length but different content stored the same value, including a source whose UTF-8 length was 154. The reader reports it as `source_length` and the docs say that this name is what the measurement supports, not a claim about what another build stores there. - **`vm.compileFunction` sets a high bit in that word.** The reader masks it out and reports the producer family as `script` or `compile_function`, so the source length stays correct for both producers. Embedded strings are reported as **byte-pattern observations with absolute byte ranges**, labelled as such in the field name and in the limitations. A reported sequence is not proof V8 retained it as a string, and a missing literal is not proof it is absent. **Fail-closed boundaries, all covered by tests:** an unknown magic is a typed `unsupported_target` failure because the file is not a V8 code cache; a short header or a payload-length disagreement is a typed `invalid_request` failure. Neither yields a partial parse and neither records Evidence. Non-goals are explicit in the tool description and the docs: the payload is serialized V8 heap data, not source; recovering logic needs a version-pinned View8-style decompiler that this tool neither provides nor depends on. Fixtures are generated from the running V8 instead of committing a version-pinned binary, so the tests exercise the real producer and stay valid across Node upgrades. - Semantic owner and earliest changed stage: format-native V8 code cache container decoding. - CLI and MCP/tool-catalog contract: one new `artifact-provider` tool and one new `inspect-v8-code-cache` CLI command, registered in `TOOL_CONTRACTS`, the `artifact` language family, `TOOL_EFFECTS`, the capability declarations and services, and the capability inventory. `docs:check` passes, so the generated catalog agrees. - Provider, bridge, target-format, or platform compatibility: no provider runs and no external tool is required, so the tool is available on every supported Node host. - Evidence, artifact, provenance, or reconstruction contract: complete Evidence with the payload byte range as its location; no artifact format, reader, or reconstruction change. - Generated metadata, package, or installation impact: catalog and document facts regenerated by the existing checks; no new dependency. Expected effects: - [x] Target content is returned as bounded structured facts. - `src/v8/V8CodeCacheParser.test.ts` (13 cases): real-producer header facts, per-field role and confidence, source length for both producers, an observation's absolute offset verified against the file bytes, the limitation text, foreign magic, payload-length mismatch, short header, missing payload bytes, a different build constant still admitted, and the observation budget. - `tests/boundary/mcp/v8CodeCacheMcp.test.ts` (4 cases): advertisement and annotations, header facts over MCP, relative-path rejection, unsupported magic, malformed container. - `tests/acceptance/v8CodeCacheCli.test.ts` (4 cases): the public CLI, relative-path resolution, byte-range observations, and the typed failure. - `npx vitest run src/contracts src/v8 src/application/v8CodeCache src/domain/v8` — 242 passed - `npx vitest run tests/boundary/mcp/v8CodeCacheMcp.test.ts tests/acceptance/v8CodeCacheCli.test.ts tests/boundary/filesystem/productCatalog.test.ts tests/acceptance/tools/localToolContracts.test.ts` — 20 passed, 4 skipped - `npx tsc --noEmit -p .` — exit 0 - `npm run build` — exit 0 - `npm run lint` — 0 errors - `npm run knip` — exit 0 - `npm run docs:check` — exit 0 - `npx oxfmt --check src tests docs` — exit 0 Gap: the header table is measured on node v24.22.1 / V8 13.6.233.17-node.58 only. No other V8 build is available here, so a different build's field order is untested; that is exactly why only three facts gate admission and the remaining roles carry a confidence level rather than being asserted. Additive. No existing tool, schema, or behaviour changes. The reader never executes the selected file, never launches a process, and never accesses the network; its audited effects are `mutatesSession: true` only, matching the other static format readers. Human owner: @XiaoBinGan - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue: #8543. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. * chore: retrigger title and readiness checks after the title was corrected * fix(v8): bound the payload scan and use the repository path conventions Review feedback from @greptile-apps on four points. **Bound the synchronous payload scan.** The scan is one synchronous pass over the payload, so the 512 MiB ceiling allowed a single request to hold the process for several seconds. The ceiling is now 64 MiB, matching the pinned CPython pyc reader, and the default is 32 MiB. The scan stays synchronous, like the BEAM and ELF note readers in this family, but the budget that bounds it is no longer large enough to matter. The new `max_file_bytes` ceiling and default are documented. **Use the absolute-path schema.** `path` now uses `absoluteLocalPathStringSchema` instead of `localPathStringSchema`, matching `inspect_erlang_beam`. A relative name previously passed validation and was resolved against the server's working directory, so `module.jsc` could select a different file than the caller meant. The rejection is now at the schema boundary. **State the extraction step.** The handoff in `docs/v8-code-cache.md` now says a cache embedded in a single-executable application or an Electron app must be extracted first, because this reader requires the magic at byte zero and returns `unsupported_target` for the surrounding ELF/PE executable. **Load only the owning contract group in tests.** Both tests now import `V8_CODE_CACHE_TOOL_CONTRACTS` directly instead of resolving the tool through the full catalog, so a focused test no longer constructs every other tool's schema. 21 cases pass across the parser, MCP boundary and CLI acceptance files; `tsc` 0; `build` 0; `knip` 0; `docs:check` 0; `oxfmt --check` 0. * fix(v8): select the tool contract by name in the focused tests Reverts the catalog-position selection I added for a review suggestion. This repository has a lint rule (`rea(no-positional-tool-contract)`) that forbids selecting a tool contract by catalog order, and `toolContract("inspect_v8_code_cache")` is how every neighbouring focused test selects one. The positional form I tried introduced two lint errors, so the named form stays. The review concern was that resolving through the full catalog constructs every other tool's schema. That cost is real but it is the repository's chosen trade: catalog ordering must never select an operation or schema, and `toolContract` is the named accessor that enforces it. * test(v8): cover the new tool in the absolute-path boundary test Main added `tests/boundary/mcp/absoluteLocalPathTools.test.ts` after this branch was opened. It enumerates every tool whose MCP `tools/list` schema must reject a relative path, and `inspect_v8_code_cache` uses `absoluteLocalPathStringSchema`, so the tool belongs in that list. Adding it keeps the enumerated field set complete instead of leaving one absolute-path tool untested. `tests/boundary/mcp` + v8 + contracts: 256 passing. `tsc` 0; `build` 0; `knip` 0; `docs:check` 0; `npm run lint` 0 errors. * perf(v8): read the payload by index instead of allocating per byte `for (const [index, byte] of payload.entries())` allocates a two-element array for every byte of the cache payload. On a 1 MiB payload that allocation dominated the scan. Measured with a real cache built from this parser, alternated so the two forms run against the same input: | payload | entries() | indexed reads | | --- | --- | --- | | 1 MiB | 15.5ms | 4.4ms | That is 3.49x on the scan, and the gap widens on smaller payloads where the allocation cost is a larger share (7.3x at 64 KiB in a synthetic run of the same shape). The scan is the whole cost of `inspect_v8_code_cache` once the file is read, so this is the tool's own hot loop. Output is unchanged: the parser returns one retained string for the 64 KiB fixture, and `src/v8` plus the CLI and MCP boundary files stay at 21 passing. `tsc` 0; `build` 0; `npm run lint` 0 errors. * fix(v8): admit only decimal tokens on the numeric CLI options Main added `tests/boundary/cli/cliDecimalArguments.test.ts` after this branch was opened. It enumerates every numeric CLI option and requires `0x10` and `1e3` to be rejected, because plain `Number` coercion would read them as 16 and 1000. This command's three options forwarded the domain fields unchanged, so the test failed on them: inspect-v8-code-cache options.maxFileBytes: Parser.parse accepts 1e3 inspect-v8-code-cache options.maxStrings: Parser.parse accepts 0x10 inspect-v8-code-cache options.maxStrings: Parser.parse accepts 1e3 inspect-v8-code-cache options.minStringBytes: Parser.parse accepts 0x10 `cliDecimalField` publishes the input view that parses the decimal token first and then lets the domain field own bounds, defaults and help, which is what the other numeric commands use. `tests/boundary/cli/cliDecimalArguments.test.ts` now passes. `tsc` 0; `build` 0; `npm run lint` 0 errors; `knip` 0; `docs:check` 0. * fix(v8): recognize module caches, and advise from remaining headroom Two review findings, each measured on Node 24.22.1 before changing anything. **A module cache was reported as a script.** `vm.SourceTextModule.createCachedData()` sets bit 30 of the source-length word, which the source-length mask `0x1fffffff` leaves out, and the producer check only tested the function bit at bit 29: | producer | source word | | --- | --- | | `vm.Script` | `0x00000013` for a 19-unit source | | `vm.compileFunction` | `0x20000009` for a 9-unit source | | `vm.SourceTextModule` | `0x40000013` for a 19-unit source | So a real module cache was labelled `script`, and `vm.Script` rejects that container. The producer enum gains `module` and the module bit is tested first; the source length is unchanged because both flags sit outside the mask. **The budget advice recommended a retry that could not work.** Both limits have ceilings — `max_strings` at 65536 and `min_string_bytes` at 256 — so an admitted file with more than 65536 runs of 256 bytes reached the branch while every suggested retry was a rejected input. `observationBudgetRemediation` now reads the remaining headroom and only recommends a change that is still admissible, falling back to selecting a smaller artifact when neither can move. The parser message states the fact and leaves recovery to the provider, which is the only place that can see both budgets. `MAX_INSPECT_V8_CODE_CACHE_MIN_STRING_BYTES` names the `min_string_bytes` ceiling that the schema previously spelled inline, so the advice and the schema cannot drift. `docs/v8-code-cache.md` describes both flag bits. `src/v8` plus the CLI and MCP boundary files: 28 passing; 7 new cases fail on the base commit. `tsc` 0; `build` 0; `npm run lint` 0 errors; `knip` 0; `docs:check` 0. * refactor(v8): decide the budget recovery as data, and test the decision The remediation tests matched fragments of the advice sentence and banned old phrases. `docs/testing.md` asks for error codes, recorded limits and recovery behaviour instead of frozen prose, so a harmless reword could fail those tests while wrong advice passed them. `observationBudgetRecovery` now returns the decision — which retries remain within the schema's admitted range, and whether a smaller artifact is the only option — and `observationBudgetRemediation` renders one sentence from it. The tests assert the decision, so the wording is free to change and an incorrect choice cannot pass. This also fixes a bug in the previous shape: it took the `min_string_bytes` branch to mean "lower it", but that branch is reachable with the value already at the schema minimum, where lowering is not a legal retry. The decision now carries `canLowerMinStringBytes` and a `requiresSmallerArtifact` flag for that case. 5 cases, all failing on the base commit, covering both headroom states, either ceiling alone, and the run-length floor. `src/v8` plus the CLI and MCP boundary files: 28 passing. `tsc` 0; `build` 0; `npm run lint` 0 errors; `knip` 0; `docs:check` 0. * ci: rerun after the wakaru release download recovered The only failing job on this branch was `javascript_recovery / real-javascript-recovery`, which failed on `curl: (22) The requested URL returned error: 504` while downloading `wakaru-linux-x64.tar.gz`. The release is reachable again (HTTP 200), so this empty commit re-triggers the lane. * docs(v8): place the guide in the tree and record the feature The guide sat at `docs/v8-code-cache.md`, outside the `docs/guides/` tree every other guide uses, and neither index linked it, so it could not be reached from `docs/README.md` or the VitePress sidebar. Moved to `docs/guides/javascript/`, linked from both indexes, and recorded the feature under `docs/specs/v8-code-cache-inspection/` with `spec.md`, `plan.md` and `tasks.md`. The spec keeps only the premises that were measured on Node 24.22.1 — the three producer words and the retained-string layout — rather than restating the implementation. `npm run docs:check` 0; `npm run format:check` 0; `tsc` 0; `build` 0; `lint` 0 errors; `knip` 0. V8 reader, CLI and MCP files: 28 passing. * docs(v8): use the documented spec path and test the advice against its struct Two review findings. **The records were at `docs/specs/v8-code-cache-inspection/`.** `AGENTS.md:73` asks for `docs/specs/<domain>/<feature-slug>/`, so they move to `docs/specs/v8/code-cache-inspection/`. **The verification section claimed more than the tests do.** It said the producer cases were built from real `vm.Script`, `vm.compileFunction` and `vm.SourceTextModule` output, and that the budget advice was compared with its owning formatter. In fact only `vm.Script` and `vm.compileFunction` are real producers — the module case sets the measured bit on a `vm.Script` cache — and only `observationBudgetRecovery` was asserted. Corrected the claim, and closed the second gap rather than only describing it: `observationBudgetRemediation` now has four cases holding the sentence to the struct it renders from. The sentence must not advise a knob the struct closed, and must mention a smaller artifact exactly when the struct requires one. Verified by making the sentence advise `max_strings` after the ceiling was reached — the test fails. Wording stays free; wrong advice does not. `npm run docs:check` 0; `npm run format:check` 0; `tsc` 0; `build` 0; `lint` 0 errors; `knip` 0. V8 reader, CLI, MCP, absolute-path and decimal-argument files: 34 passing. * fix(v8): restore the absolute-path contract entry after the rebase The rebase onto `main` conflicted in `tests/boundary/mcp/absoluteLocalPathTools.test.ts`: `main` gained `inspect_api_contract`, `inspect_devicetree`, `inspect_playwright_trace` and `inspect_python_pyc` in both the contract list and the path-field map while this branch added `inspect_v8_code_cache`. Both sides are additive, so both are kept. Without the resolution the branch carried conflict markers, which made `mergeable_state` `dirty` and every check on it meaningless. Re-verified after the rebase: `tsc` 0, `build` 0, `format:check` 0, `lint` 0 errors, `knip` 0, `docs:check` 0, and the V8 reader plus its CLI, MCP, absolute-path and decimal-argument boundary files at 34 passing. * test(v8): pin the producer from the runtime's own header word An independent reviewer ran these files on Node 22.23.4, 24.22.1 and 26.12.1. Only 22.23.4 failed, on `separates the compileFunction producer bit from the source length`, expecting `compile_function` and reading `script`. The cause is the fixture, not the parser: `vm.compileFunction(...).cachedData` carries `0x20000009` in the source-length word on Node 24.22.1, with bit 29 set, while Node 22.23.4 does not set that bit at all. Whether a given V8 build marks the word is a build detail, so asserting one build's spelling made the check version-dependent. The case now reads the word the runtime produced and asserts the parser maps it correctly, and keeps the part that must hold everywhere: the source length is the low bits, so it equals both `word & 0x1fffffff` and the source's length. The flag meanings themselves stay pinned by the synthetic `withHeaderWord` cases above, which do not depend on any build. Reverting the parser's `compile_function` arm fails this case and `keeps the function and module flags distinct`. `src/v8` plus the CLI, MCP and absolute-path boundary files: 24 and 34 passing. `tsc` 0; `build` 0; `npm run format:check` 0; `npm run lint` 0 errors; `knip` 0. * fix(v8): report an unflagged producer word as unknown, not as a script `vm.compileFunction` marks bit 29 of the source-length word on Node 24.22.1 (`0x20000004` for a 4-unit source) and does not mark it on Node 22.23.4 (`0x00000004` for the same call). Whether a V8 build marks a function cache is therefore a build detail, and an unflagged word is either a `vm.Script` cache or an unmarked function cache. The container carries nothing that separates the two. The reader reported `script` for that case, which is a confident claim the bytes do not support. My previous commit made the test accept whichever value the runtime produced, which recorded the ambiguity instead of resolving it in the contract. `unknown` is now a producer value, the unflagged word maps to it, and the observed word stays in `header.fields` for a caller that trusts a specific build fingerprint. A limitation line says the same in the report itself. `header.producer` widens to `["script", "compile_function", "module", "unknown"]`; `script` is no longer produced, because no unflagged word can be shown to be one. The spec's producer rule and its verification notes are updated to match. Reverting the mapping to `script` fails 2 of the 24 `src/v8` cases. `src/v8` with the CLI, MCP and absolute-path boundary files: 33 passing. `tsc` 0; `build` 0; `docs:check` 0; `npm run format:check` 0; `npm run lint` 0 errors. `knip` reports one unused export (`builtinDataEffectMethod`) on `main` as well, so it is not from this change. * fix(artifacts): retain completed identity across native parser failures * docs(v8): preserve unknown unflagged cache provenance --------- Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> |
||
|
|
2c27c2a43b |
feat(electron): report V8 cachedData compilation boundaries (#9501)
* feat(electron): report V8 cachedData execution boundaries
analyze-javascript-application treated new vm.Script(source, {cachedData}) and vm.compileFunction(..., {cachedData}) as ordinary source. V8 deserializes previously compiled bytecode for those calls, so an Electron preload wrapper that delegates its whole contextBridge and IPC surface to a .cache/.jsc snapshot appeared to have been fully analyzed with zero exposed APIs.
Record each vm compilation with its inert cache path when the cachedData value traces to a readFileSync/readFile of path syntax, and project a cached-data execution unknown plus a loads edge from the owning source. Compilations without a cache stay recorded as no-cached-data so absence remains distinguishable from an unparsed snapshot. Count cachedData executions in the Electron summary and state the coverage limit in the graph limitations.
* style(cli): wrap the native data type path description
The `inspect-native-data-type` argument description line is 82 columns, over the repository's 80-column `.oxfmtrc.json` limit, so `npm run format:check` fails on main and on every branch merged from it. It came in with #9465 and the following commits to this file did not touch it. Reformat the one call the formatter objects to; no behaviour change.
* style(domain): reformat the pending dynamic-code accumulator field
`npm run format:check` fails on this branch, which is what `Static checks` reports: oxfmt wants the `pendingDynamicCode` union on one line. Applying it is the whole change; no behaviour is touched.
* fix(electron): preserve VM callable and cache source uncertainty
* docs(javascript): specify cached-data compilation boundaries
* fix(electron): exclude disabled caches from recovered boundaries
---------
Co-authored-by: 2SinceJuly <202121119+2SinceJuly@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
|
||
|
|
4d7c6efe9a |
feat(desktop): open the seed's document at launch, and say when a seed was made for the task (#9054)
* feat(desktop): capture, draft, export and witness a task inside a build computer - start_build_capture runs REA's capture inside the computer through a small controller over computer-exec, after a user-space apt-get update; mark_build_checkpoint returns once the capture confirms the checkpoint; stop_build_capture returns the draft between seed and end. - export_build_environment exports with the requester's task inside the computer and fetches the bundle through data/get in bounded batches. - check_build_task grades a computer's data/get with REA's evaluator and, through seed, after_edit, near_miss and after_reset stages, records a witness with the action log and the screen recording; act_on_build_computer gains reset. - Capture progress lines carry window, checkpoint and refusal events; apps start in the home; a pack script builds the runtime archive; long tools send progress notifications. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): make build capture and witness steps retryable, and close the near-miss reset hole - A capture whose start answer is lost is stopped at once and kept unreleased until the stop is confirmed; a lost checkpoint answer is recovered from the capture's own log, and draft and export use the checkpoints its Evidence records; stop can be repeated to resume reading its result. - A witness can check its seed again after a failed read, and keeps its stages in a saving state until the record is written, so a failed save can be retried without reading the app again. - after_edit and near_miss count only click, drag, scroll, type and key, so a reset no longer stands in for the near-miss edit. - A .deb build keeps its package file for capture and passes its URL to export; bundle downloads write each checked file before fetching the next; an apt-get update failure reports its exit code and log tail; reset sends progress while it waits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): keep the Trash out of seeds, bundle folders unwritten and first frames drawn From the blind Inkscape rebuild: - Paths in ~/.local/share/Trash get a desktop_trash reason and the shared_desktop role, so a file trashed before seed is neither owned nor seeded; the export names it in a limitation. - The keep helper runs with PYTHONDONTWRITEBYTECODE=1, so starting a computer from a bundle folder no longer writes __pycache__ into it. - start_build_computer waits, bounded, until the first frame is not one colour before returning it. From review: a .deb that apt also offers exports from apt, since export passes --package-url only when the capture says the package must come from its file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): bound the first-frame wait's retries to the time left, with progress throughout Each retry of the drawn-first-frame wait runs under an abort that fires at the 10 s deadline, and the latest frame is returned when time runs out. connect takes the first frame itself while its progress heartbeat still runs, reporting "waiting for the desktop to draw". The wait moves to DrawnScreenshot.ts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): serialize each build computer's calls, keep one recording id, and separate unreadable checks from failures - One queue per computer: actions, capture steps and witness checks run one at a time, so two overlapping after_edit checks can no longer both be filed and let the witness hold without a near miss. Close cancels the running and queued calls; different computers still run concurrently. - The witness keeps one recording request id per computer, so a seed retried after a lost reply recovers the recording it started. - A check that could not read its file is undecided, not a failure, so a temporary read error can't satisfy seed, near_miss or after_reset; such a stage is refused and can be checked again. - The export's file listing is written to a file and read back in bounded batches, so a large bundle no longer overruns exec's 1 MiB output. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): treat failures on cut views as undecided, require a decided seed failure at export, and keep a close's cancellation - A presence check that misses its line, row or pointed value in a view cut short is undecided rather than failed, since the data may sit in the part left out; a witness stage can no longer be proved by such a failure. - Export counts only decided failures on the seed, and refuses a task whose every seed failure is undecided. - A step whose turn was aborted by a close or the caller returns cancelled even when its work finished, so start_build_capture no longer reports success for a computer being removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): keep a step's saved result when a cancellation arrives during its commit Reporting cancelled for any step whose turn was aborted after its work replaced a completed export or witness save with a bare cancellation, losing what was saved and leaving the witness unreadable. Steps now return what they completed; only start_build_capture, which commits nothing, checks its turn after the post-launch screenshot and reports cancelled. Asking again for a saved witness's final check returns its record. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): refuse a saved witness's repeated check for another folder Asking again for the check that ended a witness returned its saved record whatever directory came with it, so a caller naming another folder got success though nothing was saved there. A different folder is now refused, as an unfinished seed's retry already is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): assert the facts of cut-view and undecided outcomes, not their sentences The new cut-view, missing-value, undecided-refusal and witness tests froze whole descriptions, so a harmless rewording broke them. They now check each outcome's id, passed and undecided exactly and the facts its message must carry (file, pointer, line, row, stage) separately. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(desktop): read XML with a plain DOCTYPE, and check an element's whole text - Both readers accept a DOCTYPE with only a name and an optional PUBLIC or SYSTEM identifier, record it as the view's doctype, and never fetch the DTD or expand entities beyond XML's five; an internal subset, an external entity and a parameter entity stay refused alike. - text_equals and text_contains compare the concatenated text of the element (or text node or attribute) a pointer reaches, as XPath string() does, with optional normalize_whitespace; both evaluators agree, and a text check on a truncated element is undecided. - Whitespace-only text between elements is dropped only when the element holds no other text, so text split into runs keeps its spaces. - The draft suggests text_equals for an element whose text changed. So an AbiWord .abw reads as XML, and its paragraph's text is checked whole however AbiWord splits it into <c> runs, as Writer's spans are. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): draft whole-text checks on the paragraph, read only text as text, and skip asctime stamps - A changed value is read at both ends, so text that became a run still marks its paragraph, and the drafted text_equals moves up out of mixed content to the nearest ancestor named by an attribute, such as AbiWord's p by its xid. - Text checks accept only a text node or an attribute value; element names and doctype fields fail, in both evaluators. - isTimestamp also recognises asctime dates (Www Mmm dd hh:mm:ss yyyy). - XML files are drafted with the keyed diff the archive entries use, so no suggestion reaches an element by position; the shared logic moves to appTaskDraftNamed.ts. - Text-check tests assert facts, not whole sentences. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): keep checks on a changed attribute inside a paragraph whose text check replaces its runs' A drafted whole-text check on a paragraph hid every change inside it, so a link whose label and href both changed drafted only the paragraph's text and the new destination went unchecked. The text check now covers text and runs added or removed whole; a changed name or attribute of an element both versions hold keeps its own check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): read an attribute called name or attributes as an attribute when the draft keeps its check The owner of `.../attributes/name` was taken as `.../attributes`, so a changed `name` attribute inside a paragraph with a text check was dropped again. The owner is now read by segment, attributes first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): draft text checks from text in runs added whole, and name a text element by its own id before its container Text typed into a run the diff lists whole was never read, so the draft kept only a presence check on the run, which wrong text also passed. Such text now marks the nearest element both ends hold, or, when none can take the check, the added element's own text. The climb also names an element by an identifier of its own (id, xml:id, xid) before a larger container, so a headline under a long layer keeps a whole-text check that survives re-split runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): expect the whole-text check where #8988's pairing test meets text checks On this branch a changed element's text is drafted as `text_equals` on the element, so the identity pairing test now expects that check, under the same `[@role=body]` key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(skills): build a computer-app environment from a request The product skill gains references/desktop-build.md, a procedure that takes Claude from a request such as "an Inkscape environment where the agent changes a poster's headline" to a witnessed bundle and a report, through start_build_computer, act_on_build_computer, the build capture tools, export_build_environment and check_build_task: questions asked once upfront, pauses only when blocked, a seed made in the app, content checks by selector, a witness with a near miss and a reset in a fresh computer, and solver runs only within a budget. setup installs the new reference; skillVersion 61. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(skills): fold the blind Inkscape rebuild's friction into the build skill key takes an array of one chord's keys; check for a text cursor before typing in apps with single-key shortcuts; in Save As, click Documents and type only the file name; anything saved before seed, the Trash included, is part of the seed; dismiss first-run dialogs before seed; a bundle's app starts with the seed's files but need not open the document; Inkscape's window class is Inkscape. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(skills): fold the held-out AbiWord build's friction into the build skill Name the act fields and link the guide; a region screenshot becomes the latest frame; a drawn caret is not focus; confirm dialogs with Return; check the dialog's folder when the app shows only a name; an XML file the draft shows as lines was read as text, so use short line checks; and keep text checks to the value the edit types, since some apps save a reloaded document differently. Later witness stages take no directory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(skills): state the export's seed rule, the Trash exception and draft refusals exactly The export refuses a task unless at least one check fails on the seed and every check passes at the end; a file moved to the Trash is left out of the seed, so trash a stray file rather than starting over; a null draft names its cause in draft_refusal; and a line check on a format read as text only approximates a value, so bound it and call it approximate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(skills): teach the build skill to use DOCTYPE and whole-text checks The skill now checks text an app splits into runs whole with text_equals or text_contains, finds an AbiWord paragraph by its xid, and drops the Writer revision-id workaround. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(skills): point text checks at the paragraph, and say what the scrub replaces From the AbiWord rebuild: point a text check at the paragraph or another element the edit keeps, never at a run a reopened document splits; how to name an unchanged element; the export replaces the host name, user@host and home path while a bare user name stays; AbiWord's entry and class. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): keep every text check on a cut element undecided, in both evaluators The XML reader drops text deeper than its depth limit but keeps later siblings, and an element's whole text joins both sides, so a text_contains on a cut element could match text the file never holds ("at 3" + deep "WRONG" + ":30 PM" read as "at 3:30 PM"). Any text check on an element of a cut view is now undecided again, as #9050 had it, in REA's evaluator and the exported verifier; a text node or attribute value stays decided. The text check tests assert facts rather than sentences. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(desktop): open the seed's document at launch, and say when a seed was made for the task An exported app now opens the seed's one document at launch when its desktop entry's Exec takes files, so a solving agent starts in the document rather than on the app's start screen; a command that already names a file is kept, and several documents or an Exec without a file code keep the launch and say why. `--synthetic-seed`, which the build export passes, words the README and limitations for a seed made in the build computer instead of asking to keep the user's data local. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): count only a document the launch names, absolute or from its working directory, as already opened A settings path under the home, such as geany's --config, kept the seed's document from opening, and a relative document argument was missed and appended again. An argument now counts only when it resolves, from the captured working directory, to a file the capture gave the document role. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): check the seed and launch wording against their formatters, and the facts on their own The tests froze the README's and limitations' sentences, so a harmless rewrite broke them. The wording now comes from exported formatters (`seedWording`, `seedLimitation`, `launchDocumentNote`, `NO_LAUNCH_DOCUMENT`), the tests compare against those, and check the facts separately: which document opens, the respelled path in the command, the README naming it, `--synthetic-seed` and the Evidence's `synthetic_seed`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(desktop): plan the export's seeds and launch in their own module The merged export module passed the file and function size limits; the seed digests and the launch command now come from `DesktopExportLaunch.ts`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): keep a reset applied when the screenshot asked after it fails Once data/reset and the ready wait succeed, act_on_build_computer's reset is applied in the action log and returns success; a screenshot asked of it that is then refused or throws is named in the result's screenshot_error, with no frame, so the next after_reset stage is not refused. Cancellation still propagates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): keep checks for elements without text beside a text edit, and normalize DOCTYPE system id line endings A review found two gaps. - A paragraph's whole-text check covered every element added or removed inside it, including ones holding no text: an image frame, a line break. A solver who typed the text but never inserted the image passed. Such an element now keeps its own presence or absence check. - The Python reader kept a DOCTYPE system literal's CRLF where TypeScript normalizes it to LF. Both now report LF. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): wait out long build commands, fail a reset that restores nothing, and tie the witness to its bundle A review found five gaps. - Commands in the computer answer only when they end, but fetch stops waiting for headers after 300 s. So a slow export, draft or start always failed. A command with its own deadline now waits on node:http, bounded by that deadline. - after_reset held whenever some check failed, so a reset that changed nothing passed on the near-miss state. Each check must now come out as it did at the seed. - A failed or partial apt-get update left lists that looked complete, so a second start skipped the update. The update is now recorded only when it succeeds, and rerun otherwise. - A witness on a bundle computer graded whatever task it was given. Its seed stage now refuses a task whose steps or checks differ from the bundle's. - A task too large for one command argument (96 KiB) is refused before the export runs, instead of failing with E2BIG in the computer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): advertise a checkpoint-name pattern that compiles in every JS regex mode main's advertised-pattern test compiles every input schema pattern in v mode, which refuses an unescaped hyphen in a character class. The checkpoint name's hyphen is now escaped, and it means the same in u mode. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): import textSyntaxFormat once in the state format tests main's mixed-case JSON suffix fix and this branch both added the import, and the merge kept both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): keep a completed reset, an unread seed, and a failed apt update A cancel after data/reset no longer drops the restore from the action log, so a near miss cannot treat the restored seed as an edit. An unreadable seed check that later passes leaves after_reset undecided instead of failing the witness. apt-get update is kept only when Error-Mode reports success and a package list was fetched. The controller reply schema lives with the controller, and capture progress lines are read by their domain parser. * fix(desktop): keep a whitespace-only run under the paragraph text check A run whose only text is whitespace is still text the paragraph check reads. It no longer gets its own presence check, which a later save of the same words without that run would fail. Images and breaks, whose text is empty, still keep their own checks. * fix(desktop): keep an unread reset and a cut text check undecided after_reset stays undecided when any check was not read, even if another check still fails and the unread result's boolean matches the seed. A text check for a child past a truncated view is undecided in both evaluators. A reset whose reply is lost blocks a near miss until a later input or a reset whose reply arrives. * fix(desktop): retry a witness recording and a published record's cleanup A recording that fails to end or download is not written into the witness folder, and a manifest already received is fetched again without ending the recording twice. A folder that is published while its handles fail to close keeps that record and retries the same cleanup instead of writing the folder again. * fix(desktop): keep a published witness error and tag an app data refusal A second failure to close a published witness returns the original error, so its record and cleanup lease stay bound. A reset the app itself refuses is an AppDataRefusal; only a reply that is not that refusal stays unsettled. A missing child of a cut view is undecided with the same description in both evaluators, and the shared cases cover it. * fix(desktop): align a cut view's missing text with the Python check A missing child of a truncated view is undecided for the same sentence in both evaluators, including the pointer the view does not contain. * fix(desktop): keep one published witness cleanup across retries A published record and its bound cleanup error stay together. A later close failure returns that error, and the unused path that built a fresh adapter error is gone. * fix(desktop): keep a bundle task read inside the witness result A cancelled, refused, or failed read of the bundle's task files returns the witness's Result, including a cleanup lease when a handle would not close. * fix(desktop): check build runtime export capability * fix(desktop): provide complete runtime repack command * fix(desktop): retain runtime probe failures * fix(desktop): recognize captured file URL documents * fix(desktop): render captured file URLs at launch * fix(desktop): isolate launcher URL encoding * test(desktop): move launch execution to boundary suite * style: fix desktop launch test formatting * style: format native command path schema --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: morluto <morluto@users.noreply.github.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> |
||
|
|
94182f331e |
feat(go): recover bounded Go string literals from (ptr, len) headers (#9206)
* feat(go): recover bounded Go string literals from (ptr, len) headers * fix(go): deduplicate header scan spans, bound rejected cache, and reject Cf * fix(go): allow U+200C ZWNJ and U+200D ZWJ in Go string literal recovery * fix(go): index Mach-O load regions, validate MCP schema, and add feature specs * test(go): cover Mach-O region-index cancellation and load-region boundaries |
||
|
|
5a25d42f23 |
fix(desktop)!: require contemporaneous SQLite member evidence (#9470)
* fix(desktop)!: require contemporaneous SQLite member evidence * fix(desktop): preserve incomplete baseline membership uncertainty |
||
|
|
03a3fcbcea |
feat(skills): build a computer-app environment from a request (#9049)
* feat(desktop): capture, draft, export and witness a task inside a build computer - start_build_capture runs REA's capture inside the computer through a small controller over computer-exec, after a user-space apt-get update; mark_build_checkpoint returns once the capture confirms the checkpoint; stop_build_capture returns the draft between seed and end. - export_build_environment exports with the requester's task inside the computer and fetches the bundle through data/get in bounded batches. - check_build_task grades a computer's data/get with REA's evaluator and, through seed, after_edit, near_miss and after_reset stages, records a witness with the action log and the screen recording; act_on_build_computer gains reset. - Capture progress lines carry window, checkpoint and refusal events; apps start in the home; a pack script builds the runtime archive; long tools send progress notifications. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): make build capture and witness steps retryable, and close the near-miss reset hole - A capture whose start answer is lost is stopped at once and kept unreleased until the stop is confirmed; a lost checkpoint answer is recovered from the capture's own log, and draft and export use the checkpoints its Evidence records; stop can be repeated to resume reading its result. - A witness can check its seed again after a failed read, and keeps its stages in a saving state until the record is written, so a failed save can be retried without reading the app again. - after_edit and near_miss count only click, drag, scroll, type and key, so a reset no longer stands in for the near-miss edit. - A .deb build keeps its package file for capture and passes its URL to export; bundle downloads write each checked file before fetching the next; an apt-get update failure reports its exit code and log tail; reset sends progress while it waits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): keep the Trash out of seeds, bundle folders unwritten and first frames drawn From the blind Inkscape rebuild: - Paths in ~/.local/share/Trash get a desktop_trash reason and the shared_desktop role, so a file trashed before seed is neither owned nor seeded; the export names it in a limitation. - The keep helper runs with PYTHONDONTWRITEBYTECODE=1, so starting a computer from a bundle folder no longer writes __pycache__ into it. - start_build_computer waits, bounded, until the first frame is not one colour before returning it. From review: a .deb that apt also offers exports from apt, since export passes --package-url only when the capture says the package must come from its file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): bound the first-frame wait's retries to the time left, with progress throughout Each retry of the drawn-first-frame wait runs under an abort that fires at the 10 s deadline, and the latest frame is returned when time runs out. connect takes the first frame itself while its progress heartbeat still runs, reporting "waiting for the desktop to draw". The wait moves to DrawnScreenshot.ts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): serialize each build computer's calls, keep one recording id, and separate unreadable checks from failures - One queue per computer: actions, capture steps and witness checks run one at a time, so two overlapping after_edit checks can no longer both be filed and let the witness hold without a near miss. Close cancels the running and queued calls; different computers still run concurrently. - The witness keeps one recording request id per computer, so a seed retried after a lost reply recovers the recording it started. - A check that could not read its file is undecided, not a failure, so a temporary read error can't satisfy seed, near_miss or after_reset; such a stage is refused and can be checked again. - The export's file listing is written to a file and read back in bounded batches, so a large bundle no longer overruns exec's 1 MiB output. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): treat failures on cut views as undecided, require a decided seed failure at export, and keep a close's cancellation - A presence check that misses its line, row or pointed value in a view cut short is undecided rather than failed, since the data may sit in the part left out; a witness stage can no longer be proved by such a failure. - Export counts only decided failures on the seed, and refuses a task whose every seed failure is undecided. - A step whose turn was aborted by a close or the caller returns cancelled even when its work finished, so start_build_capture no longer reports success for a computer being removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): keep a step's saved result when a cancellation arrives during its commit Reporting cancelled for any step whose turn was aborted after its work replaced a completed export or witness save with a bare cancellation, losing what was saved and leaving the witness unreadable. Steps now return what they completed; only start_build_capture, which commits nothing, checks its turn after the post-launch screenshot and reports cancelled. Asking again for a saved witness's final check returns its record. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): refuse a saved witness's repeated check for another folder Asking again for the check that ended a witness returned its saved record whatever directory came with it, so a caller naming another folder got success though nothing was saved there. A different folder is now refused, as an unfinished seed's retry already is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): assert the facts of cut-view and undecided outcomes, not their sentences The new cut-view, missing-value, undecided-refusal and witness tests froze whole descriptions, so a harmless rewording broke them. They now check each outcome's id, passed and undecided exactly and the facts its message must carry (file, pointer, line, row, stage) separately. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(desktop): read XML with a plain DOCTYPE, and check an element's whole text - Both readers accept a DOCTYPE with only a name and an optional PUBLIC or SYSTEM identifier, record it as the view's doctype, and never fetch the DTD or expand entities beyond XML's five; an internal subset, an external entity and a parameter entity stay refused alike. - text_equals and text_contains compare the concatenated text of the element (or text node or attribute) a pointer reaches, as XPath string() does, with optional normalize_whitespace; both evaluators agree, and a text check on a truncated element is undecided. - Whitespace-only text between elements is dropped only when the element holds no other text, so text split into runs keeps its spaces. - The draft suggests text_equals for an element whose text changed. So an AbiWord .abw reads as XML, and its paragraph's text is checked whole however AbiWord splits it into <c> runs, as Writer's spans are. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): draft whole-text checks on the paragraph, read only text as text, and skip asctime stamps - A changed value is read at both ends, so text that became a run still marks its paragraph, and the drafted text_equals moves up out of mixed content to the nearest ancestor named by an attribute, such as AbiWord's p by its xid. - Text checks accept only a text node or an attribute value; element names and doctype fields fail, in both evaluators. - isTimestamp also recognises asctime dates (Www Mmm dd hh:mm:ss yyyy). - XML files are drafted with the keyed diff the archive entries use, so no suggestion reaches an element by position; the shared logic moves to appTaskDraftNamed.ts. - Text-check tests assert facts, not whole sentences. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): keep checks on a changed attribute inside a paragraph whose text check replaces its runs' A drafted whole-text check on a paragraph hid every change inside it, so a link whose label and href both changed drafted only the paragraph's text and the new destination went unchecked. The text check now covers text and runs added or removed whole; a changed name or attribute of an element both versions hold keeps its own check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): read an attribute called name or attributes as an attribute when the draft keeps its check The owner of `.../attributes/name` was taken as `.../attributes`, so a changed `name` attribute inside a paragraph with a text check was dropped again. The owner is now read by segment, attributes first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): draft text checks from text in runs added whole, and name a text element by its own id before its container Text typed into a run the diff lists whole was never read, so the draft kept only a presence check on the run, which wrong text also passed. Such text now marks the nearest element both ends hold, or, when none can take the check, the added element's own text. The climb also names an element by an identifier of its own (id, xml:id, xid) before a larger container, so a headline under a long layer keeps a whole-text check that survives re-split runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): expect the whole-text check where #8988's pairing test meets text checks On this branch a changed element's text is drafted as `text_equals` on the element, so the identity pairing test now expects that check, under the same `[@role=body]` key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(skills): build a computer-app environment from a request The product skill gains references/desktop-build.md, a procedure that takes Claude from a request such as "an Inkscape environment where the agent changes a poster's headline" to a witnessed bundle and a report, through start_build_computer, act_on_build_computer, the build capture tools, export_build_environment and check_build_task: questions asked once upfront, pauses only when blocked, a seed made in the app, content checks by selector, a witness with a near miss and a reset in a fresh computer, and solver runs only within a budget. setup installs the new reference; skillVersion 61. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(skills): fold the blind Inkscape rebuild's friction into the build skill key takes an array of one chord's keys; check for a text cursor before typing in apps with single-key shortcuts; in Save As, click Documents and type only the file name; anything saved before seed, the Trash included, is part of the seed; dismiss first-run dialogs before seed; a bundle's app starts with the seed's files but need not open the document; Inkscape's window class is Inkscape. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(skills): fold the held-out AbiWord build's friction into the build skill Name the act fields and link the guide; a region screenshot becomes the latest frame; a drawn caret is not focus; confirm dialogs with Return; check the dialog's folder when the app shows only a name; an XML file the draft shows as lines was read as text, so use short line checks; and keep text checks to the value the edit types, since some apps save a reloaded document differently. Later witness stages take no directory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(skills): state the export's seed rule, the Trash exception and draft refusals exactly The export refuses a task unless at least one check fails on the seed and every check passes at the end; a file moved to the Trash is left out of the seed, so trash a stray file rather than starting over; a null draft names its cause in draft_refusal; and a line check on a format read as text only approximates a value, so bound it and call it approximate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(skills): teach the build skill to use DOCTYPE and whole-text checks The skill now checks text an app splits into runs whole with text_equals or text_contains, finds an AbiWord paragraph by its xid, and drops the Writer revision-id workaround. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(skills): point text checks at the paragraph, and say what the scrub replaces From the AbiWord rebuild: point a text check at the paragraph or another element the edit keeps, never at a run a reopened document splits; how to name an unchanged element; the export replaces the host name, user@host and home path while a bare user name stays; AbiWord's entry and class. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): keep every text check on a cut element undecided, in both evaluators The XML reader drops text deeper than its depth limit but keeps later siblings, and an element's whole text joins both sides, so a text_contains on a cut element could match text the file never holds ("at 3" + deep "WRONG" + ":30 PM" read as "at 3:30 PM"). Any text check on an element of a cut view is now undecided again, as #9050 had it, in REA's evaluator and the exported verifier; a text node or attribute value stays decided. The text check tests assert facts rather than sentences. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): keep a reset applied when the screenshot asked after it fails Once data/reset and the ready wait succeed, act_on_build_computer's reset is applied in the action log and returns success; a screenshot asked of it that is then refused or throws is named in the result's screenshot_error, with no frame, so the next after_reset stage is not refused. Cancellation still propagates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): keep checks for elements without text beside a text edit, and normalize DOCTYPE system id line endings A review found two gaps. - A paragraph's whole-text check covered every element added or removed inside it, including ones holding no text: an image frame, a line break. A solver who typed the text but never inserted the image passed. Such an element now keeps its own presence or absence check. - The Python reader kept a DOCTYPE system literal's CRLF where TypeScript normalizes it to LF. Both now report LF. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): wait out long build commands, fail a reset that restores nothing, and tie the witness to its bundle A review found five gaps. - Commands in the computer answer only when they end, but fetch stops waiting for headers after 300 s. So a slow export, draft or start always failed. A command with its own deadline now waits on node:http, bounded by that deadline. - after_reset held whenever some check failed, so a reset that changed nothing passed on the near-miss state. Each check must now come out as it did at the seed. - A failed or partial apt-get update left lists that looked complete, so a second start skipped the update. The update is now recorded only when it succeeds, and rerun otherwise. - A witness on a bundle computer graded whatever task it was given. Its seed stage now refuses a task whose steps or checks differ from the bundle's. - A task too large for one command argument (96 KiB) is refused before the export runs, instead of failing with E2BIG in the computer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): advertise a checkpoint-name pattern that compiles in every JS regex mode main's advertised-pattern test compiles every input schema pattern in v mode, which refuses an unescaped hyphen in a character class. The checkpoint name's hyphen is now escaped, and it means the same in u mode. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): import textSyntaxFormat once in the state format tests main's mixed-case JSON suffix fix and this branch both added the import, and the merge kept both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): keep a completed reset, an unread seed, and a failed apt update A cancel after data/reset no longer drops the restore from the action log, so a near miss cannot treat the restored seed as an edit. An unreadable seed check that later passes leaves after_reset undecided instead of failing the witness. apt-get update is kept only when Error-Mode reports success and a package list was fetched. The controller reply schema lives with the controller, and capture progress lines are read by their domain parser. * fix(desktop): keep a whitespace-only run under the paragraph text check A run whose only text is whitespace is still text the paragraph check reads. It no longer gets its own presence check, which a later save of the same words without that run would fail. Images and breaks, whose text is empty, still keep their own checks. * fix(desktop): keep an unread reset and a cut text check undecided after_reset stays undecided when any check was not read, even if another check still fails and the unread result's boolean matches the seed. A text check for a child past a truncated view is undecided in both evaluators. A reset whose reply is lost blocks a near miss until a later input or a reset whose reply arrives. * fix(desktop): retry a witness recording and a published record's cleanup A recording that fails to end or download is not written into the witness folder, and a manifest already received is fetched again without ending the recording twice. A folder that is published while its handles fail to close keeps that record and retries the same cleanup instead of writing the folder again. * fix(desktop): keep a published witness error and tag an app data refusal A second failure to close a published witness returns the original error, so its record and cleanup lease stay bound. A reset the app itself refuses is an AppDataRefusal; only a reply that is not that refusal stays unsettled. A missing child of a cut view is undecided with the same description in both evaluators, and the shared cases cover it. * fix(desktop): align a cut view's missing text with the Python check A missing child of a truncated view is undecided for the same sentence in both evaluators, including the pointer the view does not contain. * fix(desktop): keep one published witness cleanup across retries A published record and its bound cleanup error stay together. A later close failure returns that error, and the unused path that built a fresh adapter error is gone. --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: morluto <morluto@users.noreply.github.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> |
||
|
|
a67525cdf1 |
docs: organize canonical documentation layout and verify new pages (#2791)
* docs: organize canonical documentation layout (URGENTE) Group all existing authored guides by domain and ownership, expose complete navigation, and preserve their public routes. Update physical path consumers and release configuration while retaining historical records. Document domain-based specs and ADR slugs without global numbering. Co-Authored-By: Codex <noreply@openai.com> * fix(docs): honor home layout in all-page route verification * style: format reviewed source changes * fix(docs): preserve routes and navigation cache inputs * fix: repair the static-check failures on the default branch (#2895) * fix: repair the static-check failures on the default branch The default branch fails its own required `Static checks` job three ways, so every pull request reports that job as failed regardless of its own change. - `npm run format:check` reports `src/domain/functionComparison.test.ts` and `src/ida/IdaOperationRunner.ts`. - `npm run lint` reports a duplicate `import { join } from "node:path"` in `tests/boundary/mcp/ghidraInventoryMcp.test.ts` (lines 4 and 17). - `npm run typecheck` reports `format: "devin"` missing from the client format union in `src/application/SupportedClients.ts`, and an unchecked index in `tests/boundary/cli/clientProfileLifecycle.test.ts`, whose pair array is inferred as `string[][]`. Apply the pinned formatter, drop the duplicate import, list the `"devin"` format that its own definition already uses, and mark the pair array `as const`. Validation: `npm run check:fast` and `npm run format:check` pass. * fix(setup): keep Devin on the JSON configuration dialect --------- Co-authored-by: 吴佳浩 <wujiahao@supremind.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> * fix(docs): update links after guide relocation * docs: correct verified documentation route counts * fix(docs): update browser capture guide link after move (#2820) Refresh gettext protected-link comments alongside the authored href. Co-authored-by: Codex <noreply@openai.com> * fix(docs): include http3 lab in stable routes * fix(docs): preserve historical release evidence and links * fix(ghidra): restore Windows verifier identity import * docs(wakaru): preserve pinned upstream policy link * docs(index): retain recently added guide links * docs(mcp): preserve parent retention clarification * fix(cli): preserve standalone import guidance * fix(test): preserve translated guide link drift coverage --------- Co-authored-by: Matheus Breguêz <matbrgz@gmail.com> Co-authored-by: Codex <noreply@openai.com> Co-authored-by: morluto <17176810+morluto@users.noreply.github.com> Co-authored-by: 吴佳浩Alben <35291372+XiaoBinGan@users.noreply.github.com> Co-authored-by: 吴佳浩 <wujiahao@supremind.com> |
||
|
|
3e8a5f76d0 |
feat(native): retain LLDB source coordinates and verify Pascal calls (#2800)
* feat(native): retain LLDB source coordinates and verify Pascal call entries Preserve partial line-table attribution for native locations and historical evidence compatibility. Verify owned Free Pascal call entries through CLI/MCP. Refs #2382, #2372, #2397 Co-Authored-By: Codex <noreply@openai.com> * docs: namespace native specifications by domain and feature Use stable descriptive paths instead of numeric prefixes to avoid parallel contribution collisions. Co-Authored-By: Codex <noreply@openai.com> * fix(native): bound Pascal verification and compare caller coordinates Address review findings at their producing boundaries and preserve directly affected consumers. Source inspection and git diff --check completed. Tests and automated checks were not run at the user’s explicit request. * fix(native): bound compiler shutdown and source-coordinate fixtures * docs: clarify historical native source verification * fix(native): preserve source attribution and compiler ownership * docs(native): qualify retained source attribution * fix(ci): clean up native Pascal verifier processes * test(native): type the Pascal verifier helper import after merging main Main now typechecks this boundary test, which imports the untyped canonical-temporary-directory helper and reads an unknown catch value. Add the helper's declaration file and narrow the caught error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(native): verify partial source attribution caveat * fix(native): retain verifier compiler cleanup ownership * fix(native): forward verifier cancellation and measure path bytes CLI and MCP artifact runs observe the verifier abort signal, and a failed Pascal verifier test stops the compiler group before deleting its directory. Repeated source locations grow by measured UTF-8 JSON bytes; workflow tokens, CPU and peak memory stay unmeasured. --------- Co-authored-by: Matheus Breguêz <matbrgz@gmail.com> Co-authored-by: Codex <noreply@openai.com> Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> |
||
|
|
c5301e6145 | feat(desktop): capture, draft, export and witness a task inside a build computer (#9045) | ||
|
|
ac23dc8077 |
feat(desktop): read XML with a plain DOCTYPE, and check an element's whole text (#9050)
* feat(desktop): read XML with a plain DOCTYPE, and check an element's whole text - Both readers accept a DOCTYPE with only a name and an optional PUBLIC or SYSTEM identifier, record it as the view's doctype, and never fetch the DTD or expand entities beyond XML's five; an internal subset, an external entity and a parameter entity stay refused alike. - text_equals and text_contains compare the concatenated text of the element (or text node or attribute) a pointer reaches, as XPath string() does, with optional normalize_whitespace; both evaluators agree, and a text check on a truncated element is undecided. - Whitespace-only text between elements is dropped only when the element holds no other text, so text split into runs keeps its spaces. - The draft suggests text_equals for an element whose text changed. So an AbiWord .abw reads as XML, and its paragraph's text is checked whole however AbiWord splits it into <c> runs, as Writer's spans are. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): draft whole-text checks on the paragraph, read only text as text, and skip asctime stamps - A changed value is read at both ends, so text that became a run still marks its paragraph, and the drafted text_equals moves up out of mixed content to the nearest ancestor named by an attribute, such as AbiWord's p by its xid. - Text checks accept only a text node or an attribute value; element names and doctype fields fail, in both evaluators. - isTimestamp also recognises asctime dates (Www Mmm dd hh:mm:ss yyyy). - XML files are drafted with the keyed diff the archive entries use, so no suggestion reaches an element by position; the shared logic moves to appTaskDraftNamed.ts. - Text-check tests assert facts, not whole sentences. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): keep checks on a changed attribute inside a paragraph whose text check replaces its runs' A drafted whole-text check on a paragraph hid every change inside it, so a link whose label and href both changed drafted only the paragraph's text and the new destination went unchecked. The text check now covers text and runs added or removed whole; a changed name or attribute of an element both versions hold keeps its own check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): read an attribute called name or attributes as an attribute when the draft keeps its check The owner of `.../attributes/name` was taken as `.../attributes`, so a changed `name` attribute inside a paragraph with a text check was dropped again. The owner is now read by segment, attributes first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): draft text checks from text in runs added whole, and name a text element by its own id before its container Text typed into a run the diff lists whole was never read, so the draft kept only a presence check on the run, which wrong text also passed. Such text now marks the nearest element both ends hold, or, when none can take the check, the added element's own text. The climb also names an element by an identifier of its own (id, xml:id, xid) before a larger container, so a headline under a long layer keeps a whole-text check that survives re-split runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): expect the whole-text check where #8988's pairing test meets text checks On this branch a changed element's text is drafted as `text_equals` on the element, so the identity pairing test now expects that check, under the same `[@role=body]` key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(desktop): keep checks for elements without text beside a text edit, and normalize DOCTYPE system id line endings A review found two gaps. - A paragraph's whole-text check covered every element added or removed inside it, including ones holding no text: an image frame, a line break. A solver who typed the text but never inserted the image passed. Such an element now keeps its own presence or absence check. - The Python reader kept a DOCTYPE system literal's CRLF where TypeScript normalizes it to LF. Both now report LF. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): import textSyntaxFormat once in the state format tests main's mixed-case JSON suffix fix and this branch both added the import, and the merge kept both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
f8356f3d71 |
fix(desktop): read the PPA key add-apt-repository writes into Signed-By (#8982)
* fix(desktop): read the PPA key add-apt-repository writes into Signed-By On Ubuntu 24.04, add-apt-repository puts the PPA's armored key inside the deb822 Signed-By field, and REA refused such repositories, so PPAs added the standard way could not be exported. REA now reads that key by deb822 rules, verifies the release with it through the same private gpgv keyring as key files, as the entry's only candidate (as apt does), retains it as armored and exports it as apt-keys/<name>.asc. A held key that does not verify is refused with a reason that names no URL. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(desktop): check the held-key refusal's facts, not its sentence The PPA refusal tests now assert that the reason names the sources file and the release file and no URL, and that export carries that reason, instead of comparing whole sentences. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
8580f1430c |
fix(desktop): launch spaced REA archives and Electron apps (#9085)
* fix(desktop): launch spaced REA archives and Electron apps Link the unpacked REA entrypoint to a fixed path so a top folder with spaces is not split by the generated rea launcher. When a build request marks the app as Electron, rewrite its installed desktop command with the export path's launch policy before gtk-launch. * fix(desktop): escape rewritten Exec values for desktop files Command quoting alone left literal backslashes one escape short of the desktop-entry value layer, so gio rejected the rewritten entry. Escape the command with the same rules parseDesktopEntry undoes before writing the Exec line. --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> |