Skip to content

feat(audit): report what a shipped app exposes to static analysis - #8525

Open
mvanhorn wants to merge 172 commits into
morluto:mainfrom
mvanhorn:fix/release-exposure-audit
Open

mvanhorn wants to merge 172 commits into
morluto:mainfrom
mvanhorn:fix/release-exposure-audit

Conversation

@mvanhorn

@mvanhorn mvanhorn commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

REA shows what can be recovered from a shipped application, but a developer who wants that answer for their own release has to run many tools and combine the results by hand.

This adds audit_release_exposure and rea audit-release-exposure. It reads one .app, install directory, ASAR or executable through existing readers and reports what static analysis recovers. --fail_on high, medium or low exits 3 on a matching exposed check, so it can gate a release in CI. It never runs or rewrites the artifact. It is an audit only, with no obfuscation or active protection. No issue is linked. This is a proposed new read-only tool.

Problem and expected behavior

Use case: a team about to ship an Electron app, Go binary or packaged executable wants to know whether source maps, debug companions, build paths or credential-shaped strings went out with it, and whether Electron fuses are set.

Observable outcome:

  • Fifteen named checks return exposed, not_observed, not_applicable, unknown or not_assessed, each with severity, locations and remediation.
  • There is no pass verdict, score or grade. The report says it does not establish that an application is secure, and unknown counts stay beside the findings.
  • A credential check reports the rule and location only. Matched bytes, previews, lengths and hashes are omitted. Source map text is counted and dropped.
  • Without --fail_on, the exit status reflects only whether the audit finished.

Change and scope

src/domain/releaseExposure.ts owns the report and allowances, src/artifacts/ReleaseExposureReader.ts owns the bounded scan, and src/application/releaseExposure/ReleaseExposureService.ts composes existing owners. Electron fuses, Go, Rust, and artifact inventory are reused rather than reimplemented.

A few changes reach existing owners:

  • inventoryArtifact gains optional acquisitionLimits. Only this audit sets them, at 65,536 entries and 2 GiB of hashed bytes. Exhausting one keeps a partial inventory with unknown coverage. Other callers are unchanged.
  • src/domain/binaryTarget.ts adds inspectPeCodeViewFromBuffer, which separates absent CodeView records from incomplete parsing. parsePeCodeViewFromBuffer keeps its behavior on top of it.
  • src/artifacts/inventory/classify.ts exports classifyEmbeddedExecutablePackage, so the audit recognizes a packaged executable with the same probes as inventory.

The audit is written to fail toward unknown: unresolved or oversized source maps stay undecided rather than becoming linker maps, incomplete Go metadata stays unknown, and a skipped PE stays unknown. Same-name package members are each scanned, and inline data: source maps in JavaScript are examined.

Audits use record-and-continue for declared integrity, because signing an unpacked native module after packaging is routine. A real Electron app failed the audit outright before this.

Further unknown-preserving behavior:

  • A file with an unrecognized name, such as .env.production, is probed from its first 4 KiB and scanned as text when it has no NUL bytes. UTF-16 files without a recognized name are not detected.
  • A fuse check needs every slice and sentinel to decide. An undecided slice adds unknown, and exposed still wins.
  • go.build_paths reads paths from CGO_*FLAGS, -ldflags, -gcflags and -asmflags. Quoted and attached flags are parsed, but a quoted field holding two space-separated paths with no flag between them reads as one path.
  • Native images carry their inventory digest, and a mismatch at the Go, Rust or fuse read makes that image unknown. A fuse read through an app bundle only checks membership in the inventoried digest set. This is race handling for a build replacing an executable mid-audit, so maintainers may prefer to drop it.
  • Cancellation in a later owner keeps the typed error and attaches the partial report. Cancellation during the member scan still returns no partial report. Partial Evidence is tested at service level, not through real CLI or MCP cancellation.

Not included: obfuscation, stripping, signing, modifying the artifact, network calls, or running the target. native.hardening, macho.hardened_runtime and android.manifest stay not_assessed and name their next probes.

Follow the contribution scope.
Unresolved scope, authority, side effects, or required verification block
integration. Link the required maintainer scope decision for new providers or
capabilities involving target execution, injection, mutation, or protection
recovery; ordinary fixes within existing boundaries may state "not applicable".
Draft PRs may leave the scope decision pending and the readiness and merge checklists
unchecked. Maintainers can help resolve open questions.

Contract and boundary impact

  • Semantic owner and earliest changed stage: new release-exposure domain, reader and service. Findings stay owned by the readers it composes.
  • Contribution scope fit and linked maintainer decision: read-only inspection of a local artifact, with no target execution, injection, mutation or protection recovery. It is defensive, and it does not add protection. Not applicable as a required decision. Whether REA wants this tool is for maintainers to judge, and I have not assumed approval. Also for maintainers: text.credential_markers is a small vendor-prefix list in src/domain/releaseExposureCredentialMarkers.ts, and REA may prefer not to own that list.
  • CLI and MCP/tool-catalog contract: additive. New audit_release_exposure tool and audit-release-exposure command, plus exit status 3 for --fail_on. Catalog, README and localized README counts are updated.
  • Provider, bridge, target-format, or platform compatibility: no provider or bridge. .app, install directory, ASAR or executable on any host. Universal Mach-O slicing uses lipo on macOS through the existing reader.
  • Evidence, artifact, provenance, or reconstruction contract: new Evidence with artifact identity, per-check status and coverage. Inventory contract is unchanged for other callers.
  • Target selection, authority, upstream behavior, and cleanup details (if applicable): a selected local path. Container readers are released in order, and a failed release is reported with its retained owner.
  • Generated metadata (docs/public/product-catalog.json), package, or installation impact (CI generates and validates ignored catalogs and skills/; edit authored instructions in .agents/skills/reverse-engineer-anything/ and never commit build outputs): additive tool count and one package.json verifier script. No runtime or development dependency is added: verify:release-exposure installs @electron/fuses into a temporary prefix when it runs, so it needs network access. No build output is committed.

Expected effects (check known effects; use documentation-only on its own).
Unchecked items do not establish absence; leave uncertainties visible.

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

The process and file boxes describe the existing composed readers, not the audited target: they may start lipo or xcrun and write private temporary files. The target itself is never launched or changed.

Evidence and regression coverage

  • Tests added or updated: domain, reader, service and inventory tests, CLI acceptance tests, filesystem boundary tests and MCP boundary tests.
  • Base reproduction or other evidence: npm run verify:release-exposure builds an Electron fixture, audits it, applies the remediation with @electron/fuses, and audits again. docs/verification/release-exposure-2026-10-31.md holds the record. Two installed Electron apps were audited by hand.
  • User-visible CLI/MCP output (if applicable): reduced from rea audit-release-exposure ... --json on this commit. The demo below is a rendered walkthrough of these results, not a screen recording.
MyApp.app before (--fail_on high exits 3)
exposed  high    javascript.source_map_sources
exposed  high    electron.run_as_node
exposed  medium  electron.only_load_from_asar
exposed  medium  electron.node_cli_inspect
exposed  low     packaging.extractable_payload
unknown          electron.asar_integrity

MyApp.app after removing the map and setting fuses
not_observed     javascript.source_map_sources, electron.run_as_node,
                 electron.only_load_from_asar, electron.node_cli_inspect
exposed  low     packaging.extractable_payload

Installed Electron apps
size    time   exposed  not_observed  unknown  not_assessed
481 MB  1.8 s  3        2             7        3
322 MB  3.2 s  1        4             7        3  (8 integrity contradictions recorded)
  • Remaining proof gaps: macOS host only. A real Windows PE was not audited, and PE paths use fixtures. On the installed apps, probing stops at 8 native images and one image exceeded the 256 MiB file allowance, so 7 checks stayed unknown. That is the honest result, but maintainers may want different allowances. electron.asar_integrity stayed unknown on the fixture.

For boundary fixes, identify the applicable boundary regressions
and lifecycle regressions
covered by the evidence above, and explain relevant gaps.

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Demo

