@modelprofile.com/authswitch 7.0.0 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/authority-contract.d.ts +1 -3
  3. package/dist_ts/authority-contract.js +1 -1
  4. package/dist_ts/classes.authoritybroker.js +1 -5
  5. package/dist_ts/classes.authoritycli.js +2 -2
  6. package/dist_ts/classes.authoritydaemon.js +4 -9
  7. package/dist_ts/classes.authoritydatabase.d.ts +5 -26
  8. package/dist_ts/classes.authoritydatabase.js +49 -129
  9. package/dist_ts/classes.authoritymodels.d.ts +27 -43
  10. package/dist_ts/classes.authoritymodels.js +193 -243
  11. package/dist_ts/classes.authoritypreuse.js +1 -2
  12. package/dist_ts/classes.authorityregistry.d.ts +2 -17
  13. package/dist_ts/classes.authorityregistry.js +18 -74
  14. package/dist_ts/classes.authoritysecrets.d.ts +1 -1
  15. package/dist_ts/classes.authoritysecrets.js +2 -2
  16. package/dist_ts/classes.authorityusage.d.ts +3 -3
  17. package/dist_ts/classes.claudeauthority.js +3 -7
  18. package/dist_ts/classes.claudenative.d.ts +1 -8
  19. package/dist_ts/classes.claudenative.js +2 -25
  20. package/dist_ts/classes.codexmanaged.d.ts +1 -1
  21. package/dist_ts/plugins.d.ts +7 -7
  22. package/dist_ts/plugins.js +8 -8
  23. package/dist_ts/ts_migration/0001_authority_meta.d.ts +13 -3
  24. package/dist_ts/ts_migration/0001_authority_meta.js +29 -17
  25. package/dist_ts/ts_migration/0002_remove_backup_records.d.ts +17 -0
  26. package/dist_ts/ts_migration/0002_remove_backup_records.js +48 -0
  27. package/dist_ts/ts_migration/index.d.ts +6 -3
  28. package/dist_ts/ts_migration/index.js +10 -4
  29. package/package.json +2 -5
  30. package/readme.md +22 -26
  31. package/ts/00_commitinfo_data.ts +1 -1
  32. package/ts/authority-contract.ts +1 -3
  33. package/ts/classes.authoritybroker.ts +0 -4
  34. package/ts/classes.authoritycli.ts +1 -1
  35. package/ts/classes.authoritydaemon.ts +3 -8
  36. package/ts/classes.authoritydatabase.ts +50 -141
  37. package/ts/classes.authoritymodels.ts +232 -269
  38. package/ts/classes.authoritypreuse.ts +0 -1
  39. package/ts/classes.authorityregistry.ts +20 -91
  40. package/ts/classes.authoritysecrets.ts +1 -1
  41. package/ts/classes.authorityusage.ts +3 -3
  42. package/ts/classes.claudeauthority.ts +2 -6
  43. package/ts/classes.claudenative.ts +1 -32
  44. package/ts/classes.codexmanaged.ts +1 -1
  45. package/ts/plugins.ts +7 -7
  46. package/ts/ts_migration/0001_authority_meta.ts +29 -17
  47. package/ts/ts_migration/0002_remove_backup_records.ts +49 -0
  48. package/ts/ts_migration/index.ts +10 -5
  49. package/dist_ts/authorityrehearsal.child.d.ts +0 -1
  50. package/dist_ts/authorityrehearsal.child.js +0 -395
  51. package/dist_ts/classes.authoritybackup.d.ts +0 -134
  52. package/dist_ts/classes.authoritybackup.js +0 -769
  53. package/dist_ts/classes.authorityrehearsal.d.ts +0 -127
  54. package/dist_ts/classes.authorityrehearsal.js +0 -632
  55. package/ts/authorityrehearsal.child.ts +0 -330
  56. package/ts/classes.authoritybackup.ts +0 -780
  57. package/ts/classes.authorityrehearsal.ts +0 -625
