@principles/core 1.287.7 → 1.287.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/principle-tree-ledger.d.ts +50 -0
  2. package/dist/principle-tree-ledger.d.ts.map +1 -1
  3. package/dist/principle-tree-ledger.js +133 -1
  4. package/dist/principle-tree-ledger.js.map +1 -1
  5. package/dist/runtime-v2/adapter/principle-tree-ledger-adapter.d.ts +24 -0
  6. package/dist/runtime-v2/adapter/principle-tree-ledger-adapter.d.ts.map +1 -1
  7. package/dist/runtime-v2/adapter/principle-tree-ledger-adapter.js +36 -1
  8. package/dist/runtime-v2/adapter/principle-tree-ledger-adapter.js.map +1 -1
  9. package/dist/runtime-v2/candidate-intake-service.d.ts +102 -3
  10. package/dist/runtime-v2/candidate-intake-service.d.ts.map +1 -1
  11. package/dist/runtime-v2/candidate-intake-service.js +280 -47
  12. package/dist/runtime-v2/candidate-intake-service.js.map +1 -1
  13. package/dist/runtime-v2/candidate-intake.d.ts +44 -0
  14. package/dist/runtime-v2/candidate-intake.d.ts.map +1 -1
  15. package/dist/runtime-v2/candidate-intake.js +7 -0
  16. package/dist/runtime-v2/candidate-intake.js.map +1 -1
  17. package/dist/runtime-v2/index.d.ts +6 -0
  18. package/dist/runtime-v2/index.d.ts.map +1 -1
  19. package/dist/runtime-v2/index.js +7 -0
  20. package/dist/runtime-v2/index.js.map +1 -1
  21. package/dist/runtime-v2/pain-signal-bridge.d.ts.map +1 -1
  22. package/dist/runtime-v2/pain-signal-bridge.js +14 -1
  23. package/dist/runtime-v2/pain-signal-bridge.js.map +1 -1
  24. package/dist/runtime-v2/principle-reuse/reuse-domain.d.ts +89 -0
  25. package/dist/runtime-v2/principle-reuse/reuse-domain.d.ts.map +1 -0
  26. package/dist/runtime-v2/principle-reuse/reuse-domain.js +16 -0
  27. package/dist/runtime-v2/principle-reuse/reuse-domain.js.map +1 -0
  28. package/dist/runtime-v2/principle-reuse/reuse-proposal.d.ts +87 -0
  29. package/dist/runtime-v2/principle-reuse/reuse-proposal.d.ts.map +1 -0
  30. package/dist/runtime-v2/principle-reuse/reuse-proposal.js +99 -0
  31. package/dist/runtime-v2/principle-reuse/reuse-proposal.js.map +1 -0
  32. package/dist/runtime-v2/principle-reuse/reuse-retrieval.d.ts +36 -0
  33. package/dist/runtime-v2/principle-reuse/reuse-retrieval.d.ts.map +1 -0
  34. package/dist/runtime-v2/principle-reuse/reuse-retrieval.js +118 -0
  35. package/dist/runtime-v2/principle-reuse/reuse-retrieval.js.map +1 -0
  36. package/dist/runtime-v2/principle-reuse/reuse-shortlist.d.ts +40 -0
  37. package/dist/runtime-v2/principle-reuse/reuse-shortlist.d.ts.map +1 -0
  38. package/dist/runtime-v2/principle-reuse/reuse-shortlist.js +184 -0
  39. package/dist/runtime-v2/principle-reuse/reuse-shortlist.js.map +1 -0
  40. package/dist/runtime-v2/store/pain-diagnosis/pain-diagnosis-store.d.ts +7 -0
  41. package/dist/runtime-v2/store/pain-diagnosis/pain-diagnosis-store.d.ts.map +1 -1
  42. package/dist/runtime-v2/store/pain-diagnosis/pain-diagnosis-store.js.map +1 -1
  43. package/dist/runtime-v2/store/pain-diagnosis/sqlite-pain-diagnosis-store.d.ts +1 -0
  44. package/dist/runtime-v2/store/pain-diagnosis/sqlite-pain-diagnosis-store.d.ts.map +1 -1
  45. package/dist/runtime-v2/store/pain-diagnosis/sqlite-pain-diagnosis-store.js +12 -0
  46. package/dist/runtime-v2/store/pain-diagnosis/sqlite-pain-diagnosis-store.js.map +1 -1
  47. package/dist/runtime-v2/store/runtime-state-manager.d.ts +5 -0
  48. package/dist/runtime-v2/store/runtime-state-manager.d.ts.map +1 -1
  49. package/dist/runtime-v2/store/runtime-state-manager.js +8 -0
  50. package/dist/runtime-v2/store/runtime-state-manager.js.map +1 -1
  51. package/dist/runtime-v2/types/principle-schema.d.ts +65 -0
  52. package/dist/runtime-v2/types/principle-schema.d.ts.map +1 -1
  53. package/dist/runtime-v2/types/principle-schema.js +14 -0
  54. package/dist/runtime-v2/types/principle-schema.js.map +1 -1
  55. package/dist/runtime-v2/types/principle-tree-store.d.ts +12 -0
  56. package/dist/runtime-v2/types/principle-tree-store.d.ts.map +1 -1
  57. package/dist/telemetry-event.d.ts +2 -2
  58. package/dist/telemetry-event.d.ts.map +1 -1
  59. package/dist/telemetry-event.js +2 -0
  60. package/dist/telemetry-event.js.map +1 -1
  61. package/package.json +2 -2
