@go-to-k/cdkd 0.290.5 → 0.290.6

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.
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as isVersionOnlyInvocation, t as getCdkdVersion } from "./version-BBIkp8ja.js";
2
+ import { n as isVersionOnlyInvocation, t as getCdkdVersion } from "./version-BvSdNpMz.js";
3
3
 
4
4
  //#region src/cli/pipe-close-handler.ts
5
5
  /**
@@ -74,7 +74,7 @@ async function main() {
74
74
  console.log(getCdkdVersion());
75
75
  return;
76
76
  }
77
- const { buildProgram } = await import("./program-D30EPjOn.js");
77
+ const { buildProgram } = await import("./program-Cl3fCD6-.js");
78
78
  const program = buildProgram();
79
79
  const args = reorderArgs(process.argv);
80
80
  await program.parseAsync(args);
@@ -1,6 +1,6 @@
1
1
  import { b as displayIdent, d as applyDefaultNameForFallback, f as explicitNamePropertyFor, g as looksLikeCdkdGeneratedName, h as getCurrentStackName, m as generateResourceNameWithFallback, n as getLogger, p as generateResourceName, r as isStdoutReservedForPayload, s as getLiveRenderer, v as withStackName, x as displaySafe, y as UNRENDERABLE } from "./logger-th1myfgh.js";
2
2
  import { t as awsClientDefaults } from "./aws-client-defaults-D-iYiIJ6.js";
3
- import { t as getCdkdVersion } from "./version-BBIkp8ja.js";
3
+ import { t as getCdkdVersion } from "./version-BvSdNpMz.js";
4
4
  import { AsyncLocalStorage } from "node:async_hooks";
5
5
  import { createHash, randomUUID } from "node:crypto";
6
6
  import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetBucketReplicationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
@@ -7218,6 +7218,94 @@ function describeDockerFailure(error, args) {
7218
7218
  return redactDockerArgvInText(capturedStreamText(error, "stderr") || thrownMessageText(error) || safeStringify(error), args);
7219
7219
  }
7220
7220
  /**
7221
+ * A `cause` that is safe to CHAIN onto a wrapper error, for a caller that
7222
+ * wants the retry classifiers to see the failure as an object rather than as
7223
+ * an interpolated string (issue go-to-k/cdkd#2075).
7224
+ *
7225
+ * Attaching the raw `execFile` error reopens the channel go-to-k/cdkd#2440
7226
+ * closed. The mandate above applies to every docker failure text this module
7227
+ * hands out, "including one whose argv carries no user data today" — and a
7228
+ * chained cause IS such a text: `formatError` prints `cause.message`, and the
7229
+ * CLI's top-level handler walks the whole chain. The raw message is the
7230
+ * command line, so the moment an argv gains a `-e` or a `--build-arg` the
7231
+ * secret is in a printed line again, from a call site nobody re-reads.
7232
+ *
7233
+ * So the returned cause carries the REDACTED description as its message, and
7234
+ * chains nothing further. What the classifiers read is copied across — but
7235
+ * through an ALLOWLIST ({@link CLASSIFICATION_FIELDS}), never by sweeping the
7236
+ * original's own keys.
7237
+ *
7238
+ * The allowlist is the whole point, and a denylist was the first cut: it
7239
+ * skipped `message` / `stack` / `cause` and copied the rest, which carried
7240
+ * `err.cmd` — the full command line — onto the new error verbatim. That is
7241
+ * the SAME field that defeated four rounds of the go-to-k/cdkd#2440 fence
7242
+ * (`.claude/rules/docker-argv-redaction.md`), reintroduced inside the function
7243
+ * written to close it. `stderr` / `stdout` are excluded for the same reason:
7244
+ * the composer above has already read and REDACTED them into the message, so
7245
+ * copying the raw streams would hand back exactly what it removed.
7246
+ *
7247
+ * Fail-closed is the correct direction here for the reason the cache-param
7248
+ * allowlist gives: a field missing from the allowlist costs one degraded retry
7249
+ * classification, while a field missing from a denylist costs a printed
7250
+ * credential.
7251
+ */
7252
+ /**
7253
+ * The fields {@link redactedDockerCause} carries from the original error onto
7254
+ * the redacted one.
7255
+ *
7256
+ * WHAT EACH HALF IS FOR, stated precisely because an earlier revision of this
7257
+ * comment got it wrong in a way that reads as more than it is. The AWS-shaped
7258
+ * entries (`$metadata`, `$fault`, `__type`, `code`, `statusCode`) are what
7259
+ * `isThrottlingError` / `isTransientServerError` /
7260
+ * `describeRetryClassificationSignals` actually consult, and they are reachable
7261
+ * here only when an SDK error is the cause -- the ECR-login path, whose
7262
+ * `GetAuthorizationToken` failure can be one.
7263
+ *
7264
+ * `exitCode` is NOT read by any classifier. It is carried because it is the
7265
+ * ONLY field the DOMINANT failure has: these four sites reject through
7266
+ * `spawnStreaming`, whose `SpawnError` sets `stderr` / `stdout` / `exitCode`
7267
+ * and nothing else, so without it a non-zero docker exit produced a cause with
7268
+ * a name and a message and no other content at all. What that buys is the
7269
+ * DIAGNOSTIC -- `cli/index.ts` renders the chain's own enumerable props -- not
7270
+ * a retry decision. Do not restate it as a classification field.
7271
+ *
7272
+ * `stderr` / `stdout` stay OFF: the composer has already read and REDACTED
7273
+ * them into the message, so copying the raw streams would hand back exactly
7274
+ * what it removed.
7275
+ */
7276
+ const CLASSIFICATION_FIELDS = [
7277
+ "exitCode",
7278
+ "code",
7279
+ "errno",
7280
+ "signal",
7281
+ "status",
7282
+ "statusCode",
7283
+ "$metadata",
7284
+ "$fault",
7285
+ "__type"
7286
+ ];
7287
+ function redactedDockerCause(error, args) {
7288
+ if (!(error instanceof Error)) return void 0;
7289
+ const cause = new Error(describeDockerFailure(error, args));
7290
+ try {
7291
+ cause.name = error.name;
7292
+ } catch {}
7293
+ const NON_RETRYABLE_MARKER = Symbol.for("cdkd.nonRetryable");
7294
+ try {
7295
+ if (error[NON_RETRYABLE_MARKER] === true) Object.defineProperty(cause, NON_RETRYABLE_MARKER, {
7296
+ value: true,
7297
+ enumerable: false,
7298
+ configurable: true
7299
+ });
7300
+ } catch {}
7301
+ const source = error;
7302
+ const target = cause;
7303
+ for (const key of CLASSIFICATION_FIELDS) try {
7304
+ if (key in source) target[key] = source[key];
7305
+ } catch {}
7306
+ return cause;
7307
+ }
7308
+ /**
7221
7309
  * Composer for a captured-output failure where the diagnostic may be on
7222
7310
  * STDOUT rather than stderr (`runDockerStreaming`'s non-zero-exit path, whose
7223
7311
  * `SpawnError` carries both). `fallback` is used when neither stream said
@@ -7474,7 +7562,12 @@ var DockerAssetPublisher = class {
7474
7562
  try {
7475
7563
  await this.tagImage(actualTag, tag);
7476
7564
  } catch (err) {
7477
- throw new AssetError(`Docker tag failed re-tagging '${actualTag}' → '${tag}': ${err.message ?? String(err)}`);
7565
+ const e = err;
7566
+ throw new AssetError(`Docker tag failed re-tagging '${actualTag}' → '${tag}': ${e.message ?? String(err)}`, e.cause instanceof Error ? e.cause : redactedDockerCause(err, [
7567
+ "tag",
7568
+ actualTag,
7569
+ tag
7570
+ ]));
7478
7571
  }
7479
7572
  }
7480
7573
  }
@@ -7549,7 +7642,7 @@ var DockerAssetPublisher = class {
7549
7642
  await runDockerStreaming(loginArgs, { input: password });
7550
7643
  loggedInRegistries.add(registryKey);
7551
7644
  } catch (err) {
7552
- throw new AssetError(`ECR login failed: ${formatDockerLoginError(describeDockerFailure(err, loginArgs), endpoint)}`);
7645
+ throw new AssetError(`ECR login failed: ${formatDockerLoginError(describeDockerFailure(err, loginArgs), endpoint)}`, redactedDockerCause(err, loginArgs));
7553
7646
  }
7554
7647
  }
7555
7648
  /**
@@ -7564,7 +7657,7 @@ var DockerAssetPublisher = class {
7564
7657
  try {
7565
7658
  await runDockerStreaming(tagArgs);
7566
7659
  } catch (err) {
7567
- throw new AssetError(`Docker tag failed: ${describeDockerFailure(err, tagArgs)}`);
7660
+ throw new AssetError(`Docker tag failed: ${describeDockerFailure(err, tagArgs)}`, redactedDockerCause(err, tagArgs));
7568
7661
  }
7569
7662
  }
7570
7663
  /**
@@ -7578,7 +7671,7 @@ var DockerAssetPublisher = class {
7578
7671
  try {
7579
7672
  await runDockerStreaming(pushArgs);
7580
7673
  } catch (err) {
7581
- throw new AssetError(`Docker push failed: ${describeDockerFailure(err, pushArgs)}`);
7674
+ throw new AssetError(`Docker push failed: ${describeDockerFailure(err, pushArgs)}`, redactedDockerCause(err, pushArgs));
7582
7675
  }
7583
7676
  }
7584
7677
  /**
@@ -9679,7 +9772,7 @@ var S3StateBackend = class {
9679
9772
  }));
9680
9773
  } catch (error) {
9681
9774
  const name = error.name;
9682
- if (name === "NotFound" || name === "NoSuchBucket") throw new StateError(`State bucket '${this.config.bucket}' does not exist. Run 'cdkd bootstrap' to create it, or specify an existing bucket via --state-bucket, CDKD_STATE_BUCKET, or cdk.json context.cdkd.stateBucket.`);
9775
+ if (name === "NotFound" || name === "NoSuchBucket") throw new StateError(`State bucket '${this.config.bucket}' does not exist. Run 'cdkd bootstrap' to create it, or specify an existing bucket via --state-bucket, CDKD_STATE_BUCKET, or cdk.json context.cdkd.stateBucket.`, error instanceof Error ? error : void 0);
9683
9776
  const normalized = normalizeAwsError(error, {
9684
9777
  bucket: this.config.bucket,
9685
9778
  operation: "HeadBucket"
@@ -9811,7 +9904,7 @@ var S3StateBackend = class {
9811
9904
  }
9812
9905
  return response.ETag;
9813
9906
  } catch (error) {
9814
- if (error.name === "PreconditionFailed") throw new StateError(`State has been modified by another process. Expected ETag: ${expectedEtag}, but state has changed.`);
9907
+ if (error.name === "PreconditionFailed") throw new StateError(`State has been modified by another process. Expected ETag: ${expectedEtag}, but state has changed.`, error instanceof Error ? error : void 0);
9815
9908
  const normalized = normalizeAwsError(error, {
9816
9909
  bucket: this.config.bucket,
9817
9910
  operation: "PutObject"
@@ -23363,15 +23456,19 @@ function withoutProducerRegions(context) {
23363
23456
  }
23364
23457
  /**
23365
23458
  * Masked log twins registered this pass, per pass bag (issue #3100;
23366
- * `rememberLogTwin` / `logTwinOfProduct`). Log-only: nothing that resolves or
23367
- * persists a value reads it.
23459
+ * `rememberLogTwin` / `logTwinOfProduct`). Nothing that RESOLVES a value reads
23460
+ * it. One persistence decision does: `resolveBase64` registers its encoding
23461
+ * mask-only when the input's position mask fires (issue #3119), which a nested
23462
+ * child also reaches through the inherited-bag lookup (issue #3114).
23368
23463
  *
23369
23464
  * MODULE scope, not instance scope: a region-pinned sibling resolver
23370
23465
  * (`resolverForProducerRegion`) resolves on behalf of the consumer with the
23371
23466
  * consumer's bag, so an instance-local registry left the sibling's twin where
23372
23467
  * the consumer's `Fn::Join` / `Fn::Sub` never looked. The key is still the
23373
- * pass's own bag object, so scope does not widen: another pass holds another
23374
- * bag and cannot reach these entries, and they die with the bag.
23468
+ * pass's own bag object, so scope does not widen to unrelated passes: a pass
23469
+ * reaches only the entries under its own bag and under the bag it was handed
23470
+ * as `inheritedSecrets` (a nested-stack child reading its parent's, issue
23471
+ * #3114), and the entries die with the bag.
23375
23472
  */
