Skip to content

feat: replay source evidence with safe review and recovery (TAB-22–29) - #49

Merged
hudsonaikins merged 2 commits into
codex/tab-21-source-adaptersfrom
codex/tab-22-source-replay
Sep 12, 2026
Merged

hudsonaikins merged 2 commits into
codex/tab-21-source-adaptersfrom
codex/tab-22-source-replay

Conversation

@hudsonaikins

@hudsonaikins hudsonaikins commented Sep 12, 2026 •

Copy link
Copy Markdown
Contributor

TAB-22 through TAB-29: replay reconstructs provenance from source snapshots and real Git using an explicit evaluation time and expected digest. Changed or unavailable evidence returns blocked before persistence; accepted records and original sources remain intact. Git collection failures are isolated from healthy readers. Integrated child PRs add explicit evidence verdicts, bounded packets, separate security, safe review publication, and 11 failure/recovery demo cases.

Candidate 520cb3966e2fd59a9d974d905a7868016c102a10: required local validation, hosted product validation, and hosted Quality passed. Author review found no remaining code findings; the Plane bot reference is informational. PRs #50–55 are merged into this branch.

Stacked on #48. Fixture and blocked-result demonstrations satisfy the documented acceptance without claiming complete live-provider provenance. Foundation Buildkite still blocks main integration; release and deployment remain separate decisions.

Plane-Work-Item: TAB-22
Entire-Checkpoint: 95aae876ef91
@makeplane

makeplane Bot commented Sep 12, 2026 •

Copy link
Copy Markdown

Linked to Plane Work Item(s)

References

This comment was auto-generated by Plane

* feat: preserve safe source failure reasons in review packets

Plane-Work-Item: TAB-23
Entire-Checkpoint: 95aae876ef91