package/readme.md CHANGED
@@ -92,8 +92,8 @@ digests and sealed values, while managed Codex reports durable, in-memory and ob
92
92
  state independently with fixed problem categories. Continue each independent cursor to inspect
93
93
  the complete inventory. Pages are later observations rather than one atomic global snapshot,
94
94
  and the authority metadata revision is not a change clock for every native-home record. If the
95
- management socket is unavailable, an offline caller must leave database and admission state
96
- unknown instead of starting the database to inspect it.
95
+ management socket is unavailable, an offline caller must leave the database state unknown
96
+ instead of starting the database to inspect it.
97
97
 
98
98
  The authority CLI uses that daemon surface without constructing the legacy native harness adapters:
99
99
 
@@ -176,7 +176,7 @@ both status requests and publication, and revalidate the exact credential and co
176
176
  source even when serving a cached result. Native grants are never refreshed by the daemon.
177
177
  Pending, quarantined, setup-token-without-profile-scope and other unsupported contexts
178
178
  return explicit unavailable status without a provider request. Production native home
179
- adoption still requires the separate verified migration and backup cutover.
179
+ adoption still requires the separate verified migration cutover.
180
180
 
181
181
  `AuthSwitchClient.startPreuse()` accepts one client-generated operation UUID and one exact
182
182
  OpenAI account/login/purpose. The daemon resolves an access-only grant, optionally reads the
@@ -187,8 +187,6 @@ marker remains `outcome_unknown` and is never replayed. Before-marker refusals a
187
187
  Only the request hash, selected model, timing and safe token counts are stored; the prompt,
188
188
  generated prose and credentials are absent from persistence and management responses. Account
189
189
  removal and targeted reauthentication refuse while that account has an active preuse request.
190
- Historical restore marks every unresolved preuse receipt `outcome_unknown`, including snapshots
191
- captured before the marker, because the original authority may have sent after snapshot capture.
192
190
 
193
191
  A trusted in-process daemon host can call `AuthSwitchAuthorityDaemon.startManagedCodex()`
194
192
  for a bound account and workspace. It owns a private Codex 0.155.1 app-server, passes only
@@ -226,27 +224,25 @@ The backend-only Claude native handoff journals an exact two-file write and tran
226
224
  ownership between two account grants in one SmartData transaction. An inactive Claude
227
225
  grant is refreshed by the daemon only after a durable pre-send marker; pending, native,
228
226
  and quarantined grants cannot enter that exchange. A native home and incoming grant
229
- require source-mapped migration receipts with backup metadata. The ledger field does
230
- not itself verify a SmartBucket backup, so the default daemon does not configure a
231
- Claude native home or run this path against real credentials. One-time migration and
232
- backup verification must precede production activation. Handoff receipts are queryable
233
- after a lost response. `runningEffectiveAuth: unsupported_effective_auth` means the
234
- native store changed, while an already-running Claude process's effective login cannot
235
- be proven externally; qualified live native-store switching still works.
236
-
237
- The authority database uses one versioned collection registry for startup preparation,
238
- ordered backup capture and exact restore readback. Startup rejects unknown collections,
239
- unknown metadata schemas and an incomplete restored database. Published 6.4/6.5 metadata
240
- is upgraded in place while account IDs, sealed grants, enrollments and uncertain states
241
- remain intact. A restored database keeps a durable closed-admission marker across restart;
242
- the daemon refuses provider and runtime work until a separate ownership-reconciliation
243
- step can prove it safe to open. Backup capture pins its paged records in one SmartData
244
- transaction and stages each retry anew before any SmartBucket publication. The closed
245
- restore rehearsal runs in a separate package-owned child, keeps its temporary source and
246
- record stream encrypted, restores metadata closed before any other record, then stops and
247
- reopens the same disposable database for exact stored readback. A receipt is issued only
248
- after the child has closed and its temporary root has been removed. This rehearsal does
249
- not perform a production restore or authorize a new authority instance to take ownership.
227
+ require a verified import receipt: a migration ledger row that binds the exact source
228
+ digest to one account and grant. A source counts as migrated only after such a verified
229
+ import. Nothing in this package writes that ledger yet, so the default daemon does not
230
+ configure a Claude native home or run this path against real credentials. Handoff
231
+ receipts are queryable after a lost response.
232
+ `runningEffectiveAuth: unsupported_effective_auth` means the native store changed, while
233
+ an already-running Claude process's effective login cannot be proven externally;
234
+ qualified live native-store switching still works.
235
+
236
+ The authority database admits exactly the collections of one registry and prepares each
237
+ at startup. Startup rejects unknown collections, unknown metadata schemas and an existing
238
+ store without its metadata document. Published 7.0.0 metadata is upgraded in place to the
239
+ shape 6.4/6.5 already wrote, while account IDs, sealed grants, enrollments and uncertain
240
+ states remain intact. A 7.0.0 store that a restore had marked closed is refused, not opened.
241
+ Startup also removes the backup digest that 6.4.0 to 7.0.0 stored on native handoff and
242
+ migration ledger rows, and refuses a store holding a record only the retired backup and
243
+ restore system could have written.
244
+ The store is deliberately not backed up: its refresh grants are sealed to this host's TPM,
245
+ so a lost store is recovered by one device re-login per account.
250
246
 
