@ttt-productions/ttt-core 0.79.49 → 0.79.50

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 (31) hide show
  1. package/dist/constants/craft-skill-statements.d.ts +20 -0
  2. package/dist/constants/craft-skill-statements.d.ts.map +1 -1
  3. package/dist/constants/craft-skill-statements.js +25 -9
  4. package/dist/constants/craft-skill-statements.js.map +1 -1
  5. package/dist/constants/legal-review-notice.d.ts +3 -0
  6. package/dist/constants/legal-review-notice.d.ts.map +1 -1
  7. package/dist/constants/legal-review-notice.js +3 -0
  8. package/dist/constants/legal-review-notice.js.map +1 -1
  9. package/dist/constants/public-documents.d.ts +7 -0
  10. package/dist/constants/public-documents.d.ts.map +1 -1
  11. package/dist/constants/public-documents.js +7 -0
  12. package/dist/constants/public-documents.js.map +1 -1
  13. package/dist/doc-schemas/ncii/config.d.ts +1 -5
  14. package/dist/doc-schemas/ncii/config.d.ts.map +1 -1
  15. package/dist/doc-schemas/ncii/config.js +8 -19
  16. package/dist/doc-schemas/ncii/config.js.map +1 -1
  17. package/dist/doc-schemas/operational.d.ts +47 -2
  18. package/dist/doc-schemas/operational.d.ts.map +1 -1
  19. package/dist/doc-schemas/operational.js +32 -7
  20. package/dist/doc-schemas/operational.js.map +1 -1
  21. package/dist/doc-schemas/registry.d.ts +14 -7
  22. package/dist/doc-schemas/registry.d.ts.map +1 -1
  23. package/dist/schemas/utility.d.ts +2 -0
  24. package/dist/schemas/utility.d.ts.map +1 -1
  25. package/dist/schemas/utility.js +5 -2
  26. package/dist/schemas/utility.js.map +1 -1
  27. package/dist/utils/public-documents.d.ts +14 -0
  28. package/dist/utils/public-documents.d.ts.map +1 -1
  29. package/dist/utils/public-documents.js +20 -0
  30. package/dist/utils/public-documents.js.map +1 -1
  31. package/package.json +1 -1
@@ -7,4 +7,24 @@ export declare const CRAFT_SKILL_KIND_LABELS: Record<CraftSkillKind, string>;
7
7
  export declare const CRAFT_SKILL_KIND_DESCRIPTIONS: Record<CraftSkillKind, string>;
8
8
  export declare const CRAFT_SKILL_STATEMENTS: Record<CraftSkillKind, string>;
9
9
  export declare const CRAFT_SKILL_KIND_ORDER: CraftSkillKind[];
10
+ /**
11
+ * Why "Mimicked work from outside TTT Productions" cannot be chosen yet: the picker shows it
12
+ * when a person selects that kind, and the upload callable refuses the kind with the same words.
13
+ */
14
+ export declare const CRAFT_SKILL_MIMIC_OFF_TTT_UNAVAILABLE_MESSAGE = "This option isn't available yet: sharing covers or recreations of work from outside TTT needs legal review first.";
15
+ /**
16
+ * The ONE owner of which craft kinds are blocked at launch, with each one's refusal copy. A
17
+ * blocked kind still renders in the picker (so people see it is coming) but selecting it stops
18
+ * the flow with this copy, and the upload callable refuses it with the same words. Unblocking a
19
+ * kind is removing its entry here.
20
+ */
21
+ export declare const CRAFT_SKILL_KIND_UNAVAILABLE_MESSAGES: {
22
+ readonly mimicOffTtt: "This option isn't available yet: sharing covers or recreations of work from outside TTT needs legal review first.";
23
+ };
24
+ /** A craft kind that is blocked at launch. */
25
+ export type BlockedCraftSkillKind = keyof typeof CRAFT_SKILL_KIND_UNAVAILABLE_MESSAGES;
26
+ /** Every craft kind blocked at launch — derived from the refusal copy, never restated. */
27
+ export declare const BLOCKED_CRAFT_SKILL_KINDS: readonly BlockedCraftSkillKind[];
28
+ /** True when `kind` is blocked at launch; narrows it to index its refusal copy. */
29
+ export declare function isBlockedCraftSkillKind(kind: CraftSkillKind): kind is BlockedCraftSkillKind;
10
30
  //# sourceMappingURL=craft-skill-statements.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"craft-skill-statements.d.ts","sourceRoot":"","sources":["../../src/constants/craft-skill-statements.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D;kEACkE;AAClE,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAE/C,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAIlE,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,6BAA6B,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAIxE,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAOjE,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,cAAc,EAA8C,CAAC"}
