@farmslot/protocol 0.80.0 → 0.82.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 (37) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/contracts/recipes.d.ts +4 -0
  3. package/dist/contracts/recipes.d.ts.map +1 -1
  4. package/dist/contracts/recipes.js +3 -0
  5. package/dist/contracts/recipes.js.map +1 -1
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +2 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/node/node-pty-helper.d.ts +3 -0
  11. package/dist/node/node-pty-helper.d.ts.map +1 -0
  12. package/dist/node/node-pty-helper.js +33 -0
  13. package/dist/node/node-pty-helper.js.map +1 -0
  14. package/dist/node/slot-by-repo.d.ts +3 -0
  15. package/dist/node/slot-by-repo.d.ts.map +1 -1
  16. package/dist/node/slot-by-repo.js +26 -0
  17. package/dist/node/slot-by-repo.js.map +1 -1
  18. package/dist/rpc/nodes.d.ts +7 -0
  19. package/dist/rpc/nodes.d.ts.map +1 -1
  20. package/dist/rpc/nodes.js.map +1 -1
  21. package/dist/transport/node-link-operations.d.ts +178 -0
  22. package/dist/transport/node-link-operations.d.ts.map +1 -0
  23. package/dist/transport/node-link-operations.js +69 -0
  24. package/dist/transport/node-link-operations.js.map +1 -0
  25. package/dist/transport/node-link.d.ts +106 -0
  26. package/dist/transport/node-link.d.ts.map +1 -0
  27. package/dist/transport/node-link.js +98 -0
  28. package/dist/transport/node-link.js.map +1 -0
  29. package/dist/version.d.ts +1 -1
  30. package/dist/version.js +1 -1
  31. package/package.json +20 -3
  32. package/recipe-shape.d.mts +91 -0
  33. package/recipe-shape.mjs +532 -0
  34. package/scripts/acceptance.d.mts +6 -0
  35. package/scripts/acceptance.mjs +11 -0
  36. package/scripts/recipe-library-identity.d.mts +17 -0
  37. package/scripts/recipe-library-identity.mjs +45 -0