@@ -0,0 +1,87 @@
1
+ /**
2
+ * PRI-917 Slice 2 — reuse proposal + decision contract (internal).
3
+ *
4
+ * This slice delivers the FLOW only: given a candidate, produce a bounded
5
+ * proposal of existing Principles that may already cover it, and let an
6
+ * injected decision function answer `reuse` or `create`.
7
+ *
8
+ * Deliberately NOT in this slice (SPEC v0.2 / task scope):
9
+ * - persistence of the decision or the relation (`reuseEvidence[]` is Slice 3)
10
+ * - any Console page, new approval subsystem, or automated decision model
11
+ * - any change to `derivedFromPainIds`, the ledger schema, or candidate status
12
+ *
13
+ * @see docs/specs/PRI-917-reuse-before-create-v0.1.md (SPEC v0.2)
14
+ */
15
+ import type { ReuseShortlist } from './reuse-domain.js';
16
+ import type { ReuseEvidenceActor } from '../types/principle-schema.js';
17
+ /**
18
+ * `pending` — credible existing Principles were found and an Owner decision is
19
+ * required before anything is written.
20
+ * `no_candidates` — nothing credible was found; the caller proceeds to create.
21
+ */
22
+ export type ReuseProposalStatus = 'pending' | 'no_candidates';
23
+ export interface ReuseProposalEntry {
24
+ /** Canonical Principle Ledger UUID. */
25
+ principleId: string;
26
+ score: number;
27
+ /** Human-readable reasons, one per evidence field. */
28
+ reasons: string[];
29
+ }
30
+ export interface ReuseProposal {
31
+ candidateId: string;
32
+ status: ReuseProposalStatus;
33
+ candidates: ReuseProposalEntry[];
34
+ /** Principles that passed status eligibility. */
35
+ eligibleCount: number;
36
+ }
37
+ /**
38
+ * The Owner's answer. There is no automatic option.
39
+ *
40
+ * A `reuse` verdict carries the SPEC §11 decision-exchange fields (`actor`,
41
+ * `reason`, `decidedAt`) because PRI-917 PR3B materialises the verdict into
42
+ * `Principle.reuseEvidence[]` verbatim (SPEC §12): the durable evidence must
43
+ * record WHO decided, WHY, and WHEN — an answer without them cannot be
44
+ * persisted as a reuse resolution, so the validator rejects it fail-closed.
45
+ */
46
+ export type ReuseDecision = {
47
+ decision: 'create';
48
+ } | {
49
+ decision: 'reuse';
50
+ selectedPrincipleId: string;
51
+ actor: ReuseEvidenceActor;
52
+ reason: string;
53
+ decidedAt: string;
54
+ };
55
+ /**
56
+ * Converts a deterministic shortlist into the proposal contract.
57
+ *
58
+ * The shortlist already guarantees determinism and a bounded Top-K, so this is
59
+ * a pure projection: it adds no ranking of its own and never widens the set.
60
+ */
61
+ export declare function buildReuseProposal(candidateId: string, shortlist: ReuseShortlist): ReuseProposal;
62
+ /** True when the proposal needs an Owner answer before writing. */
63
+ export declare function proposalNeedsDecision(proposal: ReuseProposal): boolean;
64
+ export type ReuseDecisionValidation = {
65
+ ok: true;
66
+ decision: ReuseDecision;
67
+ } | {
68
+ ok: false;
69
+ reason: string;
70
+ };
71
+ /**
72
+ * Runtime validator for the reuse decision (rc-1/rc-2/rc-3).
73
+ *
74
+ * The decision function is an untrusted boundary — an AI Owner parses model
75
+ * output into it — so its TypeScript type cannot be the guard. A bare
76
+ * `"create"` string, `{}`, `{decision:'REUSE'}`, a non-string principle id, or
77
+ * a missing id for reuse are ALL rejected here, because the alternative is
78
+ * silently reading a malformed answer as "go ahead and create" — the exact
79
+ * duplicate manufacturing this gate exists to prevent.
80
+ *
81
+ * PRI-917 PR3B Phase 2: a `reuse` verdict must additionally carry the
82
+ * SPEC §11 accountability fields (`actor` / `reason` / `decidedAt`) — they are
83
+ * materialised verbatim into `Principle.reuseEvidence[]`, and an answer
84
+ * without them cannot produce a self-contained, auditable evidence entry.
85
+ */
86
+ export declare function validateReuseDecision(raw: unknown): ReuseDecisionValidation;
87
+ //# sourceMappingURL=reuse-proposal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reuse-proposal.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/principle-reuse/reuse-proposal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAkB,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAEvE;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,eAAe,CAAC;AAE9D,MAAM,WAAW,kBAAkB;IACjC,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,iDAAiD;IACjD,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,EAAE,QAAQ,CAAA;CAAE,GACtB;IACE,QAAQ,EAAE,OAAO,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEN;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,cAAc,GACxB,aAAa,CAef;AAED,mEAAmE;AACnE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAEtE;AAED,MAAM,MAAM,uBAAuB,GAC/B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,GACrC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,uBAAuB,CAwC3E"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * PRI-917 Slice 2 — reuse proposal + decision contract (internal).
3
+ *
4
+ * This slice delivers the FLOW only: given a candidate, produce a bounded
5
+ * proposal of existing Principles that may already cover it, and let an
6
+ * injected decision function answer `reuse` or `create`.
7
+ *
8
+ * Deliberately NOT in this slice (SPEC v0.2 / task scope):
9
+ * - persistence of the decision or the relation (`reuseEvidence[]` is Slice 3)
10
+ * - any Console page, new approval subsystem, or automated decision model
11
+ * - any change to `derivedFromPainIds`, the ledger schema, or candidate status
12
+ *
13
+ * @see docs/specs/PRI-917-reuse-before-create-v0.1.md (SPEC v0.2)
14
+ */
15
+ /**
16
+ * Converts a deterministic shortlist into the proposal contract.
17
+ *
18
+ * The shortlist already guarantees determinism and a bounded Top-K, so this is
19
+ * a pure projection: it adds no ranking of its own and never widens the set.
20
+ */
21
+ export function buildReuseProposal(candidateId, shortlist) {
22
+ const candidates = shortlist.candidates.map((entry) => ({
23
+ principleId: entry.principleId,
24
+ score: entry.score,
25
+ reasons: [
26
+ entry.similarityReason,
27
+ ...entry.evidence.map((e) => `${e.field}: ${e.sharedTerms.slice(0, 5).join('、')}`),
28
+ ],
29
+ }));
30
+ return {
31
+ candidateId,
32
+ status: candidates.length > 0 ? 'pending' : 'no_candidates',
33
+ candidates,
34
+ eligibleCount: shortlist.eligibleCount,
35
+ };
36
+ }
37
+ /** True when the proposal needs an Owner answer before writing. */
38
+ export function proposalNeedsDecision(proposal) {
39
+ return proposal.status === 'pending';
40
+ }
41
+ /**
42
+ * Runtime validator for the reuse decision (rc-1/rc-2/rc-3).
43
+ *
44
+ * The decision function is an untrusted boundary — an AI Owner parses model
45
+ * output into it — so its TypeScript type cannot be the guard. A bare
46
+ * `"create"` string, `{}`, `{decision:'REUSE'}`, a non-string principle id, or
47
+ * a missing id for reuse are ALL rejected here, because the alternative is
48
+ * silently reading a malformed answer as "go ahead and create" — the exact
49
+ * duplicate manufacturing this gate exists to prevent.
50
+ *
51
+ * PRI-917 PR3B Phase 2: a `reuse` verdict must additionally carry the
52
+ * SPEC §11 accountability fields (`actor` / `reason` / `decidedAt`) — they are
53
+ * materialised verbatim into `Principle.reuseEvidence[]`, and an answer
54
+ * without them cannot produce a self-contained, auditable evidence entry.
55
+ */
56
+ export function validateReuseDecision(raw) {
57
+ if (raw === null || raw === undefined)
58
+ return { ok: false, reason: 'decision_is_nullish' };
59
+ if (typeof raw !== 'object' || Array.isArray(raw))
60
+ return { ok: false, reason: 'decision_is_not_an_object' };
61
+ const record = raw;
62
+ const { decision } = record;
63
+ if (decision === 'create')
64
+ return { ok: true, decision: { decision: 'create' } };
65
+ if (decision !== 'reuse')
66
+ return { ok: false, reason: `unknown_decision_value:${String(decision)}` };
67
+ const selected = record.selectedPrincipleId;
68
+ if (typeof selected !== 'string' || selected.length === 0) {
69
+ return { ok: false, reason: 'reuse_without_principle_id' };
70
+ }
71
+ const actorRaw = record.actor;
72
+ if (typeof actorRaw !== 'object' || actorRaw === null || Array.isArray(actorRaw)) {
73
+ return { ok: false, reason: 'reuse_actor_invalid' };
74
+ }
75
+ const actorRecord = actorRaw;
76
+ if (!(actorRecord.kind === 'owner' || actorRecord.kind === 'ai_owner')
77
+ || typeof actorRecord.id !== 'string'
78
+ || actorRecord.id.length === 0) {
79
+ return { ok: false, reason: 'reuse_actor_invalid' };
80
+ }
81
+ const { reason, decidedAt } = record;
82
+ if (typeof reason !== 'string' || reason.length === 0) {
83
+ return { ok: false, reason: 'reuse_reason_missing' };
84
+ }
85
+ if (typeof decidedAt !== 'string' || decidedAt.length === 0 || Number.isNaN(Date.parse(decidedAt))) {
86
+ return { ok: false, reason: 'reuse_decidedAt_invalid' };
87
+ }
88
+ return {
89
+ ok: true,
90
+ decision: {
91
+ decision: 'reuse',
92
+ selectedPrincipleId: selected,
93
+ actor: { kind: actorRecord.kind, id: actorRecord.id },
94
+ reason,
95
+ decidedAt,
96
+ },
97
+ };
98
+ }
99
+ //# sourceMappingURL=reuse-proposal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reuse-proposal.js","sourceRoot":"","sources":["../../../src/runtime-v2/principle-reuse/reuse-proposal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * PRI-917 Slice 1 — read-only reuse retrieval over the existing Principle
3
+ * Ledger.
4
+ *
5
+ * Reuses `loadLedger` (the single ledger authority) and the existing
6
+ * principle-kind guard. Creates no repository, no database, no index, no
7
+ * vector store, and no embedding service. It never writes: `derivedFromPainIds`,
8
+ * the ledger schema, and `activation_decisions` are all untouched.
9
+ *
10
+ * @see docs/specs/PRI-917-reuse-before-create-v0.1.md (SPEC v0.2)
11
+ */
12
+ import type { ReuseCandidateInput, ReusablePrinciple, ReuseShortlist, ReuseShortlistOptions } from './reuse-domain.js';
13
+ /**
14
+ * Statuses a Principle may be reused into (SPEC §15).
15
+ *
16
+ * `active` and `candidate`/`probation` are included because that is where real
17
+ * reusable knowledge lives — excluding `candidate` would leave almost nothing,
18
+ * as the live ledger is overwhelmingly `candidate`. `archived` and `deprecated`
19
+ * are excluded: reusing into a retired Principle would revive withdrawn
20
+ * knowledge. Any unrecognised status is excluded fail-closed.
21
+ */
22
+ export declare const REUSABLE_PRINCIPLE_STATUSES: ReadonlySet<string>;
23
+ export declare function isReusablePrincipleStatus(status: unknown): boolean;
24
+ export declare function readReusablePrinciples(stateDir: string): ReusablePrinciple[];
25
+ /**
26
+ * Build the reuse shortlist for a candidate, from the canonical ledger.
27
+ *
28
+ * `recommendationKind` is checked with the SAME guard the intake write boundary
29
+ * uses, so a non-principle candidate can never reach the reuse path (SPEC T6 —
30
+ * the #1851 refusal semantics stay exactly as they are; this only makes the
31
+ * reuse path refuse them too).
32
+ */
33
+ export declare function buildReuseShortlist(input: ReuseCandidateInput, stateDir: string, options?: ReuseShortlistOptions & {
34
+ recommendationKind?: unknown;
35
+ }): ReuseShortlist;
36
+ //# sourceMappingURL=reuse-retrieval.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reuse-retrieval.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/principle-reuse/reuse-retrieval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,OAAO,KAAK,EACV,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,EAAE,WAAW,CAAC,MAAM,CAI1D,CAAC;AAEH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAMlE;AA0CD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAa5E;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,mBAAmB,EAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,qBAAqB,GAAG;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAO,GACrE,cAAc,CAWhB"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * PRI-917 Slice 1 — read-only reuse retrieval over the existing Principle
3
+ * Ledger.
4
+ *
5
+ * Reuses `loadLedger` (the single ledger authority) and the existing
6
+ * principle-kind guard. Creates no repository, no database, no index, no
7
+ * vector store, and no embedding service. It never writes: `derivedFromPainIds`,
8
+ * the ledger schema, and `activation_decisions` are all untouched.
9
+ *
10
+ * @see docs/specs/PRI-917-reuse-before-create-v0.1.md (SPEC v0.2)
11
+ */
12
+ import { existsSync, readFileSync } from 'fs';
13
+ import { getLedgerFilePathPublic, loadLedger } from '../../principle-tree-ledger.js';
14
+ import { isPrincipleLedgerEligibleKind } from '../store/candidate/recommendation-kind-resolver.js';
15
+ import { PRINCIPLE_STATUSES } from '../types/principle-enums.js';
16
+ import { isRecord } from '../candidate-intake.js';
17
+ import { selectReuseShortlist } from './reuse-shortlist.js';
18
+ /**
19
+ * Statuses a Principle may be reused into (SPEC §15).
20
+ *
21
+ * `active` and `candidate`/`probation` are included because that is where real
22
+ * reusable knowledge lives — excluding `candidate` would leave almost nothing,
23
+ * as the live ledger is overwhelmingly `candidate`. `archived` and `deprecated`
24
+ * are excluded: reusing into a retired Principle would revive withdrawn
25
+ * knowledge. Any unrecognised status is excluded fail-closed.
26
+ */
27
+ export const REUSABLE_PRINCIPLE_STATUSES = new Set([
28
+ 'active',
29
+ 'candidate',
30
+ 'probation',
31
+ ]);
32
+ export function isReusablePrincipleStatus(status) {
33
+ if (typeof status !== 'string')
34
+ return false;
35
+ // Fail closed on a status outside the known enum: an unrecognised value is
36
+ // treated as not reusable rather than optimistically reusable.
37
+ if (!PRINCIPLE_STATUSES.includes(status))
38
+ return false;
39
+ return REUSABLE_PRINCIPLE_STATUSES.has(status);
40
+ }
41
+ function assertLedgerReadable(stateDir) {
42
+ const filePath = getLedgerFilePathPublic(stateDir);
43
+ if (!existsSync(filePath))
44
+ return; // no corpus yet — nothing to reuse
45
+ const raw = readFileSync(filePath, 'utf-8');
46
+ if (raw.trim() === '')
47
+ return; // an empty document is an empty corpus
48
+ // Throws on malformed JSON so the caller fails the gate rather than silently
49
+ // treating unreadable knowledge as absent knowledge.
50
+ JSON.parse(raw);
51
+ }
52
+ /**
53
+ * Read every reusable Principle from the canonical ledger.
54
+ *
55
+ * Read-only: opens the ledger document and filters in memory. No caching is
56
+ * introduced here — the corpus is small (order 10^2) and a cache would be a
57
+ * second place where ledger truth could go stale.
58
+ *
59
+ * Fail-closed on an UNREADABLE corpus. The shared `loadLedger` deliberately
60
+ * swallows a parse error and returns an empty store, which is indistinguishable
61
+ * from "nothing has been learned yet" — and the write that follows would then
62
+ * overwrite the unreadable file. Reporting that as an empty candidate set is
63
+ * precisely the silent duplicate this whole path exists to prevent, so an
64
+ * existing-but-unparseable ledger throws here instead.
65
+ *
66
+ * A genuinely MISSING ledger is not a failure: there is simply nothing to
67
+ * reuse yet, and blocking the first write of a fresh workspace would be wrong.
68
+ */
69
+ function normalizeLedgerEntry(entry) {
70
+ if (!isRecord(entry))
71
+ return null;
72
+ const { id, text, triggerPattern, action, status } = entry;
73
+ if (typeof id !== 'string' || id.length === 0)
74
+ return null;
75
+ return {
76
+ id,
77
+ text: typeof text === 'string' ? text : '',
78
+ triggerPattern: typeof triggerPattern === 'string' ? triggerPattern : '',
79
+ action: typeof action === 'string' ? action : '',
80
+ status: typeof status === 'string' ? status : '',
81
+ };
82
+ }
83
+ export function readReusablePrinciples(stateDir) {
84
+ assertLedgerReadable(stateDir);
85
+ const store = loadLedger(stateDir);
86
+ // The ledger is an untrusted document (rc-1/rc-2): validate each entry's
87
+ // fields instead of asserting the shape, so a malformed entry is skipped
88
+ // rather than flowing a non-string into the tokenizer as if it were text.
89
+ const entries = Object.values(store.tree.principles);
90
+ const reusable = [];
91
+ for (const entry of entries) {
92
+ const normalized = normalizeLedgerEntry(entry);
93
+ if (normalized && isReusablePrincipleStatus(normalized.status))
94
+ reusable.push(normalized);
95
+ }
96
+ return reusable;
97
+ }
98
+ /**
99
+ * Build the reuse shortlist for a candidate, from the canonical ledger.
100
+ *
101
+ * `recommendationKind` is checked with the SAME guard the intake write boundary
102
+ * uses, so a non-principle candidate can never reach the reuse path (SPEC T6 —
103
+ * the #1851 refusal semantics stay exactly as they are; this only makes the
104
+ * reuse path refuse them too).
105
+ */
106
+ export function buildReuseShortlist(input, stateDir, options = {}) {
107
+ const { recommendationKind, ...shortlistOptions } = options;
108
+ if (recommendationKind !== undefined && !isPrincipleLedgerEligibleKind(recommendationKind)) {
109
+ return {
110
+ candidates: [],
111
+ eligibleCount: 0,
112
+ consideredCount: 0,
113
+ candidateKindEligible: false,
114
+ };
115
+ }
116
+ return selectReuseShortlist(input, readReusablePrinciples(stateDir), shortlistOptions);
117
+ }
118
+ //# sourceMappingURL=reuse-retrieval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reuse-retrieval.js","sourceRoot":"","sources":["../../../src/runtime-v2/principle-reuse/reuse-retrieval.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * PRI-917 Slice 1 — deterministic shortlist scoring (pure, no LLM, no I/O).
3
+ *
4
+ * Why a hand-rolled tokenizer: the Principle corpus is Chinese prose, so
5
+ * whitespace tokenization collapses a sentence into one useless token.
6
+ * This module therefore emits CJK character bigrams plus lower-cased latin /
7
+ * numeric word runs. The result is deterministic, dependency-free, and
8
+ * explainable — every score decomposes into named shared terms.
9
+ *
10
+ * Explicit non-goals (SPEC §6): no embedding, no vector store, no semantic
11
+ * search service, no background process, no clock, no randomness.
12
+ */
13
+ import type { ReuseCandidate, ReuseCandidateInput, ReusablePrinciple, ReuseShortlist, ReuseShortlistOptions } from './reuse-domain.js';
14
+ /**
15
+ * Deterministic, dependency-free tokenizer.
16
+ *
17
+ * - latin / numeric runs → lower-cased word tokens (length >= 2)
18
+ * - CJK runs → character bigrams (single char when the run is length 1)
19
+ * - everything else is a separator
20
+ *
21
+ * The output is sorted, so two equal texts always tokenize identically.
22
+ */
23
+ export declare function tokenizeForReuse(input: string): string[];
24
+ /**
25
+ * Score one existing Principle against the candidate.
26
+ *
27
+ * Returns `null` when no field pair shares anything — an entry with no
28
+ * evidence is not a proposal.
29
+ */
30
+ export declare function scoreReuseCandidate(input: ReuseCandidateInput, principle: ReusablePrinciple, maxEvidenceTerms?: number): ReuseCandidate | null;
31
+ /**
32
+ * Build a deterministic, bounded shortlist of existing Principles that may
33
+ * already cover the candidate.
34
+ *
35
+ * Pure: no I/O, no clock, no randomness. Total order is `score` desc then
36
+ * `principleId` asc, so identical input always yields identical output
37
+ * regardless of ledger insertion order.
38
+ */
39
+ export declare function selectReuseShortlist(input: ReuseCandidateInput, principles: readonly ReusablePrinciple[], options?: ReuseShortlistOptions): ReuseShortlist;
40
+ //# sourceMappingURL=reuse-shortlist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reuse-shortlist.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/principle-reuse/reuse-shortlist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EAGnB,iBAAiB,EAEjB,cAAc,EACd,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AA0C3B;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAqCxD;AAQD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,mBAAmB,EAC1B,SAAS,EAAE,iBAAiB,EAC5B,gBAAgB,GAAE,MAAmC,GACpD,cAAc,GAAG,IAAI,CAoDvB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,mBAAmB,EAC1B,UAAU,EAAE,SAAS,iBAAiB,EAAE,EACxC,OAAO,GAAE,qBAA0B,GAClC,cAAc,CAkBhB"}
@@ -0,0 +1,184 @@
1
+ /**
2
+ * PRI-917 Slice 1 — deterministic shortlist scoring (pure, no LLM, no I/O).
3
+ *
4
+ * Why a hand-rolled tokenizer: the Principle corpus is Chinese prose, so
5
+ * whitespace tokenization collapses a sentence into one useless token.
6
+ * This module therefore emits CJK character bigrams plus lower-cased latin /
7
+ * numeric word runs. The result is deterministic, dependency-free, and
8
+ * explainable — every score decomposes into named shared terms.
9
+ *
10
+ * Explicit non-goals (SPEC §6): no embedding, no vector store, no semantic
11
+ * search service, no background process, no clock, no randomness.
12
+ */
13
+ const DEFAULT_TOP_K = 3;
14
+ const DEFAULT_MIN_SCORE = 0.15;
15
+ const DEFAULT_MAX_EVIDENCE_TERMS = 8;
16
+ /**
17
+ * Field-pair weights. Same-field agreement is the strong signal; a
18
+ * cross-field pair catches a candidate that states the claim in `action` where
19
+ * the existing Principle states it in `text`.
20
+ */
21
+ const FIELD_PAIR_WEIGHTS = [
22
+ { from: 'text', to: 'text', weight: 3 },
23
+ { from: 'action', to: 'action', weight: 3 },
24
+ { from: 'triggerPattern', to: 'triggerPattern', weight: 2 },
25
+ { from: 'text', to: 'action', weight: 1 },
26
+ { from: 'action', to: 'text', weight: 1 },
27
+ ];
28
+ /**
29
+ * Minimal Chinese function-word stop list. Kept deliberately small: over-pruning
30
+ * would erase real signal, and the scoring is advisory (a human/AI Owner
31
+ * decides), not authoritative.
32
+ */
33
+ const CJK_STOP_TERMS = new Set([
34
+ '的', '了', '是', '在', '和', '与', '或', '及', '对', '为', '以', '等', '中',
35
+ '上', '下', '时', '后', '前', '将', '被', '把', '就', '都', '也', '而', '但',
36
+ '并', '不', '有', '无', '一', '个', '这', '那', '其', '之', '所', '使', '由',
37
+ '如', '若', '则', '于', '从', '到', '向', '再', '更', '最', '很', '会', '能',
38
+ '应', '须', '要', '可', '个', '种', '些', '之', '者', '此', '该', '某',
39
+ ]);
40
+ const CJK_RANGE = /[㐀-䶿一-鿿]/;
41
+ function isCjk(ch) {
42
+ return CJK_RANGE.test(ch);
43
+ }
44
+ /**
45
+ * Deterministic, dependency-free tokenizer.
46
+ *
47
+ * - latin / numeric runs → lower-cased word tokens (length >= 2)
48
+ * - CJK runs → character bigrams (single char when the run is length 1)
49
+ * - everything else is a separator
50
+ *
51
+ * The output is sorted, so two equal texts always tokenize identically.
52
+ */
53
+ export function tokenizeForReuse(input) {
54
+ const normalized = input.normalize('NFKC').toLowerCase();
55
+ const tokens = [];
56
+ let latinRun = '';
57
+ let cjkRun = '';
58
+ const flushLatin = () => {
59
+ if (latinRun.length >= 2)
60
+ tokens.push(latinRun);
61
+ latinRun = '';
62
+ };
63
+ const flushCjk = () => {
64
+ if (cjkRun.length === 1) {
65
+ tokens.push(cjkRun);
66
+ }
67
+ else {
68
+ for (let i = 0; i + 1 < cjkRun.length; i++)
69
+ tokens.push(cjkRun.slice(i, i + 2));
70
+ }
71
+ cjkRun = '';
72
+ };
73
+ for (const ch of normalized) {
74
+ if (isCjk(ch)) {
75
+ flushLatin();
76
+ cjkRun += ch;
77
+ }
78
+ else if (/[a-z0-9]/.test(ch)) {
79
+ flushCjk();
80
+ latinRun += ch;
81
+ }
82
+ else {
83
+ flushLatin();
84
+ flushCjk();
85
+ }
86
+ }
87
+ flushLatin();
88
+ flushCjk();
89
+ const deduped = new Set(tokens);
90
+ for (const stop of CJK_STOP_TERMS)
91
+ deduped.delete(stop);
92
+ return [...deduped].sort();
93
+ }
94
+ function intersect(a, b) {
95
+ const shared = [];
96
+ for (const term of a)
97
+ if (b.has(term))
98
+ shared.push(term);
99
+ return shared.sort();
100
+ }
101
+ /**
102
+ * Score one existing Principle against the candidate.
103
+ *
104
+ * Returns `null` when no field pair shares anything — an entry with no
105
+ * evidence is not a proposal.
106
+ */
107
+ export function scoreReuseCandidate(input, principle, maxEvidenceTerms = DEFAULT_MAX_EVIDENCE_TERMS) {
108
+ const inputTerms = {
109
+ text: new Set(tokenizeForReuse(input.text)),
110
+ triggerPattern: new Set(tokenizeForReuse(input.triggerPattern)),
111
+ action: new Set(tokenizeForReuse(input.action)),
112
+ };
113
+ const principleTerms = {
114
+ text: new Set(tokenizeForReuse(principle.text)),
115
+ triggerPattern: new Set(tokenizeForReuse(principle.triggerPattern)),
116
+ action: new Set(tokenizeForReuse(principle.action)),
117
+ };
118
+ const evidence = [];
119
+ let weighted = 0;
120
+ let totalWeight = 0;
121
+ for (const pair of FIELD_PAIR_WEIGHTS) {
122
+ const from = inputTerms[pair.from];
123
+ const to = principleTerms[pair.to];
124
+ const smaller = Math.min(from.size, to.size);
125
+ // An empty side can never produce evidence.
126
+ if (smaller === 0)
127
+ continue;
128
+ totalWeight += pair.weight;
129
+ const shared = intersect(from, to);
130
+ if (shared.length === 0)
131
+ continue;
132
+ const coverage = shared.length / smaller;
133
+ weighted += pair.weight * coverage;
134
+ const field = pair.from === pair.to ? pair.from : `${pair.from}~${pair.to}`;
135
+ evidence.push({
136
+ field,
137
+ sharedTerms: shared.slice(0, maxEvidenceTerms),
138
+ coverage,
139
+ });
140
+ }
141
+ if (evidence.length === 0 || totalWeight === 0)
142
+ return null;
143
+ const score = weighted / totalWeight;
144
+ const [top] = evidence
145
+ .slice()
146
+ .sort((a, b) => b.coverage - a.coverage || a.field.localeCompare(b.field));
147
+ const reason = top
148
+ ? `shares ${top.sharedTerms.slice(0, 5).join('、')} on ${top.field} (coverage ${(top.coverage * 100).toFixed(0)}%)`
149
+ : 'no field overlap';
150
+ return {
151
+ principleId: principle.id,
152
+ principleText: principle.text,
153
+ score,
154
+ evidence,
155
+ similarityReason: reason,
156
+ };
157
+ }
158
+ /**
159
+ * Build a deterministic, bounded shortlist of existing Principles that may
160
+ * already cover the candidate.
161
+ *
162
+ * Pure: no I/O, no clock, no randomness. Total order is `score` desc then
163
+ * `principleId` asc, so identical input always yields identical output
164
+ * regardless of ledger insertion order.
165
+ */
166
+ export function selectReuseShortlist(input, principles, options = {}) {
167
+ const topK = options.topK ?? DEFAULT_TOP_K;
168
+ const minScore = options.minScore ?? DEFAULT_MIN_SCORE;
169
+ const maxEvidenceTerms = options.maxEvidenceTerms ?? DEFAULT_MAX_EVIDENCE_TERMS;
170
+ const scored = [];
171
+ for (const principle of principles) {
172
+ const candidate = scoreReuseCandidate(input, principle, maxEvidenceTerms);
173
+ if (candidate && candidate.score >= minScore)
174
+ scored.push(candidate);
175
+ }
176
+ scored.sort((a, b) => b.score - a.score || a.principleId.localeCompare(b.principleId));
177
+ return {
178
+ candidates: scored.slice(0, topK),
179
+ eligibleCount: principles.length,
180
+ consideredCount: scored.length,
181
+ candidateKindEligible: true,
182
+ };
183
+ }
184
+ //# sourceMappingURL=reuse-shortlist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reuse-shortlist.js","sourceRoot":"","sources":["../../../src/runtime-v2/principle-reuse/reuse-shortlist.ts"],"names":[],"mappings":"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"}
@@ -58,6 +58,13 @@ export interface PainDiagnosisStore {
58
58
  recordPainDiagnosis(input: PainDiagnosisWriteInput): Promise<PainDiagnosisRecord>;
59
59
  /** All diagnosis rows for a pain, oldest first. */
60
60
  getDiagnosesByPainId(painId: string): Promise<PainDiagnosisRecord[]>;
61
+ /**
62
+ * All diagnosis rows produced by one diagnostician task, oldest first
63
+ * (PRI-917 PR3B Phase 2: the candidate → pain bridge for reuse evidence —
64
+ * a candidate knows only its task; its Pain resolves through this query).
65
+ * Uses the existing idx_pain_diagnoses_task_id index; no schema change.
66
+ */
67
+ getDiagnosesByTaskId(taskId: string): Promise<PainDiagnosisRecord[]>;
61
68
  }
