Skip to content

v0.102.0

Choose a tag to compare

@davidfarah2003 davidfarah2003 released this 26 Oct 06:27
43a3e79

Install or update: npm i -g cotal-ai@0.102.0

Changes in this release

  • The auth service now holds one issuer session for the issuance its callout makes on a user-auth connect, where it used to mint credentials and dial a new connection for every issued connect. That dial was most of an issued connect's cost: about 15 ms one at a time, and over 200 ms each when 16 arrived together. Each auth-service context and each --callout-only replica holds its own session. Its credential keeps the five-minute issuer expiry and is replaced before it expires. The connection never reconnects. It is closed and drained when the plane is fenced, when the service stops, or when the connection is lost, and the next issuance dials a new one. Each issuance still makes its own reads and writes, and a write in flight at a loss is never sent again. Retiring a lifecycle's issuances and every other issuance window still use a one-shot session. @cotal-ai/core exports holdIssuerSession, and startAuthService takes an optional issuerSessionTtlSeconds from 5 to 300 seconds.
  • Clients now treat the exchange's rate limit as one. The 429 names the bucket that ran out as limit,
    actor or owner. A CLI command prints the auth service's sentence and exits 2 as
    DEPENDENCY_UNAVAILABLE, with a remedy saying whether only that actor or the whole account is
    limited and RATE_LIMITED, the seconds and the limit in its JSON cause, where it used to report
    PERMISSION_DENIED. cotal agent-bearer prints retry-after <n> on stdout and exits 2, and an
    endpoint asks a bearer source again when a retryAfterSeconds it was given has passed, not before.
    When the broker refuses an endpoint's bearer, the warning says so and names where the reason is, and
    the reconnect backoff is randomized so endpoints refused together spread their retries.
  • The delivery daemon's timer writer now presents the credential the daemon holds on every connect and
    reconnects onto each renewed credential the daemon adopts. The broker no longer closes the writer's
    connection when the credential it dialed with expires, and a re-dial never presents an expired
    credential, so the writer no longer goes down for a few seconds at each expiry. standaloneConnectOpts
    accepts a creds getter that is read on every attempt, and CotalEndpoint.wireCreds() returns the
    endpoint's checked credential.
  • Deliver run turns to idle seats by notice instead of a 15-second poll. The manager publishes a data-free turn notice on the seat's own reply rail whenever the seat's pending turns change, and repeats it every 5 seconds until the seat pulls a new turn. The seat pulls turn-pending when a notice arrives, when it connects, and after a reconnect while it holds a turn. A seat's manager-call bearer is reused for its lifetime minus two minutes, shared by concurrent calls, and dropped after any failed call. An idle manager-launched seat no longer exchanges a manager-call bearer or opens a control connection every 15 seconds. A seat under a manager that predates notices keeps pulling every 15 seconds and logs that once. The notice needs no new grant: only the manager instance's serve credential can publish it, and a seat can read only its own.
  • cotal up on a root with no prepared record and no stack journal starts on the legacy launcher whatever it names, including a root whose space its up registered. Before, such a root took the controller route when the invocation named no legacy-only option. On a stopped legacy user-auth root that started a controller broker beside the root's retained auth-service record, failed its auth member (OPERATION_PARTIAL), and wrote a stack journal that tied the root to the controller from then on. Only a root prepared here, or one whose stack journal exists, takes the controller route.
  • On a user-auth mesh, when some of your managers do not answer, cotal ps and cotal who name each of them by instance id in their Next, so a registration left by a manager that ended without a clean stop can be told apart from the managers that answer. The Next used to say only to retry or read one manager with --on.
  • cotal ps on a user-auth mesh with several of your managers live no longer refuses or asks which one. It reads each manager the exchange counts live through its own one-instance view and lists each under its own manager <id> header with the host its presence reports. A manager that does not answer is listed as silent and makes the read partial, as on a static mesh. status <agent>, who and the attach picker read your managers the same way. When none of your managers answers, or none is live, ps lists your agents as presence shows them, read-only, and exits 0. Its next step starts a manager: bare cotal up on the root of the space's own stack, cotal supervise anywhere else. --json reports that read as result.kind presence.
  • Report failed session-name and pane-capture reads with the tmux operation, error text and original cause.
  • A refused cotal up no longer moves the operator-global connector seed store. up reconciled that store at the boot gate, before its own checks, so an up that then refused (a folder named after a space another folder holds, a --channels file that is not JSON) had already stamped the store with its generation while saying nothing was written, and an older cotal then refused the store as a downgrade. up now seeds when it first starts a process, or when up -f checks its agents' connectors, and a start that fails after the seed moved the store says so and names it. An older cotal still refuses a newer store before writing anything; its refusal now names the store and the extensions folder and says to restore both from a backup taken before the store moved, with the versions as context.

What's Changed

Full Changelog: v0.101.7...v0.102.0