@@ -0,0 +1,106 @@
1
+ export declare const NODE_LINK_RECEIPT_RETENTION_MS: number;
2
+ /** ADR-008 Amendment 3. Infrastructure identity is independent of runner transport. */
3
+ export declare const NODE_LINK_LIMITS: {
4
+ readonly frameBytes: number;
5
+ readonly chunkBytes: number;
6
+ readonly queuedBytes: number;
7
+ readonly inFlight: 32;
8
+ readonly reservedControl: 8;
9
+ readonly streamBytes: number;
10
+ };
11
+ export interface NodeLinkCapabilities {
12
+ commands?: 1;
13
+ operations?: import('./node-link-operations.js').NodeLinkOperation[];
14
+ streams?: 1;
15
+ }
16
+ export interface NodeLinkPrincipal {
17
+ principalId: string;
18
+ generation: number;
19
+ }
20
+ export interface NodeLinkLease {
21
+ runId: string;
22
+ contextId: string;
23
+ leaseId: string;
24
+ generation: string;
25
+ }
26
+ export interface NodeLinkAuthority {
27
+ requester: NodeLinkPrincipal | {
28
+ kind: 'system';
29
+ };
30
+ executor: NodeLinkPrincipal;
31
+ grantId: string;
32
+ approvalId: string;
33
+ approval: 'ask' | 'bypass' | 'framework';
34
+ lease?: NodeLinkLease;
35
+ }
36
+ /** A resource reference is resolved by its adapter, never by a runner-name branch. */
37
+ export interface NodeLinkTarget {
38
+ nodeId: string;
39
+ resourceId: string;
40
+ }
41
+ export interface NodeLinkCommand<Input = unknown> {
42
+ commandId: string;
43
+ operation: string;
44
+ target: NodeLinkTarget;
45
+ authority: NodeLinkAuthority;
46
+ expiresAt: number;
47
+ input: Input;
48
+ }
49
+ export type NodeLinkCommandState = 'admitted' | 'running' | 'cancel-requested' | 'completed' | 'failed' | 'cancelled' | 'unknown';
50
+ export interface NodeLinkError {
51
+ code: string;
52
+ message: string;
53
+ }
54
+ /** Audit metadata contains identifiers/digests only. Protected result payloads stay separate. */
55
+ export interface NodeLinkReceipt<Result = unknown> {
56
+ commandId: string;
57
+ digest: string;
58
+ target: NodeLinkTarget;
59
+ authority: NodeLinkAuthority;
60
+ operation: string;
61
+ expiresAt: number;
62
+ admittedAt: number;
63
+ state: NodeLinkCommandState;
64
+ closeoutConfirmed: boolean;
65
+ settledAt?: number;
66
+ result?: Result;
67
+ error?: NodeLinkError;
68
+ }
69
+ export interface NodeLinkCursor {
70
+ streamId: string;
71
+ incarnation: string;
72
+ offset: number;
73
+ }
74
+ export interface NodeLinkStreamFrame<Payload = unknown> extends NodeLinkCursor {
75
+ authority: NodeLinkAuthority;
76
+ target: NodeLinkTarget;
77
+ payload: Payload;
78
+ }
79
+ export type NodeLinkResumeResult<Payload = unknown> = {
80
+ kind: 'replay';
81
+ frames: NodeLinkStreamFrame<Payload>[];
82
+ cursor: NodeLinkCursor;
83
+ } | {
84
+ kind: 'reset';
85
+ reason: 'expired' | 'gap' | 'source-replaced';
86
+ snapshot: Payload;
87
+ cursor: NodeLinkCursor;
88
+ };
89
+ export declare class NodeLinkFailure extends Error {
90
+ readonly code: string;
91
+ readonly details?: {
92
+ admitted: false;
93
+ } | undefined;
94
+ constructor(code: string, message: string, details?: {
95
+ admitted: false;
96
+ } | undefined);
97
+ }
98
+ export declare function isNodeLinkTerminal(state: NodeLinkCommandState): boolean;
99
+ export declare function isNodeLinkPrincipal(value: unknown): value is NodeLinkPrincipal;
100
+ export declare function isNodeLinkAuthority(value: unknown): value is NodeLinkAuthority;
101
+ export declare function isNodeLinkTarget(value: unknown): value is NodeLinkTarget;
102
+ /** Deadline-bearing keys remain expired after their settled receipt has been pruned. */
103
+ export declare function nodeLinkCommandDeadline(commandId: string): number | undefined;
104
+ export declare function isNodeLinkCommand(value: unknown): value is NodeLinkCommand;
105
+ export declare function isNodeLinkReceipt(value: unknown): value is NodeLinkReceipt;
106
+ //# sourceMappingURL=node-link.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-link.d.ts","sourceRoot":"","sources":["../../src/transport/node-link.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ export const NODE_LINK_RECEIPT_RETENTION_MS = 5 * 60_000;
2
+ /** ADR-008 Amendment 3. Infrastructure identity is independent of runner transport. */
3
+ export const NODE_LINK_LIMITS = {
4
+ frameBytes: 1024 * 1024,
5
+ chunkBytes: 64 * 1024,
6
+ queuedBytes: 8 * 1024 * 1024,
7
+ inFlight: 32,
8
+ reservedControl: 8,
9
+ streamBytes: 256 * 1024,
10
+ };
11
+ export class NodeLinkFailure extends Error {
12
+ constructor(code, message, details) {
13
+ super(message);
14
+ this.code = code;
15
+ this.details = details;
16
+ this.name = 'NodeLinkFailure';
17
+ }
18
+ }
19
+ export function isNodeLinkTerminal(state) {
20
+ return state === 'completed' || state === 'failed' || state === 'cancelled';
21
+ }
22
+ function record(value) {
23
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
24
+ }
25
+ const identity = (value) => typeof value === 'string' && value.length > 0 && value.length <= 512;
26
+ const finite = (value) => typeof value === 'number' && Number.isFinite(value);
27
+ export function isNodeLinkPrincipal(value) {
28
+ return (record(value) &&
29
+ identity(value.principalId) &&
30
+ Number.isSafeInteger(value.generation) &&
31
+ typeof value.generation === 'number' &&
32
+ value.generation >= 0);
33
+ }
34
+ export function isNodeLinkAuthority(value) {
35
+ if (!record(value) ||
36
+ !isNodeLinkPrincipal(value.executor) ||
37
+ !identity(value.grantId) ||
38
+ !identity(value.approvalId) ||
39
+ !['ask', 'bypass', 'framework'].includes(String(value.approval)))
40
+ return false;
41
+ if (!isNodeLinkPrincipal(value.requester) &&
42
+ !(record(value.requester) && value.requester.kind === 'system'))
43
+ return false;
44
+ const lease = value.lease;
45
+ return (lease === undefined ||
46
+ (record(lease) &&
47
+ ['runId', 'contextId', 'leaseId', 'generation'].every((field) => identity(lease[field]))));
48
+ }
49
+ export function isNodeLinkTarget(value) {
50
+ return record(value) && identity(value.nodeId) && identity(value.resourceId);
51
+ }
52
+ /** Deadline-bearing keys remain expired after their settled receipt has been pruned. */
53
+ export function nodeLinkCommandDeadline(commandId) {
54
+ const match = /^nl1:([0-9]{1,16}):[^:]+$/.exec(commandId);
55
+ if (!match)
56
+ return undefined;
57
+ const deadline = Number(match[1]);
58
+ return Number.isSafeInteger(deadline) && deadline > 0 ? deadline : undefined;
59
+ }
60
+ export function isNodeLinkCommand(value) {
61
+ return (record(value) &&
62
+ identity(value.commandId) &&
63
+ identity(value.operation) &&
64
+ isNodeLinkTarget(value.target) &&
65
+ isNodeLinkAuthority(value.authority) &&
66
+ finite(value.expiresAt) &&
67
+ (!value.commandId.startsWith('nl1:') ||
68
+ nodeLinkCommandDeadline(value.commandId) === value.expiresAt) &&
69
+ Object.hasOwn(value, 'input') &&
70
+ Object.keys(value).every((key) => ['commandId', 'operation', 'target', 'authority', 'expiresAt', 'input'].includes(key)));
71
+ }
72
+ export function isNodeLinkReceipt(value) {
73
+ return (record(value) &&
74
+ identity(value.commandId) &&
75
+ typeof value.digest === 'string' &&
76
+ /^[a-f0-9]{64}$/.test(value.digest) &&
77
+ identity(value.operation) &&
78
+ isNodeLinkTarget(value.target) &&
79
+ isNodeLinkAuthority(value.authority) &&
80
+ finite(value.expiresAt) &&
81
+ finite(value.admittedAt) &&
82
+ [
83
+ 'admitted',
84
+ 'running',
85
+ 'cancel-requested',
86
+ 'completed',
87
+ 'failed',
88
+ 'cancelled',
89
+ 'unknown',
90
+ ].includes(String(value.state)) &&
91
+ typeof value.closeoutConfirmed === 'boolean' &&
92
+ (value.settledAt === undefined || finite(value.settledAt)) &&
93
+ (value.error === undefined ||
94
+ (record(value.error) &&
95
+ identity(value.error.code) &&
96
+ typeof value.error.message === 'string')));
97
+ }
98
+ //# sourceMappingURL=node-link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-link.js","sourceRoot":"","sources":["../../src/transport/node-link.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare const PROTOCOL_VERSION = "0.80.0";
1
+ export declare const PROTOCOL_VERSION = "0.82.0";
2
2
  /** Node-facing additions since this release remain additive or capability-gated. */
3
3
  export declare const MINIMUM_PROTOCOL_VERSION = "0.76.0";
4
4
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // Published protocol release plus an explicit oldest-supported peer.
2
2
  // Different release numbers are harmless when both declared bounds are met;
3
3
  // optional methods/events still require their existing feature capabilities.
4
- export const PROTOCOL_VERSION = '0.80.0';
4
+ export const PROTOCOL_VERSION = '0.82.0';
5
5
  /** Node-facing additions since this release remain additive or capability-gated. */
6
6
  export const MINIMUM_PROTOCOL_VERSION = '0.76.0';
7
7
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farmslot/protocol",
3
- "version": "0.80.0",
3
+ "version": "0.82.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -365,6 +365,11 @@
365
365
  "import": "./dist/node/farm-layout.js",
366
366
  "default": "./dist/node/farm-layout.js"
367
367
  },
368
+ "./node/node-pty-helper": {
369
+ "types": "./dist/node/node-pty-helper.d.ts",
370
+ "import": "./dist/node/node-pty-helper.js",
371
+ "default": "./dist/node/node-pty-helper.js"
372
+ },
368
373
  "./node/loopback-host": {
369
374
  "types": "./dist/node/loopback-host.d.ts",
370
375
  "import": "./dist/node/loopback-host.js",
@@ -397,6 +402,14 @@
397
402
  "types": "./dist/performance/index.d.ts",
398
403
  "import": "./dist/performance/index.js",
399
404
  "default": "./dist/performance/index.js"
405
+ },
406
+ "./recipe-shape.mjs": {
407
+ "types": "./recipe-shape.d.mts",
408
+ "default": "./recipe-shape.mjs"
409
+ },
410
+ "./scripts/recipe-library-identity.mjs": {
411
+ "types": "./scripts/recipe-library-identity.d.mts",
412
+ "default": "./scripts/recipe-library-identity.mjs"
400
413
  }
