Skip to content

Commit 0a4e101

Browse files
authored
Merge pull request #1746 from adcontextprotocol/claude/issue-1695-owed-names
feat(reporting): use owed and list_subscription_principals, as the TypeScript SDK does
2 parents 5c722ea + e1263e7 commit 0a4e101

22 files changed

Lines changed: 123 additions & 65 deletions

‎docs/reliable-reporting-service.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,13 +422,13 @@ platform = reporting.install(MySeller()) # then serve the platform as usual
422422
The rest of this section describes the building blocks the managed path
423423
composes, for sellers who wire them by hand.
424424

425-
**Buyer.** `expected_subscription_periods(...)` is the coverage rule as a pure
425+
**Buyer.** `owed_subscription_periods(...)` is the coverage rule as a pure
426426
function over plain data. Pass it the `get_principal` subscription readback,
427427
the buys you can see (`SubscriptionBuy`, with earlier flights when a buy was
428428
extended or reinstated), the offerings with the seller's dimension mapping
429429
(`SubscriptionOffering`), the account timezone, the account's grant history,
430430
and the `subscription_coverage[]` exceptions and gaps. It returns
431-
`ExpectedSubscriptionPeriod` values, which are `ExpectedReportingPeriod`s, so
431+
`OwedSubscriptionPeriod` values, which are `ExpectedReportingPeriod`s, so
432432
they feed `evaluate_reporting_ledger` and the consumer-status planner as they
433433
are.
434434

‎docs/reporting-subscriptions-buyer.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ An `all_authorized_accounts` subscription follows every grant, including account
4949

5050
## Reconcile
5151

52-
`client.reporting.reconcile()` and `explain()` arrive in a later beta. Until then, `expected_subscription_periods(...)` and `ReportingSubscriptionTracker` compute owed periods from your own records (see [Coverage, explained](reporting-subscriptions-coverage.md#the-owed-rules)).
52+
`client.reporting.reconcile()` and `explain()` arrive in a later beta. Until then, `owed_subscription_periods(...)` and `ReportingSubscriptionTracker` compute owed periods from your own records (see [Coverage, explained](reporting-subscriptions-coverage.md#the-owed-rules)).
5353

5454
## Events
5555

‎docs/reporting-subscriptions-coverage.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Coverage, explained
22

3-
Both sides compute which periods a subscription owes with one function, `expected_subscription_periods`, over the same facts. Never compute periods yourself.
3+
Both sides compute which periods a subscription owes with one function, `owed_subscription_periods`, over the same facts. Never compute periods yourself.
44

55
## The owed rules
66

‎llms.txt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ docs/reporting-subscriptions-buyer.md.
8686
- DON'T pick `subscription_version` yourself: `subscribe` chooses it.
8787
- DO send an explicit scope: `{"all_authorized_accounts": True}` or `{"account_ids": [...]}`.
8888
- DON'T compute reporting periods with local time; use
89-
`expected_subscription_periods` (and, later, `client.reporting.reconcile`).
89+
`owed_subscription_periods` (and, later, `client.reporting.reconcile`).
9090
- DO switch on `next_step(outcome)` for accounts. DON'T fetch
9191
`pending_action.url`: show it to a person.
9292
- Sellers: DON'T call `engine.reconcile` from request handlers; the service

‎src/adcp/reporting/_reconcile.py‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ async def get_reporting_status(
7474

7575

7676
class ReportingReconciliationClient(ReportingStatusClient, Protocol):
77-
7877
async def sync_reporting_receipts(
7978
self, request: SyncReportingReceiptsRequest
8079
) -> TaskResult[SyncReportingReceiptsResponse]:

‎src/adcp/reporting/conformance.py‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -777,8 +777,7 @@ def _assert_cells_do_not_regress(
777777
if item.status in _AVAILABLE and (later is None or later.status not in _AVAILABLE):
778778
raise _fail(
779779
"REVISION_SEQUENCE_INVALID",
780-
f"{label} must not remove or degrade constituent availability from its "
781-
"predecessor",
780+
f"{label} must not remove or degrade constituent availability from its predecessor",
782781
)
783782
if item.data_through is not None and (
784783
later is None

‎src/adcp/reporting/feed/projection.py‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,9 +330,9 @@ def capture_feed(
330330
and owners[owner_id].generation_key in bindings
331331
and record.canonical_content_digest is not None
332332
):
333-
wires[identity][
334-
"canonical_content_digest"
335-
] = record.canonical_content_digest.to_wire()
333+
wires[identity]["canonical_content_digest"] = (
334+
record.canonical_content_digest.to_wire()
335+
)
336336
if record.supersedes_reporting_revision_id is not None:
337337
predecessor = revisions.get(record.supersedes_reporting_revision_id)
338338
if predecessor is None or predecessor.reporting_obligation_id != owner_id:
@@ -481,7 +481,9 @@ def capture_feed(
481481
finality = (
482482
revisions[revision_id].finality
483483
if revision_id in revisions
484-
else owners[owner_id].required_finality if owner_id in owners else None
484+
else owners[owner_id].required_finality
485+
if owner_id in owners
486+
else None
485487
)
486488
if finality not in finalities:
487489
matches = False

‎src/adcp/reporting/ledger/consumer_status.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ async def _find_period_obligation(
258258
and item.delivery_config_version == record.delivery_config_version
259259
and item.report_definition_id == record.report_definition_id
260260
),
261-
key=lambda item: (item.subscription.offering_id if item.subscription else ""),
261+
key=lambda item: item.subscription.offering_id if item.subscription else "",
262262
):
263263
candidate = await self.store.find_obligation(
264264
account_id=record.account_id,

‎src/adcp/reporting/ledger/reconciliation_projection.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,9 @@ def project_reconciliation(
258258
wire["reconciliation_status"] = (
259259
"rejected"
260260
if rejected
261-
else "accepted" if accepted and not pending_adjustments else "pending"
261+
else "accepted"
262+
if accepted and not pending_adjustments
263+
else "pending"
262264
)
263265
else:
264266
wire["reconciliation_status"] = "not_required"

‎src/adcp/reporting/outbox/worker.py‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,10 @@ async def deliver_one(self, *, account_id: str) -> bool:
226226
return False
227227
observation = _HttpObservation()
228228
if self.delivery_window is not None:
229-
observation.retry_deadline, observation.retry_window_expired = (
230-
await self.delivery_window.inspect(lease, now=self._clock())
231-
)
229+
(
230+
observation.retry_deadline,
231+
observation.retry_window_expired,
232+
) = await self.delivery_window.inspect(lease, now=self._clock())
232233
try:
233234
opened = self.cipher.open(lease.delivery)
234235
except (ReportingNotificationError, ValueError, TypeError):

0 commit comments

Comments
 (0)