Skip to content

feat(signing): add working-tree-vs-push divergence detection (S3b Part 1) - #501

Merged
qnbs merged 3 commits into
mainfrom
reconstruct-pr491-s3b-divergence-detection
Aug 25, 2026
Merged

feat(signing): add working-tree-vs-push divergence detection (S3b Part 1)#501
qnbs merged 3 commits into
mainfrom
reconstruct-pr491-s3b-divergence-detection

Conversation

@qnbs

@qnbs qnbs commented Aug 25, 2026

Copy link
Copy Markdown
Owner

User description

Summary

S3b Part 1 of the PR #491 program-continuity reconstruction — the smallest prerequisite slice for isolated exact-localSha verification (Part 2, a separate, dedicated future PR).

Neither pathEvidenceState (#498) nor any other current signal proves that the content ci-prepush-lowend.mjs's local checks actually validate (everything runs against whatever is on disk) corresponds to localSha's exact committed tree, rather than a working tree that has drifted from it. Required CI remains the sole merge-safety authority regardless — this is a local-gate trust/DX gap, not a safety hole, and this PR closes only that gap as a diagnostic signal, not as exact-tree validation.

  • resolvePushEvidence() gains workingTreeState: 'MATCHES' | 'DIVERGED' | 'NOT_APPLICABLE' | 'UNKNOWN', computed per-update via git diff --quiet <localSha> --. MATCHES is not exact-tree proof (it can't see untracked files) and is never used anywhere as a skip condition for future exact verification.
  • The new diagnostic cannot throw and is fully isolated from canonical evidence validity — UNKNOWN never rewrites evidenceState/pathEvidenceState. This matters concretely: resolveManualEvidence() throws whenever evidenceState !== 'RESOLVED', so without this isolation a transient git timeout on the new diagnostic would have turned otherwise-valid, already-verified fix(devops): replace pre-push evidence handoff #494/fix(devops): make pre-push path evidence completeness explicit #498 evidence into a hard pre-push rejection.
  • computeWorkingTreeState() checks result.error before trusting result.status, since runGit's own status: result.status ?? 1 fallback makes a killed/failed subprocess indistinguishable from a genuine "differences found" exit code 1 otherwise.
  • Tags are included in computation on the same terms as branches (an earlier draft excluded them; a diverged tag push was silently unreported).
  • Manual/no-evidence-file invocation reports NOT_APPLICABLE, not MATCHES — no localSha exists to compare against in that mode.
  • ci-prepush-lowend.mjs reports one non-blocking, informational line on DIVERGED/UNKNOWN only, not coupled to the existing full-admission escalation lever.

Reserved for Part 2 (isolated-localSha-worktree exact verification, designed fresh against then-current main): MATCHES is never a skip gate anywhere in this codebase.

Test plan

  • New deterministic, DI-injected tests (no real git subprocess): computeWorkingTreeState's error-vs-status-1 distinction tested directly; the UNKNOWN-does-not-mutate-evidenceState regression proven directly; tag inclusion, deletion/manual NOT_APPLICABLE, and aggregation precedence (DIVERGED > UNKNOWN > MATCHES) all covered.
  • 4 pre-existing resolvePushEvidence tests updated to inject worktreeMatchesCommit so they stay git-subprocess-free.
  • pnpm exec vitest run tests/unit/signing.test.ts tests/unit/tooling/ciPrepushRangeResolver.test.ts — 41/41 pass.
  • pnpm run ci:prepush — full local admission gate passes end-to-end.
  • pnpm run lint — clean (0 warnings; 6 pre-existing infos in an unrelated file).
  • pnpm run typecheck (4-checker, CI-equivalent) — clean.
  • CI: full pipeline (Build, Quality Gate ×2, E2E, E2E Deep, Lighthouse, Storybook, Visual Regression, CodeQL, Security Audit, Verified Signatures)

Summary by Sourcery

Detect working-tree divergence from pushed commits while preserving existing evidence validation and required-CI merge safety.

New Features:

  • Add diagnostic detection of whether the working tree matches each pushed commit, including branch and tag updates.

Bug Fixes:

  • Prevent Git subprocess failures from being misclassified as working-tree divergence or invalidating otherwise valid push evidence.

Enhancements:

  • Keep working-tree comparison independent from canonical evidence validity and admission decisions, with explicit handling for deleted refs and manual checks.
  • Report divergent or indeterminate working-tree comparisons as non-blocking informational pre-push diagnostics.

Documentation:

  • Update README test-count metrics to reflect the expanded test suite.

Tests:

  • Add deterministic coverage for comparison outcomes, failure handling, tag and deletion behavior, aggregation precedence, and diagnostic isolation.

CodeAnt-AI Description

Detect when local checks do not match the commits being pushed

What Changed

  • Reports whether the working tree matches, differs from, or cannot be compared with each pushed commit.
  • Includes branch and tag pushes in the comparison; deleted refs and manual checks are marked as not applicable.
  • Shows informational DIVERGED or UNKNOWN results while keeping required CI and existing evidence validation unchanged.
  • Handles Git command failures without turning valid push evidence into a rejection.
  • Adds coverage for divergence results, tag pushes, deletions, mixed updates, and failed comparisons.

Impact

✅ Clearer local push verification
✅ Earlier detection of uncommitted changes affecting push checks
✅ Fewer false pre-push rejections after Git command failures

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

  • New Features

    • Added working-tree diagnostics to push validation, identifying matching, diverged, unknown, or inapplicable states.
    • Improved pre-push reporting when the local working tree cannot be fully resolved.
  • Bug Fixes

    • Prevented working-tree diagnostic failures from interrupting validation.
    • Preserved accurate status reporting for deleted, incomplete, or partially resolved changes.
  • Documentation

    • Updated documented test totals from 6,988+ to 6,997+.

…t 1)

Neither pathEvidenceState (#498) nor any other current signal proves
that the content ci-prepush-lowend.mjs's local checks actually validate
(everything runs against whatever is on disk, cwd: projectRoot)
corresponds to localSha's exact committed tree, rather than a working
tree that has drifted from it (uncommitted edits, staged-but-uncommitted
changes, wrong ref checked out). Required CI remains the sole
merge-safety authority regardless, so this is a local-gate trust/DX
gap, not a safety hole -- and this commit closes only that gap, as a
diagnostic signal, not as exact-tree validation.

resolvePushEvidence() (signing-core.mjs) gains a new orthogonal
dimension, workingTreeState: 'MATCHES' | 'DIVERGED' | 'NOT_APPLICABLE'
| 'UNKNOWN', computed per-update via a new computeWorkingTreeState()
using `git diff --quiet <localSha> --` (compares working tree directly
against the commit's tree; structurally cannot see untracked files,
which is exactly why MATCHES is not sufficient to prove exact-tree
equivalence -- an untracked file satisfying an import that's absent
from the real commit would make a local check pass when a real
checkout of localSha would fail). DELETED updates get NOT_APPLICABLE
(no commit to compare against); TAG updates are included on the same
terms as branch updates via the same call (git's own revision parsing
transitively peels a tag to its target), not excluded as an earlier
draft had them -- a diverged tag push is now reported instead of
silently unreported. Aggregation precedence: DIVERGED > UNKNOWN >
MATCHES > (NOT_APPLICABLE only when no relevant update exists, e.g. an
all-deletions push).

computeWorkingTreeState() never throws -- it maps any runGit() failure
(spawn error, timeout) to UNKNOWN internally, and critically checks
result.error before trusting result.status, since runGit's own
`status: result.status ?? 1` fallback makes a killed/failed subprocess
indistinguishable from a genuine "differences found" exit code 1
unless the caller inspects error first. This keeps the new diagnostic
fully isolated from resolvePushEvidence's existing canonical try/catch:
a diagnostic failure can only ever produce workingTreeState: 'UNKNOWN'
on the RESOLVED path, never evidenceState: 'INVALID'. This matters
because ci-prepush-range-resolver.mjs's resolveManualEvidence() throws
whenever evidenceState !== 'RESOLVED' -- without this isolation, a
transient git timeout on the new diagnostic would have turned
otherwise-valid, already-verified #494/#498 evidence into a hard
pre-push rejection.

Propagated through resolveManualEvidence()'s evidence-file path
unchanged; the manual/no-evidence-file path (changedFilesFromManualRange,
direct `pnpm run ci:prepush` invocation) reports NOT_APPLICABLE, not
MATCHES -- there is no localSha and no push event in that mode, so no
comparison of any kind happens, and claiming MATCHES would assert an
equivalence that was never checked.

ci-prepush-lowend.mjs reports a non-blocking, informational line only
on DIVERGED or UNKNOWN (MATCHES/NOT_APPLICABLE stay silent) --
deliberately not coupled to the existing `full`-admission escalation
lever, since divergence and incomplete-change-evidence are different
failure modes with no shared remedy.

Deliberately not implemented in this slice (reserved for Part 2, an
isolated-localSha-worktree exact verification mechanism to be designed
fresh against then-current main): MATCHES is never treated as a skip
condition for exact verification anywhere in this codebase, in this
commit or otherwise -- proving tracked-content equivalence sufficient
to safely skip real verification would require also ruling out
untracked/gitignored drift, which is exactly what an isolated worktree
proves and a cheap diff cannot.

Tests: computeWorkingTreeState's runGit-error-vs-status-1 distinction
(the exact ambiguity this commit exists to close) tested directly via
injected runGit results; the UNKNOWN-does-not-mutate-evidenceState
regression proven directly, not just asserted in prose; tag inclusion,
deletion/manual NOT_APPLICABLE, and aggregation precedence (including
a mixed DIVERGED+UNKNOWN and MATCHES+UNKNOWN case) all covered
deterministically with no real git subprocess in the new tests.
Four pre-existing resolvePushEvidence tests updated to inject
worktreeMatchesCommit so they stay git-subprocess-free rather than
incidentally exercising the real default against fake SHAs.

README test-count badges resynced via `pnpm run sync:readme` (578
files / 6997+ tests).

Validated: full `pnpm run ci:prepush`, `pnpm run lint`, `pnpm run
typecheck` (4-checker), and both targeted test files all pass.
@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing

@codeant-ai

codeant-ai Bot commented Aug 25, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Reviewed your PR 3d465c6 Aug 25, 2026 · 15:45 15:48

@vercel

vercel Bot commented Aug 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
worldscript-studio Ready Ready Preview Aug 25, 2026 4:03pm

@codeant-ai

codeant-ai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@sourcery-ai

sourcery-ai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Reviewer's Guide

Introduces a diagnostic-only working-tree-vs-pushed-commit divergence signal, computed per branch and tag update and propagated to local pre-push reporting, while deliberately leaving canonical evidence validity, admission behavior, and future exact-tree verification unchanged; comprehensive DI-based tests cover failure handling and state semantics.

Sequence diagram for working-tree divergence diagnostics

sequenceDiagram
    participant Resolver as resolvePushEvidence
    participant Git as git diff --quiet
    participant Evidence as PushEvidence
    participant Prepush as ci-prepush-lowend.mjs

    Resolver->>Git: computeWorkingTreeState(localSha)
    alt result.error
        Git-->>Resolver: error
        Resolver->>Evidence: workingTreeState = UNKNOWN
    else status = 0
        Git-->>Resolver: status 0
        Resolver->>Evidence: workingTreeState = MATCHES
    else status = 1
        Git-->>Resolver: status 1
        Resolver->>Evidence: workingTreeState = DIVERGED
    else other status
        Git-->>Resolver: status
        Resolver->>Evidence: workingTreeState = UNKNOWN
    end
    Resolver->>Evidence: aggregateWorkingTreeState(updates)
    Evidence-->>Prepush: diagnostic state
    alt DIVERGED or UNKNOWN
        Prepush->>Prepush: report informational line
    end
Loading

Flow diagram for working-tree state aggregation

flowchart TD
    A[Push or manual evidence resolution] --> B{Push update has localSha?}
    B -->|No, deletion| C[NOT_APPLICABLE]
    B -->|Yes| D["computeWorkingTreeState(localSha)"]
    D --> E{git diff --quiet result}
    E -->|error or other status| F[UNKNOWN]
    E -->|status 0| G[MATCHES]
    E -->|status 1| H[DIVERGED]
    C --> I[aggregateWorkingTreeState]
    F --> I
    G --> I
    H --> I
    I --> J{Precedence}
    J -->|Any DIVERGED| K[DIVERGED]
    J -->|Else any UNKNOWN| L[UNKNOWN]
    J -->|Else all MATCHES| M[MATCHES]
    J -->|No comparable updates| N[NOT_APPLICABLE]
Loading

File-Level Changes

Change Details Files
Adds a diagnostic working-tree comparison for each pushed ref update without changing canonical evidence validity or admission decisions.
  • Runs git diff --quiet <localSha> -- and maps results to MATCHES, DIVERGED, or UNKNOWN, prioritizing subprocess errors over exit status.
  • Includes branch and tag updates, excludes deletions, and aggregates states with DIVERGED > UNKNOWN > MATCHES; reports NOT_APPLICABLE when no comparison exists.
  • Keeps the signal isolated from evidenceState/pathEvidenceState and exposes dependency injection for git-free tests.
scripts/signing/signing-core.mjs
scripts/signing/signing-core.d.mts
Propagates the working-tree diagnostic through manual evidence resolution and surfaces only actionable uncertainty as informational pre-push output.
  • Adds WorkingTreeState to resolver and signing types and returns NOT_APPLICABLE for manual/no-push-range mode.
  • Emits non-blocking DIVERGED or UNKNOWN messages while preserving required CI as the merge-safety authority.
  • Avoids coupling the diagnostic to full-admission escalation or exact-tree verification skip behavior.
scripts/ci-prepush-range-resolver.mjs
scripts/ci-prepush-range-resolver.d.mts
scripts/ci-prepush-lowend.mjs
Adds deterministic coverage for diagnostic classification, aggregation, isolation, ref handling, and manual-mode semantics.
  • Tests error-versus-status-1 handling, tag inclusion, deletion behavior, aggregation precedence, and preservation of canonical evidence states.
  • Updates existing resolver fixtures to inject the diagnostic and validates manual mode remains NOT_APPLICABLE.
  • Updates documented test-count metrics.
tests/unit/signing.test.ts
tests/unit/tooling/ciPrepushRangeResolver.test.ts
README.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label Aug 25, 2026
@codeant-ai

codeant-ai Bot commented Aug 25, 2026

Copy link
Copy Markdown

🏁 CodeAnt Quality Gate Results

Commit: 928c32f0
Scan Time: 2026-08-25 16:02:53 UTC

✅ Overall Status: PASSED

Quality Gate Details

Quality Gate Status Details
Secrets ✅ PASSED 0 secrets found
Duplicate Code ✅ PASSED 0.0% duplicated
SAST ✅ PASSED No security issues
Bugs ✅ PASSED Rating S: No bugs
IAC ✅ PASSED No IAC issues

View Full Results

@amazon-q-developer amazon-q-developer 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.

This PR implements working-tree divergence detection as a diagnostic signal with careful isolation from canonical evidence validity. The implementation correctly handles error vs. exit-code distinction, aggregates states with proper precedence, and includes comprehensive test coverage proving the diagnostic cannot corrupt evidence validity. No blocking defects identified - the code functions correctly as designed.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.

@sourcery-ai sourcery-ai 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.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="scripts/signing/signing-core.mjs" line_range="336" />
<code_context>
 }

+// QNBS-v3: diagnostic-only signal; never throws, so it cannot corrupt canonical evidence validity.
+export function computeWorkingTreeState(sha, cwd, dependencies = {}) {
+  const runGitFn = dependencies.runGit ?? runGit;
+  const result = runGitFn(['diff', '--quiet', sha, '--'], { cwd });
+  if (result.error) return 'UNKNOWN';
+  if (result.status === 0) return 'MATCHES';
+  if (result.status === 1) return 'DIVERGED';
+  return 'UNKNOWN';
+}
+
</code_context>
<issue_to_address>
**issue (bug_risk):** `computeWorkingTreeState()` does not catch exceptions from `runGitFn()`, so a thrown subprocess error escapes into `resolvePushEvidence()`'s canonical catch and converts otherwise-valid evidence into `evidenceState: 'INVALID'` instead of the promised diagnostic-only `workingTreeState: 'UNKNOWN'`.

**Triggers:** When the injected or underlying git runner throws rather than returning a result with `error`.

**Suggested fix:** Wrap the `runGitFn(...)` call in `try/catch` and return `'UNKNOWN'` from the catch block.

```suggestion
  let result;
  try {
    result = runGitFn(['diff', '--quiet', sha, '--'], { cwd });
  } catch {
    return 'UNKNOWN';
  }
```
</issue_to_address>

Sourcery assessment

Approval pending. 1 finding to address first.

Blocking findings: scripts/signing/signing-core.mjs:336


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread scripts/signing/signing-core.mjs Outdated
@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

Next included review available in 42 minutes.

View limit details

Limit details: You’ve used the included review currently available. Your 111 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6b4befae-9ea1-4e90-8d53-7dd8429fe742

📥 Commits

Reviewing files that changed from the base of the PR and between 3d465c6 and 928c32f.

📒 Files selected for processing (3)
  • README.md
  • scripts/signing/signing-core.mjs
  • tests/unit/signing.test.ts

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a3fca9b3-e826-4575-8d09-58e29339a22f

📥 Commits

Reviewing files that changed from the base of the PR and between 5475f2e and 3d465c6.

📒 Files selected for processing (8)
  • README.md
  • scripts/ci-prepush-lowend.mjs
  • scripts/ci-prepush-range-resolver.d.mts
  • scripts/ci-prepush-range-resolver.mjs
  • scripts/signing/signing-core.d.mts
  • scripts/signing/signing-core.mjs
  • tests/unit/signing.test.ts
  • tests/unit/tooling/ciPrepushRangeResolver.test.ts

Included review availability: 0 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.


📝 Walkthrough

Walkthrough

The change adds working-tree state diagnostics to push evidence, propagates the state through pre-push range resolution, reports divergent or unknown states, expands test coverage, and updates README test metrics.

Changes

Working-tree diagnostics

Layer / File(s) Summary
Evidence contracts and diagnostics
scripts/signing/signing-core.d.mts, scripts/signing/signing-core.mjs, tests/unit/signing.test.ts
The signing core defines working-tree states, classifies Git comparisons, aggregates update states, and tests matching, divergence, unknown results, and deletion handling.
Pre-push resolution and reporting
scripts/ci-prepush-range-resolver.d.mts, scripts/ci-prepush-range-resolver.mjs, scripts/ci-prepush-lowend.mjs, tests/unit/tooling/ciPrepushRangeResolver.test.ts
Range resolution returns working-tree state. Low-end pre-push checks report DIVERGED and UNKNOWN states. Tests cover manual results, evidence propagation, and path-evidence independence.
Test metrics documentation
README.md
README metrics now report 6,997+ tests across 578 test files.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: 🟡 Moderate · up to 3d465

A duplicate declaration prevents the signing test file from parsing and blocks the affected test suite from running; it should be removed before merging.

Sequence Diagram(s)

sequenceDiagram
  participant PushEvidence
  participant WorkingTreeDiagnostic
  participant Git
  participant PrepushReporter
  PushEvidence->>WorkingTreeDiagnostic: classify update state
  WorkingTreeDiagnostic->>Git: run git diff --quiet
  Git-->>WorkingTreeDiagnostic: comparison result or error
  WorkingTreeDiagnostic-->>PushEvidence: MATCHES, DIVERGED, or UNKNOWN
  PushEvidence->>PrepushReporter: provide workingTreeState
  PrepushReporter-->>PrepushReporter: report diagnostic state
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 7 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: detecting working-tree divergence from the pushed commit in signing evidence.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 7 files. (1 skipped: 1 unsupported.)

✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch reconstruct-pr491-s3b-divergence-detection

Comment @coderabbitai help to get the list of available commands.

…orkingTreeState

The default runGit() never throws (spawnSync failures are captured
into result.error, not thrown), so this was unreachable through the
real production call path. But computeWorkingTreeState() is an
exported function with an optional dependencies.runGit override, and
its whole contract -- documented in its own QNBS-v3 comment and this
slice's commit message -- is that it never throws, so a diagnostic
failure can never corrupt canonical evidence validity via
resolvePushEvidence's outer try/catch. A future caller (or test)
providing a runGit-shaped dependency that throws instead of returning
{error} would have silently broken that guarantee. Wrap the call in
its own try/catch and return UNKNOWN, matching the existing handling
for a returned result.error.

README test-count badges resynced via `pnpm run sync:readme` for the
added regression test (578 files / 6998+ tests).

Validated: full `pnpm run ci:prepush`, `pnpm run lint`, `pnpm run
typecheck` (4-checker), and both targeted test files all pass.
@qnbs

qnbs commented Aug 25, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

sourcery-ai[bot]
sourcery-ai Bot previously approved these changes Aug 25, 2026

@sourcery-ai sourcery-ai 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.

Sourcery assessment

Approved.

@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: d061c8e9ac

ℹ️ 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 scripts/signing/signing-core.mjs
…ope explicit inline

chatgpt-codex-connector correctly observed that an untracked file can
make git diff --quiet <sha> -- report MATCHES even when that file is
absent from the pushed commit (e.g. an untracked ambient .d.ts
satisfying an import the real commit is missing). This is not a new
gap -- it is the exact, deliberately-scoped limitation this slice's
design already reasons through: MATCHES is documented (commit message,
PR description, the report() wording in ci-prepush-lowend.mjs) as
"no tracked-content divergence detected", never "verified"/"validated",
and is never used anywhere as a skip condition for real verification.

Widening this check to also flag any untracked file (e.g. via
`git ls-files --others --exclude-standard`) was evaluated and rejected:
it would reintroduce exactly the false-positive-on-an-unrelated-scratch-
file problem this design avoids by construction today (a benign WIP
file anywhere in the repo would mark every push DIVERGED, making the
signal noisy enough to lose developer trust), and closing the gap
soundly would additionally require ruling out gitignored/generated-
artifact drift -- at which point the "cheap detector" has grown into
the isolated worktree that is Part 2's job, not Part 1's.

Added a one-line inline comment at the exact call site making this
scope boundary explicit in the code itself, not only in the commit
message and PR description, since a reviewer found it non-obvious
enough to flag independently.

No behavior change. Validated: full `pnpm run ci:prepush`, `pnpm run
lint`, `pnpm run typecheck` (4-checker), and both targeted test files
all pass.
@qnbs

qnbs commented Aug 25, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@sourcery-ai sourcery-ai 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.

Sourcery assessment

Approved.

@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@codecov

codecov Bot commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@qnbs
qnbs merged commit 85d2d94 into main Aug 25, 2026
33 checks passed
@qnbs
qnbs deleted the reconstruct-pr491-s3b-divergence-detection branch August 25, 2026 16:28
qnbs added a commit that referenced this pull request Aug 25, 2026
…roof (S3b Part 2a) (#502)

Part 2a of the S3b reconstruction slice (follows #501). Adds a diagnostic-only dependencyState dimension mirroring workingTreeState's 4-state model, comparing pushed commits' dependency manifests against the local reconciled baseline entirely via git objects, no worktree.

Full remediation history:
- aca9dbb: initial implementation
- 3abe3ba: fixed byte-identity (UTF-8 decoding vs raw bytes), CRLF/autocrlf false-DIVERGED, and diagnostic-isolation throw-safety (Sourcery + CodeRabbit + chatgpt-codex-connector findings)
- 4c019c3: fixed git ls-tree full-tree scoping and default path C-quoting (chatgpt-codex-connector finding)

Review epoch reached quiescence: 0 unresolved threads across all 3 channels (reviewThreads, issue comments, review bodies), fresh Sourcery APPROVED + Amazon Q "ready for merge" on the exact final commit, all 29 applicable CI checks green.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant