@sensigo/realm-cli 0.12.1 → 0.14.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 (78) hide show
  1. package/dist/agent/gate/slack-gate-notifier.d.ts +1 -1
  2. package/dist/agent/gate/slack-gate-notifier.d.ts.map +1 -1
  3. package/dist/agent/gate/slack-gate-notifier.js +1 -1
  4. package/dist/agent/gate/slack-gate-notifier.js.map +1 -1
  5. package/dist/agent/gate/slack-gate-server.d.ts +1 -1
  6. package/dist/agent/gate/slack-gate-server.d.ts.map +1 -1
  7. package/dist/agent/gate/slack-socket-client.d.ts +1 -1
  8. package/dist/agent/gate/slack-socket-client.d.ts.map +1 -1
  9. package/dist/agent/providers/agent-utils.d.ts +7 -2
  10. package/dist/agent/providers/agent-utils.d.ts.map +1 -1
  11. package/dist/agent/providers/agent-utils.js +20 -6
  12. package/dist/agent/providers/agent-utils.js.map +1 -1
  13. package/dist/agent/run-agent.d.ts +6 -0
  14. package/dist/agent/run-agent.d.ts.map +1 -1
  15. package/dist/agent/run-agent.js +5 -0
  16. package/dist/agent/run-agent.js.map +1 -1
  17. package/dist/agent/run-attach.d.ts +23 -0
  18. package/dist/agent/run-attach.d.ts.map +1 -0
  19. package/dist/agent/run-attach.js +81 -0
  20. package/dist/agent/run-attach.js.map +1 -0
  21. package/dist/commands/agent.d.ts +14 -0
  22. package/dist/commands/agent.d.ts.map +1 -1
  23. package/dist/commands/agent.js +70 -81
  24. package/dist/commands/agent.js.map +1 -1
  25. package/dist/commands/init.d.ts +2 -1
  26. package/dist/commands/init.d.ts.map +1 -1
  27. package/dist/commands/init.js +69 -2
  28. package/dist/commands/init.js.map +1 -1
  29. package/dist/commands/inspect.d.ts +1 -0
  30. package/dist/commands/inspect.d.ts.map +1 -1
  31. package/dist/commands/inspect.js +104 -1
  32. package/dist/commands/inspect.js.map +1 -1
  33. package/dist/commands/listen.d.ts +11 -0
  34. package/dist/commands/listen.d.ts.map +1 -1
  35. package/dist/commands/listen.js +36 -1
  36. package/dist/commands/listen.js.map +1 -1
  37. package/dist/commands/mcp.d.ts +2 -1
  38. package/dist/commands/mcp.d.ts.map +1 -1
  39. package/dist/commands/mcp.js +16 -5
  40. package/dist/commands/mcp.js.map +1 -1
  41. package/dist/commands/register.d.ts +6 -0
  42. package/dist/commands/register.d.ts.map +1 -1
  43. package/dist/commands/register.js +35 -1
  44. package/dist/commands/register.js.map +1 -1
  45. package/dist/commands/run.d.ts.map +1 -1
  46. package/dist/commands/run.js +18 -0
  47. package/dist/commands/run.js.map +1 -1
  48. package/dist/commands/serve.d.ts +6 -0
  49. package/dist/commands/serve.d.ts.map +1 -1
  50. package/dist/commands/serve.js +18 -4
  51. package/dist/commands/serve.js.map +1 -1
  52. package/dist/commands/test.d.ts.map +1 -1
  53. package/dist/commands/test.js +36 -1
  54. package/dist/commands/test.js.map +1 -1
  55. package/dist/commands/validate.d.ts.map +1 -1
  56. package/dist/commands/validate.js +58 -8
  57. package/dist/commands/validate.js.map +1 -1
  58. package/dist/commands/watch.d.ts.map +1 -1
  59. package/dist/commands/watch.js +6 -1
  60. package/dist/commands/watch.js.map +1 -1
  61. package/dist/extensions/extension-identity.d.ts +82 -0
  62. package/dist/extensions/extension-identity.d.ts.map +1 -0
  63. package/dist/extensions/extension-identity.js +242 -0
  64. package/dist/extensions/extension-identity.js.map +1 -0
  65. package/dist/extensions/load-project-extensions.d.ts +59 -0
  66. package/dist/extensions/load-project-extensions.d.ts.map +1 -0
  67. package/dist/extensions/load-project-extensions.js +654 -0
  68. package/dist/extensions/load-project-extensions.js.map +1 -0
  69. package/dist/extensions/manifest-secrets.d.ts +36 -0
  70. package/dist/extensions/manifest-secrets.d.ts.map +1 -0
  71. package/dist/extensions/manifest-secrets.js +126 -0
  72. package/dist/extensions/manifest-secrets.js.map +1 -0
  73. package/dist/index.js +1 -1
  74. package/package.json +4 -4
  75. package/dist/agent/preflight.d.ts +0 -36
  76. package/dist/agent/preflight.d.ts.map +0 -1
  77. package/dist/agent/preflight.js +0 -81
  78. package/dist/agent/preflight.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,eAAe,SA+BxB,CAAC"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuBpC,eAAO,MAAM,eAAe,SAiExB,CAAC"}
