@serve.zone/dcrouter 17.10.2 → 18.0.1

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 (89) hide show
  1. package/deno.json +1 -1
  2. package/dist_serve/bundle.js +360 -360
  3. package/dist_ts/00_commitinfo_data.js +2 -2
  4. package/dist_ts/acme/acme-failure-classification.d.ts +64 -0
  5. package/dist_ts/acme/acme-failure-classification.js +114 -0
  6. package/dist_ts/acme/classes.smartacme-lifecycle.d.ts +42 -0
  7. package/dist_ts/acme/classes.smartacme-lifecycle.js +75 -4
  8. package/dist_ts/acme/index.d.ts +1 -0
  9. package/dist_ts/acme/index.js +2 -1
  10. package/dist_ts/classes.dcrouter.d.ts +33 -9
  11. package/dist_ts/classes.dcrouter.js +145 -11
  12. package/dist_ts/config/classes.route-config-manager.d.ts +56 -0
  13. package/dist_ts/config/classes.route-config-manager.js +161 -1
  14. package/dist_ts/db/documents/classes.dns-authority.doc.d.ts +30 -0
  15. package/dist_ts/db/documents/classes.dns-authority.doc.js +108 -0
  16. package/dist_ts/db/documents/index.d.ts +1 -0
  17. package/dist_ts/db/documents/index.js +2 -1
  18. package/dist_ts/dns/classes.dns-server-runtime.d.ts +109 -1
  19. package/dist_ts/dns/classes.dns-server-runtime.js +212 -34
  20. package/dist_ts/dns/domain-ownership.d.ts +111 -0
  21. package/dist_ts/dns/domain-ownership.js +152 -0
  22. package/dist_ts/dns/index.d.ts +2 -0
  23. package/dist_ts/dns/index.js +3 -1
  24. package/dist_ts/dns/manager.dns-authority.d.ts +143 -0
  25. package/dist_ts/dns/manager.dns-authority.js +481 -0
  26. package/dist_ts/dns/manager.dns.d.ts +121 -12
  27. package/dist_ts/dns/manager.dns.js +298 -28
  28. package/dist_ts/email/classes.accepted-email-spool.d.ts +15 -0
  29. package/dist_ts/email/classes.accepted-email-spool.js +102 -23
  30. package/dist_ts/email/classes.smartmta-blob-storage-manager.js +12 -3
  31. package/dist_ts/errors/error.codes.d.ts +4 -0
  32. package/dist_ts/errors/error.codes.js +5 -1
  33. package/dist_ts/opsserver/classes.opsserver.d.ts +1 -0
  34. package/dist_ts/opsserver/classes.opsserver.js +3 -1
  35. package/dist_ts/opsserver/handlers/acme-config.handler.js +6 -1
  36. package/dist_ts/opsserver/handlers/certificate.handler.d.ts +16 -0
  37. package/dist_ts/opsserver/handlers/certificate.handler.js +96 -10
  38. package/dist_ts/opsserver/handlers/config.handler.js +4 -2
  39. package/dist_ts/opsserver/handlers/dns-authority.handler.d.ts +20 -0
  40. package/dist_ts/opsserver/handlers/dns-authority.handler.js +108 -0
  41. package/dist_ts/opsserver/handlers/dns-provider.handler.js +5 -1
  42. package/dist_ts/opsserver/handlers/domain.handler.js +9 -1
  43. package/dist_ts/opsserver/handlers/gatewayclient.handler.js +2 -2
  44. package/dist_ts/opsserver/handlers/index.d.ts +1 -0
  45. package/dist_ts/opsserver/handlers/index.js +2 -1
  46. package/dist_ts_interfaces/data/dns-authority.d.ts +98 -0
  47. package/dist_ts_interfaces/data/dns-authority.js +26 -0
  48. package/dist_ts_interfaces/data/index.d.ts +1 -0
  49. package/dist_ts_interfaces/data/index.js +2 -1
  50. package/dist_ts_interfaces/data/route-management.d.ts +9 -2
  51. package/dist_ts_interfaces/data/route-management.js +3 -1
  52. package/dist_ts_interfaces/requests/certificate.d.ts +23 -0
  53. package/dist_ts_interfaces/requests/certificate.js +1 -1
  54. package/dist_ts_interfaces/requests/dns-authority.d.ts +80 -0
  55. package/dist_ts_interfaces/requests/dns-authority.js +3 -0
  56. package/dist_ts_interfaces/requests/index.d.ts +1 -0
  57. package/dist_ts_interfaces/requests/index.js +2 -1
  58. package/dist_ts_oci_container/index.js +9 -4
  59. package/dist_ts_web/00_commitinfo_data.js +2 -2
  60. package/package.json +1 -1
  61. package/readme.hints.md +412 -0
  62. package/readme.md +48 -6
  63. package/ts/00_commitinfo_data.ts +1 -1
  64. package/ts/acme/acme-failure-classification.ts +201 -0
  65. package/ts/acme/classes.smartacme-lifecycle.ts +104 -3
  66. package/ts/acme/index.ts +1 -0
  67. package/ts/classes.dcrouter.ts +193 -23
  68. package/ts/config/classes.route-config-manager.ts +197 -0
  69. package/ts/db/documents/classes.dns-authority.doc.ts +49 -0
  70. package/ts/db/documents/index.ts +1 -0
  71. package/ts/dns/classes.dns-server-runtime.ts +257 -38
  72. package/ts/dns/domain-ownership.ts +272 -0
  73. package/ts/dns/index.ts +2 -0
  74. package/ts/dns/manager.dns-authority.ts +558 -0
  75. package/ts/dns/manager.dns.ts +373 -27
  76. package/ts/email/classes.accepted-email-spool.ts +98 -21
  77. package/ts/email/classes.smartmta-blob-storage-manager.ts +10 -2
  78. package/ts/errors/error.codes.ts +4 -0
  79. package/ts/opsserver/classes.opsserver.ts +2 -0
  80. package/ts/opsserver/handlers/acme-config.handler.ts +7 -0
  81. package/ts/opsserver/handlers/certificate.handler.ts +103 -8
  82. package/ts/opsserver/handlers/config.handler.ts +3 -1
  83. package/ts/opsserver/handlers/dns-authority.handler.ts +142 -0
  84. package/ts/opsserver/handlers/dns-provider.handler.ts +6 -0
  85. package/ts/opsserver/handlers/domain.handler.ts +12 -0
  86. package/ts/opsserver/handlers/gatewayclient.handler.ts +1 -1
  87. package/ts/opsserver/handlers/index.ts +1 -0
  88. package/ts/readme.md +1 -1
  89. package/ts_web/00_commitinfo_data.ts +1 -1
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/dcrouter',
6
- version: '17.10.2',
6
+ version: '18.0.1',
7
7
  description: 'A multifaceted routing service handling mail and SMS delivery functions.'