62
69
  export declare function isRootCauseCategory(value: unknown): value is RootCauseCategory;
63
70
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"pain-diagnosis-store.d.ts","sourceRoot":"","sources":["../../../../src/runtime-v2/store/pain-diagnosis/pain-diagnosis-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AAEtF,8FAA8F;AAC9F,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,kDAAkD;AAClD,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,+FAA+F;IAC/F,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,QAAQ,EAAE,qBAAqB,EAAE,CAAC;IAClC,+EAA+E;IAC/E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,mFAAmF;IACnF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,gEAAgE;AAChE,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC3C,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,mBAAmB,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAElF,mDAAmD;IACnD,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;CACtE;AAID,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,iBAAiB,CAE9E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAKlF;AAED,oEAAoE;AACpE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAEhF"}
1
+ {"version":3,"file":"pain-diagnosis-store.d.ts","sourceRoot":"","sources":["../../../../src/runtime-v2/store/pain-diagnosis/pain-diagnosis-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AAEtF,8FAA8F;AAC9F,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,kDAAkD;AAClD,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,+FAA+F;IAC/F,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,QAAQ,EAAE,qBAAqB,EAAE,CAAC;IAClC,+EAA+E;IAC/E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,mFAAmF;IACnF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,gEAAgE;AAChE,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC3C,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,mBAAmB,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAElF,mDAAmD;IACnD,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAErE;;;;;OAKG;IACH,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;CACtE;AAID,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,iBAAiB,CAE9E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAKlF;AAED,oEAAoE;AACpE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAEhF"}
@@ -1 +1 @@
1
- {"version":3,"file":"pain-diagnosis-store.js","sourceRoot":"","sources":["../../../../src/runtime-v2/store/pain-diagnosis/pain-diagnosis-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAwDH,MAAM,gBAAgB,GAAwB,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;AAErG,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAAiB;IACtD,KAAK,MAAM,QAAQ,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,CAAU,EAAE,CAAC;QAC9E,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,QAAQ,IAAI,CAAC;YAAE,OAAO,QAAQ,CAAC;IAC7D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,WAAmB;IACtE,OAAO,GAAG,MAAM,KAAK,WAAW,EAAE,CAAC;AACrC,CAAC"}
1
+ {"version":3,"file":"pain-diagnosis-store.js","sourceRoot":"","sources":["../../../../src/runtime-v2/store/pain-diagnosis/pain-diagnosis-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAgEH,MAAM,gBAAgB,GAAwB,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;AAErG,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAAiB;IACtD,KAAK,MAAM,QAAQ,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,CAAU,EAAE,CAAC;QAC9E,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,QAAQ,IAAI,CAAC;YAAE,OAAO,QAAQ,CAAC;IAC7D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,WAAmB;IACtE,OAAO,GAAG,MAAM,KAAK,WAAW,EAAE,CAAC;AACrC,CAAC"}
@@ -5,5 +5,6 @@ export declare class SqlitePainDiagnosisStore implements PainDiagnosisStore {
5
5
  constructor(connection: SqliteConnection);
6
6
  recordPainDiagnosis(input: PainDiagnosisWriteInput): Promise<PainDiagnosisRecord>;
7
7
  getDiagnosesByPainId(painId: string): Promise<PainDiagnosisRecord[]>;
8
+ getDiagnosesByTaskId(taskId: string): Promise<PainDiagnosisRecord[]>;
8
9
  }
9
10
  //# sourceMappingURL=sqlite-pain-diagnosis-store.d.ts.map