@descryy/mcp 0.11.3 → 0.11.5
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/package.json +20 -20
- package/dist/action-handshake.d.ts +0 -38
- package/dist/action-handshake.d.ts.map +0 -1
- package/dist/action-handshake.js +0 -127
- package/dist/action-handshake.js.map +0 -1
- package/dist/bin/descry-mcp.d.ts +0 -7
- package/dist/bin/descry-mcp.d.ts.map +0 -1
- package/dist/bin/descry-mcp.js +0 -72
- package/dist/bin/descry-mcp.js.map +0 -1
- package/dist/browser/auth.d.ts +0 -84
- package/dist/browser/auth.d.ts.map +0 -1
- package/dist/browser/auth.js +0 -233
- package/dist/browser/auth.js.map +0 -1
- package/dist/browser/capability-probe.d.ts +0 -109
- package/dist/browser/capability-probe.d.ts.map +0 -1
- package/dist/browser/capability-probe.js +0 -201
- package/dist/browser/capability-probe.js.map +0 -1
- package/dist/browser/driver.d.ts +0 -570
- package/dist/browser/driver.d.ts.map +0 -1
- package/dist/browser/driver.js +0 -116
- package/dist/browser/driver.js.map +0 -1
- package/dist/browser/evidence.d.ts +0 -28
- package/dist/browser/evidence.d.ts.map +0 -1
- package/dist/browser/evidence.js +0 -82
- package/dist/browser/evidence.js.map +0 -1
- package/dist/browser/fake-driver.d.ts +0 -116
- package/dist/browser/fake-driver.d.ts.map +0 -1
- package/dist/browser/fake-driver.js +0 -416
- package/dist/browser/fake-driver.js.map +0 -1
- package/dist/browser/fault-attribution.d.ts +0 -178
- package/dist/browser/fault-attribution.d.ts.map +0 -1
- package/dist/browser/fault-attribution.js +0 -266
- package/dist/browser/fault-attribution.js.map +0 -1
- package/dist/browser/graph-write.d.ts +0 -45
- package/dist/browser/graph-write.d.ts.map +0 -1
- package/dist/browser/graph-write.js +0 -103
- package/dist/browser/graph-write.js.map +0 -1
- package/dist/browser/identity-graph-write.d.ts +0 -55
- package/dist/browser/identity-graph-write.d.ts.map +0 -1
- package/dist/browser/identity-graph-write.js +0 -45
- package/dist/browser/identity-graph-write.js.map +0 -1
- package/dist/browser/page-probe.d.ts +0 -81
- package/dist/browser/page-probe.d.ts.map +0 -1
- package/dist/browser/page-probe.js +0 -202
- package/dist/browser/page-probe.js.map +0 -1
- package/dist/browser/playwright-driver.d.ts +0 -114
- package/dist/browser/playwright-driver.d.ts.map +0 -1
- package/dist/browser/playwright-driver.js +0 -1479
- package/dist/browser/playwright-driver.js.map +0 -1
- package/dist/browser/provider.d.ts +0 -26
- package/dist/browser/provider.d.ts.map +0 -1
- package/dist/browser/provider.js +0 -14
- package/dist/browser/provider.js.map +0 -1
- package/dist/browser/reach-recording-session.d.ts +0 -44
- package/dist/browser/reach-recording-session.d.ts.map +0 -1
- package/dist/browser/reach-recording-session.js +0 -143
- package/dist/browser/reach-recording-session.js.map +0 -1
- package/dist/browser/reachability.d.ts +0 -168
- package/dist/browser/reachability.d.ts.map +0 -1
- package/dist/browser/reachability.js +0 -294
- package/dist/browser/reachability.js.map +0 -1
- package/dist/browser/registry.d.ts +0 -126
- package/dist/browser/registry.d.ts.map +0 -1
- package/dist/browser/registry.js +0 -177
- package/dist/browser/registry.js.map +0 -1
- package/dist/browser/scenario-provenance.d.ts +0 -23
- package/dist/browser/scenario-provenance.d.ts.map +0 -1
- package/dist/browser/scenario-provenance.js +0 -73
- package/dist/browser/scenario-provenance.js.map +0 -1
- package/dist/browser/scenario-resolve.d.ts +0 -28
- package/dist/browser/scenario-resolve.d.ts.map +0 -1
- package/dist/browser/scenario-resolve.js +0 -96
- package/dist/browser/scenario-resolve.js.map +0 -1
- package/dist/browser/scenario-runner.d.ts +0 -72
- package/dist/browser/scenario-runner.d.ts.map +0 -1
- package/dist/browser/scenario-runner.js +0 -353
- package/dist/browser/scenario-runner.js.map +0 -1
- package/dist/browser/stack-parser.d.ts +0 -19
- package/dist/browser/stack-parser.d.ts.map +0 -1
- package/dist/browser/stack-parser.js +0 -85
- package/dist/browser/stack-parser.js.map +0 -1
- package/dist/browser/tool-support.d.ts +0 -71
- package/dist/browser/tool-support.d.ts.map +0 -1
- package/dist/browser/tool-support.js +0 -216
- package/dist/browser/tool-support.js.map +0 -1
- package/dist/browser/url-scheme.d.ts +0 -14
- package/dist/browser/url-scheme.d.ts.map +0 -1
- package/dist/browser/url-scheme.js +0 -38
- package/dist/browser/url-scheme.js.map +0 -1
- package/dist/browser/wait-target.d.ts +0 -37
- package/dist/browser/wait-target.d.ts.map +0 -1
- package/dist/browser/wait-target.js +0 -54
- package/dist/browser/wait-target.js.map +0 -1
- package/dist/cancellation.d.ts +0 -20
- package/dist/cancellation.d.ts.map +0 -1
- package/dist/cancellation.js +0 -41
- package/dist/cancellation.js.map +0 -1
- package/dist/capped.d.ts +0 -17
- package/dist/capped.d.ts.map +0 -1
- package/dist/capped.js +0 -15
- package/dist/capped.js.map +0 -1
- package/dist/credential-store.d.ts +0 -22
- package/dist/credential-store.d.ts.map +0 -1
- package/dist/credential-store.js +0 -33
- package/dist/credential-store.js.map +0 -1
- package/dist/disclosure-ledger.d.ts +0 -14
- package/dist/disclosure-ledger.d.ts.map +0 -1
- package/dist/disclosure-ledger.js +0 -18
- package/dist/disclosure-ledger.js.map +0 -1
- package/dist/evidence/observed-route-evidence.d.ts +0 -25
- package/dist/evidence/observed-route-evidence.d.ts.map +0 -1
- package/dist/evidence/observed-route-evidence.js +0 -76
- package/dist/evidence/observed-route-evidence.js.map +0 -1
- package/dist/heap.d.ts +0 -61
- package/dist/heap.d.ts.map +0 -1
- package/dist/heap.js +0 -82
- package/dist/heap.js.map +0 -1
- package/dist/heartbeat.d.ts +0 -46
- package/dist/heartbeat.d.ts.map +0 -1
- package/dist/heartbeat.js +0 -66
- package/dist/heartbeat.js.map +0 -1
- package/dist/index.d.ts +0 -32
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -19
- package/dist/index.js.map +0 -1
- package/dist/module-trust.d.ts +0 -37
- package/dist/module-trust.d.ts.map +0 -1
- package/dist/module-trust.js +0 -77
- package/dist/module-trust.js.map +0 -1
- package/dist/path-confinement.d.ts +0 -31
- package/dist/path-confinement.d.ts.map +0 -1
- package/dist/path-confinement.js +0 -44
- package/dist/path-confinement.js.map +0 -1
- package/dist/planner/predict-then-propose.d.ts +0 -134
- package/dist/planner/predict-then-propose.d.ts.map +0 -1
- package/dist/planner/predict-then-propose.js +0 -138
- package/dist/planner/predict-then-propose.js.map +0 -1
- package/dist/planner/propose-journey.d.ts +0 -75
- package/dist/planner/propose-journey.d.ts.map +0 -1
- package/dist/planner/propose-journey.js +0 -96
- package/dist/planner/propose-journey.js.map +0 -1
- package/dist/protocol.d.ts +0 -57
- package/dist/protocol.d.ts.map +0 -1
- package/dist/protocol.js +0 -90
- package/dist/protocol.js.map +0 -1
- package/dist/registry.d.ts +0 -103
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js +0 -319
- package/dist/registry.js.map +0 -1
- package/dist/render.d.ts +0 -580
- package/dist/render.d.ts.map +0 -1
- package/dist/render.js +0 -867
- package/dist/render.js.map +0 -1
- package/dist/runtime-registry.d.ts +0 -22
- package/dist/runtime-registry.d.ts.map +0 -1
- package/dist/runtime-registry.js +0 -142
- package/dist/runtime-registry.js.map +0 -1
- package/dist/sandbox-defaults.d.ts +0 -41
- package/dist/sandbox-defaults.d.ts.map +0 -1
- package/dist/sandbox-defaults.js +0 -14
- package/dist/sandbox-defaults.js.map +0 -1
- package/dist/scenarios/browser-run-plan-projection.d.ts +0 -161
- package/dist/scenarios/browser-run-plan-projection.d.ts.map +0 -1
- package/dist/scenarios/browser-run-plan-projection.js +0 -264
- package/dist/scenarios/browser-run-plan-projection.js.map +0 -1
- package/dist/scenarios/credential-ref.d.ts +0 -102
- package/dist/scenarios/credential-ref.d.ts.map +0 -1
- package/dist/scenarios/credential-ref.js +0 -148
- package/dist/scenarios/credential-ref.js.map +0 -1
- package/dist/scenarios/index.d.ts +0 -7
- package/dist/scenarios/index.d.ts.map +0 -1
- package/dist/scenarios/index.js +0 -7
- package/dist/scenarios/index.js.map +0 -1
- package/dist/scenarios/parse.d.ts +0 -18
- package/dist/scenarios/parse.d.ts.map +0 -1
- package/dist/scenarios/parse.js +0 -212
- package/dist/scenarios/parse.js.map +0 -1
- package/dist/scenarios/scenario.d.ts +0 -93
- package/dist/scenarios/scenario.d.ts.map +0 -1
- package/dist/scenarios/scenario.js +0 -27
- package/dist/scenarios/scenario.js.map +0 -1
- package/dist/scenarios/secret-ref.d.ts +0 -86
- package/dist/scenarios/secret-ref.d.ts.map +0 -1
- package/dist/scenarios/secret-ref.js +0 -125
- package/dist/scenarios/secret-ref.js.map +0 -1
- package/dist/scenarios/storage.d.ts +0 -21
- package/dist/scenarios/storage.d.ts.map +0 -1
- package/dist/scenarios/storage.js +0 -103
- package/dist/scenarios/storage.js.map +0 -1
- package/dist/server.d.ts +0 -61
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -541
- package/dist/server.js.map +0 -1
- package/dist/session.d.ts +0 -243
- package/dist/session.d.ts.map +0 -1
- package/dist/session.js +0 -602
- package/dist/session.js.map +0 -1
- package/dist/tools/alias-kit.d.ts +0 -29
- package/dist/tools/alias-kit.d.ts.map +0 -1
- package/dist/tools/alias-kit.js +0 -21
- package/dist/tools/alias-kit.js.map +0 -1
- package/dist/tools/aliases.d.ts +0 -42
- package/dist/tools/aliases.d.ts.map +0 -1
- package/dist/tools/aliases.js +0 -52
- package/dist/tools/aliases.js.map +0 -1
- package/dist/tools/analyze-workspace.d.ts +0 -52
- package/dist/tools/analyze-workspace.d.ts.map +0 -1
- package/dist/tools/analyze-workspace.js +0 -207
- package/dist/tools/analyze-workspace.js.map +0 -1
- package/dist/tools/analyze.d.ts +0 -163
- package/dist/tools/analyze.d.ts.map +0 -1
- package/dist/tools/analyze.js +0 -724
- package/dist/tools/analyze.js.map +0 -1
- package/dist/tools/browser-click.d.ts +0 -18
- package/dist/tools/browser-click.d.ts.map +0 -1
- package/dist/tools/browser-click.js +0 -110
- package/dist/tools/browser-click.js.map +0 -1
- package/dist/tools/browser-close-session.d.ts +0 -39
- package/dist/tools/browser-close-session.d.ts.map +0 -1
- package/dist/tools/browser-close-session.js +0 -120
- package/dist/tools/browser-close-session.js.map +0 -1
- package/dist/tools/browser-fill.d.ts +0 -18
- package/dist/tools/browser-fill.d.ts.map +0 -1
- package/dist/tools/browser-fill.js +0 -117
- package/dist/tools/browser-fill.js.map +0 -1
- package/dist/tools/browser-navigate.d.ts +0 -15
- package/dist/tools/browser-navigate.d.ts.map +0 -1
- package/dist/tools/browser-navigate.js +0 -104
- package/dist/tools/browser-navigate.js.map +0 -1
- package/dist/tools/browser-read.d.ts +0 -33
- package/dist/tools/browser-read.d.ts.map +0 -1
- package/dist/tools/browser-read.js +0 -113
- package/dist/tools/browser-read.js.map +0 -1
- package/dist/tools/browser-run-scenario.d.ts +0 -28
- package/dist/tools/browser-run-scenario.d.ts.map +0 -1
- package/dist/tools/browser-run-scenario.js +0 -206
- package/dist/tools/browser-run-scenario.js.map +0 -1
- package/dist/tools/browser-save-scenario.d.ts +0 -19
- package/dist/tools/browser-save-scenario.d.ts.map +0 -1
- package/dist/tools/browser-save-scenario.js +0 -447
- package/dist/tools/browser-save-scenario.js.map +0 -1
- package/dist/tools/browser-select.d.ts +0 -20
- package/dist/tools/browser-select.d.ts.map +0 -1
- package/dist/tools/browser-select.js +0 -120
- package/dist/tools/browser-select.js.map +0 -1
- package/dist/tools/browser-snapshot.d.ts +0 -46
- package/dist/tools/browser-snapshot.d.ts.map +0 -1
- package/dist/tools/browser-snapshot.js +0 -127
- package/dist/tools/browser-snapshot.js.map +0 -1
- package/dist/tools/browser-start-session.d.ts +0 -24
- package/dist/tools/browser-start-session.d.ts.map +0 -1
- package/dist/tools/browser-start-session.js +0 -622
- package/dist/tools/browser-start-session.js.map +0 -1
- package/dist/tools/browser-submit.d.ts +0 -18
- package/dist/tools/browser-submit.d.ts.map +0 -1
- package/dist/tools/browser-submit.js +0 -106
- package/dist/tools/browser-submit.js.map +0 -1
- package/dist/tools/browser-type.d.ts +0 -18
- package/dist/tools/browser-type.d.ts.map +0 -1
- package/dist/tools/browser-type.js +0 -115
- package/dist/tools/browser-type.js.map +0 -1
- package/dist/tools/browser-wait-for.d.ts +0 -45
- package/dist/tools/browser-wait-for.d.ts.map +0 -1
- package/dist/tools/browser-wait-for.js +0 -150
- package/dist/tools/browser-wait-for.js.map +0 -1
- package/dist/tools/browser.d.ts +0 -69
- package/dist/tools/browser.d.ts.map +0 -1
- package/dist/tools/browser.js +0 -386
- package/dist/tools/browser.js.map +0 -1
- package/dist/tools/chain.d.ts +0 -41
- package/dist/tools/chain.d.ts.map +0 -1
- package/dist/tools/chain.js +0 -105
- package/dist/tools/chain.js.map +0 -1
- package/dist/tools/change-scope.d.ts +0 -25
- package/dist/tools/change-scope.d.ts.map +0 -1
- package/dist/tools/change-scope.js +0 -110
- package/dist/tools/change-scope.js.map +0 -1
- package/dist/tools/code-context.d.ts +0 -83
- package/dist/tools/code-context.d.ts.map +0 -1
- package/dist/tools/code-context.js +0 -416
- package/dist/tools/code-context.js.map +0 -1
- package/dist/tools/contracts.d.ts +0 -74
- package/dist/tools/contracts.d.ts.map +0 -1
- package/dist/tools/contracts.js +0 -196
- package/dist/tools/contracts.js.map +0 -1
- package/dist/tools/cross-pr.d.ts +0 -178
- package/dist/tools/cross-pr.d.ts.map +0 -1
- package/dist/tools/cross-pr.js +0 -321
- package/dist/tools/cross-pr.js.map +0 -1
- package/dist/tools/disclosure.d.ts +0 -75
- package/dist/tools/disclosure.d.ts.map +0 -1
- package/dist/tools/disclosure.js +0 -288
- package/dist/tools/disclosure.js.map +0 -1
- package/dist/tools/draw-conclusion.d.ts +0 -55
- package/dist/tools/draw-conclusion.d.ts.map +0 -1
- package/dist/tools/draw-conclusion.js +0 -259
- package/dist/tools/draw-conclusion.js.map +0 -1
- package/dist/tools/git-context.d.ts +0 -39
- package/dist/tools/git-context.d.ts.map +0 -1
- package/dist/tools/git-context.js +0 -364
- package/dist/tools/git-context.js.map +0 -1
- package/dist/tools/git-diff.d.ts +0 -45
- package/dist/tools/git-diff.d.ts.map +0 -1
- package/dist/tools/git-diff.js +0 -338
- package/dist/tools/git-diff.js.map +0 -1
- package/dist/tools/git-history.d.ts +0 -16
- package/dist/tools/git-history.d.ts.map +0 -1
- package/dist/tools/git-history.js +0 -86
- package/dist/tools/git-history.js.map +0 -1
- package/dist/tools/history.d.ts +0 -34
- package/dist/tools/history.d.ts.map +0 -1
- package/dist/tools/history.js +0 -121
- package/dist/tools/history.js.map +0 -1
- package/dist/tools/impact.d.ts +0 -46
- package/dist/tools/impact.d.ts.map +0 -1
- package/dist/tools/impact.js +0 -225
- package/dist/tools/impact.js.map +0 -1
- package/dist/tools/index.d.ts +0 -59
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js +0 -70
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/kit.d.ts +0 -165
- package/dist/tools/kit.d.ts.map +0 -1
- package/dist/tools/kit.js +0 -153
- package/dist/tools/kit.js.map +0 -1
- package/dist/tools/link-workspace.d.ts +0 -24
- package/dist/tools/link-workspace.d.ts.map +0 -1
- package/dist/tools/link-workspace.js +0 -131
- package/dist/tools/link-workspace.js.map +0 -1
- package/dist/tools/lookup.d.ts +0 -19
- package/dist/tools/lookup.d.ts.map +0 -1
- package/dist/tools/lookup.js +0 -63
- package/dist/tools/lookup.js.map +0 -1
- package/dist/tools/mark-incident.d.ts +0 -28
- package/dist/tools/mark-incident.d.ts.map +0 -1
- package/dist/tools/mark-incident.js +0 -188
- package/dist/tools/mark-incident.js.map +0 -1
- package/dist/tools/merged-browser.d.ts +0 -11
- package/dist/tools/merged-browser.d.ts.map +0 -1
- package/dist/tools/merged-browser.js +0 -20
- package/dist/tools/merged-browser.js.map +0 -1
- package/dist/tools/merged-context.d.ts +0 -11
- package/dist/tools/merged-context.d.ts.map +0 -1
- package/dist/tools/merged-context.js +0 -21
- package/dist/tools/merged-context.js.map +0 -1
- package/dist/tools/merged-observe.d.ts +0 -13
- package/dist/tools/merged-observe.d.ts.map +0 -1
- package/dist/tools/merged-observe.js +0 -21
- package/dist/tools/merged-observe.js.map +0 -1
- package/dist/tools/merged-workspace.d.ts +0 -14
- package/dist/tools/merged-workspace.d.ts.map +0 -1
- package/dist/tools/merged-workspace.js +0 -21
- package/dist/tools/merged-workspace.js.map +0 -1
- package/dist/tools/observe-runtime.d.ts +0 -250
- package/dist/tools/observe-runtime.d.ts.map +0 -1
- package/dist/tools/observe-runtime.js +0 -1753
- package/dist/tools/observe-runtime.js.map +0 -1
- package/dist/tools/observe-tests.d.ts +0 -57
- package/dist/tools/observe-tests.d.ts.map +0 -1
- package/dist/tools/observe-tests.js +0 -368
- package/dist/tools/observe-tests.js.map +0 -1
- package/dist/tools/observe.d.ts +0 -28
- package/dist/tools/observe.d.ts.map +0 -1
- package/dist/tools/observe.js +0 -330
- package/dist/tools/observe.js.map +0 -1
- package/dist/tools/pr-analysis.d.ts +0 -189
- package/dist/tools/pr-analysis.d.ts.map +0 -1
- package/dist/tools/pr-analysis.js +0 -299
- package/dist/tools/pr-analysis.js.map +0 -1
- package/dist/tools/pre-push.d.ts +0 -168
- package/dist/tools/pre-push.d.ts.map +0 -1
- package/dist/tools/pre-push.js +0 -416
- package/dist/tools/pre-push.js.map +0 -1
- package/dist/tools/predict-reach.d.ts +0 -57
- package/dist/tools/predict-reach.d.ts.map +0 -1
- package/dist/tools/predict-reach.js +0 -159
- package/dist/tools/predict-reach.js.map +0 -1
- package/dist/tools/propagation.d.ts +0 -37
- package/dist/tools/propagation.d.ts.map +0 -1
- package/dist/tools/propagation.js +0 -162
- package/dist/tools/propagation.js.map +0 -1
- package/dist/tools/propose-journey.d.ts +0 -16
- package/dist/tools/propose-journey.d.ts.map +0 -1
- package/dist/tools/propose-journey.js +0 -121
- package/dist/tools/propose-journey.js.map +0 -1
- package/dist/tools/prove-reach.d.ts +0 -74
- package/dist/tools/prove-reach.d.ts.map +0 -1
- package/dist/tools/prove-reach.js +0 -286
- package/dist/tools/prove-reach.js.map +0 -1
- package/dist/tools/questions.d.ts +0 -30
- package/dist/tools/questions.d.ts.map +0 -1
- package/dist/tools/questions.js +0 -232
- package/dist/tools/questions.js.map +0 -1
- package/dist/tools/refusal-fetch.d.ts +0 -35
- package/dist/tools/refusal-fetch.d.ts.map +0 -1
- package/dist/tools/refusal-fetch.js +0 -103
- package/dist/tools/refusal-fetch.js.map +0 -1
- package/dist/tools/runtime-incident.d.ts +0 -33
- package/dist/tools/runtime-incident.d.ts.map +0 -1
- package/dist/tools/runtime-incident.js +0 -67
- package/dist/tools/runtime-incident.js.map +0 -1
- package/dist/tools/runtime-journey-drive.d.ts +0 -102
- package/dist/tools/runtime-journey-drive.d.ts.map +0 -1
- package/dist/tools/runtime-journey-drive.js +0 -247
- package/dist/tools/runtime-journey-drive.js.map +0 -1
- package/dist/tools/scope.d.ts +0 -45
- package/dist/tools/scope.d.ts.map +0 -1
- package/dist/tools/scope.js +0 -186
- package/dist/tools/scope.js.map +0 -1
- package/dist/tools/similar-incidents.d.ts +0 -43
- package/dist/tools/similar-incidents.d.ts.map +0 -1
- package/dist/tools/similar-incidents.js +0 -179
- package/dist/tools/similar-incidents.js.map +0 -1
- package/dist/tools/validate.d.ts +0 -133
- package/dist/tools/validate.d.ts.map +0 -1
- package/dist/tools/validate.js +0 -442
- package/dist/tools/validate.js.map +0 -1
- package/dist/tools/verb.d.ts +0 -46
- package/dist/tools/verb.d.ts.map +0 -1
- package/dist/tools/verb.js +0 -78
- package/dist/tools/verb.js.map +0 -1
- package/dist/tools/verification-status.d.ts +0 -38
- package/dist/tools/verification-status.d.ts.map +0 -1
- package/dist/tools/verification-status.js +0 -203
- package/dist/tools/verification-status.js.map +0 -1
- package/dist/tools/verify-claim.d.ts +0 -29
- package/dist/tools/verify-claim.d.ts.map +0 -1
- package/dist/tools/verify-claim.js +0 -220
- package/dist/tools/verify-claim.js.map +0 -1
- package/dist/tools/workspace.d.ts +0 -28
- package/dist/tools/workspace.d.ts.map +0 -1
- package/dist/tools/workspace.js +0 -101
- package/dist/tools/workspace.js.map +0 -1
- package/dist/transport.d.ts +0 -32
- package/dist/transport.d.ts.map +0 -1
- package/dist/transport.js +0 -85
- package/dist/transport.js.map +0 -1
- package/dist/workspace-index.d.ts +0 -164
- package/dist/workspace-index.d.ts.map +0 -1
- package/dist/workspace-index.js +0 -381
- package/dist/workspace-index.js.map +0 -1
package/dist/render.js
DELETED
|
@@ -1,867 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The one way an engine answer becomes an MCP tool result.
|
|
3
|
-
*
|
|
4
|
-
* ## Why this file exists rather than each tool formatting its own reply
|
|
5
|
-
*
|
|
6
|
-
* `QueryResult` carries three things a caller would rather not think about: a
|
|
7
|
-
* staleness stamp (§27.3), a `truncated` flag, and `notes` — the plain-words
|
|
8
|
-
* disclosures that populate the five result states' `refused`/`empty`/`failed`/
|
|
9
|
-
* `timed_out` cases. The engine computes all three correctly today. Every one of
|
|
10
|
-
* them is one careless `return result.data` away from never reaching a user.
|
|
11
|
-
*
|
|
12
|
-
* So the tool handler's return type is `QueryResult`, not content. A handler
|
|
13
|
-
* *cannot* build a reply; it can only produce an answer, and this module is the
|
|
14
|
-
* only thing that turns an answer into frames. Rule 7 — honest degradation, no
|
|
15
|
-
* silent doing-less — becomes a property of the type system rather than of
|
|
16
|
-
* whoever writes the next tool.
|
|
17
|
-
*
|
|
18
|
-
* ## `ai-tool-contract.md` §2 — the frozen envelope
|
|
19
|
-
*
|
|
20
|
-
* This module used to ship a two-value `status: "ok" | "not_analysable"`. The
|
|
21
|
-
* contract froze five: `ok` / `empty` / `refused` / `failed` / `timed_out`
|
|
22
|
-
* (§1), plus `class`, `toolVersion`, `budget` and a structured `truncated`
|
|
23
|
-
* object (§2). `AnswerStatus`/`renderAnswer`'s old two-state shape is gone
|
|
24
|
-
* rather than kept alongside the new one — two envelope shapes on the wire is
|
|
25
|
-
* the thing DEC-277's "one process mints" reasoning exists to avoid one layer
|
|
26
|
-
* up, applied here to a type rather than a decision number.
|
|
27
|
-
*
|
|
28
|
-
* ## Four invariants, asserted rather than documented (§2.1)
|
|
29
|
-
*
|
|
30
|
-
* `render.ts` already enforced the first two; the other two are new.
|
|
31
|
-
*
|
|
32
|
-
* 1. `truncated != null` with empty `disclosures` → throw.
|
|
33
|
-
* 2. `state` in `{refused, failed, timed_out}` with empty `disclosures` → throw.
|
|
34
|
-
* 3. `state == "refused"` with no verbatim reason in `disclosures` → throw (§4).
|
|
35
|
-
* 4. `class == "action"` returning anything other than a handshake envelope on
|
|
36
|
-
* the first call → throw (§7) — enforced in `action-handshake.ts` and
|
|
37
|
-
* `server.ts`, not here: this module never sees a mint, only a redeemed run.
|
|
38
|
-
*
|
|
39
|
-
* ## A fifth invariant, B6: a truncated answer must carry real counts
|
|
40
|
-
*
|
|
41
|
-
* `result.truncated === true` with no `answer.truncatedDetail` used to fall
|
|
42
|
-
* back to a sentinel, `{shown: -1, total: -1}` — chosen to be "unmistakably
|
|
43
|
-
* fake," except that it is a number, so it passes any presence check and then
|
|
44
|
-
* poisons whatever arithmetic reads `total - shown`. A field that lies is
|
|
45
|
-
* worse than a field that is absent, which is the same argument the five
|
|
46
|
-
* result states rest on. So the sentinel is gone: a tool that sets
|
|
47
|
-
* `result.truncated` without a `truncatedDetail` is a programming error,
|
|
48
|
-
* thrown in every environment except production, where the envelope instead
|
|
49
|
-
* reports `truncated: null` plus a disclosure naming the gap — degraded
|
|
50
|
-
* honestly rather than dishonestly precise. See `capped()` in `./capped.ts`
|
|
51
|
-
* for how a tool is meant to avoid ever hitting this.
|
|
52
|
-
*/
|
|
53
|
-
import { randomUUID } from "node:crypto";
|
|
54
|
-
import { aliasDisclosure } from "./tools/aliases.js";
|
|
55
|
-
import { RELIABILITY_CLASSES, REPORT_CATEGORIES, RESULT_STATES, TOOL_CLASSES, existenceCategory as deriveExistenceCategory, reliabilityCap, reliabilityDisclosure, reportCategory as deriveReportCategory, } from "@descryy/ir";
|
|
56
|
-
/**
|
|
57
|
-
* MK-5 — which of the sixteen tools states a conclusion about the user's code
|
|
58
|
-
* versus which reports a fact about the graph.
|
|
59
|
-
*
|
|
60
|
-
* Lives here rather than in `@descryy/ir`: `tool-surface.ts`'s own header
|
|
61
|
-
* scopes that file to exactly `ResultState` and `ToolClass` ("and nothing
|
|
62
|
-
* else"), because those two cross into the pipeline and the desktop surface.
|
|
63
|
-
* This distinction is agent-mode-only (`plugin-and-mcp-surface.md` §3 PL-1),
|
|
64
|
-
* so a third shared union there would be scope creep the file's own doc
|
|
65
|
-
* disclaims. `kit.ts` imports it from here rather than the reverse, because
|
|
66
|
-
* `kit.ts` already depends on this module for `ToolAnswer`/`TruncationDetail`
|
|
67
|
-
* — defining it in `kit.ts` instead would make this module import back from
|
|
68
|
-
* `kit.ts` and cycle.
|
|
69
|
-
*
|
|
70
|
-
* - `conclusion` — the output is a statement about the user's code
|
|
71
|
-
* (`validate`, `contracts`, `cross_pr`). Never raw candidates: an
|
|
72
|
-
* already-adjudicated result carrying the category and the disclosure
|
|
73
|
-
* sentence as one payload.
|
|
74
|
-
* - `evidence` — the output is a fact the graph computed, already carrying
|
|
75
|
-
* its own resolution and qualification. The other thirteen.
|
|
76
|
-
*/
|
|
77
|
-
export const TOOL_TIERS = ["conclusion", "evidence"];
|
|
78
|
-
const PROVENANCE = {
|
|
79
|
-
surface: "mcp",
|
|
80
|
-
adjudicatedBy: "descry",
|
|
81
|
-
presentedBy: "host-agent",
|
|
82
|
-
governancePipeline: false,
|
|
83
|
-
};
|
|
84
|
-
/**
|
|
85
|
-
* The ceiling on one rendered tool result, serialized — `content` frame and
|
|
86
|
-
* `structuredContent` envelope together, which is what a host actually
|
|
87
|
-
* receives and counts.
|
|
88
|
-
*
|
|
89
|
-
* A starting value, not a measurement, in this repo's usual sense: the one
|
|
90
|
-
* hard number behind it is a real failure, `get_git_diff` on an ordinary
|
|
91
|
-
* 48-file branch diff returning 84,516 characters and being rejected outright
|
|
92
|
-
* by the host before the caller saw any of it. 60,000 sits well under the
|
|
93
|
-
* smallest size observed to fail, with room for the narrated frame that
|
|
94
|
-
* repeats the disclosures alongside the envelope.
|
|
95
|
-
*
|
|
96
|
-
* Shared rather than per-tool on purpose: `get_git_diff` is the tool that hit
|
|
97
|
-
* this, twice, but nothing about the failure was specific to diffs. Any tool
|
|
98
|
-
* adopts the ceiling by implementing `ToolAnswer.fitToBudget`.
|
|
99
|
-
*/
|
|
100
|
-
export const MAX_REPLY_BYTES = 60_000;
|
|
101
|
-
// ---------------------------------------------------------------------------
|
|
102
|
-
// The wire schema for everything above
|
|
103
|
-
// ---------------------------------------------------------------------------
|
|
104
|
-
/** `T | null`, in the JSON Schema this server's declared subset uses. */
|
|
105
|
-
function nullable(schema) {
|
|
106
|
-
return { anyOf: [schema, { type: "null" }] };
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* The envelope, declared for a host to validate against — MCP's `outputSchema`.
|
|
110
|
-
*
|
|
111
|
-
* ## Why this exists at all
|
|
112
|
-
*
|
|
113
|
-
* Every reply from this server carries `structuredContent`, and until this was
|
|
114
|
-
* added a host had no way to check what it received. `tools/list` already ships
|
|
115
|
-
* `class`, `tier` and `toolVersion` on the same reasoning — a fact about the
|
|
116
|
-
* reply that an external client cannot otherwise read — and this is the
|
|
117
|
-
* standard-shaped member of that group rather than a fourth non-standard field.
|
|
118
|
-
*
|
|
119
|
-
* ## `data` is deliberately open, and that is a disclosed gap
|
|
120
|
-
*
|
|
121
|
-
* The envelope's thirteen fields are uniform across all thirty-three tools, so they
|
|
122
|
-
* are described exactly. `data` is not: its shape is `ImpactData`, `ScopeData`
|
|
123
|
-
* and thirty-one others, and nothing today derives a JSON Schema from those
|
|
124
|
-
* TypeScript types. Hand-writing thirty-three schemas would put a second description
|
|
125
|
-
* of each shape in a second place with nothing checking the two agree — the
|
|
126
|
-
* drift this repo has already paid for once with the tool count in prose, and
|
|
127
|
-
* a schema that is confidently wrong about `data` is worse for a validating
|
|
128
|
-
* host than one that declines to describe it.
|
|
129
|
-
*
|
|
130
|
-
* So `data` is `{}` — "anything" — and this paragraph is the disclosure rather
|
|
131
|
-
* than a silent omission (rule 7). Tightening it is real work with a real
|
|
132
|
-
* prerequisite: a generator from the handler types, or the schemas checked
|
|
133
|
-
* against recorded replies. Until then the promise made here is exactly the
|
|
134
|
-
* promise kept.
|
|
135
|
-
*
|
|
136
|
-
* ## The enums are read, not restated
|
|
137
|
-
*
|
|
138
|
-
* `state`, `class`, `reportCategory` and `reliabilityCap` build their `enum`
|
|
139
|
-
* from the exported vocabulary arrays. A restated list is a second source of
|
|
140
|
-
* truth that goes stale in silence; spread from the array, adding a report
|
|
141
|
-
* category and forgetting the schema is a red test instead.
|
|
142
|
-
*/
|
|
143
|
-
export const ANSWER_ENVELOPE_SCHEMA = {
|
|
144
|
-
type: "object",
|
|
145
|
-
title: "Descry answer envelope",
|
|
146
|
-
description: "The uniform reply shape for every Descry tool. `state` distinguishes " +
|
|
147
|
-
"'looked and found nothing' (empty) from 'could not look' (refused); read " +
|
|
148
|
-
"`disclosures` before summarising the answer.",
|
|
149
|
-
properties: {
|
|
150
|
-
tool: { type: "string", description: "The tool that produced this reply." },
|
|
151
|
-
toolVersion: {
|
|
152
|
-
type: "string",
|
|
153
|
-
description: "Bumped on any behaviour change; recorded with the run.",
|
|
154
|
-
},
|
|
155
|
-
callId: {
|
|
156
|
-
type: "string",
|
|
157
|
-
description: "This call's own id in this session's recorded tool calls. Cite it in verify_claim's " +
|
|
158
|
-
"\"callId\" to check a claim against this exact call's real result.",
|
|
159
|
-
},
|
|
160
|
-
state: {
|
|
161
|
-
type: "string",
|
|
162
|
-
enum: [...RESULT_STATES],
|
|
163
|
-
description: "ok = found something; empty = looked completely and found nothing (a " +
|
|
164
|
-
"fact about your code); refused = could not look (a fact about Descry, " +
|
|
165
|
-
"never about your code); failed = something broke; timed_out = ran out " +
|
|
166
|
-
"of budget, partial answer.",
|
|
167
|
-
},
|
|
168
|
-
class: {
|
|
169
|
-
type: "string",
|
|
170
|
-
enum: [...TOOL_CLASSES],
|
|
171
|
-
description: "Retry semantics: read, stateful-read, or action.",
|
|
172
|
-
},
|
|
173
|
-
headline: { type: "string", description: "One-sentence plain-English answer." },
|
|
174
|
-
data: {
|
|
175
|
-
description: "The tool's own payload, or null on refused/failed/timed_out. Shape is " +
|
|
176
|
-
"per-tool and is not described here — see this schema's own " +
|
|
177
|
-
"documentation for why, and the tool description for the fields.",
|
|
178
|
-
},
|
|
179
|
-
graph: {
|
|
180
|
-
type: "object",
|
|
181
|
-
description: "What the answer rests on.",
|
|
182
|
-
properties: {
|
|
183
|
-
commitSha: nullable({ type: "string" }),
|
|
184
|
-
builtAt: nullable({ type: "string" }),
|
|
185
|
-
irSchemaVersion: { type: "integer" },
|
|
186
|
-
resolutionFloor: {
|
|
187
|
-
...nullable({ type: "integer", minimum: 0, maximum: 4 }),
|
|
188
|
-
description: "R0 syntax only; R1 imports resolved; R2 references resolved; R3 " +
|
|
189
|
-
"type checker; R4 observed at runtime. Null when the graph was not " +
|
|
190
|
-
"consulted at all.",
|
|
191
|
-
},
|
|
192
|
-
reliabilityCap: {
|
|
193
|
-
type: "string",
|
|
194
|
-
enum: [...RELIABILITY_CLASSES],
|
|
195
|
-
description: "C = unconfirmed behavioural prediction, must not be relayed as " +
|
|
196
|
-
"fact; B = structural or reference evidence; A = as strong as this " +
|
|
197
|
-
"graph makes it.",
|
|
198
|
-
},
|
|
199
|
-
},
|
|
200
|
-
required: ["commitSha", "builtAt", "irSchemaVersion", "resolutionFloor", "reliabilityCap"],
|
|
201
|
-
},
|
|
202
|
-
truncated: nullable({
|
|
203
|
-
type: "object",
|
|
204
|
-
properties: {
|
|
205
|
-
shown: { type: "integer" },
|
|
206
|
-
total: { type: "integer", description: "The count before the cap." },
|
|
207
|
-
more: nullable({ type: "string" }),
|
|
208
|
-
},
|
|
209
|
-
required: ["shown", "total", "more"],
|
|
210
|
-
}),
|
|
211
|
-
refusals: nullable({
|
|
212
|
-
type: "object",
|
|
213
|
-
properties: {
|
|
214
|
-
count: { type: "integer" },
|
|
215
|
-
exemplar: { type: "string" },
|
|
216
|
-
handle: { type: "string", description: "Pass to refusal_fetch for the full list." },
|
|
217
|
-
},
|
|
218
|
-
required: ["count", "exemplar", "handle"],
|
|
219
|
-
}),
|
|
220
|
-
budget: {
|
|
221
|
-
type: "object",
|
|
222
|
-
properties: {
|
|
223
|
-
elapsedMs: { type: "integer" },
|
|
224
|
-
limitMs: { type: "integer" },
|
|
225
|
-
},
|
|
226
|
-
required: ["elapsedMs", "limitMs"],
|
|
227
|
-
},
|
|
228
|
-
disclosures: {
|
|
229
|
-
type: "array",
|
|
230
|
-
items: { type: "string" },
|
|
231
|
-
description: "What this answer does not cover. Never empty when the answer is " +
|
|
232
|
-
"degraded, truncated, refused, failed or timed out.",
|
|
233
|
-
},
|
|
234
|
-
configStale: {
|
|
235
|
-
type: "boolean",
|
|
236
|
-
description: "True when the running server's configuration no longer matches " +
|
|
237
|
-
".descry/config.json on disk, so this reply (including graph and " +
|
|
238
|
-
"reportCategory) reflects the stale configuration loaded at startup. " +
|
|
239
|
-
"Restart the server to pick up the on-disk change; see disclosures " +
|
|
240
|
-
"for which fields changed.",
|
|
241
|
-
},
|
|
242
|
-
reportCategory: {
|
|
243
|
-
...nullable({ type: "string", enum: [...REPORT_CATEGORIES] }),
|
|
244
|
-
description: "How strongly the CAUSE may be stated, capped by how well the code " +
|
|
245
|
-
"resolved. Null for conclusion-tier tools, and for replies that make no " +
|
|
246
|
-
"claim at all. 'confirmed' is unreachable from this surface by construction.",
|
|
247
|
-
},
|
|
248
|
-
existenceCategory: {
|
|
249
|
-
...nullable({ type: "string", enum: [...REPORT_CATEGORIES] }),
|
|
250
|
-
description: "How strongly the evidence says the failure is REAL, read from what was " +
|
|
251
|
-
"observed and never capped by how well the code resolved. Read it beside " +
|
|
252
|
-
"reportCategory, not instead of it: a reply can be 'strongly supported' " +
|
|
253
|
-
"here and 'unconfirmed' there, which means the failure was witnessed and " +
|
|
254
|
-
"its cause was not established. Null wherever no evidence reading was " +
|
|
255
|
-
"taken — conclusion-tier tools, faults, and refusals.",
|
|
256
|
-
},
|
|
257
|
-
provenance: {
|
|
258
|
-
type: "object",
|
|
259
|
-
description: "Constant for this server. governancePipeline is always false here.",
|
|
260
|
-
properties: {
|
|
261
|
-
surface: { type: "string", enum: ["mcp"] },
|
|
262
|
-
adjudicatedBy: { type: "string", enum: ["descry"] },
|
|
263
|
-
presentedBy: { type: "string", enum: ["host-agent"] },
|
|
264
|
-
governancePipeline: { type: "boolean", enum: [false] },
|
|
265
|
-
},
|
|
266
|
-
required: ["surface", "adjudicatedBy", "presentedBy", "governancePipeline"],
|
|
267
|
-
},
|
|
268
|
-
},
|
|
269
|
-
// Every field is emitted on every path, including the ones that are always
|
|
270
|
-
// null on a fault — `renderFailed` and `renderTimedOut` build the whole
|
|
271
|
-
// envelope. So "required" here is the literal truth rather than a minimum.
|
|
272
|
-
required: [
|
|
273
|
-
"tool",
|
|
274
|
-
"toolVersion",
|
|
275
|
-
"callId",
|
|
276
|
-
"state",
|
|
277
|
-
"class",
|
|
278
|
-
"headline",
|
|
279
|
-
"data",
|
|
280
|
-
"graph",
|
|
281
|
-
"truncated",
|
|
282
|
-
"refusals",
|
|
283
|
-
"budget",
|
|
284
|
-
"disclosures",
|
|
285
|
-
"configStale",
|
|
286
|
-
"reportCategory",
|
|
287
|
-
"existenceCategory",
|
|
288
|
-
"provenance",
|
|
289
|
-
],
|
|
290
|
-
};
|
|
291
|
-
/**
|
|
292
|
-
* The other shape a `tools/call` can return — `renderToolError`'s, now
|
|
293
|
-
* narrowed to the two cases where no tool was ever resolved (`name` not a
|
|
294
|
-
* string, or a name the registry does not have): there is no `ToolDefinition`
|
|
295
|
-
* to draw a real envelope from. A bad argument against a *resolved* tool goes
|
|
296
|
-
* through `renderRefusedInput` instead and is a real `state: "refused"`
|
|
297
|
-
* envelope — see that function's doc.
|
|
298
|
-
*
|
|
299
|
-
* Declared rather than quietly excluded. A schema that admitted only the
|
|
300
|
-
* envelope would be one the server itself violates on this narrower path.
|
|
301
|
-
* Declaring a union that is true beats declaring a single shape that is tidy.
|
|
302
|
-
*/
|
|
303
|
-
export const TOOL_ERROR_SCHEMA = {
|
|
304
|
-
type: "object",
|
|
305
|
-
title: "Tool argument error",
|
|
306
|
-
description: "Returned with isError when the call itself was malformed — fix the " +
|
|
307
|
-
"arguments and retry. Not a statement about the code either way.",
|
|
308
|
-
properties: {
|
|
309
|
-
tool: { type: "string" },
|
|
310
|
-
status: { type: "string", enum: ["error"] },
|
|
311
|
-
message: { type: "string" },
|
|
312
|
-
},
|
|
313
|
-
required: ["tool", "status", "message"],
|
|
314
|
-
};
|
|
315
|
-
/**
|
|
316
|
-
* What every tool declares as its `outputSchema`: the envelope or the argument
|
|
317
|
-
* error, discriminated by their required fields.
|
|
318
|
-
*
|
|
319
|
-
* One shared constant rather than a per-tool object because the shape genuinely
|
|
320
|
-
* is shared — the only per-tool part is `data`, which is open. When `data`
|
|
321
|
-
* becomes describable this becomes a function of the tool.
|
|
322
|
-
*/
|
|
323
|
-
export const TOOL_OUTPUT_SCHEMA = {
|
|
324
|
-
type: "object",
|
|
325
|
-
anyOf: [ANSWER_ENVELOPE_SCHEMA, TOOL_ERROR_SCHEMA],
|
|
326
|
-
};
|
|
327
|
-
export class DisclosureError extends Error {
|
|
328
|
-
constructor(message) {
|
|
329
|
-
super(message);
|
|
330
|
-
this.name = "DisclosureError";
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
/** Rule 7's label for a redemption that could not honour what the caller asked for. Names the
|
|
334
|
-
* arguments rather than counting them — "1 argument was discarded" tells a caller something went
|
|
335
|
-
* wrong without telling them what to fix — and names the recovery, which is the same one the
|
|
336
|
-
* `confirmToken` descriptions prescribe. See `action-handshake.ts`'s header. */
|
|
337
|
-
function discardedArgsNote(discarded) {
|
|
338
|
-
const names = discarded.map((key) => `"${key}"`).join(", ");
|
|
339
|
-
return (`This call supplied ${names} alongside a confirmToken, but a token runs the arguments frozen ` +
|
|
340
|
-
`when it was minted — the ones described for confirmation — so ${discarded.length === 1 ? "that value was" : "those values were"} discarded rather than used. ` +
|
|
341
|
-
"Call again without confirmToken to have the new arguments described, then confirm that token.");
|
|
342
|
-
}
|
|
343
|
-
/**
|
|
344
|
-
* MK-8's derivation, shared by every envelope-producing function below so the
|
|
345
|
-
* rule lives in one place rather than four.
|
|
346
|
-
*/
|
|
347
|
-
function deriveEnvelopeCategory(tier, state, resolutionFloor, nameLevel, witnessed) {
|
|
348
|
-
if (tier === "conclusion")
|
|
349
|
-
return null;
|
|
350
|
-
if (state === "failed" || state === "timed_out")
|
|
351
|
-
return null;
|
|
352
|
-
if (state === "refused")
|
|
353
|
-
return "not analysable";
|
|
354
|
-
return deriveReportCategory({
|
|
355
|
-
// G3's precondition, answered by the tool rather than assumed: a tool that
|
|
356
|
-
// ran nothing declares nothing here and short-circuits to `unconfirmed`,
|
|
357
|
-
// exactly as before. A tool that watched a real application declares what
|
|
358
|
-
// it watched.
|
|
359
|
-
hasRuntimeEvidence: witnessed !== undefined,
|
|
360
|
-
// Pinned false, and deliberately not something a tool may declare. `M` is
|
|
361
|
-
// G4's one route to `confirmed`, and DEC-334 reserves that category for a
|
|
362
|
-
// result that passed the full governance pipeline — which does not run in
|
|
363
|
-
// this surface. Accepting `M` here would let a tool mint the one label the
|
|
364
|
-
// ruling holds back, so the field is not offered rather than offered and
|
|
365
|
-
// then clamped: a clamp is a silent downgrade, and rule 7 forbids those.
|
|
366
|
-
directMechanismEvidence: false,
|
|
367
|
-
independentSignalTypes: witnessed?.independentSignalTypes ?? 0,
|
|
368
|
-
// `renderAnswer`'s own `state`/`disclosures` invariants guarantee a real
|
|
369
|
-
// graph was consulted whenever state is ok/empty, so this is never the
|
|
370
|
-
// null-graph sentinel — cast is safe, not asserted blind.
|
|
371
|
-
resolution: (resolutionFloor ?? 0),
|
|
372
|
-
nameLevel,
|
|
373
|
-
humanAsserted: false,
|
|
374
|
-
}).category;
|
|
375
|
-
}
|
|
376
|
-
/**
|
|
377
|
-
* The existence half — `documents/plans/gate_loosening.md` §3.3.
|
|
378
|
-
*
|
|
379
|
-
* Reads the same witnessed evidence the sibling above does and takes no resolution argument at
|
|
380
|
-
* all, which is the whole point: the structural floor is evidence about the cause and this is a
|
|
381
|
-
* statement about the failure. The two are computed apart so that neither can silently acquire
|
|
382
|
-
* the other's inputs.
|
|
383
|
-
*
|
|
384
|
-
* `directMechanismEvidence` is pinned `false` for exactly the reason the sibling pins it —
|
|
385
|
-
* DEC-334 holds `confirmed` for a result that passed the full governance pipeline, which does
|
|
386
|
-
* not run in an MCP call. So this tops out at `strongly supported` too, and the split changes
|
|
387
|
-
* which failures are *visible*, never which label this surface may mint.
|
|
388
|
-
*
|
|
389
|
-
* Null on refusal is deliberate and is not the same as `unconfirmed`: a refusal is a fact about
|
|
390
|
-
* Descry rather than about the application, and reporting it as an evidence reading would teach
|
|
391
|
-
* the caller that we looked and saw nothing.
|
|
392
|
-
*/
|
|
393
|
-
function deriveEnvelopeExistence(tier, state, witnessed) {
|
|
394
|
-
if (tier === "conclusion")
|
|
395
|
-
return null;
|
|
396
|
-
if (state === "failed" || state === "timed_out" || state === "refused")
|
|
397
|
-
return null;
|
|
398
|
-
return deriveExistenceCategory({
|
|
399
|
-
hasRuntimeEvidence: witnessed !== undefined,
|
|
400
|
-
directMechanismEvidence: false,
|
|
401
|
-
independentSignalTypes: witnessed?.independentSignalTypes ?? 0,
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
/**
|
|
405
|
-
* A refusal's reason must be the specific, verbatim thing that blocked it —
|
|
406
|
-
* never just the state name. This is a heuristic proxy for that rule (§4):
|
|
407
|
-
* `disclosures` must contain something a template did not produce, which we
|
|
408
|
-
* cannot verify from here, but we CAN verify the weaker, structurally
|
|
409
|
-
* checkable half — that at least one disclosure exists and it is not empty
|
|
410
|
-
* text — the same shape invariant 2 already asserts. The stronger claim (the
|
|
411
|
-
* reason is *this* refusal's actual cause, not a generic string) is a
|
|
412
|
-
* per-tool authoring discipline this function cannot see into; it is checked
|
|
413
|
-
* by `tool-contract-gate.mjs`'s exemplar reading instead.
|
|
414
|
-
*/
|
|
415
|
-
/**
|
|
416
|
-
* The retired-name disclosure, for every render path rather than the happy one.
|
|
417
|
-
*
|
|
418
|
-
* A call under a dead name that *fails* still needs to be told the name is
|
|
419
|
-
* dead — arguably more than a call that succeeds, since the caller is already
|
|
420
|
-
* debugging and "no such tool" is one release away. `renderAnswer` is not the
|
|
421
|
-
* only exit: a refusal, a failure, a handshake and a timeout are all replies a
|
|
422
|
-
* retired name can produce, and each assembles its own disclosure list.
|
|
423
|
-
*/
|
|
424
|
-
function aliasNotes(options) {
|
|
425
|
-
return options.aliasedFrom === undefined || options.aliasedTo === undefined
|
|
426
|
-
? []
|
|
427
|
-
: [aliasDisclosure(options.aliasedFrom, options.aliasedTo)];
|
|
428
|
-
}
|
|
429
|
-
export function renderAnswer(tool, answer, options) {
|
|
430
|
-
const { result, nameLevel } = answer;
|
|
431
|
-
const state = answer.state ?? "ok";
|
|
432
|
-
if (result.truncated && result.notes.length === 0) {
|
|
433
|
-
throw new DisclosureError(`${tool} returned a truncated answer with no disclosure. A partial result that does not ` +
|
|
434
|
-
"say it is partial reads as a complete one, which is the failure rule 7 exists to " +
|
|
435
|
-
"prevent. Fix the query, not this check.");
|
|
436
|
-
}
|
|
437
|
-
if ((state === "refused" || state === "failed" || state === "timed_out") && result.notes.length === 0) {
|
|
438
|
-
throw new DisclosureError(`${tool} reported "${state}" without saying why. The five result states exist to distinguish ` +
|
|
439
|
-
'"we found nothing" from "we could not look" from "something broke"; with no reason attached ' +
|
|
440
|
-
"this reply says none of them.");
|
|
441
|
-
}
|
|
442
|
-
// B6, fifth invariant (module header): a truncated answer must carry real
|
|
443
|
-
// counts. The old fallback here was a sentinel, `{shown: -1, total: -1}` —
|
|
444
|
-
// worse than absent, because it passes a presence check and then poisons
|
|
445
|
-
// arithmetic. A tool that sets `result.truncated` without supplying
|
|
446
|
-
// `answer.truncatedDetail` has not held the two together the way
|
|
447
|
-
// `capped()` (`./capped.ts`) makes automatic, so this is a defect in that
|
|
448
|
-
// tool, caught here rather than shipped: thrown everywhere except
|
|
449
|
-
// production, where the honest degradation is `null` plus a disclosure
|
|
450
|
-
// that the count itself is unavailable — never a fabricated one.
|
|
451
|
-
let missingTruncationDetail = null;
|
|
452
|
-
if (result.truncated && answer.truncatedDetail === undefined) {
|
|
453
|
-
if (process.env["NODE_ENV"] !== "production") {
|
|
454
|
-
throw new DisclosureError(`${tool} set result.truncated without a truncatedDetail (shown/total). Build the capped ` +
|
|
455
|
-
'slice and its detail together — see capped() in "./capped.ts" — rather than capping ' +
|
|
456
|
-
"and reporting separately, where one of the two can be forgotten.");
|
|
457
|
-
}
|
|
458
|
-
missingTruncationDetail =
|
|
459
|
-
"this reply was truncated, but how much was withheld is unavailable — a defect in this " +
|
|
460
|
-
"tool, not a fact about your code";
|
|
461
|
-
}
|
|
462
|
-
const resolutionFloor = result.stamp.resolutionFloor;
|
|
463
|
-
const cap = reliabilityCap(resolutionFloor, nameLevel);
|
|
464
|
-
// Full the first time this connection meets this category, a short reference
|
|
465
|
-
// to it after — see `disclosure-ledger.ts`. The floor and the class are on
|
|
466
|
-
// every reply either way; only the argument for them collapses.
|
|
467
|
-
const reliability = reliabilityDisclosure(resolutionFloor, nameLevel);
|
|
468
|
-
const disclosures = [
|
|
469
|
-
...result.notes,
|
|
470
|
-
// First among the disclosures, ahead of the reliability argument: a caller
|
|
471
|
-
// on a dead name needs to know that before it needs anything else.
|
|
472
|
-
...aliasNotes(options),
|
|
473
|
-
...(missingTruncationDetail === null ? [] : [missingTruncationDetail]),
|
|
474
|
-
options.disclosureLedger?.firstSighting(reliability.key) === false
|
|
475
|
-
? reliability.brief
|
|
476
|
-
: reliability.full,
|
|
477
|
-
...(result.stamp.commitSpread > 1
|
|
478
|
-
? [
|
|
479
|
-
`a repository in this graph has runs spanning ${result.stamp.commitSpread} distinct ` +
|
|
480
|
-
"commits; part of its graph may describe code that is no longer current",
|
|
481
|
-
]
|
|
482
|
-
: []),
|
|
483
|
-
// A neutral fact, never a warning — cross-repo sharing (`link_workspace`) is
|
|
484
|
-
// what makes cross-repo contracts/validate/similar_incidents work at all.
|
|
485
|
-
// UAT phase 5: this used to be the same sentence as the staleness warning
|
|
486
|
-
// above, driven by a global (not per-repo) commit count, so it fired on
|
|
487
|
-
// every single reply in a shared workspace and read as decay that was
|
|
488
|
-
// never real — training the reader to ignore it before the day a genuine
|
|
489
|
-
// staleness warning needed attention.
|
|
490
|
-
...(result.stamp.repoCount > 1
|
|
491
|
-
? [`this graph spans ${result.stamp.repoCount} repositories, each at its own HEAD`]
|
|
492
|
-
: []),
|
|
493
|
-
...(options.configDrift?.note === undefined ? [] : [options.configDrift.note]),
|
|
494
|
-
...(options.discardedArgs === undefined || options.discardedArgs.length === 0
|
|
495
|
-
? []
|
|
496
|
-
: [discardedArgsNote(options.discardedArgs)]),
|
|
497
|
-
];
|
|
498
|
-
// B10 — minted by the caller before this call, so it is threaded through
|
|
499
|
-
// rather than generated here; a fallback exists only for the direct callers
|
|
500
|
-
// (tests) that have no session id sequence to draw from. See `callId`'s own
|
|
501
|
-
// doc on `AnswerEnvelope` and `RenderOptions`.
|
|
502
|
-
const callId = options.callId ?? randomUUID();
|
|
503
|
-
const build = (data, extraNotes, fitTruncation) => ({
|
|
504
|
-
tool,
|
|
505
|
-
toolVersion: options.toolVersion,
|
|
506
|
-
callId,
|
|
507
|
-
state,
|
|
508
|
-
class: options.toolClass,
|
|
509
|
-
headline: answer.headline,
|
|
510
|
-
data,
|
|
511
|
-
graph: {
|
|
512
|
-
commitSha: result.stamp.commitSha,
|
|
513
|
-
builtAt: result.stamp.graphBuiltAt === null
|
|
514
|
-
? null
|
|
515
|
-
: new Date(result.stamp.graphBuiltAt).toISOString(),
|
|
516
|
-
irSchemaVersion: result.stamp.irSchemaVersion,
|
|
517
|
-
resolutionFloor,
|
|
518
|
-
reliabilityCap: cap,
|
|
519
|
-
},
|
|
520
|
-
truncated: fitTruncation ?? (!result.truncated ? null : (answer.truncatedDetail ?? null)),
|
|
521
|
-
refusals: answer.refusalSummary ?? null,
|
|
522
|
-
budget: { elapsedMs: options.elapsedMs, limitMs: options.limitMs },
|
|
523
|
-
// The fit's own notes go first among the disclosures it added, ahead of
|
|
524
|
-
// the standing reliability sentence, for the same reason `narrate` puts
|
|
525
|
-
// disclosures last: what is specific to this call must not be buried
|
|
526
|
-
// under what is true of every call.
|
|
527
|
-
disclosures: extraNotes.length === 0 ? disclosures : [...result.notes, ...extraNotes, ...disclosures.slice(result.notes.length)],
|
|
528
|
-
configStale: options.configDrift?.stale ?? false,
|
|
529
|
-
reportCategory: deriveEnvelopeCategory(options.toolTier, state, resolutionFloor, nameLevel, answer.runtimeEvidence),
|
|
530
|
-
existenceCategory: deriveEnvelopeExistence(options.toolTier, state, answer.runtimeEvidence),
|
|
531
|
-
provenance: PROVENANCE,
|
|
532
|
-
});
|
|
533
|
-
const frame = (envelope) => ({
|
|
534
|
-
content: [{ type: "text", text: narrate(envelope) }],
|
|
535
|
-
structuredContent: envelope,
|
|
536
|
-
});
|
|
537
|
-
const rendered = frame(build(result.data, [], null));
|
|
538
|
-
const ceiling = options.maxReplyBytes ?? MAX_REPLY_BYTES;
|
|
539
|
-
if (answer.fitToBudget === undefined || sizeOf(rendered) <= ceiling)
|
|
540
|
-
return rendered;
|
|
541
|
-
// The tool is asked for a payload that fits in what is left once everything
|
|
542
|
-
// else is paid for. Its own disclosures cost bytes too, so the first budget
|
|
543
|
-
// can be slightly optimistic — the loop re-measures and asks again with the
|
|
544
|
-
// corrected figure rather than assuming one pass converges. Two passes is
|
|
545
|
-
// the observed cost; the third exists so a pathological oscillation ends.
|
|
546
|
-
let fitted = rendered;
|
|
547
|
-
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
548
|
-
const payloadBytes = Buffer.byteLength(JSON.stringify(dataOf(fitted)) ?? "null", "utf8");
|
|
549
|
-
const budget = ceiling - (sizeOf(fitted) - payloadBytes);
|
|
550
|
-
const fit = answer.fitToBudget(Math.max(budget, 0));
|
|
551
|
-
if (fit.truncatedDetail !== undefined && fit.notes.length === 0) {
|
|
552
|
-
throw new DisclosureError(`${tool} dropped items to fit the reply's size budget without saying so. A reply shrunk in ` +
|
|
553
|
-
"silence reads as a complete one — the same failure invariant 1 covers for a query's own " +
|
|
554
|
-
"truncation, arriving by a different route.");
|
|
555
|
-
}
|
|
556
|
-
fitted = frame(build(fit.data, fit.notes, fit.truncatedDetail ?? null));
|
|
557
|
-
if (sizeOf(fitted) <= ceiling)
|
|
558
|
-
break;
|
|
559
|
-
}
|
|
560
|
-
// Returned even if the last pass is still over: a tool that cannot shrink
|
|
561
|
-
// below the ceiling has an oversized answer either way, and an oversized
|
|
562
|
-
// answer beats a fabricated small one.
|
|
563
|
-
return fitted;
|
|
564
|
-
}
|
|
565
|
-
function sizeOf(rendered) {
|
|
566
|
-
return Buffer.byteLength(JSON.stringify(rendered), "utf8");
|
|
567
|
-
}
|
|
568
|
-
/** The `data` inside a rendered frame, for measuring its share of the total. */
|
|
569
|
-
function dataOf(rendered) {
|
|
570
|
-
return rendered.structuredContent.data;
|
|
571
|
-
}
|
|
572
|
-
/**
|
|
573
|
-
* The text an agent actually reads.
|
|
574
|
-
*
|
|
575
|
-
* Ordered so that the disclosures are **last**, because that is what a model
|
|
576
|
-
* summarising the reply keeps. A caveat buried above the data is a caveat that
|
|
577
|
-
* gets dropped in the summary the developer sees.
|
|
578
|
-
*/
|
|
579
|
-
function narrate(envelope) {
|
|
580
|
-
const lines = [envelope.headline];
|
|
581
|
-
if (envelope.state !== "ok" && envelope.state !== "empty") {
|
|
582
|
-
lines.push("", `**${envelope.state}.** ` +
|
|
583
|
-
(envelope.state === "refused"
|
|
584
|
-
? "This is not a result — see below for why Descry could not look."
|
|
585
|
-
: envelope.state === "failed"
|
|
586
|
-
? "Something broke while answering this call — see below."
|
|
587
|
-
: "The call ran out of its declared time budget — see below."));
|
|
588
|
-
}
|
|
589
|
-
else if (envelope.state === "empty") {
|
|
590
|
-
lines.push("", "**Empty.** Descry looked completely and there was nothing to find — see below.");
|
|
591
|
-
}
|
|
592
|
-
// Three cases, not two (F3 / Part A §3, UAT Phase 5): `commitSha === null`
|
|
593
|
-
// is the only condition that actually means "nothing has been analysed" —
|
|
594
|
-
// `renderRefusedInput`/`renderFailed`/`renderTimedOut` used to hardcode it
|
|
595
|
-
// regardless of what the stored graph held, so every argument-validation
|
|
596
|
-
// refusal against an already-populated graph asserted a specific, checkable,
|
|
597
|
-
// false claim about the user's code. `resolutionFloor === null` is the
|
|
598
|
-
// existing, already-true signal for "this call never consulted the graph"
|
|
599
|
-
// (see the field's own doc on `AnswerEnvelope.graph`) — reused here rather
|
|
600
|
-
// than adding a second one that could drift from it.
|
|
601
|
-
const stale = envelope.graph.commitSha === null
|
|
602
|
-
? "The graph is empty — nothing has been analysed into it yet."
|
|
603
|
-
: envelope.graph.resolutionFloor === null
|
|
604
|
-
? `Graph at ${envelope.graph.commitSha.slice(0, 12)}` +
|
|
605
|
-
(envelope.graph.builtAt === null ? "" : `, built ${envelope.graph.builtAt}`) +
|
|
606
|
-
" is stored, but this reply made no use of it — no resolution or reliability class applies here."
|
|
607
|
-
: `Graph at ${envelope.graph.commitSha.slice(0, 12)}` +
|
|
608
|
-
(envelope.graph.builtAt === null ? "" : `, built ${envelope.graph.builtAt}`) +
|
|
609
|
-
`. Weakest evidence R${envelope.graph.resolutionFloor}; findings here cap at ` +
|
|
610
|
-
`reliability class ${envelope.graph.reliabilityCap}.`;
|
|
611
|
-
lines.push("", stale);
|
|
612
|
-
if (envelope.disclosures.length > 0) {
|
|
613
|
-
lines.push("", "What this answer does not cover:");
|
|
614
|
-
for (const note of envelope.disclosures)
|
|
615
|
-
lines.push(`- ${note}`);
|
|
616
|
-
}
|
|
617
|
-
return lines.join("\n");
|
|
618
|
-
}
|
|
619
|
-
/**
|
|
620
|
-
* A malformed call the server cannot even attribute to one tool — the RPC
|
|
621
|
-
* named no string tool, or named a tool that does not exist in the registry.
|
|
622
|
-
*
|
|
623
|
-
* Returned as a tool result with `isError`, not as a JSON-RPC error, which is
|
|
624
|
-
* what the MCP spec asks for: protocol errors are for malformed protocol, tool
|
|
625
|
-
* errors are for tools, and an agent can act on the second only if it arrives as
|
|
626
|
-
* content it can read.
|
|
627
|
-
*
|
|
628
|
-
* Deliberately outside the five-state envelope, and narrowly so: there is no
|
|
629
|
-
* resolved `ToolDefinition` here to draw `toolVersion`/`class`/`tier` from, so
|
|
630
|
-
* no real envelope can be built — inventing placeholder values for them would
|
|
631
|
-
* be worse than the bare shape. Once a tool *is* identified, a bad argument
|
|
632
|
-
* against it is `renderRefusedInput`'s case, not this one — see that
|
|
633
|
-
* function's doc for why the two are different claims.
|
|
634
|
-
*/
|
|
635
|
-
export function renderToolError(tool, message) {
|
|
636
|
-
return {
|
|
637
|
-
content: [{ type: "text", text: `${tool}: ${message}` }],
|
|
638
|
-
structuredContent: { tool, status: "error", message },
|
|
639
|
-
isError: true,
|
|
640
|
-
};
|
|
641
|
-
}
|
|
642
|
-
/**
|
|
643
|
-
* `state: "refused"` — the call named a real, resolved tool, but its input
|
|
644
|
-
* was wrong, so the tool never ran (`ToolInputError`, thrown by a tool's own
|
|
645
|
-
* argument reading, or by the dispatcher's own shape check on `arguments`
|
|
646
|
-
* once a tool is known).
|
|
647
|
-
*
|
|
648
|
-
* This used to fall through to `renderToolError`'s bare `{tool, status,
|
|
649
|
-
* message}` shape — measured as a real defect (a live `observe_runtime` call
|
|
650
|
-
* with a malformed `profile` field returned that bare shape instead of an
|
|
651
|
-
* envelope), because unlike the two cases `renderToolError` still covers, a
|
|
652
|
-
* `ToolDefinition` *is* available here: `toolVersion`, `class` and `tier` are
|
|
653
|
-
* all real, so a real envelope can be built rather than invented. "The tool
|
|
654
|
-
* was never run because its input was wrong" is a fact about this call, not
|
|
655
|
-
* about the code being examined — exactly what `state: "refused"` already
|
|
656
|
-
* means everywhere else in this file, so it is rendered the same way rather
|
|
657
|
-
* than through a second, parallel shape.
|
|
658
|
-
*
|
|
659
|
-
* `data` is always `null` (§2.2): nothing ran, so there is nothing to stamp.
|
|
660
|
-
* `isError` stays `true` for the same reason `renderFailed`/`renderTimedOut`
|
|
661
|
-
* set it — a generic client that only reads the transport-level signal still
|
|
662
|
-
* sees a failure; an AI-layer-aware caller additionally gets the real
|
|
663
|
-
* `state`/`disclosures`/`reportCategory` to reason about.
|
|
664
|
-
*/
|
|
665
|
-
export function renderRefusedInput(tool, message, options) {
|
|
666
|
-
const stamp = options.graphStamp;
|
|
667
|
-
const envelope = {
|
|
668
|
-
tool,
|
|
669
|
-
toolVersion: options.toolVersion,
|
|
670
|
-
callId: options.callId ?? randomUUID(),
|
|
671
|
-
state: "refused",
|
|
672
|
-
class: options.toolClass,
|
|
673
|
-
headline: `${tool} could not run: ${message}`,
|
|
674
|
-
data: null,
|
|
675
|
-
graph: {
|
|
676
|
-
// Facts about the *stored* graph, independent of whether this refusal
|
|
677
|
-
// ever reached it (F3, UAT Phase 5) — `renderHandshake` already reads
|
|
678
|
-
// these from `graphStamp` the same way; `resolutionFloor` stays `null`
|
|
679
|
-
// regardless, because this call genuinely never consulted the graph.
|
|
680
|
-
commitSha: stamp?.commitSha ?? null,
|
|
681
|
-
builtAt: stamp?.graphBuiltAt === undefined || stamp.graphBuiltAt === null ? null : new Date(stamp.graphBuiltAt).toISOString(),
|
|
682
|
-
irSchemaVersion: stamp?.irSchemaVersion ?? 0,
|
|
683
|
-
resolutionFloor: null,
|
|
684
|
-
reliabilityCap: "C",
|
|
685
|
-
},
|
|
686
|
-
truncated: null,
|
|
687
|
-
refusals: null,
|
|
688
|
-
budget: { elapsedMs: options.elapsedMs, limitMs: options.limitMs },
|
|
689
|
-
disclosures: [...aliasNotes(options), message, ...(options.configDrift?.note === undefined ? [] : [options.configDrift.note])],
|
|
690
|
-
configStale: options.configDrift?.stale ?? false,
|
|
691
|
-
// Same rule `deriveEnvelopeCategory` applies everywhere else: a
|
|
692
|
-
// conclusion-tier tool states its verdict in `headline`'s own words, so
|
|
693
|
-
// this stays null there; an evidence-tier tool's refusal maps to "not
|
|
694
|
-
// analysable" — "could not look" either way, whether the graph refused
|
|
695
|
-
// the query or the call never reached the graph at all.
|
|
696
|
-
reportCategory: options.toolTier === "conclusion" ? null : "not analysable",
|
|
697
|
-
// A refusal read no evidence, so it makes no existence claim — see the field doc.
|
|
698
|
-
existenceCategory: null,
|
|
699
|
-
provenance: PROVENANCE,
|
|
700
|
-
};
|
|
701
|
-
return {
|
|
702
|
-
content: [{ type: "text", text: narrate(envelope) }],
|
|
703
|
-
structuredContent: envelope,
|
|
704
|
-
isError: true,
|
|
705
|
-
};
|
|
706
|
-
}
|
|
707
|
-
/**
|
|
708
|
-
* `state: "failed"` — §1.1: "promoted from a transport error to a result."
|
|
709
|
-
*
|
|
710
|
-
* An unexpected/internal error, not a bad argument (`renderToolError` still
|
|
711
|
-
* handles those). `data` is always `null` here (§2.2): the tool does not know
|
|
712
|
-
* what happened, and anything it returned would be a guess about its own
|
|
713
|
-
* fault. `isError` stays `true` so a generic MCP client that only reads the
|
|
714
|
-
* transport-level signal still treats this as a failure; an AI-layer-aware
|
|
715
|
-
* caller additionally gets `state: "failed"` in `structuredContent` to reason
|
|
716
|
-
* about rather than a bare `{tool, status, message}` shape.
|
|
717
|
-
*
|
|
718
|
-
* `headline` is optional and exists for the *explained* half of "failed": a
|
|
719
|
-
* `ConfigError` (and any sibling raised specifically to be read, not merely
|
|
720
|
-
* caught) already carries a full written reason, and burying that behind a
|
|
721
|
-
* generic "X failed." while the real sentence sits only in `disclosures` is
|
|
722
|
-
* the bug 13.3.5 names — a caller reading just the headline learns nothing.
|
|
723
|
-
* An unexplained internal fault has no such sentence to offer, so it keeps
|
|
724
|
-
* the opaque default.
|
|
725
|
-
*/
|
|
726
|
-
export function renderFailed(tool, message, options, headline) {
|
|
727
|
-
const stamp = options.graphStamp;
|
|
728
|
-
const envelope = {
|
|
729
|
-
tool,
|
|
730
|
-
toolVersion: options.toolVersion,
|
|
731
|
-
callId: options.callId ?? randomUUID(),
|
|
732
|
-
state: "failed",
|
|
733
|
-
class: options.toolClass,
|
|
734
|
-
headline: headline ?? `${tool} failed.`,
|
|
735
|
-
data: null,
|
|
736
|
-
graph: {
|
|
737
|
-
// See `renderRefusedInput`'s identical comment (F3, UAT Phase 5): a
|
|
738
|
-
// fault is not a claim about the graph, but "nothing has been analysed"
|
|
739
|
-
// is a claim about the graph, and stating it falsely is worse than not
|
|
740
|
-
// stating a stored commit this call happened not to read.
|
|
741
|
-
commitSha: stamp?.commitSha ?? null,
|
|
742
|
-
builtAt: stamp?.graphBuiltAt === undefined || stamp.graphBuiltAt === null ? null : new Date(stamp.graphBuiltAt).toISOString(),
|
|
743
|
-
irSchemaVersion: stamp?.irSchemaVersion ?? 0,
|
|
744
|
-
resolutionFloor: null,
|
|
745
|
-
reliabilityCap: "C",
|
|
746
|
-
},
|
|
747
|
-
truncated: null,
|
|
748
|
-
refusals: null,
|
|
749
|
-
budget: { elapsedMs: options.elapsedMs, limitMs: options.limitMs },
|
|
750
|
-
disclosures: [...aliasNotes(options), message, ...(options.configDrift?.note === undefined ? [] : [options.configDrift.note])],
|
|
751
|
-
configStale: options.configDrift?.stale ?? false,
|
|
752
|
-
// A fault is not a claim about the code either way (§20) — no category applies.
|
|
753
|
-
reportCategory: null,
|
|
754
|
-
existenceCategory: null,
|
|
755
|
-
provenance: PROVENANCE,
|
|
756
|
-
};
|
|
757
|
-
return {
|
|
758
|
-
content: [{ type: "text", text: narrate(envelope) }],
|
|
759
|
-
structuredContent: envelope,
|
|
760
|
-
isError: true,
|
|
761
|
-
};
|
|
762
|
-
}
|
|
763
|
-
/**
|
|
764
|
-
* The one legitimate producer of a pending-handshake payload — §7's mint call.
|
|
765
|
-
*
|
|
766
|
-
* `class == "action"` returning anything other than this shape on an
|
|
767
|
-
* unconfirmed first call is invariant 4 (§2.1): "throw." This function is
|
|
768
|
-
* where that shape is produced, so the throw lives at the one call site that
|
|
769
|
-
* builds anything else for an action tool's first call — `server.ts`'s
|
|
770
|
-
* dispatch loop calls this and only this when `resolveActionDispatch` returns
|
|
771
|
-
* `{kind: "handshake"}`, never `tool.run`.
|
|
772
|
-
*
|
|
773
|
-
* `state: "ok"` deliberately: a mint is not a refusal, a failure or an empty
|
|
774
|
-
* result — it is a successful "here is what I would do", and the *pending*
|
|
775
|
-
* flag inside `data` is what tells a caller nothing was performed yet.
|
|
776
|
-
*/
|
|
777
|
-
export function renderHandshake(tool, token, willDo, options) {
|
|
778
|
-
const stamp = options.graphStamp;
|
|
779
|
-
const envelope = {
|
|
780
|
-
tool,
|
|
781
|
-
toolVersion: options.toolVersion,
|
|
782
|
-
callId: options.callId ?? randomUUID(),
|
|
783
|
-
state: "ok",
|
|
784
|
-
class: options.toolClass,
|
|
785
|
-
headline: `Confirmation required: ${willDo}`,
|
|
786
|
-
data: { pending: true, token, willDo },
|
|
787
|
-
graph: {
|
|
788
|
-
commitSha: stamp?.commitSha ?? null,
|
|
789
|
-
builtAt: stamp?.graphBuiltAt === undefined || stamp.graphBuiltAt === null ? null : new Date(stamp.graphBuiltAt).toISOString(),
|
|
790
|
-
irSchemaVersion: stamp?.irSchemaVersion ?? 0,
|
|
791
|
-
// Nothing has been read for THIS call — a mint makes no claim, so it
|
|
792
|
-
// carries no resolution/reliability of its own, the same reasoning
|
|
793
|
-
// `renderFailed`/`renderTimedOut` use. Only commitSha/builtAt/
|
|
794
|
-
// irSchemaVersion are real facts about the stored graph, independent of
|
|
795
|
-
// whether this pending action has been confirmed yet.
|
|
796
|
-
resolutionFloor: null,
|
|
797
|
-
reliabilityCap: "C",
|
|
798
|
-
},
|
|
799
|
-
truncated: null,
|
|
800
|
-
refusals: null,
|
|
801
|
-
budget: { elapsedMs: options.elapsedMs, limitMs: options.limitMs },
|
|
802
|
-
disclosures: [
|
|
803
|
-
...aliasNotes(options),
|
|
804
|
-
`Nothing was performed. Call ${tool} again with { "confirmToken": "${token}" } to actually do this — ` +
|
|
805
|
-
"the token expires in five minutes and is single-use.",
|
|
806
|
-
...(options.configDrift?.note === undefined ? [] : [options.configDrift.note]),
|
|
807
|
-
],
|
|
808
|
-
configStale: options.configDrift?.stale ?? false,
|
|
809
|
-
// Nothing was analysed yet — a confirmation prompt makes no claim to categorize.
|
|
810
|
-
reportCategory: null,
|
|
811
|
-
existenceCategory: null,
|
|
812
|
-
provenance: PROVENANCE,
|
|
813
|
-
};
|
|
814
|
-
return {
|
|
815
|
-
content: [{ type: "text", text: narrate(envelope) }],
|
|
816
|
-
structuredContent: envelope,
|
|
817
|
-
};
|
|
818
|
-
}
|
|
819
|
-
/**
|
|
820
|
-
* `state: "timed_out"` — the call ran out of its declared budget.
|
|
821
|
-
*
|
|
822
|
-
* §6: "not a silent truncation and never a `failed`". `data` is `null` here
|
|
823
|
-
* because none of the registered tools currently produce genuine partial
|
|
824
|
-
* results mid-run (none checks `ctx.signal` internally yet — a disclosed gap,
|
|
825
|
-
* not a silent one, named in the returned disclosure); the envelope shape
|
|
826
|
-
* supports a populated partial `data` the day a tool does.
|
|
827
|
-
*/
|
|
828
|
-
export function renderTimedOut(tool, options) {
|
|
829
|
-
const stamp = options.graphStamp;
|
|
830
|
-
const envelope = {
|
|
831
|
-
tool,
|
|
832
|
-
toolVersion: options.toolVersion,
|
|
833
|
-
callId: options.callId ?? randomUUID(),
|
|
834
|
-
state: "timed_out",
|
|
835
|
-
class: options.toolClass,
|
|
836
|
-
headline: `${tool} timed out.`,
|
|
837
|
-
data: null,
|
|
838
|
-
graph: {
|
|
839
|
-
// See `renderRefusedInput`'s identical comment (F3, UAT Phase 5).
|
|
840
|
-
commitSha: stamp?.commitSha ?? null,
|
|
841
|
-
builtAt: stamp?.graphBuiltAt === undefined || stamp.graphBuiltAt === null ? null : new Date(stamp.graphBuiltAt).toISOString(),
|
|
842
|
-
irSchemaVersion: stamp?.irSchemaVersion ?? 0,
|
|
843
|
-
resolutionFloor: null,
|
|
844
|
-
reliabilityCap: "C",
|
|
845
|
-
},
|
|
846
|
-
truncated: null,
|
|
847
|
-
refusals: null,
|
|
848
|
-
budget: { elapsedMs: options.elapsedMs, limitMs: options.limitMs },
|
|
849
|
-
disclosures: [
|
|
850
|
-
...aliasNotes(options),
|
|
851
|
-
`${tool} did not finish within its ${options.limitMs}ms budget. This is a partial answer, not ` +
|
|
852
|
-
"a finding of failure or of absence — retry, or narrow the request.",
|
|
853
|
-
...(options.configDrift?.note === undefined ? [] : [options.configDrift.note]),
|
|
854
|
-
],
|
|
855
|
-
configStale: options.configDrift?.stale ?? false,
|
|
856
|
-
// A partial run in progress makes no claim to categorize yet.
|
|
857
|
-
reportCategory: null,
|
|
858
|
-
existenceCategory: null,
|
|
859
|
-
provenance: PROVENANCE,
|
|
860
|
-
};
|
|
861
|
-
return {
|
|
862
|
-
content: [{ type: "text", text: narrate(envelope) }],
|
|
863
|
-
structuredContent: envelope,
|
|
864
|
-
isError: true,
|
|
865
|
-
};
|
|
866
|
-
}
|
|
867
|
-
//# sourceMappingURL=render.js.map
|