@uwmd/core 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/README.md +3 -3
  2. package/dist/agents/bancroft.d.ts +22 -1
  3. package/dist/agents/bancroft.d.ts.map +1 -1
  4. package/dist/agents/bancroft.js +86 -60
  5. package/dist/agents/bancroft.js.map +1 -1
  6. package/dist/agents/provider.d.ts +62 -0
  7. package/dist/agents/provider.d.ts.map +1 -0
  8. package/dist/agents/provider.js +28 -0
  9. package/dist/agents/provider.js.map +1 -0
  10. package/dist/agents/providers/anthropic.d.ts +20 -0
  11. package/dist/agents/providers/anthropic.d.ts.map +1 -0
  12. package/dist/agents/providers/anthropic.js +104 -0
  13. package/dist/agents/providers/anthropic.js.map +1 -0
  14. package/dist/agents/providers/replay.d.ts +46 -0
  15. package/dist/agents/providers/replay.d.ts.map +1 -0
  16. package/dist/agents/providers/replay.js +162 -0
  17. package/dist/agents/providers/replay.js.map +1 -0
  18. package/dist/agents/schemas.d.ts +3 -3
  19. package/dist/agents/schemas.d.ts.map +1 -1
  20. package/dist/agents/schemas.js.map +1 -1
  21. package/dist/browser.d.ts +26 -3
  22. package/dist/browser.d.ts.map +1 -1
  23. package/dist/browser.js +23 -3
  24. package/dist/browser.js.map +1 -1
  25. package/dist/calc/builtins.d.ts +10 -0
  26. package/dist/calc/builtins.d.ts.map +1 -1
  27. package/dist/calc/builtins.js +64 -42
  28. package/dist/calc/builtins.js.map +1 -1
  29. package/dist/calc/errors.js +1 -1
  30. package/dist/calc/evaluator.js +6 -2
  31. package/dist/calc/evaluator.js.map +1 -1
  32. package/dist/calc/index.d.ts +7 -0
  33. package/dist/calc/index.d.ts.map +1 -1
  34. package/dist/calc/index.js +13 -1
  35. package/dist/calc/index.js.map +1 -1
  36. package/dist/calc/quantize.d.ts +56 -0
  37. package/dist/calc/quantize.d.ts.map +1 -0
  38. package/dist/calc/quantize.js +116 -0
  39. package/dist/calc/quantize.js.map +1 -0
  40. package/dist/cli-packages.d.ts +11 -0
  41. package/dist/cli-packages.d.ts.map +1 -0
  42. package/dist/cli-packages.js +177 -0
  43. package/dist/cli-packages.js.map +1 -0
  44. package/dist/cli.js +424 -28
  45. package/dist/cli.js.map +1 -1
  46. package/dist/context.js +23 -23
  47. package/dist/deal-package-context.d.ts +52 -0
  48. package/dist/deal-package-context.d.ts.map +1 -0
  49. package/dist/deal-package-context.js +132 -0
  50. package/dist/deal-package-context.js.map +1 -0
  51. package/dist/deal-package-zip.d.ts +36 -0
  52. package/dist/deal-package-zip.d.ts.map +1 -0
  53. package/dist/deal-package-zip.js +132 -0
  54. package/dist/deal-package-zip.js.map +1 -0
  55. package/dist/deal-package.d.ts +82 -0
  56. package/dist/deal-package.d.ts.map +1 -0
  57. package/dist/deal-package.js +189 -0
  58. package/dist/deal-package.js.map +1 -0
  59. package/dist/defaults.d.ts +48 -0
  60. package/dist/defaults.d.ts.map +1 -1
  61. package/dist/defaults.js +512 -0
  62. package/dist/defaults.js.map +1 -1
  63. package/dist/index.d.ts +32 -3
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +27 -3
  66. package/dist/index.js.map +1 -1
  67. package/dist/init.js +1 -1
  68. package/dist/init.js.map +1 -1
  69. package/dist/integrity.d.ts +9 -0
  70. package/dist/integrity.d.ts.map +1 -1
  71. package/dist/integrity.js +12 -2
  72. package/dist/integrity.js.map +1 -1
  73. package/dist/lease-abstract.d.ts +82 -0
  74. package/dist/lease-abstract.d.ts.map +1 -0
  75. package/dist/lease-abstract.js +183 -0
  76. package/dist/lease-abstract.js.map +1 -0
  77. package/dist/lite-bridge.d.ts +58 -0
  78. package/dist/lite-bridge.d.ts.map +1 -0
  79. package/dist/lite-bridge.js +525 -0
  80. package/dist/lite-bridge.js.map +1 -0
  81. package/dist/lite.d.ts +63 -0
  82. package/dist/lite.d.ts.map +1 -0
  83. package/dist/lite.js +362 -0
  84. package/dist/lite.js.map +1 -0
  85. package/dist/modules.d.ts.map +1 -1
  86. package/dist/modules.js +278 -13
  87. package/dist/modules.js.map +1 -1
  88. package/dist/packs/excel-emit.d.ts +18 -1
  89. package/dist/packs/excel-emit.d.ts.map +1 -1
  90. package/dist/packs/excel-emit.js +18 -1
  91. package/dist/packs/excel-emit.js.map +1 -1
  92. package/dist/packs/hospitality.d.ts +3 -0
  93. package/dist/packs/hospitality.d.ts.map +1 -0
  94. package/dist/packs/hospitality.js +122 -0
  95. package/dist/packs/hospitality.js.map +1 -0
  96. package/dist/packs/index.d.ts +5 -1
  97. package/dist/packs/index.d.ts.map +1 -1
  98. package/dist/packs/index.js +13 -1
  99. package/dist/packs/index.js.map +1 -1
  100. package/dist/packs/land.d.ts +3 -0
  101. package/dist/packs/land.d.ts.map +1 -0
  102. package/dist/packs/land.js +124 -0
  103. package/dist/packs/land.js.map +1 -0
  104. package/dist/packs/senior-housing.d.ts +3 -0
  105. package/dist/packs/senior-housing.d.ts.map +1 -0
  106. package/dist/packs/senior-housing.js +123 -0
  107. package/dist/packs/senior-housing.js.map +1 -0
  108. package/dist/packs/student-housing.d.ts +3 -0
  109. package/dist/packs/student-housing.d.ts.map +1 -0
  110. package/dist/packs/student-housing.js +124 -0
  111. package/dist/packs/student-housing.js.map +1 -0
  112. package/dist/parser.d.ts +9 -0
  113. package/dist/parser.d.ts.map +1 -1
  114. package/dist/parser.js +40 -6
  115. package/dist/parser.js.map +1 -1
  116. package/dist/protocol.d.ts +69 -2
  117. package/dist/protocol.d.ts.map +1 -1
  118. package/dist/protocol.js +109 -1
  119. package/dist/protocol.js.map +1 -1
  120. package/dist/receipts.d.ts +216 -0
  121. package/dist/receipts.d.ts.map +1 -0
  122. package/dist/receipts.js +554 -0
  123. package/dist/receipts.js.map +1 -0
  124. package/dist/report.js +165 -165
  125. package/dist/runner.d.ts +13 -0
  126. package/dist/runner.d.ts.map +1 -1
  127. package/dist/runner.js +5 -5
  128. package/dist/runner.js.map +1 -1
  129. package/dist/source-representation.d.ts +40 -0
  130. package/dist/source-representation.d.ts.map +1 -0
  131. package/dist/source-representation.js +114 -0
  132. package/dist/source-representation.js.map +1 -0
  133. package/dist/types.d.ts +9 -0
  134. package/dist/types.d.ts.map +1 -1
  135. package/dist/types.js +34 -0
  136. package/dist/types.js.map +1 -1
  137. package/dist/uwcsv.d.ts.map +1 -1
  138. package/dist/uwcsv.js +10 -78
  139. package/dist/uwcsv.js.map +1 -1
  140. package/dist/uwxml.d.ts.map +1 -1
  141. package/dist/uwxml.js +10 -2
  142. package/dist/uwxml.js.map +1 -1
  143. package/dist/validator.js +10 -10
  144. package/dist/validator.js.map +1 -1
  145. package/dist/version.d.ts +3 -0
  146. package/dist/version.d.ts.map +1 -0
  147. package/dist/version.js +8 -0
  148. package/dist/version.js.map +1 -0
  149. package/dist/zip-safety.d.ts +15 -0
  150. package/dist/zip-safety.d.ts.map +1 -0
  151. package/dist/zip-safety.js +109 -0
  152. package/dist/zip-safety.js.map +1 -0
  153. package/package.json +12 -3
