@ifc-lite/flow-nodes 0.6.0 → 0.9.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 (112) hide show
  1. package/README.md +118 -0
  2. package/dist/ai-classify.d.ts +8 -0
  3. package/dist/ai-classify.d.ts.map +1 -0
  4. package/dist/ai-classify.js +113 -0
  5. package/dist/ai-classify.js.map +1 -0
  6. package/dist/ai-extract.d.ts +26 -0
  7. package/dist/ai-extract.d.ts.map +1 -0
  8. package/dist/ai-extract.js +127 -0
  9. package/dist/ai-extract.js.map +1 -0
  10. package/dist/ai-propose-fields.d.ts +12 -0
  11. package/dist/ai-propose-fields.d.ts.map +1 -0
  12. package/dist/ai-propose-fields.js +57 -0
  13. package/dist/ai-propose-fields.js.map +1 -0
  14. package/dist/ai-propose.d.ts +3 -0
  15. package/dist/ai-propose.d.ts.map +1 -0
  16. package/dist/ai-propose.js +94 -0
  17. package/dist/ai-propose.js.map +1 -0
  18. package/dist/ai-response-schemas.d.ts +11 -0
  19. package/dist/ai-response-schemas.d.ts.map +1 -0
  20. package/dist/ai-response-schemas.js +46 -0
  21. package/dist/ai-response-schemas.js.map +1 -0
  22. package/dist/ai-service.d.ts +60 -0
  23. package/dist/ai-service.d.ts.map +1 -0
  24. package/dist/ai-service.js +109 -0
  25. package/dist/ai-service.js.map +1 -0
  26. package/dist/ai-summarize.d.ts +3 -0
  27. package/dist/ai-summarize.d.ts.map +1 -0
  28. package/dist/ai-summarize.js +75 -0
  29. package/dist/ai-summarize.js.map +1 -0
  30. package/dist/ai.d.ts +15 -0
  31. package/dist/ai.d.ts.map +1 -0
  32. package/dist/ai.js +10 -0
  33. package/dist/ai.js.map +1 -0
  34. package/dist/bcf-nodes.d.ts.map +1 -1
  35. package/dist/bcf-nodes.js +12 -2
  36. package/dist/bcf-nodes.js.map +1 -1
  37. package/dist/bcf-publication-capacity.d.ts +5 -0
  38. package/dist/bcf-publication-capacity.d.ts.map +1 -0
  39. package/dist/bcf-publication-capacity.js +44 -0
  40. package/dist/bcf-publication-capacity.js.map +1 -0
  41. package/dist/bcf-publication-check.d.ts +4 -0
  42. package/dist/bcf-publication-check.d.ts.map +1 -0
  43. package/dist/bcf-publication-check.js +100 -0
  44. package/dist/bcf-publication-check.js.map +1 -0
  45. package/dist/bcf-publication-codec.d.ts +53 -0
  46. package/dist/bcf-publication-codec.d.ts.map +1 -0
  47. package/dist/bcf-publication-codec.js +247 -0
  48. package/dist/bcf-publication-codec.js.map +1 -0
  49. package/dist/bcf-publication-epochs.d.ts +17 -0
  50. package/dist/bcf-publication-epochs.d.ts.map +1 -0
  51. package/dist/bcf-publication-epochs.js +104 -0
  52. package/dist/bcf-publication-epochs.js.map +1 -0
  53. package/dist/bcf-publication-history.d.ts +8 -0
  54. package/dist/bcf-publication-history.d.ts.map +1 -0
  55. package/dist/bcf-publication-history.js +84 -0
  56. package/dist/bcf-publication-history.js.map +1 -0
  57. package/dist/bcf-publication-node.d.ts +4 -0
  58. package/dist/bcf-publication-node.d.ts.map +1 -0
  59. package/dist/bcf-publication-node.js +235 -0
  60. package/dist/bcf-publication-node.js.map +1 -0
  61. package/dist/bcf-publication-owner.d.ts +7 -0
  62. package/dist/bcf-publication-owner.d.ts.map +1 -0
  63. package/dist/bcf-publication-owner.js +94 -0
  64. package/dist/bcf-publication-owner.js.map +1 -0
  65. package/dist/bcf-publication-store.d.ts +40 -0
  66. package/dist/bcf-publication-store.d.ts.map +1 -0
  67. package/dist/bcf-publication-store.js +312 -0
  68. package/dist/bcf-publication-store.js.map +1 -0
  69. package/dist/bcf-publication-types.d.ts +105 -0
  70. package/dist/bcf-publication-types.d.ts.map +1 -0
  71. package/dist/bcf-publication-types.js +5 -0
  72. package/dist/bcf-publication-types.js.map +1 -0
  73. package/dist/bcf-publication.d.ts +13 -0
  74. package/dist/bcf-publication.d.ts.map +1 -0
  75. package/dist/bcf-publication.js +24 -0
  76. package/dist/bcf-publication.js.map +1 -0
  77. package/dist/bcf-write-gateway.d.ts +41 -0
  78. package/dist/bcf-write-gateway.d.ts.map +1 -0
  79. package/dist/bcf-write-gateway.js +75 -0
  80. package/dist/bcf-write-gateway.js.map +1 -0
  81. package/dist/capability.d.ts +4 -0
  82. package/dist/capability.d.ts.map +1 -0
  83. package/dist/capability.js +21 -0
  84. package/dist/capability.js.map +1 -0
  85. package/dist/element-nodes.d.ts +9 -1
  86. package/dist/element-nodes.d.ts.map +1 -1
  87. package/dist/element-nodes.js +82 -9
  88. package/dist/element-nodes.js.map +1 -1
  89. package/dist/host.d.ts +41 -40
  90. package/dist/host.d.ts.map +1 -1
  91. package/dist/host.js +2 -31
  92. package/dist/host.js.map +1 -1
  93. package/dist/ids-nodes.d.ts +23 -0
  94. package/dist/ids-nodes.d.ts.map +1 -0
  95. package/dist/ids-nodes.js +180 -0
  96. package/dist/ids-nodes.js.map +1 -0
  97. package/dist/index.d.ts +1 -0
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +4 -0
  100. package/dist/index.js.map +1 -1
  101. package/dist/ports.d.ts +38 -0
  102. package/dist/ports.d.ts.map +1 -0
  103. package/dist/ports.js +14 -0
  104. package/dist/ports.js.map +1 -0
  105. package/dist/review-node.d.ts +3 -0
  106. package/dist/review-node.d.ts.map +1 -0
  107. package/dist/review-node.js +20 -0
  108. package/dist/review-node.js.map +1 -0
  109. package/dist/speckle/url.d.ts.map +1 -1
  110. package/dist/speckle/url.js +9 -1
  111. package/dist/speckle/url.js.map +1 -1
  112. package/package.json +32 -12