8
8
  };
9
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxzQkFBc0I7SUFDNUIsT0FBTyxFQUFFLFNBQVM7SUFDbEIsV0FBVyxFQUFFLDBFQUEwRTtDQUN4RixDQUFBIn0=
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxzQkFBc0I7SUFDNUIsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLDBFQUEwRTtDQUN4RixDQUFBIn0=
@@ -0,0 +1,64 @@
1
+ import { PlatformError, type IErrorContext } from '../errors/base.errors.js';
2
+ /**
3
+ * ACME failure classification.
4
+ *
5
+ * dcrouter has two independent ACME retry budgets, and neither used to look at
6
+ * *why* a failure happened:
7
+ *
8
+ * 1. `SmartAcmeLifecycle` — SmartAcme provider startup. 5 s→1 h exponential
9
+ * backoff with jitter, hard cap of 20 attempts, then permanent give-up.
10
+ * Only a SmartProxy rebuild or a process restart re-arms it.
11
+ * 2. `CertProvisionScheduler` — per-domain certificate provisioning.
12
+ * `min(failures², 24 h)` backoff, **no cap**, re-armed by time forever.
13
+ * This is the budget that reached 31–45 failures on the broken domains.
14
+ *
15
+ * Retrying is correct for rate limits, DNS propagation and transport faults. It
16
+ * is never correct for a configuration cause: a hostname with no managed domain
17
+ * cannot acquire one by waiting, so every one of those attempts was a silent
18
+ * no-op that also kept the real reason out of the operator's view. Permanent
19
+ * causes must therefore skip the budget entirely and surface attributably.
20
+ *
21
+ * Unclassified causes stay transient on purpose. Guessing "permanent" would
22
+ * strand recoverable domains, so the default preserves existing retry behaviour;
23
+ * only causes we can positively recognise are treated as terminal.
24
+ */
25
+ export type TAcmeFailureReason =
26
+ /** Ownership of the hostname could not be proven (no DomainDoc / no provider zone / not delegation-verified). */
27
+ 'domain-ownership-unverified'
28
+ /** The DNS-01 dispatcher found no managed zone able to hold the challenge record. */
29
+ | 'no-managed-dns-zone'
30
+ /** No challenge handler / provider is wired for this domain at all. */
31
+ | 'no-challenge-handler'
32
+ /** The ACME account itself is misconfigured (email, terms, key, directory URL). */
33
+ | 'acme-account-configuration'
34
+ /** CAA forbids our issuer — only the domain holder can change this. */
35
+ | 'caa-forbids-issuance'
36
+ /** ACME server rate limit — retrying is exactly right. */
37
+ | 'rate-limited'
38
+ /** Challenge not yet visible, propagation delay, transport fault. */
39
+ | 'transient'
40
+ /** Nothing recognised. Treated as transient so recoverable causes keep retrying. */
41
+ | 'unclassified';
42
+ export interface IAcmeFailureClassification {
43
+ reason: TAcmeFailureReason;
44
+ /** True when no retry can resolve the cause, so the retry budget must not be consumed. */
45
+ permanent: boolean;
46
+ message: string;
47
+ }
48
+ /**
49
+ * Classify an ACME/provisioning failure into a retryable or terminal cause.
50
+ * Structured errors win over text matching: a `DomainOwnershipError` and any
51
+ * NON_RECOVERABLE CONFIGURATION `PlatformError` are permanent by declaration.
52
+ */
53
+ export declare const classifyAcmeFailure: (errorArg: unknown) => IAcmeFailureClassification;
54
+ /**
55
+ * Terminal ACME failure. HIGH severity so the automatic PlatformError log lands
56
+ * at `error` rather than being lost in provisioning warn noise, and
57
+ * NON_RECOVERABLE so `isRetryable()` and every downstream retry layer agree that
58
+ * this must not be retried.
59
+ */
60
+ export declare class AcmePermanentFailureError extends PlatformError {
61
+ readonly classification: IAcmeFailureClassification;
62
+ constructor(classification: IAcmeFailureClassification, operation: string, component: string, context?: IErrorContext);
63
+ protected createWithContext(context: IErrorContext): PlatformError;
64
+ }
@@ -0,0 +1,114 @@
1
+ import { PlatformError } from '../errors/base.errors.js';
2
+ import { DCR_ACME_PERMANENT_FAILURE, ErrorCategory, ErrorRecoverability, ErrorSeverity, } from '../errors/error.codes.js';
3
+ import { DomainOwnershipError } from '../dns/domain-ownership.js';
4
+ /**
5
+ * Ordered most-specific-first. Each pattern must only match text that uniquely
6
+ * identifies the cause — a false "permanent" verdict silently stops legitimate
7
+ * retries, which is a worse failure than an extra retry.
8
+ */
9
+ const reasonPatterns = [
10
+ {
11
+ // Thrown by DnsManager.buildAcmeConvenientDnsProvider() when no DomainDoc covers the FQDN.
12
+ reason: 'no-managed-dns-zone',
13
+ permanent: true,
14
+ patterns: [
15
+ /no managed domain found for/i,
16
+ /add the domain in domains before issuing certificates/i,
17
+ ],
18
+ },
19
+ {
20
+ reason: 'no-challenge-handler',
21
+ permanent: true,
22
+ patterns: [
23
+ /no (?:challenge )?handler (?:found |available )?for/i,
24
+ /no dns-01 (?:handler|provider)/i,
25
+ /domain is not supported by any challenge handler/i,
26
+ ],
27
+ },
28
+ {
29
+ reason: 'caa-forbids-issuance',
30
+ permanent: true,
31
+ patterns: [
32
+ /caa record(?:s)? (?:for [^\s]+ )?(?:prevent|forbid|do not allow)/i,
33
+ /urn:ietf:params:acme:error:caa/i,
34
+ ],
35
+ },
36
+ {
37
+ reason: 'acme-account-configuration',
38
+ permanent: true,
39
+ patterns: [
40
+ /urn:ietf:params:acme:error:invalidemail/i,
41
+ /urn:ietf:params:acme:error:accountdoesnotexist/i,
42
+ /urn:ietf:params:acme:error:unsupportedcontact/i,
43
+ /must agree to (?:the )?terms of service/i,
44
+ /accountemail is required/i,
45
+ ],
46
+ },
47
+ {
48
+ reason: 'rate-limited',
49
+ permanent: false,
50
+ patterns: [
51
+ /urn:ietf:params:acme:error:ratelimited/i,
52
+ /too many (?:certificates|requests|failed authorizations)/i,
53
+ /rate ?limit/i,
54
+ ],
55
+ },
56
+ ];
57
+ const extractMessage = (errorArg) => {
58
+ if (errorArg instanceof Error)
59
+ return errorArg.message;
60
+ if (typeof errorArg === 'string')
61
+ return errorArg;
62
+ if (errorArg && typeof errorArg === 'object' && 'message' in errorArg) {
63
+ return String(errorArg.message);
64
+ }
65
+ return String(errorArg);
66
+ };
67
+ /**
68
+ * Classify an ACME/provisioning failure into a retryable or terminal cause.
69
+ * Structured errors win over text matching: a `DomainOwnershipError` and any
70
+ * NON_RECOVERABLE CONFIGURATION `PlatformError` are permanent by declaration.
71
+ */
72
+ export const classifyAcmeFailure = (errorArg) => {
73
+ const message = extractMessage(errorArg);
74
+ if (errorArg instanceof DomainOwnershipError) {
75
+ return { reason: 'domain-ownership-unverified', permanent: true, message };
76
+ }
77
+ if (errorArg instanceof PlatformError
78
+ && errorArg.category === ErrorCategory.CONFIGURATION
79
+ && errorArg.recoverability === ErrorRecoverability.NON_RECOVERABLE) {
80
+ return { reason: 'acme-account-configuration', permanent: true, message };
81
+ }
82
+ for (const candidate of reasonPatterns) {
83
+ if (candidate.patterns.some((pattern) => pattern.test(message))) {
84
+ return { reason: candidate.reason, permanent: candidate.permanent, message };
85
+ }
86
+ }
87
+ return { reason: 'unclassified', permanent: false, message };
88
+ };
89
+ /**
90
+ * Terminal ACME failure. HIGH severity so the automatic PlatformError log lands
91
+ * at `error` rather than being lost in provisioning warn noise, and
92
+ * NON_RECOVERABLE so `isRetryable()` and every downstream retry layer agree that
93
+ * this must not be retried.
94
+ */
95
+ export class AcmePermanentFailureError extends PlatformError {
96
+ classification;
97
+ constructor(classification, operation, component, context = {}) {
98
+ super(`${operation} failed permanently (${classification.reason}): ${classification.message}`, DCR_ACME_PERMANENT_FAILURE, ErrorSeverity.HIGH, ErrorCategory.CONFIGURATION, ErrorRecoverability.NON_RECOVERABLE, {
99
+ component,
100
+ operation,
101
+ userMessage: `${operation} cannot succeed until its configuration is fixed (${classification.reason}): ${classification.message}`,
102
+ ...context,
103
+ data: {
104
+ acmeFailureReason: classification.reason,
105
+ ...context.data,
106
+ },
107
+ });
108
+ this.classification = classification;
109
+ }
110
+ createWithContext(context) {
111
+ return new AcmePermanentFailureError(this.classification, this.context.operation || 'operation', this.context.component || 'acme', context);
112
+ }
113
+ }
114
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNtZS1mYWlsdXJlLWNsYXNzaWZpY2F0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvYWNtZS9hY21lLWZhaWx1cmUtY2xhc3NpZmljYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGFBQWEsRUFBc0IsTUFBTSwwQkFBMEIsQ0FBQztBQUM3RSxPQUFPLEVBQ0wsMEJBQTBCLEVBQzFCLGFBQWEsRUFDYixtQkFBbUIsRUFDbkIsYUFBYSxHQUNkLE1BQU0sMEJBQTBCLENBQUM7QUFDbEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUF5RGxFOzs7O0dBSUc7QUFDSCxNQUFNLGNBQWMsR0FBcUI7SUFDdkM7UUFDRSwyRkFBMkY7UUFDM0YsTUFBTSxFQUFFLHFCQUFxQjtRQUM3QixTQUFTLEVBQUUsSUFBSTtRQUNmLFFBQVEsRUFBRTtZQUNSLDhCQUE4QjtZQUM5Qix3REFBd0Q7U0FDekQ7S0FDRjtJQUNEO1FBQ0UsTUFBTSxFQUFFLHNCQUFzQjtRQUM5QixTQUFTLEVBQUUsSUFBSTtRQUNmLFFBQVEsRUFBRTtZQUNSLHNEQUFzRDtZQUN0RCxpQ0FBaUM7WUFDakMsbURBQW1EO1NBQ3BEO0tBQ0Y7SUFDRDtRQUNFLE1BQU0sRUFBRSxzQkFBc0I7UUFDOUIsU0FBUyxFQUFFLElBQUk7UUFDZixRQUFRLEVBQUU7WUFDUixtRUFBbUU7WUFDbkUsaUNBQWlDO1NBQ2xDO0tBQ0Y7SUFDRDtRQUNFLE1BQU0sRUFBRSw0QkFBNEI7UUFDcEMsU0FBUyxFQUFFLElBQUk7UUFDZixRQUFRLEVBQUU7WUFDUiwwQ0FBMEM7WUFDMUMsaURBQWlEO1lBQ2pELGdEQUFnRDtZQUNoRCwwQ0FBMEM7WUFDMUMsMkJBQTJCO1NBQzVCO0tBQ0Y7SUFDRDtRQUNFLE1BQU0sRUFBRSxjQUFjO1FBQ3RCLFNBQVMsRUFBRSxLQUFLO1FBQ2hCLFFBQVEsRUFBRTtZQUNSLHlDQUF5QztZQUN6Qywy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
@@ -1,9 +1,38 @@
1
1
  import type { DcRouter } from '../classes.dcrouter.js';