@@ -0,0 +1,132 @@
1
+ // UW Deal Package ZIP codec (RFC 0018 §3).
2
+ //
3
+ // The ZIP is the archival encoding; the JSON context is a view of it. A
4
+ // canonical encoder emits entries in lexicographic path order with fixed
5
+ // timestamps, so the same package always produces the same bytes — ZIP entry
6
+ // order and mtimes are not semantic and must not leak into a digest.
7
+ //
8
+ // Decoding inspects the archive before inflating anything, using the same
9
+ // shared safe-ZIP rules as the CSV bundle. Extraction to disk is not this
10
+ // module's business and never happens here.
11
+ import { unzipSync, zipSync } from 'fflate';
12
+ import { UWPackageError, UW_PACKAGE_VERSION, assertUWDealPackageManifest, validateUWDealPackageManifest, } from './deal-package.js';
13
+ import { sha256BytesHex } from './integrity.js';
14
+ import { inspectZipSafety } from './zip-safety.js';
15
+ export const PACKAGE_MANIFEST_PATH = 'manifest.json';
16
+ // Same constant the CSV bundle uses. One day past the DOS epoch on purpose:
17
+ // fflate converts to *local* time, so 1980-01-01T00:00Z underflows the
18
+ // 1980-2099 range in any negative-offset timezone.
19
+ //
20
+ // Caveat inherited from that choice: because the conversion is local, the
21
+ // encoded DOS timestamp — and therefore the archive bytes — can differ between
22
+ // machines in different timezones. Encoding is deterministic on a given host,
23
+ // which is what the ordering guarantee needs; cross-timezone byte identity
24
+ // would require a UTC-fixed field fflate does not expose.
25
+ const FIXED_MTIME = new Date('1980-01-02T00:00:00.000Z');
26
+ function pkgError(code, message, pointer) {
27
+ return { category: 'package', code, message, ...(pointer ? { pointer } : {}) };
28
+ }
29
+ const decoder = new TextDecoder('utf-8', { fatal: true });
30
+ const encoder = new TextEncoder();
31
+ export async function encodeUWDealPackageZip(input) {
32
+ const manifest = assertUWDealPackageManifest(input.manifest);
33
+ const files = {};
34
+ for (const member of manifest.members) {
35
+ const payload = input.payloads[member.path];
36
+ if (!payload) {
37
+ throw new UWPackageError('PKGZIP-001', `Declared member has no payload: ${member.path}`);
38
+ }
39
+ const actual = `sha256:${await sha256BytesHex(payload)}`;
40
+ if (actual !== member.sha256) {
41
+ // Encoding a package whose manifest already disagrees with its bytes
42
+ // would mint a broken artifact, so this fails at write time.
43
+ throw new UWPackageError('PKGZIP-002', `Member ${member.id} digest does not match its payload (manifest ${member.sha256}, actual ${actual}).`);
44
+ }
45
+ files[member.path] = [payload, { mtime: FIXED_MTIME, level: 9 }];
46
+ }
47
+ files[PACKAGE_MANIFEST_PATH] = [
48
+ encoder.encode(`${JSON.stringify(manifest, null, 2)}\n`),
49
+ { mtime: FIXED_MTIME, level: 9 },
50
+ ];
51
+ // Lexicographic order makes the archive byte-deterministic.
52
+ const ordered = {};
53
+ for (const path of Object.keys(files).sort())
54
+ ordered[path] = files[path];
55
+ return zipSync(ordered);
56
+ }
57
+ export function decodeUWDealPackageZip(input, options = {}) {
58
+ inspectZipSafety(input, options, (violation, message) => {
59
+ throw new UWPackageError(`PKG_${violation}`, message);
60
+ });
61
+ let entries;
62
+ try {
63
+ entries = unzipSync(input);
64
+ }
65
+ catch (error) {
66
+ throw new UWPackageError('PKGZIP-003', `ZIP could not be read: ${String(error)}`);
67
+ }
68
+ const manifestBytes = entries[PACKAGE_MANIFEST_PATH];
69
+ if (!manifestBytes) {
70
+ throw new UWPackageError('PKGZIP-004', `Package is missing ${PACKAGE_MANIFEST_PATH}.`);
71
+ }
72
+ let manifest;
73
+ try {
74
+ manifest = JSON.parse(decoder.decode(manifestBytes));
75
+ }
76
+ catch (error) {
77
+ throw new UWPackageError('PKGZIP-005', `${PACKAGE_MANIFEST_PATH} is invalid: ${String(error)}`);
78
+ }
79
+ const errors = validateUWDealPackageManifest(manifest);
80
+ if (errors.length > 0) {
81
+ throw new UWPackageError(errors[0].code, errors.map((e) => e.message).join('; '));
82
+ }
83
+ const typed = manifest;
84
+ const payloads = {};
85
+ for (const member of typed.members) {
86
+ const bytes = entries[member.path];
87
+ if (!bytes) {
88
+ throw new UWPackageError('PKGZIP-006', `Declared member is absent from the archive: ${member.path}`);
89
+ }
90
+ payloads[member.path] = bytes;
91
+ }
92
+ return { manifest: typed, payloads };
93
+ }
94
+ /**
95
+ * Verify a decoded package.
96
+ *
97
+ * Three-state on purpose, matching the receipt verifier. A member whose
98
+ * representation this implementation cannot canonicalize is **unverifiable**,
99
+ * not failed — an unsupported representation is not evidence of tampering, and
100
+ * collapsing the two would teach users to ignore the distinction.
101
+ */
102
+ export async function verifyUWDealPackage(decoded, options = {}) {
103
+ const errors = [];
104
+ const unverifiable = [];
105
+ for (const member of decoded.manifest.members) {
106
+ const bytes = decoded.payloads[member.path];
107
+ if (!bytes) {
108
+ errors.push(pkgError('PKGVER-001', `Member payload missing: ${member.path}`, member.id));
109
+ continue;
110
+ }
111
+ const actual = `sha256:${await sha256BytesHex(bytes)}`;
112
+ if (actual !== member.sha256) {
113
+ errors.push(pkgError('PKGVER-002', `Member ${member.id} byte digest does not match the manifest.`, member.id));
114
+ continue;
115
+ }
116
+ if (member.semantic_digest) {
117
+ const computed = options.semanticDigestOf
118
+ ? await options.semanticDigestOf(member.id, bytes)
119
+ : null;
120
+ if (computed === null) {
121
+ unverifiable.push(member.id);
122
+ }
123
+ else if (computed !== member.semantic_digest) {
124
+ errors.push(pkgError('PKGVER-003', `Member ${member.id} semantic digest does not match.`, member.id));
125
+ }
126
+ }
127
+ }
128
+ const status = errors.length > 0 ? 'failed' : unverifiable.length > 0 ? 'unverifiable' : 'verified';
129
+ return { status, errors, unverifiable_members: unverifiable };
130
+ }
131
+ export { UW_PACKAGE_VERSION };
132
+ //# sourceMappingURL=deal-package-zip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deal-package-zip.js","sourceRoot":"","sources":["../src/deal-package-zip.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ import { type UWEdgeLayer, type ProtocolError } from './protocol.js';
2
+ export declare const UW_PACKAGE_VERSION: "1.0";
3
+ export declare const UW_PACKAGE_ZIP_CODEC: "uw-deal-package-zip";
4
+ export declare const UW_PACKAGE_ZIP_MEDIA_TYPE: "application/vnd.uwmd.deal-package+zip";
5
+ export declare const UW_PACKAGE_CONTEXT_CODEC: "uw-deal-package-context";
6
+ export declare const UW_PACKAGE_CONTEXT_MEDIA_TYPE: "application/vnd.uwmd.deal-package-context+json";
7
+ /** Roles a member may play. `source_evidence` is never inlined into a context view. */
8
+ export type UWMemberRole = 'underwriting' | 'lease_abstract' | 'source_note' | 'source_evidence' | 'model_encoding';
9
+ export interface UWPackageMember {
10
+ id: string;
11
+ path: string;
12
+ role: UWMemberRole;
13
+ media_type: string;
14
+ /** Byte digest. This — not any reference handle — is the member's identity. */
15
+ sha256: string;
16
+ /** Present for UW documents whose representation the producer could canonicalize. */
17
+ semantic_digest?: string;
18
+ document_profile?: string;
19
+ [key: string]: unknown;
20
+ }
21
+ export interface UWPackageLink {
22
+ type: string;
23
+ from: string;
24
+ to: string;
25
+ [key: string]: unknown;
26
+ }
27
+ export interface UWDealPackageManifest {
28
+ package_version: typeof UW_PACKAGE_VERSION;
29
+ package_id: string;
30
+ members: UWPackageMember[];
31
+ links: UWPackageLink[];
32
+ [key: string]: unknown;
33
+ }
34
+ /** A typed, namespaced descriptor. A handle says where bytes *might* be found. */
35
+ export interface UWSourceReference {
36
+ scheme: string;
37
+ /** The namespace that minted the handle. A foreign authority is unresolvable. */
38
+ authority?: string;
39
+ value: string;
40
+ [key: string]: unknown;
41
+ }
42
+ export interface UWEntityEdge {
43
+ type: string;
44
+ from: string;
45
+ to: string;
46
+ provenance: Array<{
47
+ source: string;
48
+ locator?: string;
49
+ note?: string;
50
+ }>;
51
+ }
52
+ export declare class UWPackageError extends Error {
53
+ readonly code: string;
54
+ constructor(code: string, message: string);
55
+ }
56
+ /** Roles whose bytes may be inlined into a JSON context view (RFC 0018 §4). */
57
+ export declare const CONTEXT_INLINABLE_ROLES: readonly UWMemberRole[];
58
+ /**
59
+ * Paths MUST be relative POSIX paths with no traversal components and MUST
60
+ * resolve to exactly one non-symlink entry. Rejected here as well as at
61
+ * extraction time, so a malformed manifest fails before any archive is opened.
62
+ */
63
+ export declare function isSafeMemberPath(path: string): boolean;
64
+ export declare function validateUWDealPackageManifest(candidate: unknown): ProtocolError[];
65
+ export declare function assertUWDealPackageManifest(candidate: unknown): UWDealPackageManifest;
66
+ /**
67
+ * Project member-layer links into entity-layer edges (RFC 0018 §5).
68
+ *
69
+ * Projection is **one-directional and explicit**. Within a package the manifest
70
+ * *is* the provenance, because every member is content-addressed — so on the
71
+ * way up we synthesize a provenance entry naming the package and the member ids
72
+ * it came from. No edge reaches the entity layer without attributable
73
+ * provenance, and no package is forced to duplicate what its digests prove.
74
+ *
75
+ * There is deliberately no inverse. An entity edge must never be projected down
76
+ * into a package, or a package would stop being a self-contained artifact and
77
+ * become a partial view of somebody's portfolio graph.
78
+ */
79
+ export declare function projectPackageLinksToEntityEdges(manifest: UWDealPackageManifest): UWEntityEdge[];
80
+ /** Types valid on a given layer — used by hosts building UI or validators. */
81
+ export declare function edgeTypesForLayer(layer: UWEdgeLayer): string[];
82
+ //# sourceMappingURL=deal-package.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deal-package.d.ts","sourceRoot":"","sources":["../src/deal-package.ts"],"names":[],"mappings":"AAUA,OAAO,EAEL,KAAK,WAAW,EAGhB,KAAK,aAAa,EACnB,MAAM,eAAe,CAAC;AAEvB,eAAO,MAAM,kBAAkB,EAAG,KAAc,CAAC;AACjD,eAAO,MAAM,oBAAoB,EAAG,qBAA8B,CAAC;AACnE,eAAO,MAAM,yBAAyB,EAAG,uCAAgD,CAAC;AAC1F,eAAO,MAAM,wBAAwB,EAAG,yBAAkC,CAAC;AAC3E,eAAO,MAAM,6BAA6B,EACxC,gDAAyD,CAAC;AAE5D,uFAAuF;AACvF,MAAM,MAAM,YAAY,GACpB,cAAc,GACd,gBAAgB,GAChB,aAAa,GACb,iBAAiB,GACjB,gBAAgB,CAAC;AAErB,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAC;IACf,qFAAqF;IACrF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE,OAAO,kBAAkB,CAAC;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,kFAAkF;AAClF,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxE;AAED,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBACV,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAK1C;AAYD,+EAA+E;AAC/E,eAAO,MAAM,uBAAuB,EAAE,SAAS,YAAY,EAKzD,CAAC;AAUH;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAItD;AAED,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,OAAO,GAAG,aAAa,EAAE,CA2FjF;AAED,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,OAAO,GAAG,qBAAqB,CAMrF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,qBAAqB,GAC9B,YAAY,EAAE,CAsBhB;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,EAAE,CAE9D"}
@@ -0,0 +1,189 @@
1
+ // UW Deal Package 1.0 — manifest model, validation, and link projection.
2
+ //
3
+ // RFC 0018 §3–§5. A package has one manifest and zero or more member payloads.
4
+ // The manifest is the authoritative inventory: ZIP entry order and timestamps
5
+ // are not semantic, and every member is content-addressed by digest.
6
+ //
7
+ // This module is browser-safe and performs no I/O of any kind. Resolving a
8
+ // reference handle is an explicit host action that happens elsewhere; nothing
9
+ // here may reach the network, and validation never writes to disk.
10
+ import { BUILTIN_EDGE_TYPES, isEdgeTypeValidOnLayer, lookupEdgeType, } from './protocol.js';
11
+ export const UW_PACKAGE_VERSION = '1.0';
12
+ export const UW_PACKAGE_ZIP_CODEC = 'uw-deal-package-zip';
13
+ export const UW_PACKAGE_ZIP_MEDIA_TYPE = 'application/vnd.uwmd.deal-package+zip';
14
+ export const UW_PACKAGE_CONTEXT_CODEC = 'uw-deal-package-context';
15
+ export const UW_PACKAGE_CONTEXT_MEDIA_TYPE = 'application/vnd.uwmd.deal-package-context+json';
16
+ export class UWPackageError extends Error {
17
+ code;
18
+ constructor(code, message) {
19
+ super(`[${code}] ${message}`);
20
+ this.name = 'UWPackageError';
21
+ this.code = code;
22
+ }
23
+ }
24
+ const SHA256_PATTERN = /^sha256:[0-9a-f]{64}$/;
25
+ const MEMBER_ROLES = [
26
+ 'underwriting',
27
+ 'lease_abstract',
28
+ 'source_note',
29
+ 'source_evidence',
30
+ 'model_encoding',
31
+ ];
32
+ /** Roles whose bytes may be inlined into a JSON context view (RFC 0018 §4). */
33
+ export const CONTEXT_INLINABLE_ROLES = Object.freeze([
34
+ 'underwriting',
35
+ 'lease_abstract',
36
+ 'source_note',
37
+ 'model_encoding',
38
+ ]);
39
+ function packageError(code, message, pointer) {
40
+ return { category: 'package', code, message, ...(pointer ? { pointer } : {}) };
41
+ }
42
+ function isRecord(v) {
43
+ return typeof v === 'object' && v !== null && !Array.isArray(v);
44
+ }
45
+ /**
46
+ * Paths MUST be relative POSIX paths with no traversal components and MUST
47
+ * resolve to exactly one non-symlink entry. Rejected here as well as at
48
+ * extraction time, so a malformed manifest fails before any archive is opened.
49
+ */
50
+ export function isSafeMemberPath(path) {
51
+ if (!path || path.includes('\\') || path.includes('\0'))
52
+ return false;
53
+ if (path.startsWith('/') || /^[A-Za-z]:/.test(path))
54
+ return false;
55
+ return !path.split('/').some((part) => part === '' || part === '.' || part === '..');
56
+ }
57
+ export function validateUWDealPackageManifest(candidate) {
58
+ const errors = [];
59
+ if (!isRecord(candidate)) {
60
+ return [packageError('PKG-001', 'Package manifest must be an object.')];
61
+ }
62
+ const manifest = candidate;
63
+ if (manifest.package_version !== UW_PACKAGE_VERSION) {
64
+ errors.push(packageError('PKG-002', `Unsupported package_version; expected ${UW_PACKAGE_VERSION}.`, 'package_version'));
65
+ }
66
+ if (typeof manifest.package_id !== 'string' || manifest.package_id.length === 0) {
67
+ errors.push(packageError('PKG-003', 'package_id is required.', 'package_id'));
68
+ }
69
+ if (!Array.isArray(manifest.members)) {
70
+ errors.push(packageError('PKG-004', 'members must be an array.', 'members'));
71
+ return errors;
72
+ }
73
+ if (manifest.links !== undefined && !Array.isArray(manifest.links)) {
74
+ errors.push(packageError('PKG-005', 'links must be an array.', 'links'));
75
+ }
76
+ const seenIds = new Set();
77
+ const seenPaths = new Set();
78
+ for (const [idx, member] of manifest.members.entries()) {
79
+ const at = `members[${idx}]`;
80
+ if (!isRecord(member)) {
81
+ errors.push(packageError('PKG-006', 'Member must be an object.', at));
82
+ continue;
83
+ }
84
+ for (const key of ['id', 'path', 'media_type']) {
85
+ if (typeof member[key] !== 'string' || member[key].length === 0) {
86
+ errors.push(packageError('PKG-007', `Member ${key} is required.`, `${at}.${key}`));
87
+ }
88
+ }
89
+ if (typeof member.id === 'string') {
90
+ if (seenIds.has(member.id)) {
91
+ errors.push(packageError('PKG-008', `Duplicate member id: ${member.id}`, `${at}.id`));
92
+ }
93
+ seenIds.add(member.id);
94
+ }
95
+ if (typeof member.path === 'string') {
96
+ if (!isSafeMemberPath(member.path)) {
97
+ errors.push(packageError('PKG-009', `Unsafe member path: ${member.path}`, `${at}.path`));
98
+ }
99
+ if (seenPaths.has(member.path)) {
100
+ errors.push(packageError('PKG-010', `Duplicate member path: ${member.path}`, `${at}.path`));
101
+ }
102
+ seenPaths.add(member.path);
103
+ }
104
+ if (!MEMBER_ROLES.includes(member.role)) {
105
+ errors.push(packageError('PKG-011', `Unknown member role: ${String(member.role)}`, `${at}.role`));
106
+ }
107
+ if (typeof member.sha256 !== 'string' || !SHA256_PATTERN.test(member.sha256)) {
108
+ errors.push(packageError('PKG-012', 'Member sha256 must be `sha256:<64 lowercase hex>`.', `${at}.sha256`));
109
+ }
110
+ if (member.semantic_digest !== undefined && !SHA256_PATTERN.test(String(member.semantic_digest))) {
111
+ errors.push(packageError('PKG-013', 'semantic_digest must be `sha256:<64 lowercase hex>`.', `${at}.semantic_digest`));
112
+ }
113
+ }
114
+ for (const [idx, link] of (manifest.links ?? []).entries()) {
115
+ const at = `links[${idx}]`;
116
+ if (!isRecord(link)) {
117
+ errors.push(packageError('PKG-014', 'Link must be an object.', at));
118
+ continue;
119
+ }
120
+ for (const key of ['type', 'from', 'to']) {
121
+ if (typeof link[key] !== 'string' || link[key].length === 0) {
122
+ errors.push(packageError('PKG-015', `Link ${key} is required.`, `${at}.${key}`));
123
+ }
124
+ }
125
+ // Dangling endpoints are the failure that makes a link graph lie, so they
126
+ // are rejected rather than dropped.
127
+ for (const end of ['from', 'to']) {
128
+ const id = link[end];
129
+ if (typeof id === 'string' && !seenIds.has(id)) {
130
+ errors.push(packageError('PKG-016', `Link ${end} does not resolve to a member: ${id}`, `${at}.${end}`));
131
+ }
132
+ }
133
+ // An unknown type is preserved; a *known* type used on the wrong layer is
134
+ // an error, because that is a claim the registry says cannot be true.
135
+ if (typeof link.type === 'string' && !isEdgeTypeValidOnLayer(link.type, 'member')) {
136
+ errors.push(packageError('PKG-017', `Edge type ${link.type} is not valid on the member layer.`, `${at}.type`));
137
+ }
138
+ }
139
+ return errors;
140
+ }
141
+ export function assertUWDealPackageManifest(candidate) {
142
+ const errors = validateUWDealPackageManifest(candidate);
143
+ if (errors.length > 0) {
144
+ throw new UWPackageError(errors[0].code, errors.map((e) => e.message).join('; '));
145
+ }
146
+ return candidate;
147
+ }
148
+ /**
149
+ * Project member-layer links into entity-layer edges (RFC 0018 §5).
150
+ *
151
+ * Projection is **one-directional and explicit**. Within a package the manifest
152
+ * *is* the provenance, because every member is content-addressed — so on the
153
+ * way up we synthesize a provenance entry naming the package and the member ids
154
+ * it came from. No edge reaches the entity layer without attributable
155
+ * provenance, and no package is forced to duplicate what its digests prove.
156
+ *
157
+ * There is deliberately no inverse. An entity edge must never be projected down
158
+ * into a package, or a package would stop being a self-contained artifact and
159
+ * become a partial view of somebody's portfolio graph.
160
+ */
161
+ export function projectPackageLinksToEntityEdges(manifest) {
162
+ const edges = [];
163
+ for (const link of manifest.links ?? []) {
164
+ const def = lookupEdgeType(link.type);
165
+ // Only types the registry declares valid on the entity layer project up.
166
+ // Member-only types (`abstracts`, `contributes_to`) describe documents and
167
+ // have no entity-layer meaning.
168
+ if (!def || !def.layers.includes('entity'))
169
+ continue;
170
+ edges.push({
171
+ type: link.type,
172
+ from: link.from,
173
+ to: link.to,
174
+ provenance: [
175
+ {
176
+ source: manifest.package_id,
177
+ locator: `${link.from} → ${link.to}`,
178
+ note: `Projected from UW Deal Package member link (${link.type}).`,
179
+ },
180
+ ],
181
+ });
182
+ }
183
+ return edges;
184
+ }
185
+ /** Types valid on a given layer — used by hosts building UI or validators. */
186
+ export function edgeTypesForLayer(layer) {
187
+ return BUILTIN_EDGE_TYPES.filter((d) => d.layers.includes(layer)).map((d) => d.type);
188
+ }
189
+ //# sourceMappingURL=deal-package.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deal-package.js","sourceRoot":"","sources":["../src/deal-package.ts"],"names":[],"mappings":"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"}
@@ -85,6 +85,54 @@ export declare const INDUSTRIAL_DEFAULTS: AssetClassDefaults;
85
85
  * ranking), not committee underwriting.
