Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ jobs:
cache: npm
- run: npm ci
- run: npm run test:action
- name: Verify dogfood evidence boundaries
run: npm run dogfood

published-action:
name: Action smoke / published v0.5.3
Expand Down
4 changes: 3 additions & 1 deletion ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ check discovery → target qualification → per-target observation

## Modules

- `src/git.ts` uses `git` argument arrays without a shell. It validates revisions, parses NUL-delimited paths, includes untracked files for the default selection, and extracts zero-context hunk ranges. Read commands suppress hooks, filesystem monitors, external diff/text conversion, and configured content drivers.
- `src/git.ts` validates revisions, parses NUL-delimited paths, includes untracked files for the default selection, and extracts zero-context hunk ranges using literal per-file pathspecs. `src/git-command.ts` supplies the shared argument-array, no-shell boundary for all static Git reads, including immutable workspace and test-map binding checks. It suppresses hooks, filesystem monitors, external diff/text conversion, and configured content drivers, refreshing bounded driver discovery (including linked-worktree config) before each operation. Timed-out, failed-to-start, and truncated reads fail closed. Unborn repositories derive their empty-tree object from Git rather than assuming SHA-1.
- `src/adapters/` contains the small `LanguageAdapter` boundary. JavaScript/TypeScript use `@babel/parser`. Python sends source text to `python -I -S` and the standard `ast` module; it does not import repository modules. Built-in adapters retain line-numbered call sites so reports can show structural call references that intersect changed lines.
- `src/graph.ts` resolves only local, statically identifiable imports. It builds reverse dependencies for impact estimates and broad test-like relationship discovery. Test-like path heuristics do not establish runnable identity.
- `src/resolution.ts` adds a fail-closed metadata layer for non-relative JavaScript/TypeScript imports. It reads bounded JSON/JSONC only, supports a narrow subset of compiler `paths` and package self-exports, retains inspectable graph evidence for successful edges, and never invokes a compiler, package manager, or repository resolver.
Expand Down Expand Up @@ -52,6 +52,8 @@ Every report is derived during one run and can be serialized as JSON or HTML. Th

- Files larger than 1 MB and binary files are not parsed.
- At most 5,000 repository files are structurally analyzed per run.
- Source parsing runs concurrently, but analyses and diagnostics are collected in inventory order rather than completion order.
- Git stdout/stderr is capped at 8 MB per ordinary read, driver-name discovery at 64 KB, ignored-workspace inventory at 512 KB, and test-map snapshot reads at 256 KiB plus one byte. A reached output cap aborts analysis rather than parsing a partial record. Git reads have a 30-second timeout.
- The displayed/risk-scored reverse-impact list is capped at 250 files per changed file; test-like relationship and qualification traversal is separately bounded by the 5,000-file analyzed inventory.
- Static module metadata is capped at 256 KB per file, 64 compiler files, 256 package files, 32 ancestor directories, 8 inherited-config levels, 128 path keys, 8 targets per key, 32 custom conditions, 64 candidates per import, 8 export-condition levels, 64 visited export branches, 50,000 non-relative import observations, 10,000 retained resolution records, and 100 emitted resolution diagnostics. A reached bound creates no edge.
- Check stdout/stderr defaults to 256 KB, runner observations are separately capped at 64 KB, and check duration defaults to 120 seconds.
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ All notable changes are documented here. This project follows Semantic Versionin

### Fixed

