Skip to content

docs(droid): capture what /limits calls, and record that this account has no window to read - #257

Merged
gcko merged 1 commit into
mainfrom
feature/drc-4073-usage-fetcher-droid-quota-via-factory-5h7d30d-windows-and
Sep 2, 2026
Merged

docs(droid): capture what /limits calls, and record that this account has no window to read#257
gcko merged 1 commit into
mainfrom
feature/drc-4073-usage-fetcher-droid-quota-via-factory-5h7d30d-windows-and

Conversation

@gcko

@gcko gcko commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Implements DRC-4073 — Usage fetcher · Droid quota via Factory (5h/7d/30d windows and credits), on the documented-verdict clause of its Done condition.

What changed

Docs only. No runtime code, no manifest, no version field.

  • docs/captures/droid/billing-limits-0.210.0-macos.jsonl: what Droid's /limits calls (GET https://api.factory.ai/api/billing/limits, bearer plus the CLI's X-Factory-* headers), the response shape on the signed-in account (four fields, no limits object, usesTokenRateLimitsBilling false), the CLI's own "Unable to fetch credit limits" verdict, the credential store (a Keychain-held key encrypting ~/.factory/auth.v2.loginkeychain), and the windowed shape read in the binary and labelled unmeasured. Shapes and closed-vocabulary values only.
  • docs/captures/README.md: the row for that file.
  • docs/design-usage-quota.md: Q-10's Factory row and paragraph now state the measurement; Q-5 records that Droid has no token Cargento may read and the DEC-10 ruling (FACTORY_API_KEY from Cargento's environment, for the reader that ships under DRC-4334); decrypting Droid's login store is a recorded rejected alternative.

User value

P4, sharpen, and the promise wording does not change. What a Droid user gets from this PR is an honest record: on an organization account Factory publishes no window, so Cargento shows nothing the vendor's own CLI cannot. The reader for individual plans is scoped in DRC-4334 and waits on an account that has windows.

Verification

  • python3 scripts/validate_plugins.py: passes (the check a docs-only diff needs).
  • python3 -m unittest cargento.skills.cargento.tests.test_documentation: OK, including the captures-table contiguity test that caught a stray blank line on the first attempt.
  • Full dashboard suite once, log saved: OK (skipped=1), no FAIL or ERROR lines. An earlier run of the same tree reported one unnamed failure that did not recur; DRC-4332 tracks the known wall-clock flake.
  • Tone check over the prose docs: clean.
  • No version field moved on this branch.
  • Live evidence: two /limits probes through the loopback proxy agreed; the capture file records both the request and the response shape.

Review depth: self-verified, per AGENTS.md's table (no behaviour change, nothing calls it).

… has no window to read

Droid's /limits command is GET https://api.factory.ai/api/billing/limits with a
bearer authorization and the CLI's X-Factory-Client, X-Client-Version and
X-Factory-Org-Id headers. Measured 2026-09-02 on droid 0.210.0 through a
loopback reverse proxy the CLI was pointed at with FACTORY_API_BASE_URL, two runs
agreeing: on the signed-in organization account the route answers 200 with four
fields (usesTokenRateLimitsBilling false, overagePreference, canManageOverage,
extraUsageAllowed) and no `limits` object, and Droid's own panel then reads
"Unable to fetch credit limits". The three rolling windows belong to individual
plans on token-rate-limits billing, and the shape the CLI is written against,
limits.standard.{fiveHour,weekly,monthly}.usedPercent, is read in the binary and
labelled unmeasured.

The credential the CLI sends is out of reach by design: a 44-byte encryption key
in the Keychain (service "Factory CLI") protects the session token in
~/.factory/auth.v2.loginkeychain, beside a refresh lock. DEC-10 (DRC-4333) chose
FACTORY_API_KEY from Cargento's own environment for the reader, which ships under
DRC-4334 once an account with windows can run this capture. The design record's
Q-5 and Q-10 carry the findings and the ruling, and decrypting the login store is
recorded as a rejected alternative.

Implements DRC-4073 on the documented-verdict clause of its Done condition.

Signed-off-by: Jared Scott <jared.scott@variable.team>
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Coverage