23376
23473
  const LOG_TWINS_BY_PASS = /* @__PURE__ */ new WeakMap();
23377
23474
  /**
@@ -24723,6 +24820,11 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
24723
24820
  async resolveParameters(template, userParameters, options) {
24724
24821
  const inheritedSecrets = options?.inheritedSecrets;
24725
24822
  const maskInherited = (text) => inheritedSecrets && inheritedSecrets.size > 0 ? maskSecretsInText(text, inheritedSecrets) : text;
24823
+ const inheritedLogContext = {
24824
+ template,
24825
+ resources: {},
24826
+ ...inheritedSecrets && { inheritedSecrets }
24827
+ };
24726
24828
  const parameters = Object.create(null);
24727
24829
  const templateParameters = template.Parameters;
24728
24830
  if (!templateParameters || typeof templateParameters !== "object") return parameters;
@@ -24735,7 +24837,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
24735
24837
  if (userValue !== void 0) {
24736
24838
  this.refuseCoercedInheritedSecret(name, paramDef, userValue, inheritedSecrets);
24737
24839
  parameters[name] = this.coerceParameterValue(userValue, paramDef.Type);
24738
- this.logger.debug(`Parameter ${name}: using user-provided value ${maskInherited(stringifyParameterForLog(paramDef, userValue))}`);
24840
+ this.logger.debug(`Parameter ${name}: using user-provided value ${maskInherited(stringifyParameterForLog(paramDef, this.maskValueLeaves(userValue, inheritedLogContext)))}`);
24739
24841
  continue;
24740
24842
  }
24741
24843
  }
@@ -25064,7 +25166,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
25064
25166
  const value = context.parameters[logicalId];
25065
25167
  const declared = context.template.Parameters;
25066
25168
  const paramDef = declared != null && Object.hasOwn(declared, logicalId) ? declared[logicalId] : void 0;
25067
- this.logger.debug(`Resolved Ref to parameter: ${logicalId} -> ${this.maskSecretsForLog(stringifyParameterForLog(paramDef, value), context)}`);
25169
+ this.logger.debug(`Resolved Ref to parameter: ${logicalId} -> ${this.maskSecretsForLog(stringifyParameterForLog(paramDef, this.maskValueLeaves(value, context)), context)}`);
25068
25170
  this.recordInheritedParameterSecrets(logicalId, value, context);
25069
25171
  return value;
25070
25172
  }
@@ -25237,10 +25339,10 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
25237
25339
  this.rejectPlaceholderArnAttribute(resource, attributeName, flatValue, logicalId, context);
25238
25340
  if (resource.resourceType === "AWS::Route53::HostedZone" && attributeName === "NameServers" && typeof flatValue === "string") {
25239
25341
  const nameServers = flatValue === "" ? [] : flatValue.split(",");
25240
- this.logger.debug(`Normalized legacy Fn::GetAtt attribute: ${logicalId}.${this.maskSecretsForLog(attributeName, context)} -> ${this.maskSecretsForLog(stringifyAttributeForLog(attributeName, nameServers), context)}`);
25342
+ this.logger.debug(`Normalized legacy Fn::GetAtt attribute: ${logicalId}.${this.maskSecretsForLog(attributeName, context)} -> ${this.maskSecretsForLog(stringifyAttributeForLog(attributeName, this.maskValueLeaves(nameServers, context)), context)}`);
25241
25343
  return this.noteAttributeSecrecy(logicalId, attributeName, nameServers, context);
25242
25344
  }
25243
- this.logger.debug(`Resolved Fn::GetAtt from attributes: ${logicalId}.${this.maskSecretsForLog(attributeName, context)} -> ${this.maskSecretsForLog(stringifyAttributeForLog(attributeName, flatValue), context)}`);
25345
+ this.logger.debug(`Resolved Fn::GetAtt from attributes: ${logicalId}.${this.maskSecretsForLog(attributeName, context)} -> ${this.maskSecretsForLog(stringifyAttributeForLog(attributeName, this.maskValueLeaves(flatValue, context)), context)}`);
25244
25346
  if (resource.resourceType === NESTED_STACK_RESOURCE_TYPE$1 && attributeName.startsWith(NESTED_STACK_OUTPUT_ATTRIBUTE_PREFIX) && carriesDynamicReference(flatValue)) return await this.reresolveCrossStackValue(flatValue, nestedStackChildRegionFromLocalArn(resource.physicalId), context, `nested stack ${logicalId} ${attributeName}`, crossStackSourceKey({ "Fn::GetAtt": getAtt }));
25245
25347
  return this.noteAttributeSecrecy(logicalId, attributeName, flatValue, context);
25246
25348
  }
@@ -25253,7 +25355,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
25253
25355
  break;
25254
25356
  }
25255
25357
  if (cursor !== void 0) {
25256
- this.logger.debug(`Resolved Fn::GetAtt from nested attributes: ${logicalId}.${this.maskSecretsForLog(attributeName, context)} -> ${this.maskSecretsForLog(stringifyAttributeForLog(attributeName, cursor), context)}`);
25358
+ this.logger.debug(`Resolved Fn::GetAtt from nested attributes: ${logicalId}.${this.maskSecretsForLog(attributeName, context)} -> ${this.maskSecretsForLog(stringifyAttributeForLog(attributeName, this.maskValueLeaves(cursor, context)), context)}`);
25257
25359
  return this.noteAttributeSecrecy(logicalId, attributeName, cursor, context);
25258
25360
  }
25259
25361
  }
@@ -25263,7 +25365,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
25263
25365
  throw markNonRetryable(new IntrinsicResolutionRefusalError(`Cannot resolve Fn::GetAtt [${logicalId}, ${this.maskSecretsForLog(attributeName, context)}]: the nested stack '${logicalId}' declares no output named '${this.maskSecretsForLog(attributeName.slice(8), context)}'. Its outputs are ${declared.length > 0 ? declared.join(", ") : "(none)"}. Check the output name in the nested stack's template, and deploy the child stack again if you have just added it.`));
25264
25366
  }
25265
25367
  const value = await this.constructGuardedAttribute(resource, attributeName, context, logicalId);
25266
- this.logger.debug(`Resolved Fn::GetAtt: ${logicalId}.${this.maskSecretsForLog(attributeName, context)} -> ${this.maskSecretsForLog(stringifyAttributeForLog(attributeName, value), context)}`);
25368
+ this.logger.debug(`Resolved Fn::GetAtt: ${logicalId}.${this.maskSecretsForLog(attributeName, context)} -> ${this.maskSecretsForLog(stringifyAttributeForLog(attributeName, this.maskValueLeaves(value, context)), context)}`);
25267
25369
  return value;
25268
25370
  }
25269
25371
  /**
@@ -25955,7 +26057,10 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
25955
26057
  const literalList = Array.isArray(rawValues);
25956
26058
  const parts = (await allSettledKeepingFirstRejection(values.map(async (v) => {
25957
26059
  if (typeof v === "string") return {
25958
- ...v.includes("{{resolve:") ? await this.resolveDynamicReferencesWithLogTwin(v, v, context) : {
26060
+ ...v.includes("{{resolve:") ? await this.resolveDynamicReferencesWithLogTwin(v, this.logTwinOfProduct({
26061
+ result: v,
26062
+ twin: v
26063
+ }, context).twin, context) : {
25959
26064
  result: v,
25960
26065
  twin: v
25961
26066
  },
@@ -27277,8 +27382,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
27277
27382
  * pass is masked too: the over-masking direction `logTwinOfProduct` accepts.
27278
27383
  */