* feat: exact-candidate packets, security, and review (TAB-24–29) (#51)

* fix: enforce complete review packet bounds and candidate acceptance

Plane-Work-Item: TAB-25

Validates TAB-24 candidate movement and unrelated-history rejection.

Entire-Checkpoint: 7098fc8f9b88

* test: validate review packets with the native schema checker

Plane-Work-Item: TAB-25
Entire-Checkpoint: 7098fc8f9b88

* feat: exact security evidence, review, and recovery (TAB-26–29) (#52)

* feat: bind separate security checks to immutable review candidates

Plane-Work-Item: TAB-26
Entire-Checkpoint: 3a4c8131eec1

* ci: require pinned provenance security scanners

Plane-Work-Item: TAB-26
Entire-Checkpoint: 3a4c8131eec1

* feat: exact review results, safe publication, and recovery (TAB-27–29) (#53)

* feat: show actionable provenance review and GitHub statuses

Plane-Work-Item: TAB-27
Entire-Checkpoint: 3a4c8131eec1

* test: demonstrate failure recovery and secured review (TAB-28/TAB-29) (#54)

* test: demonstrate provenance failure and clean-store recovery (TAB-28)

Entire-Checkpoint: 3a4c8131eec1

* fix: review the secured lineage in the release demo (TAB-29) (#55)

* test: generate unsafe token fixture at runtime (TAB-29)

Entire-Checkpoint: 3a4c8131eec1

* fix: demonstrate review of the secured provenance lineage (TAB-29)

Entire-Checkpoint: 3a4c8131eec1

---------

Co-authored-by: hudsonaikins-crown <hudson.aikins@blanoire.co>

---------

Co-authored-by: hudsonaikins-crown <hudson.aikins@blanoire.co>

---------

Co-authored-by: hudsonaikins-crown <hudson.aikins@blanoire.co>

---------

Co-authored-by: hudsonaikins-crown <hudson.aikins@blanoire.co>

---------

Co-authored-by: hudsonaikins-crown <hudson.aikins@blanoire.co>

---------

Co-authored-by: hudsonaikins-crown <hudson.aikins@blanoire.co>
@hudsonaikins hudsonaikins changed the title TAB-22: rebuild provenance from pinned source snapshots feat: replay source evidence with safe review and recovery (TAB-22–29) Sep 12, 2026
@hudsonaikins
hudsonaikins marked this pull request as ready for review September 12, 2026 23:29
@hudsonaikins
hudsonaikins merged commit 5e94954 into codex/tab-21-source-adapters Sep 12, 2026
4 checks passed
@hudsonaikins
hudsonaikins deleted the codex/tab-22-source-replay branch September 12, 2026 23:29
hudsonaikins added a commit that referenced this pull request Sep 12, 2026
…48)

* feat: normalize candidate-bound provenance source snapshots

Plane-Work-Item: TAB-21
Entire-Checkpoint: 95aae876ef91

* fix: select comparison base for manual quality checks

Plane-Work-Item: TAB-21
Entire-Checkpoint: 95aae876ef91

* feat: replay source evidence with safe review and recovery (TAB-22–29) (#49)

* feat: rebuild provenance from pinned source snapshots

Plane-Work-Item: TAB-22
Entire-Checkpoint: 95aae876ef91

* feat: explicit provenance verdicts and safe review (TAB-23–29) (#50)

* feat: preserve safe source failure reasons in review packets

Plane-Work-Item: TAB-23
Entire-Checkpoint: 95aae876ef91

* feat: exact-candidate packets, security, and review (TAB-24–29) (#51)

* fix: enforce complete review packet bounds and candidate acceptance

Plane-Work-Item: TAB-25

Validates TAB-24 candidate movement and unrelated-history rejection.

Entire-Checkpoint: 7098fc8f9b88

* test: validate review packets with the native schema checker

Plane-Work-Item: TAB-25
Entire-Checkpoint: 7098fc8f9b88

* feat: exact security evidence, review, and recovery (TAB-26–29) (#52)

* feat: bind separate security checks to immutable review candidates

Plane-Work-Item: TAB-26
Entire-Checkpoint: 3a4c8131eec1

* ci: require pinned provenance security scanners

Plane-Work-Item: TAB-26
Entire-Checkpoint: 3a4c8131eec1

* feat: exact review results, safe publication, and recovery (TAB-27–29) (#53)

* feat: show actionable provenance review and GitHub statuses

Plane-Work-Item: TAB-27
Entire-Checkpoint: 3a4c8131eec1

* test: demonstrate failure recovery and secured review (TAB-28/TAB-29) (#54)

* test: demonstrate provenance failure and clean-store recovery (TAB-28)

Entire-Checkpoint: 3a4c8131eec1

* fix: review the secured lineage in the release demo (TAB-29) (#55)

* test: generate unsafe token fixture at runtime (TAB-29)

Entire-Checkpoint: 3a4c8131eec1

* fix: demonstrate review of the secured provenance lineage (TAB-29)

Entire-Checkpoint: 3a4c8131eec1

---------

Co-authored-by: hudsonaikins-crown <hudson.aikins@blanoire.co>

---------

Co-authored-by: hudsonaikins-crown <hudson.aikins@blanoire.co>

---------

Co-authored-by: hudsonaikins-crown <hudson.aikins@blanoire.co>

---------

Co-authored-by: hudsonaikins-crown <hudson.aikins@blanoire.co>

---------

Co-authored-by: hudsonaikins-crown <hudson.aikins@blanoire.co>

---------

Co-authored-by: hudsonaikins-crown <hudson.aikins@blanoire.co>

---------

Co-authored-by: hudsonaikins-crown <hudson.aikins@blanoire.co>

---------

Co-authored-by: hudsonaikins-crown <hudson.aikins@blanoire.co>

@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: 520cb3966e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +100 to +102
function dependencyVersions(bytes) {
const manifest = JSON.parse(bytes.toString("utf8"));
return ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"].flatMap((key) => dependencyGroup(manifest, key));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject non-object package manifests before passing dependency scan

When a tracked package.json contains valid JSON whose root is a primitive or array (for example, "not-an-object" or []), this function accepts it and each dependency lookup yields an empty group, so the dependency check reports passed; with otherwise-clean scanner outputs, the entire security review is incorrectly marked passed. Validate that the parsed manifest is a non-null, non-array object before inspecting its dependency groups so malformed manifests fail closed.

Useful? React with 👍 / 👎.

Comment on lines +40 to +44
const result = await execute("git", ["ls-tree", "-r", "-z", candidate.headCommit], { cwd: repo });
if (result.exitCode !== 0) throw new Error("Candidate tree unavailable.");
const files = new Map();
let totalBytes = 0;
for (const row of result.stdout.split("\0").filter(Boolean)) {

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 Reject undecodable Git paths before materializing the snapshot

On Linux, Git permits filenames containing invalid UTF-8 bytes, but this ls-tree output is decoded as UTF-8 before paths are parsed. Distinct byte paths such as 0x80.js and 0x81.js both become �.js, so the later blob overwrites the earlier one in the temporary directory and files map; security-sensitive content in the overwritten blob is never scanned, yet all checks can report passed. Read the NUL-delimited tree output as bytes and either preserve path bytes safely or fail closed on invalid encoding and decoded-path collisions.

Useful? React with 👍 / 👎.

Comment on lines +41 to +47
"checks": {
"type": "array",
"minItems": 4,
"maxItems": 4,
"items": {
"$ref": "#/$defs/check"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Require each security check category exactly once

When a consumer validates receipts solely against this published schema, a checks array containing four secrets entries is accepted even though the authorization, trust, and dependency checks are absent; the runtime importer requires the four categories in a fixed order, so the advertised contract disagrees with the actual security invariant. Constrain the array so each required category appears exactly once, for example with fixed prefixItems or per-category contains constraints.

Useful? React with 👍 / 👎.

Comment on lines +84 to +86
const attempt = await ledger.write(path, receipt, { expectedVersion: prior.version });
const completed = { ...receipt, ...await sendStatuses({ repo, intent, base, head, publisher }) };
await ledger.write(path, completed, { expectedVersion: attempt.version });

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 Retry receipt completion after unrelated ledger writes

When two different approvals publish concurrently, both use the same refs/tabellio/provenance-statuses ref: after approval A reserves its path, approval B can reserve another path and advance the ref before A completes. A may then publish both GitHub statuses successfully but this write still uses A's old attempt.version, so it fails with a ledger conflict and leaves A permanently pending; subsequent attempts are blocked as uncertain. Complete the per-approval receipt with a CAS retry that reloads the latest ref and verifies that A's reserved entry is unchanged, or serialize all writers to this ledger.

Useful? React with 👍 / 👎.

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.

1 participant