@@ -1,12 +1,35 @@
1
1
  // realm validate <path> — validates a workflow YAML file without registering it.
2
+ //
3
+ // Strictness asymmetry (documented): extension-free workflows validate through the EXACT
4
+ // from-string path used before project extensions existed (byte-identical behavior).
5
+ // Workflows declaring `extensions:` (or validated with --extensions-module) go through
6
+ // file-based loading so extension modules can be resolved, then a SECOND pass validates
7
+ // step `config` against each resolved adapter's `config_schema` (two-pass).
2
8
  import { Command } from 'commander';
3
9
  import { join } from 'node:path';
4
10
  import { readFileSync } from 'node:fs';
5
- import { loadWorkflowFromString, WorkflowError } from '@sensigo/realm';
11
+ import { load } from 'js-yaml';
12
+ import { loadWorkflowFromString, loadWorkflowFromFile, WorkflowError } from '@sensigo/realm';
13
+ import { loadProjectExtensions } from '../extensions/load-project-extensions.js';
14
+ /** Pre-scan: does the YAML carry a top-level `extensions` key? (Parse errors → false; the
15
+ * real loader below reports them with its existing error surface.) */
16
+ function hasTopLevelExtensions(content) {
17
+ try {
18
+ const raw = load(content);
19
+ return (typeof raw === 'object' &&
20
+ raw !== null &&
21
+ !Array.isArray(raw) &&
22
+ 'extensions' in raw);
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
6
28
  export const validateCommand = new Command('validate')
7
29
  .argument('<path>', 'Path to workflow directory or workflow.yaml file')
30
+ .option('--extensions-module <path>', "Extensions module that REPLACES the workflow's declared 'extensions' modules (repair/override)")
8
31
  .description('Validate a workflow YAML file')
9
- .action((inputPath) => {
32
+ .action(async (inputPath, opts) => {
10
33
  const filePath = inputPath.endsWith('.yaml') || inputPath.endsWith('.yml')
11
34
  ? inputPath
12
35
  : join(inputPath, 'workflow.yaml');
@@ -20,16 +43,43 @@ export const validateCommand = new Command('validate')
20
43
  process.exit(1);
21
44
  return;
22
45
  }
46
+ if (!hasTopLevelExtensions(content) && opts.extensionsModule === undefined) {
47
+ // Extension-free: the exact current from-string path — byte-identical behavior.
48
+ try {
49
+ const definition = loadWorkflowFromString(content);
50
+ console.log(`Valid: ${definition.id} v${definition.version} (${Object.keys(definition.steps).length} steps)`);
51
+ }
52
+ catch (err) {
53
+ if (err instanceof WorkflowError) {
54
+ console.error(`Invalid: ${err.message}`);
55
+ process.exit(1);
56
+ }
57
+ throw err;
58
+ }
59
+ return;
60
+ }
61
+ // Extensions declared (or an override supplied): file-based two-pass validation.
23
62
  try {
24
- const definition = loadWorkflowFromString(content);
63
+ // Pass 1: structural validation + extension resolution metadata (source_dir/trust_root).
64
+ const definition = loadWorkflowFromFile(filePath);
65
+ const { registry, manifest, sentinelWarnings } = await loadProjectExtensions(definition, {
66
+ ...(opts.extensionsModule !== undefined ? { overrideModule: opts.extensionsModule } : {}),
67
+ secretMode: 'sentinel',
68
+ });
69
+ for (const warning of sentinelWarnings ?? [])
70
+ console.warn(`⚠ ${warning}`);
71
+ // Pass 2: step config validated against each resolved adapter's config_schema.
72
+ loadWorkflowFromFile(filePath, registry);
25
73
  console.log(`Valid: ${definition.id} v${definition.version} (${Object.keys(definition.steps).length} steps)`);
74
+ if (manifest.modules.length > 0) {
75
+ console.log(`Extensions: ${manifest.modules.map((m) => m.declared).join(', ')} ` +
76
+ `(adapters: ${manifest.adapters.length}, handlers: ${manifest.handlers.length}, ` +
77
+ `processors: ${manifest.processors.length})`);
78
+ }
26
79
  }
27
80
  catch (err) {
28
- if (err instanceof WorkflowError) {
29
- console.error(`Invalid: ${err.message}`);
30
- process.exit(1);
31
- }
32
- throw err;
81
+ console.error(`Invalid: ${err instanceof Error ? err.message : String(err)}`);
82
+ process.exit(1);
33
83
  }
34
84
  });
35
85
  //# sourceMappingURL=validate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEvE,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;KACnD,QAAQ,CAAC,QAAQ,EAAE,kDAAkD,CAAC;KACtE,WAAW,CAAC,+BAA+B,CAAC;KAC5C,MAAM,CAAC,CAAC,SAAiB,EAAE,EAAE;IAC5B,MAAM,QAAQ,GACZ,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;QACvD,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IAEvC,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CACT,UAAU,UAAU,CAAC,EAAE,KAAK,UAAU,CAAC,OAAO,KAAK,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,SAAS,CACjG,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YACjC,OAAO,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AA0BxD;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,iBAAiB,EACxB,MAAM,CAAC,EAAE,WAAW,EACpB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CA4Df;AAED,eAAO,MAAM,YAAY,SAoBrB,CAAC"}
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AA+BxD;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,iBAAiB,EACxB,MAAM,CAAC,EAAE,WAAW,EACpB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CA4Df;AAED,eAAO,MAAM,YAAY,SAoBrB,CAAC"}
@@ -3,16 +3,21 @@ import { watch, existsSync } from 'node:fs';
3
3
  import { join, dirname, resolve } from 'node:path';
4
4
  import { Command } from 'commander';
5
5
  import { loadWorkflowFromFile, WorkflowError } from '@sensigo/realm';
6
+ import { loadWorkflowForRegistration } from './register.js';
6
7
  /**
7
8
  * Attempts to load and register a workflow YAML file.
8
9
  * Logs the result (success or validation error) to stdout/stderr.
10
+ * Like `realm workflow register`, each (re-)registration mints the trust decision: when the
11
+ * workflow declares `extensions:`, the modules load + duck-validate and step config gets the
12
+ * config_schema two-pass BEFORE persisting. NOTE: long-lived watch processes keep the FIRST
13
+ * imported content of each module path (ESM cache) — restart watch to pick up module changes.
9
14
  * @param filePath Path to the workflow YAML file.
10
15
  * @param store The registrar to register into.
11
16
  */
12
17
  async function registerFile(filePath, store) {
13
18
  const timestamp = new Date().toISOString();
14
19
  try {
15
- const definition = loadWorkflowFromFile(filePath);
20
+ const definition = await loadWorkflowForRegistration(filePath);
16
21
  await store.register(definition);
17
22
  console.log(`[${timestamp}] Registered: ${definition.id} v${definition.version} (${Object.keys(definition.steps).length} steps)`);
18
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ import type { ExtensionIdentityEntry, ExtensionIdentityModule, ExtensionIdentitySignals } from '@sensigo/realm';
2
+ import { extensionIdentityDiffers } from '@sensigo/realm';
3
+ /** The one sweep-rule version this module can compute. Comparison ALWAYS recomputes under
4
+ * the RECORDED rule string — a future rules change must add a new version, never mutate v1. */
5
+ export declare const DIR_TREE_V1_RULES = "dir_tree_v1: include .js,.mjs,.cjs,.ts,.mts,.cts,.json; exclude dirs node_modules,.git; skip symlinks; sort by relpath; sha256(relpath\\0filehash); caps 2000 files/50MB";
6
+ /** Compares two identity entries — tree_hash + per-module entry hashes + override flag. */
7
+ export { extensionIdentityDiffers as identityDiffers };
8
+ export interface ComputeIdentityInput {
9
+ declared: string;
10
+ resolved: string;
11
+ format: ExtensionIdentityModule['format'];
12
+ }
13
+ export interface ComputeIdentityOptions {
14
+ /** Trust root for the advisory signals (package.json version, .git HEAD). */
15
+ trustRoot?: string;
16
+ /** Set when --extensions-module replaced the declared modules. */
17
+ overrideActive?: boolean;
18
+ /** Injected for tests; defaults to `new Date().toISOString()`. */
19
+ capturedAt?: string;
20
+ /** Injected for tests; defaults to `process.pid`. */
21
+ pid?: number;
22
+ /** Deployment-manifest identity (path + raw-bytes sha256) — recorded AND compared. */
23
+ manifest?: {
24
+ path: string;
25
+ content_hash: string;
26
+ };
27
+ /** Secret NAMES referenced by the manifest — recorded, never compared, never values. */
28
+ secretNames?: string[];
29
+ }
30
+ /** sha256 hex of raw bytes/text — exported for the loader's manifest content hash. */
31
+ export declare function sha256HexOf(data: Buffer | string): string;
32
+ /**
33
+ * Computes the dir_tree_v1 identity of a set of loaded extension modules: per-module
34
+ * sha256 entry hashes plus a deterministic directory-tree fingerprint over the deduped
35
+ * parent directories of the resolved entries. Pure fs + crypto — never loads code.
36
+ */
37
+ export declare function computeExtensionIdentity(modules: ComputeIdentityInput[], opts?: ComputeIdentityOptions): ExtensionIdentityEntry;
38
+ /**
39
+ * Builds an identity entry that records a capture/load FAILURE — the failure is itself
40
+ * evidence (WorkflowContextSnapshot.error precedent). Modules/tree are empty placeholders.
41
+ */
42
+ export declare function errorExtensionIdentityEntry(message: string, opts?: Pick<ComputeIdentityOptions, 'capturedAt' | 'pid' | 'overrideActive'>): ExtensionIdentityEntry;
43
+ /** Per-component result of a --check-drift recomputation against current disk state. */
44
+ export interface RecomputeResult {
45
+ comparable: true;
46
+ /** Per recorded module: current entry hash (undefined = file unreadable/missing). */
47
+ modules: Array<{
48
+ resolved: string;
49
+ recorded_hash: string;
50
+ current_hash?: string;
51
+ }>;
52
+ tree: {
53
+ recorded_hash: string;
54
+ current_hash: string;
55
+ current_truncated: boolean;
56
+ };
57
+ /**
58
+ * Deployment-manifest bytes-hash recompute (pure fs read of entry.manifest.path — no
59
+ * YAML parsing, no secret resolution). Absent when the entry recorded no manifest
60
+ * (older entries); current_hash undefined = manifest file missing/unreadable.
61
+ */
62
+ manifest?: {
63
+ path: string;
64
+ recorded_hash: string;
65
+ current_hash?: string;
66
+ };
67
+ signals?: ExtensionIdentitySignals;
68
+ }
69
+ export interface RecomputeNotComparable {
70
+ comparable: false;
71
+ reason: string;
72
+ }
73
+ /**
74
+ * Recomputes an entry's identity from CURRENT disk state STRICTLY under the entry's
75
+ * RECORDED rules and roots — an unknown rules version yields an explicit cannot-compare
76
+ * rather than a guess (a rules change must never manufacture phantom drift).
77
+ * Pure fs + crypto — never loads code.
78
+ */
79
+ export declare function recomputeIdentity(entry: ExtensionIdentityEntry, opts?: {
80
+ trustRoot?: string;
81
+ }): RecomputeResult | RecomputeNotComparable;
82
+ //# sourceMappingURL=extension-identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-identity.d.ts","sourceRoot":"","sources":["../../src/extensions/extension-identity.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAE1D;gGACgG;AAChG,eAAO,MAAM,iBAAiB,6KAC8I,CAAC;AAO7K,2FAA2F;AAC3F,OAAO,EAAE,wBAAwB,IAAI,eAAe,EAAE,CAAC;AAEvD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,uBAAuB,CAAC,QAAQ,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,sBAAsB;IACrC,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,wFAAwF;IACxF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,sFAAsF;AACtF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAEzD;AAyHD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,oBAAoB,EAAE,EAC/B,IAAI,GAAE,sBAA2B,GAChC,sBAAsB,CAyBxB;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,IAAI,CAAC,sBAAsB,EAAE,YAAY,GAAG,KAAK,GAAG,gBAAgB,CAAM,GAC/E,sBAAsB,CAiBxB;AAED,wFAAwF;AACxF,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,IAAI,CAAC;IACjB,qFAAqF;IACrF,OAAO,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnF,IAAI,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,OAAO,CAAA;KAAE,CAAC;IAClF;;;;OAIG;IACH,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E,OAAO,CAAC,EAAE,wBAAwB,CAAC;CACpC;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,KAAK,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,sBAAsB,EAC7B,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAChC,eAAe,GAAG,sBAAsB,CAmD1C"}
@@ -0,0 +1,242 @@
1
+ // extension-identity.ts — PURE fingerprint + compare for extension-code drift evidence
2
+ // (issue #119). This module is STRUCTURALLY incapable of loading code: no dynamic import,
3
+ // no module-require creation, anywhere. It only reads bytes (fs), hashes them (crypto),
4
+ // and manipulates paths — which is exactly why read-only commands (`realm run inspect
5
+ // --check-drift`) may use it without ever gaining the capability to execute project code.
6
+ // A structural test (read-only-no-extensions.test.ts) enforces this.
7
+ import { createHash } from 'node:crypto';
8
+ import { readFileSync, readdirSync } from 'node:fs';
9
+ import { dirname, join, relative, sep } from 'node:path';
10
+ import { extensionIdentityDiffers } from '@sensigo/realm';
11
+ /** The one sweep-rule version this module can compute. Comparison ALWAYS recomputes under
12
+ * the RECORDED rule string — a future rules change must add a new version, never mutate v1. */
13
+ export const DIR_TREE_V1_RULES = 'dir_tree_v1: include .js,.mjs,.cjs,.ts,.mts,.cts,.json; exclude dirs node_modules,.git; skip symlinks; sort by relpath; sha256(relpath\\0filehash); caps 2000 files/50MB';
14
+ const INCLUDED_EXTENSIONS = new Set(['.js', '.mjs', '.cjs', '.ts', '.mts', '.cts', '.json']);
15
+ const EXCLUDED_DIR_NAMES = new Set(['node_modules', '.git']);
16
+ const MAX_FILES = 2000;
17
+ const MAX_TOTAL_BYTES = 50 * 1024 * 1024;
18
+ /** Compares two identity entries — tree_hash + per-module entry hashes + override flag. */
19
+ export { extensionIdentityDiffers as identityDiffers };
20
+ /** sha256 hex of raw bytes/text — exported for the loader's manifest content hash. */
21
+ export function sha256HexOf(data) {
22
+ return sha256Hex(data);
23
+ }
24
+ function sha256Hex(data) {
25
+ return createHash('sha256').update(data).digest('hex');
26
+ }
27
+ function fileExtension(path) {
28
+ const base = path.slice(path.lastIndexOf(sep) + 1);
29
+ const dot = base.lastIndexOf('.');
30
+ return dot === -1 ? '' : base.slice(dot);
31
+ }
32
+ /**
33
+ * Deterministically enumerates the relative paths of sweep-eligible files under `root`
34
+ * per dir_tree_v1: included extensions only, `node_modules`/`.git` directories excluded at
35
+ * any depth, symlinks (files and directories) skipped, sorted by relative path.
36
+ * Enumeration is cap-free — caps apply at the hashing stage so the truncated fingerprint
37
+ * covers a DETERMINISTIC prefix of the sorted listing.
38
+ */
39
+ function enumerateTreeFiles(root) {
40
+ const relPaths = [];
41
+ const walk = (dir) => {
42
+ let entries;
43
+ try {
44
+ entries = readdirSync(dir, { withFileTypes: true });
45
+ }
46
+ catch {
47
+ return; // unreadable directory — skipped (deterministic for a given tree state)
48
+ }
49
+ for (const entry of entries) {
50
+ const full = join(dir, entry.name);
51
+ if (entry.isSymbolicLink())
52
+ continue; // dir_tree_v1: symlinks skipped
53
+ if (entry.isDirectory()) {
54
+ if (EXCLUDED_DIR_NAMES.has(entry.name))
55
+ continue;
56
+ walk(full);
57
+ }
58
+ else if (entry.isFile()) {
59
+ if (INCLUDED_EXTENSIONS.has(fileExtension(entry.name))) {
60
+ relPaths.push(relative(root, full));
61
+ }
62
+ }
63
+ }
64
+ };
65
+ walk(root);
66
+ return relPaths.sort();
67
+ }
68
+ /** Hashes the sorted file listing of `roots` under the dir_tree_v1 caps. */
69
+ function sweepTree(roots) {
70
+ // Enumerate everything first (cheap), THEN hash under caps — the truncation point is a
71
+ // deterministic prefix of the sorted listing, so truncated hashes stay comparable.
72
+ const perRoot = roots.map((root) => enumerateTreeFiles(root).map((rel) => ({ root, rel })));
73
+ const allFiles = perRoot.flat();
74
+ const lines = [];
75
+ let totalBytes = 0;
76
+ let truncated = false;
77
+ for (const file of allFiles) {
78
+ if (lines.length >= MAX_FILES || totalBytes >= MAX_TOTAL_BYTES) {
79
+ truncated = true;
80
+ break;
81
+ }
82
+ let bytes;
83
+ try {
84
+ bytes = readFileSync(join(file.root, file.rel));
85
+ }
86
+ catch {
87
+ // File disappeared between enumeration and hashing — record it as unreadable
88
+ // (deterministic for a given tree state; a vanishing file IS a tree change).
89
+ lines.push(`${file.rel}\u0000<unreadable>`);
90
+ continue;
91
+ }
92
+ totalBytes += bytes.length;
93
+ lines.push(`${file.rel}\u0000${sha256Hex(bytes)}`);
94
+ }
95
+ return {
96
+ file_count: lines.length,
97
+ total_bytes: totalBytes,
98
+ tree_hash: sha256Hex(lines.join('\n')),
99
+ truncated,
100
+ };
101
+ }
102
+ /** Advisory signals — each independently fail-soft to undefined; never compared. */
103
+ function collectSignals(trustRoot) {
104
+ if (trustRoot === undefined)
105
+ return undefined;
106
+ const signals = {};
107
+ try {
108
+ const pkg = JSON.parse(readFileSync(join(trustRoot, 'package.json'), 'utf8'));
109
+ if (typeof pkg.version === 'string')
110
+ signals.package_version = pkg.version;
111
+ }
112
+ catch {
113
+ // fail-soft
114
+ }
115
+ try {
116
+ // Read .git/HEAD; dereference ONE ref file. No child processes, ever.
117
+ const head = readFileSync(join(trustRoot, '.git', 'HEAD'), 'utf8').trim();
118
+ if (head.startsWith('ref: ')) {
119
+ const refPath = head.slice('ref: '.length).trim();
120
+ const refValue = readFileSync(join(trustRoot, '.git', refPath), 'utf8').trim();
121
+ if (refValue !== '')
122
+ signals.git_head = refValue;
123
+ }
124
+ else if (head !== '') {
125
+ signals.git_head = head; // detached HEAD — the hash itself
126
+ }
127
+ }
128
+ catch {
129
+ // fail-soft (packed refs, no .git, unreadable — all acceptable)
130
+ }
131
+ return signals.package_version === undefined && signals.git_head === undefined
132
+ ? undefined
133
+ : signals;
134
+ }
135
+ /**
136
+ * Computes the dir_tree_v1 identity of a set of loaded extension modules: per-module
137
+ * sha256 entry hashes plus a deterministic directory-tree fingerprint over the deduped
138
+ * parent directories of the resolved entries. Pure fs + crypto — never loads code.
139
+ */
140
+ export function computeExtensionIdentity(modules, opts = {}) {
141
+ const moduleEntries = modules.map((m) => ({
142
+ declared: m.declared,
143
+ resolved: m.resolved,
144
+ entry_hash: sha256Hex(readFileSync(m.resolved)),
145
+ format: m.format,
146
+ }));
147
+ const roots = [...new Set(modules.map((m) => dirname(m.resolved)))].sort();
148
+ const tree = sweepTree(roots);
149
+ const signals = collectSignals(opts.trustRoot);
150
+ return {
151
+ captured_at: opts.capturedAt ?? new Date().toISOString(),
152
+ pid: opts.pid ?? process.pid,
153
+ modules: moduleEntries,
154
+ tree: { roots, rules: DIR_TREE_V1_RULES, ...tree },
155
+ ...(signals !== undefined ? { signals } : {}),
156
+ coverage: 'dir_tree_v1',
157
+ ...(opts.manifest !== undefined ? { manifest: opts.manifest } : {}),
158
+ ...(opts.secretNames !== undefined && opts.secretNames.length > 0
159
+ ? { secret_names: opts.secretNames }
160
+ : {}),
161
+ ...(opts.overrideActive === true ? { override_active: true } : {}),
162
+ };
163
+ }
164
+ /**
165
+ * Builds an identity entry that records a capture/load FAILURE — the failure is itself
166
+ * evidence (WorkflowContextSnapshot.error precedent). Modules/tree are empty placeholders.
167
+ */
168
+ export function errorExtensionIdentityEntry(message, opts = {}) {
169
+ return {
170
+ captured_at: opts.capturedAt ?? new Date().toISOString(),
171
+ pid: opts.pid ?? process.pid,
172
+ modules: [],
173
+ tree: {
174
+ roots: [],
175
+ rules: DIR_TREE_V1_RULES,
176
+ file_count: 0,
177
+ total_bytes: 0,
178
+ tree_hash: '',
179
+ truncated: false,
180
+ },
181
+ coverage: 'dir_tree_v1',
182
+ ...(opts.overrideActive === true ? { override_active: true } : {}),
183
+ error: message,
184
+ };
185
+ }
186
+ /**
187
+ * Recomputes an entry's identity from CURRENT disk state STRICTLY under the entry's
188
+ * RECORDED rules and roots — an unknown rules version yields an explicit cannot-compare
189
+ * rather than a guess (a rules change must never manufacture phantom drift).
190
+ * Pure fs + crypto — never loads code.
191
+ */
192
+ export function recomputeIdentity(entry, opts = {}) {
193
+ if (entry.tree.rules !== DIR_TREE_V1_RULES) {
194
+ return {
195
+ comparable: false,
196
+ reason: `cannot compare (unknown rules '${entry.tree.rules}')`,
197
+ };
198
+ }
199
+ const modules = entry.modules.map((m) => {
200
+ let currentHash;
201
+ try {
202
+ currentHash = sha256Hex(readFileSync(m.resolved));
203
+ }
204
+ catch {
205
+ currentHash = undefined;
206
+ }
207
+ return {
208
+ resolved: m.resolved,
209
+ recorded_hash: m.entry_hash,
210
+ ...(currentHash !== undefined ? { current_hash: currentHash } : {}),
211
+ };
212
+ });
213
+ const tree = sweepTree(entry.tree.roots);
214
+ let manifestResult;
215
+ if (entry.manifest !== undefined) {
216
+ let currentHash;
217
+ try {
218
+ currentHash = sha256Hex(readFileSync(entry.manifest.path));
219
+ }
220
+ catch {
221
+ currentHash = undefined; // missing/unreadable — reported as MISSING by inspect
222
+ }
223
+ manifestResult = {
224
+ path: entry.manifest.path,
225
+ recorded_hash: entry.manifest.content_hash,
226
+ ...(currentHash !== undefined ? { current_hash: currentHash } : {}),
227
+ };
228
+ }
229
+ const signals = collectSignals(opts.trustRoot);
230
+ return {
231
+ comparable: true,
232
+ modules,
233
+ tree: {
234
+ recorded_hash: entry.tree.tree_hash,
235
+ current_hash: tree.tree_hash,
236
+ current_truncated: tree.truncated,
237
+ },
238
+ ...(manifestResult !== undefined ? { manifest: manifestResult } : {}),
239
+ ...(signals !== undefined ? { signals } : {}),
240
+ };
241
+ }
242
+ //# sourceMappingURL=extension-identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-identity.js","sourceRoot":"","sources":["../../src/extensions/extension-identity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import { ExtensionRegistry } from '@sensigo/realm';
2
+ import type { ExtensionManifest, SlackGateNotifierConfig, WorkflowDefinition } from '@sensigo/realm';
3
+ import { type SecretMode } from './manifest-secrets.js';
4
+ export interface LoadProjectExtensionsOptions {
5
+ /**
6
+ * Operator-typed module path that REPLACES the workflow's declared extension CODE
7
+ * modules (repair/override tool). Containment does not apply to an operator-typed path.
8
+ * The deployment manifest (config) still loads — `--project` is the manifest override.
9
+ */
10
+ overrideModule?: string;
11
+ /**
12
+ * The daemon's deployment root (`--project <dir>`), used for definitions WITHOUT
13
+ * trust_root. Absent → no manifest for such definitions (defaults only).
14
+ */
15
+ projectDir?: string;
16
+ /**
17
+ * 'real' (default): secrets resolve from the declared sources — any miss is a loud
18
+ * aggregated error, construction failures are errors (fail-before-create).
19
+ * 'sentinel' (validate/test; register/watch degrade-with-WARN): `${secret:}` refs
20
+ * resolve to `<sentinel:NAME>` labels and construction failures downgrade to warnings.
21
+ */
22
+ secretMode?: SecretMode;
23
+ }
24
+ export interface LoadedProjectExtensions {
25
+ registry: ExtensionRegistry;
26
+ manifest: ExtensionManifest;
27
+ /** Secret-resolved notifier configs from the deployment manifest, when declared. */
28
+ notifiers?: {
29
+ slack_gate?: SlackGateNotifierConfig['config'];
30
+ };
31
+ /** Sentinel-mode construction warnings (entries skipped, listed — never silent). */
32
+ sentinelWarnings?: string[];
33
+ /**
34
+ * REAL resolved manifest-secret VALUES (values only, frozen, never names→values;
35
+ * sentinel-mode values excluded; values < 4 chars excluded). Consumed by the agent
36
+ * redaction pass — must never ride any persisted or serialized structure.
37
+ */
38
+ secretValues?: readonly string[];
39
+ }
40
+ /** @internal Test-only: clears the process-lifetime registry cache. */
41
+ export declare function clearProjectExtensionsCache(): void;
42
+ /**
43
+ * Loads the project extensions and deployment configuration for a definition:
44
+ * workflow-declared CODE modules + the deployment manifest's constructed instances,
45
+ * one registry, one namespace, one collision map. No extensions, no manifest → the
46
+ * process-stable filesystem-only default registry.
47
+ *
48
+ * CONTRACT: returned registries are shared process-lifetime cache entries. The only
49
+ * permitted mutation is `getOrCreateRateLimiter` (serve bucket persistence, by design).
50
+ */
51
+ export declare function loadProjectExtensions(definition: WorkflowDefinition, opts?: LoadProjectExtensionsOptions): Promise<LoadedProjectExtensions>;
52
+ /**
53
+ * Builds a `registryProvider` for the MCP server (serve / mcp stdio): resolves each
54
+ * definition through the process-lifetime project loader. `--extensions-module` overrides
55
+ * CODE modules; `projectDir` anchors the manifest for definitions without trust_root
56
+ * (`realm mcp` passes it ONLY when --project was given — no cwd default there).
57
+ */
58
+ export declare function makeRegistryProvider(overrideModule?: string, projectDir?: string): (definition: WorkflowDefinition) => Promise<ExtensionRegistry>;
59
+ //# sourceMappingURL=load-project-extensions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-project-extensions.d.ts","sourceRoot":"","sources":["../../src/extensions/load-project-extensions.ts"],"names":[],"mappings":"AAwBA,OAAO,EAEL,iBAAiB,EAgBlB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAGV,iBAAiB,EAGjB,uBAAuB,EACvB,kBAAkB,EACnB,MAAM,gBAAgB,CAAC;AAMxB,OAAO,EAA8C,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEpG,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,oFAAoF;IACpF,SAAS,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,uBAAuB,CAAC,QAAQ,CAAC,CAAA;KAAE,CAAC;IAC/D,oFAAoF;IACpF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B;;;;OAIG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAmDD,uEAAuE;AACvE,wBAAgB,2BAA2B,IAAI,IAAI,CAElD;AAiGD;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,kBAAkB,EAC9B,IAAI,CAAC,EAAE,4BAA4B,GAClC,OAAO,CAAC,uBAAuB,CAAC,CA6IlC;AAqiBD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,cAAc,CAAC,EAAE,MAAM,EACvB,UAAU,CAAC,EAAE,MAAM,GAClB,CAAC,UAAU,EAAE,kBAAkB,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAQhE"}