27279
27384
  splitLogTwins(value, delimiter, pieces, context) {
27280
- const bag = this.logTwinBag(context);
27281
- const sourceTwin = this.isRecordedSecretForLog(value, context) ? "***" : bag ? LOG_TWINS_BY_PASS.get(bag)?.get(value) : void 0;
27385
+ const sourceTwin = this.isRecordedSecretForLog(value, context) ? "***" : this.registeredLogTwin(value, context);
27282
27386
  if (sourceTwin === void 0) return pieces;
27283
27387
  const twinPieces = sourceTwin.split(delimiter);
27284
27388
  const aligned = twinPieces.length === pieces.length && !"***".includes(delimiter);
@@ -27332,6 +27436,48 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
27332
27436
  return context?.recordedSecretValues ?? context?.inheritedSecrets;
27333
27437
  }
27334
27438
  /**
27439
+ * The masked twin registered for `value`, looked up under the pass's OWN bag
27440
+ * and under the INHERITED one (issue
27441
+ * [#3114](https://github.com/go-to-k/cdkd/issues/3114)). A nested-stack
27442
+ * child receives, as `inheritedSecrets`, the very object its parent resolved
27443
+ * the `AWS::CloudFormation::Stack` resource with: the deploy engine binds the
27444
+ * resource context's `recordedSecretValues` as the resource's secrets, and
27445
+ * `NestedStackProvider` hands that binding to the child. So a parameter value
27446
+ * the parent built around a short secret (`port:q7` -> `port:***`) is
27447
+ * registered under the child's inherited bag, while the child registers its
27448
+ * own writes under its own bag. Two DIFFERENT registered twins mask the
27449
+ * whole string, the rule `rememberLogTwin` applies within one bag. Lookups
27450
+ * only: `rememberLogTwin` still registers under `logTwinBag`, the context's
27451
+ * own `recordedSecretValues` whenever it carries one (every context
27452
+ * `buildResolverContext` returns does; the log-only context
27453
+ * `resolveParameters` builds carries none, and nothing on that path
27454
+ * registers), so such a child never writes into its parent's registry. A
27455
+ * context with ONLY an inherited bag registers into that bag, as it did
27456
+ * before this lookup existed.
27457
+ *
27458
+ * ONE LEVEL ONLY. The bag a child hands its own nested stack is the child's
27459
+ * OWN resource bag, so no twin registered ABOVE the child is reachable from a
27460
+ * grandchild. Where the middle stack passes the value THROUGH
27461
+ * (`{ Ref: Param }` straight into the grandchild's `Parameters`) nothing ever
27462
+ * registers a twin in that bag, so the grandchild prints the value whether or
27463
+ * not the bag holds pairs. Where the middle RE-WRAPS it (an `Fn::Join` around
27464
+ * the `Ref`) the middle registers its own twin, and the hand-off still drops
27465
+ * a bag holding no pairs (it passes `inheritedSecrets` only when `size` is
27466
+ * nonzero). Both are issue #3156.
27467
+ *
27468
+ * The registry is keyed by VALUE, and `splitLogTwins`' unaligned arm
27469
+ * registers every piece, public ones included. So a child `Fn::Base64` over a
27470
+ * string exactly equal to such a piece of its parent's persists `***` for a
27471
+ * non-secret property, the over-masking hazard issue #3119 already accepts
27472
+ * within one pass, now reachable across the parent / child boundary.
27473
+ */
27474
+ registeredLogTwin(value, context) {
27475
+ const own = context?.recordedSecretValues ? LOG_TWINS_BY_PASS.get(context.recordedSecretValues)?.get(value) : void 0;
27476
+ const inherited = context?.inheritedSecrets ? LOG_TWINS_BY_PASS.get(context.inheritedSecrets)?.get(value) : void 0;
27477
+ if (own === void 0) return inherited;
27478
+ return inherited === void 0 || inherited === own ? own : "***";
27479
+ }
27480
+ /**
27335
27481
  * The log twin of a RESOLUTION PRODUCT — an intrinsic part, variable or
27336
27482
  * placeholder — for issue #3100. Masked whole when its value is a recorded
27337
27483
  * secret. Otherwise a part that carries no mask of its own takes the masked
@@ -27359,8 +27505,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
27359
27505
  result: part.result,
27360
27506
  twin: "***"
27361
27507
  };
27362
- const bag = this.logTwinBag(context);
27363
- const registered = bag ? LOG_TWINS_BY_PASS.get(bag)?.get(part.result) : void 0;
27508
+ const registered = this.registeredLogTwin(part.result, context);
27364
27509
  if (registered === void 0 || registered === part.twin) return part;
27365
27510
  return {
27366
27511
  result: part.result,
@@ -27374,7 +27519,8 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
27374
27519
  * two DIFFERENT masked twins for one string register `***` for the whole
27375
27520
  * string, since their spans cannot be merged. Scoped to the pass's bag
27376
27521
  * through a `WeakMap`, like the cross-stack associations, so it dies with
27377
- * the bag and another pass's strings cannot be reached.
27522
+ * the bag. An unrelated pass cannot reach these strings; a nested child
27523
+ * whose `inheritedSecrets` is this bag reads them (`registeredLogTwin`).
27378
27524
  */
