Skip to content

Include retained TextContent logical bytes in repository usage #829

Description

@ScottArbeit

September 7 recovery status

Deferred content-inclusion work. The accepted logical UTF-8, retention, identity and description-availability requirements remain useful. The old mandatory Issue #879 ancestry, bytes-minute producer assumption, epic-branch targeting and execution checklist are superseded. Issue #1045 first establishes what current sources can measure truthfully. Do not implement this issue until a fresh checkpoint selects its measurement contract.

Scott approved D1-D5 in Issue #554. That parent now controls selected scope and current dev-process execution. The original proposal below is retained as historical evidence, not an assignment to resume it.

Historical proposal

Include retained TextContent logical bytes in repository usage

Parent epic: #554 - Grace.Operations usage accounting, billing proof, and cost reconciliation

Related feature epic: #825 - Implement blob-backed work-item descriptions

Deferred from Epic #825

Owner decision on 2026-08-10 selected Option A: Epic #825 ships the Product V1 description feature without claiming retained TextContent usage accounting. This issue moved to Operations epic #554 and remains open future work.

Do not assign implementation until #879 merges the accepted Operations SQL usage-fact journal, dispatcher, worker, and
completeness foundation. This issue then owns the first production repository-storage producer: it must append the
journal before broker delivery and retain enough durable measurement source to retry a failed append. Current Grace has
the fact contract, direct Service Bus publisher helper, ingestion, dedupe, and aggregation, but no production
repository-storage producer. Do not create a second journal, a parallel TextContent ledger, or direct synchronous
Operations SQL coupling from Grace.Actors.

Objective

Extend the repository storage usage measurement owned by Grace.Operations so every retained TextContent object
contributes its uncompressed UTF-8 byte length exactly once, regardless of GZip size or whether a later Description
supersedes or clears it.

Why this matters

TextContent consumes repository storage and must participate in usage limits and billing like other repository content.
Counting compressed size would make charges depend on compression ratio rather than the logical user payload, while a
description-specific accounting path would diverge from the shared Operations ledger.

Quality contract

Profile: Product V1.

Primary invariant: each retained repository TextContent object contributes exactly its recorded uncompressed
Utf8ByteLength to the repository storage bytes-minute observation, independent of compressed size, retries,
supersession, or clearing.

Dependency: re-check #554 and current main before assignment. Reuse the accepted repository storage observation and
projection contract. Do not create a parallel accounting ledger inside WorkItem or TextContent code.

Complexity stop: stop if #554 has not established a usable repository storage measurement seam, if implementation
requires a second billing fact interpretation, or if accurate inclusion requires a new durable state machine not already
accepted by #554.

Context and evidence

Decision closure and contract propagation

Accepted behavior

  • Usage quantity uses uncompressed Utf8ByteLength, never GZip object length.
  • Every retained TextContent object counts, including superseded descriptions and distinct objects containing identical
    text.
  • Clear changes no retained-byte quantity.
  • A newly created object conclusively deleted after known actor rejection stops contributing.
  • Temporary drift is accepted under the existing deferred usage pipeline.
  • Description writes add no synchronous quota reservation, lock, or hard concurrent limit.
  • Existing Operations replay, dedupe, correction, and owner/org/repository scoping remain the only accounting path.
  • This issue does not expose TextContent IDs, hashes, or per-object detail to users.

Propagation map

Surface Status Notes / proof
Shared DTOs, parameters, commands, events, persisted state Not changed or updated only at accepted usage seam No work-item public shape change
HTTP route, validation, permissions, error shape Not changed Description requests do not synchronously reserve usage
CLI JSON/stdout/stderr/help/examples Not changed No new usage command
SDK/facade client Not changed No TextContent accounting details exposed
Static OpenAPI and generated clients Not changed No public API change
Usage facts and Operations projections Updated Existing repository storage observation includes TextContent logical bytes
Events/webhooks/SignalR/watch/search/projections N/A outside Operations No new product event surface
Docs/ADRs/agent guidance Updated Logical-vs-compressed accounting and #554 dependency
Focused tests and final validation Updated Observation, dedupe/replay, retry, retention, and compression-ratio proof