demo

Validation performed

  • Latest review follow-up: 264 release-reader source tests and check:fast passed; the filesystem Unicode-collision regression skipped on this Mac and remains unverified on Linux locally. Validation uses constructed artifacts; no real-target/provider verification was run for this follow-up.

  • Compiler path separator follow-up: two reproducing regressions failed before the fix; the release reader and service suites passed 482 tests and npm run check:fast passed after it. The 12 CLI/filesystem/MCP boundary tests below predate this final follow-up. No external Go binary was tested for this change.

  • Latest review fixes preserve unknown coverage for encrypted packaged members, unread native images and ambiguous GNU -R runtime-token operands. The release-exposure source suites passed (504 tests), npm run check:fast passed, and CLI, filesystem and MCP boundary tests passed (12 tests). These additions use constructed artifacts and synthetic Go metadata; no external PyInstaller package or Go binary was tested for them.

  • Release-exposure review fixes: npm run check:fast passed and reader/service source suites passed (476 tests), including regressions for shebang-map read budgets, quoted Go flag fields, linker map stdout and GNU -R operands. The reader reuses already-read script bytes and retains map charges. CLI, filesystem and MCP boundary tests passed (12 tests); those boundary tests ran before the final Go-flag parser change. Bun sourcemap coverage was already covered by existing reader tests.

Run on this commit on macOS with Node 24.22.1 and npm 11.16.0:

  • npm run test:local on the changed source tests: 128 passed.
  • npm run test:focused on the changed acceptance and boundary tests: 182 passed.
  • npm run verify:release-exposure: passed, with --fail_on high exiting 3 before remediation.
  • typecheck, lint, lint:typed (0 errors), format:check, metadata:check, verify:architecture-guards, verify:test-discovery, knip:production and docs:check: passed.
  • npm run check stops at knip on one unused exported type at src/process/DarwinHelperCache.ts:465. This PR does not touch that file, and it failed the same way on main in this environment.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. The tool and the acquisitionLimits option are additive.
  • Real decompiler provider, browser, or OS coverage: none needed. Real installed Electron apps on macOS only.
  • Package or release metadata impact: one new package.json script. No new runtime dependency.
  • Security, privacy, process, or containment review: the target is never executed or rewritten. The tool declares filesystem and process effects, because composed readers may use private temporary files and lipo. Matched credential bytes and source map text stay out of the report, and every read is bounded.

Author readiness

Human owner: @mvanhorn

  • 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.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

AI was used for assistance.

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.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Codex Review Summary: 🔄 Running

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review 🔄 Running since 2026-11-10T23:35:17.068442Z 61af74a New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f183381739

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/domain/releaseExposure.ts Resolved
Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
@greptile-apps

greptile-apps Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 1/5 Tier: plus

[Medium impact] The PR adds a bounded local-artifact audit through CLI and MCP entry points.

The PR should not merge yet: earlier findings about unbounded shebang reads, lost map observations, and false Go path findings remain unresolved.

Findings

  1. P1 Different map files disappear ▶
  2. P1 Security Shebang files bypass read limits ▶
  3. P1 Standard output becomes a path ▶
Fix with agent prompt
### Issue 1
src/artifacts/ReleaseExposureReader.ts:1408-1409
On Linux, `café.map` and `cafe\u0301.map` can be separate files. If both are read as linker maps before a script declares only `café.map`, the new normalized bucket deletes both observations. The undeclared linker map disappears from `native.debug_companions`, and `--fail_on medium` can exit 0.

Keep distinct source occurrences separate when retracting a linker-map guess. The repository requires source identity and completed observations to survive lookup normalization.

### Issue 2
src/artifacts/ReleaseExposureReader.ts:1214-1219
Refunding `mapsRead` here removes the limit on full reads of shebang `.map` files. Each file has already received a read of up to 1 MiB, but those bytes do not count toward `textBytes`. Even after the text allowance is spent, later files still get that first read and refund its slot. A compressed .NET bundle can therefore force gigabytes of decompression instead of stopping full map reads after 32 files.