- Repaired the dogfood gate by moving test preparation into npm's `pretest` lifecycle and retaining a direct serial `node --test` command. It now requires positive observations for every related compiled target while correctly retaining partial evidence for filename-mapped TypeScript source. Added a self-discovery regression and a PR CI dogfood step; shell-chain recognition and compiled-source confidence remain conservative.
- Unified static Git execution so immutable workspace checks and test-map snapshot reads receive the same helper suppression as diff inspection. Driver discovery now includes worktree configuration, refreshes on each operation, uses NUL-delimited names, and fails closed when incomplete.
- Rejected truncated, timed-out, or failed Git reads instead of treating partial paths or patches as complete evidence. Per-file patch failures now stop analysis with exit code 2.
- Treated per-file Git paths literally, including both sides of a rename, so brackets, wildcards, and pathspec magic cannot mix another file's hunks into evidence.
- Derived the empty-tree object from the repository's object format, supporting SHA-256 repositories before their first commit.
- Handled early child-stdin closure as a process error instead of an unhandled `EPIPE` crash. Python analysis rejects otherwise-valid output from failed, timed-out, or truncated helpers and retries or reports a lexical fallback.
- Preserved inventory order when collecting concurrent source analyses and diagnostics, eliminating parser/I/O completion order from those results.
- Preserved ignored-file path identity across platforms when enforcing immutable workspace alignment. POSIX filenames containing literal backslashes are no longer rewritten as directory separators, so a distinct ignored runtime input such as `coverage\proof.lcov` cannot alias an explicitly allowed `coverage/proof.lcov` data artifact and bypass the pre-execution fail-closed gate.
- Failed closed on unattributed targeted-runner process failures even when another qualified batch target is unavailable. An unavailable target can no longer act as a sink that lets unrelated observed passes survive an ambiguous process-level failure; only explicitly failed targets retain localized failure attribution.
- Failed closed on deletion-only zero-context hunks when attributing current changed symbols and call references. Git represents a deletion-only hunk with a zero-length new-side range anchored to a neighboring current line; ProofDiff now reconciles reconstructed current-line spans with Git numstat additions before treating those anchors as changed current code.
Expand Down
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ npm run dogfood
npm pack --dry-run
```

`npm test` runs its `pretest` lifecycle first to build, compile tests, and validate the explicit test manifest. Keep preparation there: the `test` script itself must remain an exact serial `node --test` invocation so ProofDiff can qualify its own test targets without interpreting shell chains. CI also runs `npm run dogfood`: all checks and related compiled targets must pass, while the TypeScript source correctly remains partially verified because filename mapping does not attest compilation provenance.

## Expectations

- Add observable-behavior tests for fixes and features.
Expand Down
2 changes: 2 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ ProofDiff's safe default performs these local operations:
- writes reports only to paths explicitly requested by the user;
- performs no network requests and sends no telemetry.

All static Git reads share the same hardened launcher, including the filesystem-alignment check for immutable selections and test-map snapshot reads. Content-driver names are read as bounded NUL-delimited data from the effective repository/worktree configuration before each operation; the configuration is not cached across library calls. Incomplete configuration discovery or Git output aborts analysis. Per-file diff paths use literal pathspecs, so filename wildcards cannot change the scope of evidence. These measures retain the separate trusted-Git-directory boundary above; they do not protect against another process concurrently replacing repository/configuration files during analysis.

User-controlled revisions cannot begin with `-` or contain control/whitespace characters. ProofDiff's process launcher disables Node's shell mode. Git and parser operations are always started directly; on Windows, explicitly selected npm, pnpm, and Yarn checks use `cmd.exe` only to start the standard `.cmd` package-manager shim with fixed arguments. Package managers may then interpret their own configuration only within the documented boundaries. Filenames and report content are HTML-escaped; terminal control characters from untrusted report fields and check output are removed. GitHub job summaries HTML-escape repository-controlled paths, project analysis notes into fixed source-free categories (malformed/non-applicable compiler configuration, unsupported/ambiguous local resolution, unavailable source analysis, and explicit bounds), and omit source text, parser excerpts, symbols, commands, check output, observer payloads, and absolute repository paths. Malformed `package.json` produces a fixed parse note rather than copying the parser's source excerpt. Unclassified diagnostics are represented only by a count and cause the summary to recommend inspecting static limitations before runtime evidence. The Action writes only to GitHub's per-step summary file and does not require a write-capable token or call the GitHub API.

## Repository check execution
Expand Down
2 changes: 1 addition & 1 deletion dist/adapters/python.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion dist/adapters/python.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading