Commit graph

37 commits

Author SHA1 Message Date
Meta Vens
549962cb8a quota meter: the weekly reading comes from the CLI's own rate-limit event; while a lease is live and the reading is stale the connector makes the smallest real call. The usage poll and its HTTP client go: the setup token can never reach that endpoint (squash of eureka-body/quota-meter-stream 7d4c1bf..c298d9d; Soul s4-s5)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 13:12:31 +01:00
Meta Vens
7d4c1bf56e usage-meter-poll: gate fixes: the timeout is read per request, serve has a refusal test, the RFC 850 guard is pinned
The timeout field was read only by a test (dead_code under -D warnings), so
ask() applies it to each request. The serve wrapper is reached by a
subprocess refusal test (no network); the serve test fails inside 30 s
instead of hanging; "Wednesday 21-Oct-26 ..." (no comma) is refused.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 03:30:55 +01:00
Meta Vens
8fb8b5a71d usage-meter-poll: the serve test asks a loopback fake, never the provider (finding serve-test-asks-real-provider)
serve_config is the public wrapper over a crate-private serve_config_with
that takes the usage client; the test runs it in-process against a fake and
asserts the fake received GET /api/oauth/usage with the bearer. The endpoint
is not a document field or env, so whoever writes the config cannot redirect
the token. The subprocess test that reached api.anthropic.com is deleted.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 03:17:08 +01:00
Meta Vens
f242290ca5 usage-meter-poll: pin what the production client is built with (finding new-client-timeout-unpinned)
UsageClient carries its timeout and url; UsageClient::production() is what
start() builds, and the test asserts that client's url and 10 s timeout as
spec r2 says, replacing a 1..=60 s bound no rule names.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 03:17:08 +01:00
Meta Vens
481428a7ce usage-meter-poll: Retry-After reads all three HTTP-date forms (finding retry-after-obsolete-date-forms)
RFC 9110 10.2.3 makes a recipient accept IMF-fixdate, RFC 850 and asctime;
the last two read as absent and the poll asked again at the floor. The
two-digit RFC 850 year more than 50 years ahead is the latest past year.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 03:17:08 +01:00
Meta Vens
e17ef16d48 usage-meter-poll: a subprocess test that serve --config starts the poll
Spawns the claude-connector binary on a ready document and reads the
usage poll state line from its stderr; the connector must also stay up.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 02:49:16 +01:00
Meta Vens
c1cc349b19 usage-meter-poll: the cell decides how a reading combines; a poll is as old as its question
QuotaCell::observe_at is the one decision for both sensors: a reading older
than the held one is dropped, and a rejection stands against a reading that
only reports utilization (status polled) until its window resets or a reading
that carries its own verdict replaces it. The poll stamps its answer with the
moment it asked. Also: Retry-After in HTTP-date form is honoured; a refused
token is not sent again until it reads differently (the poll thread no longer
exits); the client's timeout is a parameter so a silent endpoint is tested;
tests pin redirects(0), the two-window mapping, the slow-server race, and the
late poll against a rejection.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 02:49:16 +01:00
Meta Vens
6982cbca7e usage-meter-poll: pin the log lines and the thread loop
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 01:44:35 +01:00
Meta Vens
7f3a46313e usage-meter-poll: test helper no longer shadowed by its own binding
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 01:37:29 +01:00
Meta Vens
9143d2c5e2 usage-meter-poll: serve_config starts the poll beside the leases
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 01:35:51 +01:00
Meta Vens
79792eea85 usage-meter-poll: the usage poll, the QuotaCell's second sensor
usage_poll asks the subscription's usage endpoint when the seven_day
reading is 15 min old or older, maps five_hour and seven_day onto
PlanQuota with status polled, and honours Retry-After; failures wait,
log once per change of state, and never touch the cell.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 01:35:50 +01:00
Meta Vens
c1802d85be lease v2: committed byte goldens, rustfmt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 05:38:48 +01:00
Meta Vens
cfea6854ab lease tests: the fake unit record is global, keep it on invocation 1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 05:30:41 +01:00
Meta Vens
9f10887169 lease v2: byte goldens, hold-loop and lease-helper tests
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 05:27:38 +01:00
Meta Vens
9db62027eb connector-usage-only: comment
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 05:08:19 +01:00
Meta Vens
7d9a6392a7 connector-usage-only: comments
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 04:59:02 +01:00
Meta Vens
a828602649 connector-usage-only: drop a stray doc comment
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 04:54:14 +01:00
Meta Vens
bb8909f2c2 connector-usage-only: regenerate v4 goldens and schemas, format, fix tests
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 04:51:05 +01:00
Meta Vens
28f2e5d2e7 connector-usage-only: test import
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 04:49:29 +01:00
Meta Vens
dcb5f109f7 connector-usage-only: store-failure tests, README front door
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 04:48:24 +01:00
Meta Vens
af5da3dfaa connector-usage-only: test fixes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 04:44:45 +01:00
Meta Vens
702e903fdd connector-usage-only: fix serve test splice
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 04:44:01 +01:00
Meta Vens
06a47bb13f connector-usage-only: delete the dollar authorities (WIP, does not yet build)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 04:43:18 +01:00
Meta Vens
d2b82a6c50 lease-persona-callers: the identity bound keeps room for the Persona sequence
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 01:59:39 +01:00
Meta Vens
47a4dcc6b4 lease-persona-callers: model-connector lease callers take the turn
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 01:58:12 +01:00
Meta Vens
1bf9fdb437 lease-persona-callers: rustfmt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 01:57:21 +01:00
Meta Vens
13cbdaf23c lease-persona-callers: a lease caller names its turn kind; Persona and Self of one caller lease side by side
LeaseTurn {SelfRun, PersonaTurn} on LeaseCaller and LeaseCallerConfig; the unit derives from the turn; Busy is keyed (caller, turn); a Persona invocation leases in sequence as lease:<invocation>:<n>, one open at a time. config add-lease-caller and init take --turn self|persona.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 01:56:34 +01:00
Meta Vens
fdcfa063c7 connector-many-callers: one connector serves every Mind as its own caller; session handles are an HMAC under a connector secret over caller, session, instance, instructions, model and transcript prefix; config add-caller/add-lease-caller; one owner for distinct admissions (squash of eureka-body/connector-many-callers d1f25b5..a96b276; Soul s1-s2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 00:11:53 +01:00
Meta Vens
d1f25b5ae6 claude-self-run-lease: Self runs borrow the one Claude token over a unix socket bound to the peer's uid, its pidfd and its unit's InvocationID; the connector sets the reservation, settle bills reported per-model usage uncapped, no report bills the reservation (squash of eureka-body/claude-self-run-lease 480cf94..b5f26ef; Soul s1-s3)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 21:54:03 +01:00
480cf941c8 claude-turn-schema-quota: schema-typed Persona replies via --json-schema, token on fd 3 never in the child env, per-window plan-quota capture, communal spend readout, not-logged-in bills zero (squash of eureka-body/claude-turn-schema-quota e867fad..429b344; Soul s1, s2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 20:18:35 +01:00
e867fad379 B4b1 claude-connector-binary: connector daemon over one CultCache config document; token from a systemd credential, pin before every spawn, private prompt dir, 401/403/429 door set, shared readiness for check and serve (squash of eureka-body/claude-connector-binary 200933f..67c7849; Soul s1, s2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 12:59:23 +01:00
200933f7cf B4a claude-code-backend: Claude backend driving the unmodified claude binary on the operator's subscription; tool-less turns, per-turn usage, process-group kill (squash of eureka-body/claude-code-backend e0c0832..341be82; Soul s1, s2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 11:03:03 +01:00
Meta Vens
e0c0832ae0 connector-spend (B3c): reserve-then-settle spend in the replay ledger, one charge owner, a windowed per-caller ceiling (squash of eureka-body/connector-spend 1d51e71..45d0927)
The reservation and the replay claim are one write in the connector's
replay store; a failed ledger write runs nothing. Amounts are integer
micro-USD with checked arithmetic, and the service derives every cost from
usage and the configured price. One function, ProviderCall::charge, decides
the charge: a result bound to its request and caller pays its true cost with
a truthful overrun, anything else pays the reservation (ruling
spend-bills-on-identity-not-validity). Each caller has a spend ceiling over
fixed epoch-aligned windows in its root-owned config
(connector-spend-caller-window-ceiling); the admission window is monotonic,
so a clock stepping back cannot reopen budget, and a clock-locked caller is
refused ClockBehindAdmissionWindow (spend-window-clock-ahead-fails-closed).
Refusals CostBound, SpendCeiling and ClockBehindAdmissionWindow are typed.

Spec eureka-body:cut_spec:cut-connector-spend.r1; reports h1-h5;
Soul s5 holds (verdict eureka-body:verdict:cut-connector-spend.s5).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 18:47:06 +01:00
Meta Vens
1d51e71ebf connector-reasoning-item (B3b): one opaque reasoning item per provider block; the service owns foreign state (squash of eureka-body/connector-reasoning-item bf958fc..d915f67)
A ReasoningState item carries each provider block as raw bytes. The service
decides what is foreign: foreign state after the last user text is refused,
earlier foreign state is dropped before the backend and counted on the
receipt. Backends receive a ProviderCall that holds only what they may see,
and the service fills and checks the receipt's provider tag and drop count;
a refused result reaches the caller as a typed Provider failure, releases
its slot and replays on retry. transcript_items turns a completed result
into transcript items from the receipt, so callers never branch on provider.

Spec eureka-body:cut_spec:cut-connector-reasoning-item.r1; reports h1-h2;
Soul s2 holds (verdict eureka-body:verdict:cut-connector-reasoning-item.s2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 13:31:06 +01:00
Meta Vens
bf958fc327 connector-contract-v3 (B3a): the v3 contract as typed documents over CultNet operations (squash of eureka-body/connector-contract-v3 ec0519d..a0a6ccb)
Each frame is a cultnet.operation_request.v0 / operation_response.v0
(service gamecult.model.connector, operation invoke) over loopback
TcpFramed, carrying the kit's sealed per-caller envelope: named
MessagePack only, unknown fields refused, binary ciphertext, JSON Schema
published from the types (ruling connector-v3-wire-cultnet-operation).
v2 is deleted with its fixtures (ruling connector-v3-only). The request is
provider-neutral, with max_output_tokens required; failure kinds, stop
reasons and usage are typed, and Policy is three typed refusals. Golden
v3 frames pin the carriage and envelope.

Spec eureka-body:cut_spec:cut-connector-contract-v3.r2; reports h1-h2;
Soul s2 holds (verdict eureka-body:verdict:cut-connector-contract-v3.s2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:26:34 +01:00
Meta Vens
ec0519d9ff connector-kit-lift: the provider-neutral connector kit, lifted from CodexConnector fd7cec4 (squash of eureka-body/connector-kit-lift 1cf879f..ba1f7eb)
The v2 contract, encrypted envelope and framing, client, caller admission
and replay, and the serve loop move into the model-connector crate behind
one ProviderBackend trait, relicensed AGPL-3.0-only by the sole copyright
holder (ruling connector-kit-relicense-agpl). Same schema ids and wire bytes
as v2, pinned by golden fixtures generated from fd7cec4. The Codex backend
is not ported (ruling codex-connector-park).

Serve owns the frame bounds: it measures the sealed envelope, refuses
configurations that cannot deliver their payload bound, answers over-bound
payloads and over-long ids with v2 refusals, and never records or replays
an undeliverable result.

Spec eureka-body:cut_spec:cut-connector-kit-lift.r1; reports h1-h5;
Soul s5 holds (verdict eureka-body:verdict:cut-connector-kit-lift.s5).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 07:12:42 +01:00
1cf879f1e0 Initial commit: LICENSE and README front door
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 03:49:49 +01:00