@jungjaehoon/mama-core 2.4.1 → 4.0.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/README.md +76 -239
- package/db/migrations/030-case-first-memory-substrate.sql +13 -98
- package/db/migrations/034-add-connector-event-scope-columns.sql +9 -13
- package/db/migrations/039-add-connector-event-operator-ingest-seq.sql +9 -95
- package/db/migrations/062-refresh-connector-event-sequences.sql +9 -113
- package/db/migrations/063-refresh-legacy-connector-event-updates.sql +9 -32
- package/db/migrations/067-add-connector-event-source-entity-id.sql +9 -13
- package/db/migrations/069-create-registry-nodes.sql +52 -0
- package/db/migrations/070-record-identity.sql +35 -0
- package/db/migrations/071-service-operation-origins.sql +187 -0
- package/db/migrations/072-observation-versions.sql +29 -0
- package/db/migrations/073-registry-corrections.sql +45 -0
- package/db/migrations/074-work-graph-ref-kinds.sql +39 -0
- package/db/migrations/075-agent-judgments.sql +58 -0
- package/db/migrations/076-scoped-checkpoint-bindings.sql +15 -0
- package/db/migrations/077-legacy-record-kind.sql +6 -0
- package/db/migrations/078-source-ingest-commands.sql +18 -0
- package/db/migrations/079-twin-edge-relations.sql +43 -0
- package/db/migrations/080-restore-duration-days.sql +7 -0
- package/db/migrations/081-mailbox.sql +61 -0
- package/db/migrations/082-commitments-row-id.sql +12 -0
- package/db/migrations/083-observation-is-the-evidence.sql +49 -0
- package/db/migrations/084-scope-kind-is-not-the-cores-to-list.sql +34 -0
- package/db/migrations/085-a-migration-has-a-source.sql +37 -0
- package/db/migrations/086-the-mailbox-is-generic.sql +110 -0
- package/db/migrations/087-mailbox-payload.sql +5 -0
- package/db/migrations/088-native-input-journal.sql +14 -0
- package/db/migrations/089-native-turn-receipt-lookup.sql +3 -0
- package/db/migrations/090-model-run-native-inputs.sql +29 -0
- package/db/migrations/091-native-turn-results.sql +11 -0
- package/db/migrations/092-restore-decision-fts.sql +34 -0
- package/db/migrations/093-native-turn-primary-kind.sql +14 -0
- package/db/migrations/094-commitment-run-provenance.sql +9 -0
- package/db/migrations/095-model-run-native-input-identity.sql +39 -0
- package/db/migrations/096-drop-connector-event-index-fts.sql +9 -0
- package/db/migrations/097-native-input-json-validity.sql +37 -0
- package/db/migrations/098-workflow-memory-kind.sql +105 -0
- package/dist/action-contracts.d.ts +212 -0
- package/dist/action-contracts.js +10 -0
- package/dist/api/catalog.d.ts +118 -0
- package/dist/api/catalog.js +1756 -0
- package/dist/api/dispatch.d.ts +76 -0
- package/dist/api/dispatch.js +372 -0
- package/dist/canonicalize.d.ts +2 -2
- package/dist/canonicalize.js +3 -3
- package/dist/client/client.d.ts +33 -0
- package/dist/client/client.js +123 -0
- package/dist/client/ipc.d.ts +81 -0
- package/dist/client/ipc.js +314 -0
- package/dist/db-adapter/base-adapter.d.ts +6 -66
- package/dist/db-adapter/base-adapter.js +6 -6
- package/dist/db-adapter/index.d.ts +5 -5
- package/dist/db-adapter/index.js +2 -5
- package/dist/db-adapter/node-sqlite-adapter.d.ts +85 -15
- package/dist/db-adapter/node-sqlite-adapter.js +1968 -570
- package/dist/db-manager.d.ts +53 -97
- package/dist/db-manager.js +121 -603
- package/dist/embedding/embedder.d.ts +132 -0
- package/dist/embedding/embedder.js +299 -0
- package/dist/identity/principal-repository.d.ts +2 -2
- package/dist/index.d.ts +43 -58
- package/dist/index.js +97 -145
- package/dist/{context-compile/channel-grant.d.ts → knowledge/access.d.ts} +12 -17
- package/dist/knowledge/access.js +663 -0
- package/dist/knowledge/case-errors.d.ts +31 -0
- package/dist/knowledge/case-errors.js +40 -0
- package/dist/{cases/search-rollup.d.ts → knowledge/case-search-rollup.d.ts} +5 -4
- package/dist/{cases/search-rollup.js → knowledge/case-search-rollup.js} +6 -8
- package/dist/{cases/store.d.ts → knowledge/case-store.d.ts} +3 -6
- package/dist/{cases/store.js → knowledge/case-store.js} +7 -42
- package/dist/{cases/timeline-range.d.ts → knowledge/case-timeline-range.d.ts} +3 -3
- package/dist/{cases/timeline-range.js → knowledge/case-timeline-range.js} +47 -25
- package/dist/{cases/types.d.ts → knowledge/case-types.d.ts} +8 -2
- package/dist/{cases/types.js → knowledge/case-types.js} +1 -1
- package/dist/knowledge/commitments.d.ts +188 -0
- package/dist/knowledge/commitments.js +370 -0
- package/dist/knowledge/decision-edges.d.ts +70 -0
- package/dist/knowledge/decision-edges.js +123 -0
- package/dist/{agent-graph/types.d.ts → knowledge/graph-query.d.ts} +80 -70
- package/dist/knowledge/graph-query.js +1585 -0
- package/dist/knowledge/identity.d.ts +16 -0
- package/dist/knowledge/identity.js +22 -0
- package/dist/knowledge/index.d.ts +47 -0
- package/dist/knowledge/index.js +90 -0
- package/dist/knowledge/judgments.d.ts +118 -0
- package/dist/knowledge/judgments.js +808 -0
- package/dist/knowledge/observations.d.ts +160 -0
- package/dist/knowledge/observations.js +449 -0
- package/dist/knowledge/question-type.d.ts +34 -0
- package/dist/knowledge/question-type.js +70 -0
- package/dist/{search → knowledge}/ranker-features.js +1 -1
- package/dist/{search → knowledge}/search-quality.d.ts +0 -1
- package/dist/knowledge/search.d.ts +38 -0
- package/dist/knowledge/search.js +91 -0
- package/dist/knowledge/source-ingest.d.ts +65 -0
- package/dist/knowledge/source-ingest.js +174 -0
- package/dist/{edges/types.d.ts → knowledge/twin-edge-types.d.ts} +31 -4
- package/dist/{edges/types.js → knowledge/twin-edge-types.js} +13 -2
- package/dist/knowledge/work-dates.d.ts +49 -0
- package/dist/knowledge/work-dates.js +120 -0
- package/dist/mama-api.d.ts +114 -778
- package/dist/mama-api.js +313 -2461
- package/dist/memory/api.d.ts +264 -24
- package/dist/memory/api.js +1633 -843
- package/dist/memory/bootstrap-builder.d.ts +2 -1
- package/dist/memory/bootstrap-builder.js +5 -5
- package/dist/memory/channel-summary-state-store.d.ts +3 -2
- package/dist/memory/channel-summary-state-store.js +53 -51
- package/dist/memory/channel-summary-store.d.ts +5 -3
- package/dist/memory/channel-summary-store.js +3 -8
- package/dist/memory/dashboard-read.d.ts +46 -0
- package/dist/memory/dashboard-read.js +94 -0
- package/dist/memory/event-store.d.ts +3 -3
- package/dist/memory/event-store.js +3 -10
- package/dist/memory/finding-store.d.ts +3 -2
- package/dist/memory/finding-store.js +2 -7
- package/dist/memory/graph-read.d.ts +52 -0
- package/dist/memory/graph-read.js +130 -0
- package/dist/memory/judgment-types.d.ts +394 -0
- package/dist/memory/judgment-types.js +16 -0
- package/dist/memory/provenance-audit.d.ts +5 -2
- package/dist/memory/provenance-audit.js +8 -14
- package/dist/memory/provenance-live.d.ts +141 -0
- package/dist/memory/provenance-live.js +409 -0
- package/dist/memory/provenance-query.d.ts +5 -4
- package/dist/memory/provenance-query.js +21 -29
- package/dist/memory/provenance-resolver.d.ts +191 -0
- package/dist/memory/provenance-resolver.js +155 -0
- package/dist/memory/provenance.d.ts +1 -11
- package/dist/memory/provenance.js +2 -33
- package/dist/memory/recall-sanitize.d.ts +55 -0
- package/dist/memory/recall-sanitize.js +144 -0
- package/dist/memory/secret-filter.d.ts +32 -0
- package/dist/memory/secret-filter.js +126 -0
- package/dist/memory/truth-store.d.ts +2 -1
- package/dist/memory/truth-store.js +1 -4
- package/dist/memory/types.d.ts +74 -24
- package/dist/memory/types.js +75 -5
- package/dist/memory/write-adapters.d.ts +98 -0
- package/dist/memory/write-adapters.js +242 -0
- package/dist/operations/owner-action-effects.d.ts +53 -0
- package/dist/operations/owner-action-effects.js +96 -0
- package/dist/provenance/source-ref.d.ts +1 -1
- package/dist/provenance/source-ref.js +0 -2
- package/dist/registry/corrections.d.ts +31 -0
- package/dist/registry/corrections.js +332 -0
- package/dist/registry/record-identity.d.ts +49 -0
- package/dist/registry/record-identity.js +133 -0
- package/dist/registry/store.d.ts +101 -0
- package/dist/registry/store.js +395 -0
- package/dist/registry/types.d.ts +28 -0
- package/dist/registry/types.js +5 -0
- package/dist/relevance-scorer.js +2 -2
- package/dist/runtime/agent-event-bus.d.ts +50 -0
- package/dist/runtime/agent-event-bus.js +101 -0
- package/dist/runtime/drivers/claude-cli-wrapper.d.ts +155 -0
- package/dist/runtime/drivers/claude-cli-wrapper.js +392 -0
- package/dist/runtime/drivers/cli-arg-redaction.d.ts +2 -0
- package/dist/runtime/drivers/cli-arg-redaction.js +18 -0
- package/dist/runtime/drivers/cli-secret-redaction.d.ts +17 -0
- package/dist/runtime/drivers/cli-secret-redaction.js +126 -0
- package/dist/runtime/drivers/codex-app-server-process.d.ts +277 -0
- package/dist/runtime/drivers/codex-app-server-process.js +2342 -0
- package/dist/runtime/drivers/codex-auxiliary-tools.d.ts +17 -0
- package/dist/runtime/drivers/codex-auxiliary-tools.js +267 -0
- package/dist/runtime/drivers/codex-home.d.ts +20 -0
- package/dist/runtime/drivers/codex-home.js +674 -0
- package/dist/runtime/drivers/codex-thread-registry.d.ts +63 -0
- package/dist/runtime/drivers/codex-thread-registry.js +433 -0
- package/dist/runtime/drivers/persistent-cli-adapter.d.ts +160 -0
- package/dist/runtime/drivers/persistent-cli-adapter.js +396 -0
- package/dist/runtime/drivers/persistent-cli-process.d.ts +424 -0
- package/dist/runtime/drivers/persistent-cli-process.js +1543 -0
- package/dist/runtime/drivers/types.d.ts +456 -0
- package/dist/runtime/drivers/types.js +110 -0
- package/dist/runtime/mailbox.d.ts +223 -0
- package/dist/runtime/mailbox.js +582 -0
- package/dist/runtime/model-run-store.d.ts +28 -0
- package/dist/{model-runs/store.js → runtime/model-run-store.js} +81 -41
- package/dist/{model-runs/types.d.ts → runtime/model-run-types.d.ts} +33 -4
- package/dist/{model-runs/types.js → runtime/model-run-types.js} +1 -1
- package/dist/runtime/native-effect-observer.d.ts +22 -0
- package/dist/runtime/native-effect-observer.js +103 -0
- package/dist/runtime/native-input-journal.d.ts +46 -0
- package/dist/runtime/native-input-journal.js +308 -0
- package/dist/runtime/native-prompt.d.ts +118 -0
- package/dist/runtime/native-prompt.js +496 -0
- package/dist/runtime/native-session.d.ts +10 -0
- package/dist/{agent-graph/index.js → runtime/native-session.js} +9 -6
- package/dist/runtime/native-tool-trace-observer.d.ts +5 -0
- package/dist/runtime/native-tool-trace-observer.js +65 -0
- package/dist/runtime/native-turn.d.ts +272 -0
- package/dist/runtime/native-turn.js +1041 -0
- package/dist/runtime/operations.d.ts +236 -0
- package/dist/runtime/operations.js +565 -0
- package/dist/runtime/post-tool-handler.d.ts +74 -0
- package/dist/runtime/post-tool-handler.js +137 -0
- package/dist/runtime/prompt-layers.d.ts +126 -0
- package/dist/runtime/prompt-layers.js +239 -0
- package/dist/runtime/runtime-process.d.ts +102 -0
- package/dist/runtime/runtime-process.js +206 -0
- package/dist/runtime/runtime.d.ts +278 -0
- package/dist/runtime/runtime.js +563 -0
- package/dist/runtime/session-pool.d.ts +176 -0
- package/dist/runtime/session-pool.js +369 -0
- package/dist/runtime/stimulus-payload.d.ts +5 -0
- package/dist/runtime/stimulus-payload.js +50 -0
- package/dist/runtime/subagent-bridge.d.ts +24 -0
- package/dist/{agent-graph/types.js → runtime/subagent-bridge.js} +1 -1
- package/dist/runtime/text-completion.d.ts +22 -0
- package/dist/{agent-situation/types.js → runtime/text-completion.js} +1 -1
- package/dist/runtime/token-estimator.d.ts +25 -0
- package/dist/runtime/token-estimator.js +75 -0
- package/dist/runtime/tool-trace-store.d.ts +22 -0
- package/dist/{model-runs → runtime}/tool-trace-store.js +46 -27
- package/dist/runtime/trace-summary.d.ts +5 -0
- package/dist/runtime/trace-summary.js +74 -0
- package/dist/runtime/turn-text.d.ts +23 -0
- package/dist/runtime/turn-text.js +41 -0
- package/dist/storage/database.d.ts +67 -0
- package/dist/storage/database.js +158 -0
- package/package.json +20 -34
- package/dist/agent-graph/alias-write.d.ts +0 -3
- package/dist/agent-graph/alias-write.js +0 -234
- package/dist/agent-graph/entity-resolve.d.ts +0 -3
- package/dist/agent-graph/entity-resolve.js +0 -271
- package/dist/agent-graph/errors.d.ts +0 -4
- package/dist/agent-graph/errors.js +0 -11
- package/dist/agent-graph/graph-query.d.ts +0 -5
- package/dist/agent-graph/graph-query.js +0 -360
- package/dist/agent-graph/index.d.ts +0 -6
- package/dist/agent-situation/builder.d.ts +0 -8
- package/dist/agent-situation/builder.js +0 -239
- package/dist/agent-situation/cache-key.d.ts +0 -4
- package/dist/agent-situation/cache-key.js +0 -64
- package/dist/agent-situation/index.d.ts +0 -7
- package/dist/agent-situation/index.js +0 -28
- package/dist/agent-situation/packet-store.d.ts +0 -27
- package/dist/agent-situation/packet-store.js +0 -228
- package/dist/agent-situation/ranking-policy.d.ts +0 -18
- package/dist/agent-situation/ranking-policy.js +0 -75
- package/dist/agent-situation/source-readers.d.ts +0 -52
- package/dist/agent-situation/source-readers.js +0 -300
- package/dist/agent-situation/types.d.ts +0 -195
- package/dist/cases/wiki-page-index.d.ts +0 -37
- package/dist/cases/wiki-page-index.js +0 -201
- package/dist/config-loader.d.ts +0 -68
- package/dist/config-loader.js +0 -239
- package/dist/connectors/event-index.d.ts +0 -24
- package/dist/connectors/event-index.js +0 -245
- package/dist/connectors/raw-query.d.ts +0 -40
- package/dist/connectors/raw-query.js +0 -412
- package/dist/connectors/types.d.ts +0 -117
- package/dist/connectors/types.js +0 -3
- package/dist/context-compile/boundary-defaults.d.ts +0 -12
- package/dist/context-compile/boundary-defaults.js +0 -105
- package/dist/context-compile/channel-grant.js +0 -66
- package/dist/context-compile/compiler-policy.d.ts +0 -39
- package/dist/context-compile/compiler-policy.js +0 -147
- package/dist/context-compile/compiler.d.ts +0 -18
- package/dist/context-compile/compiler.js +0 -404
- package/dist/context-compile/index.d.ts +0 -10
- package/dist/context-compile/index.js +0 -26
- package/dist/context-compile/packet-store.d.ts +0 -8
- package/dist/context-compile/packet-store.js +0 -239
- package/dist/context-compile/ref.d.ts +0 -7
- package/dist/context-compile/ref.js +0 -102
- package/dist/context-compile/source-readers.d.ts +0 -70
- package/dist/context-compile/source-readers.js +0 -840
- package/dist/context-compile/types.d.ts +0 -155
- package/dist/context-compile/types.js +0 -11
- package/dist/context-compile/visibility.d.ts +0 -21
- package/dist/context-compile/visibility.js +0 -224
- package/dist/decision-tracker.d.ts +0 -206
- package/dist/decision-tracker.js +0 -481
- package/dist/edges/ref-validation.d.ts +0 -7
- package/dist/edges/ref-validation.js +0 -321
- package/dist/edges/store.d.ts +0 -8
- package/dist/edges/store.js +0 -129
- package/dist/embedding-client.d.ts +0 -28
- package/dist/embedding-client.js +0 -53
- package/dist/embedding-server/index.d.ts +0 -67
- package/dist/embedding-server/index.js +0 -405
- package/dist/embedding-server/mobile/auth.d.ts +0 -44
- package/dist/embedding-server/mobile/auth.js +0 -150
- package/dist/embedding-server/mobile/daemon.d.ts +0 -129
- package/dist/embedding-server/mobile/daemon.js +0 -313
- package/dist/embedding-server/mobile/output-parser.d.ts +0 -115
- package/dist/embedding-server/mobile/output-parser.js +0 -241
- package/dist/embedding-server/mobile/session-api.d.ts +0 -57
- package/dist/embedding-server/mobile/session-api.js +0 -261
- package/dist/embedding-server/mobile/session-manager.d.ts +0 -138
- package/dist/embedding-server/mobile/session-manager.js +0 -378
- package/dist/embedding-server/mobile/websocket-handler.d.ts +0 -137
- package/dist/embedding-server/mobile/websocket-handler.js +0 -486
- package/dist/embeddings.d.ts +0 -68
- package/dist/embeddings.js +0 -244
- package/dist/entities/audit-metrics.d.ts +0 -68
- package/dist/entities/audit-metrics.js +0 -124
- package/dist/entities/candidate-generator.d.ts +0 -8
- package/dist/entities/candidate-generator.js +0 -24
- package/dist/entities/entity-linked-decision-counts.d.ts +0 -2
- package/dist/entities/entity-linked-decision-counts.js +0 -29
- package/dist/entities/entity-list.d.ts +0 -22
- package/dist/entities/entity-list.js +0 -3
- package/dist/entities/entity-orphan-list.d.ts +0 -17
- package/dist/entities/entity-orphan-list.js +0 -3
- package/dist/entities/entity-search.d.ts +0 -20
- package/dist/entities/entity-search.js +0 -3
- package/dist/entities/errors.d.ts +0 -55
- package/dist/entities/errors.js +0 -100
- package/dist/entities/lineage-store.d.ts +0 -28
- package/dist/entities/lineage-store.js +0 -204
- package/dist/entities/normalization.d.ts +0 -14
- package/dist/entities/normalization.js +0 -63
- package/dist/entities/policy-store.d.ts +0 -8
- package/dist/entities/policy-store.js +0 -75
- package/dist/entities/policy-types.d.ts +0 -72
- package/dist/entities/policy-types.js +0 -59
- package/dist/entities/projection.d.ts +0 -8
- package/dist/entities/projection.js +0 -82
- package/dist/entities/provenance-query.d.ts +0 -32
- package/dist/entities/provenance-query.js +0 -3
- package/dist/entities/read-identity.d.ts +0 -31
- package/dist/entities/read-identity.js +0 -264
- package/dist/entities/recall-bridge.d.ts +0 -5
- package/dist/entities/recall-bridge.js +0 -171
- package/dist/entities/resolution-engine.d.ts +0 -8
- package/dist/entities/resolution-engine.js +0 -3
- package/dist/entities/rollback-preview.d.ts +0 -35
- package/dist/entities/rollback-preview.js +0 -3
- package/dist/entities/source-locator.d.ts +0 -3
- package/dist/entities/source-locator.js +0 -32
- package/dist/entities/store.d.ts +0 -69
- package/dist/entities/store.js +0 -544
- package/dist/entities/types.d.ts +0 -166
- package/dist/entities/types.js +0 -30
- package/dist/memory/extraction-prompt.d.ts +0 -4
- package/dist/memory/extraction-prompt.js +0 -89
- package/dist/memory/scope-backfill.d.ts +0 -14
- package/dist/memory/scope-backfill.js +0 -3
- package/dist/memory/scope-store.d.ts +0 -4
- package/dist/memory/scope-store.js +0 -9
- package/dist/memory-store.d.ts +0 -87
- package/dist/memory-store.js +0 -78
- package/dist/model-runs/store.d.ts +0 -13
- package/dist/model-runs/tool-trace-store.d.ts +0 -8
- package/dist/notification-manager.d.ts +0 -7
- package/dist/notification-manager.js +0 -12
- package/dist/outcome-tracker.d.ts +0 -151
- package/dist/outcome-tracker.js +0 -271
- package/dist/query-intent.d.ts +0 -23
- package/dist/query-intent.js +0 -114
- package/dist/runtime/trusted-provenance.d.ts +0 -3
- package/dist/runtime/trusted-provenance.js +0 -6
- package/dist/search/question-type.d.ts +0 -5
- package/dist/search/question-type.js +0 -41
- package/dist/test-utils.d.ts +0 -80
- package/dist/test-utils.js +0 -218
- package/dist/tier-validator.d.ts +0 -43
- package/dist/tier-validator.js +0 -159
- package/dist/time-formatter.d.ts +0 -25
- package/dist/time-formatter.js +0 -93
- /package/dist/{search → knowledge}/feedback-store.d.ts +0 -0
- /package/dist/{search → knowledge}/feedback-store.js +0 -0
- /package/dist/{search → knowledge}/ranker-features.d.ts +0 -0
- /package/dist/{search → knowledge}/ranker-rescore.d.ts +0 -0
- /package/dist/{search → knowledge}/ranker-rescore.js +0 -0
- /package/dist/{search → knowledge}/ranker-trainer.d.ts +0 -0
- /package/dist/{search → knowledge}/ranker-trainer.js +0 -0
- /package/dist/{search → knowledge}/search-quality.js +0 -0
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Reading owner work back out of the commitment log.
|
|
4
|
+
*
|
|
5
|
+
* `appendJudgment` has written `commitments` and `commitment_assignments` since
|
|
6
|
+
* migration 075: a commitment row carries identity, the current revision and the
|
|
7
|
+
* head record, and one assignment row per revision carries the patch that
|
|
8
|
+
* revision applied. Nothing read them back. The only SELECT against either table
|
|
9
|
+
* was the writer's own CAS check, so the substrate could be written and never
|
|
10
|
+
* answered from - the shape this refactor exists to close.
|
|
11
|
+
*
|
|
12
|
+
* Current values are a fold, not a column. Each assignment states `set` and
|
|
13
|
+
* `clear` for that revision only, and the view is those applied in revision
|
|
14
|
+
* order. That is what keeps a correction from erasing what it corrected: the
|
|
15
|
+
* revision that changed a title is still readable next to the one that set it,
|
|
16
|
+
* and `history: 'all'` returns them.
|
|
17
|
+
*
|
|
18
|
+
* @module knowledge/commitments
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.readWork = readWork;
|
|
22
|
+
exports.createWork = createWork;
|
|
23
|
+
exports.reviseWork = reviseWork;
|
|
24
|
+
exports.withdrawWork = withdrawWork;
|
|
25
|
+
const judgments_js_1 = require("./judgments.js");
|
|
26
|
+
const work_dates_js_1 = require("./work-dates.js");
|
|
27
|
+
const DEFAULT_LIMIT = 25;
|
|
28
|
+
const MAX_LIMIT = 100;
|
|
29
|
+
function parseLimit(value) {
|
|
30
|
+
if (value === undefined)
|
|
31
|
+
return DEFAULT_LIMIT;
|
|
32
|
+
if (!Number.isSafeInteger(value) || value < 1 || value > MAX_LIMIT) {
|
|
33
|
+
throw new judgments_js_1.JudgmentError('INVALID_COMMAND', `limit must be an integer from 1 to ${MAX_LIMIT}`);
|
|
34
|
+
}
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
function parseCursor(value) {
|
|
38
|
+
if (value === undefined)
|
|
39
|
+
return 0;
|
|
40
|
+
const afterTaskId = Number(value);
|
|
41
|
+
if (!Number.isSafeInteger(afterTaskId) || afterTaskId < 0) {
|
|
42
|
+
throw new judgments_js_1.JudgmentError('INVALID_COMMAND', 'cursor is not a commitment page cursor');
|
|
43
|
+
}
|
|
44
|
+
return afterTaskId;
|
|
45
|
+
}
|
|
46
|
+
function parseAsOf(value) {
|
|
47
|
+
if (value === undefined)
|
|
48
|
+
return null;
|
|
49
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
50
|
+
throw new judgments_js_1.JudgmentError('INVALID_COMMAND', 'asOf must be an epoch millisecond integer');
|
|
51
|
+
}
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
function parsePatch(json, field) {
|
|
55
|
+
const parsed = JSON.parse(json);
|
|
56
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
57
|
+
throw new judgments_js_1.JudgmentError('INVALID_COMMAND', `${field} is not a work patch object`);
|
|
58
|
+
}
|
|
59
|
+
return parsed;
|
|
60
|
+
}
|
|
61
|
+
function parseClear(json) {
|
|
62
|
+
const parsed = JSON.parse(json);
|
|
63
|
+
if (!Array.isArray(parsed)) {
|
|
64
|
+
throw new judgments_js_1.JudgmentError('INVALID_COMMAND', 'clear_json is not a field list');
|
|
65
|
+
}
|
|
66
|
+
return parsed;
|
|
67
|
+
}
|
|
68
|
+
function applyRevision(values, revision) {
|
|
69
|
+
for (const [field, value] of Object.entries(revision.set)) {
|
|
70
|
+
values[field] = value;
|
|
71
|
+
}
|
|
72
|
+
for (const field of revision.clear) {
|
|
73
|
+
delete values[field];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Fold the assignments into the values they leave behind.
|
|
78
|
+
*
|
|
79
|
+
* `clear` is applied after `set` within one revision: a revision that sets and
|
|
80
|
+
* clears the same field is stating that the field ends the revision absent,
|
|
81
|
+
* which is what the writer's own ordering already means.
|
|
82
|
+
*/
|
|
83
|
+
function foldAssignments(revisions) {
|
|
84
|
+
const values = {};
|
|
85
|
+
for (const revision of revisions) {
|
|
86
|
+
applyRevision(values, revision);
|
|
87
|
+
}
|
|
88
|
+
return values;
|
|
89
|
+
}
|
|
90
|
+
function stringField(values, field) {
|
|
91
|
+
const value = values[field];
|
|
92
|
+
return typeof value === 'string' ? value : null;
|
|
93
|
+
}
|
|
94
|
+
/** A revision's summary, only when its record is visible to the caller. */
|
|
95
|
+
function readJudgmentSummary(adapter, recordId, admitted) {
|
|
96
|
+
if (!recordVisible(adapter, recordId, admitted))
|
|
97
|
+
return null;
|
|
98
|
+
const row = adapter.prepare('SELECT summary FROM decisions WHERE id = ?').get(recordId);
|
|
99
|
+
return row && typeof row.summary === 'string' ? row.summary : null;
|
|
100
|
+
}
|
|
101
|
+
function buildChain(adapter, revisions, admitted) {
|
|
102
|
+
const values = {};
|
|
103
|
+
return revisions.map((revision) => {
|
|
104
|
+
applyRevision(values, revision);
|
|
105
|
+
return {
|
|
106
|
+
revision: revision.revision,
|
|
107
|
+
operation: revision.operation,
|
|
108
|
+
eventDatetime: revision.eventDatetime,
|
|
109
|
+
status: revision.operation === 'withdraw' ? 'cancelled' : stringField(values, 'status'),
|
|
110
|
+
stage: stringField(values, 'stage'),
|
|
111
|
+
summary: readJudgmentSummary(adapter, revision.recordRef.id, admitted),
|
|
112
|
+
};
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Whether the caller may read this commitment.
|
|
117
|
+
*
|
|
118
|
+
* A commitment carries no scope of its own; its head record does, through the
|
|
119
|
+
* same `memory_scope_bindings` every judgment read uses. An unbound record has
|
|
120
|
+
* no partition boundary to violate and stays readable, exactly as
|
|
121
|
+
* `referenceExists` decides it for a memory ref.
|
|
122
|
+
*/
|
|
123
|
+
function recordVisible(adapter, recordId, admitted) {
|
|
124
|
+
const row = adapter
|
|
125
|
+
.prepare('SELECT COUNT(*) AS bindings FROM memory_scope_bindings WHERE memory_id = ?')
|
|
126
|
+
.get(recordId);
|
|
127
|
+
if (!row)
|
|
128
|
+
return false;
|
|
129
|
+
if (row.bindings === 0)
|
|
130
|
+
return true;
|
|
131
|
+
if (admitted.length === 0)
|
|
132
|
+
return false;
|
|
133
|
+
const placeholders = admitted.map(() => '?').join(', ');
|
|
134
|
+
return (adapter
|
|
135
|
+
.prepare(`SELECT 1 FROM memory_scope_bindings
|
|
136
|
+
WHERE memory_id = ? AND scope_id IN (${placeholders}) LIMIT 1`)
|
|
137
|
+
.get(recordId, ...admitted) !== undefined);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Read owner work: one commitment, or a bounded page of them.
|
|
141
|
+
*
|
|
142
|
+
* `asOf` folds revisions by their source event time when recorded, or by the
|
|
143
|
+
* commit clock for judgments without an event time. A backfill committed today
|
|
144
|
+
* can therefore answer what was current at a historical instant. A commitment
|
|
145
|
+
* whose first revision is later than `asOf` is absent, not empty.
|
|
146
|
+
*/
|
|
147
|
+
function readWork(adapter, query, access) {
|
|
148
|
+
const admitted = (0, judgments_js_1.admittedScopeIds)(access);
|
|
149
|
+
const limit = parseLimit(query.limit);
|
|
150
|
+
const afterTaskId = parseCursor(query.cursor);
|
|
151
|
+
const asOf = parseAsOf(query.asOf);
|
|
152
|
+
const wantsHistory = query.history === 'all';
|
|
153
|
+
const wantsChain = query.history === 'chain';
|
|
154
|
+
if (query.history !== undefined &&
|
|
155
|
+
query.history !== 'all' &&
|
|
156
|
+
query.history !== 'current' &&
|
|
157
|
+
query.history !== 'chain') {
|
|
158
|
+
throw new judgments_js_1.JudgmentError('INVALID_COMMAND', "history must be 'current', 'chain', or 'all'");
|
|
159
|
+
}
|
|
160
|
+
if (query.commitmentId !== undefined && query.rowId !== undefined) {
|
|
161
|
+
throw new judgments_js_1.JudgmentError('INVALID_COMMAND', 'Ask by commitmentId or rowId, not both');
|
|
162
|
+
}
|
|
163
|
+
const reasons = [];
|
|
164
|
+
let rows;
|
|
165
|
+
let total = null;
|
|
166
|
+
if (query.commitmentId !== undefined) {
|
|
167
|
+
rows = adapter
|
|
168
|
+
.prepare('SELECT * FROM commitments WHERE commitment_id = ?')
|
|
169
|
+
.all(query.commitmentId);
|
|
170
|
+
}
|
|
171
|
+
else if (query.rowId !== undefined) {
|
|
172
|
+
rows = adapter
|
|
173
|
+
.prepare('SELECT * FROM commitments WHERE row_id = ?')
|
|
174
|
+
.all(query.rowId);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
// One extra row decides whether another page exists without a second count.
|
|
178
|
+
rows = adapter
|
|
179
|
+
.prepare('SELECT * FROM commitments WHERE row_id > ? ORDER BY row_id ASC LIMIT ?')
|
|
180
|
+
.all(afterTaskId, limit + 1);
|
|
181
|
+
total = adapter.prepare('SELECT COUNT(*) AS n FROM commitments').get().n;
|
|
182
|
+
}
|
|
183
|
+
const hasMore = query.commitmentId === undefined && query.rowId === undefined ? rows.length > limit : false;
|
|
184
|
+
const pageRows = hasMore ? rows.slice(0, limit) : rows;
|
|
185
|
+
const items = [];
|
|
186
|
+
let scopeHidden = 0;
|
|
187
|
+
for (const row of pageRows) {
|
|
188
|
+
if (!recordVisible(adapter, row.head_record_id, admitted)) {
|
|
189
|
+
scopeHidden += 1;
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
const assignments = adapter
|
|
193
|
+
.prepare(asOf === null
|
|
194
|
+
? `SELECT assignment.*, judgment.event_datetime AS judgment_event_datetime
|
|
195
|
+
FROM commitment_assignments assignment
|
|
196
|
+
JOIN decisions judgment ON judgment.id = assignment.record_id
|
|
197
|
+
WHERE assignment.commitment_id = ? ORDER BY assignment.revision ASC`
|
|
198
|
+
: `SELECT assignment.*, judgment.event_datetime AS judgment_event_datetime FROM commitment_assignments assignment
|
|
199
|
+
JOIN decisions judgment ON judgment.id = assignment.record_id
|
|
200
|
+
WHERE assignment.commitment_id = ?
|
|
201
|
+
AND COALESCE(assignment.applies_from, judgment.event_datetime, assignment.created_at) <= ?
|
|
202
|
+
ORDER BY assignment.revision ASC`)
|
|
203
|
+
.all(...(asOf === null ? [row.commitment_id] : [row.commitment_id, asOf]));
|
|
204
|
+
if (assignments.length === 0) {
|
|
205
|
+
// Bounded away entirely: the commitment had not been created at `asOf`.
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
const revisions = assignments.map((assignment) => ({
|
|
209
|
+
revision: assignment.revision,
|
|
210
|
+
operation: assignment.operation,
|
|
211
|
+
recordRef: { kind: 'memory', id: assignment.record_id },
|
|
212
|
+
set: parsePatch(assignment.set_json, 'set_json'),
|
|
213
|
+
clear: parseClear(assignment.clear_json),
|
|
214
|
+
eventDatetime: assignment.applies_from ?? assignment.judgment_event_datetime ?? null,
|
|
215
|
+
createdAt: assignment.created_at,
|
|
216
|
+
}));
|
|
217
|
+
const head = revisions[revisions.length - 1];
|
|
218
|
+
items.push({
|
|
219
|
+
commitmentId: row.commitment_id,
|
|
220
|
+
rowId: row.row_id,
|
|
221
|
+
revision: head.revision,
|
|
222
|
+
latestJudgmentRef: head.recordRef,
|
|
223
|
+
values: foldAssignments(revisions),
|
|
224
|
+
withdrawn: revisions.some((revision) => revision.operation === 'withdraw'),
|
|
225
|
+
basis: revisions.map((revision) => revision.recordRef),
|
|
226
|
+
createdAt: row.created_at,
|
|
227
|
+
updatedAt: asOf === null ? row.updated_at : (head.eventDatetime ?? head.createdAt),
|
|
228
|
+
...(wantsHistory ? { history: revisions } : {}),
|
|
229
|
+
...(wantsChain ? { chain: buildChain(adapter, revisions, admitted) } : {}),
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
if (hasMore) {
|
|
233
|
+
reasons.push('more commitments follow this page');
|
|
234
|
+
}
|
|
235
|
+
if (scopeHidden > 0) {
|
|
236
|
+
// Named, never silent: a page short by rows the caller cannot read is a
|
|
237
|
+
// different answer from a page that is short because there is no more work.
|
|
238
|
+
reasons.push(`${scopeHidden} commitment(s) outside the caller's scopes`);
|
|
239
|
+
}
|
|
240
|
+
if (asOf !== null) {
|
|
241
|
+
reasons.push(`bounded to revisions effective at or before ${asOf}`);
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
items,
|
|
245
|
+
nextCursor: hasMore ? String(pageRows[pageRows.length - 1].row_id) : null,
|
|
246
|
+
coverage: {
|
|
247
|
+
returned: items.length,
|
|
248
|
+
total,
|
|
249
|
+
complete: !hasMore && scopeHidden === 0,
|
|
250
|
+
reasons,
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* The record half of a work command, with absent fields omitted rather than set
|
|
256
|
+
* to `undefined`.
|
|
257
|
+
*
|
|
258
|
+
* The command payload is canonicalized and hashed into `command_bindings`, and
|
|
259
|
+
* the canonicalizer rejects an explicit `undefined` - correctly, since a key
|
|
260
|
+
* present with no value and a key absent are different payloads and must not
|
|
261
|
+
* hash alike.
|
|
262
|
+
*/
|
|
263
|
+
function recordFields(command) {
|
|
264
|
+
return {
|
|
265
|
+
commandId: command.commandId,
|
|
266
|
+
...(command.modelRunId === undefined ? {} : { modelRunId: command.modelRunId }),
|
|
267
|
+
topic: command.topic,
|
|
268
|
+
summary: command.summary,
|
|
269
|
+
recordKind: 'commitment',
|
|
270
|
+
...(command.reasoning === undefined ? {} : { reasoning: command.reasoning }),
|
|
271
|
+
...(command.scopes === undefined ? {} : { scopes: command.scopes }),
|
|
272
|
+
...(command.sourceRefs === undefined ? {} : { sourceRefs: command.sourceRefs }),
|
|
273
|
+
...(command.links === undefined ? {} : { links: command.links }),
|
|
274
|
+
...(command.eventDatetime === undefined ? {} : { eventDatetime: command.eventDatetime }),
|
|
275
|
+
...(command.recordedAt === undefined ? {} : { recordedAt: command.recordedAt }),
|
|
276
|
+
...(command.event === undefined ? {} : { event: command.event }),
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
function requireWorkReceipt(receipt) {
|
|
280
|
+
if (!receipt.work) {
|
|
281
|
+
// appendJudgment writes the commitment inside the same transaction as the
|
|
282
|
+
// record, so a receipt without one means the command was not a commitment.
|
|
283
|
+
throw new judgments_js_1.JudgmentError('INVALID_COMMAND', 'The judgment carried no commitment receipt');
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
commitmentId: receipt.work.commitmentId,
|
|
287
|
+
revision: receipt.work.revision,
|
|
288
|
+
recordRef: { kind: 'memory', id: receipt.recordId },
|
|
289
|
+
receipt,
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Commit new owner work.
|
|
294
|
+
*
|
|
295
|
+
* The work and the record that states it commit together: `appendJudgment` owns
|
|
296
|
+
* the transaction, and this is the vocabulary in front of it. A caller that
|
|
297
|
+
* wrote a task row here and a record there is the split this replaces.
|
|
298
|
+
*/
|
|
299
|
+
async function createWork(command, access, options) {
|
|
300
|
+
(0, work_dates_js_1.assertWorkPatchValues)(command.set);
|
|
301
|
+
const receipt = await (0, judgments_js_1.appendJudgment)({
|
|
302
|
+
...recordFields(command),
|
|
303
|
+
work: {
|
|
304
|
+
operation: 'create',
|
|
305
|
+
set: command.set,
|
|
306
|
+
...(command.imported === undefined ? {} : { imported: command.imported }),
|
|
307
|
+
},
|
|
308
|
+
}, access, options);
|
|
309
|
+
return requireWorkReceipt(receipt);
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Revise owner work at an expected revision.
|
|
313
|
+
*
|
|
314
|
+
* The revision is the caller's claim about what it read. A concurrent write
|
|
315
|
+
* moves it and this fails loudly rather than overwriting what the caller never
|
|
316
|
+
* saw - the same compare-and-set the ledger it replaces performed.
|
|
317
|
+
*/
|
|
318
|
+
async function reviseWork(command, access, options) {
|
|
319
|
+
const statesNothing = command.set === undefined &&
|
|
320
|
+
(command.clear === undefined || command.clear.length === 0) &&
|
|
321
|
+
(command.links === undefined || command.links.length === 0);
|
|
322
|
+
if (statesNothing) {
|
|
323
|
+
throw new judgments_js_1.JudgmentError('INVALID_COMMAND', 'A revision must set, clear, or link at least one field');
|
|
324
|
+
}
|
|
325
|
+
if (command.set !== undefined) {
|
|
326
|
+
(0, work_dates_js_1.assertWorkPatchValues)(command.set);
|
|
327
|
+
}
|
|
328
|
+
// A revision is the caller's claim about what it read; a commitment it cannot
|
|
329
|
+
// see is one it cannot name. The read gate answers 'unavailable' rather than
|
|
330
|
+
// 'denied' so an outside-scope id probes the same silence as a wrong one.
|
|
331
|
+
if (readWork(options.adapter, { commitmentId: command.commitmentId }, access).items.length === 0) {
|
|
332
|
+
throw new judgments_js_1.JudgmentError('REFERENCE_NOT_FOUND', `Commitment is unavailable: ${command.commitmentId}`);
|
|
333
|
+
}
|
|
334
|
+
const receipt = await (0, judgments_js_1.appendJudgment)({
|
|
335
|
+
...recordFields(command),
|
|
336
|
+
work: {
|
|
337
|
+
operation: 'revise',
|
|
338
|
+
commitmentId: command.commitmentId,
|
|
339
|
+
...(command.expectedRevision === undefined
|
|
340
|
+
? {}
|
|
341
|
+
: { expectedRevision: command.expectedRevision }),
|
|
342
|
+
...(command.set === undefined ? {} : { set: command.set }),
|
|
343
|
+
...(command.clear === undefined ? {} : { clear: command.clear }),
|
|
344
|
+
},
|
|
345
|
+
}, access, options);
|
|
346
|
+
return requireWorkReceipt(receipt);
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Withdraw owner work.
|
|
350
|
+
*
|
|
351
|
+
* Withdrawal is a revision like any other: the values stay readable and the
|
|
352
|
+
* commitment is marked. Nothing is deleted, so a withdrawn commitment can still
|
|
353
|
+
* answer what it held and who withdrew it.
|
|
354
|
+
*/
|
|
355
|
+
async function withdrawWork(command, access, options) {
|
|
356
|
+
// Same gate as a revision: withdrawal is a claim about what the caller read.
|
|
357
|
+
if (readWork(options.adapter, { commitmentId: command.commitmentId }, access).items.length === 0) {
|
|
358
|
+
throw new judgments_js_1.JudgmentError('REFERENCE_NOT_FOUND', `Commitment is unavailable: ${command.commitmentId}`);
|
|
359
|
+
}
|
|
360
|
+
const receipt = await (0, judgments_js_1.appendJudgment)({
|
|
361
|
+
...recordFields(command),
|
|
362
|
+
work: {
|
|
363
|
+
operation: 'withdraw',
|
|
364
|
+
commitmentId: command.commitmentId,
|
|
365
|
+
expectedRevision: command.expectedRevision,
|
|
366
|
+
},
|
|
367
|
+
}, access, options);
|
|
368
|
+
return requireWorkReceipt(receipt);
|
|
369
|
+
}
|
|
370
|
+
//# sourceMappingURL=commitments.js.map
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { DatabaseAdapter } from '../db-manager.js';
|
|
2
|
+
/**
|
|
3
|
+
* decision_edges + link_audit_log write boundary.
|
|
4
|
+
*
|
|
5
|
+
* Every mutation of the decision-edge graph goes through this module, so
|
|
6
|
+
* `decision_edges` and `link_audit_log` each have exactly one writing module
|
|
7
|
+
* inside `knowledge/` (the sibling judgments.ts owns the judgment-command
|
|
8
|
+
* edge insert). Each function performs the edge change and its audit row
|
|
9
|
+
* inside ONE adapter transaction - a link write and its audit row commit or
|
|
10
|
+
* fail together.
|
|
11
|
+
*/
|
|
12
|
+
type EdgeWriter = Pick<DatabaseAdapter, 'prepare' | 'transaction'>;
|
|
13
|
+
export interface DecisionEdgeKey {
|
|
14
|
+
fromId: string;
|
|
15
|
+
toId: string;
|
|
16
|
+
relationship: string;
|
|
17
|
+
}
|
|
18
|
+
export interface DecisionEdgeRow extends DecisionEdgeKey {
|
|
19
|
+
reason: string | null;
|
|
20
|
+
createdBy: string | null;
|
|
21
|
+
approvedByUser: number | null;
|
|
22
|
+
decisionId: string | null;
|
|
23
|
+
evidence: string | null;
|
|
24
|
+
createdAt: number | null;
|
|
25
|
+
}
|
|
26
|
+
export interface ProposedDecisionEdge extends DecisionEdgeKey {
|
|
27
|
+
reason: string;
|
|
28
|
+
decisionId: string | null;
|
|
29
|
+
evidence: string | null;
|
|
30
|
+
}
|
|
31
|
+
export interface DecisionEdgeDeleteFailure {
|
|
32
|
+
link: string;
|
|
33
|
+
error: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Insert-or-replace one decision edge row with explicit governance columns.
|
|
37
|
+
* Used by the public createEdge API (createdBy 'llm', approvedByUser 1) and by
|
|
38
|
+
* the backup-restore path (columns replayed from the backup file).
|
|
39
|
+
*/
|
|
40
|
+
export declare function upsertDecisionEdge(adapter: EdgeWriter, edge: DecisionEdgeRow): void;
|
|
41
|
+
/**
|
|
42
|
+
* Record a proposed edge pending user approval, plus its 'proposed' audit row.
|
|
43
|
+
*/
|
|
44
|
+
export declare function proposeDecisionEdge(adapter: EdgeWriter, edge: ProposedDecisionEdge): void;
|
|
45
|
+
/**
|
|
46
|
+
* Approve a pending edge, plus its 'approved' audit row.
|
|
47
|
+
*/
|
|
48
|
+
export declare function approveDecisionEdge(adapter: EdgeWriter, key: DecisionEdgeKey): void;
|
|
49
|
+
/**
|
|
50
|
+
* Reject a proposed edge: the 'rejected' audit row is written before the edge
|
|
51
|
+
* is deleted, in the same transaction.
|
|
52
|
+
*/
|
|
53
|
+
export declare function rejectDecisionEdge(adapter: EdgeWriter, key: DecisionEdgeKey, reason: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Remove the auto-generated edge population (created_by='user' with no
|
|
56
|
+
* proposal context) and record one 'deprecated' audit row per removed link.
|
|
57
|
+
* `links` is the already-scanned target set; it only feeds the audit rows.
|
|
58
|
+
*/
|
|
59
|
+
export declare function deprecateAutoDecisionEdges(adapter: EdgeWriter, links: readonly DecisionEdgeKey[], reason: string): void;
|
|
60
|
+
/**
|
|
61
|
+
* Delete one batch of edges, writing a 'deprecated' audit row for each. A
|
|
62
|
+
* per-link failure is collected and the batch continues, matching the cleanup
|
|
63
|
+
* tool's accounting; a failure of the batch itself throws to the caller.
|
|
64
|
+
*/
|
|
65
|
+
export declare function deleteDecisionEdgesWithAudit(adapter: EdgeWriter, links: readonly DecisionEdgeKey[], reason: string): {
|
|
66
|
+
deleted: number;
|
|
67
|
+
failures: DecisionEdgeDeleteFailure[];
|
|
68
|
+
};
|
|
69
|
+
export {};
|
|
70
|
+
//# sourceMappingURL=decision-edges.d.ts.map
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.upsertDecisionEdge = upsertDecisionEdge;
|
|
4
|
+
exports.proposeDecisionEdge = proposeDecisionEdge;
|
|
5
|
+
exports.approveDecisionEdge = approveDecisionEdge;
|
|
6
|
+
exports.rejectDecisionEdge = rejectDecisionEdge;
|
|
7
|
+
exports.deprecateAutoDecisionEdges = deprecateAutoDecisionEdges;
|
|
8
|
+
exports.deleteDecisionEdgesWithAudit = deleteDecisionEdgesWithAudit;
|
|
9
|
+
/**
|
|
10
|
+
* Insert-or-replace one decision edge row with explicit governance columns.
|
|
11
|
+
* Used by the public createEdge API (createdBy 'llm', approvedByUser 1) and by
|
|
12
|
+
* the backup-restore path (columns replayed from the backup file).
|
|
13
|
+
*/
|
|
14
|
+
function upsertDecisionEdge(adapter, edge) {
|
|
15
|
+
adapter
|
|
16
|
+
.prepare(`INSERT OR REPLACE INTO decision_edges
|
|
17
|
+
(from_id, to_id, relationship, reason, created_by, approved_by_user, decision_id, evidence, created_at)
|
|
18
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
19
|
+
.run(edge.fromId, edge.toId, edge.relationship, edge.reason, edge.createdBy, edge.approvedByUser, edge.decisionId, edge.evidence, edge.createdAt);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Record a proposed edge pending user approval, plus its 'proposed' audit row.
|
|
23
|
+
*/
|
|
24
|
+
function proposeDecisionEdge(adapter, edge) {
|
|
25
|
+
adapter.transaction(() => {
|
|
26
|
+
adapter
|
|
27
|
+
.prepare(`INSERT INTO decision_edges
|
|
28
|
+
(from_id, to_id, relationship, reason, created_by, approved_by_user, decision_id, evidence, created_at)
|
|
29
|
+
VALUES (?, ?, ?, ?, 'llm', 0, ?, ?, ?)`)
|
|
30
|
+
.run(edge.fromId, edge.toId, edge.relationship, edge.reason, edge.decisionId, edge.evidence, Date.now());
|
|
31
|
+
adapter
|
|
32
|
+
.prepare(`INSERT INTO link_audit_log (from_id, to_id, relationship, action, actor, reason, created_at)
|
|
33
|
+
VALUES (?, ?, ?, 'proposed', 'llm', ?, ?)`)
|
|
34
|
+
.run(edge.fromId, edge.toId, edge.relationship, edge.reason, Date.now());
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Approve a pending edge, plus its 'approved' audit row.
|
|
39
|
+
*/
|
|
40
|
+
function approveDecisionEdge(adapter, key) {
|
|
41
|
+
adapter.transaction(() => {
|
|
42
|
+
adapter
|
|
43
|
+
.prepare(`UPDATE decision_edges
|
|
44
|
+
SET approved_by_user = 1, approved_at = ?
|
|
45
|
+
WHERE from_id = ? AND to_id = ? AND relationship = ?`)
|
|
46
|
+
.run(Date.now(), key.fromId, key.toId, key.relationship);
|
|
47
|
+
adapter
|
|
48
|
+
.prepare(`INSERT INTO link_audit_log (from_id, to_id, relationship, action, actor, created_at)
|
|
49
|
+
VALUES (?, ?, ?, 'approved', 'user', ?)`)
|
|
50
|
+
.run(key.fromId, key.toId, key.relationship, Date.now());
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Reject a proposed edge: the 'rejected' audit row is written before the edge
|
|
55
|
+
* is deleted, in the same transaction.
|
|
56
|
+
*/
|
|
57
|
+
function rejectDecisionEdge(adapter, key, reason) {
|
|
58
|
+
adapter.transaction(() => {
|
|
59
|
+
adapter
|
|
60
|
+
.prepare(`INSERT INTO link_audit_log (from_id, to_id, relationship, action, actor, reason, created_at)
|
|
61
|
+
VALUES (?, ?, ?, 'rejected', 'user', ?, ?)`)
|
|
62
|
+
.run(key.fromId, key.toId, key.relationship, reason, Date.now());
|
|
63
|
+
adapter
|
|
64
|
+
.prepare(`DELETE FROM decision_edges
|
|
65
|
+
WHERE from_id = ? AND to_id = ? AND relationship = ?`)
|
|
66
|
+
.run(key.fromId, key.toId, key.relationship);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Remove the auto-generated edge population (created_by='user' with no
|
|
71
|
+
* proposal context) and record one 'deprecated' audit row per removed link.
|
|
72
|
+
* `links` is the already-scanned target set; it only feeds the audit rows.
|
|
73
|
+
*/
|
|
74
|
+
function deprecateAutoDecisionEdges(adapter, links, reason) {
|
|
75
|
+
adapter.transaction(() => {
|
|
76
|
+
adapter
|
|
77
|
+
.prepare(`DELETE FROM decision_edges WHERE created_by = 'user' AND decision_id IS NULL`)
|
|
78
|
+
.run();
|
|
79
|
+
const auditStmt = adapter.prepare(`INSERT INTO link_audit_log (from_id, to_id, relationship, action, actor, reason, created_at)
|
|
80
|
+
VALUES (?, ?, ?, 'deprecated', 'system', ?, ?)`);
|
|
81
|
+
const timestamp = Date.now();
|
|
82
|
+
for (const link of links) {
|
|
83
|
+
auditStmt.run(link.fromId, link.toId, link.relationship, reason, timestamp);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Delete one batch of edges, writing a 'deprecated' audit row for each. A
|
|
89
|
+
* per-link failure is collected and the batch continues, matching the cleanup
|
|
90
|
+
* tool's accounting; a failure of the batch itself throws to the caller.
|
|
91
|
+
*/
|
|
92
|
+
function deleteDecisionEdgesWithAudit(adapter, links, reason) {
|
|
93
|
+
const deleteStmt = adapter.prepare(`DELETE FROM decision_edges
|
|
94
|
+
WHERE from_id = ? AND to_id = ? AND relationship = ?`);
|
|
95
|
+
const auditStmt = adapter.prepare(`INSERT INTO link_audit_log (from_id, to_id, relationship, action, actor, reason, created_at)
|
|
96
|
+
VALUES (?, ?, ?, 'deprecated', 'system', ?, ?)`);
|
|
97
|
+
let deleted = 0;
|
|
98
|
+
const failures = [];
|
|
99
|
+
const processLinks = () => {
|
|
100
|
+
for (const link of links) {
|
|
101
|
+
try {
|
|
102
|
+
deleteStmt.run(link.fromId, link.toId, link.relationship);
|
|
103
|
+
auditStmt.run(link.fromId, link.toId, link.relationship, reason, Date.now());
|
|
104
|
+
deleted++;
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
failures.push({
|
|
108
|
+
link: `${link.fromId}->${link.toId}`,
|
|
109
|
+
error: error instanceof Error ? error.message : String(error),
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
// Use transaction if available, otherwise run directly
|
|
115
|
+
if (adapter.transaction) {
|
|
116
|
+
adapter.transaction(processLinks);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
processLinks();
|
|
120
|
+
}
|
|
121
|
+
return { deleted, failures };
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=decision-edges.js.map
|