The repository requires resource limits before costly work. Detect the shebang from a bounded header, reuse bytes already read, and keep actual reads charged.

> **How this was verified:** Compressed members reach `readMap` on each iteration, and this branch restores its slot without charging the first read to `textBytes`.

### Issue 3
src/application/releaseExposure/ReleaseExposureService.ts:undefined-1105
GNU ld treats `-Map=-` as “write the map to standard output,” not as a filename. With `-ldflags` containing `-extldflags=-Wl,-Map=-`, the new `Map` alternative makes `goRelativeFlagPaths` return `"-"`. A build with no other paths then reports `go.build_paths` as `exposed` and wrongly exits 3 under `--fail_on low`.

Keep the option’s meaning through path extraction so this standard-output value is excluded without dropping real map filenames.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Adds a local release-exposure audit through shared CLI and MCP workflows.

  • A local app or executable gets one report of what static analysis can recover.
  • The audit is available from the CLI and MCP tool catalog.
  • Artifact inventory can stop at caller-set entry and byte limits.
  • Existing readers now distinguish incomplete metadata from metadata that is absent.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[CLI or MCP request] --> B[ReleaseExposureService]
  B --> C[Inventory and bounded member reads]
  C --> D[Source maps, companions, and text coverage]
  C --> E[Credential marker scan]
  B --> F[Desktop, fuse, Go, and Rust readers]
  D --> G[Fixed check report]
  E --> G
  F --> G
  G --> H[Evidence]
  H --> I[Optional CLI severity gate]
Loading

Reviews (123) · Last reviewed commit: "fix(release-exposure): count unread text..." · Reviewed by Greptile

Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
Comment thread scripts/verify-release-exposure.mjs Resolved
…lags 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.
…ing 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.
Comment thread src/artifacts/ReleaseExposureReader.ts Resolved

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ffc2f2309e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
Comment thread src/artifacts/ReleaseExposureReader.ts Resolved

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 34811879c7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
Comment thread src/artifacts/ReleaseExposureReader.ts Resolved

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c7692515e0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
…ed 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.
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.
…ched 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.
…ilure

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.
@mvanhorn
mvanhorn force-pushed the fix/release-exposure-audit branch from c769251 to f553459 Compare November 1, 2026 18:36
Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
Comment thread src/artifacts/ReleaseExposureReader.ts Resolved

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f553459c9a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…le 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.
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.
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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 169c978598

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
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.
…llation

A scan cancelled after some members were examined reported its partial
scan only when cleanup also failed, so a clean cancellation dropped the
recovered source-map and credential observations. A cancelled scan now
hands its assembled facts to the interrupted-scan visitor with unknown
coverage and a cancellation limitation, and the caller still receives
the cancellation error carrying that partial audit.
Comment thread docs/release-exposure.md Resolved

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 580aec3faf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
…ber scan is cancelled

Since the member scan keeps what it examined on ordinary cancellation,
the status guide no longer says that cancelling the scan returns no
partial report. It now describes the partial observation and limits the
no-report case to cancellation before the scan can be assembled.
… short

A text-named member read with one or two bytes of the text allowance
left returns only `#` or `#!`, which cannot establish a Node shebang, so
`runner.txt` kept its non-script role and its unexamined inline map was
treated as absent. A partial or missing header that could still start a
shebang line now leaves the member's maps unassessed, as an unread
member's do once the allowance is spent.
…SAR layouts