2
+ import { type TAcmeFailureReason } from './acme-failure-classification.js';
3
+ /** Terminal state of the SmartAcme provider startup budget. */
4
+ export interface IAcmeStartFailure {
5
+ reason: TAcmeFailureReason;
6
+ /** True when no further retry can resolve the cause. */
7
+ permanent: boolean;
8
+ /** Attempts consumed when the budget ended. */
9
+ attempts: number;
10
+ message: string;
11
+ at: number;
12
+ /** What an operator has to do to re-arm startup. */
13
+ rearmedBy: string;
14
+ }
15
+ /** Attempts allowed for transient SmartAcme startup failures before giving up. */
16
+ export declare const smartAcmeStartMaxAttempts = 20;
2
17
  /**
3
18
  * Background start/retry/stop lifecycle for the DcRouter-owned SmartAcme
4
19
  * instance. SmartAcme startup can hit ACME rate limits, so startup runs in
5
20
  * the background with generation-guarded exponential retry, and certificate
6
21
  * provisioning is re-triggered once DNS-01 becomes ready.
22
+ *
23
+ * Retry semantics, which are NOT shared with the per-domain
24
+ * `CertProvisionScheduler` budget:
25
+ * - increments once per failed `smartAcme.start()`;
26
+ * - 5 s → 1 h exponential backoff with ±20% jitter;
27
+ * - capped at `smartAcmeStartMaxAttempts` transient attempts;
28
+ * - reset by `startInBackground()`, `stop()`, and a successful start;
29
+ * - re-armed only by `startInBackground()`, i.e. a SmartProxy rebuild, an
30
+ * explicit `rearm()` after a configuration change, or a process restart.
31
+ * Nothing re-arms it on a timer, so the terminal state is recorded in
32
+ * `startFailure` and logged at `error` instead of scrolling past as a warning.
33
+ *
34
+ * A permanent cause never enters the backoff at all: retrying a misconfigured
35
+ * ACME account cannot fix it, and spending the budget on it hides the reason.
7
36
  */
