Commit Graph
2027 Commits
Author SHA1 Message Date
131fbe0754 feat(environment): serve writes whose calls send different members (#7539)
* feat(environment): serve the writes callers make without recorded form fields

- A create member a recording sent empty ("", null, false, [] or {}) is no
  longer required; a call that leaves it out is applied as sending that value
  (body.blank).
- List views render envelope members that list the listed entities' ids
  (Paperless's `all`), so creates in such collections are confirmed.
- Updates move their entity in collections kept sorted by a field they write,
  and a failed whole-collection read after an update can teach that order.
- A later create that stores an unruled field otherwise is withheld at the
  create, and an item read may fill values a create's answer had not loaded.
- An unsent field respelled between null, [] and {} is unchanged.
- The skill asks for one create with every field and one with only what a
  person must give.

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

* docs(skill): show how to read signed-in pages before recording

Agents guessed capture keys (artifacts, dom, final) to see pages behind
sign-in, which inspect_web_page cannot reach.

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

* fix(environment): accept every empty spelling recorded creates sent

A create that fills only what a person must give sends `null` where the
full create sent a string, and `null` or `false` for the same flag. The
merged plan now accepts each recorded empty value, and a call that leaves
the member out is applied as the earliest call sent it.

Also adds the spec folder for this change.

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

* docs(skill): keep the vary-fields step neutral on UI or API writes

Agents read "the form" as a cue to write through the UI, where some
applications' request bodies are not exposed; a body-unusable UI write
now re-records once with request steps.

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

* docs(environment): record verification for blank members and sorted writes

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

* fix(environment): address review of blank members and sorted writes

- Bulk updates move their entities in turn against the others' earlier
  values and install the final order once, as replay does.
- A member's recorded empty values stay accepted once a later call teaches
  its default; a left-out member with a default keeps the default.
- Write answers spell empty lists and maps as their recorded answers did.
- A rename can teach a sort when the creates chose one by a field the
  update did not write, such as ids that ascend with titles.

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

* feat(environment): serve the writes that later reads explain

- An item read whose object is marked deleted (deleted, isDeleted or
  is_deleted true) agrees with an absent entity, as EspoCRM answers a
  deleted record; such an object never seeds or adopts an entity.
- maxSize, max_results and maxResults are page sizes, for whole-collection
  list lines and the list query's limit role.
- An item view also shows the fields only reads after its type's first write
  show, when no initial entity holds them (Vikunja's task subscription),
  without requiring them; write answers leave such a field out for entities
  without it, and it no longer withholds the write as incomplete-entities.
- The skill asks updates to change the fields a person would change, and
  expects a deleted object to read back as 404 or marked deleted.

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

* fix(environment): answer sent empty members as sent, and keep a placed create's order

- A write answer spells an empty list or map the call did not send as its
  recorded answer did; one the call sent is answered as sent, so a create
  sending `[]` is not answered `null` because the first recorded create was.
- A read listing the whole collection that placed a create leaves the create
  only the sorted inserts whose order that read follows, so a later rename
  cannot teach a sort an earlier read ruled out.

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

* fix(environment): answer bulk updates without fields only later reads show

A bulk update's answer renders each entity with the same allowance a single
update's answer has: a field only reads after the type's first write showed,
which no initial entity holds, is left out for an entity without it, so a
bulk update of a seeded task is no longer refused for lacking it.

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

* docs(environment): correct how the EspoCRM contact update task passes

The agent trajectories show gpt-oss passes it by creating a replacement contact
and deleting the original, since the served update refuses emailAddress; the
update itself is refused in both builds.

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

* fix(environment): answer a read of a served-deleted entity marked deleted

An application that soft-deletes still answers a deleted record by id, marked
deleted. Serving now keeps an entity a served delete removed from a type whose
recorded item reads show that, until a reset or load and within the size
data/add loads, and answers a read of it with its last fields and the flag
true, instead of refusing the read.

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

* fix(environment): keep unloaded create answers, check bulk answers with sent members, narrow inserts only on collection-order reads

- A create whose item read loaded values its answer had not records them
  (`observation.read.unloaded`), and a served create's answer keeps them as
  the recorded answer showed them, a zero-time owner included, while the state
  holds the read's.
- Replay checks a bulk update's recorded answers with each target's sent
  members, as serving answers them, so echoed `null` and `[]` no longer make
  the plan body-unusable.
- A whole-collection read whose query sorts it shows the query's order, so it
  no longer narrows a create's sorted insert candidates.

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

* docs(environment): record the census with main's unknown-clock rule merged

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

* feat(environment): serve query numbers, counted values and made objects

- A query parameter accepts a number or boolean, which serving sends as its
  JSON text, as agents send page sizes and flags.
- A sequence may start at the value its first create took above every value
  its type held (Vikunja's per-project task index), and a later create's
  composed, template or started-sequence rule is adopted when it also spells
  the first create's value.
- A made-object rule explains an object the application makes with each
  created entity: members the request stamped, members holding the entity's
  own id, and counts one past the held objects' values.
- A create's answer names the id of the one object a one-element array member
  holds, so bulk creates link to their type.
- The skill reads each listed object by id before writing.

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

* feat(environment): let a linked create take path values it stores

A create linked to its type's own collection, whose path has no parameters,
accepts any path values when its plan stores each one in a field, as a Vikunja
task stores its project; replay and serving apply it alike.

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

* fix(environment): learn a sort from a rename only when moving its entities reaches it

Serving moves only the entities a write changes in a collection kept sorted,
so replay now tries a sort after a rename only when the entities no write the
read exercised changed already follow it. Seeded folders listed out of title
order no longer teach a title sort that serving would answer with another
order.

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

* fix(environment): keep unloaded create answers a sent value did not echo, and learn no sort from query-sorted reads

- A served create keeps a value its recorded answer had not loaded unless the
  call sent that member and the plan stores it as sent, so a create sending
  `active: false` is answered `false` as recorded while the state holds the
  read's `true`.
- A rename no longer teaches a sort from a whole-collection read its query
  sorts, whose ties need not follow the collection's own order.

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

* docs(environment): verify query values, counted values and made objects

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

* fix(environment): learn the soft-delete flag in the state view and serve by it

Extraction now records the member later item reads set true on a record the
application soft-deleted, and the item view carries it as `deleted_flag`.
Serving reads that fact instead of scanning recorded bodies itself, so one
owner decides what a soft delete looks like.

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

* docs(environment): record the call-values checks at #7274 93821024

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

* fix(environment): learn the soft-delete flag from item reads with a query too

A client may read a deleted record back only with a query, such as a
cache-busting parameter. Every successful read of the item tool now shows the
flag; only plain later reads still add fields.

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

* docs(environment): record the call-values checks at #7274 45832406

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

* fix(environment): learn sorts only from orders a list read confirmed

- A sort retry after a failed whole-collection read requires the entities no
  write changed since a list last showed them to follow it already, rather than
  excusing every entity the update's tool ever wrote: an earlier rename a list
  confirmed in place stays where it was.
- An update takes its creates' sort only from a create a list read showed
  placed; replay still tries a sort a create guessed from the initial order.

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

* fix(environment): drop entities read back as deleted and answer soft deletes as deleted

- A held entity a later read shows marked deleted is dropped, not adopted with
  the marked object's fields.
- Bulk-update replay renders answers with the optional and later-only fields
  serving uses, so a bulk update of created and seeded entities replays.
- A served delete of a soft-deleting type answers with the entity marked
  deleted, single and bulk.
- A deleted flag only query reads showed is a field of the item view, so a
  served tombstone keeps it where live records omit it.

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

* fix(environment): check made objects as recorded and keep their ids and clocks honest

- A made object's clock counts as a write clock, so a capture with no clock
  anchor withholds the create instead of stamping 1970.
- Members holding the entity's identity follow the id written, generated or
  sent, through the type's id field.
- A later create's made object is checked as recorded, before its own members
  are rewritten, so one naming another entity withholds the plan.
- A later create's template is adopted only when it spells that create's value
  too, not just when the first create's text holds its source value.

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

* fix(environment): move updated entities only by placed sorts and keep query-sorted reads from confirming order

Replay moved an updated entity by a sort a create only guessed, while the
update plan exported only placed sorts, so a read could confirm an update
by a move serving would not make. Both now use the placed sort. A passing
list read clears its entities from the moved set only when the state
decides the order of every entity it lists, so a read whose query sorts
it no longer hides an earlier move from a later sort check.

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

* docs(environment): count six withheld plans that explain more, not seven

The bulk task create counted among them is served on this branch.

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

* fix(environment): try a learned sort by moving each pending write in turn, as serving does

#retrySort sorted the whole collection, which a list could match while
serving, moving each renamed entity in turn against the others' values
before their own writes, gave another order. The state now records the
values each write replaced, and the retry replays the writes since a
list in collection order last showed their entities.

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

* fix(environment): answer a served delete with the deleted flag its recorded answer showed

An application may answer a delete with the record as it was and mark it
deleted only on later reads. Delete answers, single and bulk, now take
the flag's value from the recorded answer; reads of a served-deleted
entity still show it marked deleted.

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

* chore(environment): set aside two hunks next to lines main's saved-values change rewrites

Main's #7267 changes the lines beside the blank-member docs and the
empty-spelling check in explainUpdate. Setting them aside lets that merge
apply cleanly; the commit after it puts them back on top of main's text.

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

* chore(environment): restore the set-aside hunks on main and bump the skill to 51

Puts the blank-member docs and the empty-spelling check back beside main's
slug and composed text and heldSlugRule. Main is at skill 50 with
different text, so this branch's skill changes take 51.

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

* chore(environment): bump the skill to 52 above #7260's 51

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

* chore(environment): put back the call-values hunks main's merge took its side for, and bump the skill to 53

The merge of main kept main's side where it overlapped this branch, so it
could commit without a conflict. This restores this branch's side next to
main's: made-object agreement beside the & slug spellings, sequence starts
in the earlier evidence (now built by earlierOf), the combined value
imports, and recording step 2 beside main's UI-first step 3. Main is at
skill 50 and #7274 at 52, so this branch takes 53.

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

* fix(environment): keep sorts a list showed in place ruled out, and created answers' nested members as recorded

A whole list in collection order that showed a renamed entity where a
sort by the renamed field would have moved it now rules that sort out, so
a later rename of the same entity cannot teach it. A create's answer
leaves out members its item read added inside an object the answer
showed, as the recorded answer did; the state still stores them.

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

* feat(environment): serve writes whose calls send different members

Recordings now vary what a type's two creates and updates send, and REA
withheld writes where a later call left out what the first sent. An update
plan's required members narrow to those every call sent; a member one create
sent and another left for the application to number is a sequence that
takes the value a call sends; a PUT's left-out member the application
cleared becomes that member's default; and an update's clock is held as
the read after it spells it. The skill spaces creates (skill 54).

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

* fix(environment): keep a later create's made object only with clocks its request stamped

followsMadeObjects only checked that a made object's clocks parsed, so a
later create whose object showed an older clock still passed, while serving
stamps the write's clock. Its clocks must now be in the rule's format and
within the stamp window of that create's request.

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

* fix(environment): accept sent values either way, check defaults against every call, and store update clocks as reads spell them

A sequence that takes sent values now accepts one a later create sent
after the first left the member to be numbered. A default an update learned
must agree with every update that left its member out, else the plan is
withheld. An update plan whose read-back spells a stamped clock at a coarser
precision keeps that read as observation.read, and serving stores the
update's clocks in its spelling while answers keep the response's.

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

* fix(environment): check recorded member and sequence values

* fix(environment): compare soft-deleted read fields

* fix(environment): reject contradictory learned sequences

* fix(environment): preserve initially deleted item observations

* fix(environment): index stored deleted entities separately

* fix(environment): replay lists that include deleted records

* fix(environment): count a sequence number a create sends, as replay does

Serving now records a number a call sends for a `sequence` with `sent` in the
same count history it generates from, so after that entity is deleted the next
generated number still follows it, as replay's takeSequences does.

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

* fix(environment): make no count of a made-object member earlier creates held alike

A count only a later create shows starts at the exemplar's value, which is
right only while the exemplar is the one create accepted: creates accepted
after it showed the member unchanged, which a count would have moved. The
merge now refuses such a count, as the top-level sequence check does.

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

* fix(environment): check PUT defaults against reads, and respell update clocks by serving's rule

A default a PUT learns must also agree with what the read after an earlier or
the current call showed for the member its answer left out, so a call whose
read showed the member kept withholds a later clearing default.

Replay and serving now choose an update clock's stored spelling by one rule,
readSpellsCoarser: the read after it at a coarser precision in the same zone
and separator. A read in another zone or separator is no longer adopted by
replay, which serving could not store, and a create's plain clocks stay as
answered, as serving makes them.

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

* fix(environment): keep the largest sequence value in replay, and store update clocks by the kept read

Replay now keeps the largest value a sequence took, as serving's commitWrite
does, so a lower sent value no longer lowers the next number.

Serving stores every update's clocks in the spelling of the read the plan
keeps as observation.read; replay now does the same through
readSpelledClocks, instead of adopting each update's own read, so a later
update whose read spells its clock otherwise contradicts the plan. The plain
clock branch of restampedFields, which no caller used any more, is gone.

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

* fix(environment): keep a left-out default from numbering, a read's sub-millisecond digits, and references named by member

A member a call left out and the application stored a fixed value for is no
longer turned into a numbered sequence by a later call that left it out.
Serving shortens an update's clock to the read's precision from the answer's
own digits, keeping microseconds. A PUT that names a reference field's entity
by its member supplies that field, for the default check and in serving.

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

* fix(environment): count a reference a later PUT names toward the default an earlier one cleared

The default check now reads the reference rules the current call shows as
well as the plan's, so a PUT naming the owner by ownerId after one that
cleared it is served, as in the other order.

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

* fix(environment): number a left-out member past every sent value, and never fill it with a sent blank

A later create the application numbered at or below a value an earlier create
sent no longer turns the echo into a numbered sequence, since serving counts
past every sent value. A member a numbered sequence covers is not filled with
an empty value another call sent when a call leaves it out.

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

* fix(environment): count sent values in the sequence's scope before numbering a left-out member

The largest value earlier creates sent is kept by type and by collection, and
a collection-scoped sequence adopted later checks only its own collection, so
a number sent in another collection no longer withholds a create numbered
within its own.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-29 16:14:05 +08:00
f7cd4e5256 fix(adb): validate screen capture PNG headers (#7962)
* fix(adb): validate screen capture PNG headers

* fix(adb): state screen header validation limits

* style(adb): format screen capture assertion

Match the current formatter after integrating main.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-29 16:04:49 +08:00
gensokyo-dev e3d8d20236 fix(native): preserve dispatch metadata format refusals (#8013)
* fix(native): preserve dispatch metadata format refusals

* test(native): normalize CLI format refusal envelopes

* test(native): assert admitted metadata target paths
2026-10-29 15:48:42 +08:00
17ceb77ca5 fix(mcp): preserve input validation issue attribution (#7981)
* fix(mcp): preserve input validation issue attribution

* fix(mcp): charge nested issue projection before allocation

* style(mcp): format server declarations

* fix(mcp): avoid duplicate fallback diagnostics

* test(mcp): assert structured validation issues

* test(mcp): align browser input issue assertions

* fix(mcp): retain SDK diagnostic parts once

* style(mcp): format diagnostic projection

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-29 15:39:10 +08:00
Dragolone 124e97eac5 fix(native): explain categories whose class reference names no class (#8006)
An Objective-C category whose class field is null, or is bound to a
symbol other than `_OBJC_CLASS_$_`, was recorded as partial with
`category_class_unresolved`, but no issue was raised, so the
`objc_properties_categories` coverage facet reported `partial` with a
null reason. swiftc emits such categories for @objc members of an
extension on another module's Swift class and binds the class field to
the class metadata symbol (`_$s…CN`); Keynote and Notability carry them.

Report the reference as a `category_class_unresolved` issue naming the
bound symbol, or stating that the reference is null, matching the issue
already raised for an unreadable local class reference.
2026-10-29 15:14:10 +08:00
Dragolone 95637a3d70 fix(artifacts): name every U-Boot uImage type in the pinned image.h (#8007)
TYPE_NAMES stopped at flat_dt (8), while the U-Boot include/image.h
commit that the tables are pinned to defines image types 0-47. A header
declaring a later type, such as kernel_noload (14) or tfa-bl31 (45),
was reported with type_name "unknown".

Add types 9-47 with their mkimage -T short names from boot/image.c at
the same commit. IH_TYPE_LOADABLE (22) has no short name there and is
named "loadable", as other tables already name identifiers U-Boot does
not list. Identifiers past the enum stay "unknown".
2026-10-29 15:13:37 +08:00
LN Bodicherlaandgensokyo-dev c9bf6a9df7 feat(managed)!: show readable type names in member signatures (#5309)
feat(managed): show readable type names in member signatures

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-29 14:34:42 +08:00
gensokyo-dev f60e42a9ae fix(mcp)!: bound validation work before tool dispatch (#7905)
Reuse the pinned SDK's combined array-element and object-member admission
before canonical validation, deferred runtime loading and tool execution.
Share a configurable finite allowance across eager/deferred HTTP and stdio,
and project refusals to bounded, actionable transport resource errors.

Preserve canonical CLI/application contracts, caller-selected input values,
ordinary validation semantics and complete Evidence access. Exercise actual
transport boundaries, real artifact/TShark workflows, packaged installation,
continued service and downstream identity/capacity regressions.

Fixes #7882

BREAKING CHANGE: MCP tool arguments now default to 1,024 combined array
elements and object members per call. Select a larger positive finite
REA_MCP_MAX_INPUT_ELEMENTS allowance and restart for larger inline inputs,
or use retained/file selectors where supported. Inputs are never truncated.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
2026-10-29 05:56:38 +00:00
gensokyo-dev b966ebeb22 docs(readme): align Linux x64 analysis prerequisites (#7997) 2026-10-29 13:44:07 +08:00
d39b3000ec feat(artifacts): inventory and extract U-Boot FIT images (#7771)
* feat(artifacts): inventory and extract U-Boot FIT images

open_binary refused U-Boot Flattened Image Tree files as an unsupported
format, so inspect_artifact and extract_artifact could not list or
recover a FIT's kernel, devicetree, ramdisk and loadable images.

Recognize an FDT v16/v17 with a top-level /images node and parse it with
the existing parseDevicetree. Each /images child becomes an inventory
entry named images/<unit-name>.bin that extracts its stored bytes from
embedded data, data-offset (past the 4-aligned devicetree end) or
data-position (from the file start). Image format_metadata records the
declared type, arch, os, compression, load and entry; root metadata
records the description, timestamp and configurations.

crc32, md5, sha1, sha256, sha384 and sha512 hash nodes are verified in
one streamed pass per image; other algorithms are reported unverified.
Signatures are reported, not verified, and nothing is decompressed,
decrypted or executed. Data outside the file, overlapping or duplicate
image data, a missing or repeated data source and hash mismatches fail
closed. The devicetree is bounded by the fixed 16 MiB allowance;
external image data is streamed from disk.

Refs #7129

* fix(artifacts): bound FIT configuration references and suggest analysis only for plain images

* fix(artifacts): retain buffered FIT stream cancellation

* test(artifacts): gate FIT faults on the observed read phase

* fix(artifacts): verify FIT links and summary identities

* fix(artifacts): bound FIT diagnostics and retain unknown signatures

* fix(artifacts): compare FIT declarations and resolved data links

* fix(artifacts): admit FIT raw probes through the shared loader contract

* fix(artifacts): preserve FIT field availability independently

* fix(artifacts): isolate nested entry metadata from reader facts

---------

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: gensokyo-dev <342580529+users.noreply.github.com>
2026-10-29 13:33:26 +08:00
gensokyo-dev 50b2ab137f fix(browser): preserve DOM length units in captures and comparisons (#7971)
* fix(browser): declare DOM node value length units

* fix(browser): preserve unknown DOM length comparisons
2026-10-29 11:27:01 +08:00
gensokyo-dev cf9f010dcd feat(managed): filter and project retained member views (#7968)
* feat(managed): filter and project retained member views

* test(managed): guard relationship endpoint filter semantics
2026-10-29 10:39:34 +08:00
morluto 3dcb40dc26 fix(uninstall): protect ZCode fallback registrations (#7970)
fix(uninstall): preserve inactive ZCode fallback servers
2026-10-29 10:05:35 +08:00
morluto 7b9bcf724f style: fix native documentation and test formatting 2026-10-29 10:02:22 +08:00
gensokyo-dev 7ca216a266 fix(docs): restore translated offline provider ownership notes (#7964) 2026-10-29 09:38:51 +08:00
morluto 33d6975749 fix(certificates)!: disclose undecoded unsigned attributes (#7920)
* fix(certificates): disclose undecoded unsigned attributes

* test(certificates): use parser-owned limitation text
2026-10-29 08:56:07 +08:00
morluto 640e19d79d fix(native)!: own Mach-O load commands in binary reader (#7952)
* fix(native): retain selected Mach-O slice identity

* fix(native)!: own Mach-O load commands in binary reader

* fix(native): preserve malformed Mach-O and image base limits

* fix(native): preserve leading BOM in Mach-O names

* test(native): update Mach-O provenance verification

* fix(native): retain completed Mach-O inspection on cleanup failure

* fix: bound Mach-O projected section output

* fix(native): own retained Mach-O command bytes

* fix(native): retain Mach-O outcomes on final cancellation

* fix(cli): preserve caller path in partial evidence

* fix: reserve Mach-O projection envelope budget
2026-10-29 08:37:36 +08:00
Ha1baraA1 a965cbab06 fix(ghidra): omit duplicate load-image result (#7777)
* fix(ghidra): omit duplicate load-image result

* docs(mcp): describe load-image evidence projection
2026-10-29 08:23:38 +08:00
64d282b0a6 fix(process): normalize descendants of slash-spelled directory roots (#7803)
* fix(process): normalize descendants of slash-spelled directory roots

A working directory or observation path ending in / or /. kept its
trailing separator as the alias, so descendant paths never met the
delimiter lookahead and stayed literal. Strip those spellings before
building aliases and version the path normalization contract as v3.

Fixes #7584

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

* fix(process): normalize filesystem root descendants

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-29 08:23:19 +08:00
morluto 3a512303d9 fix(cli)!: refuse lossy text output (#7852)
* fix(cli)!: refuse lossy text output

* fix(cli): retain failure identity on text refusal

* fix(cli): check failed TOON token windows

* test(cli): bound keyed archive case duration
2026-10-29 08:09:49 +08:00
morluto 794907fa3d fix(javascript): trace boundary results to assigned bindings (#7912) 2026-10-29 07:58:57 +08:00
morluto 0179d94420 fix(browser): disclose opaque redirect coverage gaps (#7943) 2026-10-29 07:57:00 +08:00
morluto 844bb46351 fix(javascript): retain Electron switch conditions (#7910)
* fix(javascript): retain Electron switch conditions

* fix(javascript): bound switch path traversal
2026-10-29 07:56:15 +08:00
morluto 086abf3996 fix(javascript): distinguish bundled script locations (#7909) 2026-10-29 07:56:06 +08:00
morluto 66f5b650d9 fix(apk): explain unknown signer comparison (#7927) 2026-10-29 07:53:38 +08:00
morlutoandgreptile-apps[bot] 1631dcb09a docs: include Kuna in native provider guidance (#7929)
* docs: include Kuna in native provider guidance

* docs(i18n): include Kuna in native provider guidance

* docs: align provider guide links

* Update README.md

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* docs: align provider links and translated formatting

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-10-29 07:53:28 +08:00
ShuaixinHuangandmorluto fc24b08851 feat(artifacts): read Zstandard ZIP members (#7780)
* feat(artifacts): read Zstandard-compressed ZIP members

* fix(artifacts): classify ZIP dictionary failures

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-29 07:44:10 +08:00
PARK HYEONMIN (박현민) b4923f85c5 docs(ghidra): count 27 read-only operations in current guides (#7794)
The inventory registry gained read_binary_inventory_summary, so the
read-only inventory is fifteen inventory and twelve function operations.
Update the adapter summary and the Windows lane descriptions to match the
registries the Windows verifier derives its coverage from. The historical
Windows verification record keeps its observed 26-operation count.

Fixes #7611
2026-10-29 07:38:33 +08:00
RRFZandmorluto 8c83886891 fix(pe): report exhausted certificate decoder allowances as resource limits (#7881)
* fix(pe): report exhausted certificate decoder allowances as resource limits

A PKCS#7 payload that exhausted the fixed 64 KiB decoded-text or 16,384-value ASN.1 allowance was refused as malformed input with advice to correct request fields. Keep the allowance and limit on the decoder failure and report it as a nonretryable resource_constraint with fixed-allowance recovery.

Fixes #7531

* test(pe): cover certificate allowances through MCP

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-29 07:36:56 +08:00
morluto 1e088c19ad fix(environment)!: report recorded reads and target uncertainty (#7834)
* fix(environment)!: report recorded reads and target uncertainty

BREAKING CHANGE: Environment state and coverage can report method-replay for non-GET safe reads; exhaustive reason consumers must handle it.

* docs(environment): include safe-method replay reason
2026-10-29 05:09:31 +08:00
morluto 6c76a7ffb0 fix(wasm): retain core facts with invalid custom names (#7822)
* fix(wasm): retain core facts with invalid custom names

* fix(wasm): retain objdump output on parse failure
2026-10-29 05:08:41 +08:00
morluto 2aa0d45e13 fix(mcp): guide oversized unknown recovery (#7876) 2026-10-29 05:07:35 +08:00
morluto bd687bbc40 fix(ghidra)!: distinguish unlisted instruction addresses (#7823)
* fix(ghidra)!: distinguish unlisted instruction addresses

BREAKING CHANGE: Ghidra now returns not-in-listing for in-memory addresses without listed instructions or defined data. Consumers matching the former undecodable value must handle the new status.

* fix(ghidra): invalidate snapshots with old instruction status

* test(ghidra): update raw profile commitment goldens
2026-10-29 04:59:04 +08:00
morluto 46c457f74c docs(ghidra): fix DOL guide PowerPC link (#7857) 2026-10-29 04:57:59 +08:00
gensokyo-devandEntrpi 37827af591 feat(artifacts): compare inventories from Evidence sources (#7869)
* feat(artifacts): compare artifacts by Evidence reference and from the CLI

compare_artifacts made agents send back the complete inventory Evidence
that REA already retains, and the CLI had no artifact comparison.

Each side of compare_artifacts now takes exactly one of: complete inline
Evidence (unchanged), {kind: "retained-evidence", evidence_id}, or
{kind: "evidence-file", path, evidence_id?}. The two references are the
sources inspect_analysis_view accepts; both tools now compose one
definition in evidenceReference.ts. A summary still resolves to its exact
retained parent, and every source form gives the same comparison Evidence.
An unresolvable retained reference is refused with a typed missing
reference error.

The application layer owns source resolution and the comparison Evidence,
so MCP and the new `rea compare-artifacts` command share one workflow.
readEvidenceFileSource reports bundle-selection refusals at the caller's
own field path.

* refactor(artifacts): resolve compare_artifacts sides like compare_functions

compare_functions, compare_wasm_interfaces and the JavaScript application
comparisons name each side with evidenceInputSchema and resolve it with
resolvePairedEvidenceRequest. compare_artifacts reached the same result
for inline and retained sides through its own dispatch.

evidenceSourceInputSchema now extends evidenceInputSchema with the
Evidence-file reference, and resolvePairedEvidenceSources sends inline and
retained sides to the same resolveEvidenceInput and file sides to the
shared Evidence file reader. compare_artifacts uses both, so the forms it
shares with compare_functions are parsed and resolved by one owner. The
advertised input schema is unchanged.

* docs(cli): point rea compare to compare-artifacts for inventory contents

rea compare (compare_bundles) compares records by Evidence identity and
explicit pairs and never reads artifact contents, so two build
inventories stay unresolved there. Its help and the CLI guide now name
compare-artifacts for that comparison.

* fix(artifacts): resolve summary parents within Evidence source bundles

* perf(evidence): reuse file-owned immutable authentication proofs

* test(evidence): inject failures at both authentication boundaries

---------

Co-authored-by: Entrpi <entrpi@proton.me>
2026-10-29 03:12:03 +08:00
gensokyo-dev 2f3c71f39e docs(errors): align byte entropy recovery catalog (#7884) 2026-10-29 03:03:04 +08:00
gensokyo-dev 8f9af920ef fix(pcap): redact HTTP credentials in failed capture diagnostics (#7871)
Project bounded JSON diagnostics using shared URI roles and source spans.
Keep complete parser input unchanged and compute safe diagnostics lazily.
Preserve byte facts, error classification, path data and cleanup ownership.
Reuse JSON escape-coordinate mapping with IDA diagnostics.

Fixes #7812

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
2026-10-28 18:14:22 +00:00
gensokyo-dev 4b0ff68e2e fix(browser): retain prior-hop response facts in session timelines (#7807)
* fix(browser): retain prior-hop response facts in session timelines

* fix(browser): share response URL classification

* fix(browser): preserve malformed response status failures

* fix(browser): account for filtered redirect response coverage

* test(browser): supply prior response URLs in redirect fixtures

* fix(browser): retain malformed orphan response status coverage
2026-10-29 02:04:15 +08:00
Dragolone f19436c156 fix(artifacts): split U-Boot script uImages on their size table (#7805)
U-Boot's mkimage writes the multi-file size table for script images
(`mkimage -T script`, the boot.scr format) exactly as it does for multi
images, `mkimage -l` lists the script as "Image 0", and the `source`
command skips the table before running the script ("scripts are just
multi-image files with one component", boot/image-board.c).

The uImage reader parsed the table only for IH_TYPE_MULTI, so a script
image reported sub_image_count 0 and exposed only payload.bin, whose
first bytes are the binary size table rather than the script text.

Treat IH_TYPE_SCRIPT like IH_TYPE_MULTI: parse the same bounded table,
expose image-<n>.bin components and report the size-table limitation.
payload.bin is unchanged. A script payload without a valid table now
fails closed, as a multi image already does.
2026-10-29 01:57:09 +08:00
morluto 0747e46401 fix(cli): recognize integrity failures with partial observations (#7836) 2026-10-29 01:55:57 +08:00
morluto 183e2e2d1e fix(il2cpp): validate structural record extents (#7861) 2026-10-29 01:55:47 +08:00
morluto aaf4d21068 fix(source-map): clarify policy and evidence provenance (#7828) 2026-10-29 01:29:59 +08:00
morluto 60ab4da329 fix(cli): correct completion options and setup guidance (#7851)
* fix(cli): align MCP doctor completion with its options

* fix(cli): explain zsh completion initialization

* fix(cli): include launcher timing in doctor completion

* style(cli): format doctor completion schema
2026-10-29 01:28:04 +08:00
morluto f9e7571a3d feat(javascript): discover semantic call literals in feature traces (#7840)
* feat(javascript): discover semantic call literals in feature traces

* fix(javascript): bound retained call literals by transfer capacity

* test(javascript): align feature no-match diagnostic
2026-10-29 01:25:23 +08:00
morluto 4109271bcb fix(process)!: reject unsupported one-column terminals (#7848)
* fix(process)!: reject unsupported one-column terminals

* test(process): exercise actual two-column resize
2026-10-29 01:23:02 +08:00
morluto af1ccb6506 fix(android): preserve manifest component spelling (#7818) 2026-10-29 01:10:45 +08:00
Entrpiandgensokyo-dev 64196b08ca feat(artifacts): inventory and extract ESP32 firmware images (#7498)
* feat(artifacts): inventory and extract ESP32 firmware images

ESP32-family app and bootloader images (magic 0xE9) had no reader, so
open_binary refused OTA downloads, app partitions and bootloaders.

Add the esp-image container format behind inspect_artifact and
extract_artifact. A pure decoder reads each byte once and keeps only
fixed-size fields. Derived facts cover the chip, from a table cited to
ESP-IDF v6.1; segment classification as ESP-IDF's should_map and
should_load; checksum and appended SHA-256 results; app and bootloader
descriptors; Secure Boot v2 signature blocks, observed and unverified;
and undescribed trailing byte ranges. Truncation and undescribed bytes
make coverage unknown. ESP8266 images are refused with a specific
reason, and ciphertext stays unrecognized.

Add the format to every target, Evidence, snapshot, live-summary and
artifact vocabulary, document it, and add an optional verify:esp-images
lane that compares esptool-built images with esptool image-info and
espsecure signature-info-v2.

Refs #3615

* test(artifacts): run the ESP image lane on esptool v5.6.0

The lane compared descriptor fields only when esptool image-info printed
one, so a descriptor that REA reports and esptool does not print passed
without comparison. Compare the descriptor kind in both directions.

Record that the lane passed for all 13 images with esptool and espsecure
v5.6.0, the version the layout facts cite, as well as with 4.12.0.

* refactor(artifacts): define ESP image layout sizes once

The decoder and the derived facts each defined the segment-header,
appended-digest and flash-sector sizes, the erased-byte scan and the
offset formatter. Define them once with the other fixed-layout structures
and import them in both places. The signature slot count is the one
constant that drives the slot scan.

Correct the observedEnd comment: it is the end of the last chunk read.

* fix(artifacts): report ESP-IDF's segment length limit by chip

ESP-IDF's verify_segment_header rejects a segment of 16 MiB or more
unless the chip maps flash through 32-bit cache addresses
(SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP: ESP32-S3, P4, C5, C61, H4 and
S31 in v6.1). Record that capability in the chip table and add a
limitation for such segments; unknown chips get none.

`loaded` repeats should_load. It does not mean the bootloader accepts the
segment: verify_load_addresses still rejects one outside the chip's RAM,
which REA does not model. Say so in the docs, the skill reference and the
inventory limitation.

* test(artifacts): check ESP lane tools first and verify extraction

The lane started work before checking its tools, so a missing RISC-V
target, ld.lld, esptool or espsecure surfaced as a raw spawn or command
error. Check each one before building and name the variable to set. Warn
when esptool is not v5.6.0, the release the layout facts cite.

Assert each segment's class for the ESP32-C3 app, its variants and the
bootloader, as the Xtensa image already did. Extract the app and the
signed image through the CLI and compare every file with the bytes at
esptool's segment offsets or in the appended signature sector; the
source's SHA-256 must be unchanged and equal the reported root_sha256.

* docs(artifacts): state what the ESP image lane does not establish

The Verification section listed the lane's checks but not its gaps: only
ESP32-C3 and ESP32 images come from a real producer, no real project
build, OTA download or flash dump is inspected, no signature is verified,
and the lane does not run in CI.

Record the timing of the final lane run on esptool v5.6.0.

* fix(artifacts): compare ESP segment declarations

Segment entries hash only their data, so compare_artifacts reported a
segment that moved to another load address with the same bytes as
unchanged; only the image itself changed. Compare each segment's
load_addr and data_len as its declaration, as Node SEA and PyInstaller
members are compared, and count a changed declaration as a metadata
change, also when content is unavailable.

Header offsets are layout and the classification is derived, so neither
is compared.

* test(artifacts): run ESP lane commands as owned process trees

The lane ran its tools through execFile. A timeout killed only the direct
child, so a linker or assembler that Clang or GCC had started could keep
running while the lane removed its workspace. Run every command through
createVerifierCommands, check the tools inside withVerifierCleanup, and
remove the workspace only after commands.close() has stopped every tree;
a failed close keeps the workspace.

Only a nonzero exit now counts as a refusal or an expected esptool
failure; timeouts and spawn failures propagate. Supervising each command
roughly doubles the lane's run time.

* test(artifacts): cancel ESP decoding after its first decoded chunk

The cancellation test requested cancel or close on setImmediate, which
can land while the file is still being opened and checked, so it never
showed that decoding had started. It also passed against a reader that
ignored both requests while decoding. Acknowledge the decoder's first
chunk, then cancel or close, join the operation, and assert that no
later chunk reaches the decoder and that the reader ends closed.

* docs(artifacts): record which ESP metadata comparison ignores

Segments are compared by their declaration. The image's and the
signature blocks' format_metadata are not: every field comes from their
own bytes, which content comparison already covers, and a block's
image_digest_matches follows the image's content.

* docs(artifacts): state that ESP mmu_page_size is a base-2 logarithm

The app descriptor's mmu_page_size keeps ESP-IDF's name and value, the
MMU page size in log base 2 as esp_app_desc_t declares it, so 16 means
64 KiB. Say so in docs/esp-image.md and the schema comment; a reader
could otherwise take 16 as 16 KiB.

* fix(esp-image): retain member consumption and share lifecycle regressions

* test(artifacts): scope MCP catalogs and budget full-schema validation

* test(artifacts): verify compact output profiles and document bounded catalogs

* test(artifacts): close readers when cleanup-test admission fails

* test(artifacts): compare ESP image limitations with their owners

The decoder and reader tests froze complete limitation sentences, so a
harmless rewording failed them. The wording now has two owners:
ESP_IMAGE_LIMITATIONS in espImageFacts.ts, which the decoder, the inventory
and the reader use, and ESP_DESCRIPTOR_LIMITATIONS beside the descriptor
decoder. Tests compare delivered limitations with the owner, called with the
facts each case establishes (segment index, declared and available bytes,
offsets, chip, page range), next to the structured assertions they already
make. Delivered text is unchanged.

* test(esp-image): assert structured facts and owned guidance

* fix(esp-image): keep spi_flash_mode and descriptor fields before a truncated tail

ESP-IDF v6.1's esp_app_desc_t declares spi_flash_mode at byte 181, after
mmu_page_size, as the committed reference layout shows; the descriptor now
keeps it as stored. The decoder also required all 256 descriptor bytes,
though it reads none past byte 181, so a file ending in the reserved tail
lost the version, project, digest and revision facts it does hold. The app
descriptor now needs only its fields; the segment's truncation is reported
as before.

* test(esp-image): pin the P-192 public key digest to espsecure's layout

espsecure packs ECDSA signature blocks as "<BBBx32sB64s64s1031x" and
zero-pads a 48-byte P-192 point to 64 bytes, so the signature starts at
byte 101 for every SHA-256 curve. signature_info_v2 hashes sig_block[36:101]
and _digest_sbv2_public_key the curve ID with the padded point. No test built
a P-192 block; this one checks public_key_sha256 against that definition.

* fix(esp-image): keep each app descriptor field the file holds in full

A file can end anywhere inside the 256-byte esp_app_desc_t. The decoder
needed every field byte, so a cut at byte 176 dropped the version, project
and app_elf_sha256 it does hold. Once the 4-byte magic identifies an app
descriptor, each field is now kept when the file holds all of its bytes and
is null otherwise; observed_length records where the descriptor ends, so a
cut field is told apart from text that is not UTF-8. The fields after the
magic become nullable in the metadata schema.

* fix(esp-image): report a signature block whose image digest does not match

A CRC-valid Secure Boot v2 block can carry another image's digest. The
block recorded image_digest_matches false, but no limitation said so, unlike
a checksum or appended-SHA mismatch, so CLI and MCP summaries showed only
the generic unverified note. The mismatch is now a limitation; coverage
stays complete and signature_status stays unverified. The three other
signature-sector limitations move into ESP_IMAGE_LIMITATIONS with their
text unchanged, so all ESP image wording has one owner.

* refactor(esp-image): remove redundant descriptor byte guards

---------

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-28 23:18:22 +08:00
gensokyo-dev 6c895eeb8e fix(process)!: redact sensitive terminal echoes before retaining Evidence (#7804)
Seal sensitive terminal chunks before deferred rendering, apply one bounded
capture-local literal matcher, and retain exact redacted byte accounting.
Keep private input facts in explicit fields and separate comparison policies.
Retain distinct terminal failures once and verify structured refusal facts.

Fixes #7782

BREAKING CHANGE: sensitive interaction data is empty with sensitive and input_bytes fields instead of a byte-count placeholder. Sensitive raw_data is also redacted. Read input_bytes and recapture both comparison sides when migrating older private-input Evidence.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
2026-10-28 14:39:34 +00:00
Dragolone 6fd5d347c7 fix(browser): ignore repeated CSP directives within one policy (#7798)
CSP3 parsing keeps the first directive of each name in a policy and ignores
later repeats; Chrome reports "Ignoring duplicate Content-Security-Policy
directive". parseCsp flattened every policy's directives into one stream, so
a header such as `script-src 'self'; script-src 'unsafe-inline'` reported the
ignored `'unsafe-inline'` directive as declared and counted nonces and hashes
from it. Track directive names per policy so only the effective directive is
retained, while the same name in separate comma-separated or repeated-field
policies is still listed once per policy.
2026-10-28 22:23:00 +08:00
Ysopwnableandgensokyo-dev 7b6d872a25 docs: celebrate 400,000 GitHub stars 🎉 (#7801)
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-28 22:12:43 +08:00