Inside an ASAR layout, a sibling whose name had a dot and no `.exe`
suffix, such as `my.app`, was neither ranked for the native sample nor
counted as a possible Electron host. With shared libraries filling the
sample, that image could be dropped while the layout still counted its
host as read, so safe fuses on a helper reported `run_as_node` as not
observed. A dotted sibling that is not named like a shared library is
now sampled after plain siblings and counted as a possible host.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0e729e7a3a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
The env shebang reader split the whole line on spaces before handling -S,
so a launcher such as `#!/usr/bin/env -S NODE_OPTIONS='--conditions
development' node` named `development'` as its program and its maps were
never assessed. An -S operand now takes the rest of the line and is split
the way GNU env -S splits it: single and double quotes, backslash escapes,
\_ and \c, and a leading # comment. A string env itself rejects, such as an
unterminated quote, runs no program.
When a Go, Rust, fuse or desktop owner finished its Evidence and then saw
cancellation, completeProviderEvidence returned that Evidence as the
error's partial observation, but the audit only kept the error and
substituted a not-run fact, so a recovered Go build path or Rust package
list reported unknown. Each owner's Evidence-to-fact reading now lives in
one function used for both a successful read and a completed partial, so
the partial passes the same schema and inventory digest checks before its
fact is kept. Later owners still do not run.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 41929a061b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
…essed

`env -S` expands `${NAME}` from the environment, so a launcher such as
`#!/usr/bin/env -S ${NODE_BIN}` may run Node, but the shebang reader kept
the placeholder as the program name and treated the file as plain text,
reporting its inline map as absent. The env splitter now marks fields that
expand a variable, and a program whose name holds one leaves the shebang
undecided: the member's maps count as unassessed, and a `.map` companion
with such a header is not taken as a linker map. Quoted or escaped `${`
stays literal, and a resolved basename such as `${DIR}/bin/deno` still
decides.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c6a5afbf3b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
A directly selected app.asar whose header exceeds asar.max_header_bytes
now returns the typed header admission refusal and its recovery, as the
directory scan already does, instead of a generic partial report.
…am unassessed

An undeclared `runner.map` whose `env -S` program is `${NODE_BIN}` may
run Node, so `examineMapMember` now treats an undecided `nodeShebang`
result as an unassessed map and companion, as `classifySiblingMap`
already does, rather than falling through to a linker-map guess.
Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
splitForwardedLinkerFlags hands -Wl,-Map=private-link.map to the linker
side, but LINKER_PATH_FLAG had no Map entry, so the relative map path was
dropped and go.build_paths read not_observed. Add Map to the file-valued
linker options so -Map=FILE and -Map FILE are both reported.
An oversized .map whose shebang names its program with an unresolved
variable, or a package member with an undecided PE header, returned
before counting its unscanned text, so credential markers could read
not_observed. Count any non-bytes read as skipped text in both branches.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c5d9afcf6f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/artifacts/ReleaseExposureReader.ts Resolved

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6ac1dee17d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
Comment thread src/domain/releaseExposure.ts Resolved

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 15bc3db523

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c878c1f5b7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +910 to +914
: !droppedOutsideHost &&
layouts.every(
(folder) =>
settledLayouts.has(folder) ||
hostRead(preferred.filter((image) => inLayout(folder, image.path))),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep partial inventory from certifying fuse-host coverage

When the 2 GiB inventory allowance stops a directory scan after a/a.exe but before a separate asar: false build under b/, complete desktop discovery still supplies only A's ASAR layout. Because droppedOutsideHost considers only inventoried images, this branch can set electronExecutableIncluded to true despite scan.coverage === "unknown", causing fuseCheck() to report A's safe fuses as not_observed for the whole selection. Fresh evidence beyond the earlier dropped-sample fix: a bounded check of the current sampling/reducer helpers returns not_observed when B is absent from the partial inventory, versus unknown when B's sentinel-less host is inventoried. Preserve incomplete-inventory uncertainty independently of whether every discovered layout has a sampled host.

AGENTS.md reference: AGENTS.md:L19-L19

Useful? React with 👍 / 👎.

Comment thread src/artifacts/ReleaseExposureReader.ts Resolved
A declaration recorded only its NFC lookup key, so every member or
sibling sharing that key took the declared JavaScript-map route. On a
normalization-sensitive filesystem an unrelated linker map spelled in
another form lost its companion evidence when the declaring script was
scanned first.

Record the resolved spellings each declaration writes and treat only an
exact match as declared. Another spelling in the bucket is read as an
undeclared map; when no declared spelling is reached, its linker-map
guess stays unresolved coverage rather than companion evidence.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants