@pulse-compute/wasm-contracts 0.0.0 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/README.md +34 -2
  2. package/package.json +123 -6
  3. package/src/assets/contracts.js +296 -0
  4. package/src/config/provider-resolution.js +54 -0
  5. package/src/config/runtime-provider-kv.js +73 -0
  6. package/src/config/symbolic-refs.js +192 -0
  7. package/src/crypto/contracts.js +637 -0
  8. package/src/definitions/config-schema.js +30 -0
  9. package/src/definitions/handler-roles.js +66 -0
  10. package/src/definitions/path-grammar.js +11 -0
  11. package/src/definitions/router-api.js +146 -0
  12. package/src/diagnostics/codes.js +42 -0
  13. package/src/diagnostics/reporter.js +20 -0
  14. package/src/diagnostics.js +139 -0
  15. package/src/dispatch-table.js +23 -0
  16. package/src/entities/catalog.d.ts +7 -0
  17. package/src/entities/catalog.js +87 -0
  18. package/src/entities/contracts.d.ts +95 -0
  19. package/src/entities/contracts.js +122 -0
  20. package/src/entities/json-rpc.d.ts +27 -0
  21. package/src/entities/json-rpc.js +69 -0
  22. package/src/entities/runtime.d.ts +67 -0
  23. package/src/entities/runtime.js +288 -0
  24. package/src/events/contracts.js +456 -0
  25. package/src/execution-plan.js +42 -0
  26. package/src/grip/contracts.js +106 -0
  27. package/src/handler/backend-json-request-body.js +58 -0
  28. package/src/handler/beta-lifecycle-golden.js +97 -0
  29. package/src/handler/canonical-native-plan.js +143 -0
  30. package/src/handler/canonical-native-runtime.js +168 -0
  31. package/src/handler/canonical-runtime.js +13 -0
  32. package/src/handler/context.js +131 -0
  33. package/src/handler/ctx-contract.js +71 -0
  34. package/src/handler/doctor-readiness-aggregator.js +67 -0
  35. package/src/handler/effects.js +446 -0
  36. package/src/handler/io-lifecycle.js +134 -0
  37. package/src/handler/lifecycle-authoring-alignment.js +52 -0
  38. package/src/handler/lifecycle-readiness-aggregate.js +93 -0
  39. package/src/handler/reference-node-lifecycle-golden.js +73 -0
  40. package/src/handler/request-json-body.js +147 -0
  41. package/src/handler/runtime-api.js +471 -0
  42. package/src/handler/schema-decode-result.js +135 -0
  43. package/src/handler/schema-response-codec.js +141 -0
  44. package/src/handler/surface-contract.js +594 -0
  45. package/src/handler/types-contract.js +51 -0
  46. package/src/handler-table.js +28 -0
  47. package/src/host/backend-capabilities.js +24 -0
  48. package/src/host/capabilities.js +273 -0
  49. package/src/host/channel-broadcaster.js +60 -0
  50. package/src/host/json-body.js +80 -0
  51. package/src/host/request-result-headers.js +38 -0
  52. package/src/host/streaming-passthrough.js +90 -0
  53. package/src/host/wasm-host-abi.js +154 -0
  54. package/src/index.js +75 -0
  55. package/src/jwt/contracts.js +427 -0
  56. package/src/library/api-surface.js +99 -0
  57. package/src/library/contracts.js +273 -0
  58. package/src/library/manifest.js +317 -0
  59. package/src/library/second-package-owned-lowering.js +39 -0
  60. package/src/library/sidecars.js +147 -0
  61. package/src/logging.js +89 -0
  62. package/src/package/package-contract.js +975 -0
  63. package/src/package/package-contract.schema.json +303 -0
  64. package/src/package/runtime-pulse-live.js +100 -0
  65. package/src/path-table.js +12 -0
  66. package/src/path.js +275 -0
  67. package/src/project/config-factory.js +48 -0
  68. package/src/project/config-plan.js +409 -0
  69. package/src/project/config-runtime.js +46 -0
  70. package/src/project/javascript-application.js +212 -0
  71. package/src/project/javascript-core-capabilities.js +44 -0
  72. package/src/project/native-optimization.js +9 -0
  73. package/src/project/package-ownership.js +242 -0
  74. package/src/project/package-product-projection.js +171 -0
  75. package/src/project/reachable-graph-identity.js +219 -0
  76. package/src/project/reachable-graph-projections.js +279 -0
  77. package/src/project/reachable-graph-resolver.js +303 -0
  78. package/src/project/reachable-graph-v2.js +430 -0
  79. package/src/project/reachable-graph-v2.schema.json +285 -0
  80. package/src/project/reachable-graph.js +199 -0
  81. package/src/project/reachable-graph.schema.json +222 -0
  82. package/src/project/target-support-evidence.js +559 -0
  83. package/src/provider/canonical-provider.js +235 -0
  84. package/src/provider/final-wasm-policy.js +87 -0
  85. package/src/provider/toolchain.js +771 -0
  86. package/src/route-plan.js +43 -0
  87. package/src/schema-json/compile.js +63 -0
  88. package/src/schema-json/contracts.js +10 -0
  89. package/src/schema-json/generic-parser.js +62 -0
  90. package/src/schema-json/registry.js +359 -0
  91. package/src/schema-json/semantic-trace.js +241 -0
  92. package/src/schema-json/v1.js +65 -0
  93. package/src/schema-json/v2.js +110 -0
  94. package/src/sha256.js +104 -0
  95. package/src/spine.js +381 -0
  96. package/src/stable-id.js +142 -0