8
37
  export declare class SmartAcmeLifecycle {
9
38
  private dcRouterRef;
@@ -11,12 +40,25 @@ export declare class SmartAcmeLifecycle {
11
40
  ready: boolean;
12
41
  /** Tracks whether the taskbuffer SmartAcme service is started, so SmartProxy rebuilds can re-kick startup. */
13
42
  serviceStarted: boolean;
43
+ /**
44
+ * Set when the startup budget ended — either immediately for a permanent cause
45
+ * or after the transient attempt cap. Cleared on every (re-)arm and on success.
46
+ */
47
+ startFailure?: IAcmeStartFailure;
14
48
  private startGeneration;
15
49
  private startPromise?;
16
50
  private retryTimer?;
17
51
  private retryAttempt;
18
52
  constructor(dcRouterRef: DcRouter);
19
53
  startInBackground(): void;
54
+ /**
55
+ * Re-arm startup after a configuration change that can plausibly fix a
56
+ * previously terminal cause (e.g. the ACME account settings were corrected).
57
+ * Without this, an exhausted or permanently-failed budget could only be reset
58
+ * by a SmartProxy rebuild or a full restart — and a dcrouter restart is a
59
+ * measured 30–60 s of total public outage.
60
+ */
61
+ rearm(reasonArg: string): boolean;
20
62
  stop(): Promise<void>;
21
63
  private scheduleStart;
22
64
  private runStartAttempt;
@@ -1,10 +1,27 @@
1
1
  import * as plugins from '../plugins.js';
2
2
  import { logger } from '../logger.js';
3
+ import { AcmePermanentFailureError, classifyAcmeFailure, } from './acme-failure-classification.js';
4
+ /** Attempts allowed for transient SmartAcme startup failures before giving up. */
5
+ export const smartAcmeStartMaxAttempts = 20;
3
6
  /**
4
7
  * Background start/retry/stop lifecycle for the DcRouter-owned SmartAcme
5
8
  * instance. SmartAcme startup can hit ACME rate limits, so startup runs in
6
9
  * the background with generation-guarded exponential retry, and certificate
7
10
  * provisioning is re-triggered once DNS-01 becomes ready.
11
+ *
12
+ * Retry semantics, which are NOT shared with the per-domain
13
+ * `CertProvisionScheduler` budget:
14
+ * - increments once per failed `smartAcme.start()`;
15
+ * - 5 s → 1 h exponential backoff with ±20% jitter;
16
+ * - capped at `smartAcmeStartMaxAttempts` transient attempts;
17
+ * - reset by `startInBackground()`, `stop()`, and a successful start;
18
+ * - re-armed only by `startInBackground()`, i.e. a SmartProxy rebuild, an
19
+ * explicit `rearm()` after a configuration change, or a process restart.
20
+ * Nothing re-arms it on a timer, so the terminal state is recorded in
21
+ * `startFailure` and logged at `error` instead of scrolling past as a warning.
22
+ *
23
+ * A permanent cause never enters the backoff at all: retrying a misconfigured
24
+ * ACME account cannot fix it, and spending the budget on it hides the reason.
8
25
  */
9
26
  export class SmartAcmeLifecycle {
10
27
  dcRouterRef;
@@ -12,6 +29,11 @@ export class SmartAcmeLifecycle {
12
29
  ready = false;
13
30
  /** Tracks whether the taskbuffer SmartAcme service is started, so SmartProxy rebuilds can re-kick startup. */
14
31
  serviceStarted = false;
32
+ /**
33
+ * Set when the startup budget ended — either immediately for a permanent cause
34
+ * or after the transient attempt cap. Cleared on every (re-)arm and on success.
35
+ */
36
+ startFailure;
15
37
  startGeneration = 0;
16
38
  startPromise;
17
39
  retryTimer;
@@ -27,13 +49,33 @@ export class SmartAcmeLifecycle {
27
49
  const generation = ++this.startGeneration;
28
50
  this.ready = false;
29
51
  this.retryAttempt = 0;
52
+ this.startFailure = undefined;
30
53
  this.clearRetryTimer();
31
54
  this.scheduleStart(generation, 0);
32
55
  }
56
+ /**
57
+ * Re-arm startup after a configuration change that can plausibly fix a
58
+ * previously terminal cause (e.g. the ACME account settings were corrected).
59
+ * Without this, an exhausted or permanently-failed budget could only be reset
60
+ * by a SmartProxy rebuild or a full restart — and a dcrouter restart is a
61
+ * measured 30–60 s of total public outage.
62
+ */
63
+ rearm(reasonArg) {
64
+ if (!this.dcRouterRef.smartAcme || !this.serviceStarted) {
65
+ return false;
66
+ }
67
+ if (this.ready && !this.startFailure) {
68
+ return false;
69
+ }
70
+ logger.log('info', `Re-arming SmartAcme DNS-01 provider startup: ${reasonArg}`);
71
+ this.startInBackground();
72
+ return true;
73
+ }
33
74
  async stop() {
34
75
  this.startGeneration++;
35
76
  this.ready = false;
36
77
  this.retryAttempt = 0;
78
+ this.startFailure = undefined;
37
79
  this.clearRetryTimer();
38
80
  const smartAcme = this.dcRouterRef.smartAcme;
39
81
  if (!smartAcme) {
@@ -82,6 +124,7 @@ export class SmartAcmeLifecycle {
82
124
  }
83
125
  this.ready = true;
84
126
  this.retryAttempt = 0;
127
+ this.startFailure = undefined;
85
128
  logger.log('info', 'SmartAcme DNS-01 provider is now ready');
86
129
  this.retriggerCertificateProvisioning();
87
130
  }
@@ -93,9 +136,37 @@ export class SmartAcmeLifecycle {
93
136
  await smartAcme.stop().catch((stopErr) => {
94
137
  logger.log('warn', `Failed to clean up SmartAcme after startup failure: ${stopErr.message}`);
95
138
  });
139
+ // Classify before spending any of the budget: a permanent cause is not made
140
+ // truer by 20 more attempts, and every attempt spent on it is an hour in
141
+ // which nothing tells the operator what is actually wrong.
142
+ const classification = classifyAcmeFailure(err);
143
+ if (classification.permanent) {
144
+ this.startFailure = {
145
+ reason: classification.reason,
146
+ permanent: true,
147
+ attempts: this.retryAttempt,
148
+ message: classification.message,
149
+ at: Date.now(),
150
+ rearmedBy: 'fixing the ACME configuration (which calls rearm()), a SmartProxy rebuild, or a process restart',
151
+ };
152
+ // Constructing this logs at `error` with the code and category attached.
153
+ new AcmePermanentFailureError(classification, 'SmartAcme DNS-01 provider startup', 'smartacme-lifecycle', { data: { attempts: this.retryAttempt, rearmedBy: this.startFailure.rearmedBy } });
154
+ return;
155
+ }
96
156
  this.retryAttempt++;
97
- if (this.retryAttempt > 20) {
98
- logger.log('error', `SmartAcme DNS-01 provider failed after 20 startup attempts: ${err.message}`);
157
+ if (this.retryAttempt > smartAcmeStartMaxAttempts) {
158
+ this.startFailure = {
159
+ reason: classification.reason,
160
+ permanent: false,
161
+ attempts: this.retryAttempt - 1,
162
+ message: classification.message,
163
+ at: Date.now(),
164
+ rearmedBy: 'a SmartProxy rebuild, an explicit rearm() after a configuration change, or a process restart',
165
+ };
166
+ logger.log('error', `SmartAcme DNS-01 provider gave up after ${smartAcmeStartMaxAttempts} startup attempts `
167
+ + `(${classification.reason}): ${classification.message}. `
168
+ + 'Nothing re-arms this on a timer — DNS-01 stays unavailable and every affected route falls back to a '
169
+ + `no-op http-01 path until ${this.startFailure.rearmedBy}.`, { acmeFailureReason: classification.reason, attempts: this.startFailure.attempts });
99
170
  return;
100
171
  }
101
172
  const baseDelayMs = 5000;
@@ -103,7 +174,7 @@ export class SmartAcmeLifecycle {
103
174
  const delayMs = Math.min(baseDelayMs * Math.pow(2, this.retryAttempt - 1), maxDelayMs);
104
175
  const jitter = 0.8 + Math.random() * 0.4;
105
176
  const actualDelayMs = Math.floor(delayMs * jitter);
106
- logger.log('warn', `SmartAcme DNS-01 provider startup failed: ${err.message}; retrying in ${actualDelayMs}ms (attempt ${this.retryAttempt}/20)`);
177
+ logger.log('warn', `SmartAcme DNS-01 provider startup failed: ${err.message}; retrying in ${actualDelayMs}ms (attempt ${this.retryAttempt}/${smartAcmeStartMaxAttempts})`);
107
178
  this.scheduleStart(generation, actualDelayMs);
108
179
  }
109
180
  finally {
@@ -141,4 +212,4 @@ export class SmartAcmeLifecycle {
141
212
  }
142
213
  }
143
214
  }
144
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zbWFydGFjbWUtbGlmZWN5Y2xlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvYWNtZS9jbGFzc2VzLnNtYXJ0YWNtZS1saWZlY3ljbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUd0Qzs7Ozs7R0FLRztBQUNILE1BQU0sT0FBTyxrQkFBa0I7SUFXVDtJQVZwQixpRUFBaUU7SUFDMUQsS0FBSyxHQUFHLEtBQUssQ0FBQztJQUNyQiw4R0FBOEc7SUFDdkcsY0FBYyxHQUFHLEtBQUssQ0FBQztJQUV0QixlQUFlLEdBQUcsQ0FBQyxDQUFDO0lBQ3BCLFlBQVksQ0FBaUI7SUFDN0IsVUFBVSxDQUFpQztJQUMzQyxZQUFZLEdBQUcsQ0FBQyxDQUFDO0lBRXpCLFlBQW9CLFdBQXFCO1FBQXJCLGdCQUFXLEdBQVgsV0FBVyxDQUFVO0lBQUcsQ0FBQztJQUV0QyxpQkFBaUI7UUFDdEIsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDaEMsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7WUFDbkIsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLFVBQVUsR0FBRyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDMUMsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUM7UUFDdEIsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFTSxLQUFLLENBQUMsSUFBSTtRQUNmLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsS0FBSyxHQUFHLEtB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
215
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zbWFydGFjbWUtbGlmZWN5Y2xlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvYWNtZS9jbGFzc2VzLnNtYXJ0YWNtZS1saWZlY3ljbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUV0QyxPQUFPLEVBQ0wseUJBQXlCLEVBQ3pCLG1CQUFtQixHQUVwQixNQUFNLGtDQUFrQyxDQUFDO0FBZTFDLGtGQUFrRjtBQUNsRixNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBRyxFQUFFLENBQUM7QUFFNUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQkc7QUFDSCxNQUFNLE9BQU8sa0JBQWtCO0lBZ0JUO0lBZnBCLGlFQUFpRTtJQUMxRCxLQUFLLEdBQUcsS0FBSyxDQUFDO0lBQ3JCLDhHQUE4RztJQUN2RyxjQUFjLEdBQUcsS0FBSyxDQUFDO0lBQzlCOzs7T0FHRztJQUNJLFlBQVksQ0FBcUI7SUFFaEMsZUFBZSxHQUFHLENBQUMsQ0FBQztJQUNwQixZQUFZLENBQWlCO0lBQzdCLFVBQVUsQ0FBaUM7SUFDM0MsWUFBWSxHQUFHLENBQUMsQ0FBQztJQUV6QixZQUFvQixXQUFxQjtRQUFyQixnQkFBVyxHQUFYLFdBQVcsQ0FBVTtJQUFHLENBQUM7SUFFdEMsaUJBQWlCO1FBQ3RCLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ2hDLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1lBQ25CLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxVQUFVLEdBQUcsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDO1FBQzFDLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDO1FBQ3RCLElBQUksQ0FBQyxZQUFZLEdBQUcsU0FBUyxDQUFDO1FBQzlCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksS0FBSyxDQUFDLFNBQWlCO1FBQzVCLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN4RCxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDckMsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBQ0QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsZ0RBQWdELFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDaEYsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDekIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRU0sS0FBSyxDQUFDLElBQUk7UUFDZixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUM7UUFDdEIsSUFBSSxDQUFDLFlBQVksR0FBRyxTQUFTLENBQUM7UUFDOUIsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBRXZCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDO1FBQzdDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNmLE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDekIsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixNQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzFFLENBQUM7Z0JBQVMsQ0FBQztZQUNULElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQzdDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztZQUN6QyxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFTyxhQUFhLENBQUMsVUFBa0IsRUFBRSxPQUFlO1FBQ3ZELElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN2QixNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2pDLElBQUksQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDO1lBQzVCLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7Z0JBQzdDLE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLHVDQUF3QyxHQUFhLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUN2RixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNaLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQzdCLE1BQU0sY0FBYyxHQUFHLFVBQWlCLENBQUM7UUFDekMsSUFBSSxPQUFPLGNBQWMsRUFBRSxLQUFLLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDaEQsY0FBYyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3pCLENBQUM7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLGVBQWUsQ0FBQyxVQUFrQjtRQUM5QyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQztRQUM3QyxJQUFJLENBQUMsU0FBUyxJQUFJLFVBQVUsS0FBSyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDdEQsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLFlBQVksR0FBRyxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUM7UUFFakMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxZQUFZLENBQUM7WUFDbkIsSUFBSSxVQUFVLEtBQUssSUFBSSxDQUFDLGVBQWUsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDcEYsTUFBTSxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7b0JBQ25DLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLDRDQUE2QyxHQUFhLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztnQkFDM0YsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsT0FBTztZQUNULENBQUM7WUFFRCxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztZQUNsQixJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQztZQUN0QixJQUFJLENBQUMsWUFBWSxHQUFHLFNBQVMsQ0FBQztZQUM5QixNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSx3Q0FBd0MsQ0FBQyxDQUFDO1lBQzdELElBQUksQ0FBQyxnQ0FBZ0MsRUFBRSxDQUFDO1FBQzFDLENBQUM7UUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1lBQ2IsSUFBSSxVQUFVLEtBQUssSUFBSSxDQUFDLGVBQWUsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDcEYsT0FBTztZQUNULENBQUM7WUFFRCxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztZQUNuQixNQUFNLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtnQkFDdkMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsdURBQXdELE9BQWlCLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUMxRyxDQUFDLENBQUMsQ0FBQztZQUVILDRFQUE0RTtZQUM1RSx5RUFBeUU7WUFDekUsMkRBQTJEO1lBQzNELE1BQU0sY0FBYyxHQUFHLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2hELElBQUksY0FBYyxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUM3QixJQUFJLENBQUMsWUFBWSxHQUFHO29CQUNsQixNQUFNLEVBQUUsY0FBYyxDQUFDLE1BQU07b0JBQzdCLFNBQVMsRUFBRSxJQUFJO29CQUNmLFFBQVEsRUFBRSxJQUFJLENBQUMsWUFBWTtvQkFDM0IsT0FBTyxFQUFFLGNBQWMsQ0FBQyxPQUFPO29CQUMvQixFQUFFLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRTtvQkFDZCxTQUFTLEVBQUUsaUdBQWlHO2lCQUM3RyxDQUFDO2dCQUNGLHlFQUF5RTtnQkFDekUsSUFBSSx5QkFBeUIsQ0FDM0IsY0FBYyxFQUNkLG1DQUFtQyxFQUNuQyxxQkFBcUIsRUFDckIsRUFBRSxJQUFJLEVBQUUsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUNsRixDQUFDO2dCQUNGLE9BQU87WUFDVCxDQUFDO1lBRUQsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3BCLElBQUksSUFBSSxDQUFDLFlBQVksR0FBRyx5QkFBeUIsRUFBRSxDQUFDO2dCQUNsRCxJQUFJLENBQUMsWUFBWSxHQUFHO29CQUNsQixNQUFNLEVBQUUsY0FBYyxDQUFDLE1BQU07b0JBQzdCLFNBQVMsRUFBRSxLQUFLO29CQUNoQixRQUFRLEVBQUUsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDO29CQUMvQixPQUFPLEVBQUUsY0FBYyxDQUFDLE9BQU87b0JBQy9CLEVBQUUsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFO29CQUNkLFNBQVMsRUFBRSw4RkFBOEY7aUJBQzFHLENBQUM7Z0JBQ0YsTUFBTSxDQUFDLEdBQUcsQ0FDUixPQUFPLEVBQ1AsMkNBQTJDLHlCQUF5QixvQkFBb0I7c0JBQ3BGLElBQUksY0FBYyxDQUFDLE1BQU0sTUFBTSxjQUFjLENBQUMsT0FBTyxJQUFJO3NCQUN6RCxzR0FBc0c7c0JBQ3RHLDRCQUE0QixJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsR0FBRyxFQUM5RCxFQUFFLGlCQUFpQixFQUFFLGNBQWMsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLENBQ25GLENBQUM7Z0JBQ0YsT0FBTztZQUNULENBQUM7WUFFRCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUM7WUFDekIsTUFBTSxVQUFVLEdBQUcsU0FBUyxDQUFDO1lBQzdCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDdkYsTUFBTSxNQUFNLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUM7WUFDekMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDLENBQUM7WUFDbkQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsNkNBQThDLEdBQWEsQ0FBQyxPQUFPLGlCQUFpQixhQUFhLGVBQWUsSUFBSSxDQUFDLFlBQVksSUFBSSx5QkFBeUIsR0FBRyxDQUFDLENBQUM7WUFDdEwsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDaEQsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsSUFBSSxJQUFJLENBQUMsWUFBWSxLQUFLLFlBQVksRUFBRSxDQUFDO2dCQUN2QyxJQUFJLENBQUMsWUFBWSxHQUFHLFNBQVMsQ0FBQztZQUNoQyxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFTyxnQ0FBZ0M7UUFDdEMsdUZBQXVGO1FBQ3ZGLGtGQUFrRjtRQUNsRixxREFBcUQ7UUFDckQsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDeEMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsK0RBQStELENBQUMsQ0FBQztZQUNwRixJQUFJLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLFdBQVcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQVEsRUFBRSxFQUFFO2dCQUNuRSxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSwyQ0FBMkMsR0FBRyxFQUFFLE9BQU8sSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZGLENBQUMsQ0FBQyxDQUFDO1lBQ0gsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDaEMsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLHNCQUFzQixFQUFFLENBQUM7Z0JBQzVDLElBQUksQ0FBQyxXQUFXLENBQUMsc0JBQXNCLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDbEQsQ0FBQztZQUNELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUMzRSxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSw4Q0FBOEMsYUFBYSxDQUFDLE1BQU0sU0FBUyxDQUFDLENBQUM7WUFDaEcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQVEsRUFBRSxFQUFFO2dCQUN6RSxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSwyQ0FBMkMsR0FBRyxFQUFFLE9BQU8sSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZGLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7SUFFTyxlQUFlO1FBQ3JCLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3BCLFlBQVksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDOUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFDOUIsQ0FBQztJQUNILENBQUM7Q0FDRiJ9
@@ -1,2 +1,3 @@
1
1
  export * from './manager.acme-config.js';
2
2
  export * from './classes.smartacme-lifecycle.js';
3
+ export * from './acme-failure-classification.js';
@@ -1,3 +1,4 @@
1
1
  export * from './manager.acme-config.js';
2
2
  export * from './classes.smartacme-lifecycle.js';
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9hY21lL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsMEJBQTBCLENBQUM7QUFDekMsY0FBYyxrQ0FBa0MsQ0FBQyJ9
3
+ export * from './acme-failure-classification.js';
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9hY21lL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsMEJBQTBCLENBQUM7QUFDekMsY0FBYyxrQ0FBa0MsQ0FBQztBQUNqRCxjQUFjLGtDQUFrQyxDQUFDIn0=
@@ -12,6 +12,7 @@ import { RouteConfigManager, ApiTokenManager, GatewayClientManager, ReferenceRes
12
12
  import { SecurityPolicyManager, RoutePolicyAugmenter } from './security/index.js';
13
13
  import { type IHttp3Config } from './http3/index.js';
14
14
  import { DnsManager } from './dns/manager.dns.js';
15
+ import { DnsAuthorityManager } from './dns/manager.dns-authority.js';
15
16
  import { DnsServerRuntime } from './dns/classes.dns-server-runtime.js';
16
17
  import { GatewayRouteDnsReconciler } from './dns/classes.gateway-route-dns-reconciler.js';
17
18
  import { AcmeConfigManager } from './acme/manager.acme-config.js';
@@ -61,16 +62,14 @@ export interface IDcRouterOptions {
61
62
  /**
62
63
  * The nameserver domains (e.g., ['ns1.example.com', 'ns2.example.com'])
63
64
  * These will automatically get A records pointing to publicIp or proxyIps[0]
64
- * These are what go in the NS records for ALL domains in dnsScopes
65
+ * A zone becomes authoritative by having its public NS records observed
66
+ * naming one of these — that is the only way into the authority set.
67
+ *
68
+ * There is deliberately no `dnsScopes` counterpart. Which zones dcrouter
69
+ * answers for is database state carrying its own delegation evidence, not
70
+ * deployment configuration; see ts/dns/manager.dns-authority.ts.
65
71
  */
66
72
  dnsNsDomains?: string[];
67
- /**
68
- * Domains this DNS server is authoritative for (e.g., ['example.com', 'mail.example.org'])
69
- * NS records will be auto-generated for these domains
70
- * Any DNS record outside these scopes will trigger a warning
71
- * Email domains with `internal-dns` mode must be included here
72
- */
73
- dnsScopes?: string[];
74
73
  /** Explicit UDP bind address for the embedded DNS server. Defaults to auto-detection. */
75
74
  dnsBindInterface?: string;
76
75
  /**
@@ -88,7 +87,7 @@ export interface IDcRouterOptions {
88
87
  publicIp?: string;
89
88
  /**
90
89
  * DNS records to register
91
- * Must be within the defined dnsScopes (or receive warning)
90
+ * Must be within a delegation-verified zone (or receive warning)
92
91
  * Only need A, CNAME, TXT, MX records (NS records auto-generated, SOA handled by smartdns)
93
92
  * Can use `useIngressProxy: false` to expose real server IP (defaults to true)
94
93
  */
@@ -246,6 +245,8 @@ export declare class DcRouter {
246
245
  referenceResolver?: ReferenceResolver;
247
246
  targetProfileManager?: TargetProfileManager;
248
247
  dnsManager?: DnsManager;
248
+ /** Owns which zones dcrouter may answer for authoritatively, and proves it. */
249
+ dnsAuthorityManager?: DnsAuthorityManager;
249
250
  gatewayRouteDnsReconciler?: GatewayRouteDnsReconciler;
250
251
  opsEventManager?: OpsEventManager;
251
252
  acmeConfigManager?: AcmeConfigManager;
@@ -373,6 +374,29 @@ export declare class DcRouter {
373
374
  /** Serialized edge mutation on the RemoteIngress hub (delegates to the hub lifecycle). */
374
375
  mutateRemoteIngressEdges<T>(mutation: (manager: RemoteIngressManager) => Promise<T>, syncAllowedEdges?: boolean): Promise<T>;
375
376
  updateRemoteIngressHubSettings(updates: TRemoteIngressHubSettingsUpdate, updatedBy: string): Promise<IRemoteIngressHubSettings>;
377
+ /**
378
+ * Re-derive every piece of runtime state that depends on the effective DNS
379
+ * authority set, after a zone gained or lost delegation-verified authority.
380
+ *
381
+ * Deliberately reuses the existing machinery rather than paralleling it:
382
+ * `reconcileAuthoritativeZones()` drives the same `runtimeRegistrations`
383
+ * registry that domain deletion uses, and the overlay and route-warning
384
+ * refreshes are the same calls the domain mutation paths make. Throws on the
385
+ * first failure so `DnsAuthorityManager` can roll the change back rather than
386
+ * leave the router half-converted.
387
+ */
388
+ reconcileDnsAuthority(reasonArg: string): Promise<void>;
389
+ /**
390
+ * Re-derive the private-route DNS overlay from the currently applied route set.
391
+ *
392
+ * The overlay is derived from routes but gated on domain ownership, so a domain
393
+ * mutation can invalidate it without any route changing. Deleting a DomainDoc
394
+ * is the case that matters: without this the overlay keeps answering `aa` for a
395
+ * hostname whose zone we no longer manage until some unrelated route apply
396
+ * happens. Named here so the mutation site can trigger its own invalidation
397
+ * instead of forcing a full route re-apply.
398
+ */
399
+ resyncPrivateRouteDnsOverlay(reasonArg: string): Promise<void>;
376
400
  /** Restart SmartProxy after RemoteIngress hub settings changed listener wiring. Called by RemoteIngressHubLifecycle. */
377
401
  restartSmartProxyForRemoteIngressSettings(): Promise<void>;
378
402
  /** Bootstrap routes the RemoteIngress hub uses to derive edge ports before the DB route set is applied. */