86
86
  */
87
87
  export declare const SELF_STORAGE_DEFAULTS: AssetClassDefaults;
88
+ /**
89
+ * Hospitality asset-class defaults, v1.0.0.
90
+ *
91
+ * Calibrated for stabilized, branded select-service and upscale hotels. The
92
+ * key class-specific inputs are occupancy, ADR, RevPAR, the GOP margin, and the
93
+ * franchise/management/FF&E load that sits between GOP and NOI. Hotels are
94
+ * operating businesses, so the expense-ratio and cap-rate bands run materially
95
+ * wider than for the lease-based classes. Triage grade (scope-stage VOI
96
+ * ranking), not committee underwriting.
97
+ */
98
+ export declare const HOSPITALITY_DEFAULTS: AssetClassDefaults;
99
+ /**
100
+ * Senior-housing asset-class defaults, v1.0.0.
101
+ *
102
+ * Calibrated for stabilized assisted-living and memory-care communities under
103
+ * third-party management. Senior housing is an operating business with a heavy
104
+ * labor load, so the expense-ratio band runs the widest of any class here and
105
+ * the labor ratio is itself a defaulted input. Independent living sits toward
106
+ * the low end of the expense and care bands; memory care toward the high end.
107
+ * Triage grade (scope-stage VOI ranking), not committee underwriting.
108
+ */
109
+ export declare const SENIOR_HOUSING_DEFAULTS: AssetClassDefaults;
110
+ /**
111
+ * Student-housing asset-class defaults, v1.0.0.
112
+ *
113
+ * Calibrated for stabilized purpose-built off-campus product within walking
114
+ * distance of a large public university. Student housing leases by the bed on
115
+ * an academic-year cycle, so the two inputs that matter most have no
116
+ * conventional-multifamily analogue: the pre-lease rate for the coming year,
117
+ * and the turnover cost of re-leasing nearly the whole property on one date.
118
+ * The expense ratio runs above conventional multifamily for the same reason.
119
+ * Triage grade (scope-stage VOI ranking), not committee underwriting.
120
+ */
121
+ export declare const STUDENT_HOUSING_DEFAULTS: AssetClassDefaults;
122
+ /**
123
+ * Land asset-class defaults, v1.0.0.
124
+ *
125
+ * Calibrated for entitled residential land held for horizontal development and
126
+ * finished-lot sale. Land is not an income property, so this table carries no
127
+ * occupancy, expense-ratio, or exit-cap entry — there is nothing to occupy and
128
+ * no stabilized income to capitalize. What it does carry instead are the inputs
129
+ * land is actually underwritten on: how much of the gross acreage is usable,
130
+ * what the annual carry costs as a share of basis, what share of eventual
131
+ * sellout the land basis represents, and the shorter/pricier/lower-leverage
132
+ * terms of a land acquisition facility. Triage grade (scope-stage VOI ranking),
133
+ * not committee underwriting.
134
+ */
135
+ export declare const LAND_DEFAULTS: AssetClassDefaults;
88
136
  /**
89
137
  * Look up the published defaults for an asset class. Returns null when no
90
138
  * table is registered (callers should fall through to `global_default` /
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEhF,MAAM,WAAW,YAAY;IAC3B,0CAA0C;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,+DAA+D;IAC/D,MAAM,EAAE,qBAAqB,CAAC;IAC9B,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,UAAU,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IACxC,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACtC;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,EAAE,kBA6FlC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,EAAE,kBA6G7B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,EAAE,kBA6G7B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,kBA6GjC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,EAAE,kBAqGnC,CAAC;AAUF;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAEpF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAG5F;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAGjE"}
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEhF,MAAM,WAAW,YAAY;IAC3B,0CAA0C;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,+DAA+D;IAC/D,MAAM,EAAE,qBAAqB,CAAC;IAC9B,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,UAAU,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IACxC,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACtC;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,EAAE,kBA6FlC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,EAAE,kBA6G7B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,EAAE,kBA6G7B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,kBA6GjC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,EAAE,kBAqGnC,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,EAAE,kBAqHlC,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,EAAE,kBA6HrC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,EAAE,kBAqHtC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,EAAE,kBAqG3B,CAAC;AAcF;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAEpF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAG5F;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAGjE"}