251
247
  ## Usage
252
248
 
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@modelprofile.com/authswitch',
6
- version: '7.0.0',
6
+ version: '8.0.0',
7
7
  description: 'Manage Codex, OpenCode and Claude Code accounts with guided switching and live usage status'
8
8
  }
@@ -169,8 +169,6 @@ export interface IAuthSwitchDoctorPage {
169
169
  database: {
170
170
  state: 'available';
171
171
  observedAt: string;
172
- schemaVersion: 2;
173
- admission: 'open' | 'closed_restored';
174
172
  epoch: string;
175
173
  revision: number;
176
174
  };
@@ -229,7 +227,7 @@ export interface IAuthSwitchPreuseOperation {
229
227
  result: { inputTokens: number | null; outputTokens: number | null; totalTokens: number | null } | null;
230
228
  problem: 'none' | 'target_unavailable' | 'access_unavailable' | 'catalog_unavailable'
231
229
  | 'account_busy' | 'cancelled' | 'authority_closing' | 'interrupted'
232
- | 'request_uncertain' | 'restored_history_uncertain';
230
+ | 'request_uncertain';
233
231
  createdAt: string;
234
232
  updatedAt: string;
235
233
  finishedAt: string | null;
@@ -131,7 +131,6 @@ export class AuthSwitchAuthorityBroker {
131
131
  public notifyChanged(): void { this.publish(); }
132
132
 
133
133
  public async start(): Promise<void> {
134
- await this.database.assertOpenAdmission();
135
134
  const probe = plugins.crypto.randomBytes(32);
136
135
  const probeId = idHash('authswitch-custody-probe-v1');
137
136
  try {
@@ -199,7 +198,6 @@ export class AuthSwitchAuthorityBroker {
199
198
 
200
199
  public async refreshDueAccounts(): Promise<void> {
201
200
  if (this.closed) return;
202
- await this.database.assertOpenAdmission();
203
201
  for (const state of ['ready', 'retry_wait'] as const) {
204
202
  let after: string | null = null;
205
203
  while (true) {
@@ -664,7 +662,6 @@ export class AuthSwitchAuthorityBroker {
664
662
  private async resolveManagedAccess(readView: () => Promise<{
665
663
  account: IStoredAuthorityAccount; grant: IStoredAuthorityGrant;
666
664
  }>, minValidityMs: number, rejectedGrantGeneration?: number): Promise<IAuthSwitchResolvedAccess> {
667
- await this.database.assertOpenAdmission();
668
665
  for (let attempt = 0; attempt < 4; attempt++) {
669
666
  const { account, grant } = await readView();
670
667
  if (account.removed || grant.accountId !== account.id || grant.id !== account.primaryGrantId
@@ -732,7 +729,6 @@ export class AuthSwitchAuthorityBroker {
732
729
 
733
730
  private async performRefresh(accountId: string, minValidityMs: number,
734
731
  rejectedGrantGeneration?: number): Promise<void> {
735
- await this.database.assertOpenAdmission();
736
732
  const initial = await this.database.readAccountAndPrimaryGrant(accountId);
737
733
  const initialGrant = initial.grant;
738
734
  if (!initial.account || initial.account.removed || !initialGrant || initialGrant.purpose !== 'openai_managed'
@@ -289,7 +289,7 @@ const renderDoctorPage = (page: IAuthSwitchDoctorPage, pageNumber: number): stri
289
289
  const lines = [
290
290
  `Authority doctor page ${pageNumber} — observed ${safe(page.observedAt)}`,
291
291
  ` daemon=${safe(page.daemon.state)}; Claude native authority=${safe(page.daemon.claudeNativeAuthority)}; observed=${safe(page.daemon.observedAt)}`,
292
- ` database=${safe(page.database.state)}; admission=${safe(page.database.admission)}; schema=${page.database.schemaVersion}; revision=${page.database.revision}; observed=${safe(page.database.observedAt)}`,
292
+ ` database=${safe(page.database.state)}; revision=${page.database.revision}; observed=${safe(page.database.observedAt)}`,
293
293
  ` accounts: ${page.accounts.length} stored evidence record(s); live provider check not performed`,
294
294
  ` logins: ${page.logins.length} stored evidence record(s); live provider check not performed`,
295
295
  ];
@@ -79,10 +79,7 @@ export class AuthSwitchAuthorityDaemon {
79
79
  this.broker = new AuthSwitchAuthorityBroker(this.database, { ...options.broker, provider });
80
80
  this.usage = new AuthSwitchAuthorityUsage({
81
81
  ...options.usage,
82
- readContext: async (accountId, loginId) => {
83
- await this.database.assertOpenAdmission();
84
- return this.database.readUsageContext(accountId, loginId);
85
- },
82
+ readContext: (accountId, loginId) => this.database.readUsageContext(accountId, loginId),
86
83
  resolveAccess: (context, rejectedGrantGeneration, minValidityMs) =>
87
84
  this.broker.resolveUsageAccess(context, rejectedGrantGeneration, minValidityMs),
88
85
  resolveClaudeLogin: (context, rejectedGrantGeneration, minValidityMs) => {
@@ -450,8 +447,8 @@ export class AuthSwitchAuthorityDaemon {
450
447
  observedAt,
451
448
  daemon: { state: this.closing ? 'closing' : 'ready',
452
449
  claudeNativeAuthority: this.claudeNative ? 'configured' : 'not_configured', observedAt },
453
- database: { state: 'available', observedAt: stored.observedAt, schemaVersion: stored.meta.schemaVersion,
454
- admission: stored.meta.admission, epoch: stored.meta.epoch, revision: stored.meta.revision },
450
+ database: { state: 'available', observedAt: stored.observedAt,
451
+ epoch: stored.meta.epoch, revision: stored.meta.revision },
455
452
  accounts: stored.accounts.map(account => ({ id: account.id, providerId: account.providerId,
456
453
  removed: account.removed, statusObservedAt: account.statusObservedAt,
457
454
  evidence: 'stored', liveCheck: 'not_checked' })),
@@ -491,7 +488,6 @@ export class AuthSwitchAuthorityDaemon {
491
488
  if (this.managementServer || this.runtimeServer) throw new Error('Authswitch authority daemon is already started.');
492
489
  await this.database.start();
493
490
  try {
494
- await this.database.assertOpenAdmission();
495
491
  await this.broker.start();
496
492
  await this.preuse.start();
497
493
  if (this.claudeNative) await this.claudeNative.start();
@@ -566,7 +562,6 @@ export class AuthSwitchAuthorityDaemon {
566
562
  let runtime: AuthSwitchManagedCodex | undefined;
567
563
  let claimed = false;
568
564
  try {
569
- await this.database.assertOpenAdmission();
570
565
  const home = input.codexHomeDirectory;
571
566
  const parent = plugins.path.dirname(home);
572
567
  const parentStat = await plugins.fs.promises.lstat(parent);