Skip to content

fix(acquisition): reject future deployment evidence timestamps - #484

Merged
seonghobae merged 6 commits into
mainfrom
fix/acquisition-deployment-future-timestamps
Aug 23, 2026
Merged

fix(acquisition): reject future deployment evidence timestamps#484
seonghobae merged 6 commits into
mainfrom
fix/acquisition-deployment-future-timestamps

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Purpose

Test-first hardening of buyer-facing deployment/acquisition evidence. This lane closes two authority classes without weakening release, attestation, KPI, or scanner gates:

  1. retained acquisition deployment evidence must reject future or impossible chronology instead of accepting any structurally parseable timestamp; and
  2. the deployment evidence builder must not coerce string values into authoritative 100% traffic or a sufficient KPI observation window.

Verified RED evidence

Protected/live base: 4916f189f0d9496c4dc189cc1ee51d5819fd53c4.

  • Temporal/acquisition RED: exact-head CI proved future generatedAt, deployedAt, deploymentCreatedAt, kpiExecutedAt, and smokeTimestamp, plus coerced traffic/reviewer authority, were accepted by the retained-evidence evaluator.
  • Builder traffic RED: c893c57b766cbc6be091cc0ff0b4e0d689ed8edb — the focused test requiring string "100" traffic to fail was the only new failing regression.
  • Builder KPI RED: b9ad49085c1a950aab5cdaf6ff076e606d5b3cf1 — exact-head CI reported exactly the two focused authority-type failures while the remaining 2,314 tests passed.

Repairs

  • c9c974e3272f92c7d94a538a1c5b1b07bf77703a: acquisition evaluator now validates non-future timestamps and Gregorian calendar dates, requires numeric trafficPercentage === 100, and requires a positive safe-integer reviewer count.
  • e29a503595d9487643500ff4ab7b9460046cbb88: deployment builder now requires numeric percentage === 100 and a safe-integer KPI window of at least 30 days; string coercion is no longer authority.

The final production delta is bounded to scripts/lib/acquisition-deployment-evidence.mjs and scripts/deployment-evidence.mjs, with realistic regressions in two test files.

Exact-head verification

Candidate: e29a503595d9487643500ff4ab7b9460046cbb88.

  • Application CI: PASS
  • reviewer-ci: PASS
  • central Security Scan: PASS
  • unresolved review threads: 0
  • branch contains the current live protected base with no behind commits at verification time

Authority boundary

This does not invent deployment evidence, customer operation, revenue, or transfer completion, and it does not replace Sigstore verification. It prevents malformed chronology and JSON type coercion from being promoted into acquisition-grade deployment authority.

@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@seonghobae, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 28 minutes

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

Wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c894b837-1f3a-4504-befe-3777ea5e5477

📥 Commits

Reviewing files that changed from the base of the PR and between 4916f18 and e29a503.

📒 Files selected for processing (4)
  • scripts/deployment-evidence.mjs
  • scripts/lib/acquisition-deployment-evidence.mjs
  • test/acquisition-deployment-evidence-temporal-integrity.test.ts
  • test/deployment-evidence-traffic-authority.test.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@seonghobae
seonghobae marked this pull request as ready for review August 23, 2026 01:41
@seonghobae
seonghobae merged commit 2d8a07d into main Aug 23, 2026
15 of 17 checks passed
@seonghobae
seonghobae deleted the fix/acquisition-deployment-future-timestamps branch August 23, 2026 01:41

@devin-ai-integration devin-ai-integration 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.

Devin Review found 2 potential issues.

Open in Devin Review

Comment on lines +180 to 181
deployment.deployment?.trafficPercentage === 100,
"deployment_traffic_not_full",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Coercion removal aligns with numeric producers

The stricter checks (match.percentage !== 100, Number.isSafeInteger(requireWindowDays), trafficPercentage === 100, safe-integer reviewer_count) reject strings. The producers all emit numbers: scripts/kpi-gate.mjs:44 writes a numeric window, scripts/lib/production-environment-governance.mjs:159 sets reviewer_count from reviewers.length, and the builder emits trafficPercentage: 100. Legitimate evidence stays accepted.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines 220 to +234
"deployment_smoke_failed",
"Deployment validation must prove successful post-deployment smoke checks.",
);
add(
failures,
isValidNonFutureTimestamp(deployment.validation?.kpiExecutedAt, nowMilliseconds),
"deployment_kpi_timestamp_invalid",
"Deployment KPI execution time must be a valid non-future timestamp.",
);
add(
failures,
isValidNonFutureTimestamp(deployment.validation?.smokeTimestamp, nowMilliseconds),
"deployment_smoke_timestamp_invalid",
"Deployment smoke time must be a valid non-future timestamp.",
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: New timestamp gates require builder fields present

The evaluator now hard-requires deployedAt, deploymentCreatedAt, kpiExecutedAt, and smokeTimestamp as valid non-future timestamps. Retained evidence missing any field, or produced on a runner whose clock leads the audit runner, now fails. The builder always emits these and audits run later, so real evidence passes.

(Refers to this code)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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