@llblab/pi-kit 0.38.4 → 0.39.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.
- package/CHANGELOG.md +5 -0
- package/README.md +1 -1
- package/node_modules/@llblab/pi-actors/AGENTS.md +108 -20
- package/node_modules/@llblab/pi-actors/BACKLOG.md +207 -4
- package/node_modules/@llblab/pi-actors/CHANGELOG.md +13 -0
- package/node_modules/@llblab/pi-actors/README.md +31 -1
- package/node_modules/@llblab/pi-actors/dist/index.js +1 -1
- package/node_modules/@llblab/pi-actors/dist/lib/async-runs.d.ts +37 -0
- package/node_modules/@llblab/pi-actors/dist/lib/async-runs.js +131 -62
- package/node_modules/@llblab/pi-actors/dist/lib/automatic-review-runtime.d.ts +2 -0
- package/node_modules/@llblab/pi-actors/dist/lib/automatic-review-runtime.js +3 -2
- package/node_modules/@llblab/pi-actors/dist/lib/command-templates.d.ts +37 -0
- package/node_modules/@llblab/pi-actors/dist/lib/command-templates.js +263 -129
- package/node_modules/@llblab/pi-actors/dist/lib/execution-files.d.ts +32 -0
- package/node_modules/@llblab/pi-actors/dist/lib/execution-files.js +128 -0
- package/node_modules/@llblab/pi-actors/dist/lib/execution-output.js +5 -4
- package/node_modules/@llblab/pi-actors/dist/lib/execution-sessions.d.ts +19 -1
- package/node_modules/@llblab/pi-actors/dist/lib/execution-sessions.js +62 -26
- package/node_modules/@llblab/pi-actors/dist/lib/execution.d.ts +4 -1
- package/node_modules/@llblab/pi-actors/dist/lib/execution.js +6 -1
- package/node_modules/@llblab/pi-actors/dist/lib/extension-runtime.d.ts +9 -2
- package/node_modules/@llblab/pi-actors/dist/lib/extension-runtime.js +92 -14
- package/node_modules/@llblab/pi-actors/dist/lib/file-state.js +21 -2
- package/node_modules/@llblab/pi-actors/dist/lib/inspector-command.js +2 -2
- package/node_modules/@llblab/pi-actors/dist/lib/inspector-overlay.d.ts +25 -7
- package/node_modules/@llblab/pi-actors/dist/lib/inspector-overlay.js +562 -262
- package/node_modules/@llblab/pi-actors/dist/lib/inspector.d.ts +20 -10
- package/node_modules/@llblab/pi-actors/dist/lib/inspector.js +80 -91
- package/node_modules/@llblab/pi-actors/dist/lib/limits.d.ts +1 -0
- package/node_modules/@llblab/pi-actors/dist/lib/limits.js +1 -0
- package/node_modules/@llblab/pi-actors/dist/lib/observability.d.ts +15 -1
- package/node_modules/@llblab/pi-actors/dist/lib/observability.js +216 -99
- package/node_modules/@llblab/pi-actors/dist/lib/pi.d.ts +5 -4
- package/node_modules/@llblab/pi-actors/dist/lib/pi.js +64 -10
- package/node_modules/@llblab/pi-actors/dist/lib/recipe-projection.d.ts +18 -0
- package/node_modules/@llblab/pi-actors/dist/lib/recipe-projection.js +220 -0
- package/node_modules/@llblab/pi-actors/dist/lib/recipes-context.d.ts +2 -0
- package/node_modules/@llblab/pi-actors/dist/lib/recipes-context.js +30 -6
- package/node_modules/@llblab/pi-actors/dist/lib/registry.js +270 -36
- package/node_modules/@llblab/pi-actors/dist/lib/run-delivery.d.ts +213 -5
- package/node_modules/@llblab/pi-actors/dist/lib/run-delivery.js +1909 -40
- package/node_modules/@llblab/pi-actors/dist/lib/run-supervision.d.ts +107 -0
- package/node_modules/@llblab/pi-actors/dist/lib/run-supervision.js +412 -0
- package/node_modules/@llblab/pi-actors/dist/lib/run-ui-runtime.d.ts +9 -2
- package/node_modules/@llblab/pi-actors/dist/lib/run-ui-runtime.js +283 -60
- package/node_modules/@llblab/pi-actors/dist/lib/runs-artifacts.d.ts +26 -1
- package/node_modules/@llblab/pi-actors/dist/lib/runs-artifacts.js +68 -2
- package/node_modules/@llblab/pi-actors/dist/lib/runs-context-exports.d.ts +451 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-context-exports.js +2315 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-context-index.d.ts +97 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-context-index.js +368 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-control-delivery.js +46 -7
- package/node_modules/@llblab/pi-actors/dist/lib/runs-control.d.ts +78 -2
- package/node_modules/@llblab/pi-actors/dist/lib/runs-control.js +334 -2
- package/node_modules/@llblab/pi-actors/dist/lib/runs-controls.js +4 -1
- package/node_modules/@llblab/pi-actors/dist/lib/runs-descendant-launches.d.ts +80 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-descendant-launches.js +287 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-execution-evidence.d.ts +110 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-execution-evidence.js +282 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-index.d.ts +66 -1
- package/node_modules/@llblab/pi-actors/dist/lib/runs-index.js +349 -13
- package/node_modules/@llblab/pi-actors/dist/lib/runs-native-launches.d.ts +73 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-native-launches.js +227 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-outcomes.d.ts +141 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-outcomes.js +292 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-ownership.d.ts +10 -1
- package/node_modules/@llblab/pi-actors/dist/lib/runs-ownership.js +36 -4
- package/node_modules/@llblab/pi-actors/dist/lib/runs-process-windows-mi.d.ts +46 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-process-windows-mi.js +114 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-process.d.ts +34 -1
- package/node_modules/@llblab/pi-actors/dist/lib/runs-process.js +158 -26
- package/node_modules/@llblab/pi-actors/dist/lib/runs-results.d.ts +116 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-results.js +518 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-retention.d.ts +15 -2
- package/node_modules/@llblab/pi-actors/dist/lib/runs-retention.js +148 -9
- package/node_modules/@llblab/pi-actors/dist/lib/runs-session-exports.d.ts +95 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-session-exports.js +470 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-snapshot.d.ts +58 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-snapshot.js +92 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-start.d.ts +2 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-start.js +44 -3
- package/node_modules/@llblab/pi-actors/dist/lib/runs-status.d.ts +15 -1
- package/node_modules/@llblab/pi-actors/dist/lib/runs-status.js +337 -13
- package/node_modules/@llblab/pi-actors/dist/lib/runs-supervision.d.ts +105 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-supervision.js +501 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-trace.d.ts +1 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-trace.js +14 -3
- package/node_modules/@llblab/pi-actors/dist/lib/runtime.js +22 -3
- package/node_modules/@llblab/pi-actors/dist/lib/session-evidence.d.ts +37 -0
- package/node_modules/@llblab/pi-actors/dist/lib/session-evidence.js +59 -3
- package/node_modules/@llblab/pi-actors/dist/lib/state-readers.d.ts +4 -1
- package/node_modules/@llblab/pi-actors/dist/lib/state-readers.js +14 -8
- package/node_modules/@llblab/pi-actors/dist/lib/temp.d.ts +2 -4
- package/node_modules/@llblab/pi-actors/dist/lib/temp.js +4 -56
- package/node_modules/@llblab/pi-actors/dist/lib/tools-access.d.ts +3 -0
- package/node_modules/@llblab/pi-actors/dist/lib/tools-access.js +13 -0
- package/node_modules/@llblab/pi-actors/dist/lib/tools-inspect.d.ts +1 -0
- package/node_modules/@llblab/pi-actors/dist/lib/tools-inspect.js +110 -43
- package/node_modules/@llblab/pi-actors/dist/lib/tools-local.d.ts +3 -0
- package/node_modules/@llblab/pi-actors/dist/lib/tools-local.js +18 -6
- package/node_modules/@llblab/pi-actors/dist/lib/tools-message.d.ts +4 -1
- package/node_modules/@llblab/pi-actors/dist/lib/tools-message.js +126 -31
- package/node_modules/@llblab/pi-actors/dist/lib/tools-response.d.ts +31 -3
- package/node_modules/@llblab/pi-actors/dist/lib/tools-response.js +311 -47
- package/node_modules/@llblab/pi-actors/dist/lib/tools-spawn.d.ts +3 -0
- package/node_modules/@llblab/pi-actors/dist/lib/tools-spawn.js +29 -7
- package/node_modules/@llblab/pi-actors/dist/lib/trace-projection.d.ts +20 -0
- package/node_modules/@llblab/pi-actors/dist/lib/trace-projection.js +192 -43
- package/node_modules/@llblab/pi-actors/dist/scripts/async-runner.mjs +272 -194
- package/node_modules/@llblab/pi-actors/dist/scripts/conformance.mjs +14 -2
- package/node_modules/@llblab/pi-actors/dist/skills/actors/SKILL.md +46 -2
- package/node_modules/@llblab/pi-actors/dist/skills/actors/references/diagnostics.md +40 -0
- package/node_modules/@llblab/pi-actors/dist/skills/actors/references/runs.md +55 -1
- package/node_modules/@llblab/pi-actors/docs/README.md +9 -1
- package/node_modules/@llblab/pi-actors/docs/actor-inspector.md +84 -15
- package/node_modules/@llblab/pi-actors/docs/agent-experience.md +216 -0
- package/node_modules/@llblab/pi-actors/docs/async-runs.md +18 -2
- package/node_modules/@llblab/pi-actors/docs/composition-transport.md +103 -0
- package/node_modules/@llblab/pi-actors/docs/coordinator-delivery.md +204 -4
- package/node_modules/@llblab/pi-actors/docs/inspection.md +38 -2
- package/node_modules/@llblab/pi-actors/docs/output-projection-map.md +130 -0
- package/node_modules/@llblab/pi-actors/docs/releasing.md +19 -2
- package/node_modules/@llblab/pi-actors/docs/run-supervision.md +1622 -0
- package/node_modules/@llblab/pi-actors/docs/template-recipes.md +4 -0
- package/node_modules/@llblab/pi-actors/docs/windows-process-observation.md +248 -0
- package/node_modules/@llblab/pi-actors/index.ts +1 -1
- package/node_modules/@llblab/pi-actors/lib/async-runs.ts +164 -73
- package/node_modules/@llblab/pi-actors/lib/automatic-review-runtime.ts +4 -2
- package/node_modules/@llblab/pi-actors/lib/command-templates.ts +287 -138
- package/node_modules/@llblab/pi-actors/lib/execution-files.ts +118 -0
- package/node_modules/@llblab/pi-actors/lib/execution-output.ts +4 -4
- package/node_modules/@llblab/pi-actors/lib/execution-sessions.ts +57 -27
- package/node_modules/@llblab/pi-actors/lib/execution.ts +8 -0
- package/node_modules/@llblab/pi-actors/lib/extension-runtime.ts +102 -12
- package/node_modules/@llblab/pi-actors/lib/file-state.ts +16 -2
- package/node_modules/@llblab/pi-actors/lib/inspector-command.ts +2 -2
- package/node_modules/@llblab/pi-actors/lib/inspector-overlay.ts +524 -261
- package/node_modules/@llblab/pi-actors/lib/inspector.ts +101 -130
- package/node_modules/@llblab/pi-actors/lib/limits.ts +1 -0
- package/node_modules/@llblab/pi-actors/lib/observability.ts +235 -116
- package/node_modules/@llblab/pi-actors/lib/pi.ts +59 -11
- package/node_modules/@llblab/pi-actors/lib/recipe-projection.ts +232 -0
- package/node_modules/@llblab/pi-actors/lib/recipes-context.ts +27 -6
- package/node_modules/@llblab/pi-actors/lib/registry.ts +266 -36
- package/node_modules/@llblab/pi-actors/lib/run-delivery.ts +1737 -49
- package/node_modules/@llblab/pi-actors/lib/run-supervision.ts +411 -0
- package/node_modules/@llblab/pi-actors/lib/run-ui-runtime.ts +237 -73
- package/node_modules/@llblab/pi-actors/lib/runs-artifacts.ts +73 -1
- package/node_modules/@llblab/pi-actors/lib/runs-context-exports.ts +1871 -0
- package/node_modules/@llblab/pi-actors/lib/runs-context-index.ts +372 -0
- package/node_modules/@llblab/pi-actors/lib/runs-control-delivery.ts +36 -18
- package/node_modules/@llblab/pi-actors/lib/runs-control.ts +297 -1
- package/node_modules/@llblab/pi-actors/lib/runs-controls.ts +3 -1
- package/node_modules/@llblab/pi-actors/lib/runs-descendant-launches.ts +338 -0
- package/node_modules/@llblab/pi-actors/lib/runs-execution-evidence.ts +302 -0
- package/node_modules/@llblab/pi-actors/lib/runs-index.ts +345 -17
- package/node_modules/@llblab/pi-actors/lib/runs-native-launches.ts +270 -0
- package/node_modules/@llblab/pi-actors/lib/runs-outcomes.ts +377 -0
- package/node_modules/@llblab/pi-actors/lib/runs-ownership.ts +37 -4
- package/node_modules/@llblab/pi-actors/lib/runs-process-windows-mi.ts +113 -0
- package/node_modules/@llblab/pi-actors/lib/runs-process.ts +210 -34
- package/node_modules/@llblab/pi-actors/lib/runs-results.ts +601 -0
- package/node_modules/@llblab/pi-actors/lib/runs-retention.ts +134 -10
- package/node_modules/@llblab/pi-actors/lib/runs-session-exports.ts +406 -0
- package/node_modules/@llblab/pi-actors/lib/runs-snapshot.ts +143 -0
- package/node_modules/@llblab/pi-actors/lib/runs-start.ts +44 -2
- package/node_modules/@llblab/pi-actors/lib/runs-status.ts +252 -10
- package/node_modules/@llblab/pi-actors/lib/runs-supervision.ts +394 -0
- package/node_modules/@llblab/pi-actors/lib/runs-trace.ts +14 -3
- package/node_modules/@llblab/pi-actors/lib/runtime.ts +22 -3
- package/node_modules/@llblab/pi-actors/lib/session-evidence.ts +76 -4
- package/node_modules/@llblab/pi-actors/lib/state-readers.ts +16 -7
- package/node_modules/@llblab/pi-actors/lib/temp.ts +3 -56
- package/node_modules/@llblab/pi-actors/lib/tools-access.ts +13 -0
- package/node_modules/@llblab/pi-actors/lib/tools-inspect.ts +110 -51
- package/node_modules/@llblab/pi-actors/lib/tools-local.ts +37 -24
- package/node_modules/@llblab/pi-actors/lib/tools-message.ts +120 -37
- package/node_modules/@llblab/pi-actors/lib/tools-response.ts +273 -50
- package/node_modules/@llblab/pi-actors/lib/tools-spawn.ts +31 -10
- package/node_modules/@llblab/pi-actors/lib/trace-projection.ts +165 -42
- package/node_modules/@llblab/pi-actors/package.json +10 -6
- package/node_modules/@llblab/pi-actors/scripts/async-runner.mjs +272 -194
- package/node_modules/@llblab/pi-actors/scripts/conformance.mjs +14 -2
- package/node_modules/@llblab/pi-actors/skills/actors/SKILL.md +46 -2
- package/node_modules/@llblab/pi-actors/skills/actors/references/diagnostics.md +40 -0
- package/node_modules/@llblab/pi-actors/skills/actors/references/runs.md +55 -1
- package/node_modules/yaml/LICENSE +13 -0
- package/node_modules/yaml/README.md +172 -0
- package/node_modules/yaml/bin.mjs +11 -0
- package/node_modules/yaml/browser/dist/compose/compose-collection.js +88 -0
- package/node_modules/yaml/browser/dist/compose/compose-doc.js +43 -0
- package/node_modules/yaml/browser/dist/compose/compose-node.js +109 -0
- package/node_modules/yaml/browser/dist/compose/compose-scalar.js +86 -0
- package/node_modules/yaml/browser/dist/compose/composer.js +219 -0
- package/node_modules/yaml/browser/dist/compose/resolve-block-map.js +115 -0
- package/node_modules/yaml/browser/dist/compose/resolve-block-scalar.js +198 -0
- package/node_modules/yaml/browser/dist/compose/resolve-block-seq.js +49 -0
- package/node_modules/yaml/browser/dist/compose/resolve-end.js +37 -0
- package/node_modules/yaml/browser/dist/compose/resolve-flow-collection.js +207 -0
- package/node_modules/yaml/browser/dist/compose/resolve-flow-scalar.js +225 -0
- package/node_modules/yaml/browser/dist/compose/resolve-props.js +146 -0
- package/node_modules/yaml/browser/dist/compose/util-contains-newline.js +34 -0
- package/node_modules/yaml/browser/dist/compose/util-empty-scalar-position.js +26 -0
- package/node_modules/yaml/browser/dist/compose/util-flow-indent-check.js +15 -0
- package/node_modules/yaml/browser/dist/compose/util-map-includes.js +13 -0
- package/node_modules/yaml/browser/dist/doc/Document.js +335 -0
- package/node_modules/yaml/browser/dist/doc/anchors.js +71 -0
- package/node_modules/yaml/browser/dist/doc/applyReviver.js +55 -0
- package/node_modules/yaml/browser/dist/doc/createNode.js +88 -0
- package/node_modules/yaml/browser/dist/doc/directives.js +176 -0
- package/node_modules/yaml/browser/dist/errors.js +57 -0
- package/node_modules/yaml/browser/dist/index.js +17 -0
- package/node_modules/yaml/browser/dist/log.js +11 -0
- package/node_modules/yaml/browser/dist/nodes/Alias.js +116 -0
- package/node_modules/yaml/browser/dist/nodes/Collection.js +147 -0
- package/node_modules/yaml/browser/dist/nodes/Node.js +38 -0
- package/node_modules/yaml/browser/dist/nodes/Pair.js +36 -0
- package/node_modules/yaml/browser/dist/nodes/Scalar.js +24 -0
- package/node_modules/yaml/browser/dist/nodes/YAMLMap.js +144 -0
- package/node_modules/yaml/browser/dist/nodes/YAMLSeq.js +113 -0
- package/node_modules/yaml/browser/dist/nodes/addPairToJSMap.js +63 -0
- package/node_modules/yaml/browser/dist/nodes/identity.js +36 -0
- package/node_modules/yaml/browser/dist/nodes/toJS.js +37 -0
- package/node_modules/yaml/browser/dist/parse/cst-scalar.js +214 -0
- package/node_modules/yaml/browser/dist/parse/cst-stringify.js +61 -0
- package/node_modules/yaml/browser/dist/parse/cst-visit.js +97 -0
- package/node_modules/yaml/browser/dist/parse/cst.js +98 -0
- package/node_modules/yaml/browser/dist/parse/lexer.js +721 -0
- package/node_modules/yaml/browser/dist/parse/line-counter.js +39 -0
- package/node_modules/yaml/browser/dist/parse/parser.js +975 -0
- package/node_modules/yaml/browser/dist/public-api.js +102 -0
- package/node_modules/yaml/browser/dist/schema/Schema.js +37 -0
- package/node_modules/yaml/browser/dist/schema/common/map.js +17 -0
- package/node_modules/yaml/browser/dist/schema/common/null.js +15 -0
- package/node_modules/yaml/browser/dist/schema/common/seq.js +17 -0
- package/node_modules/yaml/browser/dist/schema/common/string.js +14 -0
- package/node_modules/yaml/browser/dist/schema/core/bool.js +19 -0
- package/node_modules/yaml/browser/dist/schema/core/float.js +43 -0
- package/node_modules/yaml/browser/dist/schema/core/int.js +38 -0
- package/node_modules/yaml/browser/dist/schema/core/schema.js +23 -0
- package/node_modules/yaml/browser/dist/schema/json/schema.js +62 -0
- package/node_modules/yaml/browser/dist/schema/tags.js +96 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/binary.js +58 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/bool.js +26 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/float.js +46 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/int.js +71 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/merge.js +67 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/omap.js +74 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/pairs.js +78 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/schema.js +39 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/set.js +93 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/timestamp.js +101 -0
- package/node_modules/yaml/browser/dist/stringify/foldFlowLines.js +146 -0
- package/node_modules/yaml/browser/dist/stringify/stringify.js +129 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyCollection.js +153 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyComment.js +20 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyDocument.js +85 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyNumber.js +25 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyPair.js +150 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyString.js +336 -0
- package/node_modules/yaml/browser/dist/util.js +11 -0
- package/node_modules/yaml/browser/dist/visit.js +233 -0
- package/node_modules/yaml/browser/index.js +5 -0
- package/node_modules/yaml/browser/package.json +3 -0
- package/node_modules/yaml/dist/cli.d.ts +8 -0
- package/node_modules/yaml/dist/cli.mjs +201 -0
- package/node_modules/yaml/dist/compose/compose-collection.d.ts +11 -0
- package/node_modules/yaml/dist/compose/compose-collection.js +90 -0
- package/node_modules/yaml/dist/compose/compose-doc.d.ts +7 -0
- package/node_modules/yaml/dist/compose/compose-doc.js +45 -0
- package/node_modules/yaml/dist/compose/compose-node.d.ts +29 -0
- package/node_modules/yaml/dist/compose/compose-node.js +112 -0
- package/node_modules/yaml/dist/compose/compose-scalar.d.ts +5 -0
- package/node_modules/yaml/dist/compose/compose-scalar.js +88 -0
- package/node_modules/yaml/dist/compose/composer.d.ts +63 -0
- package/node_modules/yaml/dist/compose/composer.js +224 -0
- package/node_modules/yaml/dist/compose/resolve-block-map.d.ts +6 -0
- package/node_modules/yaml/dist/compose/resolve-block-map.js +117 -0
- package/node_modules/yaml/dist/compose/resolve-block-scalar.d.ts +11 -0
- package/node_modules/yaml/dist/compose/resolve-block-scalar.js +200 -0
- package/node_modules/yaml/dist/compose/resolve-block-seq.d.ts +6 -0
- package/node_modules/yaml/dist/compose/resolve-block-seq.js +51 -0
- package/node_modules/yaml/dist/compose/resolve-end.d.ts +6 -0
- package/node_modules/yaml/dist/compose/resolve-end.js +39 -0
- package/node_modules/yaml/dist/compose/resolve-flow-collection.d.ts +7 -0
- package/node_modules/yaml/dist/compose/resolve-flow-collection.js +209 -0
- package/node_modules/yaml/dist/compose/resolve-flow-scalar.d.ts +10 -0
- package/node_modules/yaml/dist/compose/resolve-flow-scalar.js +227 -0
- package/node_modules/yaml/dist/compose/resolve-props.d.ts +23 -0
- package/node_modules/yaml/dist/compose/resolve-props.js +148 -0
- package/node_modules/yaml/dist/compose/util-contains-newline.d.ts +2 -0
- package/node_modules/yaml/dist/compose/util-contains-newline.js +36 -0
- package/node_modules/yaml/dist/compose/util-empty-scalar-position.d.ts +2 -0
- package/node_modules/yaml/dist/compose/util-empty-scalar-position.js +28 -0
- package/node_modules/yaml/dist/compose/util-flow-indent-check.d.ts +3 -0
- package/node_modules/yaml/dist/compose/util-flow-indent-check.js +17 -0
- package/node_modules/yaml/dist/compose/util-map-includes.d.ts +4 -0
- package/node_modules/yaml/dist/compose/util-map-includes.js +15 -0
- package/node_modules/yaml/dist/doc/Document.d.ts +141 -0
- package/node_modules/yaml/dist/doc/Document.js +337 -0
- package/node_modules/yaml/dist/doc/anchors.d.ts +24 -0
- package/node_modules/yaml/dist/doc/anchors.js +76 -0
- package/node_modules/yaml/dist/doc/applyReviver.d.ts +9 -0
- package/node_modules/yaml/dist/doc/applyReviver.js +57 -0
- package/node_modules/yaml/dist/doc/createNode.d.ts +17 -0
- package/node_modules/yaml/dist/doc/createNode.js +90 -0
- package/node_modules/yaml/dist/doc/directives.d.ts +49 -0
- package/node_modules/yaml/dist/doc/directives.js +178 -0
- package/node_modules/yaml/dist/errors.d.ts +21 -0
- package/node_modules/yaml/dist/errors.js +62 -0
- package/node_modules/yaml/dist/index.d.ts +25 -0
- package/node_modules/yaml/dist/index.js +50 -0
- package/node_modules/yaml/dist/log.d.ts +3 -0
- package/node_modules/yaml/dist/log.js +19 -0
- package/node_modules/yaml/dist/nodes/Alias.d.ts +29 -0
- package/node_modules/yaml/dist/nodes/Alias.js +118 -0
- package/node_modules/yaml/dist/nodes/Collection.d.ts +73 -0
- package/node_modules/yaml/dist/nodes/Collection.js +151 -0
- package/node_modules/yaml/dist/nodes/Node.d.ts +53 -0
- package/node_modules/yaml/dist/nodes/Node.js +40 -0
- package/node_modules/yaml/dist/nodes/Pair.d.ts +22 -0
- package/node_modules/yaml/dist/nodes/Pair.js +39 -0
- package/node_modules/yaml/dist/nodes/Scalar.d.ts +47 -0
- package/node_modules/yaml/dist/nodes/Scalar.js +27 -0
- package/node_modules/yaml/dist/nodes/YAMLMap.d.ts +53 -0
- package/node_modules/yaml/dist/nodes/YAMLMap.js +147 -0
- package/node_modules/yaml/dist/nodes/YAMLSeq.d.ts +60 -0
- package/node_modules/yaml/dist/nodes/YAMLSeq.js +115 -0
- package/node_modules/yaml/dist/nodes/addPairToJSMap.d.ts +4 -0
- package/node_modules/yaml/dist/nodes/addPairToJSMap.js +65 -0
- package/node_modules/yaml/dist/nodes/identity.d.ts +23 -0
- package/node_modules/yaml/dist/nodes/identity.js +53 -0
- package/node_modules/yaml/dist/nodes/toJS.d.ts +29 -0
- package/node_modules/yaml/dist/nodes/toJS.js +39 -0
- package/node_modules/yaml/dist/options.d.ts +350 -0
- package/node_modules/yaml/dist/parse/cst-scalar.d.ts +64 -0
- package/node_modules/yaml/dist/parse/cst-scalar.js +218 -0
- package/node_modules/yaml/dist/parse/cst-stringify.d.ts +8 -0
- package/node_modules/yaml/dist/parse/cst-stringify.js +63 -0
- package/node_modules/yaml/dist/parse/cst-visit.d.ts +39 -0
- package/node_modules/yaml/dist/parse/cst-visit.js +99 -0
- package/node_modules/yaml/dist/parse/cst.d.ts +109 -0
- package/node_modules/yaml/dist/parse/cst.js +112 -0
- package/node_modules/yaml/dist/parse/lexer.d.ts +87 -0
- package/node_modules/yaml/dist/parse/lexer.js +723 -0
- package/node_modules/yaml/dist/parse/line-counter.d.ts +22 -0
- package/node_modules/yaml/dist/parse/line-counter.js +41 -0
- package/node_modules/yaml/dist/parse/parser.d.ts +84 -0
- package/node_modules/yaml/dist/parse/parser.js +980 -0
- package/node_modules/yaml/dist/public-api.d.ts +44 -0
- package/node_modules/yaml/dist/public-api.js +107 -0
- package/node_modules/yaml/dist/schema/Schema.d.ts +17 -0
- package/node_modules/yaml/dist/schema/Schema.js +39 -0
- package/node_modules/yaml/dist/schema/common/map.d.ts +2 -0
- package/node_modules/yaml/dist/schema/common/map.js +19 -0
- package/node_modules/yaml/dist/schema/common/null.d.ts +4 -0
- package/node_modules/yaml/dist/schema/common/null.js +17 -0
- package/node_modules/yaml/dist/schema/common/seq.d.ts +2 -0
- package/node_modules/yaml/dist/schema/common/seq.js +19 -0
- package/node_modules/yaml/dist/schema/common/string.d.ts +2 -0
- package/node_modules/yaml/dist/schema/common/string.js +16 -0
- package/node_modules/yaml/dist/schema/core/bool.d.ts +4 -0
- package/node_modules/yaml/dist/schema/core/bool.js +21 -0
- package/node_modules/yaml/dist/schema/core/float.d.ts +4 -0
- package/node_modules/yaml/dist/schema/core/float.js +47 -0
- package/node_modules/yaml/dist/schema/core/int.d.ts +4 -0
- package/node_modules/yaml/dist/schema/core/int.js +42 -0
- package/node_modules/yaml/dist/schema/core/schema.d.ts +1 -0
- package/node_modules/yaml/dist/schema/core/schema.js +25 -0
- package/node_modules/yaml/dist/schema/json/schema.d.ts +2 -0
- package/node_modules/yaml/dist/schema/json/schema.js +64 -0
- package/node_modules/yaml/dist/schema/json-schema.d.ts +69 -0
- package/node_modules/yaml/dist/schema/tags.d.ts +48 -0
- package/node_modules/yaml/dist/schema/tags.js +99 -0
- package/node_modules/yaml/dist/schema/types.d.ts +92 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/binary.d.ts +2 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/binary.js +70 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/bool.d.ts +7 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/bool.js +29 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/float.d.ts +4 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/float.js +50 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/int.d.ts +5 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/int.js +76 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/merge.d.ts +9 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/merge.js +71 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/omap.d.ts +22 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/omap.js +77 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/pairs.d.ts +10 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/pairs.js +82 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/schema.d.ts +1 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/schema.js +41 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/set.d.ts +28 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/set.js +96 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/timestamp.d.ts +6 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js +105 -0
- package/node_modules/yaml/dist/stringify/foldFlowLines.d.ts +34 -0
- package/node_modules/yaml/dist/stringify/foldFlowLines.js +151 -0
- package/node_modules/yaml/dist/stringify/stringify.d.ts +21 -0
- package/node_modules/yaml/dist/stringify/stringify.js +132 -0
- package/node_modules/yaml/dist/stringify/stringifyCollection.d.ts +17 -0
- package/node_modules/yaml/dist/stringify/stringifyCollection.js +155 -0
- package/node_modules/yaml/dist/stringify/stringifyComment.d.ts +10 -0
- package/node_modules/yaml/dist/stringify/stringifyComment.js +24 -0
- package/node_modules/yaml/dist/stringify/stringifyDocument.d.ts +4 -0
- package/node_modules/yaml/dist/stringify/stringifyDocument.js +87 -0
- package/node_modules/yaml/dist/stringify/stringifyNumber.d.ts +2 -0
- package/node_modules/yaml/dist/stringify/stringifyNumber.js +27 -0
- package/node_modules/yaml/dist/stringify/stringifyPair.d.ts +3 -0
- package/node_modules/yaml/dist/stringify/stringifyPair.js +152 -0
- package/node_modules/yaml/dist/stringify/stringifyString.d.ts +9 -0
- package/node_modules/yaml/dist/stringify/stringifyString.js +338 -0
- package/node_modules/yaml/dist/test-events.d.ts +4 -0
- package/node_modules/yaml/dist/test-events.js +134 -0
- package/node_modules/yaml/dist/util.d.ts +16 -0
- package/node_modules/yaml/dist/util.js +28 -0
- package/node_modules/yaml/dist/visit.d.ts +102 -0
- package/node_modules/yaml/dist/visit.js +236 -0
- package/node_modules/yaml/package.json +97 -0
- package/node_modules/yaml/util.js +2 -0
- package/package.json +2 -2
- package/node_modules/@llblab/pi-actors/banner.jpg +0 -0
- package/node_modules/@llblab/pi-actors/dist/lib/inspector-actions.d.ts +0 -16
- package/node_modules/@llblab/pi-actors/dist/lib/inspector-actions.js +0 -57
- package/node_modules/@llblab/pi-actors/lib/inspector-actions.ts +0 -79
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run context-index metadata, deterministic references and admitted publication.
|
|
3
|
+
* Owns: bounded identity/index reads, role schema, regular references and admitted index publication.
|
|
4
|
+
* Excludes: role-body reads/creation/redaction, model exposure authorization, lifecycle admission and native authority.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { closeSync, constants, fstatSync, lstatSync, openSync, readSync, type BigIntStats } from "node:fs";
|
|
8
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
9
|
+
|
|
10
|
+
import { writeTextAtomic } from "./file-state.ts";
|
|
11
|
+
import { readOwnedRunStateDirectory, RUN_STATE_OWNERSHIP_FILE } from "./runs-ownership.ts";
|
|
12
|
+
|
|
13
|
+
export const RUN_CONTEXT_INDEX_FILE = "context-index.json";
|
|
14
|
+
export const RUN_CONTEXT_INDEX_METADATA_MAX_BYTES = 16 * 1024;
|
|
15
|
+
/** Canonical run.json input, not an index/marker/model-output allowance. */
|
|
16
|
+
export const RUN_CONTEXT_SOURCE_METADATA_MAX_BYTES = 1024 * 1024;
|
|
17
|
+
|
|
18
|
+
const EXPORTS = {
|
|
19
|
+
recipe: ["recipe.json", "application/json", false],
|
|
20
|
+
result: ["result.json", "application/json", false],
|
|
21
|
+
trace: ["trace.jsonl", "application/x-ndjson", true],
|
|
22
|
+
control: ["control.json", "application/json", true],
|
|
23
|
+
execution: ["execution.json", "application/json", true],
|
|
24
|
+
artifacts: ["artifacts.json", "application/json", false],
|
|
25
|
+
sessions: ["sessions.json", "application/json", true],
|
|
26
|
+
stdout: ["stdout.log", "text/plain", true],
|
|
27
|
+
stderr: ["stderr.log", "text/plain", true],
|
|
28
|
+
} as const;
|
|
29
|
+
|
|
30
|
+
export type RunContextRole = keyof typeof EXPORTS;
|
|
31
|
+
export function runContextExportPath(role: RunContextRole): string {
|
|
32
|
+
return "evidence/" + EXPORTS[role][0];
|
|
33
|
+
}
|
|
34
|
+
export interface RunContextIndexIdentity {
|
|
35
|
+
readonly run: string;
|
|
36
|
+
readonly run_instance_id: string;
|
|
37
|
+
readonly ownerId?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface RunContextCoverage {
|
|
40
|
+
readonly truncated: boolean;
|
|
41
|
+
readonly redacted: boolean;
|
|
42
|
+
readonly history_complete?: boolean;
|
|
43
|
+
}
|
|
44
|
+
export type RunContextEntry =
|
|
45
|
+
| { readonly availability: "available"; readonly path: string; readonly media_type: string;
|
|
46
|
+
readonly bytes_total: number; readonly mutable: boolean; readonly coverage: Readonly<RunContextCoverage> }
|
|
47
|
+
| { readonly availability: "pending" | "not_applicable"; readonly path: null }
|
|
48
|
+
| { readonly availability: "unavailable"; readonly path: null; readonly reason: string };
|
|
49
|
+
export interface RunContextIndex {
|
|
50
|
+
readonly schema: "run-context-index-v1";
|
|
51
|
+
readonly run: string;
|
|
52
|
+
readonly run_instance_id: string;
|
|
53
|
+
readonly updated_at: string;
|
|
54
|
+
readonly entries: Readonly<Record<RunContextRole, Readonly<RunContextEntry>>>;
|
|
55
|
+
}
|
|
56
|
+
export type RunContextIndexReading =
|
|
57
|
+
| { readonly state: "available"; readonly index: Readonly<RunContextIndex>;
|
|
58
|
+
readonly identity: Readonly<RunContextIndexIdentity>; readonly local_path: string }
|
|
59
|
+
| { readonly state: "unavailable"; readonly reason: "identity_unavailable" | "identity_mismatch" |
|
|
60
|
+
"index_unavailable" | "index_invalid" | "role_unavailable" | "observation_changed" };
|
|
61
|
+
|
|
62
|
+
export type RunContextIdentityReading =
|
|
63
|
+
| { readonly state: "available"; readonly identity: Readonly<RunContextIndexIdentity>;
|
|
64
|
+
readonly local_path: string; readonly unchanged: () => boolean }
|
|
65
|
+
| { readonly state: "unavailable"; readonly reason: "identity_unavailable" | "identity_mismatch" | "observation_changed" };
|
|
66
|
+
|
|
67
|
+
export type RunContextExportLocationReading =
|
|
68
|
+
| { readonly state: "available"; readonly identity: Readonly<RunContextIndexIdentity>;
|
|
69
|
+
readonly path: string; readonly local_path: string; readonly bytes_total: number;
|
|
70
|
+
readonly mutable: true; readonly unchanged: () => boolean }
|
|
71
|
+
| { readonly state: "unavailable"; readonly reason: "role_invalid" | "identity_unavailable" | "identity_mismatch" |
|
|
72
|
+
"observation_changed" | "export_missing" | "export_unavailable" | "export_size_unrepresentable" };
|
|
73
|
+
|
|
74
|
+
type IndexUnavailable = Extract<RunContextIndexReading, { state: "unavailable" }>;
|
|
75
|
+
type FailureReason = IndexUnavailable["reason"];
|
|
76
|
+
function unavailable(reason: FailureReason): IndexUnavailable {
|
|
77
|
+
return Object.freeze({ state: "unavailable", reason });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function object(value: unknown): Record<string, unknown> | undefined {
|
|
81
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value as Record<string, unknown> : undefined;
|
|
82
|
+
}
|
|
83
|
+
function own(value: Record<string, unknown> | undefined, key: string): unknown {
|
|
84
|
+
return value && Object.hasOwn(value, key) ? value[key] : undefined;
|
|
85
|
+
}
|
|
86
|
+
function known(value: Record<string, unknown>, keys: readonly string[]): boolean {
|
|
87
|
+
return Object.keys(value).every(key => keys.includes(key));
|
|
88
|
+
}
|
|
89
|
+
function text(value: unknown): value is string {
|
|
90
|
+
return typeof value === "string" && value.length > 0 && value.length <= RUN_CONTEXT_INDEX_METADATA_MAX_BYTES;
|
|
91
|
+
}
|
|
92
|
+
function identity(value: unknown): RunContextIndexIdentity | undefined {
|
|
93
|
+
const source = object(value);
|
|
94
|
+
const run = own(source, "run");
|
|
95
|
+
const generation = own(source, "run_instance_id");
|
|
96
|
+
if (!text(run) || /[^A-Za-z0-9_.-]/u.test(run) || !text(generation)) return undefined;
|
|
97
|
+
if (source && Object.hasOwn(source, "ownerId")) {
|
|
98
|
+
return text(source.ownerId) ? { run, run_instance_id: generation, ownerId: source.ownerId } : undefined;
|
|
99
|
+
}
|
|
100
|
+
return source?.ownerId === undefined ? { run, run_instance_id: generation } : undefined;
|
|
101
|
+
}
|
|
102
|
+
function sameIdentity(left: RunContextIndexIdentity, right: RunContextIndexIdentity): boolean {
|
|
103
|
+
return left.run === right.run && left.run_instance_id === right.run_instance_id && left.ownerId === right.ownerId;
|
|
104
|
+
}
|
|
105
|
+
function sameObject(left: BigIntStats, right: BigIntStats): boolean {
|
|
106
|
+
return left.dev === right.dev && left.ino === right.ino;
|
|
107
|
+
}
|
|
108
|
+
function sameFile(left: BigIntStats, right: BigIntStats): boolean {
|
|
109
|
+
return right.isFile() && sameObject(left, right) && left.size === right.size &&
|
|
110
|
+
left.mtimeNs === right.mtimeNs && left.ctimeNs === right.ctimeNs;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Retain the opened object for bounded JSON reads or readability-only role checks; never read role bytes. */
|
|
114
|
+
function inspectFile(path: string, metadataMaxBytes?: number): { stamp: BigIntStats; value: unknown } | undefined {
|
|
115
|
+
let fd: number | undefined;
|
|
116
|
+
try {
|
|
117
|
+
const before = lstatSync(path, { bigint: true });
|
|
118
|
+
if (!before.isFile() || (metadataMaxBytes !== undefined && before.size > BigInt(metadataMaxBytes))) return undefined;
|
|
119
|
+
fd = openSync(path, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0));
|
|
120
|
+
const opened = fstatSync(fd, { bigint: true });
|
|
121
|
+
if (!sameFile(before, opened)) return undefined;
|
|
122
|
+
let value: unknown;
|
|
123
|
+
if (metadataMaxBytes !== undefined) {
|
|
124
|
+
const bytes = Buffer.alloc(Number(opened.size));
|
|
125
|
+
let offset = 0;
|
|
126
|
+
while (offset < bytes.length) {
|
|
127
|
+
const read = readSync(fd, bytes, offset, bytes.length - offset, offset);
|
|
128
|
+
if (!read) break;
|
|
129
|
+
offset += read;
|
|
130
|
+
}
|
|
131
|
+
if (offset !== bytes.length) return undefined;
|
|
132
|
+
try { value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes)); }
|
|
133
|
+
catch { value = undefined; }
|
|
134
|
+
}
|
|
135
|
+
if (!sameFile(opened, fstatSync(fd, { bigint: true })) || !sameFile(opened, lstatSync(path, { bigint: true }))) return undefined;
|
|
136
|
+
return { stamp: opened, value };
|
|
137
|
+
} catch { return undefined; }
|
|
138
|
+
finally { if (fd !== undefined) closeSync(fd); }
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function decodeEntry(value: unknown, role: RunContextRole): Readonly<RunContextEntry> | undefined {
|
|
142
|
+
const entry = object(value);
|
|
143
|
+
if (!entry) return undefined;
|
|
144
|
+
const availability = own(entry, "availability");
|
|
145
|
+
const path = own(entry, "path");
|
|
146
|
+
if (availability === "pending" || availability === "not_applicable") {
|
|
147
|
+
return path === null && known(entry, ["availability", "path"]) ? Object.freeze({ availability, path }) : undefined;
|
|
148
|
+
}
|
|
149
|
+
if (availability === "unavailable") {
|
|
150
|
+
const reason = own(entry, "reason");
|
|
151
|
+
return path === null && typeof reason === "string" && /^[a-z][a-z0-9_]{0,63}$/u.test(reason) &&
|
|
152
|
+
!/[\r\n]/u.test(reason) && known(entry, ["availability", "path", "reason"])
|
|
153
|
+
? Object.freeze({ availability, path, reason }) : undefined;
|
|
154
|
+
}
|
|
155
|
+
const [, media, temporal] = EXPORTS[role];
|
|
156
|
+
const mediaType = own(entry, "media_type");
|
|
157
|
+
const bytes = own(entry, "bytes_total");
|
|
158
|
+
const mutable = own(entry, "mutable");
|
|
159
|
+
const coverage = object(own(entry, "coverage"));
|
|
160
|
+
if (availability !== "available" || path !== runContextExportPath(role) || typeof mediaType !== "string" ||
|
|
161
|
+
(mediaType !== media && !(media === "text/plain" && mediaType === "text/plain; charset=utf-8")) ||
|
|
162
|
+
typeof bytes !== "number" || !Number.isSafeInteger(bytes) || bytes < 0 || typeof mutable !== "boolean" || !coverage ||
|
|
163
|
+
!known(entry, ["availability", "path", "media_type", "bytes_total", "mutable", "coverage"]) ||
|
|
164
|
+
!known(coverage, ["truncated", "redacted", "history_complete"]) ||
|
|
165
|
+
typeof own(coverage, "truncated") !== "boolean" || typeof own(coverage, "redacted") !== "boolean" ||
|
|
166
|
+
((temporal || Object.hasOwn(coverage, "history_complete")) && typeof own(coverage, "history_complete") !== "boolean")) return undefined;
|
|
167
|
+
return Object.freeze({ availability, path, media_type: mediaType, bytes_total: bytes, mutable,
|
|
168
|
+
coverage: Object.freeze({ truncated: coverage.truncated as boolean, redacted: coverage.redacted as boolean,
|
|
169
|
+
...(typeof coverage.history_complete === "boolean" ? { history_complete: coverage.history_complete } : {}) }) });
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function decodeIndex(value: unknown, expected: RunContextIndexIdentity): Readonly<RunContextIndex> | undefined {
|
|
173
|
+
const source = object(value);
|
|
174
|
+
const entries = object(own(source, "entries"));
|
|
175
|
+
const updated = own(source, "updated_at");
|
|
176
|
+
const time = typeof updated === "string" ? Date.parse(updated) : NaN;
|
|
177
|
+
if (!source || !known(source, ["schema", "run", "run_instance_id", "updated_at", "entries"]) ||
|
|
178
|
+
own(source, "schema") !== "run-context-index-v1" || own(source, "run") !== expected.run ||
|
|
179
|
+
own(source, "run_instance_id") !== expected.run_instance_id || !entries ||
|
|
180
|
+
!Number.isSafeInteger(time) || new Date(time).toISOString() !== updated || !known(entries, Object.keys(EXPORTS))) return undefined;
|
|
181
|
+
const decoded = {} as Record<RunContextRole, Readonly<RunContextEntry>>;
|
|
182
|
+
for (const role of Object.keys(EXPORTS) as RunContextRole[]) {
|
|
183
|
+
const entry = decodeEntry(own(entries, role), role);
|
|
184
|
+
if (!entry) return undefined;
|
|
185
|
+
decoded[role] = entry;
|
|
186
|
+
}
|
|
187
|
+
return Object.freeze({ schema: "run-context-index-v1", run: expected.run, run_instance_id: expected.run_instance_id,
|
|
188
|
+
updated_at: updated as string, entries: Object.freeze(decoded) });
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
interface ContextOwnerObservation {
|
|
192
|
+
root: string;
|
|
193
|
+
directory: BigIntStats;
|
|
194
|
+
marker: BigIntStats;
|
|
195
|
+
meta: BigIntStats;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function readContextOwner(stateDir: string, request: RunContextIndexIdentity):
|
|
199
|
+
{ state: "available"; owner: ContextOwnerObservation } | IndexUnavailable {
|
|
200
|
+
try {
|
|
201
|
+
const root = resolve(stateDir);
|
|
202
|
+
const directory = lstatSync(root, { bigint: true });
|
|
203
|
+
const marker = lstatSync(join(root, RUN_STATE_OWNERSHIP_FILE), { bigint: true });
|
|
204
|
+
if (!directory.isDirectory() || !marker.isFile() || marker.size > BigInt(RUN_CONTEXT_INDEX_METADATA_MAX_BYTES)) {
|
|
205
|
+
return unavailable("identity_unavailable");
|
|
206
|
+
}
|
|
207
|
+
const owned = readOwnedRunStateDirectory(root, { maxBytes: RUN_CONTEXT_INDEX_METADATA_MAX_BYTES });
|
|
208
|
+
if (owned.run !== request.run) return unavailable("identity_mismatch");
|
|
209
|
+
const meta = inspectFile(join(owned.stateDir, "run.json"), RUN_CONTEXT_SOURCE_METADATA_MAX_BYTES);
|
|
210
|
+
const value = object(meta?.value);
|
|
211
|
+
const actual = identity(value);
|
|
212
|
+
if (!meta || !value || !actual) return unavailable("identity_unavailable");
|
|
213
|
+
if (!sameIdentity(request, actual) || own(value, "state_dir") !== owned.stateDir) return unavailable("identity_mismatch");
|
|
214
|
+
return { state: "available", owner: { root: owned.stateDir, directory, marker, meta: meta.stamp } };
|
|
215
|
+
} catch { return unavailable("identity_unavailable"); }
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function ownerUnchanged(owner: ContextOwnerObservation): boolean {
|
|
219
|
+
const current = lstatSync(owner.root, { bigint: true });
|
|
220
|
+
return current.isDirectory() && sameObject(owner.directory, current) &&
|
|
221
|
+
sameFile(owner.marker, lstatSync(join(owner.root, RUN_STATE_OWNERSHIP_FILE), { bigint: true })) &&
|
|
222
|
+
sameFile(owner.meta, lstatSync(join(owner.root, "run.json"), { bigint: true }));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** Shared readonly owner/generation observation without requiring an index or granting body/work authority. */
|
|
226
|
+
export function readRunContextIdentity(stateDir: string, expected: unknown): Readonly<RunContextIdentityReading> {
|
|
227
|
+
const request = identity(expected);
|
|
228
|
+
if (!request || !isAbsolute(stateDir)) return Object.freeze({ state: "unavailable", reason: "identity_unavailable" });
|
|
229
|
+
const admission = readContextOwner(stateDir, request);
|
|
230
|
+
if (admission.state === "unavailable") return Object.freeze({ state: "unavailable",
|
|
231
|
+
reason: admission.reason === "identity_mismatch" ? "identity_mismatch" : "identity_unavailable" });
|
|
232
|
+
const unchanged = (): boolean => { try { return ownerUnchanged(admission.owner); } catch { return false; } };
|
|
233
|
+
if (!unchanged()) return Object.freeze({ state: "unavailable", reason: "observation_changed" });
|
|
234
|
+
return Object.freeze({ state: "available", identity: Object.freeze({ ...request }), local_path: admission.owner.root, unchanged });
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
interface ExportObservation { path: string; stamp: BigIntStats; directory: BigIntStats; }
|
|
238
|
+
function inspectExport(root: string, entry: Extract<RunContextEntry, { availability: "available" }>): ExportObservation | undefined {
|
|
239
|
+
try {
|
|
240
|
+
const directory = lstatSync(join(root, "evidence"), { bigint: true });
|
|
241
|
+
if (!directory.isDirectory() || directory.isSymbolicLink()) return undefined;
|
|
242
|
+
const path = join(root, entry.path);
|
|
243
|
+
const observed = inspectFile(path);
|
|
244
|
+
return observed && observed.stamp.size === BigInt(entry.bytes_total) ? { path, stamp: observed.stamp, directory } : undefined;
|
|
245
|
+
} catch { return undefined; }
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function exportsUnchanged(root: string, exports: readonly ExportObservation[]): boolean {
|
|
249
|
+
return exports.every(file => {
|
|
250
|
+
const directory = lstatSync(join(root, "evidence"), { bigint: true });
|
|
251
|
+
return directory.isDirectory() && !directory.isSymbolicLink() && sameObject(file.directory, directory) &&
|
|
252
|
+
sameFile(file.stamp, lstatSync(file.path, { bigint: true }));
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/** Physical fixed-role location only: no index/producer, role-body reads or curated publication certification. */
|
|
257
|
+
export function observeRunContextExportLocation(stateDir: string, expected: unknown, role: unknown): Readonly<RunContextExportLocationReading> {
|
|
258
|
+
const refused = (reason: Extract<RunContextExportLocationReading, { state: "unavailable" }>["reason"]): Readonly<RunContextExportLocationReading> => Object.freeze({ state: "unavailable", reason });
|
|
259
|
+
if (typeof role !== "string" || !Object.hasOwn(EXPORTS, role)) return refused("role_invalid");
|
|
260
|
+
const owner = readRunContextIdentity(stateDir, expected);
|
|
261
|
+
if (owner.state === "unavailable") return owner;
|
|
262
|
+
const relative = runContextExportPath(role as RunContextRole);
|
|
263
|
+
try {
|
|
264
|
+
const directory = lstatSync(join(owner.local_path, "evidence"), { bigint: true });
|
|
265
|
+
if (!directory.isDirectory() || directory.isSymbolicLink()) return refused("export_unavailable");
|
|
266
|
+
const path = join(owner.local_path, relative);
|
|
267
|
+
const stamp = lstatSync(path, { bigint: true });
|
|
268
|
+
if (!stamp.isFile()) return refused("export_unavailable");
|
|
269
|
+
if (stamp.size < 0n || stamp.size > BigInt(Number.MAX_SAFE_INTEGER)) return refused("export_size_unrepresentable");
|
|
270
|
+
const observed: ExportObservation = { path, stamp, directory };
|
|
271
|
+
const unchanged = (): boolean => {
|
|
272
|
+
try { return owner.unchanged() && exportsUnchanged(owner.local_path, [observed]); }
|
|
273
|
+
catch { return false; }
|
|
274
|
+
};
|
|
275
|
+
if (!unchanged()) return refused("observation_changed");
|
|
276
|
+
return Object.freeze({ state: "available", identity: owner.identity, path: relative, local_path: path,
|
|
277
|
+
bytes_total: Number(stamp.size), mutable: true, unchanged });
|
|
278
|
+
} catch (error) { return refused((error as NodeJS.ErrnoException).code === "ENOENT" ? "export_missing" : "export_unavailable"); }
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/** Kernel-local metadata, not proof that bodies are redacted/immutable or permission to expose local_path. */
|
|
282
|
+
export function readRunContextIndex(stateDir: string, expected: unknown): Readonly<RunContextIndexReading> {
|
|
283
|
+
const request = identity(expected);
|
|
284
|
+
if (!request || !isAbsolute(stateDir)) return unavailable("identity_unavailable");
|
|
285
|
+
try {
|
|
286
|
+
const admission = readContextOwner(stateDir, request);
|
|
287
|
+
if (admission.state === "unavailable") return admission;
|
|
288
|
+
const owner = admission.owner;
|
|
289
|
+
const indexPath = join(owner.root, RUN_CONTEXT_INDEX_FILE);
|
|
290
|
+
const captured = inspectFile(indexPath, RUN_CONTEXT_INDEX_METADATA_MAX_BYTES);
|
|
291
|
+
if (!captured) return unavailable("index_unavailable");
|
|
292
|
+
const index = decodeIndex(captured.value, request);
|
|
293
|
+
if (!index) return unavailable("index_invalid");
|
|
294
|
+
const admitted: ExportObservation[] = [];
|
|
295
|
+
for (const entry of Object.values(index.entries)) {
|
|
296
|
+
if (entry.availability !== "available") continue;
|
|
297
|
+
const observed = inspectExport(owner.root, entry);
|
|
298
|
+
if (!observed) return unavailable("role_unavailable");
|
|
299
|
+
admitted.push(observed);
|
|
300
|
+
}
|
|
301
|
+
// These rechecks reject observed change, not a multi-file atomic-snapshot or sandbox guarantee.
|
|
302
|
+
if (!ownerUnchanged(owner) || !sameFile(captured.stamp, lstatSync(indexPath, { bigint: true })) ||
|
|
303
|
+
!exportsUnchanged(owner.root, admitted)) return unavailable("observation_changed");
|
|
304
|
+
return Object.freeze({ state: "available", index, identity: Object.freeze({ ...request }), local_path: indexPath });
|
|
305
|
+
} catch { return unavailable("index_unavailable"); }
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export interface RunContextIndexPublication {
|
|
309
|
+
readonly index: Readonly<RunContextIndex>;
|
|
310
|
+
readonly local_path: string;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/** Trusted persistence only: the caller must hold evidence admission and supply authorized export-owner metadata, not actor flags. */
|
|
314
|
+
export function writeRunContextIndexUnderLock(
|
|
315
|
+
stateDir: string,
|
|
316
|
+
expected: unknown,
|
|
317
|
+
updates: unknown,
|
|
318
|
+
): Readonly<RunContextIndexPublication> {
|
|
319
|
+
const request = identity(expected);
|
|
320
|
+
const changes = object(updates);
|
|
321
|
+
if (!request || !isAbsolute(stateDir) || !changes || !known(changes, Object.keys(EXPORTS))) {
|
|
322
|
+
throw new Error("Run context index publication input is invalid.");
|
|
323
|
+
}
|
|
324
|
+
const admission = readContextOwner(stateDir, request);
|
|
325
|
+
if (admission.state === "unavailable") throw new Error("Run context index owner is unavailable or changed.");
|
|
326
|
+
const owner = admission.owner;
|
|
327
|
+
const path = join(owner.root, RUN_CONTEXT_INDEX_FILE);
|
|
328
|
+
let prior: Readonly<RunContextIndex> | undefined;
|
|
329
|
+
let priorStamp: BigIntStats | undefined;
|
|
330
|
+
try {
|
|
331
|
+
const existing = lstatSync(path, { bigint: true });
|
|
332
|
+
if (!existing.isFile()) throw new Error("Run context index target is unavailable or invalid.");
|
|
333
|
+
const captured = inspectFile(path, RUN_CONTEXT_INDEX_METADATA_MAX_BYTES);
|
|
334
|
+
if (!captured || !(prior = decodeIndex(captured.value, request))) {
|
|
335
|
+
throw new Error("Run context index is unavailable, invalid or belongs to another generation.");
|
|
336
|
+
}
|
|
337
|
+
priorStamp = captured.stamp;
|
|
338
|
+
} catch (error) {
|
|
339
|
+
if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
|
|
340
|
+
}
|
|
341
|
+
const entries = Object.fromEntries((Object.keys(EXPORTS) as RunContextRole[]).map(role => [
|
|
342
|
+
role, Object.hasOwn(changes, role) ? changes[role] : prior?.entries[role] ??
|
|
343
|
+
{ availability: "unavailable", path: null, reason: "export_not_published" },
|
|
344
|
+
]));
|
|
345
|
+
const candidate = decodeIndex({ schema: "run-context-index-v1", run: request.run, run_instance_id: request.run_instance_id,
|
|
346
|
+
updated_at: new Date().toISOString(), entries }, request);
|
|
347
|
+
if (!candidate) throw new Error("Run context index role metadata is invalid.");
|
|
348
|
+
const admitted: ExportObservation[] = [];
|
|
349
|
+
const finalEntries = { ...candidate.entries };
|
|
350
|
+
for (const role of Object.keys(EXPORTS) as RunContextRole[]) {
|
|
351
|
+
const entry = candidate.entries[role];
|
|
352
|
+
if (entry.availability !== "available") continue;
|
|
353
|
+
const observed = inspectExport(owner.root, entry);
|
|
354
|
+
if (observed) admitted.push(observed);
|
|
355
|
+
else finalEntries[role] = Object.freeze({ availability: "unavailable", path: null, reason: "export_unavailable" });
|
|
356
|
+
}
|
|
357
|
+
const index = Object.freeze({ ...candidate, entries: Object.freeze(finalEntries) });
|
|
358
|
+
const content = JSON.stringify(index, null, 2) + "\n";
|
|
359
|
+
if (Buffer.byteLength(content, "utf8") > RUN_CONTEXT_INDEX_METADATA_MAX_BYTES) {
|
|
360
|
+
throw new Error("Run context index exceeds its bounded metadata limit.");
|
|
361
|
+
}
|
|
362
|
+
writeTextAtomic(path, content, { onBeforeReplace() {
|
|
363
|
+
let current: BigIntStats | undefined;
|
|
364
|
+
try { current = lstatSync(path, { bigint: true }); }
|
|
365
|
+
catch (error) { if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error; }
|
|
366
|
+
if (!ownerUnchanged(owner) || !exportsUnchanged(owner.root, admitted) ||
|
|
367
|
+
(priorStamp ? !current || !sameFile(priorStamp, current) : current !== undefined)) {
|
|
368
|
+
throw new Error("Run context index observation changed before publication.");
|
|
369
|
+
}
|
|
370
|
+
} });
|
|
371
|
+
return Object.freeze({ index, local_path: path });
|
|
372
|
+
}
|
|
@@ -87,11 +87,21 @@ function sendToFifo(endpoint: RunControlEndpoint, payload: string): number {
|
|
|
87
87
|
throw new Error(`Run Control endpoint is not a FIFO: ${endpoint.path}`);
|
|
88
88
|
}
|
|
89
89
|
let fd: number | undefined;
|
|
90
|
+
let writeFailed = false, writeFailure: unknown;
|
|
90
91
|
try {
|
|
91
92
|
fd = openSync(endpoint.path, constants.O_WRONLY | constants.O_NONBLOCK);
|
|
92
93
|
return writeSync(fd, payload);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
writeFailed = true; writeFailure = error;
|
|
96
|
+
throw error;
|
|
93
97
|
} finally {
|
|
94
|
-
if (fd !== undefined)
|
|
98
|
+
if (fd !== undefined) {
|
|
99
|
+
try { closeSync(fd); }
|
|
100
|
+
catch (error) {
|
|
101
|
+
if (writeFailed) throw new AggregateError([writeFailure, error], "Run Control FIFO write and close failed", { cause: writeFailure });
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
95
105
|
}
|
|
96
106
|
}
|
|
97
107
|
|
|
@@ -122,6 +132,10 @@ function sendToNamedPipe(
|
|
|
122
132
|
});
|
|
123
133
|
}
|
|
124
134
|
|
|
135
|
+
function aggregateControlFailure(failure: Error, causes: readonly unknown[], recording: unknown): AggregateError {
|
|
136
|
+
return Object.assign(new AggregateError([...causes, recording], failure.message, { cause: causes[0] }), failure);
|
|
137
|
+
}
|
|
138
|
+
|
|
125
139
|
export async function deliverRunControl(
|
|
126
140
|
run: string,
|
|
127
141
|
stateDir: string,
|
|
@@ -145,20 +159,20 @@ export async function deliverRunControl(
|
|
|
145
159
|
const control = appendRunControlInStateDir(stateDir, normalizedRequest);
|
|
146
160
|
const endpoint = readRunControlEndpoint(stateDir, request.run_instance_id);
|
|
147
161
|
if (!endpoint) {
|
|
148
|
-
|
|
149
|
-
stateDir,
|
|
150
|
-
control.id,
|
|
151
|
-
"failed",
|
|
152
|
-
{ error: "control endpoint is not ready for this Run generation" },
|
|
153
|
-
["queued", "delivered"],
|
|
154
|
-
);
|
|
155
|
-
throw Object.assign(new Error("Run Control endpoint is not ready."), {
|
|
162
|
+
const failure = Object.assign(new Error("Run Control endpoint is not ready."), {
|
|
156
163
|
action,
|
|
157
164
|
control_id: control.id,
|
|
158
165
|
reason: "endpoint_not_ready",
|
|
159
166
|
run,
|
|
160
167
|
run_instance_id: request.run_instance_id,
|
|
161
168
|
});
|
|
169
|
+
try {
|
|
170
|
+
updateRunControlStatusInStateDir(stateDir, control.id, "failed",
|
|
171
|
+
{ error: "control endpoint is not ready for this Run generation" }, ["queued", "delivered"]);
|
|
172
|
+
} catch (recordingError) {
|
|
173
|
+
throw aggregateControlFailure(failure, [failure], recordingError);
|
|
174
|
+
}
|
|
175
|
+
throw failure;
|
|
162
176
|
}
|
|
163
177
|
try {
|
|
164
178
|
const { bytes, payload } = encodeRunControlWire({
|
|
@@ -189,15 +203,13 @@ export async function deliverRunControl(
|
|
|
189
203
|
run_instance_id: request.run_instance_id,
|
|
190
204
|
};
|
|
191
205
|
} catch (error) {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
);
|
|
200
|
-
throw Object.assign(new Error(`Run Control delivery failed: ${reason}`), {
|
|
206
|
+
let reason: string;
|
|
207
|
+
const causes: unknown[] = [error];
|
|
208
|
+
try { reason = String(error instanceof Error ? error.message : error); }
|
|
209
|
+
catch (formattingError) { reason = "failure text unavailable"; causes.push(formattingError); }
|
|
210
|
+
const message = `Run Control delivery failed: ${reason}`;
|
|
211
|
+
const failure = Object.assign(causes.length === 1 ? new Error(message, { cause: error })
|
|
212
|
+
: new AggregateError(causes, message, { cause: error }), {
|
|
201
213
|
action,
|
|
202
214
|
control_id: control.id,
|
|
203
215
|
endpoint_type: endpoint.type,
|
|
@@ -205,5 +217,11 @@ export async function deliverRunControl(
|
|
|
205
217
|
run,
|
|
206
218
|
run_instance_id: request.run_instance_id,
|
|
207
219
|
});
|
|
220
|
+
try {
|
|
221
|
+
updateRunControlStatusInStateDir(stateDir, control.id, "failed", { error: reason }, ["queued", "delivered"]);
|
|
222
|
+
} catch (recordingError) {
|
|
223
|
+
throw aggregateControlFailure(failure, causes, recordingError);
|
|
224
|
+
}
|
|
225
|
+
throw failure;
|
|
208
226
|
}
|
|
209
227
|
}
|