401
414
  },
402
415
  "scripts": {
@@ -405,7 +418,7 @@
405
418
  "format:check": "prettier --check --ignore-path ../../.prettierignore .",
406
419
  "lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\"",
407
420
  "lint:fix": "eslint \"src/**/*.ts\" \"test/**/*.ts\" --fix",
408
- "test": "yarn build && node ../../scripts/quality/run-tsx-tests.mjs --cwd . --tsconfig tsconfig.json test",
421
+ "test": "yarn build && node --test test/recipe-shape.test.cjs && node ../../scripts/quality/run-tsx-tests.mjs --cwd . --tsconfig tsconfig.json test",
409
422
  "quality": "prettier --check --ignore-path ../../.prettierignore . && eslint \"src/**/*.ts\" \"test/**/*.ts\" && tsc --noEmit --project tsconfig.json && yarn test",
410
423
  "build": "rm -rf dist && tsc --project tsconfig.json",
411
424
  "prepack": "cd ../.. && node scripts/quality/check-farmslot-package-readiness.mjs --require-changelog --packages @farmslot/protocol && yarn workspace @farmslot/protocol build",
@@ -448,7 +461,11 @@
448
461
  "scripts/acceptance.d.cts",
449
462
  "scripts/acceptance.d.mts",
450
463
  "scripts/review-approval-policy.cjs",
451
- "scripts/review-approval-policy.d.cts"
464
+ "scripts/review-approval-policy.d.cts",
465
+ "recipe-shape.mjs",
466
+ "recipe-shape.d.mts",
467
+ "scripts/recipe-library-identity.mjs",
468
+ "scripts/recipe-library-identity.d.mts"
452
469
  ],
