Files
deepseek-harness/packages/credentials/authorization/src/invariant.ts
T
Yichen Jiang 732a7361f5 feat(authorization): obtain a credential by asking the human
Some credentials cannot be configured, only obtained: getting one means
a conversation — open this page, paste that code, pick an account. The
new seam owns that conversation and the one-attempt-per-key lifecycle,
and never the protocol, so a second authorization protocol arrives as
another flow rather than as another seam.

A flow is registered under the CredentialKey it writes, which is also
how the seam knows which plugin answers for the format inside that
record. The flow owns the write: run() resolving means the record is
already committed through ctx.credentials, and the seam confirms it.
That keeps a library persisting through its own store adapter the
single writer instead of being copied back out and written twice.

The interaction travels with the request rather than a registry,
because whoever starts an authorization is the one who can talk to the
human about it. A request already withdrawn never claims the key and
never starts the flow — relying on each flow to check its signal before
the first await would let one that does not hang holding the key.
2026-08-20 17:58:38 +08:00

46 lines
1.9 KiB
TypeScript

/**
* Package-owned invariant companion for `@deepseek-ai/dsh-authorization`.
* @module @deepseek-ai/dsh-authorization/invariant
*/
import type { Context } from '@deepseek-ai/cordis'
import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants'
const PACKAGE_NAME = '@deepseek-ai/dsh-authorization'
/** Cordis companion plugin name. */
export const name = 'authorization-invariant'
/** Service required before the companion can reserve package ownership. */
export const inject = ['invariants']
/**
* Install the single-flight release contract: `authorization/settled` names a
* finished attempt, and the seam admits one attempt per key, so the key must
* already be free when the event fires. A slot still held at settlement is
* unrecoverable — every later `begin()` for that key is refused as
* `ALREADY_IN_FLIGHT` until the process restarts — and it is invisible from the
* outside, because a wedged key looks exactly like a busy one.
*/
const install: InvariantInstaller = (ctx: Context, fail: InvariantFailure) => {
ctx.on('authorization/settled', (key) => {
const authorization = ctx.get('authorization')
if (authorization === undefined) {
fail(`authorization/settled for "${key}" emitted without a live authorization service`)
return
}
// A flow withdrawn during its own attempt settles with nothing left to
// describe, which is the disposer's documented behavior rather than a leak.
if (authorization.describe(key)?.inFlight === true) {
fail(`authorization/settled for "${key}" left the key in flight, wedging every later attempt`)
}
})
}
/**
* Register this package's invariant companion.
* @param ctx - Cordis context carrying the invariant service.
* @returns the installed registration's disposer after setup succeeds.
*/
export const apply = (ctx: Context): Promise<() => void> =>
Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install))