Say what absence means for every optional field - #10
Merged
Conversation
Sixteen of the twenty-four optional fields on ProviderUsage carried no doc comment at all. A consumer reading the type — which is where a Rust consumer stands, rather than in the producer's markdown contract — had to infer what each absence meant, and the inference that reads as unremarkable is usually the fail-open one. Doc comments only; no shape, serde attribute, or behaviour changes. Three of these are load-bearing rather than tidy: - The three window slots CAN HAVE HOLES. Each is filled from its own optional upstream field, so `secondary` may be absent while `tertiary` is present. A consumer stopping at the first gap misses real limits. - `saved_resets` absent is NOT "zero credits held". It also covers the credit-inventory lookup having failed on that fetch, since that lookup is separate from the usage fetch and may fail without degrading the entry. - `account` absent means the producer could not resolve an identity, not that the provider has one account — so an unlabelled entry is not evidence that a labelled one does not exist. The rest state the same thing in smaller ways: an absent `org_name` is not a personal account, an absent `plan_type` is not a missing plan, an absent `window` on an ExtraWindow is a limit whose figure could not be read rather than an absent limit.
A doc comment that states a fact invites agreement; one that states what breaks invites care. Two of these were facts only. `raw_used_percent` said what it is and that UIs should display it, and never said which number to pace on. The natural reading — the raw figure is the truer one — routes work away from an account whose credit is about to be spent, and the credit expires whether or not it is used, so the cautious-looking reading is the lossy one. `source` said "observability only", which is true and does not stop anyone keying on it. It is per-lane rather than per-account and changes between polls with nothing having changed about the account, so a consumer treating a change as an event sees phantom transitions.
There was a problem hiding this comment.
1 issue found across 1 file
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="crates/cortexkit-provider-usage/src/lib.rs">
<violation number="1" location="crates/cortexkit-provider-usage/src/lib.rs:160">
P2: The new doc says absent `soonest_expires_at` means "no credit states an expiry", but that contradicts the type it documents: `CreditExpiry` has a required `expires_at: String`, so every element of `credits` necessarily states an expiry. The sentence is only consistent when `credits` is empty, and it misleadingly implies a non-empty inventory could coexist with "no credit states an expiry". Suggest reword to what the field actually means (the producer did not surface a soonest expiry) so consumers aren't misled.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| pub struct SavedResets { | ||
| #[serde(default)] | ||
| pub available_count: u32, | ||
| /// When the next credit lapses. Absent means **no credit states an expiry**, |
There was a problem hiding this comment.
P2: The new doc says absent soonest_expires_at means "no credit states an expiry", but that contradicts the type it documents: CreditExpiry has a required expires_at: String, so every element of credits necessarily states an expiry. The sentence is only consistent when credits is empty, and it misleadingly implies a non-empty inventory could coexist with "no credit states an expiry". Suggest reword to what the field actually means (the producer did not surface a soonest expiry) so consumers aren't misled.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/cortexkit-provider-usage/src/lib.rs, line 160:
<comment>The new doc says absent `soonest_expires_at` means "no credit states an expiry", but that contradicts the type it documents: `CreditExpiry` has a required `expires_at: String`, so every element of `credits` necessarily states an expiry. The sentence is only consistent when `credits` is empty, and it misleadingly implies a non-empty inventory could coexist with "no credit states an expiry". Suggest reword to what the field actually means (the producer did not surface a soonest expiry) so consumers aren't misled.</comment>
<file context>
@@ -123,6 +157,8 @@ pub struct CreditExpiry {
pub struct SavedResets {
#[serde(default)]
pub available_count: u32,
+ /// When the next credit lapses. Absent means **no credit states an expiry**,
+ /// which is not the same as none expiring soon.
#[serde(skip_serializing_if = "Option::is_none", default)]
</file context>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Sixteen of the twenty-four optional fields on
ProviderUsagecarried no doc comment at all. A consumer reading the type — which is where a Rust consumer stands, rather than in the producer's markdown contract — had to infer what each absence meant, and the inference that reads as unremarkable is usually the fail-open one.Doc comments only. No shape, serde attribute, or behaviour changes.
cargo fmt,clippy -D warningsand tests clean; astrocyte (which path-depends on this crate) builds unchanged.Three of these are load-bearing rather than tidy:
secondarymay be absent whiletertiaryis present. A consumer stopping at the first gap misses real limits — this is a live bug shape, not a hypothetical one.saved_resetsabsent is not "zero credits held". It also covers the credit-inventory lookup having failed on that fetch, since that lookup is separate from the usage fetch and may fail without degrading the entry. Verified at the producer call site.accountabsent means the producer could not resolve an identity, not that the provider has one account — so an unlabelled entry is not evidence that a labelled one does not exist.The rest state the same thing in smaller ways: an absent
org_nameis not a personal account, an absentplan_typeis not a missing plan, an absentwindowon anExtraWindowis a limit whose figure could not be read rather than an absent limit.Found by enumerating every optional field from the
skip_serializing_ifattributes and checking each against the documented semantics, rather than by anything going wrong.Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Summary by cubic
Doc comments now define absence semantics on all optional usage fields; no type, serde, or behavior changes. Clarifies pitfalls: window slots can have holes;
saved_resetsabsent is not zero;accountabsent means identity unresolved; pace onused_percentnotraw_used_percent;sourceis per-lane and unstable.Written for commit ac99e23. Summary will update on new commits.