453
470
  "publishConfig": {
454
471
  "access": "public"
@@ -0,0 +1,91 @@
1
+ export interface RecipeShapeCriterion {
2
+ id: string;
3
+ text?: string;
4
+ proofMode?: string;
5
+ }
6
+ export interface RecipeShapeBlock {
7
+ id: string;
8
+ ref?: string;
9
+ tokens?: string[];
10
+ sig?: string[];
11
+ }
12
+ export interface RecipeShapeSource {
13
+ name: string;
14
+ revision: string | null;
15
+ fingerprint: string | null;
16
+ }
17
+ export interface RecipeShapeCatalog {
18
+ adapter?: string | null;
19
+ available: boolean;
20
+ blocks: RecipeShapeBlock[];
21
+ sources: RecipeShapeSource[];
22
+ }
23
+ export interface RecipeShapeInput {
24
+ recipe: unknown;
25
+ nonLocalCriteria?: string[];
26
+ criteria?: RecipeShapeCriterion[] | null;
27
+ catalog?: RecipeShapeCatalog | null;
28
+ }
29
+ export interface RecipeShapeHint {
30
+ kind: 'parameterize' | 'compose' | 'shorten' | 'acceptance' | 'catalog';
31
+ message: string;
32
+ field?: string;
33
+ nodes?: string[];
34
+ flow?: string;
35
+ ref?: string;
36
+ criterionId?: string;
37
+ }
38
+ export interface RecipeShapeFeedback {
39
+ policyVersion: number;
40
+ inputIdentity: { recipe: string; criteria: string; catalog: string };
41
+ nodes: number;
42
+ calls: number;
43
+ templatedValues: number;
44
+ literalValues: number;
45
+ short: number;
46
+ composed: number | null;
47
+ parameterized: number;
48
+ inlineDuplicates: { flow: string; ref?: string; nodes: string[] }[];
49
+ goodShape: boolean;
50
+ acCoverage: {
51
+ nonLocal: string[];
52
+ available: boolean;
53
+ expected: string[];
54
+ covered: string[];
55
+ missing: string[];
56
+ reviewOnly: string[];
57
+ unexpected: string[];
58
+ complete: boolean;
59
+ };
60
+ eligibleForImitation: boolean;
61
+ catalogTrust: 'worker-supplied-self-consistent';
62
+ status: 'ok' | 'warn' | 'unavailable';
63
+ hints: RecipeShapeHint[];
64
+ }
65
+ export const POLICY_VERSION: number;
66
+ export const RECIPE_SHAPE_POLICY: Readonly<{
67
+ short: Readonly<{ good: number; max: number }>;
68
+ positive: Readonly<{ short: number; composed: number; parameterized: number }>;
69
+ skipValueKeys: string;
70
+ selectorKeys: string;
71
+ }>;
72
+ export function stableDigest(value: unknown): string;
73
+ export function inspectRecipeShape(recipe: {
74
+ workflow?: { entry?: string; teardown?: string; nodes?: Record<string, unknown> };
75
+ }): { order: string[]; reachable: string[]; tokens: string[]; signature: string[] };
76
+ export function recipeShapeNodeToken(node: Record<string, unknown>): string;
77
+ export function recipeShapeSignature(tokens: string[]): string[];
78
+ export function isRecipeShapeObservation(action?: string): boolean;
79
+ export function scoreRecipeShape(input: RecipeShapeInput): RecipeShapeFeedback;
80
+ export function isRecipeShapeFeedback(value: unknown): value is RecipeShapeFeedback;
81
+
82
+ export function recipeShapeLibraryRef(
83
+ name: string | null,
84
+ relativePath: string,
85
+ platforms?: string[],
86
+ adapter?: string,
87
+ ): string | null;
88
+ export function recipeShapeBlock(ref: string, recipe: unknown): RecipeShapeBlock | null;
89
+ export function processShapeRequest(request: Record<string, unknown>): unknown;
90
+
91
+ export function recipeShapeSelector(node: Record<string, unknown>): string | null;