1
+ {"version":3,"file":"craft-skill-statements.d.ts","sourceRoot":"","sources":["../../src/constants/craft-skill-statements.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D;kEACkE;AAClE,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAE/C,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAIlE,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,6BAA6B,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAIxE,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAOjE,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,cAAc,EAA8C,CAAC;AAElG;;;GAGG;AACH,eAAO,MAAM,6CAA6C,sHAC2D,CAAC;AAEtH;;;;;GAKG;AACH,eAAO,MAAM,qCAAqC;;CAEU,CAAC;AAE7D,8CAA8C;AAC9C,MAAM,MAAM,qBAAqB,GAAG,MAAM,OAAO,qCAAqC,CAAC;AAEvF,0FAA0F;AAC1F,eAAO,MAAM,yBAAyB,EAEjC,SAAS,qBAAqB,EAAE,CAAC;AAEtC,mFAAmF;AACnF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,IAAI,qBAAqB,CAE3F"}
@@ -1,14 +1,10 @@
1
1
  // ============================================================================
2
2
  // CRAFT-SKILL ATTESTATION — the ONE home for the three-kind upload flow's
3
- // statement version, VERBATIM agreement statements (v1, wording agreed with DJ
4
- // 2026-07-04), kind labels/descriptions, and picker order. Consolidated here
5
- // 2026-07-13 from the former "keep identical" pair in ttt-prod
6
- // `src/lib/craft-skill-statements.ts` (live frontend copy) and
7
- // `functions/src/craft-skills/craftSkillUploadContract.ts` (dead backend
8
- // mirror). The client displays these and the user must explicitly agree before
9
- // the file picker unlocks; the backend records only `{ statementKind,
10
- // statementVersion, agreedAt }` and validates the version against
11
- // CRAFT_SKILL_STATEMENT_VERSION.
3
+ // statement version, VERBATIM agreement statements, kind labels/descriptions,
4
+ // picker order, and the refusal copy for a kind that is not available yet. The
5
+ // client displays these and the user must explicitly agree before the file
6
+ // picker unlocks; the backend records only `{ statementKind, statementVersion,
7
+ // agreedAt }` and validates the version against CRAFT_SKILL_STATEMENT_VERSION.
12
8
  // ============================================================================
13
9
  /** Bump when any VERBATIM statement below changes; the version is recorded on every
14
10
  * craft-skill doc so we know which wording the user agreed to. */
@@ -30,4 +26,24 @@ export const CRAFT_SKILL_STATEMENTS = {
30
26
  mimicOffTtt: 'This craft skill is my performance or recreation of a work that did not originate on TTT Productions (including public-domain or out-of-copyright works), shown only to demonstrate my abilities. The underlying work belongs to its owner, and I claim no ownership of it. I understand TTT Productions may remove this content at any time, including in response to a rights-holder request.',
31
27
  };
32
28
  export const CRAFT_SKILL_KIND_ORDER = ['original', 'mimicOnTtt', 'mimicOffTtt'];
29
+ /**
30
+ * Why "Mimicked work from outside TTT Productions" cannot be chosen yet: the picker shows it
31
+ * when a person selects that kind, and the upload callable refuses the kind with the same words.
32
+ */
33
+ export const CRAFT_SKILL_MIMIC_OFF_TTT_UNAVAILABLE_MESSAGE = "This option isn't available yet: sharing covers or recreations of work from outside TTT needs legal review first.";
34
+ /**
35
+ * The ONE owner of which craft kinds are blocked at launch, with each one's refusal copy. A
36
+ * blocked kind still renders in the picker (so people see it is coming) but selecting it stops
37
+ * the flow with this copy, and the upload callable refuses it with the same words. Unblocking a
38
+ * kind is removing its entry here.
39
+ */
40
+ export const CRAFT_SKILL_KIND_UNAVAILABLE_MESSAGES = {
41
+ mimicOffTtt: CRAFT_SKILL_MIMIC_OFF_TTT_UNAVAILABLE_MESSAGE,
42
+ };
43
+ /** Every craft kind blocked at launch — derived from the refusal copy, never restated. */
44
+ export const BLOCKED_CRAFT_SKILL_KINDS = Object.keys(CRAFT_SKILL_KIND_UNAVAILABLE_MESSAGES);
45
+ /** True when `kind` is blocked at launch; narrows it to index its refusal copy. */
46
+ export function isBlockedCraftSkillKind(kind) {
47
+ return Object.prototype.hasOwnProperty.call(CRAFT_SKILL_KIND_UNAVAILABLE_MESSAGES, kind);
48
+ }
33
49
  //# sourceMappingURL=craft-skill-statements.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"craft-skill-statements.js","sourceRoot":"","sources":["../../src/constants/craft-skill-statements.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,0EAA0E;AAC1E,+EAA+E;AAC/E,6EAA6E;AAC7E,+DAA+D;AAC/D,+DAA+D;AAC/D,yEAAyE;AACzE,+EAA+E;AAC/E,sEAAsE;AACtE,kEAAkE;AAClE,iCAAiC;AACjC,+EAA+E;AAI/E;kEACkE;AAClE,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC;AAE/C,MAAM,CAAC,MAAM,uBAAuB,GAAmC;IACrE,QAAQ,EAAE,aAAa;IACvB,UAAU,EAAE,oCAAoC;IAChD,WAAW,EAAE,4CAA4C;CAC1D,CAAC;AAEF,kEAAkE;AAClE,MAAM,CAAC,MAAM,6BAA6B,GAAmC;IAC3E,QAAQ,EAAE,sCAAsC;IAChD,UAAU,EAAE,gFAAgF;IAC5F,WAAW,EAAE,iFAAiF;CAC/F,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAmC;IACpE,QAAQ,EACN,qJAAqJ;IACvJ,UAAU,EACR,oRAAoR;IACtR,WAAW,EACT,iYAAiY;CACpY,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAqB,CAAC,UAAU,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC","sourcesContent":["// ============================================================================\n// CRAFT-SKILL ATTESTATION — the ONE home for the three-kind upload flow's\n// statement version, VERBATIM agreement statements (v1, wording agreed with DJ\n// 2026-07-04), kind labels/descriptions, and picker order. Consolidated here\n// 2026-07-13 from the former \"keep identical\" pair in ttt-prod\n// `src/lib/craft-skill-statements.ts` (live frontend copy) and\n// `functions/src/craft-skills/craftSkillUploadContract.ts` (dead backend\n// mirror). The client displays these and the user must explicitly agree before\n// the file picker unlocks; the backend records only `{ statementKind,\n// statementVersion, agreedAt }` and validates the version against\n// CRAFT_SKILL_STATEMENT_VERSION.\n// ============================================================================\n\nimport type { CraftSkillKind } from '../doc-schemas/user.js';\n\n/** Bump when any VERBATIM statement below changes; the version is recorded on every\n * craft-skill doc so we know which wording the user agreed to. */\nexport const CRAFT_SKILL_STATEMENT_VERSION = 1;\n\nexport const CRAFT_SKILL_KIND_LABELS: Record<CraftSkillKind, string> = {\n original: 'My own work',\n mimicOnTtt: 'Mimicked work from TTT Productions',\n mimicOffTtt: 'Mimicked work from outside TTT Productions',\n};\n\n/** One-line helper shown under each kind option in the picker. */\nexport const CRAFT_SKILL_KIND_DESCRIPTIONS: Record<CraftSkillKind, string> = {\n original: 'Entirely your own original creation.',\n mimicOnTtt: 'Your performance or recreation of another member’s TTT work (link the source).',\n mimicOffTtt: 'A cover or recreation of work from outside TTT (including public-domain works).',\n};\n\nexport const CRAFT_SKILL_STATEMENTS: Record<CraftSkillKind, string> = {\n original:\n 'I certify this craft skill is entirely my own original creation and I own all rights to it. No part of it copies or imitates another person’s work.',\n mimicOnTtt:\n 'This craft skill is my performance or recreation of work created by a member of the TTT Productions community, shown here to demonstrate my abilities. I have linked the original artisan or work below. The original work belongs to its creator, and I claim no ownership of it.',\n mimicOffTtt:\n 'This craft skill is my performance or recreation of a work that did not originate on TTT Productions (including public-domain or out-of-copyright works), shown only to demonstrate my abilities. The underlying work belongs to its owner, and I claim no ownership of it. I understand TTT Productions may remove this content at any time, including in response to a rights-holder request.',\n};\n\nexport const CRAFT_SKILL_KIND_ORDER: CraftSkillKind[] = ['original', 'mimicOnTtt', 'mimicOffTtt'];\n"]}
1
+ {"version":3,"file":"craft-skill-statements.js","sourceRoot":"","sources":["../../src/constants/craft-skill-statements.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,0EAA0E;AAC1E,8EAA8E;AAC9E,+EAA+E;AAC/E,2EAA2E;AAC3E,+EAA+E;AAC/E,+EAA+E;AAC/E,+EAA+E;AAI/E;kEACkE;AAClE,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC;AAE/C,MAAM,CAAC,MAAM,uBAAuB,GAAmC;IACrE,QAAQ,EAAE,aAAa;IACvB,UAAU,EAAE,oCAAoC;IAChD,WAAW,EAAE,4CAA4C;CAC1D,CAAC;AAEF,kEAAkE;AAClE,MAAM,CAAC,MAAM,6BAA6B,GAAmC;IAC3E,QAAQ,EAAE,sCAAsC;IAChD,UAAU,EAAE,gFAAgF;IAC5F,WAAW,EAAE,iFAAiF;CAC/F,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAmC;IACpE,QAAQ,EACN,qJAAqJ;IACvJ,UAAU,EACR,oRAAoR;IACtR,WAAW,EACT,iYAAiY;CACpY,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAqB,CAAC,UAAU,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;AAElG;;;GAGG;AACH,MAAM,CAAC,MAAM,6CAA6C,GACxD,mHAAmH,CAAC;AAEtH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qCAAqC,GAAG;IACnD,WAAW,EAAE,6CAA6C;CACA,CAAC;AAK7D,0FAA0F;AAC1F,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,IAAI,CAClD,qCAAqC,CACF,CAAC;AAEtC,mFAAmF;AACnF,MAAM,UAAU,uBAAuB,CAAC,IAAoB;IAC1D,OAAO,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,qCAAqC,EAAE,IAAI,CAAC,CAAC;AAC3F,CAAC","sourcesContent":["// ============================================================================\n// CRAFT-SKILL ATTESTATION — the ONE home for the three-kind upload flow's\n// statement version, VERBATIM agreement statements, kind labels/descriptions,\n// picker order, and the refusal copy for a kind that is not available yet. The\n// client displays these and the user must explicitly agree before the file\n// picker unlocks; the backend records only `{ statementKind, statementVersion,\n// agreedAt }` and validates the version against CRAFT_SKILL_STATEMENT_VERSION.\n// ============================================================================\n\nimport type { CraftSkillKind } from '../doc-schemas/user.js';\n\n/** Bump when any VERBATIM statement below changes; the version is recorded on every\n * craft-skill doc so we know which wording the user agreed to. */\nexport const CRAFT_SKILL_STATEMENT_VERSION = 1;\n\nexport const CRAFT_SKILL_KIND_LABELS: Record<CraftSkillKind, string> = {\n original: 'My own work',\n mimicOnTtt: 'Mimicked work from TTT Productions',\n mimicOffTtt: 'Mimicked work from outside TTT Productions',\n};\n\n/** One-line helper shown under each kind option in the picker. */\nexport const CRAFT_SKILL_KIND_DESCRIPTIONS: Record<CraftSkillKind, string> = {\n original: 'Entirely your own original creation.',\n mimicOnTtt: 'Your performance or recreation of another member’s TTT work (link the source).',\n mimicOffTtt: 'A cover or recreation of work from outside TTT (including public-domain works).',\n};\n\nexport const CRAFT_SKILL_STATEMENTS: Record<CraftSkillKind, string> = {\n original:\n 'I certify this craft skill is entirely my own original creation and I own all rights to it. No part of it copies or imitates another person’s work.',\n mimicOnTtt:\n 'This craft skill is my performance or recreation of work created by a member of the TTT Productions community, shown here to demonstrate my abilities. I have linked the original artisan or work below. The original work belongs to its creator, and I claim no ownership of it.',\n mimicOffTtt:\n 'This craft skill is my performance or recreation of a work that did not originate on TTT Productions (including public-domain or out-of-copyright works), shown only to demonstrate my abilities. The underlying work belongs to its owner, and I claim no ownership of it. I understand TTT Productions may remove this content at any time, including in response to a rights-holder request.',\n};\n\nexport const CRAFT_SKILL_KIND_ORDER: CraftSkillKind[] = ['original', 'mimicOnTtt', 'mimicOffTtt'];\n\n/**\n * Why \"Mimicked work from outside TTT Productions\" cannot be chosen yet: the picker shows it\n * when a person selects that kind, and the upload callable refuses the kind with the same words.\n */\nexport const CRAFT_SKILL_MIMIC_OFF_TTT_UNAVAILABLE_MESSAGE =\n \"This option isn't available yet: sharing covers or recreations of work from outside TTT needs legal review first.\";\n\n/**\n * The ONE owner of which craft kinds are blocked at launch, with each one's refusal copy. A\n * blocked kind still renders in the picker (so people see it is coming) but selecting it stops\n * the flow with this copy, and the upload callable refuses it with the same words. Unblocking a\n * kind is removing its entry here.\n */\nexport const CRAFT_SKILL_KIND_UNAVAILABLE_MESSAGES = {\n mimicOffTtt: CRAFT_SKILL_MIMIC_OFF_TTT_UNAVAILABLE_MESSAGE,\n} as const satisfies Partial<Record<CraftSkillKind, string>>;\n\n/** A craft kind that is blocked at launch. */\nexport type BlockedCraftSkillKind = keyof typeof CRAFT_SKILL_KIND_UNAVAILABLE_MESSAGES;\n\n/** Every craft kind blocked at launch — derived from the refusal copy, never restated. */\nexport const BLOCKED_CRAFT_SKILL_KINDS = Object.keys(\n CRAFT_SKILL_KIND_UNAVAILABLE_MESSAGES,\n) as readonly BlockedCraftSkillKind[];\n\n/** True when `kind` is blocked at launch; narrows it to index its refusal copy. */\nexport function isBlockedCraftSkillKind(kind: CraftSkillKind): kind is BlockedCraftSkillKind {\n return Object.prototype.hasOwnProperty.call(CRAFT_SKILL_KIND_UNAVAILABLE_MESSAGES, kind);\n}\n"]}
@@ -54,6 +54,9 @@ export declare const LEGAL_REVIEW_NOTICE_PLACEMENTS: {
54
54
  readonly artisanCreatorUpgrade: readonly ["inline", "strip"];
55
55
  /** Craft-skill upload, beside its agreement. */
56
56
  readonly craftSkillUpload: readonly ["inline", "strip"];
57
+ /** An Artisan submitting an Audition entry — a compact strip beside Submit Entry (the launch
58
+ * mascot Auditions hand their winning art to TTT). */
59
+ readonly auditionEntrySubmission: readonly ["strip"];
57
60
  /** Square first post, beside its agreement. */
58
61
  readonly squareStreetzFirstPost: readonly ["inline", "strip"];
59
62
  /** Guild invite agreements. */
@@ -1 +1 @@
1
- {"version":3,"file":"legal-review-notice.d.ts","sourceRoot":"","sources":["../../src/constants/legal-review-notice.ts"],"names":[],"mappings":"AAkBA,OAAO,EAA0B,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEtF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AAItF,iFAAiF;AACjF,MAAM,MAAM,2BAA2B,GAAG,gBAAgB,GAAG,aAAa,CAAC;AAE3E,6EAA6E;AAC7E,MAAM,MAAM,wBAAwB,GAChC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,2BAA2B,CAAA;CAAE,CAAC;AAIpG,2DAA2D;AAC3D,eAAO,MAAM,2BAA2B,mCAAmC,CAAC;AAE5E,4BAA4B;AAC5B,eAAO,MAAM,wBAAwB,QAMuC,CAAC;AAE7E,mEAAmE;AACnE,eAAO,MAAM,8BAA8B,EAAE,SAAS,wBAAwB,EAG7E,CAAC;AAEF,sEAAsE;AACtE,eAAO,MAAM,4BAA4B,QAE2B,CAAC;AAqBrE,wGAAwG;AACxG,wBAAgB,kCAAkC,IAAI,SAAS,wBAAwB,EAAE,CAIxF;AAID;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,kDAAmD,CAAC;AAC7F,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,4BAA4B,CAAC,CAAC,MAAM,CAAC,CAAC;AAIrF;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B;IACzC;6FACyF;;IAEzF,mEAAmE;;IAEnE,wEAAwE;;IAExE,iGAAiG;;IAEjG,oGAAoG;;IAEpG,mDAAmD;;IAEnD,6CAA6C;;IAE7C,gDAAgD;;IAEhD,+CAA+C;;IAE/C,+BAA+B;;IAE/B,gDAAgD;;IAEhD,oCAAoC;;IAEpC,0CAA0C;;IAE1C,8CAA8C;;IAE9C,0BAA0B;;IAE1B,4BAA4B;;IAE5B,uBAAuB;;CAEwC,CAAC;AAElE,uCAAuC;AACvC,MAAM,MAAM,wBAAwB,GAAG,MAAM,OAAO,8BAA8B,CAAC;AAEnF,iDAAiD;AACjD,MAAM,MAAM,2BAA2B,CAAC,CAAC,SAAS,wBAAwB,IACxE,CAAC,OAAO,8BAA8B,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD,eAAO,MAAM,4BAA4B,EAEpC,wBAAwB,EAAE,CAAC;AAYhC;;;GAGG;AACH,wBAAgB,sCAAsC,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAE5F;AAID,4EAA4E;AAC5E,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,SAAS,wBAAwB,EAAE,GAAG,MAAM,CAEnG;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,wBAAwB,EAC3E,OAAO,EAAE,CAAC,EACV,OAAO,CAAC,EAAE,2BAA2B,CAAC,CAAC,CAAC,GACvC,MAAM,GAAG,IAAI,CAgBf;AAID,gGAAgG;AAChG,wBAAgB,+BAA+B,IAAI,MAAM,GAAG,IAAI,CAE/D;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,cAAc,EAAE,MAAM,GAAG,wBAAwB,GAAG,IAAI,CAGrG"}
1
+ {"version":3,"file":"legal-review-notice.d.ts","sourceRoot":"","sources":["../../src/constants/legal-review-notice.ts"],"names":[],"mappings":"AAkBA,OAAO,EAA0B,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEtF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AAItF,iFAAiF;AACjF,MAAM,MAAM,2BAA2B,GAAG,gBAAgB,GAAG,aAAa,CAAC;AAE3E,6EAA6E;AAC7E,MAAM,MAAM,wBAAwB,GAChC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,2BAA2B,CAAA;CAAE,CAAC;AAIpG,2DAA2D;AAC3D,eAAO,MAAM,2BAA2B,mCAAmC,CAAC;AAE5E,4BAA4B;AAC5B,eAAO,MAAM,wBAAwB,QAMuC,CAAC;AAE7E,mEAAmE;AACnE,eAAO,MAAM,8BAA8B,EAAE,SAAS,wBAAwB,EAG7E,CAAC;AAEF,sEAAsE;AACtE,eAAO,MAAM,4BAA4B,QAE2B,CAAC;AAqBrE,wGAAwG;AACxG,wBAAgB,kCAAkC,IAAI,SAAS,wBAAwB,EAAE,CAIxF;AAID;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,kDAAmD,CAAC;AAC7F,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,4BAA4B,CAAC,CAAC,MAAM,CAAC,CAAC;AAIrF;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B;IACzC;6FACyF;;IAEzF,mEAAmE;;IAEnE,wEAAwE;;IAExE,iGAAiG;;IAEjG,oGAAoG;;IAEpG,mDAAmD;;IAEnD,6CAA6C;;IAE7C,gDAAgD;;IAEhD;2DACuD;;IAEvD,+CAA+C;;IAE/C,+BAA+B;;IAE/B,gDAAgD;;IAEhD,oCAAoC;;IAEpC,0CAA0C;;IAE1C,8CAA8C;;IAE9C,0BAA0B;;IAE1B,4BAA4B;;IAE5B,uBAAuB;;CAEwC,CAAC;AAElE,uCAAuC;AACvC,MAAM,MAAM,wBAAwB,GAAG,MAAM,OAAO,8BAA8B,CAAC;AAEnF,iDAAiD;AACjD,MAAM,MAAM,2BAA2B,CAAC,CAAC,SAAS,wBAAwB,IACxE,CAAC,OAAO,8BAA8B,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD,eAAO,MAAM,4BAA4B,EAEpC,wBAAwB,EAAE,CAAC;AAYhC;;;GAGG;AACH,wBAAgB,sCAAsC,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAE5F;AAID,4EAA4E;AAC5E,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,SAAS,wBAAwB,EAAE,GAAG,MAAM,CAEnG;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,wBAAwB,EAC3E,OAAO,EAAE,CAAC,EACV,OAAO,CAAC,EAAE,2BAA2B,CAAC,CAAC,CAAC,GACvC,MAAM,GAAG,IAAI,CAgBf;AAID,gGAAgG;AAChG,wBAAgB,+BAA+B,IAAI,MAAM,GAAG,IAAI,CAE/D;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,cAAc,EAAE,MAAM,GAAG,wBAAwB,GAAG,IAAI,CAGrG"}
@@ -90,6 +90,9 @@ export const LEGAL_REVIEW_NOTICE_PLACEMENTS = {
90
90
  artisanCreatorUpgrade: ['inline', 'strip'],
91
91
  /** Craft-skill upload, beside its agreement. */
92
92
  craftSkillUpload: ['inline', 'strip'],
93
+ /** An Artisan submitting an Audition entry — a compact strip beside Submit Entry (the launch
94
+ * mascot Auditions hand their winning art to TTT). */
95
+ auditionEntrySubmission: ['strip'],
93
96
  /** Square first post, beside its agreement. */
94
97
  squareStreetzFirstPost: ['inline', 'strip'],
95
98
  /** Guild invite agreements. */
@@ -1 +1 @@
1
- {"version":3,"file":"legal-review-notice.js","sourceRoot":"","sources":["../../src/constants/legal-review-notice.ts"],"names":[],"mappings":"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","sourcesContent":["// ============================================================================\n// FOUNDER LEGAL-REVIEW NOTICE — the ONE owner of the notice copy, its placements,\n// and the plain-text helper for backend-owned copy. The on/off switch and the\n// immutable revision id live in ./legal-review-notice-state.ts.\n//\n// TTT's public pages were written by the founder before any legal review. The\n// notice says so wherever people read policy, create accounts, upload, publish,\n// or pledge. The app renders it through one component,\n// `<LegalReviewNotice context=… variant=… />`; nothing restates these words or\n// keeps a local flag.\n//\n// Copy is settled and verbatim — never reword it in place. A wording change is a\n// new LEGAL_REVIEW_NOTICE_REVISION (the package test pins each revision's copy).\n// Links are semantic targets, not URLs: a public document id, or the founder's\n// note itself; the app maps them to routes or its note dialog.\n// ============================================================================\n\nimport { SPECIAL_DOCS } from '../paths/collections.js';\nimport { PUBLIC_DOCUMENT_LABELS, type PublicDocumentId } from './public-documents.js';\nimport { LEGAL_REVIEW_NOTICE_ACTIVE, LEGAL_REVIEW_NOTICE_REVISION } from './legal-review-notice-state.js';\nimport type { LegalReviewNoticeReceipt } from '../doc-schemas/legal-review-notice.js';\n\n// ── Copy model ───────────────────────────────────────────────────────────────\n\n/** Where a notice link points: a public document, or the founder's full note. */\nexport type LegalReviewNoticeLinkTarget = PublicDocumentId | 'founderNote';\n\n/** One run of notice copy. A link carries a semantic target, never a URL. */\nexport type LegalReviewNoticeSegment =\n | { readonly kind: 'text'; readonly text: string }\n | { readonly kind: 'link'; readonly label: string; readonly target: LegalReviewNoticeLinkTarget };\n\n// ── The settled copy ─────────────────────────────────────────────────────────\n\n/** The full note's heading (the note's first sentence). */\nexport const LEGAL_REVIEW_NOTICE_HEADING = \"A note from DJ, TTT's founder.\";\n\n/** The full note's body. */\nexport const LEGAL_REVIEW_NOTICE_BODY =\n \"These pages describe how I intend TTT to work: my principles and what I'm trying to build. \" +\n 'I wrote them myself, with help from AI tools, before I could afford a lawyer, so none of it ' +\n \"has had legal review, and I honestly don't know whether all of it is legally sound. Charter \" +\n \"Season support keeps TTT running first; after that, it's how I'll get a lawyer to turn this \" +\n 'into real, reviewed legal wording. The words may change when that happens. My intentions ' +\n \"won't. If a change needs your agreement, I'll ask you before it applies.\";\n\n/** The short line. Its closing sentence links to the full note. */\nexport const LEGAL_REVIEW_NOTICE_SHORT_LINE: readonly LegalReviewNoticeSegment[] = [\n { kind: 'text', text: \"TTT's terms are my intentions, written by me and not yet reviewed by a lawyer. \" },\n { kind: 'link', label: \"Read the founder's note.\", target: 'founderNote' },\n];\n\n/** The required acknowledgment checkbox (Hall submission, pledge). */\nexport const LEGAL_REVIEW_NOTICE_CHECKBOX =\n \"I understand TTT's terms express the founder's intentions, have not had legal review, and \" +\n 'will be updated once Charter Season support makes that possible.';\n\n// The registration Terms checkbox. While the notice is active it carries the notice clause;\n// otherwise it is the plain agreement. Both link the two documents by their canonical labels.\nconst REGISTRATION_TERMS_AGREEMENT_LEAD: readonly LegalReviewNoticeSegment[] = [\n { kind: 'text', text: 'I have read and agree to the ' },\n { kind: 'link', label: PUBLIC_DOCUMENT_LABELS[SPECIAL_DOCS.TERMS_PAGE], target: SPECIAL_DOCS.TERMS_PAGE },\n { kind: 'text', text: ' and ' },\n { kind: 'link', label: PUBLIC_DOCUMENT_LABELS[SPECIAL_DOCS.PRIVACY_PAGE], target: SPECIAL_DOCS.PRIVACY_PAGE },\n];\n\nconst REGISTRATION_TERMS_AGREEMENT_WITH_NOTICE: readonly LegalReviewNoticeSegment[] = [\n ...REGISTRATION_TERMS_AGREEMENT_LEAD,\n { kind: 'text', text: \", and I understand they express the founder's intentions and have not had legal review.\" },\n];\n\nconst REGISTRATION_TERMS_AGREEMENT_WITHOUT_NOTICE: readonly LegalReviewNoticeSegment[] = [\n ...REGISTRATION_TERMS_AGREEMENT_LEAD,\n { kind: 'text', text: '.' },\n];\n\n/** The registration Terms checkbox label, with the notice clause exactly while the notice is active. */\nexport function registrationTermsAgreementSegments(): readonly LegalReviewNoticeSegment[] {\n return LEGAL_REVIEW_NOTICE_ACTIVE\n ? REGISTRATION_TERMS_AGREEMENT_WITH_NOTICE\n : REGISTRATION_TERMS_AGREEMENT_WITHOUT_NOTICE;\n}\n\n// ── Variants and placements ──────────────────────────────────────────────────\n\n/**\n * How the notice renders:\n * - `inline` — the short line, in the flow of surrounding text;\n * - `strip` — the short line as a compact strip;\n * - `card` — the full note (heading + body);\n * - `checkbox` — the required acknowledgment checkbox.\n */\nexport const LEGAL_REVIEW_NOTICE_VARIANTS = ['inline', 'strip', 'card', 'checkbox'] as const;\nexport type LegalReviewNoticeVariant = (typeof LEGAL_REVIEW_NOTICE_VARIANTS)[number];\n\ntype LegalReviewNoticeVariantList = readonly [LegalReviewNoticeVariant, ...LegalReviewNoticeVariant[]];\n\n/**\n * Every placement of the notice and the variants it may render (the first is its default).\n * The keys ARE the typed context union. Take It Down and the DMCA policy are statutory\n * processes and carry no notice, so they have no context\n * (see `publicDocumentCarriesLegalReviewNotice`).\n */\nexport const LEGAL_REVIEW_NOTICE_PLACEMENTS = {\n /** Terms, Privacy, Rules & Agreements, Future Plans — beside the current content, rendered at\n * display time (never stored in the document body); also the Admin editors' preview. */\n publicDocument: ['strip'],\n /** Registration — the full note above the agreement checkboxes. */\n registration: ['card'],\n /** The \"Our stuff has changed\" re-acceptance prompt — the full note. */\n reacceptance: ['card'],\n /** Pledge checkout — a compact explanation plus a separate required checkbox on every pledge. */\n pledge: ['strip', 'checkbox'],\n /** Hall submission — a required checkbox in the publish attestations, above Submit for Approval. */\n publish: ['checkbox'],\n /** Work / Realm creation, beside its agreement. */\n workProjectCreation: ['inline', 'strip'],\n /** Artisan upgrade, beside its agreement. */\n artisanCreatorUpgrade: ['inline', 'strip'],\n /** Craft-skill upload, beside its agreement. */\n craftSkillUpload: ['inline', 'strip'],\n /** Square first post, beside its agreement. */\n squareStreetzFirstPost: ['inline', 'strip'],\n /** Guild invite agreements. */\n guildInviteAgreement: ['inline', 'strip'],\n /** Hall download, beside its acknowledgment. */\n hallDownload: ['inline', 'strip'],\n /** The Charter Season explainer. */\n charterExplainer: ['inline', 'card'],\n /** The landing page's founder section. */\n landingFounder: ['inline', 'card'],\n /** The landing page's fundraising section. */\n landingFundraising: ['inline', 'card'],\n /** Stake explanations. */\n stakeShareExplanation: ['inline', 'card'],\n /** Bouquet explanations. */\n bouquetAppreciationExplanation: ['inline', 'card'],\n /** The site footer. */\n footer: ['inline'],\n} as const satisfies Record<string, LegalReviewNoticeVariantList>;\n\n/** A named placement of the notice. */\nexport type LegalReviewNoticeContext = keyof typeof LEGAL_REVIEW_NOTICE_PLACEMENTS;\n\n/** The variants a given placement may render. */\nexport type LegalReviewNoticeVariantFor<C extends LegalReviewNoticeContext> =\n (typeof LEGAL_REVIEW_NOTICE_PLACEMENTS)[C][number];\n\nexport const LEGAL_REVIEW_NOTICE_CONTEXTS = Object.keys(\n LEGAL_REVIEW_NOTICE_PLACEMENTS,\n) as LegalReviewNoticeContext[];\n\nconst PUBLIC_DOCUMENT_CARRIES_NOTICE: Record<PublicDocumentId, boolean> = {\n [SPECIAL_DOCS.TERMS_PAGE]: true,\n [SPECIAL_DOCS.PRIVACY_PAGE]: true,\n [SPECIAL_DOCS.RULES_AND_AGREEMENTS]: true,\n [SPECIAL_DOCS.FUTURE_PLANS]: true,\n // Statutory processes run as built.\n [SPECIAL_DOCS.DMCA_POLICY]: false,\n [SPECIAL_DOCS.TAKE_IT_DOWN_PAGE_COPY]: false,\n};\n\n/**\n * Whether a public document's page (and its Admin editor preview) shows the `publicDocument`\n * notice strip. A placement fact only — the notice itself still renders nothing while off.\n */\nexport function publicDocumentCarriesLegalReviewNotice(documentId: PublicDocumentId): boolean {\n return PUBLIC_DOCUMENT_CARRIES_NOTICE[documentId];\n}\n\n// ── Plain text (backend-owned copy) ──────────────────────────────────────────\n\n/** Flatten segments to plain text: text as written, a link as its label. */\nexport function legalReviewNoticeSegmentsText(segments: readonly LegalReviewNoticeSegment[]): string {\n return segments.map((segment) => (segment.kind === 'text' ? segment.text : segment.label)).join('');\n}\n\n/**\n * The notice as plain text for a placement, for backend-owned copy (a Stripe description, an\n * email). `null` while the notice is off. `variant` defaults to the placement's first variant;\n * a variant the placement does not render throws.\n */\nexport function legalReviewNoticePlainText<C extends LegalReviewNoticeContext>(\n context: C,\n variant?: LegalReviewNoticeVariantFor<C>,\n): string | null {\n if (!LEGAL_REVIEW_NOTICE_ACTIVE) return null;\n const allowed: readonly LegalReviewNoticeVariant[] = LEGAL_REVIEW_NOTICE_PLACEMENTS[context];\n const chosen: LegalReviewNoticeVariant = variant ?? allowed[0];\n if (!allowed.includes(chosen)) {\n throw new Error(`The ${context} notice placement does not render the ${chosen} variant.`);\n }\n switch (chosen) {\n case 'inline':\n case 'strip':\n return legalReviewNoticeSegmentsText(LEGAL_REVIEW_NOTICE_SHORT_LINE);\n case 'card':\n return `${LEGAL_REVIEW_NOTICE_HEADING} ${LEGAL_REVIEW_NOTICE_BODY}`;\n case 'checkbox':\n return LEGAL_REVIEW_NOTICE_CHECKBOX;\n }\n}\n\n// ── What gets recorded ───────────────────────────────────────────────────────\n\n/** The revision a server records with an acceptance or acknowledgment now; `null` while off. */\nexport function activeLegalReviewNoticeRevision(): string | null {\n return LEGAL_REVIEW_NOTICE_ACTIVE ? LEGAL_REVIEW_NOTICE_REVISION : null;\n}\n\n/**\n * The receipt a server records when a person acknowledges the notice (pledge evidence, the Hall\n * threshold item): the active revision and the server time. `null` while the notice is off —\n * nothing is required, so nothing is recorded.\n */\nexport function buildLegalReviewNoticeReceipt(acknowledgedAt: number): LegalReviewNoticeReceipt | null {\n const revision = activeLegalReviewNoticeRevision();\n return revision === null ? null : { revision, acknowledgedAt };\n}\n"]}
1
+ {"version":3,"file":"legal-review-notice.js","sourceRoot":"","sources":["../../src/constants/legal-review-notice.ts"],"names":[],"mappings":"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","sourcesContent":["// ============================================================================\n// FOUNDER LEGAL-REVIEW NOTICE — the ONE owner of the notice copy, its placements,\n// and the plain-text helper for backend-owned copy. The on/off switch and the\n// immutable revision id live in ./legal-review-notice-state.ts.\n//\n// TTT's public pages were written by the founder before any legal review. The\n// notice says so wherever people read policy, create accounts, upload, publish,\n// or pledge. The app renders it through one component,\n// `<LegalReviewNotice context=… variant=… />`; nothing restates these words or\n// keeps a local flag.\n//\n// Copy is settled and verbatim — never reword it in place. A wording change is a\n// new LEGAL_REVIEW_NOTICE_REVISION (the package test pins each revision's copy).\n// Links are semantic targets, not URLs: a public document id, or the founder's\n// note itself; the app maps them to routes or its note dialog.\n// ============================================================================\n\nimport { SPECIAL_DOCS } from '../paths/collections.js';\nimport { PUBLIC_DOCUMENT_LABELS, type PublicDocumentId } from './public-documents.js';\nimport { LEGAL_REVIEW_NOTICE_ACTIVE, LEGAL_REVIEW_NOTICE_REVISION } from './legal-review-notice-state.js';\nimport type { LegalReviewNoticeReceipt } from '../doc-schemas/legal-review-notice.js';\n\n// ── Copy model ───────────────────────────────────────────────────────────────\n\n/** Where a notice link points: a public document, or the founder's full note. */\nexport type LegalReviewNoticeLinkTarget = PublicDocumentId | 'founderNote';\n\n/** One run of notice copy. A link carries a semantic target, never a URL. */\nexport type LegalReviewNoticeSegment =\n | { readonly kind: 'text'; readonly text: string }\n | { readonly kind: 'link'; readonly label: string; readonly target: LegalReviewNoticeLinkTarget };\n\n// ── The settled copy ─────────────────────────────────────────────────────────\n\n/** The full note's heading (the note's first sentence). */\nexport const LEGAL_REVIEW_NOTICE_HEADING = \"A note from DJ, TTT's founder.\";\n\n/** The full note's body. */\nexport const LEGAL_REVIEW_NOTICE_BODY =\n \"These pages describe how I intend TTT to work: my principles and what I'm trying to build. \" +\n 'I wrote them myself, with help from AI tools, before I could afford a lawyer, so none of it ' +\n \"has had legal review, and I honestly don't know whether all of it is legally sound. Charter \" +\n \"Season support keeps TTT running first; after that, it's how I'll get a lawyer to turn this \" +\n 'into real, reviewed legal wording. The words may change when that happens. My intentions ' +\n \"won't. If a change needs your agreement, I'll ask you before it applies.\";\n\n/** The short line. Its closing sentence links to the full note. */\nexport const LEGAL_REVIEW_NOTICE_SHORT_LINE: readonly LegalReviewNoticeSegment[] = [\n { kind: 'text', text: \"TTT's terms are my intentions, written by me and not yet reviewed by a lawyer. \" },\n { kind: 'link', label: \"Read the founder's note.\", target: 'founderNote' },\n];\n\n/** The required acknowledgment checkbox (Hall submission, pledge). */\nexport const LEGAL_REVIEW_NOTICE_CHECKBOX =\n \"I understand TTT's terms express the founder's intentions, have not had legal review, and \" +\n 'will be updated once Charter Season support makes that possible.';\n\n// The registration Terms checkbox. While the notice is active it carries the notice clause;\n// otherwise it is the plain agreement. Both link the two documents by their canonical labels.\nconst REGISTRATION_TERMS_AGREEMENT_LEAD: readonly LegalReviewNoticeSegment[] = [\n { kind: 'text', text: 'I have read and agree to the ' },\n { kind: 'link', label: PUBLIC_DOCUMENT_LABELS[SPECIAL_DOCS.TERMS_PAGE], target: SPECIAL_DOCS.TERMS_PAGE },\n { kind: 'text', text: ' and ' },\n { kind: 'link', label: PUBLIC_DOCUMENT_LABELS[SPECIAL_DOCS.PRIVACY_PAGE], target: SPECIAL_DOCS.PRIVACY_PAGE },\n];\n\nconst REGISTRATION_TERMS_AGREEMENT_WITH_NOTICE: readonly LegalReviewNoticeSegment[] = [\n ...REGISTRATION_TERMS_AGREEMENT_LEAD,\n { kind: 'text', text: \", and I understand they express the founder's intentions and have not had legal review.\" },\n];\n\nconst REGISTRATION_TERMS_AGREEMENT_WITHOUT_NOTICE: readonly LegalReviewNoticeSegment[] = [\n ...REGISTRATION_TERMS_AGREEMENT_LEAD,\n { kind: 'text', text: '.' },\n];\n\n/** The registration Terms checkbox label, with the notice clause exactly while the notice is active. */\nexport function registrationTermsAgreementSegments(): readonly LegalReviewNoticeSegment[] {\n return LEGAL_REVIEW_NOTICE_ACTIVE\n ? REGISTRATION_TERMS_AGREEMENT_WITH_NOTICE\n : REGISTRATION_TERMS_AGREEMENT_WITHOUT_NOTICE;\n}\n\n// ── Variants and placements ──────────────────────────────────────────────────\n\n/**\n * How the notice renders:\n * - `inline` — the short line, in the flow of surrounding text;\n * - `strip` — the short line as a compact strip;\n * - `card` — the full note (heading + body);\n * - `checkbox` — the required acknowledgment checkbox.\n */\nexport const LEGAL_REVIEW_NOTICE_VARIANTS = ['inline', 'strip', 'card', 'checkbox'] as const;\nexport type LegalReviewNoticeVariant = (typeof LEGAL_REVIEW_NOTICE_VARIANTS)[number];\n\ntype LegalReviewNoticeVariantList = readonly [LegalReviewNoticeVariant, ...LegalReviewNoticeVariant[]];\n\n/**\n * Every placement of the notice and the variants it may render (the first is its default).\n * The keys ARE the typed context union. Take It Down and the DMCA policy are statutory\n * processes and carry no notice, so they have no context\n * (see `publicDocumentCarriesLegalReviewNotice`).\n */\nexport const LEGAL_REVIEW_NOTICE_PLACEMENTS = {\n /** Terms, Privacy, Rules & Agreements, Future Plans — beside the current content, rendered at\n * display time (never stored in the document body); also the Admin editors' preview. */\n publicDocument: ['strip'],\n /** Registration — the full note above the agreement checkboxes. */\n registration: ['card'],\n /** The \"Our stuff has changed\" re-acceptance prompt — the full note. */\n reacceptance: ['card'],\n /** Pledge checkout — a compact explanation plus a separate required checkbox on every pledge. */\n pledge: ['strip', 'checkbox'],\n /** Hall submission — a required checkbox in the publish attestations, above Submit for Approval. */\n publish: ['checkbox'],\n /** Work / Realm creation, beside its agreement. */\n workProjectCreation: ['inline', 'strip'],\n /** Artisan upgrade, beside its agreement. */\n artisanCreatorUpgrade: ['inline', 'strip'],\n /** Craft-skill upload, beside its agreement. */\n craftSkillUpload: ['inline', 'strip'],\n /** An Artisan submitting an Audition entry — a compact strip beside Submit Entry (the launch\n * mascot Auditions hand their winning art to TTT). */\n auditionEntrySubmission: ['strip'],\n /** Square first post, beside its agreement. */\n squareStreetzFirstPost: ['inline', 'strip'],\n /** Guild invite agreements. */\n guildInviteAgreement: ['inline', 'strip'],\n /** Hall download, beside its acknowledgment. */\n hallDownload: ['inline', 'strip'],\n /** The Charter Season explainer. */\n charterExplainer: ['inline', 'card'],\n /** The landing page's founder section. */\n landingFounder: ['inline', 'card'],\n /** The landing page's fundraising section. */\n landingFundraising: ['inline', 'card'],\n /** Stake explanations. */\n stakeShareExplanation: ['inline', 'card'],\n /** Bouquet explanations. */\n bouquetAppreciationExplanation: ['inline', 'card'],\n /** The site footer. */\n footer: ['inline'],\n} as const satisfies Record<string, LegalReviewNoticeVariantList>;\n\n/** A named placement of the notice. */\nexport type LegalReviewNoticeContext = keyof typeof LEGAL_REVIEW_NOTICE_PLACEMENTS;\n\n/** The variants a given placement may render. */\nexport type LegalReviewNoticeVariantFor<C extends LegalReviewNoticeContext> =\n (typeof LEGAL_REVIEW_NOTICE_PLACEMENTS)[C][number];\n\nexport const LEGAL_REVIEW_NOTICE_CONTEXTS = Object.keys(\n LEGAL_REVIEW_NOTICE_PLACEMENTS,\n) as LegalReviewNoticeContext[];\n\nconst PUBLIC_DOCUMENT_CARRIES_NOTICE: Record<PublicDocumentId, boolean> = {\n [SPECIAL_DOCS.TERMS_PAGE]: true,\n [SPECIAL_DOCS.PRIVACY_PAGE]: true,\n [SPECIAL_DOCS.RULES_AND_AGREEMENTS]: true,\n [SPECIAL_DOCS.FUTURE_PLANS]: true,\n // Statutory processes run as built.\n [SPECIAL_DOCS.DMCA_POLICY]: false,\n [SPECIAL_DOCS.TAKE_IT_DOWN_PAGE_COPY]: false,\n};\n\n/**\n * Whether a public document's page (and its Admin editor preview) shows the `publicDocument`\n * notice strip. A placement fact only — the notice itself still renders nothing while off.\n */\nexport function publicDocumentCarriesLegalReviewNotice(documentId: PublicDocumentId): boolean {\n return PUBLIC_DOCUMENT_CARRIES_NOTICE[documentId];\n}\n\n// ── Plain text (backend-owned copy) ──────────────────────────────────────────\n\n/** Flatten segments to plain text: text as written, a link as its label. */\nexport function legalReviewNoticeSegmentsText(segments: readonly LegalReviewNoticeSegment[]): string {\n return segments.map((segment) => (segment.kind === 'text' ? segment.text : segment.label)).join('');\n}\n\n/**\n * The notice as plain text for a placement, for backend-owned copy (a Stripe description, an\n * email). `null` while the notice is off. `variant` defaults to the placement's first variant;\n * a variant the placement does not render throws.\n */\nexport function legalReviewNoticePlainText<C extends LegalReviewNoticeContext>(\n context: C,\n variant?: LegalReviewNoticeVariantFor<C>,\n): string | null {\n if (!LEGAL_REVIEW_NOTICE_ACTIVE) return null;\n const allowed: readonly LegalReviewNoticeVariant[] = LEGAL_REVIEW_NOTICE_PLACEMENTS[context];\n const chosen: LegalReviewNoticeVariant = variant ?? allowed[0];\n if (!allowed.includes(chosen)) {\n throw new Error(`The ${context} notice placement does not render the ${chosen} variant.`);\n }\n switch (chosen) {\n case 'inline':\n case 'strip':\n return legalReviewNoticeSegmentsText(LEGAL_REVIEW_NOTICE_SHORT_LINE);\n case 'card':\n return `${LEGAL_REVIEW_NOTICE_HEADING} ${LEGAL_REVIEW_NOTICE_BODY}`;\n case 'checkbox':\n return LEGAL_REVIEW_NOTICE_CHECKBOX;\n }\n}\n\n// ── What gets recorded ───────────────────────────────────────────────────────\n\n/** The revision a server records with an acceptance or acknowledgment now; `null` while off. */\nexport function activeLegalReviewNoticeRevision(): string | null {\n return LEGAL_REVIEW_NOTICE_ACTIVE ? LEGAL_REVIEW_NOTICE_REVISION : null;\n}\n\n/**\n * The receipt a server records when a person acknowledges the notice (pledge evidence, the Hall\n * threshold item): the active revision and the server time. `null` while the notice is off —\n * nothing is required, so nothing is recorded.\n */\nexport function buildLegalReviewNoticeReceipt(acknowledgedAt: number): LegalReviewNoticeReceipt | null {\n const revision = activeLegalReviewNoticeRevision();\n return revision === null ? null : { revision, acknowledgedAt };\n}\n"]}
@@ -15,6 +15,13 @@ export declare const PUBLIC_DOCUMENTS_ACCEPTED_CLAIM = "docsAccepted";
15
15
  */
16
16
  export declare const PUBLIC_DOCUMENT_ACCEPTANCE_SOURCES: readonly ["registration", "reacceptance"];
17
17
  export type PublicDocumentAcceptanceSource = (typeof PUBLIC_DOCUMENT_ACCEPTANCE_SOURCES)[number];
18
+ /**
19
+ * The re-acceptance prompt's explicit agreement line, shown above its Accept and Log out
20
+ * choices. Verbatim and independent of the founder notice: it shows whether or not the notice
21
+ * is active. What a person accepted is recorded as the document/version pairs the prompt
22
+ * listed, so this line carries no revision of its own.
23
+ */
24
+ export declare const PUBLIC_DOCUMENTS_REACCEPTANCE_STATEMENT = "By choosing Accept, you agree to the current versions of the documents listed above.";
18
25
  /** Versions returned per page by the Admin history read (newest first). */
19
26
  export declare const PUBLIC_DOCUMENT_HISTORY_PAGE_LIMIT = 10;
20
27
  //# sourceMappingURL=public-documents.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public-documents.d.ts","sourceRoot":"","sources":["../../src/constants/public-documents.ts"],"names":[],"mappings":"AAkBA,yDAAyD;AACzD,eAAO,MAAM,mBAAmB,uHAOtB,CAAC;AACX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,2FAA2F;AAC3F,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAOnE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,iBAAiB,CAAC;AAE9D;;;GAGG;AACH,eAAO,MAAM,kCAAkC,2CAA4C,CAAC;AAC5F,MAAM,MAAM,8BAA8B,GAAG,CAAC,OAAO,kCAAkC,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjG,2EAA2E;AAC3E,eAAO,MAAM,kCAAkC,KAAK,CAAC"}
1
+ {"version":3,"file":"public-documents.d.ts","sourceRoot":"","sources":["../../src/constants/public-documents.ts"],"names":[],"mappings":"AAkBA,yDAAyD;AACzD,eAAO,MAAM,mBAAmB,uHAOtB,CAAC;AACX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,2FAA2F;AAC3F,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAOnE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,iBAAiB,CAAC;AAE9D;;;GAGG;AACH,eAAO,MAAM,kCAAkC,2CAA4C,CAAC;AAC5F,MAAM,MAAM,8BAA8B,GAAG,CAAC,OAAO,kCAAkC,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjG;;;;;GAKG;AACH,eAAO,MAAM,uCAAuC,yFACoC,CAAC;AAEzF,2EAA2E;AAC3E,eAAO,MAAM,kCAAkC,KAAK,CAAC"}
@@ -43,6 +43,13 @@ export const PUBLIC_DOCUMENTS_ACCEPTED_CLAIM = 'docsAccepted';
43
43
  * Both write the same private summary and the same `publicDocuments.accepted` audit event.
44
44
  */
45
45
  export const PUBLIC_DOCUMENT_ACCEPTANCE_SOURCES = ['registration', 'reacceptance'];
46
+ /**
47
+ * The re-acceptance prompt's explicit agreement line, shown above its Accept and Log out
48
+ * choices. Verbatim and independent of the founder notice: it shows whether or not the notice
49
+ * is active. What a person accepted is recorded as the document/version pairs the prompt
50
+ * listed, so this line carries no revision of its own.
51
+ */
52
+ export const PUBLIC_DOCUMENTS_REACCEPTANCE_STATEMENT = 'By choosing Accept, you agree to the current versions of the documents listed above.';
46
53
  /** Versions returned per page by the Admin history read (newest first). */
47
54
  export const PUBLIC_DOCUMENT_HISTORY_PAGE_LIMIT = 10;
48
55
  //# sourceMappingURL=public-documents.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"public-documents.js","sourceRoot":"","sources":["../../src/constants/public-documents.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,gFAAgF;AAChF,0EAA0E;AAC1E,8EAA8E;AAC9E,iFAAiF;AACjF,kCAAkC;AAClC,EAAE;AACF,6EAA6E;AAC7E,iFAAiF;AACjF,2DAA2D;AAC3D,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,iEAAiE;AACjE,+EAA+E;AAE/E,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,yDAAyD;AACzD,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,YAAY,CAAC,UAAU;IACvB,YAAY,CAAC,YAAY;IACzB,YAAY,CAAC,oBAAoB;IACjC,YAAY,CAAC,YAAY;IACzB,YAAY,CAAC,WAAW;IACxB,YAAY,CAAC,sBAAsB;CAC3B,CAAC;AAGX,2FAA2F;AAC3F,MAAM,CAAC,MAAM,sBAAsB,GAAqC;IACtE,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,kBAAkB;IAC7C,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,gBAAgB;IAC7C,CAAC,YAAY,CAAC,oBAAoB,CAAC,EAAE,oBAAoB;IACzD,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,cAAc;IAC3C,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,aAAa;IACzC,CAAC,YAAY,CAAC,sBAAsB,CAAC,EAAE,cAAc;CACtD,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,cAAc,CAAC;AAE9D;;;GAGG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC,cAAc,EAAE,cAAc,CAAU,CAAC;AAG5F,2EAA2E;AAC3E,MAAM,CAAC,MAAM,kCAAkC,GAAG,EAAE,CAAC","sourcesContent":["// ============================================================================\n// PUBLIC DOCUMENTS — the Admin-editable public web pages that are versioned and\n// published in release bundles: Terms of Service, Privacy Policy, Rules &\n// Agreements, Future Plans, the DMCA policy, and the Take It Down explanatory\n// copy. ONE owner for the document identity, display labels, and the numbers the\n// release / acceptance flow uses.\n//\n// Each PublicDocumentId is ALSO the doc id of that document's public current\n// projection under `_appConfig` (PATH_BUILDERS.publicDocumentProjection), so the\n// ids derive from SPECIAL_DOCS rather than being restated.\n//\n// Versions are whole numbers v1, v2, … per document. \"Require acceptance\" is a\n// property of a RELEASE, never a second version number: a release that requires\n// acceptance raises the single required-acceptance level by one.\n// ============================================================================\n\nimport { SPECIAL_DOCS } from '../paths/collections.js';\n\n/** Every public document, in canonical display order. */\nexport const PUBLIC_DOCUMENT_IDS = [\n SPECIAL_DOCS.TERMS_PAGE,\n SPECIAL_DOCS.PRIVACY_PAGE,\n SPECIAL_DOCS.RULES_AND_AGREEMENTS,\n SPECIAL_DOCS.FUTURE_PLANS,\n SPECIAL_DOCS.DMCA_POLICY,\n SPECIAL_DOCS.TAKE_IT_DOWN_PAGE_COPY,\n] as const;\nexport type PublicDocumentId = (typeof PUBLIC_DOCUMENT_IDS)[number];\n\n/** The user-facing name of each public document (Admin list, acceptance prompt, links). */\nexport const PUBLIC_DOCUMENT_LABELS: Record<PublicDocumentId, string> = {\n [SPECIAL_DOCS.TERMS_PAGE]: 'Terms of Service',\n [SPECIAL_DOCS.PRIVACY_PAGE]: 'Privacy Policy',\n [SPECIAL_DOCS.RULES_AND_AGREEMENTS]: 'Rules & Agreements',\n [SPECIAL_DOCS.FUTURE_PLANS]: 'Future Plans',\n [SPECIAL_DOCS.DMCA_POLICY]: 'DMCA Policy',\n [SPECIAL_DOCS.TAKE_IT_DOWN_PAGE_COPY]: 'Take It Down',\n};\n\n/**\n * The custom claim holding the caller's accepted level. Written by the acceptance core\n * (through `updateClaim`) and read by the backend acceptance gate (auth-core's\n * `acceptance.claimKey`) — one name for both sides.\n */\nexport const PUBLIC_DOCUMENTS_ACCEPTED_CLAIM = 'docsAccepted';\n\n/**\n * How an acceptance was recorded: at registration, or through the re-acceptance prompt.\n * Both write the same private summary and the same `publicDocuments.accepted` audit event.\n */\nexport const PUBLIC_DOCUMENT_ACCEPTANCE_SOURCES = ['registration', 'reacceptance'] as const;\nexport type PublicDocumentAcceptanceSource = (typeof PUBLIC_DOCUMENT_ACCEPTANCE_SOURCES)[number];\n\n/** Versions returned per page by the Admin history read (newest first). */\nexport const PUBLIC_DOCUMENT_HISTORY_PAGE_LIMIT = 10;\n"]}
1
+ {"version":3,"file":"public-documents.js","sourceRoot":"","sources":["../../src/constants/public-documents.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,gFAAgF;AAChF,0EAA0E;AAC1E,8EAA8E;AAC9E,iFAAiF;AACjF,kCAAkC;AAClC,EAAE;AACF,6EAA6E;AAC7E,iFAAiF;AACjF,2DAA2D;AAC3D,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,iEAAiE;AACjE,+EAA+E;AAE/E,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,yDAAyD;AACzD,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,YAAY,CAAC,UAAU;IACvB,YAAY,CAAC,YAAY;IACzB,YAAY,CAAC,oBAAoB;IACjC,YAAY,CAAC,YAAY;IACzB,YAAY,CAAC,WAAW;IACxB,YAAY,CAAC,sBAAsB;CAC3B,CAAC;AAGX,2FAA2F;AAC3F,MAAM,CAAC,MAAM,sBAAsB,GAAqC;IACtE,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,kBAAkB;IAC7C,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,gBAAgB;IAC7C,CAAC,YAAY,CAAC,oBAAoB,CAAC,EAAE,oBAAoB;IACzD,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,cAAc;IAC3C,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,aAAa;IACzC,CAAC,YAAY,CAAC,sBAAsB,CAAC,EAAE,cAAc;CACtD,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,cAAc,CAAC;AAE9D;;;GAGG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC,cAAc,EAAE,cAAc,CAAU,CAAC;AAG5F;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uCAAuC,GAClD,sFAAsF,CAAC;AAEzF,2EAA2E;AAC3E,MAAM,CAAC,MAAM,kCAAkC,GAAG,EAAE,CAAC","sourcesContent":["// ============================================================================\n// PUBLIC DOCUMENTS — the Admin-editable public web pages that are versioned and\n// published in release bundles: Terms of Service, Privacy Policy, Rules &\n// Agreements, Future Plans, the DMCA policy, and the Take It Down explanatory\n// copy. ONE owner for the document identity, display labels, and the numbers the\n// release / acceptance flow uses.\n//\n// Each PublicDocumentId is ALSO the doc id of that document's public current\n// projection under `_appConfig` (PATH_BUILDERS.publicDocumentProjection), so the\n// ids derive from SPECIAL_DOCS rather than being restated.\n//\n// Versions are whole numbers v1, v2, … per document. \"Require acceptance\" is a\n// property of a RELEASE, never a second version number: a release that requires\n// acceptance raises the single required-acceptance level by one.\n// ============================================================================\n\nimport { SPECIAL_DOCS } from '../paths/collections.js';\n\n/** Every public document, in canonical display order. */\nexport const PUBLIC_DOCUMENT_IDS = [\n SPECIAL_DOCS.TERMS_PAGE,\n SPECIAL_DOCS.PRIVACY_PAGE,\n SPECIAL_DOCS.RULES_AND_AGREEMENTS,\n SPECIAL_DOCS.FUTURE_PLANS,\n SPECIAL_DOCS.DMCA_POLICY,\n SPECIAL_DOCS.TAKE_IT_DOWN_PAGE_COPY,\n] as const;\nexport type PublicDocumentId = (typeof PUBLIC_DOCUMENT_IDS)[number];\n\n/** The user-facing name of each public document (Admin list, acceptance prompt, links). */\nexport const PUBLIC_DOCUMENT_LABELS: Record<PublicDocumentId, string> = {\n [SPECIAL_DOCS.TERMS_PAGE]: 'Terms of Service',\n [SPECIAL_DOCS.PRIVACY_PAGE]: 'Privacy Policy',\n [SPECIAL_DOCS.RULES_AND_AGREEMENTS]: 'Rules & Agreements',\n [SPECIAL_DOCS.FUTURE_PLANS]: 'Future Plans',\n [SPECIAL_DOCS.DMCA_POLICY]: 'DMCA Policy',\n [SPECIAL_DOCS.TAKE_IT_DOWN_PAGE_COPY]: 'Take It Down',\n};\n\n/**\n * The custom claim holding the caller's accepted level. Written by the acceptance core\n * (through `updateClaim`) and read by the backend acceptance gate (auth-core's\n * `acceptance.claimKey`) — one name for both sides.\n */\nexport const PUBLIC_DOCUMENTS_ACCEPTED_CLAIM = 'docsAccepted';\n\n/**\n * How an acceptance was recorded: at registration, or through the re-acceptance prompt.\n * Both write the same private summary and the same `publicDocuments.accepted` audit event.\n */\nexport const PUBLIC_DOCUMENT_ACCEPTANCE_SOURCES = ['registration', 'reacceptance'] as const;\nexport type PublicDocumentAcceptanceSource = (typeof PUBLIC_DOCUMENT_ACCEPTANCE_SOURCES)[number];\n\n/**\n * The re-acceptance prompt's explicit agreement line, shown above its Accept and Log out\n * choices. Verbatim and independent of the founder notice: it shows whether or not the notice\n * is active. What a person accepted is recorded as the document/version pairs the prompt\n * listed, so this line carries no revision of its own.\n */\nexport const PUBLIC_DOCUMENTS_REACCEPTANCE_STATEMENT =\n 'By choosing Accept, you agree to the current versions of the documents listed above.';\n\n/** Versions returned per page by the Admin history read (newest first). */\nexport const PUBLIC_DOCUMENT_HISTORY_PAGE_LIMIT = 10;\n"]}
@@ -2,10 +2,7 @@ import { z } from 'zod';
2
2
  /** Blocked-hash retention policy — indefinite until an appeal reverses it. */
3
3
  export declare const NciiBlockedHashRetentionPolicySchema: z.ZodLiteral<"indefiniteUntilReversed">;
4
4
  export type NciiBlockedHashRetentionPolicy = z.infer<typeof NciiBlockedHashRetentionPolicySchema>;
5
- /** `_serverData/nciiPolicy` = `NciiPolicyConfigV1` — the DJ-approved launch defaults.
6
- * Counsel ratifies (`counselApproved`) at the pre-launch gate; uploads stay
7
- * blocked until then. Any value missing/placeholder → the launch audit FAILS
8
- * CLOSED. */
5
+ /** `_serverData/nciiPolicy` = `NciiPolicyConfigV1` — the operator launch defaults. */
9
6
  export declare const NciiPolicyConfigV1Schema: z.ZodObject<{
10
7
  policyVersion: z.ZodLiteral<"ncii.2026-06-23.v1">;
11
8
  requesterPiiRetentionDays: z.ZodNumber;
@@ -33,7 +30,6 @@ export declare const NciiPolicyConfigV1Schema: z.ZodObject<{
33
30
  evidenceScanMemoryBudgetMb: z.ZodNumber;
34
31
  rejectArchiveAndPolyglotPayloads: z.ZodBoolean;
35
32
  approvedBy: z.ZodLiteral<"operatorLaunchDefault">;
36
- counselApproved: z.ZodBoolean;
37
33
  }, z.core.$strict>;
38
34
  export type NciiPolicyConfigV1 = z.infer<typeof NciiPolicyConfigV1Schema>;
39
35
  /** The frozen launch default for `_serverData/nciiPolicy`. */
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/doc-schemas/ncii/config.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,8EAA8E;AAC9E,eAAO,MAAM,oCAAoC,yCAAuC,CAAC;AACzF,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oCAAoC,CAAC,CAAC;AAElG;;;aAGa;AACb,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAsC1B,CAAC;AACZ,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,8DAA8D;AAC9D,eAAO,MAAM,6BAA6B,EAAE,kBAiC3C,CAAC;AAYF;6CAC6C;AAC7C,eAAO,MAAM,oCAAoC,iCAA+B,CAAC;AACjF,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oCAAoC,CAAC,CAAC;AAElG;qCACqC;AACrC,eAAO,MAAM,uCAAuC;;;;;;;EAOlD,CAAC;AACH,MAAM,MAAM,iCAAiC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uCAAuC,CAAC,CAAC;AAExG;gFACgF;AAChF,eAAO,MAAM,yCAAyC;;;;;;;;;;;;;;;;kBAiB3C,CAAC;AACZ,MAAM,MAAM,mCAAmC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yCAAyC,CAAC,CAAC;AAE5G,8EAA8E;AAC9E,eAAO,MAAM,+CAA+C,EAAE,mCAgB7D,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/doc-schemas/ncii/config.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,8EAA8E;AAC9E,eAAO,MAAM,oCAAoC,yCAAuC,CAAC;AACzF,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oCAAoC,CAAC,CAAC;AAElG,sFAAsF;AACtF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAoC1B,CAAC;AACZ,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,8DAA8D;AAC9D,eAAO,MAAM,6BAA6B,EAAE,kBAgC3C,CAAC;AAYF;6CAC6C;AAC7C,eAAO,MAAM,oCAAoC,iCAA+B,CAAC;AACjF,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oCAAoC,CAAC,CAAC;AAElG;qCACqC;AACrC,eAAO,MAAM,uCAAuC;;;;;;;EAOlD,CAAC;AACH,MAAM,MAAM,iCAAiC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uCAAuC,CAAC,CAAC;AAExG;gFACgF;AAChF,eAAO,MAAM,yCAAyC;;;;;;;;;;;;;;;;kBAiB3C,CAAC;AACZ,MAAM,MAAM,mCAAmC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yCAAyC,CAAC,CAAC;AAE5G,8EAA8E;AAC9E,eAAO,MAAM,+CAA+C,EAAE,mCAgB7D,CAAC"}
@@ -1,26 +1,21 @@
1
1
  // Trust & Safety — NCII config singletons (Appendix A §A11 [H6] / [H-17] / [H-18]).
2
2
  //
3
- // Two `_config` singleton documents:
3
+ // Two Admin-SDK-only `_serverData` singleton documents, wired into COLLECTIONS,
4
+ // PATH_BUILDERS, and the doc-schema registry:
4
5
  // - `_serverData/nciiPolicy` → NciiPolicyConfigV1
5
6
  // - `_serverData/privilegedReviewerSecurity` → PrivilegedReviewerSecurityProfileV1
6
7
  //
7
- // These are VERSIONED launch defaults. Qualified counsel must approve them before
8
- // uploads open and may increase, decrease, or otherwise modify them. Any change
9
- // increments the policy version and triggers a retention/configuration review. The
10
- // launch/config audit FAILS CLOSED if any value is missing or a placeholder;
11
- // uploads stay BLOCKED until `counselApproved` flips true at the pre-launch counsel
12
- // gate.
8
+ // These are VERSIONED operator launch defaults (`approvedBy: 'operatorLaunchDefault'`);
9
+ // a reader falls back to the frozen DEFAULT when the stored doc is absent. Any change
10
+ // increments the policy version and triggers a retention/configuration review.
13
11
  //
14
12
  // Every value in the DEFAULT consts below is transcribed verbatim from the frozen
15
13
  // Trust & Safety spec (Appendix A §A11 [H6] / [H-17] / [H-18]) — no invented values,
16
14
  // no placeholders; the durable design owner is ttt-prod
17
15
  // docs/design/nonconsensual-intimate-imagery-and-take-it-down.md. The schemas pin
18
16
  // each literal-defaulted field where the spec fixes a single literal value
19
- // (`policyVersion`, `approvedBy`, `counselApproved`, the security-profile string
20
- // literals, etc.) so a config write cannot silently drift from the frozen posture.
21
- //
22
- // Collection note: these are `_config` singleton docs; wiring collections.ts /
23
- // path-builders.ts / registry.ts is deferred to the app leg.
17
+ // (`policyVersion`, `approvedBy`, the security-profile string literals, etc.) so a
18
+ // config write cannot silently drift from the frozen posture.
24
19
  import { z } from 'zod';
25
20
  // ===========================================================================
26
21
  // §A11 [H6] — NciiPolicyConfigV1 + DEFAULT_NCII_POLICY_CONFIG_V1
@@ -28,10 +23,7 @@ import { z } from 'zod';
28
23
  // ===========================================================================
29
24
  /** Blocked-hash retention policy — indefinite until an appeal reverses it. */
30
25
  export const NciiBlockedHashRetentionPolicySchema = z.literal('indefiniteUntilReversed');
31
- /** `_serverData/nciiPolicy` = `NciiPolicyConfigV1` — the DJ-approved launch defaults.
32
- * Counsel ratifies (`counselApproved`) at the pre-launch gate; uploads stay
33
- * blocked until then. Any value missing/placeholder → the launch audit FAILS
34
- * CLOSED. */
26
+ /** `_serverData/nciiPolicy` = `NciiPolicyConfigV1` — the operator launch defaults. */
35
27
  export const NciiPolicyConfigV1Schema = z.object({
36
28
  policyVersion: z.literal('ncii.2026-06-23.v1'),
37
29
  requesterPiiRetentionDays: z.number(),
@@ -68,8 +60,6 @@ export const NciiPolicyConfigV1Schema = z.object({
68
60
  evidenceScanMemoryBudgetMb: z.number(),
69
61
  rejectArchiveAndPolyglotPayloads: z.boolean(),
70
62
  approvedBy: z.literal('operatorLaunchDefault'),
71
- // counselApproved flips true at the pre-launch counsel gate; uploads stay blocked until then
72
- counselApproved: z.boolean(),
73
63
  }).strict();
74
64
  /** The frozen launch default for `_serverData/nciiPolicy`. */
75
65
  export const DEFAULT_NCII_POLICY_CONFIG_V1 = {
@@ -104,7 +94,6 @@ export const DEFAULT_NCII_POLICY_CONFIG_V1 = {
104
94
  evidenceScanMemoryBudgetMb: 512,
105
95
  rejectArchiveAndPolyglotPayloads: true,
106
96
  approvedBy: 'operatorLaunchDefault',
107
- counselApproved: false,
108
97
  };
109
98
  // ===========================================================================
110
99
  // §A11 [H-17] — PrivilegedReviewerSecurityProfileV1 +
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/doc-schemas/ncii/config.ts"],"names":[],"mappings":"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","sourcesContent":["// Trust & Safety — NCII config singletons (Appendix A §A11 [H6] / [H-17] / [H-18]).\n//\n// Two `_config` singleton documents:\n// - `_serverData/nciiPolicy` → NciiPolicyConfigV1\n// - `_serverData/privilegedReviewerSecurity` → PrivilegedReviewerSecurityProfileV1\n//\n// These are VERSIONED launch defaults. Qualified counsel must approve them before\n// uploads open and may increase, decrease, or otherwise modify them. Any change\n// increments the policy version and triggers a retention/configuration review. The\n// launch/config audit FAILS CLOSED if any value is missing or a placeholder;\n// uploads stay BLOCKED until `counselApproved` flips true at the pre-launch counsel\n// gate.\n//\n// Every value in the DEFAULT consts below is transcribed verbatim from the frozen\n// Trust & Safety spec (Appendix A §A11 [H6] / [H-17] / [H-18]) — no invented values,\n// no placeholders; the durable design owner is ttt-prod\n// docs/design/nonconsensual-intimate-imagery-and-take-it-down.md. The schemas pin\n// each literal-defaulted field where the spec fixes a single literal value\n// (`policyVersion`, `approvedBy`, `counselApproved`, the security-profile string\n// literals, etc.) so a config write cannot silently drift from the frozen posture.\n//\n// Collection note: these are `_config` singleton docs; wiring collections.ts /\n// path-builders.ts / registry.ts is deferred to the app leg.\n\nimport { z } from 'zod';\n\n// ===========================================================================\n// §A11 [H6] — NciiPolicyConfigV1 + DEFAULT_NCII_POLICY_CONFIG_V1\n// `_serverData/nciiPolicy`\n// ===========================================================================\n\n/** Blocked-hash retention policy — indefinite until an appeal reverses it. */\nexport const NciiBlockedHashRetentionPolicySchema = z.literal('indefiniteUntilReversed');\nexport type NciiBlockedHashRetentionPolicy = z.infer<typeof NciiBlockedHashRetentionPolicySchema>;\n\n/** `_serverData/nciiPolicy` = `NciiPolicyConfigV1` — the DJ-approved launch defaults.\n * Counsel ratifies (`counselApproved`) at the pre-launch gate; uploads stay\n * blocked until then. Any value missing/placeholder → the launch audit FAILS\n * CLOSED. */\nexport const NciiPolicyConfigV1Schema = z.object({\n policyVersion: z.literal('ncii.2026-06-23.v1'),\n requesterPiiRetentionDays: z.number(),\n evidenceRetentionDays: z.number(),\n blockedHashRetentionPolicy: NciiBlockedHashRetentionPolicySchema,\n allowedEvidenceMimeTypes: z.array(z.string().min(1)),\n maxEvidenceFileBytes: z.number(),\n maxEvidenceFilesPerRequest: z.number(),\n maxEvidenceTotalBytesPerRequest: z.number(),\n uploadReservationMinutes: z.number(),\n abandonedUploadCleanupHours: z.number(),\n // [H1/M3] temp-hold values:\n tempHoldInitialHours: z.number(),\n tempHoldPendingValidityExtensionHours: z.number(),\n tempHoldMaxTotalHours: z.number(),\n incompleteInvalidReleaseDelayHours: z.number(),\n // [NCII route rate-limit hardening — 2026-07-01, OPERATIONAL operator defaults, not legal-retention\n // values; counsel may tune]. The public intake route returns 429 + Retry-After and NEVER discards a\n // submission. App-Check is the PRIMARY defense with only a GENEROUS per-IP burst backstop (generous\n // enough not to throttle a real VPN/shared-IP victim — per-IP was rejected for the evidence BYTES\n // path; this is the HTTP route only). (The supplement route + status token were removed with the\n // public post-submission tracking tail — the public flow is submit-only.)\n intakeRateLimitWindowSeconds: z.number(),\n intakeRateLimitMaxPerIp: z.number(),\n // [H-07] dedup window for the deterministic initial-intake idempotency key\n idempotencyWindowHours: z.number(),\n // [M-10] evidence parser-hardening budgets (attacker-controlled bytes):\n maxEvidenceDecodePixels: z.number(),\n maxEvidenceImageDimension: z.number(),\n maxEvidenceVideoFrames: z.number(),\n maxEvidenceVideoDurationSec: z.number(),\n evidenceParserTimeoutSec: z.number(),\n evidenceScanCpuBudgetMs: z.number(),\n evidenceScanMemoryBudgetMb: z.number(),\n rejectArchiveAndPolyglotPayloads: z.boolean(),\n approvedBy: z.literal('operatorLaunchDefault'),\n // counselApproved flips true at the pre-launch counsel gate; uploads stay blocked until then\n counselApproved: z.boolean(),\n}).strict();\nexport type NciiPolicyConfigV1 = z.infer<typeof NciiPolicyConfigV1Schema>;\n\n/** The frozen launch default for `_serverData/nciiPolicy`. */\nexport const DEFAULT_NCII_POLICY_CONFIG_V1: NciiPolicyConfigV1 = {\n policyVersion: 'ncii.2026-06-23.v1',\n requesterPiiRetentionDays: 90,\n evidenceRetentionDays: 60,\n blockedHashRetentionPolicy: 'indefiniteUntilReversed',\n allowedEvidenceMimeTypes: ['image/jpeg', 'image/png', 'image/webp', 'image/gif', 'video/mp4', 'video/webm'],\n // [H-01/R10] 100MB per file (was 500MB): the evidence-scan trigger downloads the whole object into a\n // ~512MiB Function before scanning, so an allowed file must fit in memory. Total = 3×100MB = 300MB.\n // Count stays 3. The storage.rules `nciiEvidence` per-file cap mirrors this 100MB (rules can't read\n // this config).\n maxEvidenceFileBytes: 104857600,\n maxEvidenceFilesPerRequest: 3,\n maxEvidenceTotalBytesPerRequest: 314572800,\n uploadReservationMinutes: 30,\n abandonedUploadCleanupHours: 24,\n tempHoldInitialHours: 72,\n tempHoldPendingValidityExtensionHours: 48,\n tempHoldMaxTotalHours: 336,\n incompleteInvalidReleaseDelayHours: 24,\n // [NCII route rate-limit hardening — 2026-07-01 operator defaults; generous, counsel may tune]\n intakeRateLimitWindowSeconds: 3600, // per source IP (secondary flood guard; App-Check is primary)\n intakeRateLimitMaxPerIp: 20, // generous so a shared/VPN IP with several genuine victims isn't throttled\n idempotencyWindowHours: 72,\n maxEvidenceDecodePixels: 40000000,\n maxEvidenceImageDimension: 12000,\n maxEvidenceVideoFrames: 600,\n maxEvidenceVideoDurationSec: 600,\n evidenceParserTimeoutSec: 60,\n evidenceScanCpuBudgetMs: 30000,\n evidenceScanMemoryBudgetMb: 512,\n rejectArchiveAndPolyglotPayloads: true,\n approvedBy: 'operatorLaunchDefault',\n counselApproved: false,\n};\n\n// ===========================================================================\n// §A11 [H-17] — PrivilegedReviewerSecurityProfileV1 +\n// DEFAULT_PRIVILEGED_REVIEWER_SECURITY_PROFILE_V1\n// `_serverData/privilegedReviewerSecurity`\n//\n// \"fresh reauth\" / \"two-step reauth\" for ANY privileged-reviewer capability means\n// a reauth that satisfies THIS profile — NEVER a bare password re-prompt. Enforced\n// even though one solo operator holds every capability at launch.\n// ===========================================================================\n\n/** The phishing-resistant second factor — password-only, SMS, and TOTP are NEVER\n * sufficient for a privileged capability. */\nexport const PrivilegedReviewerSecondFactorSchema = z.literal('passkeyWebAuthn');\nexport type PrivilegedReviewerSecondFactor = z.infer<typeof PrivilegedReviewerSecondFactorSchema>;\n\n/** The capabilities that require the passkey assertion + an explicit typed\n * confirmation (two-step reauth). */\nexport const PrivilegedTwoStepReauthCapabilitySchema = z.enum([\n 'evidenceReveal',\n 'ncmecCredentialUse',\n 'reverseHashBlock',\n 'legalDisposition',\n 'falsePositiveCorrection',\n 'ncmecManualFallback',\n]);\nexport type PrivilegedTwoStepReauthCapability = z.infer<typeof PrivilegedTwoStepReauthCapabilitySchema>;\n\n/** `_serverData/privilegedReviewerSecurity` = `PrivilegedReviewerSecurityProfileV1` —\n * what \"fresh reauth\" actually means for any privileged-reviewer capability. */\nexport const PrivilegedReviewerSecurityProfileV1Schema = z.object({\n // phishing-resistant; password-only, SMS, and TOTP are NEVER sufficient for a privileged capability\n requiredSecondFactor: PrivilegedReviewerSecondFactorSchema,\n // a capability invocation needs a WebAuthn assertion at least this fresh; older → re-prompt\n privilegedReauthTtlSeconds: z.number(),\n // the privileged session is bound to the enrolled authenticator/device; separate from the ordinary app session\n privilegedSessionDeviceBound: z.boolean(),\n // these require the passkey assertion + an explicit typed confirmation\n twoStepReauthCapabilities: z.array(PrivilegedTwoStepReauthCapabilitySchema),\n // offline one-time break-glass codes, generated at enrollment, stored physically offline\n recoveryCodeCount: z.number(),\n // using one is logged, fires the external critical alarm, and forces enrolling a fresh passkey\n recoveryCodeUse: z.literal('auditedHighSeverity+forcesReenroll+criticalAlarm'),\n // lost-device: revoke ALL privileged sessions → forces re-enrollment before any capability works again\n allowPrivilegedSessionRevocation: z.boolean(),\n // each privileged-capability use writes an audit event (actor, capability, caseId, reauth method, before/after for evidence reads)\n everyInvocationAudited: z.boolean(),\n}).strict();\nexport type PrivilegedReviewerSecurityProfileV1 = z.infer<typeof PrivilegedReviewerSecurityProfileV1Schema>;\n\n/** The frozen launch default for `_serverData/privilegedReviewerSecurity`. */\nexport const DEFAULT_PRIVILEGED_REVIEWER_SECURITY_PROFILE_V1: PrivilegedReviewerSecurityProfileV1 = {\n requiredSecondFactor: 'passkeyWebAuthn',\n privilegedReauthTtlSeconds: 300,\n privilegedSessionDeviceBound: true,\n twoStepReauthCapabilities: [\n 'evidenceReveal',\n 'ncmecCredentialUse',\n 'reverseHashBlock',\n 'legalDisposition',\n 'falsePositiveCorrection',\n 'ncmecManualFallback',\n ],\n recoveryCodeCount: 10,\n recoveryCodeUse: 'auditedHighSeverity+forcesReenroll+criticalAlarm',\n allowPrivilegedSessionRevocation: true,\n everyInvocationAudited: true,\n};\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/doc-schemas/ncii/config.ts"],"names":[],"mappings":"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","sourcesContent":["// Trust & Safety — NCII config singletons (Appendix A §A11 [H6] / [H-17] / [H-18]).\n//\n// Two Admin-SDK-only `_serverData` singleton documents, wired into COLLECTIONS,\n// PATH_BUILDERS, and the doc-schema registry:\n// - `_serverData/nciiPolicy` → NciiPolicyConfigV1\n// - `_serverData/privilegedReviewerSecurity` → PrivilegedReviewerSecurityProfileV1\n//\n// These are VERSIONED operator launch defaults (`approvedBy: 'operatorLaunchDefault'`);\n// a reader falls back to the frozen DEFAULT when the stored doc is absent. Any change\n// increments the policy version and triggers a retention/configuration review.\n//\n// Every value in the DEFAULT consts below is transcribed verbatim from the frozen\n// Trust & Safety spec (Appendix A §A11 [H6] / [H-17] / [H-18]) — no invented values,\n// no placeholders; the durable design owner is ttt-prod\n// docs/design/nonconsensual-intimate-imagery-and-take-it-down.md. The schemas pin\n// each literal-defaulted field where the spec fixes a single literal value\n// (`policyVersion`, `approvedBy`, the security-profile string literals, etc.) so a\n// config write cannot silently drift from the frozen posture.\n\nimport { z } from 'zod';\n\n// ===========================================================================\n// §A11 [H6] — NciiPolicyConfigV1 + DEFAULT_NCII_POLICY_CONFIG_V1\n// `_serverData/nciiPolicy`\n// ===========================================================================\n\n/** Blocked-hash retention policy — indefinite until an appeal reverses it. */\nexport const NciiBlockedHashRetentionPolicySchema = z.literal('indefiniteUntilReversed');\nexport type NciiBlockedHashRetentionPolicy = z.infer<typeof NciiBlockedHashRetentionPolicySchema>;\n\n/** `_serverData/nciiPolicy` = `NciiPolicyConfigV1` — the operator launch defaults. */\nexport const NciiPolicyConfigV1Schema = z.object({\n policyVersion: z.literal('ncii.2026-06-23.v1'),\n requesterPiiRetentionDays: z.number(),\n evidenceRetentionDays: z.number(),\n blockedHashRetentionPolicy: NciiBlockedHashRetentionPolicySchema,\n allowedEvidenceMimeTypes: z.array(z.string().min(1)),\n maxEvidenceFileBytes: z.number(),\n maxEvidenceFilesPerRequest: z.number(),\n maxEvidenceTotalBytesPerRequest: z.number(),\n uploadReservationMinutes: z.number(),\n abandonedUploadCleanupHours: z.number(),\n // [H1/M3] temp-hold values:\n tempHoldInitialHours: z.number(),\n tempHoldPendingValidityExtensionHours: z.number(),\n tempHoldMaxTotalHours: z.number(),\n incompleteInvalidReleaseDelayHours: z.number(),\n // [NCII route rate-limit hardening — 2026-07-01, OPERATIONAL operator defaults, not legal-retention\n // values; counsel may tune]. The public intake route returns 429 + Retry-After and NEVER discards a\n // submission. App-Check is the PRIMARY defense with only a GENEROUS per-IP burst backstop (generous\n // enough not to throttle a real VPN/shared-IP victim — per-IP was rejected for the evidence BYTES\n // path; this is the HTTP route only). (The supplement route + status token were removed with the\n // public post-submission tracking tail — the public flow is submit-only.)\n intakeRateLimitWindowSeconds: z.number(),\n intakeRateLimitMaxPerIp: z.number(),\n // [H-07] dedup window for the deterministic initial-intake idempotency key\n idempotencyWindowHours: z.number(),\n // [M-10] evidence parser-hardening budgets (attacker-controlled bytes):\n maxEvidenceDecodePixels: z.number(),\n maxEvidenceImageDimension: z.number(),\n maxEvidenceVideoFrames: z.number(),\n maxEvidenceVideoDurationSec: z.number(),\n evidenceParserTimeoutSec: z.number(),\n evidenceScanCpuBudgetMs: z.number(),\n evidenceScanMemoryBudgetMb: z.number(),\n rejectArchiveAndPolyglotPayloads: z.boolean(),\n approvedBy: z.literal('operatorLaunchDefault'),\n}).strict();\nexport type NciiPolicyConfigV1 = z.infer<typeof NciiPolicyConfigV1Schema>;\n\n/** The frozen launch default for `_serverData/nciiPolicy`. */\nexport const DEFAULT_NCII_POLICY_CONFIG_V1: NciiPolicyConfigV1 = {\n policyVersion: 'ncii.2026-06-23.v1',\n requesterPiiRetentionDays: 90,\n evidenceRetentionDays: 60,\n blockedHashRetentionPolicy: 'indefiniteUntilReversed',\n allowedEvidenceMimeTypes: ['image/jpeg', 'image/png', 'image/webp', 'image/gif', 'video/mp4', 'video/webm'],\n // [H-01/R10] 100MB per file (was 500MB): the evidence-scan trigger downloads the whole object into a\n // ~512MiB Function before scanning, so an allowed file must fit in memory. Total = 3×100MB = 300MB.\n // Count stays 3. The storage.rules `nciiEvidence` per-file cap mirrors this 100MB (rules can't read\n // this config).\n maxEvidenceFileBytes: 104857600,\n maxEvidenceFilesPerRequest: 3,\n maxEvidenceTotalBytesPerRequest: 314572800,\n uploadReservationMinutes: 30,\n abandonedUploadCleanupHours: 24,\n tempHoldInitialHours: 72,\n tempHoldPendingValidityExtensionHours: 48,\n tempHoldMaxTotalHours: 336,\n incompleteInvalidReleaseDelayHours: 24,\n // [NCII route rate-limit hardening — 2026-07-01 operator defaults; generous, counsel may tune]\n intakeRateLimitWindowSeconds: 3600, // per source IP (secondary flood guard; App-Check is primary)\n intakeRateLimitMaxPerIp: 20, // generous so a shared/VPN IP with several genuine victims isn't throttled\n idempotencyWindowHours: 72,\n maxEvidenceDecodePixels: 40000000,\n maxEvidenceImageDimension: 12000,\n maxEvidenceVideoFrames: 600,\n maxEvidenceVideoDurationSec: 600,\n evidenceParserTimeoutSec: 60,\n evidenceScanCpuBudgetMs: 30000,\n evidenceScanMemoryBudgetMb: 512,\n rejectArchiveAndPolyglotPayloads: true,\n approvedBy: 'operatorLaunchDefault',\n};\n\n// ===========================================================================\n// §A11 [H-17] — PrivilegedReviewerSecurityProfileV1 +\n// DEFAULT_PRIVILEGED_REVIEWER_SECURITY_PROFILE_V1\n// `_serverData/privilegedReviewerSecurity`\n//\n// \"fresh reauth\" / \"two-step reauth\" for ANY privileged-reviewer capability means\n// a reauth that satisfies THIS profile — NEVER a bare password re-prompt. Enforced\n// even though one solo operator holds every capability at launch.\n// ===========================================================================\n\n/** The phishing-resistant second factor — password-only, SMS, and TOTP are NEVER\n * sufficient for a privileged capability. */\nexport const PrivilegedReviewerSecondFactorSchema = z.literal('passkeyWebAuthn');\nexport type PrivilegedReviewerSecondFactor = z.infer<typeof PrivilegedReviewerSecondFactorSchema>;\n\n/** The capabilities that require the passkey assertion + an explicit typed\n * confirmation (two-step reauth). */\nexport const PrivilegedTwoStepReauthCapabilitySchema = z.enum([\n 'evidenceReveal',\n 'ncmecCredentialUse',\n 'reverseHashBlock',\n 'legalDisposition',\n 'falsePositiveCorrection',\n 'ncmecManualFallback',\n]);\nexport type PrivilegedTwoStepReauthCapability = z.infer<typeof PrivilegedTwoStepReauthCapabilitySchema>;\n\n/** `_serverData/privilegedReviewerSecurity` = `PrivilegedReviewerSecurityProfileV1` —\n * what \"fresh reauth\" actually means for any privileged-reviewer capability. */\nexport const PrivilegedReviewerSecurityProfileV1Schema = z.object({\n // phishing-resistant; password-only, SMS, and TOTP are NEVER sufficient for a privileged capability\n requiredSecondFactor: PrivilegedReviewerSecondFactorSchema,\n // a capability invocation needs a WebAuthn assertion at least this fresh; older → re-prompt\n privilegedReauthTtlSeconds: z.number(),\n // the privileged session is bound to the enrolled authenticator/device; separate from the ordinary app session\n privilegedSessionDeviceBound: z.boolean(),\n // these require the passkey assertion + an explicit typed confirmation\n twoStepReauthCapabilities: z.array(PrivilegedTwoStepReauthCapabilitySchema),\n // offline one-time break-glass codes, generated at enrollment, stored physically offline\n recoveryCodeCount: z.number(),\n // using one is logged, fires the external critical alarm, and forces enrolling a fresh passkey\n recoveryCodeUse: z.literal('auditedHighSeverity+forcesReenroll+criticalAlarm'),\n // lost-device: revoke ALL privileged sessions → forces re-enrollment before any capability works again\n allowPrivilegedSessionRevocation: z.boolean(),\n // each privileged-capability use writes an audit event (actor, capability, caseId, reauth method, before/after for evidence reads)\n everyInvocationAudited: z.boolean(),\n}).strict();\nexport type PrivilegedReviewerSecurityProfileV1 = z.infer<typeof PrivilegedReviewerSecurityProfileV1Schema>;\n\n/** The frozen launch default for `_serverData/privilegedReviewerSecurity`. */\nexport const DEFAULT_PRIVILEGED_REVIEWER_SECURITY_PROFILE_V1: PrivilegedReviewerSecurityProfileV1 = {\n requiredSecondFactor: 'passkeyWebAuthn',\n privilegedReauthTtlSeconds: 300,\n privilegedSessionDeviceBound: true,\n twoStepReauthCapabilities: [\n 'evidenceReveal',\n 'ncmecCredentialUse',\n 'reverseHashBlock',\n 'legalDisposition',\n 'falsePositiveCorrection',\n 'ncmecManualFallback',\n ],\n recoveryCodeCount: 10,\n recoveryCodeUse: 'auditedHighSeverity+forcesReenroll+criticalAlarm',\n allowPrivilegedSessionRevocation: true,\n everyInvocationAudited: true,\n};\n"]}
@@ -42,18 +42,63 @@ export declare const ShortLinkSchema: z.ZodObject<{
42
42
  clicks: z.ZodNumber;
43
43
  }, z.core.$strip>;
44
44
  export type ShortLink = z.infer<typeof ShortLinkSchema>;
45
- export declare const StatusReconcileQueueEntrySchema: z.ZodObject<{
45
+ /**
46
+ * Which post-commit Auth effect failed and queued the uid:
47
+ * - `accountStatus` — the status claim / `disabled` flag / token revocation after a status change;
48
+ * - `publicDocumentsAcceptedClaim` — the `docsAccepted` claim after a public-document acceptance.
49
+ * An entry without `authEffect` predates the field and is an `accountStatus` entry.
50
+ */
51
+ export declare const STATUS_RECONCILE_QUEUE_AUTH_EFFECTS: readonly ["accountStatus", "publicDocumentsAcceptedClaim"];
52
+ export declare const StatusReconcileQueueAuthEffectSchema: z.ZodEnum<{
53
+ accountStatus: "accountStatus";
54
+ publicDocumentsAcceptedClaim: "publicDocumentsAcceptedClaim";
55
+ }>;
56
+ export type StatusReconcileQueueAuthEffect = z.infer<typeof StatusReconcileQueueAuthEffectSchema>;
57
+ /** A failed status effect: the drain drives the account toward `targetStatus`. */
58
+ export declare const StatusReconcileQueueAccountStatusEntrySchema: z.ZodObject<{
59
+ authEffect: z.ZodOptional<z.ZodLiteral<"accountStatus">>;
60
+ targetStatus: z.ZodEnum<{
61
+ banned: "banned";
62
+ active: "active";
63
+ suspended: "suspended";
64
+ }>;
65
+ uid: z.ZodString;
66
+ enqueuedAt: z.ZodNumber;
67
+ lastAttemptAt: z.ZodOptional<z.ZodNumber>;
68
+ attemptCount: z.ZodNumber;
69
+ reason: z.ZodLiteral<"postCommitAuthEffectFailed">;
70
+ }, z.core.$strip>;
71
+ export type StatusReconcileQueueAccountStatusEntry = z.infer<typeof StatusReconcileQueueAccountStatusEntrySchema>;
72
+ /** A failed `docsAccepted` claim write. Strict: it carries no status, so no `targetStatus`. */
73
+ export declare const StatusReconcileQueuePublicDocumentsAcceptedClaimEntrySchema: z.ZodObject<{
74
+ authEffect: z.ZodLiteral<"publicDocumentsAcceptedClaim">;
46
75
  uid: z.ZodString;
47
76
  enqueuedAt: z.ZodNumber;
48
77
  lastAttemptAt: z.ZodOptional<z.ZodNumber>;
49
78
  attemptCount: z.ZodNumber;
79
+ reason: z.ZodLiteral<"postCommitAuthEffectFailed">;
80
+ }, z.core.$strict>;
81
+ export type StatusReconcileQueuePublicDocumentsAcceptedClaimEntry = z.infer<typeof StatusReconcileQueuePublicDocumentsAcceptedClaimEntrySchema>;
82
+ export declare const StatusReconcileQueueEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
83
+ authEffect: z.ZodOptional<z.ZodLiteral<"accountStatus">>;
50
84
  targetStatus: z.ZodEnum<{
51
85
  banned: "banned";
52
86
  active: "active";
53
87
  suspended: "suspended";
54
88
  }>;
89
+ uid: z.ZodString;
90
+ enqueuedAt: z.ZodNumber;
91
+ lastAttemptAt: z.ZodOptional<z.ZodNumber>;
92
+ attemptCount: z.ZodNumber;
55
93
  reason: z.ZodLiteral<"postCommitAuthEffectFailed">;
56
- }, z.core.$strip>;
94
+ }, z.core.$strip>, z.ZodObject<{
95
+ authEffect: z.ZodLiteral<"publicDocumentsAcceptedClaim">;
96
+ uid: z.ZodString;
97
+ enqueuedAt: z.ZodNumber;
98
+ lastAttemptAt: z.ZodOptional<z.ZodNumber>;
99
+ attemptCount: z.ZodNumber;
100
+ reason: z.ZodLiteral<"postCommitAuthEffectFailed">;
101
+ }, z.core.$strict>], "authEffect">;
57
102
  export type StatusReconcileQueueEntry = z.infer<typeof StatusReconcileQueueEntrySchema>;
58
103
  export declare const FeedbackAliasSchema: z.ZodObject<{
59
104
  canonicalId: z.ZodString;
@@ -1 +1 @@
1
- {"version":3,"file":"operational.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/operational.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,yBAAyB;;;iBAGpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAK5E,eAAO,MAAM,uBAAuB;;;;iBASlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAIxE,eAAO,MAAM,0BAA0B;;;;;;;;;;;iBAWrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAO9E,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;iBAa1B,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAOxD,eAAO,MAAM,+BAA+B;;;;;;;;;;;iBAO1C,CAAC;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAIxF,eAAO,MAAM,mBAAmB;;;iBAG9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAKhE,eAAO,MAAM,oBAAoB;;;;;;;iBAK/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
1
+ {"version":3,"file":"operational.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/operational.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,yBAAyB;;;iBAGpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAK5E,eAAO,MAAM,uBAAuB;;;;iBASlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAIxE,eAAO,MAAM,0BAA0B;;;;;;;;;;;iBAWrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAO9E,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;iBAa1B,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AASxD;;;;;GAKG;AACH,eAAO,MAAM,mCAAmC,4DAA6D,CAAC;AAC9G,eAAO,MAAM,oCAAoC;;;EAA8C,CAAC;AAChG,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oCAAoC,CAAC,CAAC;AAUlG,kFAAkF;AAClF,eAAO,MAAM,4CAA4C;;;;;;;;;;;;iBAIvD,CAAC;AACH,MAAM,MAAM,sCAAsC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4CAA4C,CAAC,CAAC;AAElH,+FAA+F;AAC/F,eAAO,MAAM,2DAA2D;;;;;;;kBAK7D,CAAC;AACZ,MAAM,MAAM,qDAAqD,GAAG,CAAC,CAAC,KAAK,CACzE,OAAO,2DAA2D,CACnE,CAAC;AAEF,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;kCAG1C,CAAC;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAIxF,eAAO,MAAM,mBAAmB;;;iBAG9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAKhE,eAAO,MAAM,oBAAoB;;;;;;;iBAK/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
@@ -54,19 +54,44 @@ export const ShortLinkSchema = z.object({
54
54
  createdBy: z.string(),
55
55
  clicks: z.number(),
56
56
  });
57
- // statusReconcileQueue/{uid} — backend-only retry queue for post-commit auth-effect reconciliation.
58
- // Written when an account-status change committed to Firestore but the follow-on Auth effect
59
- // (custom-claim set / account disable) failed; a retry loop drives the account toward `targetStatus`
60
- // and deletes the entry on success. Keyed by the affected uid (doc id == uid); Admin-SDK-only.
61
- // Timestamps are epoch-millis numbers (this repo never uses Firestore Timestamps).
62
- export const StatusReconcileQueueEntrySchema = z.object({
57
+ // statusReconcileQueue/{uid} — backend-only retry queue for post-commit Auth-effect reconciliation.
58
+ // Written when a change committed to Firestore but its follow-on Auth effect failed; the drain
59
+ // re-converges every Auth-side mirror of the uid from its canonical docs and deletes the entry on
60
+ // success. Keyed by the affected uid (doc id == uid; one entry per uid, whichever effect queued
61
+ // it); Admin-SDK-only. Timestamps are epoch-millis numbers (this repo never uses Firestore
62
+ // Timestamps).
63
+ /**
64
+ * Which post-commit Auth effect failed and queued the uid:
65
+ * - `accountStatus` — the status claim / `disabled` flag / token revocation after a status change;
66
+ * - `publicDocumentsAcceptedClaim` — the `docsAccepted` claim after a public-document acceptance.
67
+ * An entry without `authEffect` predates the field and is an `accountStatus` entry.
68
+ */
69
+ export const STATUS_RECONCILE_QUEUE_AUTH_EFFECTS = ['accountStatus', 'publicDocumentsAcceptedClaim'];
70
+ export const StatusReconcileQueueAuthEffectSchema = z.enum(STATUS_RECONCILE_QUEUE_AUTH_EFFECTS);
71
+ const statusReconcileQueueEntryBase = {
63
72
  uid: z.string(),
64
73
  enqueuedAt: z.number(),
65
74
  lastAttemptAt: z.number().optional(),
66
75
  attemptCount: z.number(),
67
- targetStatus: UserAccountStatusSchema,
68
76
  reason: z.literal('postCommitAuthEffectFailed'),
77
+ };
78
+ /** A failed status effect: the drain drives the account toward `targetStatus`. */
79
+ export const StatusReconcileQueueAccountStatusEntrySchema = z.object({
80
+ ...statusReconcileQueueEntryBase,
81
+ authEffect: z.literal('accountStatus').optional(),
82
+ targetStatus: UserAccountStatusSchema,
69
83
  });
84
+ /** A failed `docsAccepted` claim write. Strict: it carries no status, so no `targetStatus`. */
85
+ export const StatusReconcileQueuePublicDocumentsAcceptedClaimEntrySchema = z
86
+ .object({
87
+ ...statusReconcileQueueEntryBase,
88
+ authEffect: z.literal('publicDocumentsAcceptedClaim'),
89
+ })
90
+ .strict();
91
+ export const StatusReconcileQueueEntrySchema = z.discriminatedUnion('authEffect', [
92
+ StatusReconcileQueueAccountStatusEntrySchema,
93
+ StatusReconcileQueuePublicDocumentsAcceptedClaimEntrySchema,
94
+ ]);
70
95
  // feedbackAliases/{aliasId} — Console-managed map collapsing a synonym suggestion onto a canonical
71
96
  // one; read by submitFeedback, no callable writes it. (firestore.rules §3F / submitFeedback.ts)
72
97
  export const FeedbackAliasSchema = z.object({
@@ -1 +1 @@
1
- {"version":3,"file":"operational.js","sourceRoot":"","sources":["../../src/doc-schemas/operational.ts"],"names":[],"mappings":"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","sourcesContent":["// Operational / utility Firestore document SCHEMAS — small backend-written docs that aren't\n// part of a feature domain. Reverse-engineered from their backend write sites. Types via z.infer.\n\nimport { z } from 'zod';\nimport { UserAccountStatusSchema } from './user.js';\n\n// reservedDisplayNames/{displayNameUppercase} — uniqueness claim written in the registerUser\n// transaction; existence == name taken. (functions/src/users/registerUser.ts)\nexport const ReservedDisplayNameSchema = z.object({\n userId: z.string(),\n displayName: z.string(),\n});\nexport type ReservedDisplayName = z.infer<typeof ReservedDisplayNameSchema>;\n\n// reservedRealmNames/{workingTitleUppercase} — platform-wide Realm-name uniqueness claim, written\n// in the createWorkRealm transaction (existence == name taken). Mirrors reservedDisplayNames; key is\n// the UPPERCASE realm working title. (legal-convo [BUILD]: realm names unique platform-wide.)\nexport const ReservedRealmNameSchema = z.object({\n workRealmId: z.string(),\n workingTitle: z.string(),\n // RETIRED name (DJ ruling 2026-07-12, option B): set true when a moderation\n // force-retitle removes this name — the name is dead platform-wide FOREVER; no\n // realm (including the original owner) can ever claim it again, and no rename\n // path releases the reservation. Ordinary renames release un-retired\n // reservations normally. Backend-only-writable.\n retired: z.boolean().optional(),\n});\nexport type ReservedRealmName = z.infer<typeof ReservedRealmNameSchema>;\n\n// stakeShareAuditEvents/{eventId} — Firestore-trigger audit of guildmate stake-share changes.\n// (functions/src/audit/runWorkProjectGuildmateUserStakeShareAudit.ts)\nexport const StakeShareAuditEventSchema = z.object({\n eventId: z.string(),\n subtype: z.string(),\n reason: z.string(),\n workProjectId: z.string(),\n guildmateUserUid: z.string(),\n guildmateUserPath: z.string(),\n beforeStakeShares: z.number().nullable(),\n afterStakeShares: z.number().nullable(),\n createdAt: z.number(),\n source: z.string(),\n});\nexport type StakeShareAuditEvent = z.infer<typeof StakeShareAuditEventSchema>;\n\n// shortLinks/{shortId} — short link to a share target (Audition / AuditionEntry /\n// Commission), with a click counter. (functions/src/utility/createShortLink.ts)\n// `type` mirrors the CreateShortLinkInput target type; `metadata` carries the target\n// id(s) the destination URL was built from. Fields are per-target-optional so a new\n// target type slots in without reworking the map. Add a `type` value when adding a target.\nexport const ShortLinkSchema = z.object({\n shortId: z.string(),\n shortUrl: z.string(),\n destinationUrl: z.string(),\n type: z.enum(['audition', 'audition-entry', 'commission']),\n metadata: z.object({\n auditionId: z.string().nullable(),\n auditionEntryId: z.string().nullable(),\n commissionListingId: z.string().nullable(),\n }),\n createdAt: z.number(),\n createdBy: z.string(),\n clicks: z.number(),\n});\nexport type ShortLink = z.infer<typeof ShortLinkSchema>;\n\n// statusReconcileQueue/{uid} — backend-only retry queue for post-commit auth-effect reconciliation.\n// Written when an account-status change committed to Firestore but the follow-on Auth effect\n// (custom-claim set / account disable) failed; a retry loop drives the account toward `targetStatus`\n// and deletes the entry on success. Keyed by the affected uid (doc id == uid); Admin-SDK-only.\n// Timestamps are epoch-millis numbers (this repo never uses Firestore Timestamps).\nexport const StatusReconcileQueueEntrySchema = z.object({\n uid: z.string(),\n enqueuedAt: z.number(),\n lastAttemptAt: z.number().optional(),\n attemptCount: z.number(),\n targetStatus: UserAccountStatusSchema,\n reason: z.literal('postCommitAuthEffectFailed'),\n});\nexport type StatusReconcileQueueEntry = z.infer<typeof StatusReconcileQueueEntrySchema>;\n\n// feedbackAliases/{aliasId} — Console-managed map collapsing a synonym suggestion onto a canonical\n// one; read by submitFeedback, no callable writes it. (firestore.rules §3F / submitFeedback.ts)\nexport const FeedbackAliasSchema = z.object({\n canonicalId: z.string(),\n originalType: z.string(),\n});\nexport type FeedbackAlias = z.infer<typeof FeedbackAliasSchema>;\n\n// feedbackSubmissions/{feedbackType}/userSuggestions/{suggestionId} — an aggregated user\n// suggestion with its deduped submitter list + count. The path nests the feedbackSubmissions +\n// userSuggestions registry segments. (functions/src/utility/submitFeedback.ts)\nexport const UserSuggestionSchema = z.object({\n suggestionText: z.string(),\n count: z.number(),\n submittedBy: z.array(z.object({ userId: z.string() })),\n lastSubmitted: z.number(),\n});\nexport type UserSuggestion = z.infer<typeof UserSuggestionSchema>;\n"]}
1
+ {"version":3,"file":"operational.js","sourceRoot":"","sources":["../../src/doc-schemas/operational.ts"],"names":[],"mappings":"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","sourcesContent":["// Operational / utility Firestore document SCHEMAS — small backend-written docs that aren't\n// part of a feature domain. Reverse-engineered from their backend write sites. Types via z.infer.\n\nimport { z } from 'zod';\nimport { UserAccountStatusSchema } from './user.js';\n\n// reservedDisplayNames/{displayNameUppercase} — uniqueness claim written in the registerUser\n// transaction; existence == name taken. (functions/src/users/registerUser.ts)\nexport const ReservedDisplayNameSchema = z.object({\n userId: z.string(),\n displayName: z.string(),\n});\nexport type ReservedDisplayName = z.infer<typeof ReservedDisplayNameSchema>;\n\n// reservedRealmNames/{workingTitleUppercase} — platform-wide Realm-name uniqueness claim, written\n// in the createWorkRealm transaction (existence == name taken). Mirrors reservedDisplayNames; key is\n// the UPPERCASE realm working title. (legal-convo [BUILD]: realm names unique platform-wide.)\nexport const ReservedRealmNameSchema = z.object({\n workRealmId: z.string(),\n workingTitle: z.string(),\n // RETIRED name (DJ ruling 2026-07-12, option B): set true when a moderation\n // force-retitle removes this name — the name is dead platform-wide FOREVER; no\n // realm (including the original owner) can ever claim it again, and no rename\n // path releases the reservation. Ordinary renames release un-retired\n // reservations normally. Backend-only-writable.\n retired: z.boolean().optional(),\n});\nexport type ReservedRealmName = z.infer<typeof ReservedRealmNameSchema>;\n\n// stakeShareAuditEvents/{eventId} — Firestore-trigger audit of guildmate stake-share changes.\n// (functions/src/audit/runWorkProjectGuildmateUserStakeShareAudit.ts)\nexport const StakeShareAuditEventSchema = z.object({\n eventId: z.string(),\n subtype: z.string(),\n reason: z.string(),\n workProjectId: z.string(),\n guildmateUserUid: z.string(),\n guildmateUserPath: z.string(),\n beforeStakeShares: z.number().nullable(),\n afterStakeShares: z.number().nullable(),\n createdAt: z.number(),\n source: z.string(),\n});\nexport type StakeShareAuditEvent = z.infer<typeof StakeShareAuditEventSchema>;\n\n// shortLinks/{shortId} — short link to a share target (Audition / AuditionEntry /\n// Commission), with a click counter. (functions/src/utility/createShortLink.ts)\n// `type` mirrors the CreateShortLinkInput target type; `metadata` carries the target\n// id(s) the destination URL was built from. Fields are per-target-optional so a new\n// target type slots in without reworking the map. Add a `type` value when adding a target.\nexport const ShortLinkSchema = z.object({\n shortId: z.string(),\n shortUrl: z.string(),\n destinationUrl: z.string(),\n type: z.enum(['audition', 'audition-entry', 'commission']),\n metadata: z.object({\n auditionId: z.string().nullable(),\n auditionEntryId: z.string().nullable(),\n commissionListingId: z.string().nullable(),\n }),\n createdAt: z.number(),\n createdBy: z.string(),\n clicks: z.number(),\n});\nexport type ShortLink = z.infer<typeof ShortLinkSchema>;\n\n// statusReconcileQueue/{uid} — backend-only retry queue for post-commit Auth-effect reconciliation.\n// Written when a change committed to Firestore but its follow-on Auth effect failed; the drain\n// re-converges every Auth-side mirror of the uid from its canonical docs and deletes the entry on\n// success. Keyed by the affected uid (doc id == uid; one entry per uid, whichever effect queued\n// it); Admin-SDK-only. Timestamps are epoch-millis numbers (this repo never uses Firestore\n// Timestamps).\n\n/**\n * Which post-commit Auth effect failed and queued the uid:\n * - `accountStatus` — the status claim / `disabled` flag / token revocation after a status change;\n * - `publicDocumentsAcceptedClaim` — the `docsAccepted` claim after a public-document acceptance.\n * An entry without `authEffect` predates the field and is an `accountStatus` entry.\n */\nexport const STATUS_RECONCILE_QUEUE_AUTH_EFFECTS = ['accountStatus', 'publicDocumentsAcceptedClaim'] as const;\nexport const StatusReconcileQueueAuthEffectSchema = z.enum(STATUS_RECONCILE_QUEUE_AUTH_EFFECTS);\nexport type StatusReconcileQueueAuthEffect = z.infer<typeof StatusReconcileQueueAuthEffectSchema>;\n\nconst statusReconcileQueueEntryBase = {\n uid: z.string(),\n enqueuedAt: z.number(),\n lastAttemptAt: z.number().optional(),\n attemptCount: z.number(),\n reason: z.literal('postCommitAuthEffectFailed'),\n};\n\n/** A failed status effect: the drain drives the account toward `targetStatus`. */\nexport const StatusReconcileQueueAccountStatusEntrySchema = z.object({\n ...statusReconcileQueueEntryBase,\n authEffect: z.literal('accountStatus' satisfies StatusReconcileQueueAuthEffect).optional(),\n targetStatus: UserAccountStatusSchema,\n});\nexport type StatusReconcileQueueAccountStatusEntry = z.infer<typeof StatusReconcileQueueAccountStatusEntrySchema>;\n\n/** A failed `docsAccepted` claim write. Strict: it carries no status, so no `targetStatus`. */\nexport const StatusReconcileQueuePublicDocumentsAcceptedClaimEntrySchema = z\n .object({\n ...statusReconcileQueueEntryBase,\n authEffect: z.literal('publicDocumentsAcceptedClaim' satisfies StatusReconcileQueueAuthEffect),\n })\n .strict();\nexport type StatusReconcileQueuePublicDocumentsAcceptedClaimEntry = z.infer<\n typeof StatusReconcileQueuePublicDocumentsAcceptedClaimEntrySchema\n>;\n\nexport const StatusReconcileQueueEntrySchema = z.discriminatedUnion('authEffect', [\n StatusReconcileQueueAccountStatusEntrySchema,\n StatusReconcileQueuePublicDocumentsAcceptedClaimEntrySchema,\n]);\nexport type StatusReconcileQueueEntry = z.infer<typeof StatusReconcileQueueEntrySchema>;\n\n// feedbackAliases/{aliasId} — Console-managed map collapsing a synonym suggestion onto a canonical\n// one; read by submitFeedback, no callable writes it. (firestore.rules §3F / submitFeedback.ts)\nexport const FeedbackAliasSchema = z.object({\n canonicalId: z.string(),\n originalType: z.string(),\n});\nexport type FeedbackAlias = z.infer<typeof FeedbackAliasSchema>;\n\n// feedbackSubmissions/{feedbackType}/userSuggestions/{suggestionId} — an aggregated user\n// suggestion with its deduped submitter list + count. The path nests the feedbackSubmissions +\n// userSuggestions registry segments. (functions/src/utility/submitFeedback.ts)\nexport const UserSuggestionSchema = z.object({\n suggestionText: z.string(),\n count: z.number(),\n submittedBy: z.array(z.object({ userId: z.string() })),\n lastSubmitted: z.number(),\n});\nexport type UserSuggestion = z.infer<typeof UserSuggestionSchema>;\n"]}
@@ -4710,18 +4710,26 @@ export declare const COLLECTION_SCHEMAS: {
4710
4710
  }, z.core.$strip>>;
4711
4711
  lastSubmitted: z.ZodNumber;
4712
4712
  }, z.core.$strip>;
4713
- readonly 'statusReconcileQueue/{uid}': z.ZodObject<{
4714
- uid: z.ZodString;
4715
- enqueuedAt: z.ZodNumber;
4716
- lastAttemptAt: z.ZodOptional<z.ZodNumber>;
4717
- attemptCount: z.ZodNumber;
4713
+ readonly 'statusReconcileQueue/{uid}': z.ZodDiscriminatedUnion<[z.ZodObject<{
4714
+ authEffect: z.ZodOptional<z.ZodLiteral<"accountStatus">>;
4718
4715
  targetStatus: z.ZodEnum<{
4719
4716
  banned: "banned";
4720
4717
  active: "active";
4721
4718
  suspended: "suspended";
4722
4719
  }>;
4720
+ uid: z.ZodString;
4721
+ enqueuedAt: z.ZodNumber;
4722
+ lastAttemptAt: z.ZodOptional<z.ZodNumber>;
4723
+ attemptCount: z.ZodNumber;
4723
4724
  reason: z.ZodLiteral<"postCommitAuthEffectFailed">;
4724
- }, z.core.$strip>;
4725
+ }, z.core.$strip>, z.ZodObject<{
4726
+ authEffect: z.ZodLiteral<"publicDocumentsAcceptedClaim">;
4727
+ uid: z.ZodString;
4728
+ enqueuedAt: z.ZodNumber;
4729
+ lastAttemptAt: z.ZodOptional<z.ZodNumber>;
4730
+ attemptCount: z.ZodNumber;
4731
+ reason: z.ZodLiteral<"postCommitAuthEffectFailed">;
4732
+ }, z.core.$strict>], "authEffect">;
4725
4733
  readonly 'publicDocuments/{documentId}/publicDocumentVersions/{versionId}': z.ZodDiscriminatedUnion<[z.ZodObject<{
4726
4734
  documentId: z.ZodLiteral<"termsOfService">;
4727
4735
  content: z.ZodObject<{
@@ -7185,7 +7193,6 @@ export declare const COLLECTION_SCHEMAS: {
7185
7193
  evidenceScanMemoryBudgetMb: z.ZodNumber;
7186
7194
  rejectArchiveAndPolyglotPayloads: z.ZodBoolean;
7187
7195
  approvedBy: z.ZodLiteral<"operatorLaunchDefault">;
7188
- counselApproved: z.ZodBoolean;
7189
7196
  }, z.core.$strict>;
7190
7197
  readonly '_serverData/privilegedReviewerSecurity': z.ZodObject<{
7191
7198
  requiredSecondFactor: z.ZodLiteral<"passkeyWebAuthn">;
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/registry.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmN7B,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmQkB,CAAC;AAElD,MAAM,MAAM,wBAAwB,GAAG,MAAM,OAAO,kBAAkB,CAAC;AAEvE;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;CAmBiC,CAAC;AAEvE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAOvC,CAAC"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/registry.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmN7B,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmQkB,CAAC;AAElD,MAAM,MAAM,wBAAwB,GAAG,MAAM,OAAO,kBAAkB,CAAC;AAEvE;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;CAmBiC,CAAC;AAEvE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAOvC,CAAC"}
@@ -37,6 +37,8 @@ export declare const SeedPrivacyPageInputSchema: z.ZodObject<{}, z.core.$strict>
37
37
  export type SeedPrivacyPageInput = z.infer<typeof SeedPrivacyPageInputSchema>;
38
38
  export declare const SeedTakeItDownPageCopyInputSchema: z.ZodObject<{}, z.core.$strict>;
39
39
  export type SeedTakeItDownPageCopyInput = z.infer<typeof SeedTakeItDownPageCopyInputSchema>;
40
+ export declare const SeedDmcaPolicyInputSchema: z.ZodObject<{}, z.core.$strict>;
41
+ export type SeedDmcaPolicyInput = z.infer<typeof SeedDmcaPolicyInputSchema>;
40
42
  /** Admin add/remove words on the self-owned curated profanity list (no external sync). */
41
43
  export declare const CurateProfanityListInputSchema: z.ZodObject<{
42
44
  add: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -1 +1 @@
1
- {"version":3,"file":"utility.d.ts","sourceRoot":"","sources":["../../src/schemas/utility.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utility.d.ts","sourceRoot":"","sources":["../../src/schemas/utility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,eAAO,MAAM,kCAAkC;;kBAEpC,CAAC;AACZ,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAK9F,eAAO,MAAM,yBAAyB;;;;EAAuD,CAAC;AAC9F,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,0BAA0B;;;;;;;;;;kCAcrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAI9E,eAAO,MAAM,4BAA4B,iCAAwB,CAAC;AAClE,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF,eAAO,MAAM,gCAAgC,iCAAwB,CAAC;AACtE,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAE1F,eAAO,MAAM,oCAAoC,iCAAwB,CAAC;AAC1E,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oCAAoC,CAAC,CAAC;AAMlG,eAAO,MAAM,iCAAiC,iCAAwB,CAAC;AACvE,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAE5F,eAAO,MAAM,0BAA0B,iCAAwB,CAAC;AAChE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,wBAAwB,iCAAwB,CAAC;AAC9D,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,eAAO,MAAM,0BAA0B,iCAAwB,CAAC;AAChE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,iCAAiC,iCAAwB,CAAC;AACvE,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAE5F,eAAO,MAAM,yBAAyB,iCAAwB,CAAC;AAC/D,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,0FAA0F;AAC1F,eAAO,MAAM,8BAA8B;;;kBAQvC,CAAC;AACL,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF,eAAO,MAAM,8BAA8B;;;kBAGhC,CAAC;AACZ,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF,eAAO,MAAM,yBAAyB;;;;;;;;;kBAG3B,CAAC;AACZ,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,8BAA8B;;kBAEhC,CAAC;AACZ,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF,eAAO,MAAM,gCAAgC;;kBAElC,CAAC;AACZ,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAI1F,eAAO,MAAM,0BAA0B;;iBAErC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAI9E,eAAO,MAAM,iCAAiC;;iBAE5C,CAAC;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAI5F,eAAO,MAAM,+BAA+B;;;;;;iBAS1C,CAAC;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAIxF,eAAO,MAAM,mCAAmC;;;;;iBAQ9C,CAAC;AACH,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC"}
@@ -28,13 +28,16 @@ export const CreateShortLinkInputSchema = z.discriminatedUnion('targetType', [
28
28
  export const SeedProfanityListInputSchema = z.object({}).strict();
29
29
  export const SeedReservedUsernamesInputSchema = z.object({}).strict();
30
30
  export const SeedBlockedFranchiseNamesInputSchema = z.object({}).strict();
31
+ // Public-document seed callables (Ready for Launch tab), one per PublicDocumentId. Each
32
+ // publishes its document's launch content as v1 through the public-document release owner,
33
+ // only while that document has never been published (otherwise a no-op). The input is
34
+ // intentionally empty.
31
35
  export const SeedRulesAndAgreementsInputSchema = z.object({}).strict();
32
36
  export const SeedFuturePlansInputSchema = z.object({}).strict();
33
- // Content-pages migration (DJ ruling 2026-07-06): seed callables for the three
34
- // editable content-page singletons (strict seed-if-empty — doc exists ⇒ no-op).
35
37
  export const SeedTermsPageInputSchema = z.object({}).strict();
36
38
  export const SeedPrivacyPageInputSchema = z.object({}).strict();
37
39
  export const SeedTakeItDownPageCopyInputSchema = z.object({}).strict();
40
+ export const SeedDmcaPolicyInputSchema = z.object({}).strict();
38
41
  /** Admin add/remove words on the self-owned curated profanity list (no external sync). */
39
42
  export const CurateProfanityListInputSchema = z
40
43
  .object({
@@ -1 +1 @@
1
- {"version":3,"file":"utility.js","sourceRoot":"","sources":["../../src/schemas/utility.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport {\n violationIdSchema,\n auditionIdSchema,\n auditionEntryIdSchema,\n commissionListingIdSchema,\n} from './atoms.js';\nimport { MAX_APPEAL_MESSAGE_LENGTH, MAX_FEEDBACK_SUGGESTION_LENGTH, FEEDBACK_TYPES } from '../constants/business.js';\n\nexport const AcceptViolationDecisionInputSchema = z.object({\n violationId: violationIdSchema,\n}).strict();\nexport type AcceptViolationDecisionInput = z.infer<typeof AcceptViolationDecisionInputSchema>;\n\n// Share-target types the short-link system can point at. New system entities (hall items,\n// etc.) slot in by adding a `targetType` literal + its own union member below — no rework\n// of the existing members. Each member carries exactly the id(s) its destination URL needs.\nexport const ShortLinkTargetTypeSchema = z.enum(['audition', 'audition-entry', 'commission']);\nexport type ShortLinkTargetType = z.infer<typeof ShortLinkTargetTypeSchema>;\n\nexport const CreateShortLinkInputSchema = z.discriminatedUnion('targetType', [\n z.object({\n targetType: z.literal('audition'),\n auditionId: auditionIdSchema,\n }).strict(),\n z.object({\n targetType: z.literal('audition-entry'),\n auditionId: auditionIdSchema,\n auditionEntryId: auditionEntryIdSchema,\n }).strict(),\n z.object({\n targetType: z.literal('commission'),\n commissionListingId: commissionListingIdSchema,\n }).strict(),\n]);\nexport type CreateShortLinkInput = z.infer<typeof CreateShortLinkInputSchema>;\n\n// No-input seed callables (Ready for Launch tab). Each prepopulates one system\n// dataset from a canonical backend constant; the input is intentionally empty.\nexport const SeedProfanityListInputSchema = z.object({}).strict();\nexport type SeedProfanityListInput = z.infer<typeof SeedProfanityListInputSchema>;\n\nexport const SeedReservedUsernamesInputSchema = z.object({}).strict();\nexport type SeedReservedUsernamesInput = z.infer<typeof SeedReservedUsernamesInputSchema>;\n\nexport const SeedBlockedFranchiseNamesInputSchema = z.object({}).strict();\nexport type SeedBlockedFranchiseNamesInput = z.infer<typeof SeedBlockedFranchiseNamesInputSchema>;\n\nexport const SeedRulesAndAgreementsInputSchema = z.object({}).strict();\nexport type SeedRulesAndAgreementsInput = z.infer<typeof SeedRulesAndAgreementsInputSchema>;\n\nexport const SeedFuturePlansInputSchema = z.object({}).strict();\nexport type SeedFuturePlansInput = z.infer<typeof SeedFuturePlansInputSchema>;\n\n// Content-pages migration (DJ ruling 2026-07-06): seed callables for the three\n// editable content-page singletons (strict seed-if-empty — doc exists ⇒ no-op).\nexport const SeedTermsPageInputSchema = z.object({}).strict();\nexport type SeedTermsPageInput = z.infer<typeof SeedTermsPageInputSchema>;\n\nexport const SeedPrivacyPageInputSchema = z.object({}).strict();\nexport type SeedPrivacyPageInput = z.infer<typeof SeedPrivacyPageInputSchema>;\n\nexport const SeedTakeItDownPageCopyInputSchema = z.object({}).strict();\nexport type SeedTakeItDownPageCopyInput = z.infer<typeof SeedTakeItDownPageCopyInputSchema>;\n\n/** Admin add/remove words on the self-owned curated profanity list (no external sync). */\nexport const CurateProfanityListInputSchema = z\n .object({\n add: z.array(z.string().min(1).max(64)).max(500).optional(),\n remove: z.array(z.string().min(1).max(64)).max(500).optional(),\n })\n .strict()\n .refine((v) => (v.add?.length ?? 0) + (v.remove?.length ?? 0) > 0, {\n message: 'Provide at least one word to add or remove.',\n });\nexport type CurateProfanityListInput = z.infer<typeof CurateProfanityListInputSchema>;\n\nexport const SubmitContentAppealInputSchema = z.object({\n violationId: violationIdSchema,\n appealMessage: z.string().min(1).max(MAX_APPEAL_MESSAGE_LENGTH),\n}).strict();\nexport type SubmitContentAppealInput = z.infer<typeof SubmitContentAppealInputSchema>;\n\nexport const SubmitFeedbackInputSchema = z.object({\n feedbackType: z.enum(FEEDBACK_TYPES),\n suggestion: z.string().min(1).max(MAX_FEEDBACK_SUGGESTION_LENGTH).regex(/^[a-z]+$/),\n}).strict();\nexport type SubmitFeedbackInput = z.infer<typeof SubmitFeedbackInputSchema>;\n\nexport const TrackShortLinkClickInputSchema = z.object({\n shortId: z.string().min(1).max(64),\n}).strict();\nexport type TrackShortLinkClickInput = z.infer<typeof TrackShortLinkClickInputSchema>;\n\nexport const MarkAdminDispatchReadInputSchema = z.object({\n adminDispatchId: z.string().min(1).max(128),\n}).strict();\nexport type MarkAdminDispatchReadInput = z.infer<typeof MarkAdminDispatchReadInputSchema>;\n\n// Admin/jr-admin deletes a short link (`deleteShortLink`). Non-strict posture is carried\n// faithfully from the source callable.\nexport const DeleteShortLinkInputSchema = z.object({\n shortId: z.string().min(1, 'shortId is required'),\n});\nexport type DeleteShortLinkInput = z.infer<typeof DeleteShortLinkInputSchema>;\n\n// --- Authoritative mutation RESULTS (non-strict server → client posture) ---\n\nexport const MarkAdminDispatchReadResultSchema = z.object({\n success: z.literal(true),\n});\nexport type MarkAdminDispatchReadResult = z.infer<typeof MarkAdminDispatchReadResultSchema>;\n\n// submitContentAppeal — the transaction sets appealStatus 'pending' + appealedAt = now on\n// the violation; both are known at commit and let the client patch its violations list.\nexport const SubmitContentAppealResultSchema = z.object({\n success: z.literal(true),\n violationId: violationIdSchema,\n /** The violation's appeal state after commit. */\n appealStatus: z.literal('pending'),\n appealedAt: z.number(),\n /** Operation-receipt audit id — the `content.appealSubmitted` event written in the same\n * transaction. Optional/additive; the domain id (`violationId`) is already carried above. */\n auditEventId: z.string().min(1).optional(),\n});\nexport type SubmitContentAppealResult = z.infer<typeof SubmitContentAppealResultSchema>;\n\n// acceptViolationDecision — the violation record (and its pendingMedia/archive docs) are\n// removed at commit; the client drops the row from its violation + pendingMedia caches.\nexport const AcceptViolationDecisionResultSchema = z.object({\n success: z.literal(true),\n violationId: violationIdSchema,\n /** True when the record was already gone (idempotent accept). */\n alreadyRemoved: z.boolean(),\n /** Operation-receipt audit id — the `content.violationAccepted` event written in the same\n * transaction. Optional/additive; the domain id (`violationId`) is already carried above. */\n auditEventId: z.string().min(1).optional(),\n});\nexport type AcceptViolationDecisionResult = z.infer<typeof AcceptViolationDecisionResultSchema>;\n\n"]}
1
+ {"version":3,"file":"utility.js","sourceRoot":"","sources":["../../src/schemas/utility.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport {\n violationIdSchema,\n auditionIdSchema,\n auditionEntryIdSchema,\n commissionListingIdSchema,\n} from './atoms.js';\nimport { MAX_APPEAL_MESSAGE_LENGTH, MAX_FEEDBACK_SUGGESTION_LENGTH, FEEDBACK_TYPES } from '../constants/business.js';\n\nexport const AcceptViolationDecisionInputSchema = z.object({\n violationId: violationIdSchema,\n}).strict();\nexport type AcceptViolationDecisionInput = z.infer<typeof AcceptViolationDecisionInputSchema>;\n\n// Share-target types the short-link system can point at. New system entities (hall items,\n// etc.) slot in by adding a `targetType` literal + its own union member below — no rework\n// of the existing members. Each member carries exactly the id(s) its destination URL needs.\nexport const ShortLinkTargetTypeSchema = z.enum(['audition', 'audition-entry', 'commission']);\nexport type ShortLinkTargetType = z.infer<typeof ShortLinkTargetTypeSchema>;\n\nexport const CreateShortLinkInputSchema = z.discriminatedUnion('targetType', [\n z.object({\n targetType: z.literal('audition'),\n auditionId: auditionIdSchema,\n }).strict(),\n z.object({\n targetType: z.literal('audition-entry'),\n auditionId: auditionIdSchema,\n auditionEntryId: auditionEntryIdSchema,\n }).strict(),\n z.object({\n targetType: z.literal('commission'),\n commissionListingId: commissionListingIdSchema,\n }).strict(),\n]);\nexport type CreateShortLinkInput = z.infer<typeof CreateShortLinkInputSchema>;\n\n// No-input seed callables (Ready for Launch tab). Each prepopulates one system\n// dataset from a canonical backend constant; the input is intentionally empty.\nexport const SeedProfanityListInputSchema = z.object({}).strict();\nexport type SeedProfanityListInput = z.infer<typeof SeedProfanityListInputSchema>;\n\nexport const SeedReservedUsernamesInputSchema = z.object({}).strict();\nexport type SeedReservedUsernamesInput = z.infer<typeof SeedReservedUsernamesInputSchema>;\n\nexport const SeedBlockedFranchiseNamesInputSchema = z.object({}).strict();\nexport type SeedBlockedFranchiseNamesInput = z.infer<typeof SeedBlockedFranchiseNamesInputSchema>;\n\n// Public-document seed callables (Ready for Launch tab), one per PublicDocumentId. Each\n// publishes its document's launch content as v1 through the public-document release owner,\n// only while that document has never been published (otherwise a no-op). The input is\n// intentionally empty.\nexport const SeedRulesAndAgreementsInputSchema = z.object({}).strict();\nexport type SeedRulesAndAgreementsInput = z.infer<typeof SeedRulesAndAgreementsInputSchema>;\n\nexport const SeedFuturePlansInputSchema = z.object({}).strict();\nexport type SeedFuturePlansInput = z.infer<typeof SeedFuturePlansInputSchema>;\n\nexport const SeedTermsPageInputSchema = z.object({}).strict();\nexport type SeedTermsPageInput = z.infer<typeof SeedTermsPageInputSchema>;\n\nexport const SeedPrivacyPageInputSchema = z.object({}).strict();\nexport type SeedPrivacyPageInput = z.infer<typeof SeedPrivacyPageInputSchema>;\n\nexport const SeedTakeItDownPageCopyInputSchema = z.object({}).strict();\nexport type SeedTakeItDownPageCopyInput = z.infer<typeof SeedTakeItDownPageCopyInputSchema>;\n\nexport const SeedDmcaPolicyInputSchema = z.object({}).strict();\nexport type SeedDmcaPolicyInput = z.infer<typeof SeedDmcaPolicyInputSchema>;\n\n/** Admin add/remove words on the self-owned curated profanity list (no external sync). */\nexport const CurateProfanityListInputSchema = z\n .object({\n add: z.array(z.string().min(1).max(64)).max(500).optional(),\n remove: z.array(z.string().min(1).max(64)).max(500).optional(),\n })\n .strict()\n .refine((v) => (v.add?.length ?? 0) + (v.remove?.length ?? 0) > 0, {\n message: 'Provide at least one word to add or remove.',\n });\nexport type CurateProfanityListInput = z.infer<typeof CurateProfanityListInputSchema>;\n\nexport const SubmitContentAppealInputSchema = z.object({\n violationId: violationIdSchema,\n appealMessage: z.string().min(1).max(MAX_APPEAL_MESSAGE_LENGTH),\n}).strict();\nexport type SubmitContentAppealInput = z.infer<typeof SubmitContentAppealInputSchema>;\n\nexport const SubmitFeedbackInputSchema = z.object({\n feedbackType: z.enum(FEEDBACK_TYPES),\n suggestion: z.string().min(1).max(MAX_FEEDBACK_SUGGESTION_LENGTH).regex(/^[a-z]+$/),\n}).strict();\nexport type SubmitFeedbackInput = z.infer<typeof SubmitFeedbackInputSchema>;\n\nexport const TrackShortLinkClickInputSchema = z.object({\n shortId: z.string().min(1).max(64),\n}).strict();\nexport type TrackShortLinkClickInput = z.infer<typeof TrackShortLinkClickInputSchema>;\n\nexport const MarkAdminDispatchReadInputSchema = z.object({\n adminDispatchId: z.string().min(1).max(128),\n}).strict();\nexport type MarkAdminDispatchReadInput = z.infer<typeof MarkAdminDispatchReadInputSchema>;\n\n// Admin/jr-admin deletes a short link (`deleteShortLink`). Non-strict posture is carried\n// faithfully from the source callable.\nexport const DeleteShortLinkInputSchema = z.object({\n shortId: z.string().min(1, 'shortId is required'),\n});\nexport type DeleteShortLinkInput = z.infer<typeof DeleteShortLinkInputSchema>;\n\n// --- Authoritative mutation RESULTS (non-strict server → client posture) ---\n\nexport const MarkAdminDispatchReadResultSchema = z.object({\n success: z.literal(true),\n});\nexport type MarkAdminDispatchReadResult = z.infer<typeof MarkAdminDispatchReadResultSchema>;\n\n// submitContentAppeal — the transaction sets appealStatus 'pending' + appealedAt = now on\n// the violation; both are known at commit and let the client patch its violations list.\nexport const SubmitContentAppealResultSchema = z.object({\n success: z.literal(true),\n violationId: violationIdSchema,\n /** The violation's appeal state after commit. */\n appealStatus: z.literal('pending'),\n appealedAt: z.number(),\n /** Operation-receipt audit id — the `content.appealSubmitted` event written in the same\n * transaction. Optional/additive; the domain id (`violationId`) is already carried above. */\n auditEventId: z.string().min(1).optional(),\n});\nexport type SubmitContentAppealResult = z.infer<typeof SubmitContentAppealResultSchema>;\n\n// acceptViolationDecision — the violation record (and its pendingMedia/archive docs) are\n// removed at commit; the client drops the row from its violation + pendingMedia caches.\nexport const AcceptViolationDecisionResultSchema = z.object({\n success: z.literal(true),\n violationId: violationIdSchema,\n /** True when the record was already gone (idempotent accept). */\n alreadyRemoved: z.boolean(),\n /** Operation-receipt audit id — the `content.violationAccepted` event written in the same\n * transaction. Optional/additive; the domain id (`violationId`) is already carried above. */\n auditEventId: z.string().min(1).optional(),\n});\nexport type AcceptViolationDecisionResult = z.infer<typeof AcceptViolationDecisionResultSchema>;\n\n"]}
@@ -1,9 +1,12 @@
1
1
  import { type PublicDocumentId } from '../constants/public-documents.js';
2
2
  import type { PublicDocumentAcceptance, PublicDocumentContent, PublicDocumentProjection, PublicDocumentVersionBlock, PublicDocumentVersionRef } from '../doc-schemas/public-documents.js';
3
+ import type { UserPrivateData } from '../doc-schemas/user.js';
3
4
  /** The version block before any release: every document at version 0, nothing required. */
4
5
  export declare const EMPTY_PUBLIC_DOCUMENT_VERSION_BLOCK: PublicDocumentVersionBlock;
5
6
  /** A document's current published version; 0 when it has never been published. */
6
7
  export declare function currentPublicDocumentVersion(block: PublicDocumentVersionBlock | undefined, documentId: PublicDocumentId): number;
8
+ /** The latest version of a document a release required acceptance of; 0 when none has. */
9
+ export declare function requiredPublicDocumentVersion(block: PublicDocumentVersionBlock | undefined, documentId: PublicDocumentId): number;
7
10
  /** The required-acceptance level in force; 0 when nothing has ever required acceptance. */
8
11
  export declare function requiredPublicDocumentAcceptanceLevel(block: PublicDocumentVersionBlock | undefined): number;
9
12
  /** The level a person has accepted; 0 when they have accepted nothing. */
@@ -19,6 +22,17 @@ export declare function isPublicDocumentAcceptanceRequired(block: PublicDocument
19
22
  * expects back.
20
23
  */
21
24
  export declare function changedPublicDocuments(block: PublicDocumentVersionBlock | undefined, acceptance: PublicDocumentAcceptance | undefined): PublicDocumentVersionRef[];
25
+ /** The two private-doc fields the Square agreements card records. */
26
+ export type SquareStreetzAgreementsRecord = Pick<UserPrivateData, 'squareStreetzAgreementsDate' | 'squareStreetzAgreementsVersion'>;
27
+ /**
28
+ * True when the person's Square agreements still stand: they recorded an acceptance date AND
29
+ * the Rules & Agreements version they accepted is at or above the latest version a release
30
+ * REQUIRED acceptance of. The card incorporates the Rules page by reference, so a Rules release
31
+ * that required acceptance asks again; one that did not never does. The composer (client) and
32
+ * every Square post path (server) decide with this one rule. A missing version block means no
33
+ * Rules release has required acceptance yet.
34
+ */
35
+ export declare function squareStreetzAgreementsSatisfied(privateData: SquareStreetzAgreementsRecord | null | undefined, block: PublicDocumentVersionBlock | undefined): boolean;
22
36
  /**
23
37
  * True when two document/version lists name the same pairs (order-insensitive). The acceptance
24
38
  * callable compares the versions the prompt showed with `changedPublicDocuments` now; any
@@ -1 +1 @@
1
- {"version":3,"file":"public-documents.d.ts","sourceRoot":"","sources":["../../src/utils/public-documents.ts"],"names":[],"mappings":"AAKA,OAAO,EAAuB,KAAK,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAC9F,OAAO,KAAK,EACV,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,EAC1B,wBAAwB,EAEzB,MAAM,oCAAoC,CAAC;AAE5C,2FAA2F;AAC3F,eAAO,MAAM,mCAAmC,EAAE,0BAGlB,CAAC;AAEjC,kFAAkF;AAClF,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,0BAA0B,GAAG,SAAS,EAC7C,UAAU,EAAE,gBAAgB,GAC3B,MAAM,CAER;AAED,2FAA2F;AAC3F,wBAAgB,qCAAqC,CAAC,KAAK,EAAE,0BAA0B,GAAG,SAAS,GAAG,MAAM,CAE3G;AAED,0EAA0E;AAC1E,wBAAgB,qCAAqC,CAAC,UAAU,EAAE,wBAAwB,GAAG,SAAS,GAAG,MAAM,CAE9G;AAED,0EAA0E;AAC1E,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,wBAAwB,GAAG,SAAS,EAChD,UAAU,EAAE,gBAAgB,GAC3B,MAAM,CAER;AAED,8FAA8F;AAC9F,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,0BAA0B,GAAG,SAAS,EAC7C,UAAU,EAAE,wBAAwB,GAAG,SAAS,GAC/C,OAAO,CAET;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,0BAA0B,GAAG,SAAS,EAC7C,UAAU,EAAE,wBAAwB,GAAG,SAAS,GAC/C,wBAAwB,EAAE,CAO5B;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,CAAC,EAAE,SAAS,wBAAwB,EAAE,EACtC,CAAC,EAAE,SAAS,wBAAwB,EAAE,GACrC,OAAO,CAMT;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,0BAA0B,GAAG,SAAS,EAC7C,QAAQ,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,yBAAyB,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACzE,wBAAwB,CAc1B;AAED,kDAAkD;AAClD,MAAM,WAAW,yBAAyB;IACxC,kCAAkC;IAClC,KAAK,EAAE,0BAA0B,CAAC;IAClC,gFAAgF;IAChF,SAAS,EAAE,wBAAwB,EAAE,CAAC;IACtC,wDAAwD;IACxD,uBAAuB,EAAE,MAAM,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,0BAA0B,GAAG,SAAS,EAC7C,WAAW,EAAE,SAAS,gBAAgB,EAAE,EACxC,iBAAiB,EAAE,OAAO,GACzB,yBAAyB,CA4B3B;AAED,gGAAgG;AAChG,wBAAgB,6BAA6B,CAAC,CAAC,SAAS,gBAAgB,EACtE,OAAO,EAAE,qBAAqB,CAAC,CAAC,CAAC,EACjC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAClB,wBAAwB,CAAC,CAAC,CAAC,CAE7B;AAeD;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,SAAS,gBAAgB,EACpE,CAAC,EAAE,qBAAqB,CAAC,CAAC,CAAC,EAC3B,CAAC,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAC1B,OAAO,CAET"}
1
+ {"version":3,"file":"public-documents.d.ts","sourceRoot":"","sources":["../../src/utils/public-documents.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@
3
3
  // acceptance callable (server) make. One owner, so the prompt and the server can never
4
4
  // disagree about what changed or what is required.
5
5
  import { PUBLIC_DOCUMENT_IDS } from '../constants/public-documents.js';
6
+ import { SPECIAL_DOCS } from '../paths/collections.js';
6
7
  /** The version block before any release: every document at version 0, nothing required. */
7
8
  export const EMPTY_PUBLIC_DOCUMENT_VERSION_BLOCK = Object.freeze({
8
9
  documents: Object.freeze({}),
@@ -12,6 +13,10 @@ export const EMPTY_PUBLIC_DOCUMENT_VERSION_BLOCK = Object.freeze({
12
13
  export function currentPublicDocumentVersion(block, documentId) {
13
14
  return block?.documents[documentId]?.currentVersion ?? 0;
14
15
  }
16
+ /** The latest version of a document a release required acceptance of; 0 when none has. */
17
+ export function requiredPublicDocumentVersion(block, documentId) {
18
+ return block?.documents[documentId]?.requiredVersion ?? 0;
19
+ }
15
20
  /** The required-acceptance level in force; 0 when nothing has ever required acceptance. */
16
21
  export function requiredPublicDocumentAcceptanceLevel(block) {
17
22
  return block?.requiredAcceptanceLevel ?? 0;
@@ -43,6 +48,21 @@ export function changedPublicDocuments(block, acceptance) {
43
48
  }
44
49
  return changed;
45
50
  }
51
+ /**
52
+ * True when the person's Square agreements still stand: they recorded an acceptance date AND
53
+ * the Rules & Agreements version they accepted is at or above the latest version a release
54
+ * REQUIRED acceptance of. The card incorporates the Rules page by reference, so a Rules release
55
+ * that required acceptance asks again; one that did not never does. The composer (client) and
56
+ * every Square post path (server) decide with this one rule. A missing version block means no
57
+ * Rules release has required acceptance yet.
58
+ */
59
+ export function squareStreetzAgreementsSatisfied(privateData, block) {
60
+ const acceptedAt = privateData?.squareStreetzAgreementsDate;
61
+ const acceptedRulesVersion = privateData?.squareStreetzAgreementsVersion;
62
+ return (typeof acceptedAt === 'number' &&
63
+ typeof acceptedRulesVersion === 'number' &&
64
+ acceptedRulesVersion >= requiredPublicDocumentVersion(block, SPECIAL_DOCS.RULES_AND_AGREEMENTS));
65
+ }
46
66
  /**
47
67
  * True when two document/version lists name the same pairs (order-insensitive). The acceptance
48
68
  * callable compares the versions the prompt showed with `changedPublicDocuments` now; any
@@ -1 +1 @@
1
- {"version":3,"file":"public-documents.js","sourceRoot":"","sources":["../../src/utils/public-documents.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,uFAAuF;AACvF,uFAAuF;AACvF,mDAAmD;AAEnD,OAAO,EAAE,mBAAmB,EAAyB,MAAM,kCAAkC,CAAC;AAU9F,2FAA2F;AAC3F,MAAM,CAAC,MAAM,mCAAmC,GAA+B,MAAM,CAAC,MAAM,CAAC;IAC3F,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;IAC5B,uBAAuB,EAAE,CAAC;CAC3B,CAA+B,CAAC;AAEjC,kFAAkF;AAClF,MAAM,UAAU,4BAA4B,CAC1C,KAA6C,EAC7C,UAA4B;IAE5B,OAAO,KAAK,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,cAAc,IAAI,CAAC,CAAC;AAC3D,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,qCAAqC,CAAC,KAA6C;IACjG,OAAO,KAAK,EAAE,uBAAuB,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,qCAAqC,CAAC,UAAgD;IACpG,OAAO,UAAU,EAAE,aAAa,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,6BAA6B,CAC3C,UAAgD,EAChD,UAA4B;IAE5B,OAAO,UAAU,EAAE,gBAAgB,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AACvD,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,kCAAkC,CAChD,KAA6C,EAC7C,UAAgD;IAEhD,OAAO,qCAAqC,CAAC,KAAK,CAAC,GAAG,qCAAqC,CAAC,UAAU,CAAC,CAAC;AAC1G,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CACpC,KAA6C,EAC7C,UAAgD;IAEhD,MAAM,OAAO,GAA+B,EAAE,CAAC;IAC/C,KAAK,MAAM,UAAU,IAAI,mBAAmB,EAAE,CAAC;QAC7C,MAAM,OAAO,GAAG,4BAA4B,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAChE,IAAI,OAAO,GAAG,6BAA6B,CAAC,UAAU,EAAE,UAAU,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;IAC7G,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,CAAsC,EACtC,CAAsC;IAEtC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,MAAM,GAAG,GAAG,CAAC,GAA6B,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;IAClF,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACjC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACzC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,+BAA+B,CAC7C,KAA6C,EAC7C,QAA0E;IAE1E,MAAM,gBAAgB,GAAiD,EAAE,CAAC;IAC1E,KAAK,MAAM,UAAU,IAAI,mBAAmB,EAAE,CAAC;QAC7C,MAAM,OAAO,GAAG,4BAA4B,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAChE,IAAI,OAAO,GAAG,CAAC;YAAE,gBAAgB,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC;IAC1D,CAAC;IACD,OAAO;QACL,gBAAgB;QAChB,aAAa,EAAE,qCAAqC,CAAC,KAAK,CAAC;QAC3D,GAAG,CAAC,QAAQ,CAAC,yBAAyB,KAAK,IAAI;YAC7C,CAAC,CAAC,EAAE,yBAAyB,EAAE,QAAQ,CAAC,yBAAyB,EAAE;YACnE,CAAC,CAAC,EAAE,CAAC;QACP,UAAU,EAAE,QAAQ,CAAC,UAAU;KAChC,CAAC;AACJ,CAAC;AAYD;;;;;;GAMG;AACH,MAAM,UAAU,yBAAyB,CACvC,KAA6C,EAC7C,WAAwC,EACxC,iBAA0B;IAE1B,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAC/F,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;IACtC,IAAI,QAAQ,CAAC,IAAI,KAAK,WAAW,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAEjG,MAAM,aAAa,GAAG,qCAAqC,CAAC,KAAK,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,iBAAiB,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;IACxE,MAAM,aAAa,GAAkE;QACnF,GAAG,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;KAC5B,CAAC;IACF,MAAM,QAAQ,GAA+B,EAAE,CAAC;IAEhD,KAAK,MAAM,UAAU,IAAI,mBAAmB,EAAE,CAAC;QAC7C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,SAAS;QACxC,MAAM,QAAQ,GAAG,KAAK,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,CAAC,QAAQ,EAAE,cAAc,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACpD,aAAa,CAAC,UAAU,CAAC,GAAG;YAC1B,cAAc,EAAE,OAAO;YACvB,eAAe,EAAE,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,eAAe,IAAI,CAAC,CAAC;SAChF,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,OAAO;QACL,KAAK,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,uBAAuB,EAAE,SAAS,EAAE;QACvE,SAAS,EAAE,QAAQ;QACnB,uBAAuB,EAAE,SAAS;KACnC,CAAC;AACJ,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,6BAA6B,CAC3C,OAAiC,EACjC,OAAe,EACf,WAAmB;IAEnB,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AAC3D,CAAC;AAED,yFAAyF;AACzF,0FAA0F;AAC1F,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAC3E,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC;aAC7D,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC;aAClC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpD,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAC9F,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CACzC,CAA2B,EAC3B,CAA2B;IAE3B,OAAO,aAAa,CAAC,CAAC,CAAC,KAAK,aAAa,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC","sourcesContent":["// Pure rules of the versioned public-document system — the version math the one publish\n// transaction applies, and the comparisons both the acceptance prompt (client) and the\n// acceptance callable (server) make. One owner, so the prompt and the server can never\n// disagree about what changed or what is required.\n\nimport { PUBLIC_DOCUMENT_IDS, type PublicDocumentId } from '../constants/public-documents.js';\nimport type {\n PublicDocumentAcceptance,\n PublicDocumentContent,\n PublicDocumentProjection,\n PublicDocumentVersionBlock,\n PublicDocumentVersionRef,\n PublicDocumentVersionState,\n} from '../doc-schemas/public-documents.js';\n\n/** The version block before any release: every document at version 0, nothing required. */\nexport const EMPTY_PUBLIC_DOCUMENT_VERSION_BLOCK: PublicDocumentVersionBlock = Object.freeze({\n documents: Object.freeze({}),\n requiredAcceptanceLevel: 0,\n}) as PublicDocumentVersionBlock;\n\n/** A document's current published version; 0 when it has never been published. */\nexport function currentPublicDocumentVersion(\n block: PublicDocumentVersionBlock | undefined,\n documentId: PublicDocumentId,\n): number {\n return block?.documents[documentId]?.currentVersion ?? 0;\n}\n\n/** The required-acceptance level in force; 0 when nothing has ever required acceptance. */\nexport function requiredPublicDocumentAcceptanceLevel(block: PublicDocumentVersionBlock | undefined): number {\n return block?.requiredAcceptanceLevel ?? 0;\n}\n\n/** The level a person has accepted; 0 when they have accepted nothing. */\nexport function acceptedPublicDocumentAcceptanceLevel(acceptance: PublicDocumentAcceptance | undefined): number {\n return acceptance?.acceptedLevel ?? 0;\n}\n\n/** A document's accepted version; 0 when the person never accepted it. */\nexport function acceptedPublicDocumentVersion(\n acceptance: PublicDocumentAcceptance | undefined,\n documentId: PublicDocumentId,\n): number {\n return acceptance?.documentVersions[documentId] ?? 0;\n}\n\n/** True when the person must accept before continuing: the required level is above theirs. */\nexport function isPublicDocumentAcceptanceRequired(\n block: PublicDocumentVersionBlock | undefined,\n acceptance: PublicDocumentAcceptance | undefined,\n): boolean {\n return requiredPublicDocumentAcceptanceLevel(block) > acceptedPublicDocumentAcceptanceLevel(acceptance);\n}\n\n/**\n * Every document whose CURRENT version is newer than the one the person accepted — including\n * changes from releases that did not require acceptance — at its current version, in canonical\n * order. This is exactly the list the acceptance prompt shows and the acceptance callable\n * expects back.\n */\nexport function changedPublicDocuments(\n block: PublicDocumentVersionBlock | undefined,\n acceptance: PublicDocumentAcceptance | undefined,\n): PublicDocumentVersionRef[] {\n const changed: PublicDocumentVersionRef[] = [];\n for (const documentId of PUBLIC_DOCUMENT_IDS) {\n const version = currentPublicDocumentVersion(block, documentId);\n if (version > acceptedPublicDocumentVersion(acceptance, documentId)) changed.push({ documentId, version });\n }\n return changed;\n}\n\n/**\n * True when two document/version lists name the same pairs (order-insensitive). The acceptance\n * callable compares the versions the prompt showed with `changedPublicDocuments` now; any\n * difference means a publish raced the prompt, so it refreshes and asks again.\n */\nexport function samePublicDocumentVersions(\n a: readonly PublicDocumentVersionRef[],\n b: readonly PublicDocumentVersionRef[],\n): boolean {\n if (a.length !== b.length) return false;\n const key = (ref: PublicDocumentVersionRef) => `${ref.documentId}@${ref.version}`;\n const left = new Set(a.map(key));\n if (left.size !== a.length) return false;\n return b.every((ref) => left.has(key(ref)));\n}\n\n/**\n * The summary a person holds after accepting everything current — every published document at\n * its current version and the current required level. Registration and the acceptance callable\n * both write exactly this. `legalReviewNoticeRevision` is the active notice revision, or null\n * while the notice is off (then it is not recorded).\n */\nexport function publicDocumentAcceptanceSummary(\n block: PublicDocumentVersionBlock | undefined,\n recorded: { acceptedAt: number; legalReviewNoticeRevision: string | null },\n): PublicDocumentAcceptance {\n const documentVersions: PublicDocumentAcceptance['documentVersions'] = {};\n for (const documentId of PUBLIC_DOCUMENT_IDS) {\n const version = currentPublicDocumentVersion(block, documentId);\n if (version > 0) documentVersions[documentId] = version;\n }\n return {\n documentVersions,\n acceptedLevel: requiredPublicDocumentAcceptanceLevel(block),\n ...(recorded.legalReviewNoticeRevision !== null\n ? { legalReviewNoticeRevision: recorded.legalReviewNoticeRevision }\n : {}),\n acceptedAt: recorded.acceptedAt,\n };\n}\n\n/** What one release does to the version block. */\nexport interface PublicDocumentReleasePlan {\n /** The version block to write. */\n block: PublicDocumentVersionBlock;\n /** Each released document at its newly assigned version, in canonical order. */\n documents: PublicDocumentVersionRef[];\n /** The required-acceptance level after this release. */\n requiredAcceptanceLevel: number;\n}\n\n/**\n * Plan a release: each included document moves to its next whole-number version; when the\n * release requires acceptance, each also becomes that document's required version and the\n * required level rises by exactly one. Documents not in the release are untouched. Pure — the\n * publish transaction reads the block, plans, then writes the versions, projections, block,\n * release record, and audit event together. Throws on an empty or duplicated document list.\n */\nexport function planPublicDocumentRelease(\n block: PublicDocumentVersionBlock | undefined,\n documentIds: readonly PublicDocumentId[],\n requireAcceptance: boolean,\n): PublicDocumentReleasePlan {\n if (documentIds.length === 0) throw new Error('A release must include at least one document.');\n const included = new Set(documentIds);\n if (included.size !== documentIds.length) throw new Error('A release lists each document once.');\n\n const previousLevel = requiredPublicDocumentAcceptanceLevel(block);\n const nextLevel = requireAcceptance ? previousLevel + 1 : previousLevel;\n const nextDocuments: Partial<Record<PublicDocumentId, PublicDocumentVersionState>> = {\n ...(block?.documents ?? {}),\n };\n const released: PublicDocumentVersionRef[] = [];\n\n for (const documentId of PUBLIC_DOCUMENT_IDS) {\n if (!included.has(documentId)) continue;\n const previous = block?.documents[documentId];\n const version = (previous?.currentVersion ?? 0) + 1;\n nextDocuments[documentId] = {\n currentVersion: version,\n requiredVersion: requireAcceptance ? version : (previous?.requiredVersion ?? 0),\n };\n released.push({ documentId, version });\n }\n\n return {\n block: { documents: nextDocuments, requiredAcceptanceLevel: nextLevel },\n documents: released,\n requiredAcceptanceLevel: nextLevel,\n };\n}\n\n/** The current projection the publish writes for a document: its content, version, and time. */\nexport function buildPublicDocumentProjection<D extends PublicDocumentId>(\n content: PublicDocumentContent<D>,\n version: number,\n publishedAt: number,\n): PublicDocumentProjection<D> {\n return { ...content, version, lastUpdated: publishedAt };\n}\n\n// Key-order-insensitive canonical form of JSON-like content (strings, numbers, booleans,\n// null, arrays, plain objects). An `undefined` object field is the same as an absent one.\nfunction canonicalJson(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(canonicalJson).join(',')}]`;\n if (value !== null && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n .filter(([, v]) => v !== undefined)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson(v)}`).join(',')}}`;\n }\n return JSON.stringify(value) ?? 'null';\n}\n\n/**\n * True when two contents of the same document are the same words and structure (field order\n * ignored). The publish rejects a working copy equal to the current version, and the Admin\n * release form keeps Publish disabled for one.\n */\nexport function publicDocumentContentEquals<D extends PublicDocumentId>(\n a: PublicDocumentContent<D>,\n b: PublicDocumentContent<D>,\n): boolean {\n return canonicalJson(a) === canonicalJson(b);\n}\n"]}
1
+ {"version":3,"file":"public-documents.js","sourceRoot":"","sources":["../../src/utils/public-documents.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,uFAAuF;AACvF,uFAAuF;AACvF,mDAAmD;AAEnD,OAAO,EAAE,mBAAmB,EAAyB,MAAM,kCAAkC,CAAC;AAC9F,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAWvD,2FAA2F;AAC3F,MAAM,CAAC,MAAM,mCAAmC,GAA+B,MAAM,CAAC,MAAM,CAAC;IAC3F,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;IAC5B,uBAAuB,EAAE,CAAC;CAC3B,CAA+B,CAAC;AAEjC,kFAAkF;AAClF,MAAM,UAAU,4BAA4B,CAC1C,KAA6C,EAC7C,UAA4B;IAE5B,OAAO,KAAK,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,cAAc,IAAI,CAAC,CAAC;AAC3D,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,6BAA6B,CAC3C,KAA6C,EAC7C,UAA4B;IAE5B,OAAO,KAAK,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,eAAe,IAAI,CAAC,CAAC;AAC5D,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,qCAAqC,CAAC,KAA6C;IACjG,OAAO,KAAK,EAAE,uBAAuB,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,qCAAqC,CAAC,UAAgD;IACpG,OAAO,UAAU,EAAE,aAAa,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,6BAA6B,CAC3C,UAAgD,EAChD,UAA4B;IAE5B,OAAO,UAAU,EAAE,gBAAgB,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AACvD,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,kCAAkC,CAChD,KAA6C,EAC7C,UAAgD;IAEhD,OAAO,qCAAqC,CAAC,KAAK,CAAC,GAAG,qCAAqC,CAAC,UAAU,CAAC,CAAC;AAC1G,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CACpC,KAA6C,EAC7C,UAAgD;IAEhD,MAAM,OAAO,GAA+B,EAAE,CAAC;IAC/C,KAAK,MAAM,UAAU,IAAI,mBAAmB,EAAE,CAAC;QAC7C,MAAM,OAAO,GAAG,4BAA4B,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAChE,IAAI,OAAO,GAAG,6BAA6B,CAAC,UAAU,EAAE,UAAU,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;IAC7G,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAQD;;;;;;;GAOG;AACH,MAAM,UAAU,gCAAgC,CAC9C,WAA6D,EAC7D,KAA6C;IAE7C,MAAM,UAAU,GAAG,WAAW,EAAE,2BAA2B,CAAC;IAC5D,MAAM,oBAAoB,GAAG,WAAW,EAAE,8BAA8B,CAAC;IACzE,OAAO,CACL,OAAO,UAAU,KAAK,QAAQ;QAC9B,OAAO,oBAAoB,KAAK,QAAQ;QACxC,oBAAoB,IAAI,6BAA6B,CAAC,KAAK,EAAE,YAAY,CAAC,oBAAoB,CAAC,CAChG,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,CAAsC,EACtC,CAAsC;IAEtC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,MAAM,GAAG,GAAG,CAAC,GAA6B,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;IAClF,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACjC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACzC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,+BAA+B,CAC7C,KAA6C,EAC7C,QAA0E;IAE1E,MAAM,gBAAgB,GAAiD,EAAE,CAAC;IAC1E,KAAK,MAAM,UAAU,IAAI,mBAAmB,EAAE,CAAC;QAC7C,MAAM,OAAO,GAAG,4BAA4B,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAChE,IAAI,OAAO,GAAG,CAAC;YAAE,gBAAgB,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC;IAC1D,CAAC;IACD,OAAO;QACL,gBAAgB;QAChB,aAAa,EAAE,qCAAqC,CAAC,KAAK,CAAC;QAC3D,GAAG,CAAC,QAAQ,CAAC,yBAAyB,KAAK,IAAI;YAC7C,CAAC,CAAC,EAAE,yBAAyB,EAAE,QAAQ,CAAC,yBAAyB,EAAE;YACnE,CAAC,CAAC,EAAE,CAAC;QACP,UAAU,EAAE,QAAQ,CAAC,UAAU;KAChC,CAAC;AACJ,CAAC;AAYD;;;;;;GAMG;AACH,MAAM,UAAU,yBAAyB,CACvC,KAA6C,EAC7C,WAAwC,EACxC,iBAA0B;IAE1B,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAC/F,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;IACtC,IAAI,QAAQ,CAAC,IAAI,KAAK,WAAW,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAEjG,MAAM,aAAa,GAAG,qCAAqC,CAAC,KAAK,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,iBAAiB,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;IACxE,MAAM,aAAa,GAAkE;QACnF,GAAG,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;KAC5B,CAAC;IACF,MAAM,QAAQ,GAA+B,EAAE,CAAC;IAEhD,KAAK,MAAM,UAAU,IAAI,mBAAmB,EAAE,CAAC;QAC7C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,SAAS;QACxC,MAAM,QAAQ,GAAG,KAAK,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,CAAC,QAAQ,EAAE,cAAc,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACpD,aAAa,CAAC,UAAU,CAAC,GAAG;YAC1B,cAAc,EAAE,OAAO;YACvB,eAAe,EAAE,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,eAAe,IAAI,CAAC,CAAC;SAChF,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,OAAO;QACL,KAAK,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,uBAAuB,EAAE,SAAS,EAAE;QACvE,SAAS,EAAE,QAAQ;QACnB,uBAAuB,EAAE,SAAS;KACnC,CAAC;AACJ,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,6BAA6B,CAC3C,OAAiC,EACjC,OAAe,EACf,WAAmB;IAEnB,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AAC3D,CAAC;AAED,yFAAyF;AACzF,0FAA0F;AAC1F,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAC3E,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC;aAC7D,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC;aAClC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpD,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAC9F,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CACzC,CAA2B,EAC3B,CAA2B;IAE3B,OAAO,aAAa,CAAC,CAAC,CAAC,KAAK,aAAa,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC","sourcesContent":["// Pure rules of the versioned public-document system — the version math the one publish\n// transaction applies, and the comparisons both the acceptance prompt (client) and the\n// acceptance callable (server) make. One owner, so the prompt and the server can never\n// disagree about what changed or what is required.\n\nimport { PUBLIC_DOCUMENT_IDS, type PublicDocumentId } from '../constants/public-documents.js';\nimport { SPECIAL_DOCS } from '../paths/collections.js';\nimport type {\n PublicDocumentAcceptance,\n PublicDocumentContent,\n PublicDocumentProjection,\n PublicDocumentVersionBlock,\n PublicDocumentVersionRef,\n PublicDocumentVersionState,\n} from '../doc-schemas/public-documents.js';\nimport type { UserPrivateData } from '../doc-schemas/user.js';\n\n/** The version block before any release: every document at version 0, nothing required. */\nexport const EMPTY_PUBLIC_DOCUMENT_VERSION_BLOCK: PublicDocumentVersionBlock = Object.freeze({\n documents: Object.freeze({}),\n requiredAcceptanceLevel: 0,\n}) as PublicDocumentVersionBlock;\n\n/** A document's current published version; 0 when it has never been published. */\nexport function currentPublicDocumentVersion(\n block: PublicDocumentVersionBlock | undefined,\n documentId: PublicDocumentId,\n): number {\n return block?.documents[documentId]?.currentVersion ?? 0;\n}\n\n/** The latest version of a document a release required acceptance of; 0 when none has. */\nexport function requiredPublicDocumentVersion(\n block: PublicDocumentVersionBlock | undefined,\n documentId: PublicDocumentId,\n): number {\n return block?.documents[documentId]?.requiredVersion ?? 0;\n}\n\n/** The required-acceptance level in force; 0 when nothing has ever required acceptance. */\nexport function requiredPublicDocumentAcceptanceLevel(block: PublicDocumentVersionBlock | undefined): number {\n return block?.requiredAcceptanceLevel ?? 0;\n}\n\n/** The level a person has accepted; 0 when they have accepted nothing. */\nexport function acceptedPublicDocumentAcceptanceLevel(acceptance: PublicDocumentAcceptance | undefined): number {\n return acceptance?.acceptedLevel ?? 0;\n}\n\n/** A document's accepted version; 0 when the person never accepted it. */\nexport function acceptedPublicDocumentVersion(\n acceptance: PublicDocumentAcceptance | undefined,\n documentId: PublicDocumentId,\n): number {\n return acceptance?.documentVersions[documentId] ?? 0;\n}\n\n/** True when the person must accept before continuing: the required level is above theirs. */\nexport function isPublicDocumentAcceptanceRequired(\n block: PublicDocumentVersionBlock | undefined,\n acceptance: PublicDocumentAcceptance | undefined,\n): boolean {\n return requiredPublicDocumentAcceptanceLevel(block) > acceptedPublicDocumentAcceptanceLevel(acceptance);\n}\n\n/**\n * Every document whose CURRENT version is newer than the one the person accepted — including\n * changes from releases that did not require acceptance — at its current version, in canonical\n * order. This is exactly the list the acceptance prompt shows and the acceptance callable\n * expects back.\n */\nexport function changedPublicDocuments(\n block: PublicDocumentVersionBlock | undefined,\n acceptance: PublicDocumentAcceptance | undefined,\n): PublicDocumentVersionRef[] {\n const changed: PublicDocumentVersionRef[] = [];\n for (const documentId of PUBLIC_DOCUMENT_IDS) {\n const version = currentPublicDocumentVersion(block, documentId);\n if (version > acceptedPublicDocumentVersion(acceptance, documentId)) changed.push({ documentId, version });\n }\n return changed;\n}\n\n/** The two private-doc fields the Square agreements card records. */\nexport type SquareStreetzAgreementsRecord = Pick<\n UserPrivateData,\n 'squareStreetzAgreementsDate' | 'squareStreetzAgreementsVersion'\n>;\n\n/**\n * True when the person's Square agreements still stand: they recorded an acceptance date AND\n * the Rules & Agreements version they accepted is at or above the latest version a release\n * REQUIRED acceptance of. The card incorporates the Rules page by reference, so a Rules release\n * that required acceptance asks again; one that did not never does. The composer (client) and\n * every Square post path (server) decide with this one rule. A missing version block means no\n * Rules release has required acceptance yet.\n */\nexport function squareStreetzAgreementsSatisfied(\n privateData: SquareStreetzAgreementsRecord | null | undefined,\n block: PublicDocumentVersionBlock | undefined,\n): boolean {\n const acceptedAt = privateData?.squareStreetzAgreementsDate;\n const acceptedRulesVersion = privateData?.squareStreetzAgreementsVersion;\n return (\n typeof acceptedAt === 'number' &&\n typeof acceptedRulesVersion === 'number' &&\n acceptedRulesVersion >= requiredPublicDocumentVersion(block, SPECIAL_DOCS.RULES_AND_AGREEMENTS)\n );\n}\n\n/**\n * True when two document/version lists name the same pairs (order-insensitive). The acceptance\n * callable compares the versions the prompt showed with `changedPublicDocuments` now; any\n * difference means a publish raced the prompt, so it refreshes and asks again.\n */\nexport function samePublicDocumentVersions(\n a: readonly PublicDocumentVersionRef[],\n b: readonly PublicDocumentVersionRef[],\n): boolean {\n if (a.length !== b.length) return false;\n const key = (ref: PublicDocumentVersionRef) => `${ref.documentId}@${ref.version}`;\n const left = new Set(a.map(key));\n if (left.size !== a.length) return false;\n return b.every((ref) => left.has(key(ref)));\n}\n\n/**\n * The summary a person holds after accepting everything current — every published document at\n * its current version and the current required level. Registration and the acceptance callable\n * both write exactly this. `legalReviewNoticeRevision` is the active notice revision, or null\n * while the notice is off (then it is not recorded).\n */\nexport function publicDocumentAcceptanceSummary(\n block: PublicDocumentVersionBlock | undefined,\n recorded: { acceptedAt: number; legalReviewNoticeRevision: string | null },\n): PublicDocumentAcceptance {\n const documentVersions: PublicDocumentAcceptance['documentVersions'] = {};\n for (const documentId of PUBLIC_DOCUMENT_IDS) {\n const version = currentPublicDocumentVersion(block, documentId);\n if (version > 0) documentVersions[documentId] = version;\n }\n return {\n documentVersions,\n acceptedLevel: requiredPublicDocumentAcceptanceLevel(block),\n ...(recorded.legalReviewNoticeRevision !== null\n ? { legalReviewNoticeRevision: recorded.legalReviewNoticeRevision }\n : {}),\n acceptedAt: recorded.acceptedAt,\n };\n}\n\n/** What one release does to the version block. */\nexport interface PublicDocumentReleasePlan {\n /** The version block to write. */\n block: PublicDocumentVersionBlock;\n /** Each released document at its newly assigned version, in canonical order. */\n documents: PublicDocumentVersionRef[];\n /** The required-acceptance level after this release. */\n requiredAcceptanceLevel: number;\n}\n\n/**\n * Plan a release: each included document moves to its next whole-number version; when the\n * release requires acceptance, each also becomes that document's required version and the\n * required level rises by exactly one. Documents not in the release are untouched. Pure — the\n * publish transaction reads the block, plans, then writes the versions, projections, block,\n * release record, and audit event together. Throws on an empty or duplicated document list.\n */\nexport function planPublicDocumentRelease(\n block: PublicDocumentVersionBlock | undefined,\n documentIds: readonly PublicDocumentId[],\n requireAcceptance: boolean,\n): PublicDocumentReleasePlan {\n if (documentIds.length === 0) throw new Error('A release must include at least one document.');\n const included = new Set(documentIds);\n if (included.size !== documentIds.length) throw new Error('A release lists each document once.');\n\n const previousLevel = requiredPublicDocumentAcceptanceLevel(block);\n const nextLevel = requireAcceptance ? previousLevel + 1 : previousLevel;\n const nextDocuments: Partial<Record<PublicDocumentId, PublicDocumentVersionState>> = {\n ...(block?.documents ?? {}),\n };\n const released: PublicDocumentVersionRef[] = [];\n\n for (const documentId of PUBLIC_DOCUMENT_IDS) {\n if (!included.has(documentId)) continue;\n const previous = block?.documents[documentId];\n const version = (previous?.currentVersion ?? 0) + 1;\n nextDocuments[documentId] = {\n currentVersion: version,\n requiredVersion: requireAcceptance ? version : (previous?.requiredVersion ?? 0),\n };\n released.push({ documentId, version });\n }\n\n return {\n block: { documents: nextDocuments, requiredAcceptanceLevel: nextLevel },\n documents: released,\n requiredAcceptanceLevel: nextLevel,\n };\n}\n\n/** The current projection the publish writes for a document: its content, version, and time. */\nexport function buildPublicDocumentProjection<D extends PublicDocumentId>(\n content: PublicDocumentContent<D>,\n version: number,\n publishedAt: number,\n): PublicDocumentProjection<D> {\n return { ...content, version, lastUpdated: publishedAt };\n}\n\n// Key-order-insensitive canonical form of JSON-like content (strings, numbers, booleans,\n// null, arrays, plain objects). An `undefined` object field is the same as an absent one.\nfunction canonicalJson(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(canonicalJson).join(',')}]`;\n if (value !== null && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n .filter(([, v]) => v !== undefined)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson(v)}`).join(',')}}`;\n }\n return JSON.stringify(value) ?? 'null';\n}\n\n/**\n * True when two contents of the same document are the same words and structure (field order\n * ignored). The publish rejects a working copy equal to the current version, and the Admin\n * release form keeps Publish disabled for one.\n */\nexport function publicDocumentContentEquals<D extends PublicDocumentId>(\n a: PublicDocumentContent<D>,\n b: PublicDocumentContent<D>,\n): boolean {\n return canonicalJson(a) === canonicalJson(b);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttt-productions/ttt-core",
3
- "version": "0.79.49",
3
+ "version": "0.79.50",
4
4
  "description": "Core types, Firestore path constants, and shared constants for TTT Productions",
5
5
  "repository": {
6
6
  "type": "git",