Owned paths

  • The repository storage measurement source accepted by Epic: Grace Operations usage visibility and explainable accounting #554 after current-head preflight
  • Focused src/Grace.Types/Usage.Types.fs or usage helper changes only if the existing contract requires extension
  • src/Grace.Actors/OperationalFactsPublisher.Actor.fs only if the accepted producer seam requires it
  • src/Grace.Operations*/** projection and test paths needed to include TextContent in repository storage quantity
  • Focused server or TextContent storage metadata/index seam required by the accepted Epic: Grace Operations usage visibility and explainable accounting #554 measurement design
  • Matching Types, actor publisher, server integration, and Operations tests
  • Usage/accounting and coordination-surface documentation

Forbidden or sensitive paths

  • A WorkItem-specific or TextContent-specific billing ledger.
  • A new public UsageFact kind without owner-approved expansion of Epic: Grace Operations usage visibility and explainable accounting #554.
  • Compressed blob size as billed or limited quantity.
  • Synchronous quota reservation or hard-limit locking in description writes.
  • Decrementing retained usage when a Description is superseded or cleared.
  • Exposing per-object TextContent IDs, hashes, or storage locations in owner usage APIs.
  • Provider cost or reconciliation details in user-visible responses.
  • Changes to description set/clear semantics.
  • Compatibility or stored-data conversion behavior.

Risk surfaces

  • Proof/test work
  • DTO or contract work at the usage seam
  • Storage, Service Bus, Operations worker, and Aspire
  • Async/runtime behavior
  • Usage/billing projection
  • Final audit and docs

Minimum detail gate

Invariant tuple

  • Measurement: repository storage bytes-minute observation.
  • Identity dimensions: owner ID, organization ID, repository ID, storage pool ID, minute bucket, and retained
    TextContent identity as required by the accepted producer/projection dedupe design.
  • Quantity source: uncompressed TextContent.Utf8ByteLength for retained objects.
  • Durable path: accepted Epic: Grace Operations usage visibility and explainable accounting #554 usage fact ingestion and projection; no parallel ledger.

Forbidden implementation shapes

  • Publishing a one-time bytes-added value as though it were a bytes-minute observation.
  • Counting compressed object length.
  • Counting only the current description while earlier objects remain stored.
  • Double-counting matching retries or replayed usage evidence.
  • Coupling description success to Operations availability.
  • Inventing a new counter actor or per-description accounting state without owner review.

Expected tests

  • Positive: one retained object; multiple versions; identical text with distinct IDs; create description; set description.
  • Negative: retry/replay duplicate; conclusively deleted failed-write object; malformed or missing accounting source facts;
    Operations unavailable does not fail description mutation.
  • Regression: existing repository storage observations and owner/org/repository scope remain correct; no public contract
    exposes per-object details.
  • Boundary: compressible and incompressible payloads with equal UTF-8 lengths contribute equally; clear changes no
    quantity; large accepted payload uses its exact uncompressed length.

High-risk adversarial examples

  • A 65,536-character highly compressible description occupies few physical bytes; logical usage still records its full
    UTF-8 length.
  • The same description operation is retried after an uncertain result; retained bytes are not counted twice.
  • Two separate descriptions contain identical text; both retained objects count.
  • Current description is cleared; all older objects continue to count.
  • Operations ingestion is temporarily unavailable; description succeeds and deferred accounting recovers through the
    existing Epic: Grace Operations usage visibility and explainable accounting #554 mechanism.

Selected risk-surface traps

  • Usage semantics: preserve minute observation rather than treating it as a delta.
  • Storage: count retained logical bytes, including non-current content.
  • Replay/dedupe: deterministic proof must fail if quantity doubles.
  • Runtime: description availability must not depend on Operations availability.
  • Final audit: reconcile this issue's implementation with current Epic: Grace Operations usage visibility and explainable accounting #554 contracts before claiming completion.

Explicit N/A waivers

  • CLI/SDK/OpenAPI: N/A; no user-facing usage command or per-object contract is added.
  • Hard concurrent limit: N/A by accepted design; deferred pipeline drift is allowed.
  • Provider reconciliation/cost: N/A; remains owned by Epic: Grace Operations usage visibility and explainable accounting #554 workstreams.
  • Data compatibility: N/A; Grace has no production data.

Implementation steps

  1. Re-read Epic: Grace Operations usage visibility and explainable accounting #554, its active usage workstreams, and current main usage contracts before assignment.
  2. Record the accepted repository storage measurement producer/projection seam in the issue or PR.
  3. Stop for owner review if no stable bytes-minute producer seam exists or if the required change conflicts with Epic: Grace Operations usage visibility and explainable accounting #554.
  4. Add a failing focused test showing one retained TextContent's uncompressed length is absent from repository storage
    quantity.
  5. Extend the accepted logical storage measurement source to include retained TextContent.
  6. Use TextContent.Utf8ByteLength; do not inspect or report GZip object length as logical usage.
  7. Count every retained TextContent object once under owner/org/repository/storage-pool scope.
  8. Continue counting superseded descriptions because their objects remain stored.
  9. Make clear leave the retained-byte quantity unchanged.
  10. Stop counting only an object conclusively deleted after a known failed mutation.
  11. Preserve description mutation success when the Operations pipeline is unavailable.
  12. Use existing Epic: Grace Operations usage visibility and explainable accounting #554 retry, replay, dedupe, correction, and minute-normalization behavior.
  13. Add proof that matching retries and replay do not double-count.
  14. Add proof that two distinct objects with identical text are both counted.
  15. Add proof that equal uncompressed lengths contribute equal quantity despite different compression ratios.
  16. Add proof for create, set, supersede, clear, and conclusively deleted failed-write cases.
  17. Add proof that owner/org/repository/storage-pool scope remains unchanged.
  18. Add proof that no per-object identifiers or hashes enter public owner-usage responses.
  19. Update Operations and coordination-surface documentation with logical-byte semantics and pipeline freshness.
  20. Format touched F# files and run focused Types/Operations/server tests plus git diff --check.
  21. Run the Epic: Grace Operations usage visibility and explainable accounting #554-selected integration or Aspire proof when the accepted producer crosses Service Bus/worker storage.
  22. Record any residual lag or reconciliation risk without adding synchronous enforcement.

Validation profile

Primary profile: deployment-runtime if the accepted producer crosses Service Bus/worker storage; otherwise
domain-contract with focused Operations projection proof. Select exactly one broad final local gate only when current
epic #554 guidance requires it.

Public behavior under test

  • Boundary: repository storage usage observation and owner-scoped Operations projection.
  • Behavior: retained TextContent contributes uncompressed logical bytes exactly once without affecting description
    availability.
  • RED evidence: current code has usage ingestion plumbing but no proven TextContent inclusion source.

Path lease conflict score

3 - cross-epic accounting surface. This issue depends on #554's current contract and may overlap Operations files.
Do not start concurrently with an active #554 branch touching the same producer/projection files. Refresh and compare
write sets immediately before assignment.

Expected validation

  • Run focused usage-type, publisher, ingestion, projection, retry/replay, and description-availability tests selected by
    the actual implementation seam.
  • Use Aspire or the Epic: Grace Operations usage visibility and explainable accounting #554 runtime profile if Service Bus and Operations worker behavior changes.
  • Run formatting, docs lint, generated checks if applicable, and git diff --check.
  • GitHub Validate and fresh Sol High review are required for the same PR head.
  • Do not stack Fast/Full on another selected broad gate.

Docs impact

Update Operations usage semantics and the coordination-surface design to state that retained TextContent uses
uncompressed UTF-8 length, prior versions remain billable while retained, clearing does not reduce usage, and accounting
is deferred rather than synchronously reserved.

Definition of done

  • All 22 implementation steps are completed or explicitly marked N/A with issue evidence.
  • Current Epic: Grace Operations usage visibility and explainable accounting #554 contracts are rechecked and reused without a parallel ledger.
  • Every retained TextContent object contributes exact uncompressed UTF-8 bytes once.
  • Retry, replay, duplicate text, supersession, clear, failed-write deletion, and compression-ratio proof passes.
  • Description success remains independent of Operations availability.
  • Public owner usage exposes no TextContent internal facts.
  • Worker self-review finds no accounting-semantics or cross-epic conflict gap.
  • A ready-for-review PR targeting the epic branch links this issue.
  • GitHub Validate and a fresh Sol High review pass for the same PR head.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions