feat(tui): provider-accepted Computer meter receipts - #5781
Conversation
Bind v3 Computer admission (profile, 1x/2x/4x multiplier, account, quote, expiry) before dispatch. Mint immutable receipts only for provider-accepted active seconds at per-second granularity. Reject wall-clock-if-idle, queued/stopped/teardown time, and allocations that do not exactly match standard-8/16/32. Tests use hermetic Daytona-shaped fixtures. No live provider call, no charge, no deploy. Signed-off-by: CodeWhale Bot <bot@codewhale.net>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Claude finished @Hmbown's task in 3m 11s —— View job Review complete
This is a source-only, additive module ( Note: I wasn't able to run Findings1. Admission expiry only checks interval start, not end — let expires = parse_timestamp(&admission.expires_at, "expiresAt")?;
if started >= expires {
return Err(ComputerMeterError::AdmissionExpired);
}Only 2. pub fn sum_standard_equivalent_seconds(receipts: &[ComputerMeterReceipt]) -> u64 {
receipts.iter().map(|r| r.standard_equivalent_seconds).fold(0, u64::saturating_add)
}
Minor / lower-confidence notes
|
Signed-off-by: CodeWhale Bot <bot@codewhale.net>
|
Claude finished @Hmbown's task in 2m 1s —— View job Review complete
This "synchronize" trigger only adds commit Findings1. Admission expiry only checks interval start, not end — let expires = parse_timestamp(&admission.expires_at, "expiresAt")?;
if started >= expires {
return Err(ComputerMeterError::AdmissionExpired);
}Only 2. pub fn sum_standard_equivalent_seconds(receipts: &[ComputerMeterReceipt]) -> u64 {
receipts.iter().map(|r| r.standard_equivalent_seconds).fold(0, u64::saturating_add)
}
Additional observation (new, not in the earlier review)3. Sandbox↔admission binding is enforced only by the Good choices
|
There was a problem hiding this comment.
Codewhale review
The PR adds a new computer_meter module that binds immutable admission records and mints receipts only for provider-accepted active seconds. It includes fixture-based tests and a cloud_dispatch helper. The core design is sound, but an admission expiry boundary check is incomplete and the PR includes unrelated changelog entries.
Findings
- [ERROR] Admission expiry is not enforced for intervals that cross the expiry boundary (
crates/tui/src/computer_meter.rs)
In issue_computer_meter_receipt, only the interval start is checked against admission.expires_at. A provider-accepted interval that begins before expiry but ends after expiry is billed for the entire duration, including seconds after admission expiry. This can over-bill the customer and contradicts the admission expiry contract. The function should fail closed when ended_at is after expires_at, or truncate the interval before billing. - [WARNING] Unrelated changelog entries included in PR (
CHANGELOG.md)
Both CHANGELOG.md and crates/tui/CHANGELOG.md add a Pod-language entry referencing #5776. These entries appear unrelated to Computer meter receipts and likely came from another branch. They should be removed to keep this PR focused and avoid misleading release notes. - [INFO] Missing test for cloud job sandbox id mismatch (
crates/tui/src/cloud_dispatch.rs)
meter_cloud_job is a public wrapper that rejects mismatched job.sandbox_id, but the new sandbox_create_is_not_computer_entitlement test only covers a matching sandbox and idle/accepted observations. A test should verify that a mismatched sandbox id fails closed with computer_meter_allocation_mismatch. - [INFO] Several error variants and correction error paths are not tested (
crates/tui/src/computer_meter/tests.rs)
The fixture pack covers many happy-path and failure cases, but there are no tests for AdmissionExpired, IntervalReversed, RevisionMismatch, ReferenceInvalid, TimestampInvalid, or correct_computer_meter_receipt error branches such as account/admission mismatch or profile/multiplier differences. Adding at least the expiry-crossing test would also strengthen confidence in issue #5781.
Assessment
The module is well-structured and the receipt flow is mostly fail-closed, but the incomplete expiry-boundary enforcement is a billing-honesty bug that should be fixed before merge. Unrelated changelog entries should also be removed. Additional negative tests would materially improve coverage.
Advisory review by Codewhale (codewhale review --pr 5781 --post, head 45f54eceaa18037930d453282e95d81dc23ce484). Line-specific findings are also posted as inline review comments; mechanical fixes arrive as committable suggestions you can apply from the Files tab. CODEOWNERS approval still governs merge.
No-Issue: source-only PRODUCT_PRD §7 Computer meter receipts; no tracked Engine issue yet.
Summary
Source-only v3 Computer metering honesty for Codewhale Engine. Codewhale remains the billing authority; Daytona supplies infrastructure.
standard-8/standard-16/standard-32), CPU/RAM/disk, 1x/2x/4x multiplier, meter/catalog revisions, account, funding authority, quote identity, and expiry in an immutable admission record before dispatch.cloud_dispatchsandbox create is infrastructure identity, not entitlement;meter_cloud_jobrequires admission plus a provider-accepted active observation.No live Daytona, no charge, no deploy.
Testing
scripts/dev-test.sh crates/tui/src/computer_meter.rs(4/4)sandbox_create_is_not_computer_entitlement(1/1)cargo fmt -p codewhale-tuicargo fmt --all -- --check(not run; leaf change)cargo clippy --workspace --all-targets --all-features --locked(not run; leaf change)cargo test --workspace --all-features --locked(not run; leaf change)Hermetic fixtures live in
crates/tui/src/computer_meter/fixtures/cases.json.Checklist
crates/tui/src/computer_meter.rsas the Engine receipt authority. Does not replacecloud_dispatchlaunch; that remains infrastructure-only.Signed-off-by: CodeWhale Bot bot@codewhale.net