Skip to content

Say what absence means for every optional field - #10

Merged
ualtinok merged 2 commits into
masterfrom
docs/optional-field-absence
Aug 7, 2026
Merged

Say what absence means for every optional field#10
ualtinok merged 2 commits into
masterfrom
docs/optional-field-absence

Conversation

@ualtinok

@ualtinok ualtinok commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

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. cargo fmt, clippy -D warnings and tests clean; astrocyte (which path-depends on this crate) builds unchanged.

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 — this is a live bug shape, not a hypothetical one.
  • 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. Verified at the producer call site.
  • 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.

Found by enumerating every optional field from the skip_serializing_if attributes and checking each against the documented semantics, rather than by anything going wrong.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with 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_resets absent is not zero; account absent means identity unresolved; pace on used_percent not raw_used_percent; source is per-lane and unstable.

Written for commit ac99e23. Summary will update on new commits.

Review in cubic

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.

@cubic-dev-ai cubic-dev-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.

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**,

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

@ualtinok
ualtinok merged commit 28f28f4 into master Aug 7, 2026
8 checks passed
@ualtinok
ualtinok deleted the docs/optional-field-absence branch August 7, 2026 11:53
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