hikoutei 0.11.101-dev → 0.11.103-dev

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 (56) hide show
  1. package/dist/cli/adoptFlow.d.ts.map +1 -1
  2. package/dist/cli/adoptFlow.js +31 -0
  3. package/dist/cli/adoptFlow.js.map +1 -1
  4. package/dist/cli/checkpoint.d.ts +38 -52
  5. package/dist/cli/checkpoint.d.ts.map +1 -1
  6. package/dist/cli/checkpoint.js +87 -34
  7. package/dist/cli/checkpoint.js.map +1 -1
  8. package/dist/cli/envFileWriter.d.ts +42 -8
  9. package/dist/cli/envFileWriter.d.ts.map +1 -1
  10. package/dist/cli/envFileWriter.js +60 -30
  11. package/dist/cli/envFileWriter.js.map +1 -1
  12. package/dist/cli/errors.d.ts +6 -5
  13. package/dist/cli/errors.d.ts.map +1 -1
  14. package/dist/cli/errors.js +6 -5
  15. package/dist/cli/errors.js.map +1 -1
  16. package/dist/cli/gcloudRunner.d.ts +22 -5
  17. package/dist/cli/gcloudRunner.d.ts.map +1 -1
  18. package/dist/cli/gcloudRunner.js +168 -0
  19. package/dist/cli/gcloudRunner.js.map +1 -1
  20. package/dist/cli/keyContract.d.ts +62 -0
  21. package/dist/cli/keyContract.d.ts.map +1 -0
  22. package/dist/cli/keyContract.js +24 -0
  23. package/dist/cli/keyContract.js.map +1 -0
  24. package/dist/cli/keyMaterial.d.ts +1 -1
  25. package/dist/cli/keyMaterial.d.ts.map +1 -1
  26. package/dist/cli/keyMaterial.js +2 -2
  27. package/dist/cli/keyMaterial.js.map +1 -1
  28. package/dist/cli/keyProvision.d.ts +22 -44
  29. package/dist/cli/keyProvision.d.ts.map +1 -1
  30. package/dist/cli/keyProvision.js +212 -103
  31. package/dist/cli/keyProvision.js.map +1 -1
  32. package/dist/cli/setupFlow.d.ts +2 -7
  33. package/dist/cli/setupFlow.d.ts.map +1 -1
  34. package/dist/cli/setupFlow.js +301 -55
  35. package/dist/cli/setupFlow.js.map +1 -1
  36. package/dist/cli/setupPathCollision.d.ts +11 -3
  37. package/dist/cli/setupPathCollision.d.ts.map +1 -1
  38. package/dist/cli/setupPathCollision.js +10 -7
  39. package/dist/cli/setupPathCollision.js.map +1 -1
  40. package/dist/cli/setupPaths.d.ts +2 -0
  41. package/dist/cli/setupPaths.d.ts.map +1 -1
  42. package/dist/cli/setupPaths.js +9 -0
  43. package/dist/cli/setupPaths.js.map +1 -1
  44. package/dist/sheets/providers/google-sheets-api/model/batchBuilder.d.ts +10 -0
  45. package/dist/sheets/providers/google-sheets-api/model/batchBuilder.d.ts.map +1 -1
  46. package/dist/sheets/providers/google-sheets-api/model/batchBuilder.js +25 -36
  47. package/dist/sheets/providers/google-sheets-api/model/batchBuilder.js.map +1 -1
  48. package/dist/sheets/providers/google-sheets-api/model/planner.d.ts.map +1 -1
  49. package/dist/sheets/providers/google-sheets-api/model/planner.js +0 -3
  50. package/dist/sheets/providers/google-sheets-api/model/planner.js.map +1 -1
  51. package/dist/sheets/providers/google-sheets-api/operations/fastAppend.d.ts.map +1 -1
  52. package/dist/sheets/providers/google-sheets-api/operations/fastAppend.js +3 -13
  53. package/dist/sheets/providers/google-sheets-api/operations/fastAppend.js.map +1 -1
  54. package/dist/sheets/providers/google-sheets-api/operations/rowChecks.js +9 -10
  55. package/dist/sheets/providers/google-sheets-api/operations/rowChecks.js.map +1 -1
  56. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"setupFlow.d.ts","sourceRoot":"","sources":["../../../../../../src/setupFlow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AAGH,OAAO,EAeL,KAAK,MAAM,EAKZ,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAqE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACnH,OAAO,EAAiD,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAgB5H,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC/F,OAAO,EAAE,sBAAsB,EAAE,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC1F,OAAO,EAAoB,KAAK,YAAY,EAAwB,MAAM,mBAAmB,CAAC;AAC9F,OAAO,EAML,KAAK,iBAAiB,EACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAKL,KAAK,OAAO,EACb,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAEV,oBAAoB,EAEpB,YAAY,EAEb,MAAM,oBAAoB,CAAC;AAG5B,qFAAqF;AACrF,eAAO,MAAM,qBAAqB,kCAAkC,CAAC;AAErE,2EAA2E;AAC3E,eAAO,MAAM,gCAAgC,kBAAkB,CAAC;AAEhE,+EAA+E;AAC/E,eAAO,MAAM,aAAa,MAAgC,CAAC;AAE3D,+EAA+E;AAC/E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,6EAA6E;IAC7E,QAAQ,CAAC,aAAa,EAAE,cAAc,CAAC;IACvC,yDAAyD;IACzD,QAAQ,CAAC,cAAc,EAAE,oBAAoB,CAAC;IAC9C,gFAAgF;IAChF,QAAQ,CAAC,cAAc,EAAE,gBAAgB,CAAC;IAC1C,qEAAqE;IACrE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9C,yCAAyC;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,iCAAiC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IACtC,gFAAgF;IAChF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,sDAAsD;AACtD,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,0CAA0C;AAC1C,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExD,qEAAqE;AACrE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,0EAA0E;IAC1E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,uFAAuF;IACvF,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC,YAAY,CAAC,GAAG,WAAW,CAAC;IAChE,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,4EAA4E;IAC5E,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,2CAA2C;AAC3C,MAAM,MAAM,WAAW,GACnB;IACA,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;CAC9C,GACC;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAA;CAAE,GAC9F,gBAAgB,CAAC;AAUrB,+CAA+C;AAC/C,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjE;AAyCD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAmB,EAAE,MAAM,GAAE,MAAM,MAAoB,GAAG,MAAM,CAItG;AAGD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,cAAc,EAAE,CA6JnG;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,GAAG,MAAM,CAatE;AAED,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CA2B3D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,CAwK7E;AAs4BD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAMzE;AAED,sEAAsE;AACtE,eAAO,MAAM,eAAe,sCAAsC,CAAC;AAEnE,kFAAkF;AAClF,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAE7D,+DAA+D;AAC/D,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,uDAAuD;IACvD,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED,+DAA+D;AAC/D,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC;AAEnE;;;;;;;;;;;;GAYG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAuCvG"}
1
+ {"version":3,"file":"setupFlow.d.ts","sourceRoot":"","sources":["../../../../../../src/setupFlow.ts"],"names":[],"mappings":"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"}
@@ -65,18 +65,19 @@
65
65
  * lock, checkpoint, key, or env mutation, and manual setup remains
66
66
  * available.
67
67
  */
68
- import { basename, dirname, join } from "node:path";
69
68
  import { acquireSetupLock, checkStateCompatibility, generateCreationMarker, isValidGcpProjectId, isValidServiceAccountName, loadSetupState, releaseSetupLock, saveSetupState, serviceAccountEmail, SERVICE_ACCOUNT_KEY_FILE_MODE, SETUP_STATE_VERSION, setupLockPath, setupStateTempPath, } from "./checkpoint.js";
70
69
  import { MAX_SETUP_SA_COUNT, parseSaCount } from "./args.js";
71
70
  import { SETUP_ERROR_CODES, carrierCode, setupFailure } from "./errors.js";
72
71
  import { describeGcloudFailure, errorResult, outcomeOf } from "./flowResult.js";
73
72
  import { revalidateSetupPaths, writeSetupEnvFile, } from "./envFileWriter.js";
74
73
  import { findSetupPathCollision } from "./setupPathCollision.js";
74
+ import { poolKeyPath } from "./setupPaths.js";
75
75
  import { readServiceAccountKeyCredentialSecurely, readServiceAccountKeySecurely, } from "./keyMaterial.js";
76
76
  // Compat re-exports: the extracted modules are the canonical homes; the
77
77
  // setupFlow import path is kept stable for existing importers.
78
78
  export { writeSetupEnvFile, atomicWritePrivateFile, SETUP_ENV_KEYS } from "./envFileWriter.js";
79
79
  export { findSetupPathCollision } from "./setupPathCollision.js";
80
+ export { poolKeyPath };
80
81
  import { createSafeRunner } from "./gcloudRunner.js";
81
82
  import { boundedCheckReporter, POOL_EXPANSION_PHASE, safeProgressSink, SETUP_PROGRESS_OPERATIONS, } from "./setupProgress.js";
82
83
  import { checkHumanDriveAccess, DRIVE_ACCESS_COMMAND, } from "./humanAuth.js";
@@ -292,7 +293,50 @@ export function planSetupCommands(options, slug) {
292
293
  kind: "file",
293
294
  label: `write ${options.outputPath}`,
294
295
  outcome: "GOOGLE_APPLICATION_CREDENTIALS and HIKOUTEI_SYNC_SPREADSHEET_URL set; unrelated lines preserved; written atomically via a private temp file + rename, never through a symlink alias",
295
- }, {
296
+ });
297
+ // The requested credential pool is part of the dry-run plan: one
298
+ // ensure/key/share/verify group per additional account, both pool
299
+ // checkpoint writes, and the pool .env rewrite. Single-SA runs plan
300
+ // exactly as before.
301
+ const dryRunSaCount = options.saCount ?? 1;
302
+ for (let index = 2; index <= dryRunSaCount; index += 1) {
303
+ const poolSaName = `${options.saName}-${index}`;
304
+ const poolEmail = serviceAccountEmail(poolSaName, projectId);
305
+ const poolPath = poolKeyPath(options.keyPath, index);
306
+ commands.push({
307
+ kind: "gcloud",
308
+ command: ["iam", "service-accounts", "create", poolSaName, "--project", projectId, "--display-name", "hikoutei setup"],
309
+ outcome: `pool service account ${index} created (reused when it already exists)`,
310
+ }, {
311
+ kind: "file",
312
+ label: `checkpoint ${options.statePath}`,
313
+ outcome: `pool key ${index} write-ahead marker and baseline persisted before its single create; a resume reconciles and never creates a duplicate`,
314
+ }, {
315
+ kind: "gcloud",
316
+ command: ["iam", "service-accounts", "keys", "create", KEY_STAGE_PLACEHOLDER, "--iam-account", poolEmail, "--project", projectId],
317
+ outcome: `pool key ${index} created in a private staging directory, validated there, and installed atomically at ${poolPath}`,
318
+ }, {
319
+ kind: "api",
320
+ label: `drive.permissions: share ${poolEmail} as writer`,
321
+ outcome: `pool service account ${index} granted writer access without a notification email`,
322
+ }, {
323
+ kind: "api",
324
+ label: `spreadsheets.get with the ${poolEmail} key`,
325
+ outcome: `pool service-account access ${index} verified`,
326
+ }, {
327
+ kind: "file",
328
+ label: `checkpoint ${options.statePath}`,
329
+ outcome: `verified pool entry ${index} persisted; its in-flight write-ahead is cleared`,
330
+ });
331
+ }
332
+ if (dryRunSaCount > 1) {
333
+ commands.push({
334
+ kind: "file",
335
+ label: `write ${options.outputPath}`,
336
+ outcome: `HIKOUTEI_SYNC_CREDENTIALS set to the ${dryRunSaCount}-entry credential pool; unrelated lines preserved`,
337
+ });
338
+ }
339
+ commands.push({
296
340
  kind: "file",
297
341
  label: `release setup lock ${lockPath}`,
298
342
  outcome: "released",
@@ -395,14 +439,25 @@ export async function runSetup(options) {
395
439
  (!Number.isSafeInteger(options.saCount) || options.saCount < 1 || options.saCount > MAX_SETUP_SA_COUNT)) {
396
440
  return errorResult(SETUP_ERROR_CODES.INVALID_ARGS, `invalid sa-count value: expected a positive integer between 1 and ${MAX_SETUP_SA_COUNT}`);
397
441
  }
442
+ // Derived pool identities are validated before anything runs (dry runs
443
+ // included): an over-long `--sa-name` that cannot expand into N valid
444
+ // `<saName>-<i>` accounts is a usage error, never a mid-run failure
445
+ // after the primary resources were already mutated.
446
+ const poolPlanError = validatePoolPlan(options.saName, options.saCount ?? 1);
447
+ if (poolPlanError !== null) {
448
+ return errorResult(SETUP_ERROR_CODES.INVALID_ARGS, poolPlanError);
449
+ }
398
450
  // Reject canonical path collisions before anything else runs: `--output`
399
451
  // must never alias the key, checkpoint, checkpoint temp, or lock path, and
400
- // the key must never alias the checkpoint, temp, or lock. This is a usage
401
- // error, not a runtime failure.
452
+ // the key must never alias the checkpoint, temp, or lock. Planned
453
+ // credential-pool key paths (entries 2..N) are reserved too: a pool key
454
+ // aliasing any reserved path rejects the run before any mutation. This is
455
+ // a usage error, not a runtime failure.
402
456
  const collision = findSetupPathCollision({
403
457
  keyPath: options.keyPath,
404
458
  outputPath: options.outputPath,
405
459
  statePath: options.statePath,
460
+ poolKeyPaths: plannedPoolKeyPaths(options.keyPath, options.saCount ?? 1),
406
461
  });
407
462
  if (collision.status === "collision") {
408
463
  return errorResult(SETUP_ERROR_CODES.INVALID_ARGS, collision.message);
@@ -532,6 +587,12 @@ async function runSetupLocked(options, executed, human, runner, keySleeper, prog
532
587
  return errorResult(SETUP_ERROR_CODES.SETUP_STATE_INVALID, checkpointResult.message);
533
588
  }
534
589
  const checkpoint = checkpointResult.status === "loaded" ? checkpointResult.state : undefined;
590
+ if (checkpoint?.status === "complete" &&
591
+ ((checkpoint.pool?.length ?? 1) > MAX_SETUP_SA_COUNT ||
592
+ (checkpoint.poolKeyStarted?.index ?? 0) > MAX_SETUP_SA_COUNT)) {
593
+ return errorResult(SETUP_ERROR_CODES.SETUP_STATE_INVALID, `the credential pool in ${options.statePath} exceeds the supported maximum of ${MAX_SETUP_SA_COUNT}; ` +
594
+ `remove the setup state and rerun setup`);
595
+ }
535
596
  // Report the resume context once: the phases a checkpoint guarantees as
536
597
  // already complete. cloud_auth and drive_access are never
537
598
  // checkpoint-complete (every run re-runs them fresh), and the output phase
@@ -542,6 +603,24 @@ async function runSetupLocked(options, executed, human, runner, keySleeper, prog
542
603
  completedFromCheckpoint: checkpointCompletedPhases(checkpoint.status),
543
604
  });
544
605
  }
606
+ // Stored + planned pool key paths must never alias a reserved path: a
607
+ // checkpointed pool (or in-flight pool write-ahead) that collides with
608
+ // the current run's key/output/state/temp/lock rejects the run here,
609
+ // still before any mutation (the project phase is the first writer).
610
+ const storedPoolPaths = storedPoolKeyPaths(checkpoint);
611
+ if (storedPoolPaths.length > 0 || (options.saCount ?? 1) > 1) {
612
+ const poolCollision = findSetupPathCollision({
613
+ keyPath: options.keyPath,
614
+ outputPath: options.outputPath,
615
+ statePath: options.statePath,
616
+ poolKeyPaths: [
617
+ ...new Set([...plannedPoolKeyPaths(options.keyPath, options.saCount ?? 1), ...storedPoolPaths]),
618
+ ],
619
+ });
620
+ if (poolCollision.status === "collision") {
621
+ return errorResult(SETUP_ERROR_CODES.INVALID_ARGS, poolCollision.message);
622
+ }
623
+ }
545
624
  // Key file: on resume it must exist and match the checkpoint once the
546
625
  // key phase was reached (key_ready and later); a `key_create_started`
547
626
  // checkpoint defers key handling to the reconciliation step because the
@@ -1086,8 +1165,15 @@ async function runSetupLocked(options, executed, human, runner, keySleeper, prog
1086
1165
  // spreadsheet URL is derived from the id — never trusted from storage.
1087
1166
  // Revalidate the reserved paths immediately before this write so an alias
1088
1167
  // planted mid-run can never redirect the .env write onto the key or the
1089
- // checkpoint.
1090
- const envPreflight = revalidateSetupPaths(options);
1168
+ // checkpoint. A checkpointed pool survives smaller/default reruns: its
1169
+ // paths are preserved in the .env (the writer only emits the pool line
1170
+ // for >= 2 paths, so a fresh single-SA run still strips a stale line)
1171
+ // and reserved against aliasing, exactly like the primary key.
1172
+ const preservedPoolPaths = checkpointPoolEntries(checkpoint).map((entry) => entry.keyPath);
1173
+ const poolReservedPaths = [
1174
+ ...new Set([...plannedPoolKeyPaths(options.keyPath, options.saCount ?? 1), ...storedPoolKeyPaths(checkpoint)]),
1175
+ ];
1176
+ const envPreflight = revalidateSetupPaths(options, poolReservedPaths);
1091
1177
  if (envPreflight !== null) {
1092
1178
  return envPreflight;
1093
1179
  }
@@ -1095,7 +1181,7 @@ async function runSetupLocked(options, executed, human, runner, keySleeper, prog
1095
1181
  progress.report({ type: "operation_started", phase: "output", operation: SETUP_PROGRESS_OPERATIONS.ENV_WRITE });
1096
1182
  let envResult;
1097
1183
  try {
1098
- envResult = writeSetupEnvFile(options.outputPath, options.keyPath, spreadsheetEditUrl(spreadsheet.spreadsheetId), [options.statePath, setupLockPath(options.statePath), setupStateTempPath(options.statePath)]);
1184
+ envResult = writeSetupEnvFile(options.outputPath, options.keyPath, spreadsheetEditUrl(spreadsheet.spreadsheetId), [options.statePath, setupLockPath(options.statePath), setupStateTempPath(options.statePath), ...poolReservedPaths], preservedPoolPaths);
1099
1185
  }
1100
1186
  catch (error) {
1101
1187
  return errorResult(carrierCode(error) ?? SETUP_ERROR_CODES.OUTPUT_WRITE_FAILED, `could not write ${options.outputPath}: ${messageOf(error)}`);
@@ -1133,10 +1219,28 @@ async function runSetupLocked(options, executed, human, runner, keySleeper, prog
1133
1219
  resumed: checkpoint !== undefined,
1134
1220
  };
1135
1221
  // Single-SA runs return exactly as before (no pool checkpoint key, no
1136
- // pool env line, no pool progress); the pool expansion below runs only
1137
- // when more than one service account was requested.
1222
+ // pool env line, no pool progress) — unless a checkpointed pool exists:
1223
+ // resuming a pooled setup with a smaller or default count never removes
1224
+ // entries, so the stored pool (with its kept count) is reported and the
1225
+ // .env above already preserved its pool line. The pool expansion below
1226
+ // runs only when more than one service account was requested.
1138
1227
  const saCount = options.saCount ?? 1;
1139
- if (saCount <= 1) {
1228
+ const checkpointPool = checkpointPoolEntries(checkpoint);
1229
+ const hasPoolKeyInFlight = checkpoint?.status === "complete" && checkpoint.poolKeyStarted !== undefined;
1230
+ if (saCount <= 1 && !hasPoolKeyInFlight) {
1231
+ if (checkpointPool.length > 0) {
1232
+ return {
1233
+ status: "ok",
1234
+ dryRun: false,
1235
+ commands: executed,
1236
+ summary: {
1237
+ ...baseSummary,
1238
+ poolSize: checkpointPool.length,
1239
+ poolPaths: checkpointPool.map((entry) => entry.keyPath),
1240
+ poolKeptEntries: checkpointPool.length,
1241
+ },
1242
+ };
1243
+ }
1140
1244
  return {
1141
1245
  status: "ok",
1142
1246
  dryRun: false,
@@ -1259,17 +1363,81 @@ async function ensureServiceAccount(runner, executed, progress, phase, input) {
1259
1363
  return { status: "ok", reused: false };
1260
1364
  }
1261
1365
  /**
1262
- * Derives the key path for pool entry `index` (2-based) next to the
1263
- * primary key path, mirroring the primary naming: `name-2.json` beside
1264
- * `name.json` (or `name-2` beside an extensionless `name`). The directory
1265
- * is preserved and no existing file is ever touched here.
1366
+ * Planned key paths for pool entries 2..N next to the primary key path.
1367
+ *
1368
+ * Empty for single-SA runs, so single-account callers are unchanged.
1369
+ */
1370
+ function plannedPoolKeyPaths(primaryKeyPath, saCount) {
1371
+ const paths = [];
1372
+ for (let index = 2; index <= saCount; index += 1) {
1373
+ paths.push(poolKeyPath(primaryKeyPath, index));
1374
+ }
1375
+ return paths;
1376
+ }
1377
+ /**
1378
+ * Validates every derived `<saName>-<i>` pool account name for entries
1379
+ * 2..N against the canonical service-account format.
1380
+ *
1381
+ * Returns an `invalid_args` message, or null when the plan is valid. Runs
1382
+ * before any subprocess, API call, or file mutation (dry runs included),
1383
+ * so an over-long `--sa-name` that cannot expand into N valid accounts
1384
+ * fails before the primary resources are mutated. Single-SA runs always
1385
+ * validate (the loop is empty).
1386
+ */
1387
+ function validatePoolPlan(saName, saCount) {
1388
+ for (let index = 2; index <= saCount; index += 1) {
1389
+ const derived = `${saName}-${index}`;
1390
+ if (!isValidServiceAccountName(derived)) {
1391
+ return (`service-account name "${saName}" is too long to expand into a ${saCount}-account ` +
1392
+ `pool ("${derived}" is not a valid service-account name); use a shorter --sa-name`);
1393
+ }
1394
+ }
1395
+ return null;
1396
+ }
1397
+ /**
1398
+ * Additional key paths (entries 2..N) stored in a loaded checkpoint plus
1399
+ * any in-flight pool-key write-ahead. Entry 1 is the primary key and is
1400
+ * already reserved separately.
1401
+ *
1402
+ * Empty unless the checkpoint is `complete` with a pool, so single-SA
1403
+ * resumes are unchanged.
1266
1404
  */
1267
- export function poolKeyPath(primaryKeyPath, index) {
1268
- const base = basename(primaryKeyPath);
1269
- const dot = base.lastIndexOf(".");
1270
- const stem = dot > 0 ? base.slice(0, dot) : base;
1271
- const ext = dot > 0 ? base.slice(dot) : "";
1272
- return join(dirname(primaryKeyPath), `${stem}-${index}${ext}`);
1405
+ function storedPoolKeyPaths(checkpoint) {
1406
+ if (checkpoint?.status !== "complete") {
1407
+ return [];
1408
+ }
1409
+ // Entry 1 is the primary key path, already reserved by `options.keyPath`.
1410
+ const paths = (checkpoint.pool ?? []).slice(1).map((entry) => entry.keyPath);
1411
+ if (checkpoint.poolKeyStarted !== undefined) {
1412
+ paths.push(checkpoint.poolKeyStarted.keyPath);
1413
+ }
1414
+ return paths;
1415
+ }
1416
+ /**
1417
+ * Additional key paths (entries 2..N) carried by a checkpoint STATE value
1418
+ * plus any in-flight pool-key write-ahead. Entry 1 is reserved separately
1419
+ * as the primary key.
1420
+ *
1421
+ * Empty unless the state is `complete` with a pool.
1422
+ */
1423
+ function statePoolPaths(state) {
1424
+ if (state.status !== "complete") {
1425
+ return [];
1426
+ }
1427
+ // Entry 1 is the primary key path, already reserved by `options.keyPath`.
1428
+ const paths = (state.pool ?? []).slice(1).map((entry) => entry.keyPath);
1429
+ if (state.poolKeyStarted !== undefined) {
1430
+ paths.push(state.poolKeyStarted.keyPath);
1431
+ }
1432
+ return paths;
1433
+ }
1434
+ /**
1435
+ * Pool entries stored in a loaded checkpoint.
1436
+ *
1437
+ * Empty for fresh runs and single-SA checkpoints.
1438
+ */
1439
+ function checkpointPoolEntries(checkpoint) {
1440
+ return checkpoint?.status === "complete" ? (checkpoint.pool ?? []) : [];
1273
1441
  }
1274
1442
  /** Prompt text for the interactive service-account count question. */
1275
1443
  export const SA_COUNT_PROMPT = "Service accounts to create? [1]: ";
@@ -1328,22 +1496,23 @@ export async function resolveSaCountForSetup(options) {
1328
1496
  *
1329
1497
  * Runs after the primary flow reached `complete`: for each missing entry
1330
1498
  * it ensures the `<saName>-<i>` service account exists (the same
1331
- * ensure/create path as the primary), issues its key with the same
1332
- * settlement loop (`settleServiceAccountKey` with `fresh` permission and
1333
- * its own marker/baseline), grants it writer access, verifies access with
1334
- * the same verifier, and persists the entry to the `complete` checkpoint
1335
- * IMMEDIATELY — a mid-pool failure keeps entries 1..i-1 so the resume
1336
- * skips them. Failures use the same error codes as the primary path.
1499
+ * ensure/create path as the primary), issues its key under a per-entry
1500
+ * write-ahead (the fresh baseline plus a new marker are persisted as
1501
+ * `poolKeyStarted` on the `complete` checkpoint BEFORE the single create,
1502
+ * and only the invocation that just persisted it may create with `fresh`
1503
+ * permission), grants it writer access, verifies access with the same
1504
+ * verifier, and persists the entry to the `complete` checkpoint
1505
+ * IMMEDIATELY (clearing the write-ahead) — a mid-pool failure keeps
1506
+ * entries 1..i-1 so the resume skips them, and a crash at any pool-key
1507
+ * boundary resumes by reconciling the stored marker/baseline with
1508
+ * `reconcile` permission instead of creating a second key (an unmatched
1509
+ * cloud key fails with `key_create_uncertain`; nothing is ever deleted
1510
+ * automatically). Failures use the same error codes as the primary path.
1337
1511
  * Finally the `.env` file is rewritten with the comma-separated
1338
1512
  * `HIKOUTEI_SYNC_CREDENTIALS` pool line. The bounded key/verify progress
1339
1513
  * reporters stay unwired here (the tracker hosts one bounded kind per
1340
1514
  * phase): only generic operation events are emitted under
1341
1515
  * `pool_expansion`, which never advances the overall ten-phase count.
1342
- *
1343
- * // ponytail: no per-pool-SA key write-ahead checkpoint; a crash between
1344
- * // a pool key create and its pool-entry persist leaves an orphaned cloud
1345
- * // key that the retry treats as baseline (fails uncertain, never
1346
- * // duplicates silently). Persist per-SA key markers if this ever matters.
1347
1516
  */
1348
1517
  async function expandCredentialPool(runner, executed, progress, api, options, keySleeper, context) {
1349
1518
  progress.report({ type: "phase_started", phase: POOL_EXPANSION_PHASE });
@@ -1377,11 +1546,18 @@ async function expandCredentialPool(runner, executed, progress, api, options, ke
1377
1546
  }
1378
1547
  }
1379
1548
  // Keep-all resume: resuming with a smaller --sa-count never removes
1380
- // entries — the loop below only appends missing entries 2..N, so the
1381
- // pool only grows and the summary reports the actual (larger) size.
1549
+ // entries, and any existing write-ahead is reconciled before returning.
1382
1550
  const keptPoolEntries = storedPool?.length ?? 0;
1383
1551
  const pool = storedPool !== undefined ? [...storedPool] : [primaryEntry];
1384
- for (let index = pool.length + 1; index <= context.saCount; index += 1) {
1552
+ // A crashed pool-key run leaves its write-ahead on the complete
1553
+ // checkpoint: the next run reconciles that entry only (stored
1554
+ // marker/baseline, reconcile permission) and never creates a second key
1555
+ // for it. Only the first missing index can carry a write-ahead — every
1556
+ // persisted entry clears it.
1557
+ const resumedPoolKey = reloaded.state.poolKeyStarted;
1558
+ const resumedPoolKeyIndex = pool.length + 1;
1559
+ const targetSaCount = Math.max(context.saCount, resumedPoolKey === undefined ? 0 : resumedPoolKeyIndex);
1560
+ for (let index = pool.length + 1; index <= targetSaCount; index += 1) {
1385
1561
  const saName = `${options.saName}-${index}`;
1386
1562
  if (!isValidServiceAccountName(saName)) {
1387
1563
  return {
@@ -1400,25 +1576,79 @@ async function expandCredentialPool(runner, executed, progress, api, options, ke
1400
1576
  if (ensured.status === "error") {
1401
1577
  return ensured;
1402
1578
  }
1403
- progress.report({ type: "operation_started", phase: POOL_EXPANSION_PHASE, operation: SETUP_PROGRESS_OPERATIONS.KEY_LIST });
1404
- const keyList = await listUserManagedServiceAccountKeys(runner, executed, {
1405
- projectId: context.projectId,
1406
- saEmail,
1407
- purpose: "baseline",
1408
- });
1409
- progress.report({ type: "operation_completed", phase: POOL_EXPANSION_PHASE, operation: SETUP_PROGRESS_OPERATIONS.KEY_LIST });
1410
- if (keyList.status === "error") {
1411
- return { status: "error", error: keyList.error };
1579
+ // Pool-key write-ahead: a resumed write-ahead for THIS index settles
1580
+ // reconcile-only with the stored marker/baseline (no fresh baseline
1581
+ // list — the stored baseline scopes the reconciliation, exactly like
1582
+ // the primary key_create_started resume); otherwise the fresh baseline
1583
+ // is listed and the new marker plus baseline are persisted BEFORE the
1584
+ // single create, and only this invocation (fresh permission) may issue
1585
+ // it.
1586
+ let settled;
1587
+ if (resumedPoolKey !== undefined && index === resumedPoolKeyIndex) {
1588
+ if (resumedPoolKey.index !== index ||
1589
+ resumedPoolKey.saName !== saName ||
1590
+ resumedPoolKey.saEmail !== saEmail ||
1591
+ resumedPoolKey.keyPath !== keyPath) {
1592
+ return {
1593
+ status: "error",
1594
+ error: errorResult(SETUP_ERROR_CODES.SETUP_STATE_INVALID, `the in-flight pool key in ${options.statePath} does not match pool entry ${index}; ` +
1595
+ `remove the setup state and rerun setup`),
1596
+ };
1597
+ }
1598
+ settled = await settleServiceAccountKey(runner, executed, {
1599
+ keyPath,
1600
+ projectId: context.projectId,
1601
+ saEmail,
1602
+ keyMarker: resumedPoolKey.keyMarker,
1603
+ baseline: resumedPoolKey.keyBaseline,
1604
+ createPermission: "reconcile",
1605
+ sleeper: keySleeper,
1606
+ });
1607
+ }
1608
+ else {
1609
+ progress.report({ type: "operation_started", phase: POOL_EXPANSION_PHASE, operation: SETUP_PROGRESS_OPERATIONS.KEY_LIST });
1610
+ const keyList = await listUserManagedServiceAccountKeys(runner, executed, {
1611
+ projectId: context.projectId,
1612
+ saEmail,
1613
+ purpose: "baseline",
1614
+ });
1615
+ progress.report({ type: "operation_completed", phase: POOL_EXPANSION_PHASE, operation: SETUP_PROGRESS_OPERATIONS.KEY_LIST });
1616
+ if (keyList.status === "error") {
1617
+ return { status: "error", error: keyList.error };
1618
+ }
1619
+ const keyMarker = generateCreationMarker();
1620
+ progress.report({ type: "operation_started", phase: POOL_EXPANSION_PHASE, operation: SETUP_PROGRESS_OPERATIONS.CHECKPOINT_PERSIST });
1621
+ const writeAheadBase = spreadsheetState(options, context.projectId, context.ownerEmail, context.title, context.primaryEmail, { spreadsheetId: context.spreadsheetId }, "complete", context.projectMode, context.keyOrigin, context.shareOrigin);
1622
+ if (writeAheadBase.status !== "complete") {
1623
+ // Unreachable: the builder returns the requested status; fail
1624
+ // closed rather than create a key without its write-ahead.
1625
+ return {
1626
+ status: "error",
1627
+ error: errorResult(SETUP_ERROR_CODES.SETUP_STATE_INVALID, `could not persist the credential pool in ${options.statePath}; remove the setup state and rerun setup`),
1628
+ };
1629
+ }
1630
+ const writeAheadError = persistState(options, executed, {
1631
+ ...writeAheadBase,
1632
+ pool: [...pool],
1633
+ poolKeyStarted: { index, saName, saEmail, keyPath, keyMarker, keyBaseline: [...keyList.names] },
1634
+ });
1635
+ progress.report({ type: "operation_completed", phase: POOL_EXPANSION_PHASE, operation: SETUP_PROGRESS_OPERATIONS.CHECKPOINT_PERSIST });
1636
+ if (writeAheadError !== null) {
1637
+ return { status: "error", error: writeAheadError };
1638
+ }
1639
+ // This invocation JUST persisted the fresh pool-key write-ahead, so
1640
+ // it is the only one allowed to issue the single key create for
1641
+ // this entry (fresh permission).
1642
+ settled = await settleServiceAccountKey(runner, executed, {
1643
+ keyPath,
1644
+ projectId: context.projectId,
1645
+ saEmail,
1646
+ keyMarker,
1647
+ baseline: keyList.names,
1648
+ createPermission: "fresh",
1649
+ sleeper: keySleeper,
1650
+ });
1412
1651
  }
1413
- const settled = await settleServiceAccountKey(runner, executed, {
1414
- keyPath,
1415
- projectId: context.projectId,
1416
- saEmail,
1417
- keyMarker: generateCreationMarker(),
1418
- baseline: keyList.names,
1419
- createPermission: "fresh",
1420
- sleeper: keySleeper,
1421
- });
1422
1652
  if (settled.status === "error") {
1423
1653
  return settled;
1424
1654
  }
@@ -1509,7 +1739,15 @@ async function expandCredentialPool(runner, executed, progress, api, options, ke
1509
1739
  progress.report({ type: "operation_started", phase: POOL_EXPANSION_PHASE, operation: SETUP_PROGRESS_OPERATIONS.ENV_WRITE });
1510
1740
  let envModified = false;
1511
1741
  try {
1512
- const poolWrite = writeSetupEnvFile(options.outputPath, options.keyPath, spreadsheetEditUrl(context.spreadsheetId), [options.statePath, setupLockPath(options.statePath), setupStateTempPath(options.statePath)], pool.map((entry) => entry.keyPath));
1742
+ // The pool keys are reserved against aliasing here too: the rewritten
1743
+ // .env must never land on (or be read through) a pool key path.
1744
+ const poolPaths = pool.map((entry) => entry.keyPath);
1745
+ const poolKeyPaths = poolPaths.slice(1);
1746
+ const poolCollision = revalidateSetupPaths(options, poolKeyPaths);
1747
+ if (poolCollision !== null) {
1748
+ return { status: "error", error: poolCollision };
1749
+ }
1750
+ const poolWrite = writeSetupEnvFile(options.outputPath, options.keyPath, spreadsheetEditUrl(context.spreadsheetId), [options.statePath, setupLockPath(options.statePath), setupStateTempPath(options.statePath), ...poolKeyPaths], poolPaths);
1513
1751
  envModified = poolWrite.modified;
1514
1752
  }
1515
1753
  catch (error) {
@@ -1815,8 +2053,16 @@ function uncertainCreateResult(message) {
1815
2053
  function persistState(options, executed, state) {
1816
2054
  // Fail closed if a reserved path alias appeared after the initial
1817
2055
  // preflight: the checkpoint write must never be redirected by a symlink
1818
- // or hardlink that was not there when the run started.
1819
- const revalidated = revalidateSetupPaths(options);
2056
+ // or hardlink that was not there when the run started. Planned pool key
2057
+ // paths plus the pool paths carried by the state being saved are
2058
+ // reserved too, so an alias planted mid-run can never redirect a pool
2059
+ // checkpoint write onto a key or the .env.
2060
+ const revalidated = revalidateSetupPaths(options, [
2061
+ ...new Set([
2062
+ ...plannedPoolKeyPaths(options.keyPath, options.saCount ?? 1),
2063
+ ...statePoolPaths(state),
2064
+ ]),
2065
+ ]);
1820
2066
  if (revalidated !== null) {
1821
2067
  return revalidated;
1822
2068
  }