@@ -0,0 +1,5 @@
1
+ export declare const DIGEST_SLOTS = 4096;
2
+ export declare function capacityDigest(value: unknown): string;
3
+ /** Monotonic, never-deleted slots. Same-digest racers converge on the same first slot. */
4
+ export declare function reserveDigest(directory: string, digest: string, publish: (directory: string, filename: string, value: unknown) => Promise<void>, read: (directory: string, filename: string) => Promise<unknown>, sync: (directory: string) => Promise<void>): Promise<void>;
5
+ //# sourceMappingURL=bcf-publication-capacity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bcf-publication-capacity.d.ts","sourceRoot":"","sources":["../src/bcf-publication-capacity.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,YAAY,OAAQ,CAAC;AAElC,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAIrD;AAED,0FAA0F;AAC1F,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EACnE,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,EAC/E,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB5H"}
@@ -0,0 +1,44 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { record, refuse } from './bcf-publication-codec.js';
5
+ export const DIGEST_SLOTS = 4_096;
6
+ const code = (error) => record(error) ? error.code : undefined;
7
+ export function capacityDigest(value) {
8
+ if (!record(value) || value.version !== 2 || typeof value.digest !== 'string' || !/^[a-f0-9]{64}$/.test(value.digest)
9
+ || Object.keys(value).some(k => !['version', 'digest'].includes(k)))
10
+ refuse('invalid digest capacity record');
11
+ return value.digest;
12
+ }
13
+ /** Monotonic, never-deleted slots. Same-digest racers converge on the same first slot. */
14
+ export async function reserveDigest(directory, digest, publish, read, sync) {
15
+ for (let slot = 0; slot < DIGEST_SLOTS; slot += 1) {
16
+ const filename = `slot-${slot}.json`;
17
+ try {
18
+ if (capacityDigest(await read(directory, filename)) === digest) {
19
+ await sync(directory);
20
+ return;
21
+ }
22
+ continue;
23
+ }
24
+ catch (error) {
25
+ if (code(error) !== 'ENOENT')
26
+ throw error;
27
+ }
28
+ try {
29
+ await publish(directory, filename, { version: 2, digest });
30
+ }
31
+ catch (error) {
32
+ if (code(error) !== 'EEXIST')
33
+ throw error;
34
+ // A competing same-digest claim won this exact first available slot.
35
+ if (capacityDigest(await read(directory, filename)) !== digest)
36
+ continue;
37
+ }
38
+ // A failed fsync leaves this immutable claim authoritative and reusable, never deleted.
39
+ await sync(directory);
40
+ return;
41
+ }
42
+ refuse('digest bucket capacity reached before sending; existing receipts remain readable');
43
+ }
44
+ //# sourceMappingURL=bcf-publication-capacity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bcf-publication-capacity.js","sourceRoot":"","sources":["../src/bcf-publication-capacity.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAE5D,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC;AAClC,MAAM,IAAI,GAAG,CAAC,KAAc,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AACxE,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;WAChH,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAAE,MAAM,CAAC,gCAAgC,CAAC,CAAC;IAChH,OAAO,KAAK,CAAC,MAAM,CAAC;AACtB,CAAC;AAED,0FAA0F;AAC1F,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB,EAAE,MAAc,EACnE,OAA+E,EAC/E,IAA+D,EAAE,IAA0C;IAC3G,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,YAAY,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,QAAQ,IAAI,OAAO,CAAC;QACrC,IAAI,CAAC;YACH,IAAI,cAAc,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;gBAAC,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC;gBAAC,OAAO;YAAC,CAAC;YAClG,SAAS;QACX,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,QAAQ;gBAAE,MAAM,KAAK,CAAC;QAAC,CAAC;QAC9D,IAAI,CAAC;YAAC,MAAM,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAAC,CAAC;QACnE,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,QAAQ;gBAAE,MAAM,KAAK,CAAC;YAC1C,qEAAqE;YACrE,IAAI,cAAc,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,KAAK,MAAM;gBAAE,SAAS;QAC3E,CAAC;QACD,wFAAwF;QACxF,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC;QACtB,OAAO;IACT,CAAC;IACD,MAAM,CAAC,kFAAkF,CAAC,CAAC;AAC7F,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { NativeBcfPublicationCheck, NativeBcfPublicationCheckOptions, StoredBcfAttempt } from './bcf-publication-types.js';
2
+ /** Explicit bounded, read-only lookup through the canonical capability-gated transport. */
3
+ export declare function lookupNativeBcfAttempt(attempt: StoredBcfAttempt, options: NativeBcfPublicationCheckOptions, secrets: readonly string[]): Promise<NativeBcfPublicationCheck>;
4
+ //# sourceMappingURL=bcf-publication-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bcf-publication-check.d.ts","sourceRoot":"","sources":["../src/bcf-publication-check.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,yBAAyB,EAAE,gCAAgC,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEhI,2FAA2F;AAC3F,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,gCAAgC,EAC/G,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAwEhE"}
@@ -0,0 +1,100 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { BcfApiClient } from '@ifc-lite/bcf-api';
5
+ import { coreNetworkRequest } from '@ifc-lite/sandbox';
6
+ import { canonical, credentialFree, NATIVE_METADATA, record, refuse, text } from './bcf-publication-codec.js';
7
+ /** Explicit bounded, read-only lookup through the canonical capability-gated transport. */
8
+ export async function lookupNativeBcfAttempt(attempt, options, secrets) {
9
+ const intent = attempt.intent;
10
+ const sensitive = [...secrets, ...(options.token ? [options.token] : [])];
11
+ credentialFree(intent, sensitive);
12
+ const client = new BcfApiClient({ baseUrl: intent.baseUrl, version: intent.version, getAccessToken: () => options.token,
13
+ fetchFn: async (url, init) => {
14
+ if (init?.method && init.method !== 'GET')
15
+ refuse('recovery only permits reads');
16
+ const headers = {};
17
+ new Headers(init?.headers).forEach((value, key) => { headers[key] = value; });
18
+ const result = await coreNetworkRequest({ url, method: 'GET', headers, timeoutMs: 15_000, maxBytes: 5 * 1024 * 1024,
19
+ signal: options.signal }, options.networkGrants, options.networkTransport);
20
+ if (result.truncated)
21
+ refuse('server check exceeded response bound');
22
+ return new Response([204, 205, 304].includes(result.status) ? null : result.body, { status: result.status, headers: result.headers });
23
+ } });
24
+ const candidates = [];
25
+ const seen = new Set();
26
+ let incomparable = false;
27
+ const now = new Date();
28
+ function consider(item) {
29
+ if (!record(item) || !text(item.guid))
30
+ refuse('invalid server check response');
31
+ // Servers may trim free text on storage. Such a match still only proposes
32
+ // a manual candidate: discarding it could falsely release a duplicate write.
33
+ const remote = item;
34
+ if (!Object.entries(intent.payload).every(([key, value]) => {
35
+ const stored = remote[key];
36
+ if (['title', 'description', 'comment'].includes(key) && typeof stored === 'string' && typeof value === 'string') {
37
+ return stored.trim() === value.trim();
38
+ }
39
+ return canonical(stored ?? null) === canonical(value ?? null);
40
+ })) {
41
+ // A server may rewrite or omit mutable fields. Without a client marker
42
+ // or known remote GUID, a non-match cannot prove this is another effect.
43
+ incomparable = true;
44
+ return;
45
+ }
46
+ credentialFree({ guid: item.guid }, sensitive);
47
+ if (!candidates.some(candidate => candidate.guid === item.guid))
48
+ candidates.push({ guid: item.guid });
49
+ if (candidates.length > 50)
50
+ refuse('too many matching recovery candidates');
51
+ }
52
+ if (intent.operation === 'createComment') {
53
+ const comments = await client.getComments(intent.projectId, intent.topicGuid ?? '', { signal: options.signal });
54
+ if (!Array.isArray(comments) || comments.length > 50_000)
55
+ refuse('comment check exceeds work bound');
56
+ for (const comment of comments)
57
+ consider(comment);
58
+ }
59
+ else {
60
+ let complete = false;
61
+ // Bound requests as well as entities: a server-capped one-row page must
62
+ // not turn the former 250-page budget into 50,000 network round trips.
63
+ for (let skip = 0, pages = 0; skip <= 50_000 && pages <= 250; pages += 1) {
64
+ const page = await client.getTopics(intent.projectId, { top: 200, skip }, { signal: options.signal });
65
+ if (!Array.isArray(page) || page.length > 50_000)
66
+ refuse('invalid topic page');
67
+ // $top is a maximum: a server may cap it below 200. Only an empty page
68
+ // proves exhaustion, and advancing by actual length avoids skipping rows.
69
+ if (page.length === 0) {
70
+ complete = true;
71
+ break;
72
+ }
73
+ let fresh = 0;
74
+ for (const topic of page) {
75
+ if (!record(topic) || !text(topic.guid))
76
+ refuse('invalid server topic');
77
+ if (seen.has(topic.guid))
78
+ continue;
79
+ seen.add(topic.guid);
80
+ fresh += 1;
81
+ consider(topic);
82
+ }
83
+ if (seen.size > 50_000)
84
+ refuse('topic check exceeds work bound');
85
+ if (fresh === 0)
86
+ refuse('server ignored topic pagination');
87
+ skip += page.length;
88
+ }
89
+ // Partial enumeration cannot claim that an effect is absent.
90
+ if (!complete)
91
+ refuse('topic enumeration incomplete');
92
+ }
93
+ // An empty visible collection can hide a committed effect under another authority.
94
+ // Token presence does not prove visibility; only the operator can assert this scope.
95
+ const absenceConfirmed = !candidates.length && !incomparable && options.confirmFullReadAccess === true;
96
+ return { at: now.toISOString(), result: candidates.length ? NATIVE_METADATA.check.ambiguous
97
+ : absenceConfirmed ? NATIVE_METADATA.check.absent : NATIVE_METADATA.check.unavailable, candidates,
98
+ ...(absenceConfirmed ? { fullReadAccessConfirmed: NATIVE_METADATA.fullReadAccessConfirmed } : {}) };
99
+ }
100
+ //# sourceMappingURL=bcf-publication-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bcf-publication-check.js","sourceRoot":"","sources":["../src/bcf-publication-check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import type { BcfWriteIntent } from './bcf-write-gateway.js';
2
+ import type { StoredBcfAttempt, StoredBcfCheck, StoredBcfOutcome } from './bcf-publication-types.js';
3
+ export declare const MAX_RECORD_BYTES: number;
4
+ export declare const MAX_GENERATIONS = 256;
5
+ export declare const MAX_RECORDS: number;
6
+ export declare const MAX_CHECKS = 16;
7
+ /** Shared construction/decoding values; the representability guard must not drift from saved records. */
8
+ export declare const NATIVE_METADATA: {
9
+ readonly state: {
10
+ readonly done: "done";
11
+ readonly failed: "failed";
12
+ readonly uncertain: "uncertain";
13
+ readonly sending: "sending";
14
+ };
15
+ readonly evidence: {
16
+ readonly response: "response";
17
+ readonly reconciled: "reconciled";
18
+ };
19
+ readonly check: {
20
+ readonly absent: "absent";
21
+ readonly ambiguous: "ambiguous";
22
+ readonly unavailable: "unavailable";
23
+ };
24
+ readonly owner: {
25
+ readonly alive: "alive";
26
+ readonly dead: "dead";
27
+ readonly unknown: "unknown";
28
+ };
29
+ readonly fullReadAccessConfirmed: true;
30
+ readonly assertion: "owner-stopped";
31
+ readonly confirmedAbsent: "confirmed-absent";
32
+ readonly failures: string[];
33
+ readonly message: {
34
+ readonly refused: "The request was refused without a confirmed effect.";
35
+ readonly unknown: "The server outcome is unknown; check before sending again.";
36
+ readonly absent: "Explicitly confirmed absent after a successful server check.";
37
+ };
38
+ };
39
+ export declare const record: (v: unknown) => v is Record<string, unknown>;
40
+ export declare const text: (v: unknown) => v is string;
41
+ export declare function refuse(message: string): never;
42
+ export declare function hash(value: string): string;
43
+ /** Stable object-key ordering; arrays retain their intentional order. */
44
+ export declare function canonical(value: unknown): string;
45
+ export declare function credentialFree(value: unknown, secrets: readonly string[]): void;
46
+ /** Refuse an unrepresentable bearer before effect, never success followed by unreadable generated metadata. */
47
+ export declare function assertNativeRepresentable(secrets: readonly string[]): void;
48
+ export declare function normalizeIntent(value: unknown, secrets?: readonly string[]): BcfWriteIntent;
49
+ export declare function intentDigest(intent: BcfWriteIntent): string;
50
+ export declare function decodeAttempt(value: unknown, filename: string): StoredBcfAttempt;
51
+ export declare function decodeOutcome(value: unknown, attempt: StoredBcfAttempt, checked?: boolean): StoredBcfOutcome;
52
+ export declare function decodeCheck(value: unknown, attempt: StoredBcfAttempt, filename: string): StoredBcfCheck;
53
+ //# sourceMappingURL=bcf-publication-codec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bcf-publication-codec.d.ts","sourceRoot":"","sources":["../src/bcf-publication-codec.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAErG,eAAO,MAAM,gBAAgB,QAAa,CAAC;AAC3C,eAAO,MAAM,eAAe,MAAM,CAAC;AACnC,eAAO,MAAM,WAAW,QAAsB,CAAC;AAC/C,eAAO,MAAM,UAAU,KAAK,CAAC;AAY7B,yGAAyG;AACzG,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAUlB,CAAC;AACX,eAAO,MAAM,MAAM,GAAI,GAAG,OAAO,KAAG,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAsD,CAAC;AACtH,eAAO,MAAM,IAAI,GAAI,GAAG,OAAO,KAAG,CAAC,IAAI,MAAqE,CAAC;AAE7G,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAA4D;AAC1G,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAA6D;AAExG,yEAAyE;AACzE,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAIhD;AACD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAqB/E;AAED,+GAA+G;AAC/G,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAI1E;AAcD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,SAAS,MAAM,EAAO,GAAG,cAAc,CA+B/F;AACD,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAG3D;AACD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAahF;AACD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,OAAO,UAAQ,GAAG,gBAAgB,CA2B1G;AACD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,CAoBvG"}
@@ -0,0 +1,247 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { Buffer } from 'node:buffer';
5
+ import { createHash } from 'node:crypto';
6
+ import { normalizeBcfBaseUrl } from '@ifc-lite/bcf-api';
7
+ export const MAX_RECORD_BYTES = 256 * 1024;
8
+ export const MAX_GENERATIONS = 256;
9
+ export const MAX_RECORDS = 4 * MAX_GENERATIONS;
10
+ export const MAX_CHECKS = 16;
11
+ const TOPIC_FIELDS = ['title', 'topic_type', 'topic_status', 'priority', 'labels', 'assigned_to', 'stage', 'description', 'due_date'];
12
+ const COMMENT_FIELDS = ['comment', 'viewpoint_guid', 'reply_to_comment_guid'];
13
+ // These are protocol keys, not user credential data. Context-specific decoders
14
+ // still reject a known key appearing in the wrong record/payload location.
15
+ const SCHEMA_KEYS = new Set([...TOPIC_FIELDS, ...COMMENT_FIELDS,
16
+ 'nodeType', 'operation', 'baseUrl', 'version', 'projectId', 'topicGuid', 'payload', 'intent',
17
+ 'id', 'digest', 'generation', 'queuedAt', 'owner', 'pid', 'host', 'boot', 'domain', 'instance',
18
+ 'state', 'receipt', 'remoteGuid', 'at', 'evidence', 'failure', 'code', 'message', 'status',
19
+ 'checkId', 'check', 'result', 'candidates', 'fullReadAccessConfirmed', 'guid', 'candidateGuid', 'settlement', 'outcome', 'proofCheckId',
20
+ 'assertion', 'epoch', 'previous', 'attempt', 'checks', 'checkPending', 'reconciled', 'ownerStatus', 'ownerConfirmed']);
21
+ const FAILURES = ['auth', 'permission', 'rejected', 'no-response', 'server-error', 'conflict-exists', 'interrupted'];
22
+ /** Shared construction/decoding values; the representability guard must not drift from saved records. */
23
+ export const NATIVE_METADATA = {
24
+ state: { done: 'done', failed: 'failed', uncertain: 'uncertain', sending: 'sending' },
25
+ evidence: { response: 'response', reconciled: 'reconciled' },
26
+ check: { absent: 'absent', ambiguous: 'ambiguous', unavailable: 'unavailable' },
27
+ owner: { alive: 'alive', dead: 'dead', unknown: 'unknown' },
28
+ fullReadAccessConfirmed: true,
29
+ assertion: 'owner-stopped', confirmedAbsent: 'confirmed-absent', failures: FAILURES,
30
+ message: { refused: 'The request was refused without a confirmed effect.',
31
+ unknown: 'The server outcome is unknown; check before sending again.',
32
+ absent: 'Explicitly confirmed absent after a successful server check.' },
33
+ };
34
+ export const record = (v) => !!v && typeof v === 'object' && !Array.isArray(v);
35
+ export const text = (v) => typeof v === 'string' && v.length > 0 && v.length <= 20_000;
36
+ const date = (v) => text(v) && Number.isFinite(Date.parse(v));
37
+ export function refuse(message) { throw new Error(`BCF publication refused: ${message}`); }
38
+ export function hash(value) { return createHash('sha256').update(value).digest('hex'); }
39
+ /** Stable object-key ordering; arrays retain their intentional order. */
40
+ export function canonical(value) {
41
+ if (Array.isArray(value))
42
+ return `[${value.map(canonical).join(',')}]`;
43
+ if (record(value))
44
+ return `{${Object.keys(value).sort().map(k => `${JSON.stringify(k)}:${canonical(value[k])}`).join(',')}}`;
45
+ return JSON.stringify(value);
46
+ }
47
+ export function credentialFree(value, secrets) {
48
+ const serialized = JSON.stringify(value);
49
+ if (/authorization\s*:\s*bearer\s+|"Bearer (?=[A-Za-z0-9._~+/=-]*[0-9._~+/=-])[A-Za-z0-9._~+/=-]{8,}"|[?&](?:access_token|token|password|secret)=|"(?:authorization|password|access_token|token|secret)"\s*:/i.test(serialized))
50
+ refuse('credentials must not enter durable state');
51
+ const sensitive = secrets.filter(secret => secret.length > 0).map(secret => JSON.stringify(secret).slice(1, -1));
52
+ if (!sensitive.length)
53
+ return;
54
+ const reject = (item) => {
55
+ const encoded = JSON.stringify(item);
56
+ if (encoded !== undefined && sensitive.some(secret => encoded.includes(secret)))
57
+ refuse('credentials must not enter durable state');
58
+ };
59
+ const pending = [value];
60
+ while (pending.length) {
61
+ const item = pending.pop();
62
+ if (Array.isArray(item)) {
63
+ for (const field of item)
64
+ pending.push(field);
65
+ }
66
+ else if (record(item)) {
67
+ for (const [key, field] of Object.entries(item)) {
68
+ if (!SCHEMA_KEYS.has(key))
69
+ reject(key);
70
+ pending.push(field);
71
+ }
72
+ }
73
+ else
74
+ reject(item);
75
+ }
76
+ }
77
+ /** Refuse an unrepresentable bearer before effect, never success followed by unreadable generated metadata. */
78
+ export function assertNativeRepresentable(secrets) {
79
+ credentialFree([...Object.values(NATIVE_METADATA.state), ...Object.values(NATIVE_METADATA.evidence),
80
+ ...Object.values(NATIVE_METADATA.check), ...Object.values(NATIVE_METADATA.owner), ...NATIVE_METADATA.failures,
81
+ NATIVE_METADATA.assertion, NATIVE_METADATA.fullReadAccessConfirmed, NATIVE_METADATA.confirmedAbsent, ...Object.values(NATIVE_METADATA.message)], secrets);
82
+ }
83
+ function validatePayload(value, comment) {
84
+ if (!record(value))
85
+ refuse('invalid write payload');
86
+ const allowed = comment ? COMMENT_FIELDS : TOPIC_FIELDS;
87
+ if (Object.keys(value).some(k => !allowed.includes(k)) || !text(value[comment ? 'comment' : 'title']))
88
+ refuse('invalid write payload');
89
+ for (const [key, item] of Object.entries(value)) {
90
+ if (item === null || item === undefined)
91
+ continue;
92
+ if (key === 'labels') {
93
+ if (!Array.isArray(item) || item.length > 500 || !item.every(v => typeof v === 'string' && v.length <= 20_000))
94
+ refuse('invalid labels');
95
+ }
96
+ else if (typeof item !== 'string' || item.length > 20_000)
97
+ refuse('invalid payload field');
98
+ }
99
+ }
100
+ export function normalizeIntent(value, secrets = []) {
101
+ if (!record(value) || !text(value.nodeType) || !text(value.baseUrl) || !text(value.version) || !text(value.projectId)
102
+ || !['createTopic', 'createComment'].includes(String(value.operation)) || !record(value.payload))
103
+ refuse('invalid intent');
104
+ const keys = ['nodeType', 'operation', 'baseUrl', 'version', 'projectId', 'topicGuid', 'payload'];
105
+ if (Object.keys(value).some(k => !keys.includes(k)))
106
+ refuse('unknown intent fields');
107
+ let url;
108
+ try {
109
+ url = new URL(value.baseUrl);
110
+ }
111
+ catch {
112
+ refuse('invalid server URL');
113
+ }
114
+ if (url.protocol !== 'https:' || url.username || url.password || url.search || url.hash)
115
+ refuse('server URL must be credential-free HTTPS');
116
+ if (!/^[A-Za-z0-9.-]{1,32}$/.test(value.version))
117
+ refuse('invalid API version');
118
+ const comment = value.operation === 'createComment';
119
+ if (value.nodeType !== (comment ? 'bcf.addComment' : 'bcf.createTopic'))
120
+ refuse('node and operation disagree');
121
+ if (comment ? !text(value.topicGuid) : value.topicGuid !== undefined)
122
+ refuse('invalid topic target');
123
+ validatePayload(value.payload, comment);
124
+ let serialized;
125
+ try {
126
+ serialized = JSON.stringify(value.payload);
127
+ }
128
+ catch {
129
+ refuse('invalid write payload');
130
+ }
131
+ if (serialized === undefined)
132
+ refuse('invalid write payload');
133
+ if (Buffer.byteLength(serialized) > MAX_RECORD_BYTES / 2)
134
+ refuse('intent exceeds storage bound');
135
+ let payload;
136
+ try {
137
+ payload = JSON.parse(serialized);
138
+ }
139
+ catch {
140
+ refuse('invalid write payload');
141
+ }
142
+ validatePayload(payload, comment);
143
+ // Custom serialization errors must not expose their message/cause to callers.
144
+ try {
145
+ credentialFree(value, secrets);
146
+ }
147
+ catch {
148
+ refuse('credentials must not enter durable state');
149
+ }
150
+ // Canonical identity must match the exact JSON schema persisted on disk.
151
+ // Spreading an own undefined optional key hashes data that JSON omits.
152
+ const normalized = { nodeType: value.nodeType, operation: comment ? 'createComment' : 'createTopic',
153
+ baseUrl: normalizeBcfBaseUrl(value.baseUrl), version: value.version, projectId: value.projectId,
154
+ ...(comment && text(value.topicGuid) ? { topicGuid: value.topicGuid } : {}),
155
+ payload };
156
+ credentialFree(normalized, secrets);
157
+ if (Buffer.byteLength(JSON.stringify(normalized)) > MAX_RECORD_BYTES / 2)
158
+ refuse('intent exceeds storage bound');
159
+ return normalized;
160
+ }
161
+ export function intentDigest(intent) {
162
+ const { nodeType: _nodeType, ...effect } = intent;
163
+ return hash(canonical(effect));
164
+ }
165
+ export function decodeAttempt(value, filename) {
166
+ if (!record(value) || value.version !== 1 || !text(value.id) || !text(value.digest) || !Number.isSafeInteger(value.generation)
167
+ || Number(value.generation) < 1 || !date(value.queuedAt) || !record(value.owner) || !Number.isSafeInteger(value.owner.pid)
168
+ || Number(value.owner.pid) < 1 || !text(value.owner.host) || !/^[a-f0-9]{64}$/.test(value.owner.host)
169
+ || Object.keys(value.owner).some(k => !['pid', 'host', 'boot', 'domain', 'instance'].includes(k)))
170
+ refuse('malformed attempt');
171
+ const owner = value.owner;
172
+ if (['boot', 'domain', 'instance'].some(k => owner[k] !== undefined)
173
+ && !['boot', 'domain', 'instance'].every(k => typeof owner[k] === 'string' && /^[a-f0-9]{64}$/.test(owner[k])))
174
+ refuse('incomplete owner identity');
175
+ const intent = normalizeIntent(value.intent);
176
+ if (canonical(value.intent) !== canonical(intent) || value.digest !== intentDigest(intent)
177
+ || value.id !== `${value.digest}-${value.generation}` || filename !== `${value.id}.intent.json`)
178
+ refuse('attempt identity mismatch');
179
+ if (Object.keys(value).some(k => !['version', 'id', 'digest', 'generation', 'intent', 'queuedAt', 'owner'].includes(k)))
180
+ refuse('unknown attempt fields');
181
+ return value;
182
+ }
183
+ export function decodeOutcome(value, attempt, checked = false) {
184
+ if (!record(value) || value.version !== 1 || value.id !== attempt.id || value.digest !== attempt.digest
185
+ || !['done', 'failed', 'uncertain'].includes(String(value.state)))
186
+ refuse('malformed outcome');
187
+ if (Object.keys(value).some(k => !['version', 'id', 'digest', 'state', 'receipt', 'failure'].includes(k)))
188
+ refuse('unknown outcome fields');
189
+ if (value.state === 'done') {
190
+ const r = value.receipt;
191
+ if (value.failure !== undefined || !record(r) || !text(r.remoteGuid) || !date(r.at)
192
+ || !['response', 'reconciled'].includes(String(r.evidence)) || (!checked && r.evidence !== 'response')
193
+ || Object.keys(r).some(k => !['remoteGuid', 'at', 'evidence'].includes(k)))
194
+ refuse('invalid receipt');
195
+ }
196
+ else {
197
+ const f = value.failure;
198
+ if (value.receipt !== undefined || !record(f) || !(FAILURES.includes(String(f.code)) || (checked && f.code === 'confirmed-absent')) || !text(f.message) || !date(f.at)
199
+ || (f.status !== undefined && (!Number.isInteger(f.status) || Number(f.status) < 0 || Number(f.status) > 599))
200
+ || Object.keys(f).some(k => !['code', 'message', 'at', 'status'].includes(k)))
201
+ refuse('invalid failure');
202
+ }
203
+ if (value.state === 'failed' && record(value.failure) && !['auth', 'permission', 'rejected', ...(checked ? ['confirmed-absent'] : [])].includes(String(value.failure.code)))
204
+ refuse('uncertain failure marked definite');
205
+ if (value.state === 'uncertain' && record(value.failure) && !['no-response', 'server-error', 'conflict-exists', 'interrupted'].includes(String(value.failure.code)))
206
+ refuse('definite failure marked uncertain');
207
+ if (record(value.failure)) {
208
+ const { code, status } = value.failure;
209
+ if ((code === 'auth' && status !== 401) || (code === 'permission' && status !== undefined && status !== 403)
210
+ || (code === 'server-error' && (typeof status !== 'number' || status < 500))
211
+ || (code === 'conflict-exists' && status !== 409)
212
+ || (code === 'rejected' && (typeof status !== 'number' || status < 400 || status >= 500 || [401, 403, 409].includes(status)))
213
+ || (['no-response', 'interrupted', 'confirmed-absent'].includes(String(code)) && status !== undefined && status !== 0))
214
+ refuse('failure status contradicts classification');
215
+ }
216
+ credentialFree(value, []);
217
+ return value;
218
+ }
219
+ export function decodeCheck(value, attempt, filename) {
220
+ if (!record(value) || value.version !== 1 || value.id !== attempt.id || value.digest !== attempt.digest || !text(value.checkId)
221
+ || !/^[1-9][0-9]{0,15}$/.test(value.checkId) || !Number.isSafeInteger(Number(value.checkId)) || (filename !== `${attempt.id}.check-${value.checkId}.json` && filename !== `${attempt.id}.checked-${value.checkId}.json`) || !record(value.check))
222
+ refuse('malformed check');
223
+ const c = value.check;
224
+ if (!date(c.at) || !['absent', 'ambiguous', 'unavailable'].includes(String(c.result)) || !Array.isArray(c.candidates)
225
+ || c.candidates.length > 50 || !c.candidates.every(v => record(v) && text(v.guid) && Object.keys(v).length === 1)
226
+ || (c.result !== 'ambiguous' && c.candidates.length > 0)
227
+ || (c.fullReadAccessConfirmed !== undefined && (c.fullReadAccessConfirmed !== true || c.result !== 'absent'))
228
+ || Object.keys(c).some(k => !['at', 'result', 'candidates', 'fullReadAccessConfirmed'].includes(k))
229
+ || Object.keys(value).some(k => !['version', 'id', 'digest', 'checkId', 'check', 'settlement'].includes(k)))
230
+ refuse('invalid checked candidates');
231
+ if (value.settlement !== undefined) {
232
+ const settled = value.settlement;
233
+ if (!record(settled) || !text(settled.proofCheckId) || Object.keys(settled).some(k => !['outcome', 'proofCheckId'].includes(k)))
234
+ refuse('malformed settlement');
235
+ const outcome = decodeOutcome(settled.outcome, attempt, true);
236
+ if (!(outcome.state === 'done' && outcome.receipt?.evidence === 'reconciled')
237
+ && !(outcome.state === 'failed' && outcome.failure?.code === 'confirmed-absent'))
238
+ refuse('invalid settlement receipt');
239
+ if (filename.includes('.checked-'))
240
+ refuse('check response cannot settle an intent');
241
+ }
242
+ else if (filename.includes('.check-') && (c.result !== 'unavailable' || c.candidates.length))
243
+ refuse('check reservation must be unavailable');
244
+ credentialFree(value, []);
245
+ return value;
246
+ }
247
+ //# sourceMappingURL=bcf-publication-codec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bcf-publication-codec.js","sourceRoot":"","sources":["../src/bcf-publication-codec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { StoredBcfAttempt, StoredBcfCheck } from './bcf-publication-types.js';
2
+ export interface BcfCheckEpoch {
3
+ version: 1;
4
+ id: string;
5
+ digest: string;
6
+ epoch: number;
7
+ previous?: StoredBcfCheck;
8
+ }
9
+ export declare function epochOf(checkId: string): number;
10
+ /** Contiguous immutable markers permit bounded lookup; archived epoch bodies are never walked. */
11
+ export declare function loadCheckEpoch(attempt: StoredBcfAttempt, read: (epoch: number, filename: string) => Promise<unknown>): Promise<{
12
+ checks: StoredBcfCheck[];
13
+ pending: boolean;
14
+ }>;
15
+ /** Existing marker must contain the same immutable predecessor proof. */
16
+ export declare function verifyCheckEpoch(value: unknown, expected: BcfCheckEpoch, attempt: StoredBcfAttempt): void;
17
+ //# sourceMappingURL=bcf-publication-epochs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bcf-publication-epochs.d.ts","sourceRoot":"","sources":["../src/bcf-publication-epochs.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAInF,MAAM,WAAW,aAAa;IAAG,OAAO,EAAE,CAAC,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,cAAc,CAAA;CAAE;AACnH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAM/C;AAcD,kGAAkG;AAClG,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,EAC5D,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAwCtH;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAEzG"}