@@ -0,0 +1,39 @@
1
+ 'use strict';
2
+
3
+ const SECOND_PACKAGE_OWNED_LOWERING_PROOF_VERSION = 'pulsewasm.second-package-owned-lowering-proof.v1';
4
+ const SECOND_PACKAGE_OWNED_LOWERING_PROOF_ARTIFACT = 'second-package-owned-lowering-proof.json';
5
+ const GRIP_LOWERING_PLAN_VERSION = 'pulsewasm.grip-lowering-plan.v1';
6
+ const GRIP_LOWERING_PLAN_ARTIFACT = 'grip-lowering-plan.json';
7
+
8
+ const SECOND_PACKAGE_OWNED_LOWERING_SCOPE = Object.freeze({
9
+ phase: '54',
10
+ firstPackage: '@pulse-compute/assets',
11
+ secondPackage: '@pulse-compute/grip',
12
+ firstContractId: 'pulse.assets',
13
+ secondContractId: 'pulse.grip',
14
+ purpose: 'Prove the lowerable package protocol is not assets-specific by adding a second package-owned manifest/facade/compiler-builder/sidecar surface.',
15
+ productionRuntimeRequired: false,
16
+ providerRuntimeRequired: false
17
+ });
18
+
19
+ const SECOND_PACKAGE_OWNED_LOWERING_POLICY = Object.freeze({
20
+ packageOwnsFacade: true,
21
+ packageOwnsManifest: true,
22
+ packageOwnsCompilerBuilder: true,
23
+ packageOwnsSidecarDeclaration: true,
24
+ libraryKitOwnsGenericDiscovery: true,
25
+ compilerOwnsPackageMapping: false,
26
+ arbitraryThirdPartyLowererExecution: false,
27
+ firstPartyTrustRequired: true,
28
+ productionGripRuntimeBehavior: false,
29
+ betaProtocolBreadthOverProductionCompleteness: true
30
+ });
31
+
32
+ module.exports = {
33
+ SECOND_PACKAGE_OWNED_LOWERING_PROOF_VERSION,
34
+ SECOND_PACKAGE_OWNED_LOWERING_PROOF_ARTIFACT,
35
+ GRIP_LOWERING_PLAN_VERSION,
36
+ GRIP_LOWERING_PLAN_ARTIFACT,
37
+ SECOND_PACKAGE_OWNED_LOWERING_SCOPE,
38
+ SECOND_PACKAGE_OWNED_LOWERING_POLICY
39
+ };
@@ -0,0 +1,147 @@
1
+ 'use strict';
2
+
3
+ const { normalizeDiagnostic } = require('../diagnostics.js');
4
+ const {
5
+ LIBRARY_CONTRACT_VERSION,
6
+ ALLOWED_HOST_CAPABILITIES,
7
+ normalizeContractModeKeys
8
+ } = require('./contracts.js');
9
+ const LIBRARY_SIDECAR_PHASE = '12C';
10
+ const LIBRARY_SIDECAR_CONSUMPTION_VERSION = 'pulsewasm.library-sidecar-consumption.v1';
11
+ const CTX_EXTENSION_SCOPE_MAP_VERSION = 'pulsewasm.ctx-extension-scope-map.v1';
12
+ const LIBRARY_SIDECAR_SMOKE_VERSION = 'pulsewasm.library-sidecar-smoke.v1';
13
+
14
+ function makeDiagnostic(code, message, hint, details) {
15
+ return normalizeDiagnostic({
16
+ phase: 'library-sidecars',
17
+ severity: 'error',
18
+ code,
19
+ message,
20
+ hint,
21
+ details,
22
+ loc: { file: '<library-sidecars>' }
23
+ });
24
+ }
25
+
26
+ function defaultCtxExtensionContract() {
27
+ return {
28
+ version: LIBRARY_CONTRACT_VERSION,
29
+ package: 'pulse.test-extension',
30
+ description: 'Phase 12C fixture contract proving declared ctx extension installation, scope checking, AS sidecar linking, and lowering.',
31
+ modes: {
32
+ typescript: { entry: './dist/index.js' },
33
+ jsEngine: { entry: './dist/index.js' },
34
+ wasm: {
35
+ mode: 'wasm-sidecar',
36
+ sidecar: './as/index.as.ts',
37
+ hostCapabilities: ['headers', 'result'],
38
+ lowerings: [
39
+ {
40
+ tsSymbol: 'ctx.test.mark',
41
+ asSymbol: 'pulse_test_mark',
42
+ callShape: 'ctx-extension-literal-string',
43
+ hostCapabilities: ['headers', 'result']
44
+ }
45
+ ],
46
+ ctxExtensions: [
47
+ {
48
+ namespace: 'test',
49
+ installedBy: { kind: 'middleware', tsSymbol: 'testExtension' },
50
+ methods: [
51
+ {
52
+ tsPath: 'ctx.test.mark',
53
+ asSymbol: 'pulse_test_mark',
54
+ callShape: 'literal-string',
55
+ hostCapabilities: ['headers', 'result']
56
+ }
57
+ ]
58
+ }
59
+ ]
60
+ }
61
+ },
62
+ policy: {
63
+ fixtureOnly: true,
64
+ inferredCompatibility: false,
65
+ arbitraryTsCompilation: false,
66
+ sidecarRequiredForWasm: true,
67
+ scopeCheckedCtxExtension: true,
68
+ realGripSemanticsImplemented: false,
69
+ assetsImplemented: false
70
+ }
71
+ };
72
+ }
73
+
74
+ function validateCtxExtensions(contract) {
75
+ const diagnostics = [];
76
+ const modes = normalizeContractModeKeys(contract.modes);
77
+ const wasm = modes.wasm || {};
78
+ const extensions = Array.isArray(wasm.ctxExtensions) ? wasm.ctxExtensions : [];
79
+ for (const extension of extensions) {
80
+ if (!extension || typeof extension.namespace !== 'string' || extension.namespace.length === 0) {
81
+ diagnostics.push(makeDiagnostic(
82
+ 'PULSEWASM_LIBRARY_CTX_EXTENSION_NAMESPACE_REQUIRED',
83
+ `Library ${contract.package || '<unknown>'} declares a ctx extension without a static namespace.`,
84
+ 'Declare modes.wasm.ctxExtensions[].namespace as a static string.',
85
+ { package: contract.package, extension }
86
+ ));
87
+ continue;
88
+ }
89
+ if (!extension.installedBy || extension.installedBy.kind !== 'middleware' || typeof extension.installedBy.tsSymbol !== 'string') {
90
+ diagnostics.push(makeDiagnostic(
91
+ 'PULSEWASM_LIBRARY_CTX_EXTENSION_INSTALLER_REQUIRED',
92
+ `ctx.${extension.namespace} must declare the middleware symbol that installs it.`,
93
+ 'Declare installedBy: { kind: "middleware", tsSymbol: "..." } for compiled-Wasm scope tracking.',
94
+ { package: contract.package, extension }
95
+ ));
96
+ }
97
+ const methods = Array.isArray(extension.methods) ? extension.methods : [];
98
+ if (methods.length === 0) {
99
+ diagnostics.push(makeDiagnostic(
100
+ 'PULSEWASM_LIBRARY_CTX_EXTENSION_METHODS_REQUIRED',
101
+ `ctx.${extension.namespace} declares no lowerable methods.`,
102
+ 'Declare at least one methods[] entry with tsPath and asSymbol.',
103
+ { package: contract.package, extension }
104
+ ));
105
+ }
106
+ for (const method of methods) {
107
+ if (!method || typeof method.tsPath !== 'string' || typeof method.asSymbol !== 'string') {
108
+ diagnostics.push(makeDiagnostic(
109
+ 'PULSEWASM_LIBRARY_CTX_EXTENSION_METHOD_INVALID',
110
+ `ctx.${extension.namespace} declares an invalid extension method.`,
111
+ 'Each method must include static tsPath and asSymbol strings.',
112
+ { package: contract.package, extension, method }
113
+ ));
114
+ }
115
+ for (const capability of method.hostCapabilities || []) {
116
+ if (!ALLOWED_HOST_CAPABILITIES.includes(capability)) {
117
+ diagnostics.push(makeDiagnostic(
118
+ 'PULSEWASM_LIBRARY_CTX_EXTENSION_UNKNOWN_CAPABILITY',
119
+ `ctx.${extension.namespace}.${method && method.tsPath ? method.tsPath : '<method>'} requires unknown host capability ${JSON.stringify(capability)}.`,
120
+ `Use one of: ${ALLOWED_HOST_CAPABILITIES.join(', ')}.`,
121
+ { package: contract.package, capability }
122
+ ));
123
+ }
124
+ }
125
+ }
126
+ }
127
+ return { extensions, diagnostics };
128
+ }
129
+
130
+ function ctxExtensionValidationExamples() {
131
+ return [
132
+ { source: 'ctx.test.mark("ok")', status: 'allowed-in-installed-scope', lowering: 'pulse_test_mark(ctx, "ok")' },
133
+ { source: 'ctx.test.mark("ok")', status: 'rejected-outside-installed-scope', diagnostic: 'PULSEWASM_CTX_EXTENSION_NOT_IN_SCOPE' },
134
+ { source: 'ctx.anythingElse.foo()', status: 'rejected-undeclared-extension', diagnostic: 'PULSEWASM_CTX_EXTENSION_UNDECLARED' },
135
+ { source: 'const t = ctx.test; t.mark("ok")', status: 'rejected-extension-aliasing', diagnostic: 'PULSEWASM_CTX_EXTENSION_ESCAPE_UNSUPPORTED' }
136
+ ];
137
+ }
138
+
139
+ module.exports = {
140
+ LIBRARY_SIDECAR_PHASE,
141
+ LIBRARY_SIDECAR_CONSUMPTION_VERSION,
142
+ CTX_EXTENSION_SCOPE_MAP_VERSION,
143
+ LIBRARY_SIDECAR_SMOKE_VERSION,
144
+ defaultCtxExtensionContract,
145
+ validateCtxExtensions,
146
+ ctxExtensionValidationExamples
147
+ };
package/src/logging.js ADDED
@@ -0,0 +1,89 @@
1
+ 'use strict';
2
+
3
+ const LOGGING_CONTRACT_VERSION = 'pulse.logging.v1';
4
+ const DEFAULT_REPORTING_LEVEL = 'info';
5
+ const REPORTING_LEVEL_NAMES = Object.freeze(['off', 'error', 'warn', 'info', 'debug']);
6
+ const REPORTING_LEVELS = Object.freeze(Object.fromEntries(
7
+ REPORTING_LEVEL_NAMES.map((name, level) => [name, level])
8
+ ));
9
+ const LOG_METHOD_LEVELS = Object.freeze({
10
+ error: REPORTING_LEVELS.error,
11
+ warn: REPORTING_LEVELS.warn,
12
+ info: REPORTING_LEVELS.info,
13
+ debug: REPORTING_LEVELS.debug
14
+ });
15
+ const PULSE_LOG_ABI = Object.freeze({
16
+ version: 'pulse.log-abi.v1',
17
+ operation: 'pulse_log',
18
+ signature: 'pulse_log(level:i32,message_ptr:i32,message_len:i32)->void',
19
+ parameters: Object.freeze([
20
+ Object.freeze({ name: 'level', type: 'i32' }),
21
+ Object.freeze({ name: 'message_ptr', type: 'i32' }),
22
+ Object.freeze({ name: 'message_len', type: 'i32' })
23
+ ]),
24
+ result: 'void',
25
+ synchronous: true,
26
+ effect: false,
27
+ continuation: false,
28
+ suspension: false,
29
+ providerAdapterOwned: true
30
+ });
31
+
32
+ function normalizeReportingLevel(value = DEFAULT_REPORTING_LEVEL, field = 'reporting') {
33
+ const normalized = String(value).trim().toLowerCase();
34
+ if (!Object.prototype.hasOwnProperty.call(REPORTING_LEVELS, normalized)) {
35
+ const error = new TypeError(`${field} must be one of ${REPORTING_LEVEL_NAMES.join(', ')}.`);
36
+ error.code = 'PULSE_REPORTING_LEVEL_UNSUPPORTED';
37
+ error.details = Object.freeze({ field, value, allowed: REPORTING_LEVEL_NAMES });
38
+ throw error;
39
+ }
40
+ return normalized;
41
+ }
42
+
43
+ function reportingLevelNumber(value = DEFAULT_REPORTING_LEVEL, field = 'reporting') {
44
+ return REPORTING_LEVELS[normalizeReportingLevel(value, field)];
45
+ }
46
+
47
+ function resolveReportingLevel(profileReporting, pulseReporting = DEFAULT_REPORTING_LEVEL) {
48
+ return normalizeReportingLevel(
49
+ profileReporting === undefined || profileReporting === null
50
+ ? pulseReporting
51
+ : profileReporting,
52
+ 'reporting'
53
+ );
54
+ }
55
+
56
+ function reportingDescriptor(value = DEFAULT_REPORTING_LEVEL) {
57
+ const name = normalizeReportingLevel(value);
58
+ return Object.freeze({
59
+ version: LOGGING_CONTRACT_VERSION,
60
+ name,
61
+ level: REPORTING_LEVELS[name],
62
+ default: name === DEFAULT_REPORTING_LEVEL,
63
+ abi: PULSE_LOG_ABI
64
+ });
65
+ }
66
+
67
+ function logStatementEnabled(statementLevel, reportingLevel) {
68
+ const statement = typeof statementLevel === 'number'
69
+ ? statementLevel
70
+ : LOG_METHOD_LEVELS[String(statementLevel)];
71
+ const reporting = typeof reportingLevel === 'number'
72
+ ? reportingLevel
73
+ : reportingLevelNumber(reportingLevel);
74
+ return Number.isInteger(statement) && statement >= REPORTING_LEVELS.error && statement <= reporting;
75
+ }
76
+
77
+ module.exports = Object.freeze({
78
+ LOGGING_CONTRACT_VERSION,
79
+ DEFAULT_REPORTING_LEVEL,
80
+ REPORTING_LEVEL_NAMES,
81
+ REPORTING_LEVELS,
82
+ LOG_METHOD_LEVELS,
83
+ PULSE_LOG_ABI,
84
+ normalizeReportingLevel,
85
+ reportingLevelNumber,
86
+ resolveReportingLevel,
87
+ reportingDescriptor,
88
+ logStatementEnabled
89
+ });