Name                                                                  Stmts   Miss Branch BrPart  Cover
-------------------------------------------------------------------------------------------------------
cargento/skills/cargento/agy_hook.py                                     79     14     28      7  78.5%
cargento/skills/cargento/cargento_runtime/__init__.py                     0      0      0      0 100.0%
cargento/skills/cargento/cargento_runtime/aggregate.py                  213      1     64      0  99.6%
cargento/skills/cargento/cargento_runtime/asks.py                       110      0     28      0 100.0%
cargento/skills/cargento/cargento_runtime/claude_data.py                305     33    142     17  88.8%
cargento/skills/cargento/cargento_runtime/cli.py                        120     17     26      4  84.2%
cargento/skills/cargento/cargento_runtime/collectors/__init__.py          0      0      0      0 100.0%
cargento/skills/cargento/cargento_runtime/collectors/antigravity.py     410     41    166     25  87.2%
cargento/skills/cargento/cargento_runtime/collectors/claude.py          256     15     94     12  91.7%
cargento/skills/cargento/cargento_runtime/collectors/codex.py           101      7     38      7  89.9%
cargento/skills/cargento/cargento_runtime/collectors/copilot.py         148      6     50      2  96.0%
cargento/skills/cargento/cargento_runtime/collectors/cursor.py          276     19    104     16  90.3%
cargento/skills/cargento/cargento_runtime/collectors/droid.py            32      3      6      1  89.5%
cargento/skills/cargento/cargento_runtime/collectors/gemini.py           53      7     16      4  84.1%
cargento/skills/cargento/cargento_runtime/collectors/goose.py            89     11     28      4  87.2%
cargento/skills/cargento/cargento_runtime/collectors/opencode.py         78      6     26      2  92.3%
cargento/skills/cargento/cargento_runtime/collectors/pi.py              326     34    152     20  88.7%
cargento/skills/cargento/cargento_runtime/config.py                     189      1     20      1  99.0%
cargento/skills/cargento/cargento_runtime/diagnostics.py                 84      4     26      4  92.7%
cargento/skills/cargento/cargento_runtime/dismissals.py                 113      2     28      2  97.2%
cargento/skills/cargento/cargento_runtime/events.py                     169      0     64      0 100.0%
cargento/skills/cargento/cargento_runtime/git_status.py                  28      2      8      2  88.9%
cargento/skills/cargento/cargento_runtime/http_api.py                   520     36    172     10  93.1%
cargento/skills/cargento/cargento_runtime/io.py                         130      2     28      0  98.7%
cargento/skills/cargento/cargento_runtime/lifecycle.py                  325     15    106      6  95.1%
cargento/skills/cargento/cargento_runtime/notifications.py              174     14     60      4  91.5%
cargento/skills/cargento/cargento_runtime/observation.py                271      9     74      1  97.1%
cargento/skills/cargento/cargento_runtime/observer.py                   239     25    108     13  87.3%
cargento/skills/cargento/cargento_runtime/probe.py                       44      0     18      1  98.4%
cargento/skills/cargento/cargento_runtime/quota.py                      333      2    112      1  99.3%
cargento/skills/cargento/cargento_runtime/records.py                    262      6    116     10  95.8%
cargento/skills/cargento/cargento_runtime/sessions.py                   101      0     44      0 100.0%
cargento/skills/cargento/cargento_runtime/snapshot.py                    36      0      4      0 100.0%
cargento/skills/cargento/cargento_runtime/spacedock.py                  454     48    238     26  89.0%
cargento/skills/cargento/cargento_runtime/state.py                       66      0      2      0 100.0%
cargento/skills/cargento/cargento_runtime/stream.py                      57      0      8      0 100.0%
cargento/skills/cargento/cargento_runtime/transcripts.py                523     31    268     27  92.7%
cargento/skills/cargento/cargento_runtime/turns.py                      197     14    104     12  90.7%
cargento/skills/cargento/cargento_runtime/web/__init__.py                 0      0      0      0 100.0%
cargento/skills/cargento/cargento_runtime/web/page.py                    38      0     10      0 100.0%
cargento/skills/cargento/event_hook.py                                   86      4     28      3  93.9%
cargento/skills/cargento/mcp_server.py                                  377     22    112     14  92.2%
cargento/skills/cargento/notify_hook.py                                  49     15      6      1  67.3%
cargento/skills/cargento/server.py                                        3      0      2      1  80.0%
cargento/skills/cargento/statusline_hook.py                             131     13     46      8  87.0%
scripts/bench_collect.py                                                211     10     54      6  94.0%
scripts/bench_event_latency.py                                           67     21     14      1  67.9%
scripts/bump_version.py                                                  60     12     24      5  77.4%
scripts/capture_hook.py                                                 287     30     86     11  88.5%
scripts/derive_prompt_shapes.py                                         210     16     88     14  89.3%
scripts/lint_embedded.py                                                 89      3     28      2  95.7%
scripts/validate_plugins.py                                             675    190    390     60  69.2%
-------------------------------------------------------------------------------------------------------
TOTAL                                                                  9194    761   3464    367  90.1%

Threshold: fail_under in pyproject.toml · label coverage-exception to bypass (visible in PR timeline).

@gcko
gcko merged commit 900b51c into main Sep 2, 2026
11 checks passed
@gcko
gcko deleted the feature/drc-4073-usage-fetcher-droid-quota-via-factory-5h7d30d-windows-and branch September 2, 2026 12:54
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