27379
27525
  rememberLogTwin(context, result, twin) {
27380
27526
  if (twin === result) return;
@@ -29149,7 +29295,7 @@ var CloudControlProvider = class {
29149
29295
  const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
29150
29296
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
29151
29297
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
29152
- const { ASGProvider } = await import("./asg-provider-DU7mN-cS.js").then((n) => n.n);
29298
+ const { ASGProvider } = await import("./asg-provider-CsdVn4cg.js").then((n) => n.n);
29153
29299
  const asgProvider = new ASGProvider();
29154
29300
  return withIndeterminateGuard(await asgProvider.delete(logicalId, physicalId, resourceType, _properties, context), indeterminateGuard);
29155
29301
  }
@@ -41849,4 +41995,4 @@ var DeployEngine = class DeployEngine {
41849
41995
 
41850
41996
  //#endregion
41851
41997
  export { secretSafeKeyDisplay as $, isCrossRegionRedirect as $n, CdkdError as $r, applyRoleArnIfSet as $t, planOrphanAdoption as A, forceQuitRecoveryClause as An, resolveStateBucketWithDefaultAndSource as Ar, isSettledInstanceState as At, formatResourceLine as B, shouldRetainResource as Bn, expectedOwnerParam as Br, readConfigString as Bt, createPreDeleteFinalSnapshot as C, isRetryableTransientError as Ci, redactSecretsForState as Cn, getDefaultStateBucketName as Cr, cfnRefValueFromPhysicalId as Ct, makeCanonicalizePropertiesFn as D, markRedactedCause as Di, rebuildClientForBucketRegion as Dn, resolveCaptureObservedState as Dr, isUnboundTemplateParameter as Dt, unsupportedFinalSnapshotError as E, markNonRetryable as Ei, S3StateBackend as En, resolveAutoAssetStorage as Er, isImpossibleEmptyStoredAttribute as Et, WARM_THROUGHPUT_MEMBERS as F, exportNamesCarriedFrom as Fn, CFN_TEMPLATE_URL_LIMIT as Fr, coerceCfnBoolean as Ft, red as G, createAssetRedirectResolver as Gn, processStackMessages as Gr, classifyReplaySecretRegion as Gt, cyan as H, stringifyValue as Hn, canonicalizeRegion as Hr, requireConfigArray as Ht, coerceWarmThroughput as I, importableOutputKeys as In, MIGRATE_TMP_PREFIX as Ir, coerceCfnInteger as It, collectPublishedOutputNames as J, AssetModeResolver as Jn, AwsClients as Jr, s3BucketArn as Jt, yellow as K, loadPublishableAssetManifest as Kn, clearBucketRegionCache as Kr, producerRegionsFromState as Kt, isWarmThroughputDecrease as L, importableOutputs as Ln, findLargeInlineResources as Lr, configBooleanRefusal as Lt, isStatefulRecreateTargetForReplace as M, shellQuote as Mn, stateBucketExistenceConfirmed as Mr, normalizeAwsTagsToCfn as Mt, isStatefulRecreateTargetSync as N, CUSTOM_RESOURCE_RESPONSE_PREFIX as Nn, warnDeprecatedNoPrefixCliFlag as Nr, resolveExplicitPhysicalId as Nt, extractDeploymentEventError as O, retryClassificationText as Oi, buildForceUnlockCommand as On, resolveSkipPrefix as Or, parameterTypeMayLoseSecretIdentity as Ot, renderStatefulReason as P, DEFAULT_STATE_PREFIX as Pn, CFN_TEMPLATE_BODY_LIMIT as Pr, assertRegionMatch as Pt, secretBearingStateKeyWarning as Q, getBootstrapMarkerKey as Qn, AssetError as Qr, s3BucketWebsiteUrl as Qt, toCfnInteger as R, orphansAfterRollback as Rn, uploadCfnTemplate as Rr, configIntegerRefusal as Rt, ccRoutedFinalSnapshotError as S, isMarkedNonRetryable as Si, recoverMaskedOutput as Sn, synthesisStatusMessage as Sr, carriesDynamicReference as St, refusesFinalSnapshot as T, isTransientServerError as Ti, LockManager as Tn, resolveApp as Tr, getAccountInfo as Tt, gray as U, WorkGraph as Un, derivePartitionAndUrlSuffix as Ur, requireConfigObject as Ut, bold as V, AssetPublisher as Vn, PARTITION_TABLE as Vr, replayWarn as Vt, green as W, buildAssetRedirectMap as Wn, AssemblyReader as Wr, requireConfigString as Wt, isExportAliasCollision as X, assertAssetBucketRegion as Xn, resetAwsClients as Xr, s3BucketDualStackDomainName as Xt, exportAliasCollisionScrubWarning as Y, BOOTSTRAP_MARKER_PREFIX as Yn, getAwsClients as Yr, s3BucketDomainName as Yt, secretBearing as Z, ensureAssetStorage as Zn, setAwsClients as Zr, s3BucketRegionalDomainName as Zt, isSecretBearingReferenceString as _, SynthesisError as _i, isSingleDynamicReferenceToken as _n, escapeRegExp$1 as _r, deleteIndeterminateGuards as _t, DeploymentEventsStore as a, IntrinsicResolutionRefusalError as ai, withRetry as an, describeAwsFailure as ar, wouldReturnToSdkProvider as at, PRE_DELETE_SNAPSHOT_TYPES as b, normalizeAwsError as bi, maskSecretsInText as bn, getDockerImageBySourceHash as br, isTerminationProtectionPropagationError as bt, replayFailedOperations as c, LockError as ci, STATE_SOURCED_BASELINE_RULES as cn, describeDockerExecFailure as cr, maskerOrIdentity as ct, updatePartialReason as d, ProvisioningError as di, TEMPLATE_SOURCED_RULES as dn, formatDockerLoginError as dr, interruptWatchListenerCount as dt, ConfigError as ei, DiffCalculator as en, parseBootstrapMarker as er, getCurrentResourceSecrets as et, withResourceDeadline as f, ResourceTimeoutError as fi, carriesSecretMask as fn, getDockerCmd as fr, isInterruptedWaitError as ft, bagHoldsSecretExpression as g, StateError as gi, identityKeyFor as gn, runDockerStreaming as gr, UNSPECIFIED_SKIP_REASON as gt, computeImplicitDeleteEdges as h, StackTerminationProtectionError as hi, errorCauseChain as hn, runDockerForeground as hr, slowCcOperationTimeoutMs as ht, DeploymentEventsReader as i, DynamicReferenceRegionAmbiguousError as ii, describeTypeWithThrottleRetry as in, buildDenyExternalAccessPolicy as ir, ProviderRegistry as it, MULTI_REGION_RECREATE_BLOCKED_TYPES as j, formatLockExpiry as jn, resolveUseCdkBootstrapAssets as jr, WAFv2WebACLProvider as jt, makeSiblingClaimReader as k, __exportAll as ki, buildLockContentionMessage as kn, resolveStateBucketWithDefault as kr, refStateLookupFromResource as kt, replayRollback as l, NestedStackChildDirectDestroyError as li, STATE_SOURCED_CROSS_GENERATION_RULES as ln, describeDockerFailure as lr, beginCommandInterruptScope as lt, IMPLICIT_DELETE_DEPENDENCIES as m, StackHasActiveImportsError as mi, dynamicReferenceTokens as mn, redactDockerArgvValues as mr, CloudControlProvider as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, DependencyError as ni, findActionableSilentDrops as nn, validateAssetBucketName as nr, collectInlinePolicyNamesManagedBySiblings as nt, planFailedOps as o, LocalInvokeBuildError as oi, DagBuilder as on, buildDockerImage as or, createMaskedRetryLogger as ot, maskingRetryLogger as p, ResourceUpdateNotSupportedError as pi, createSecretMasker as pn, partitionSensitiveEnv as pr, startInterruptWatch as pt, collectDeclaredOutputNames as q, rewriteTemplateAssetReferences as qn, resolveBucketRegion as qr, withSharedDrainBudget as qt, DeployEngine as r, DeployCancelledError as ri, findSilentDropProperties as rn, validateContainerRepoName as rr, clearOnUpdateRemoval as rt, planRollback as s, LocalStartServiceError as si, TemplateParser as sn, describeDockerCapturedOutput as sr, maskDeep as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, CrossAccountSecretRefusalError as ti, INTRINSIC_KEYS as tn, readBootstrapMarkerBody as tr, IAMRoleProvider as tt, updatePartialMessage as u, PartialFailureError as ui, STATE_SOURCED_READBACK_RULES as un, dockerSpawnEnvWithSensitive as ur, endCommandInterruptScope as ut, bindingSkippedOutputs as v, formatError as vi, markSameGenerationBag as vn, stripControlChars as vr, deleteSkipReason as vt, isFinalSnapshotError as w, isThrottlingError as wi, scrubResourceRecord as wn, getLegacyStateBucketName as wr, coerceParameterTypedValue as wt, buildFinalSnapshotIdentifier as x, withErrorHandling as xi, recordMaskOnlyValue as xn, Synthesizer as xr, IntrinsicFunctionResolver as xt, ATOMIC_FINAL_SNAPSHOT_TYPES as y, isCdkdError as yi, maskSecretsInError as yn, AssetManifestLoader as yr, disableInstanceApiTermination as yt, toFiniteNumber as z, orphansCarriedFrom as zn, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as zr, configStringRefusal as zt };
41852
- //# sourceMappingURL=deploy-engine-WFO9o9M0.js.map
41998
+ //# sourceMappingURL=deploy-engine-BU7n9_qY.js.map