@principles/pd-cli 1.162.5 → 1.162.6
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/dist/commands/pain-recall.js +1 -1
- package/dist/commands/pain-recall.js.map +1 -1
- package/package.json +3 -3
- package/dist/services/pain-recall.d.ts +0 -192
- package/dist/services/pain-recall.d.ts.map +0 -1
- package/dist/services/pain-recall.js +0 -727
- package/dist/services/pain-recall.js.map +0 -1
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import * as path from 'path';
|
|
14
14
|
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
15
|
-
import { recallPains, PAIN_RECALL_DEFAULT_LIMIT, PAIN_RECALL_MIN_LIMIT, PAIN_RECALL_MAX_LIMIT, } from '
|
|
15
|
+
import { recallPains, PAIN_RECALL_DEFAULT_LIMIT, PAIN_RECALL_MIN_LIMIT, PAIN_RECALL_MAX_LIMIT, } from '@principles/core/runtime-v2/pain-recall';
|
|
16
16
|
function fail(input) {
|
|
17
17
|
const { message, reason, nextAction, json } = input;
|
|
18
18
|
if (json) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pain-recall.js","sourceRoot":"","sources":["../../src/commands/pain-recall.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EACL,WAAW,EACX,yBAAyB,EACzB,qBAAqB,EACrB,qBAAqB,GAEtB,MAAM,
|
|
1
|
+
{"version":3,"file":"pain-recall.js","sourceRoot":"","sources":["../../src/commands/pain-recall.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@principles/pd-cli",
|
|
3
|
-
"version": "1.162.
|
|
3
|
+
"version": "1.162.6",
|
|
4
4
|
"description": "PD CLI — Pain recording, sample management, and governance tasks for Principles Disciple",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
"test": "vitest run"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@principles/core": "^1.
|
|
24
|
+
"@principles/core": "^1.298.0",
|
|
25
25
|
"@principles/codex-adapter": "^0.6.1",
|
|
26
26
|
"@principles/workbuddy-adapter": "^0.2.15",
|
|
27
27
|
"@principles/host-runtime": "^0.14.2",
|
|
28
28
|
"@principles/install-layout": "^0.4.0",
|
|
29
|
-
"principles-disciple": "^2.2.
|
|
29
|
+
"principles-disciple": "^2.2.11",
|
|
30
30
|
"better-sqlite3": "^13.0.3",
|
|
31
31
|
"commander": "^12.0.0",
|
|
32
32
|
"js-yaml": "^5.4.3"
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pain Recall read model — SPEC-PD-PAIN-RECALL-CLI-001.
|
|
3
|
-
*
|
|
4
|
-
* Resolves a canonical ledger principle to its verifiably-associated
|
|
5
|
-
* historical pains through the two authoritative edges only:
|
|
6
|
-
*
|
|
7
|
-
* 1. `Principle.reuseEvidence[]` — carries a REAL `painId` (validated at
|
|
8
|
-
* the ledger write boundary, appendReuseEvidence);
|
|
9
|
-
* 2. `Principle.derivedFromPainIds[]` — stores CANDIDATE ids despite its
|
|
10
|
-
* legacy pain-oriented name (see PainChainReadModel's linkage note);
|
|
11
|
-
* the pain resolves through candidate → task → `tasks.input_ref`
|
|
12
|
-
* (fallback: the `diagnosis_<painId>` task-id spelling).
|
|
13
|
-
*
|
|
14
|
-
* Anything not reachable through those edges is excluded and REPORTED
|
|
15
|
-
* (unresolvedAssociations) — never guessed from text similarity, never
|
|
16
|
-
* resolved through candidateId/taskId/artifactId masquerading as pain ids.
|
|
17
|
-
*
|
|
18
|
-
* Strictly read-only: the ledger through readLedgerFileState, trajectory.db
|
|
19
|
-
* through openTrajectoryDbReadonly, state.db through RuntimeStateManager with
|
|
20
|
-
* readonly:true + bootstrapIfMissing:false. Missing stays missing; unreadable
|
|
21
|
-
* stays unreadable; neither is ever reported as an empty result.
|
|
22
|
-
*
|
|
23
|
-
* WAL safety (SPEC §6.1/§9.2; SPEC-PD-AGENT-CAPABILITY-API-001 v0.3 §10.3.1):
|
|
24
|
-
* both production databases are persisted in WAL journal mode. Any readonly
|
|
25
|
-
* open of a WAL database can touch workspace files — a quiet WAL gains
|
|
26
|
-
* `-wal`/`-shm` sidecars, a missing `-shm` gets created, and an existing
|
|
27
|
-
* `-shm` can be rewritten by WAL-index recovery (all reproduced 2026-10-28 on
|
|
28
|
-
* better-sqlite3 13.0.3, which cannot open `file:` URIs, so SQLite's
|
|
29
|
-
* immutable=1 zero-side-effect mode is unavailable). Therefore EVERY WAL-mode
|
|
30
|
-
* database is read through a staged, fingerprint-verified snapshot in a
|
|
31
|
-
* private temp directory; only rollback-journal databases keep the direct
|
|
32
|
-
* readonly open, which creates nothing. The snapshot copies the main file
|
|
33
|
-
* plus a non-empty `-wal` (the pair SQLite needs to recover un-checkpointed
|
|
34
|
-
* commits; `-shm` is an index cache and is deliberately never copied — the
|
|
35
|
-
* staged open regenerates it beside the copy).
|
|
36
|
-
*
|
|
37
|
-
* Snapshot acceptance contract (proved in stageWalSnapshot): the T1 re-check
|
|
38
|
-
* is ordered main → wal → main, making the WAL fingerprint read the single
|
|
39
|
-
* LINEARIZATION POINT. Acceptance means the staged bytes equal the real
|
|
40
|
-
* database state at that instant: the wal read observes the wal directly,
|
|
41
|
-
* and the bracketing main reads (equal to each other and to T0) pin the main
|
|
42
|
-
* bytes across the whole window — under SQLite-only writes the main file's
|
|
43
|
-
* byte-image cannot return to a previous value (monotonic change counter),
|
|
44
|
-
* so a bracketed main equal on both ends was unchanged in between. Any write
|
|
45
|
-
* completing before the linearization point is therefore caught (a commit
|
|
46
|
-
* changes the wal; a checkpoint changes main and is visible at one of the
|
|
47
|
-
* bracketing reads), and the trailing main re-read additionally rejects a
|
|
48
|
-
* checkpoint landing between the wal read and the protocol's end. An ABA
|
|
49
|
-
* rewrite (commit → checkpoint → wal delete → main bytes back at T0) cannot
|
|
50
|
-
* produce a stale acceptance: a commit surviving to the linearization point
|
|
51
|
-
* moved the main bytes and is rejected; bytes genuinely ending at the T0
|
|
52
|
-
* state mean the staged copy IS the current state, so returning it is
|
|
53
|
-
* correct. Writes after the linearization point (an un-checkpointed commit
|
|
54
|
-
* landing in the trailing window) are post-linearization events — a correct
|
|
55
|
-
* point-in-time read, not staleness. "Always latest at return time" would
|
|
56
|
-
* require writer coordination, which no available mechanism provides
|
|
57
|
-
* honestly (see the implementation report's option analysis A–D).
|
|
58
|
-
*/
|
|
59
|
-
import * as fs from 'fs';
|
|
60
|
-
export declare const PAIN_RECALL_SCHEMA_VERSION = "pd.pain-recall.v1";
|
|
61
|
-
export declare const PAIN_RECALL_DEFAULT_LIMIT = 3;
|
|
62
|
-
export declare const PAIN_RECALL_MIN_LIMIT = 1;
|
|
63
|
-
export declare const PAIN_RECALL_MAX_LIMIT = 10;
|
|
64
|
-
export type PainRecallStatus = 'ok' | 'no_matches' | 'principle_not_found' | 'ambiguous_principle' | 'pain_not_found' | 'source_missing' | 'source_unreadable' | 'partial';
|
|
65
|
-
export type SourceAvailability = 'ok' | 'missing' | 'unreadable' | 'not_checked';
|
|
66
|
-
export type AssociationType = 'explicit_reuse' | 'derived_from' | 'multiple_paths';
|
|
67
|
-
export interface RecallEvidenceRef {
|
|
68
|
-
kind: 'reuse_evidence' | 'candidate_lineage';
|
|
69
|
-
candidateId: string;
|
|
70
|
-
taskId?: string;
|
|
71
|
-
decidedAt?: string;
|
|
72
|
-
decisionId?: string;
|
|
73
|
-
}
|
|
74
|
-
export interface RecallAssociation {
|
|
75
|
-
type: AssociationType;
|
|
76
|
-
confidence: 'explicit' | 'lineage_verified';
|
|
77
|
-
evidenceRefs: RecallEvidenceRef[];
|
|
78
|
-
}
|
|
79
|
-
export interface PainEventView {
|
|
80
|
-
occurredAt: string | null;
|
|
81
|
-
source: string | null;
|
|
82
|
-
host: string;
|
|
83
|
-
score: number | null;
|
|
84
|
-
severity: string | null;
|
|
85
|
-
reason: string | null;
|
|
86
|
-
text: string | null;
|
|
87
|
-
/** A verbatim owner statement is only reported via correctionEvidence; the
|
|
88
|
-
* pain row itself never carries one, so this is structurally null. */
|
|
89
|
-
rawStatement: null;
|
|
90
|
-
}
|
|
91
|
-
export interface DiagnosisView {
|
|
92
|
-
diagnosisId: string;
|
|
93
|
-
taskId: string;
|
|
94
|
-
category: string;
|
|
95
|
-
rootCause: string;
|
|
96
|
-
supportingEvidence: readonly {
|
|
97
|
-
sourceRef: string;
|
|
98
|
-
note: string;
|
|
99
|
-
}[];
|
|
100
|
-
confidence: number | null;
|
|
101
|
-
isOriginalOwnerStatement: false;
|
|
102
|
-
}
|
|
103
|
-
export interface CorrectionEvidenceView {
|
|
104
|
-
text: string;
|
|
105
|
-
classification?: string;
|
|
106
|
-
channel?: string;
|
|
107
|
-
sessionId?: string;
|
|
108
|
-
occurredAt?: string;
|
|
109
|
-
}
|
|
110
|
-
export type ItemAvailability = 'available' | 'not_recorded' | 'unreadable';
|
|
111
|
-
export interface RecallLineageHop {
|
|
112
|
-
from: string;
|
|
113
|
-
to: string;
|
|
114
|
-
relation: string;
|
|
115
|
-
}
|
|
116
|
-
export interface PainRecallEntry {
|
|
117
|
-
painId: string;
|
|
118
|
-
association: RecallAssociation;
|
|
119
|
-
pain: PainEventView;
|
|
120
|
-
diagnoses: DiagnosisView[];
|
|
121
|
-
correctionEvidence: CorrectionEvidenceView | null;
|
|
122
|
-
availability: {
|
|
123
|
-
painEvent: 'available';
|
|
124
|
-
diagnoses: ItemAvailability;
|
|
125
|
-
correctionEvidence: ItemAvailability;
|
|
126
|
-
};
|
|
127
|
-
lineage: RecallLineageHop[];
|
|
128
|
-
}
|
|
129
|
-
export interface PainRecallQuery {
|
|
130
|
-
requestedPrincipleId: string;
|
|
131
|
-
painId?: string;
|
|
132
|
-
context?: string;
|
|
133
|
-
/** Validated upstream: integer within [1, 10]. */
|
|
134
|
-
limit: number;
|
|
135
|
-
}
|
|
136
|
-
export interface UnresolvedAssociation {
|
|
137
|
-
painId?: string;
|
|
138
|
-
candidateId?: string;
|
|
139
|
-
reason: string;
|
|
140
|
-
}
|
|
141
|
-
export interface PainRecallResult {
|
|
142
|
-
schemaVersion: string;
|
|
143
|
-
status: PainRecallStatus;
|
|
144
|
-
/** Sub-reason for pain_not_found: not_associated | pain_event_not_found. */
|
|
145
|
-
statusDetail?: string;
|
|
146
|
-
principle: {
|
|
147
|
-
requestedId: string;
|
|
148
|
-
canonicalId: string | null;
|
|
149
|
-
identityStatus: 'resolved' | 'not_found' | 'ambiguous';
|
|
150
|
-
text?: string;
|
|
151
|
-
};
|
|
152
|
-
query: {
|
|
153
|
-
limit: number;
|
|
154
|
-
painId?: string;
|
|
155
|
-
contextUsedForRanking: boolean;
|
|
156
|
-
truncated: boolean;
|
|
157
|
-
};
|
|
158
|
-
results: PainRecallEntry[];
|
|
159
|
-
summary: {
|
|
160
|
-
returned: number;
|
|
161
|
-
availableCandidates: number;
|
|
162
|
-
truncated: boolean;
|
|
163
|
-
};
|
|
164
|
-
sources: {
|
|
165
|
-
ledger: SourceAvailability;
|
|
166
|
-
trajectoryDb: SourceAvailability;
|
|
167
|
-
stateDb: SourceAvailability;
|
|
168
|
-
};
|
|
169
|
-
unresolvedAssociations: UnresolvedAssociation[];
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Deterministic fault-injection seam for snapshot-race tests — the same
|
|
173
|
-
* pattern as the runtime's databaseFactory seam (PR #2192). Every field is
|
|
174
|
-
* undefined in production; tests assign, then clear in a finally block.
|
|
175
|
-
*/
|
|
176
|
-
export declare const painRecallSnapshotTestHooks: {
|
|
177
|
-
/** Replaces statSync for fingerprinting/classification (throw to simulate EACCES/EIO). */
|
|
178
|
-
statSync?: (path: string) => fs.Stats;
|
|
179
|
-
/** Replaces mkdtempSync for staging-root creation (throw to simulate failure). */
|
|
180
|
-
mkdtempSync?: (prefix: string) => string;
|
|
181
|
-
/** Called after each source→staging copyFileSync with (source, staged). */
|
|
182
|
-
afterCopyFile?: (source: string, stagedPath: string) => void;
|
|
183
|
-
/**
|
|
184
|
-
* Called between the T1 main fingerprint read and the T1 wal fingerprint
|
|
185
|
-
* read — the exact window a concurrent writer can hide in when the pair is
|
|
186
|
-
* sampled non-atomically. Tests use it to inject a deterministic
|
|
187
|
-
* commit→checkpoint→close cycle inside the re-check.
|
|
188
|
-
*/
|
|
189
|
-
afterT1MainFingerprint?: (sourceDbPath: string) => void;
|
|
190
|
-
};
|
|
191
|
-
export declare function recallPains(workspaceDir: string, query: PainRecallQuery): Promise<PainRecallResult>;
|
|
192
|
-
//# sourceMappingURL=pain-recall.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pain-recall.d.ts","sourceRoot":"","sources":["../../src/services/pain-recall.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,727 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pain Recall read model — SPEC-PD-PAIN-RECALL-CLI-001.
|
|
3
|
-
*
|
|
4
|
-
* Resolves a canonical ledger principle to its verifiably-associated
|
|
5
|
-
* historical pains through the two authoritative edges only:
|
|
6
|
-
*
|
|
7
|
-
* 1. `Principle.reuseEvidence[]` — carries a REAL `painId` (validated at
|
|
8
|
-
* the ledger write boundary, appendReuseEvidence);
|
|
9
|
-
* 2. `Principle.derivedFromPainIds[]` — stores CANDIDATE ids despite its
|
|
10
|
-
* legacy pain-oriented name (see PainChainReadModel's linkage note);
|
|
11
|
-
* the pain resolves through candidate → task → `tasks.input_ref`
|
|
12
|
-
* (fallback: the `diagnosis_<painId>` task-id spelling).
|
|
13
|
-
*
|
|
14
|
-
* Anything not reachable through those edges is excluded and REPORTED
|
|
15
|
-
* (unresolvedAssociations) — never guessed from text similarity, never
|
|
16
|
-
* resolved through candidateId/taskId/artifactId masquerading as pain ids.
|
|
17
|
-
*
|
|
18
|
-
* Strictly read-only: the ledger through readLedgerFileState, trajectory.db
|
|
19
|
-
* through openTrajectoryDbReadonly, state.db through RuntimeStateManager with
|
|
20
|
-
* readonly:true + bootstrapIfMissing:false. Missing stays missing; unreadable
|
|
21
|
-
* stays unreadable; neither is ever reported as an empty result.
|
|
22
|
-
*
|
|
23
|
-
* WAL safety (SPEC §6.1/§9.2; SPEC-PD-AGENT-CAPABILITY-API-001 v0.3 §10.3.1):
|
|
24
|
-
* both production databases are persisted in WAL journal mode. Any readonly
|
|
25
|
-
* open of a WAL database can touch workspace files — a quiet WAL gains
|
|
26
|
-
* `-wal`/`-shm` sidecars, a missing `-shm` gets created, and an existing
|
|
27
|
-
* `-shm` can be rewritten by WAL-index recovery (all reproduced 2026-10-28 on
|
|
28
|
-
* better-sqlite3 13.0.3, which cannot open `file:` URIs, so SQLite's
|
|
29
|
-
* immutable=1 zero-side-effect mode is unavailable). Therefore EVERY WAL-mode
|
|
30
|
-
* database is read through a staged, fingerprint-verified snapshot in a
|
|
31
|
-
* private temp directory; only rollback-journal databases keep the direct
|
|
32
|
-
* readonly open, which creates nothing. The snapshot copies the main file
|
|
33
|
-
* plus a non-empty `-wal` (the pair SQLite needs to recover un-checkpointed
|
|
34
|
-
* commits; `-shm` is an index cache and is deliberately never copied — the
|
|
35
|
-
* staged open regenerates it beside the copy).
|
|
36
|
-
*
|
|
37
|
-
* Snapshot acceptance contract (proved in stageWalSnapshot): the T1 re-check
|
|
38
|
-
* is ordered main → wal → main, making the WAL fingerprint read the single
|
|
39
|
-
* LINEARIZATION POINT. Acceptance means the staged bytes equal the real
|
|
40
|
-
* database state at that instant: the wal read observes the wal directly,
|
|
41
|
-
* and the bracketing main reads (equal to each other and to T0) pin the main
|
|
42
|
-
* bytes across the whole window — under SQLite-only writes the main file's
|
|
43
|
-
* byte-image cannot return to a previous value (monotonic change counter),
|
|
44
|
-
* so a bracketed main equal on both ends was unchanged in between. Any write
|
|
45
|
-
* completing before the linearization point is therefore caught (a commit
|
|
46
|
-
* changes the wal; a checkpoint changes main and is visible at one of the
|
|
47
|
-
* bracketing reads), and the trailing main re-read additionally rejects a
|
|
48
|
-
* checkpoint landing between the wal read and the protocol's end. An ABA
|
|
49
|
-
* rewrite (commit → checkpoint → wal delete → main bytes back at T0) cannot
|
|
50
|
-
* produce a stale acceptance: a commit surviving to the linearization point
|
|
51
|
-
* moved the main bytes and is rejected; bytes genuinely ending at the T0
|
|
52
|
-
* state mean the staged copy IS the current state, so returning it is
|
|
53
|
-
* correct. Writes after the linearization point (an un-checkpointed commit
|
|
54
|
-
* landing in the trailing window) are post-linearization events — a correct
|
|
55
|
-
* point-in-time read, not staleness. "Always latest at return time" would
|
|
56
|
-
* require writer coordination, which no available mechanism provides
|
|
57
|
-
* honestly (see the implementation report's option analysis A–D).
|
|
58
|
-
*/
|
|
59
|
-
import * as fs from 'fs';
|
|
60
|
-
import * as crypto from 'crypto';
|
|
61
|
-
import * as os from 'os';
|
|
62
|
-
import * as path from 'path';
|
|
63
|
-
import { readLedgerFileState } from '@principles/core/principle-tree-ledger';
|
|
64
|
-
import { openTrajectoryDbReadonly } from '@principles/core/trajectory-store';
|
|
65
|
-
import { RuntimeStateManager } from '@principles/core/runtime-v2';
|
|
66
|
-
export const PAIN_RECALL_SCHEMA_VERSION = 'pd.pain-recall.v1';
|
|
67
|
-
export const PAIN_RECALL_DEFAULT_LIMIT = 3;
|
|
68
|
-
export const PAIN_RECALL_MIN_LIMIT = 1;
|
|
69
|
-
export const PAIN_RECALL_MAX_LIMIT = 10;
|
|
70
|
-
function emptyResult(input) {
|
|
71
|
-
const { query, status } = input;
|
|
72
|
-
return {
|
|
73
|
-
schemaVersion: PAIN_RECALL_SCHEMA_VERSION,
|
|
74
|
-
status,
|
|
75
|
-
principle: { requestedId: query.requestedPrincipleId, canonicalId: null, identityStatus: 'not_found' },
|
|
76
|
-
query: {
|
|
77
|
-
limit: query.limit,
|
|
78
|
-
...(query.painId !== undefined ? { painId: query.painId } : {}),
|
|
79
|
-
contextUsedForRanking: false,
|
|
80
|
-
truncated: false,
|
|
81
|
-
},
|
|
82
|
-
results: [],
|
|
83
|
-
summary: { returned: 0, availableCandidates: 0, truncated: false },
|
|
84
|
-
sources: input.sources,
|
|
85
|
-
unresolvedAssociations: [],
|
|
86
|
-
...input.overwrites,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
// ── Deterministic local ranking (no model, no network) ───────────────────────
|
|
90
|
-
/** Latin/digit runs plus individual Han characters — deterministic, locale-free. */
|
|
91
|
-
function tokenize(text) {
|
|
92
|
-
const tokens = text.toLowerCase().match(/[a-z0-9]+/g) ?? [];
|
|
93
|
-
const han = text.match(/\p{Script=Han}/gu) ?? [];
|
|
94
|
-
return [...tokens, ...han];
|
|
95
|
-
}
|
|
96
|
-
function contextOverlapScore(contextTokens, doc) {
|
|
97
|
-
if (contextTokens.size === 0)
|
|
98
|
-
return 0;
|
|
99
|
-
const docTokens = new Set(tokenize(doc));
|
|
100
|
-
let score = 0;
|
|
101
|
-
for (const token of contextTokens) {
|
|
102
|
-
if (docTokens.has(token))
|
|
103
|
-
score += 1;
|
|
104
|
-
}
|
|
105
|
-
return score;
|
|
106
|
-
}
|
|
107
|
-
// ── Row guards (rc-1/rc-4: every DB/ledger value is guarded before use) ──────
|
|
108
|
-
function isRecord(value) {
|
|
109
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
110
|
-
}
|
|
111
|
-
function ownString(row, key) {
|
|
112
|
-
const value = row[key];
|
|
113
|
-
return typeof value === 'string' && value.length > 0 ? value : null;
|
|
114
|
-
}
|
|
115
|
-
function safeParseRecord(json) {
|
|
116
|
-
try {
|
|
117
|
-
const parsed = JSON.parse(json);
|
|
118
|
-
return isRecord(parsed) ? parsed : null;
|
|
119
|
-
}
|
|
120
|
-
catch {
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Deterministic fault-injection seam for snapshot-race tests — the same
|
|
126
|
-
* pattern as the runtime's databaseFactory seam (PR #2192). Every field is
|
|
127
|
-
* undefined in production; tests assign, then clear in a finally block.
|
|
128
|
-
*/
|
|
129
|
-
export const painRecallSnapshotTestHooks = {};
|
|
130
|
-
function isEnoent(err) {
|
|
131
|
-
if (!isRecord(err))
|
|
132
|
-
return false;
|
|
133
|
-
return Object.hasOwn(err, 'code') && err.code === 'ENOENT';
|
|
134
|
-
}
|
|
135
|
-
function hashFileStreaming(filePath) {
|
|
136
|
-
let fd;
|
|
137
|
-
try {
|
|
138
|
-
fd = fs.openSync(filePath, 'r');
|
|
139
|
-
}
|
|
140
|
-
catch {
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
try {
|
|
144
|
-
const hash = crypto.createHash('sha256');
|
|
145
|
-
const chunk = Buffer.alloc(128 * 1024);
|
|
146
|
-
for (;;) {
|
|
147
|
-
const read = fs.readSync(fd, chunk, 0, chunk.length, null);
|
|
148
|
-
if (read === 0)
|
|
149
|
-
break;
|
|
150
|
-
hash.update(read === chunk.length ? chunk : chunk.subarray(0, read));
|
|
151
|
-
}
|
|
152
|
-
return hash.digest('hex');
|
|
153
|
-
}
|
|
154
|
-
catch {
|
|
155
|
-
return null;
|
|
156
|
-
}
|
|
157
|
-
finally {
|
|
158
|
-
try {
|
|
159
|
-
fs.closeSync(fd);
|
|
160
|
-
}
|
|
161
|
-
catch { /* fd already closed */ }
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
function fingerprintFile(filePath) {
|
|
165
|
-
let stats;
|
|
166
|
-
try {
|
|
167
|
-
stats = (painRecallSnapshotTestHooks.statSync ?? fs.statSync)(filePath);
|
|
168
|
-
}
|
|
169
|
-
catch (err) {
|
|
170
|
-
return isEnoent(err) ? { state: 'absent' } : { state: 'unverifiable' };
|
|
171
|
-
}
|
|
172
|
-
if (!stats.isFile())
|
|
173
|
-
return { state: 'unverifiable' };
|
|
174
|
-
const hash = hashFileStreaming(filePath);
|
|
175
|
-
return hash === null ? { state: 'unverifiable' } : { state: 'present', size: stats.size, hash };
|
|
176
|
-
}
|
|
177
|
-
function fingerprintsMatch(a, b) {
|
|
178
|
-
if (a.state !== b.state)
|
|
179
|
-
return false;
|
|
180
|
-
if (a.state === 'present' && b.state === 'present') {
|
|
181
|
-
return a.size === b.size && a.hash === b.hash;
|
|
182
|
-
}
|
|
183
|
-
return true; // same non-present state (both absent, or both unverifiable)
|
|
184
|
-
}
|
|
185
|
-
function classifyWalSidecar(walFingerprint) {
|
|
186
|
-
switch (walFingerprint.state) {
|
|
187
|
-
case 'absent': return 'absent';
|
|
188
|
-
case 'unverifiable': return 'unverifiable';
|
|
189
|
-
case 'present': return walFingerprint.size === 0 ? 'quiet' : 'active';
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Decide how a database may be opened without violating the strict read-only
|
|
194
|
-
* contract. Classification is a plain 100-byte file-header read — no SQLite
|
|
195
|
-
* involvement, no side effects. Any WAL-mode header routes to 'stage': a
|
|
196
|
-
* readonly open of a WAL database can create or rewrite workspace sidecars
|
|
197
|
-
* (missing `-shm`, quiet `-wal`, WAL-index recovery), so the workspace
|
|
198
|
-
* original is never opened directly. A file whose header cannot be read is
|
|
199
|
-
* 'unverifiable' (fail closed); a non-SQLite file is 'direct' so the real
|
|
200
|
-
* open fails exactly as before.
|
|
201
|
-
*/
|
|
202
|
-
function planReadonlyOpen(dbPath) {
|
|
203
|
-
let header;
|
|
204
|
-
try {
|
|
205
|
-
const fd = fs.openSync(dbPath, 'r');
|
|
206
|
-
try {
|
|
207
|
-
header = Buffer.alloc(100);
|
|
208
|
-
if (fs.readSync(fd, header, 0, 100, 0) < 100)
|
|
209
|
-
return 'unverifiable';
|
|
210
|
-
}
|
|
211
|
-
finally {
|
|
212
|
-
fs.closeSync(fd);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
catch {
|
|
216
|
-
return 'unverifiable';
|
|
217
|
-
}
|
|
218
|
-
if (header.subarray(0, 16).toString('latin1') !== 'SQLite format 3\u0000') {
|
|
219
|
-
return 'direct'; // not a SQLite file: let the real open fail exactly as before
|
|
220
|
-
}
|
|
221
|
-
// Header bytes 18/19 (file format write/read version): 2 = WAL, 1 = rollback journal.
|
|
222
|
-
const walMode = header[18] === 2 || header[19] === 2;
|
|
223
|
-
return walMode ? 'stage' : 'direct';
|
|
224
|
-
}
|
|
225
|
-
function removeStagingRoot(root) {
|
|
226
|
-
try {
|
|
227
|
-
fs.rmSync(root, { recursive: true, force: true, maxRetries: 5, retryDelay: 50 });
|
|
228
|
-
}
|
|
229
|
-
catch {
|
|
230
|
-
// Best effort only: a leftover temp dir never affects correctness, and a
|
|
231
|
-
// cleanup failure must not mask the outcome already decided here.
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Stage a fingerprint-verified point-in-time snapshot of a WAL-mode database
|
|
236
|
-
* for reading. The workspace original is never opened: everything happens on
|
|
237
|
-
* copies under a private temp root laid out like the workspace (the caller's
|
|
238
|
-
* readonly entry points then read `<root>/<relSegments>`).
|
|
239
|
-
*
|
|
240
|
-
* Consistency contract per snapshot:
|
|
241
|
-
* 1. fingerprint (main, wal) at T0 — existence, size, SHA-256;
|
|
242
|
-
* 2. copy main, plus the `-wal` when it is present and non-empty (the pair
|
|
243
|
-
* SQLite needs to recover un-checkpointed commits; `-shm` is never
|
|
244
|
-
* copied — the staged open regenerates it beside the copy);
|
|
245
|
-
* 3. verify the staged copies hash-match the T0 fingerprints;
|
|
246
|
-
* 4. T1 re-check ordered main → wal → main (see the ordering comment at
|
|
247
|
-
* the re-check itself): the wal read is the linearization point, the
|
|
248
|
-
* trailing main re-read is a checkpoint detector for the trailing
|
|
249
|
-
* window. Any drift at any of the three reads rejects the snapshot.
|
|
250
|
-
*
|
|
251
|
-
* Acceptance ⇒ staged bytes == the real database state at the linearization
|
|
252
|
-
* point (the T1 WAL read): the wal is observed directly there, and the main
|
|
253
|
-
* is pinned across the window by the two equal bracketing reads (main's
|
|
254
|
-
* byte-image cannot return to a previous value under SQLite-only writes —
|
|
255
|
-
* monotonic change counter). Writes completing before that instant are
|
|
256
|
-
* always caught; writes after it are post-linearization (a correct
|
|
257
|
-
* point-in-time read). An ABA sequence (commit → checkpoint → wal delete →
|
|
258
|
-
* bytes back at T0) resolves safely: a surviving commit moved main and is
|
|
259
|
-
* rejected; bytes truly back at T0 make the copy the current state, so
|
|
260
|
-
* returning it is correct. Failure modes — mkdtemp failure, copy failure,
|
|
261
|
-
* fingerprint drift, undecidable file states — all return `{ ok: false }`;
|
|
262
|
-
* the caller reports the source `unreadable`. No sleep, no timing
|
|
263
|
-
* assumptions: tests inject deterministic races through
|
|
264
|
-
* `painRecallSnapshotTestHooks`.
|
|
265
|
-
*/
|
|
266
|
-
function stageWalSnapshot(sourceDbPath, relSegments) {
|
|
267
|
-
let root = null;
|
|
268
|
-
let verified = false;
|
|
269
|
-
try {
|
|
270
|
-
const mainFingerprint = fingerprintFile(sourceDbPath);
|
|
271
|
-
const walPath = `${sourceDbPath}-wal`;
|
|
272
|
-
const walFingerprint = fingerprintFile(walPath);
|
|
273
|
-
const walState = classifyWalSidecar(walFingerprint);
|
|
274
|
-
if (mainFingerprint.state !== 'present')
|
|
275
|
-
return { ok: false }; // missing/unreadable main
|
|
276
|
-
if (walState === 'unverifiable')
|
|
277
|
-
return { ok: false }; // undecidable wal state (P2-1: fail closed)
|
|
278
|
-
const copyWal = walState === 'active'; // quiet/absent: main alone is complete
|
|
279
|
-
const mkdtemp = painRecallSnapshotTestHooks.mkdtempSync ?? fs.mkdtempSync;
|
|
280
|
-
root = mkdtemp(path.join(os.tmpdir(), 'pd-pain-recall-stage-'));
|
|
281
|
-
const stagedMain = path.join(root, ...relSegments);
|
|
282
|
-
fs.mkdirSync(path.dirname(stagedMain), { recursive: true });
|
|
283
|
-
fs.copyFileSync(sourceDbPath, stagedMain);
|
|
284
|
-
painRecallSnapshotTestHooks.afterCopyFile?.(sourceDbPath, stagedMain);
|
|
285
|
-
if (copyWal) {
|
|
286
|
-
fs.copyFileSync(walPath, `${stagedMain}-wal`);
|
|
287
|
-
painRecallSnapshotTestHooks.afterCopyFile?.(walPath, `${stagedMain}-wal`);
|
|
288
|
-
}
|
|
289
|
-
// The staged bytes must equal what we fingerprinted — a torn or tampered
|
|
290
|
-
// copy is rejected before it can look like a successful read.
|
|
291
|
-
if (!fingerprintsMatch(fingerprintFile(stagedMain), mainFingerprint))
|
|
292
|
-
return { ok: false };
|
|
293
|
-
if (copyWal && !fingerprintsMatch(fingerprintFile(`${stagedMain}-wal`), walFingerprint)) {
|
|
294
|
-
return { ok: false };
|
|
295
|
-
}
|
|
296
|
-
// T1 re-check — ordered as main → wal → main so the pair sampling has a
|
|
297
|
-
// single provable linearization point (the WAL read) and the trailing
|
|
298
|
-
// main re-read acts as a checkpoint detector for the trailing window:
|
|
299
|
-
// r1 main — must still equal T0's main
|
|
300
|
-
// r2 wal — the LINEARIZATION POINT; must still equal T0's wal
|
|
301
|
-
// r3 main — trailing detector; a checkpoint in (r2, r3] changes main
|
|
302
|
-
// and conservatively rejects the whole snapshot
|
|
303
|
-
// Any write COMPLETING before r2 is caught: a commit changes the wal
|
|
304
|
-
// (visible at r2); a checkpoint changes main (visible at r1 or r3). A
|
|
305
|
-
// commit landing AFTER r2 is post-linearization — the accepted snapshot
|
|
306
|
-
// is the real database state at r2, which is a correct point-in-time
|
|
307
|
-
// read, not a stale one. (rc-7: no stale state reuse.)
|
|
308
|
-
if (!fingerprintsMatch(fingerprintFile(sourceDbPath), mainFingerprint))
|
|
309
|
-
return { ok: false };
|
|
310
|
-
painRecallSnapshotTestHooks.afterT1MainFingerprint?.(sourceDbPath);
|
|
311
|
-
if (!fingerprintsMatch(fingerprintFile(walPath), walFingerprint))
|
|
312
|
-
return { ok: false };
|
|
313
|
-
if (!fingerprintsMatch(fingerprintFile(sourceDbPath), mainFingerprint))
|
|
314
|
-
return { ok: false };
|
|
315
|
-
verified = true;
|
|
316
|
-
return { ok: true, root };
|
|
317
|
-
}
|
|
318
|
-
catch {
|
|
319
|
-
return { ok: false };
|
|
320
|
-
}
|
|
321
|
-
finally {
|
|
322
|
-
if (root !== null && !verified)
|
|
323
|
-
removeStagingRoot(root);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
// ── Main entry ───────────────────────────────────────────────────────────────
|
|
327
|
-
export async function recallPains(workspaceDir, query) {
|
|
328
|
-
// 1. Ledger — the identity authority. Missing/unreadable is a source-level
|
|
329
|
-
// failure, never a silent empty ledger.
|
|
330
|
-
const ledgerState = readLedgerFileState(path.join(workspaceDir, '.state'));
|
|
331
|
-
const ledgerAvailability = ledgerState.availability.status === 'ok'
|
|
332
|
-
? 'ok'
|
|
333
|
-
: ledgerState.availability.status === 'empty'
|
|
334
|
-
? 'missing'
|
|
335
|
-
: 'unreadable';
|
|
336
|
-
if (ledgerAvailability !== 'ok') {
|
|
337
|
-
return emptyResult({
|
|
338
|
-
query,
|
|
339
|
-
status: ledgerAvailability === 'missing' ? 'source_missing' : 'source_unreadable',
|
|
340
|
-
sources: { ledger: ledgerAvailability, trajectoryDb: 'not_checked', stateDb: 'not_checked' },
|
|
341
|
-
});
|
|
342
|
-
}
|
|
343
|
-
// 2. Canonical identity: exact ledger-key match only. Display titles and
|
|
344
|
-
// draft ids never resolve (there is no title lookup at all).
|
|
345
|
-
const principleEntry = ledgerState.ledger.tree.principles[query.requestedPrincipleId];
|
|
346
|
-
if (!isRecord(principleEntry) || ownString(principleEntry, 'id') === null) {
|
|
347
|
-
return emptyResult({
|
|
348
|
-
query,
|
|
349
|
-
status: 'principle_not_found',
|
|
350
|
-
sources: { ledger: 'ok', trajectoryDb: 'not_checked', stateDb: 'not_checked' },
|
|
351
|
-
});
|
|
352
|
-
}
|
|
353
|
-
const canonicalId = query.requestedPrincipleId;
|
|
354
|
-
const principleText = ownString(principleEntry, 'text');
|
|
355
|
-
// 3. state.db — strict readonly, no bootstrap. Missing/unreadable keeps the
|
|
356
|
-
// reuse-evidence edges alive and only degrades lineage + diagnoses.
|
|
357
|
-
// WAL-mode databases are read through a fingerprint-verified staged
|
|
358
|
-
// snapshot so nothing in the workspace is opened, created, or modified
|
|
359
|
-
// (see WAL safety note atop this module).
|
|
360
|
-
const stagedRoots = [];
|
|
361
|
-
const stateDbPath = path.join(workspaceDir, '.pd', 'state.db');
|
|
362
|
-
let stateDb = 'ok';
|
|
363
|
-
let manager = null;
|
|
364
|
-
if (!fs.existsSync(stateDbPath)) {
|
|
365
|
-
stateDb = 'missing';
|
|
366
|
-
}
|
|
367
|
-
else {
|
|
368
|
-
const plan = planReadonlyOpen(stateDbPath);
|
|
369
|
-
let stateDbAccessRoot = workspaceDir;
|
|
370
|
-
if (plan === 'unverifiable') {
|
|
371
|
-
stateDb = 'unreadable';
|
|
372
|
-
}
|
|
373
|
-
else if (plan === 'stage') {
|
|
374
|
-
const staged = stageWalSnapshot(stateDbPath, ['.pd', 'state.db']);
|
|
375
|
-
if (!staged.ok) {
|
|
376
|
-
stateDb = 'unreadable';
|
|
377
|
-
}
|
|
378
|
-
else {
|
|
379
|
-
stagedRoots.push(staged.root);
|
|
380
|
-
stateDbAccessRoot = staged.root;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
if (stateDb === 'ok') {
|
|
384
|
-
try {
|
|
385
|
-
manager = new RuntimeStateManager({ workspaceDir: stateDbAccessRoot, readonly: true, bootstrapIfMissing: false });
|
|
386
|
-
await manager.initialize();
|
|
387
|
-
// getDb() is lazy — force the readonly open NOW so a present-but-corrupt
|
|
388
|
-
// file is classified unreadable instead of surfacing per-query later.
|
|
389
|
-
// SQLite defers the header check to the first statement, hence the
|
|
390
|
-
// read-only liveness probe (SELECT 1 writes nothing).
|
|
391
|
-
manager.connection.getDb().prepare('SELECT 1 AS probe').get();
|
|
392
|
-
}
|
|
393
|
-
catch {
|
|
394
|
-
manager = null;
|
|
395
|
-
stateDb = 'unreadable';
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
try {
|
|
400
|
-
// 4. trajectory.db — the pain-event authority. Missing/unreadable is a
|
|
401
|
-
// source-level failure (recall's subject is the pain history itself).
|
|
402
|
-
// Same WAL staging rule as state.db: the workspace original is opened
|
|
403
|
-
// directly only in rollback-journal mode; any snapshot failure fails
|
|
404
|
-
// the source as unreadable — never an empty result.
|
|
405
|
-
let trajectoryDb;
|
|
406
|
-
try {
|
|
407
|
-
const trajectoryDbPath = path.join(workspaceDir, '.state', 'trajectory.db');
|
|
408
|
-
let trajectoryAccessRoot = workspaceDir;
|
|
409
|
-
if (fs.existsSync(trajectoryDbPath)) {
|
|
410
|
-
const plan = planReadonlyOpen(trajectoryDbPath);
|
|
411
|
-
if (plan === 'unverifiable') {
|
|
412
|
-
throw new Error('readonly_precondition_failed: trajectory.db header state unverifiable');
|
|
413
|
-
}
|
|
414
|
-
if (plan === 'stage') {
|
|
415
|
-
const staged = stageWalSnapshot(trajectoryDbPath, ['.state', 'trajectory.db']);
|
|
416
|
-
if (!staged.ok) {
|
|
417
|
-
throw new Error('readonly_precondition_failed: trajectory.db snapshot could not be verified');
|
|
418
|
-
}
|
|
419
|
-
stagedRoots.push(staged.root);
|
|
420
|
-
trajectoryAccessRoot = staged.root;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
trajectoryDb = openTrajectoryDbReadonly(trajectoryAccessRoot);
|
|
424
|
-
// SQLite defers the file-header check to the first statement (same as
|
|
425
|
-
// state.db above): probe pain_events NOW so a corrupt file or a
|
|
426
|
-
// schema-less database falls into the source_unreadable classification
|
|
427
|
-
// instead of escaping as a raw query error. Close before rethrowing so
|
|
428
|
-
// no handle leaks into the failure path.
|
|
429
|
-
try {
|
|
430
|
-
trajectoryDb.prepare('SELECT 1 FROM pain_events LIMIT 1').get();
|
|
431
|
-
}
|
|
432
|
-
catch (probeErr) {
|
|
433
|
-
trajectoryDb.close();
|
|
434
|
-
throw probeErr;
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
catch {
|
|
438
|
-
const missing = !fs.existsSync(path.join(workspaceDir, '.state', 'trajectory.db'));
|
|
439
|
-
return emptyResult({
|
|
440
|
-
query,
|
|
441
|
-
status: missing ? 'source_missing' : 'source_unreadable',
|
|
442
|
-
sources: { ledger: 'ok', trajectoryDb: missing ? 'missing' : 'unreadable', stateDb },
|
|
443
|
-
});
|
|
444
|
-
}
|
|
445
|
-
try {
|
|
446
|
-
// 5. Association edges from the two authoritative sources.
|
|
447
|
-
const unresolved = [];
|
|
448
|
-
const edges = [];
|
|
449
|
-
const { reuseEvidence } = principleEntry;
|
|
450
|
-
if (Array.isArray(reuseEvidence)) {
|
|
451
|
-
for (const entry of reuseEvidence) {
|
|
452
|
-
if (!isRecord(entry))
|
|
453
|
-
continue;
|
|
454
|
-
const painId = ownString(entry, 'painId');
|
|
455
|
-
const candidateId = ownString(entry, 'candidateId');
|
|
456
|
-
if (painId === null || candidateId === null)
|
|
457
|
-
continue; // malformed row: not a verifiable edge
|
|
458
|
-
edges.push({
|
|
459
|
-
painId,
|
|
460
|
-
explicit: true,
|
|
461
|
-
ref: {
|
|
462
|
-
kind: 'reuse_evidence',
|
|
463
|
-
candidateId,
|
|
464
|
-
...(ownString(entry, 'decidedAt') !== null ? { decidedAt: ownString(entry, 'decidedAt') ?? undefined } : {}),
|
|
465
|
-
...(ownString(entry, 'decisionId') !== null ? { decisionId: ownString(entry, 'decisionId') ?? undefined } : {}),
|
|
466
|
-
},
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
const derivedIds = principleEntry.derivedFromPainIds;
|
|
471
|
-
if (Array.isArray(derivedIds)) {
|
|
472
|
-
for (const value of derivedIds) {
|
|
473
|
-
if (typeof value !== 'string' || value.length === 0)
|
|
474
|
-
continue;
|
|
475
|
-
const candidateId = value; // candidate id by production contract, despite the field name
|
|
476
|
-
if (manager === null) {
|
|
477
|
-
unresolved.push({ candidateId, reason: 'state_db_unavailable' });
|
|
478
|
-
continue;
|
|
479
|
-
}
|
|
480
|
-
let candidateTaskId = null;
|
|
481
|
-
try {
|
|
482
|
-
const candidate = await manager.getCandidate(candidateId);
|
|
483
|
-
candidateTaskId = candidate !== null && typeof candidate.taskId === 'string' && candidate.taskId.length > 0
|
|
484
|
-
? candidate.taskId
|
|
485
|
-
: null;
|
|
486
|
-
}
|
|
487
|
-
catch {
|
|
488
|
-
unresolved.push({ candidateId, reason: 'candidate_query_failed' });
|
|
489
|
-
continue;
|
|
490
|
-
}
|
|
491
|
-
if (candidateTaskId === null) {
|
|
492
|
-
unresolved.push({ candidateId, reason: 'candidate_not_found' });
|
|
493
|
-
continue;
|
|
494
|
-
}
|
|
495
|
-
let painId = null;
|
|
496
|
-
try {
|
|
497
|
-
const task = await manager.getTask(candidateTaskId);
|
|
498
|
-
const inputRef = task !== null && typeof task.inputRef === 'string' && task.inputRef.length > 0
|
|
499
|
-
? task.inputRef
|
|
500
|
-
: null;
|
|
501
|
-
painId = inputRef;
|
|
502
|
-
}
|
|
503
|
-
catch {
|
|
504
|
-
painId = null;
|
|
505
|
-
}
|
|
506
|
-
if (painId === null && candidateTaskId.startsWith('diagnosis_') && candidateTaskId.length > 'diagnosis_'.length) {
|
|
507
|
-
painId = candidateTaskId.slice('diagnosis_'.length); // authoritative task-id spelling fallback
|
|
508
|
-
}
|
|
509
|
-
if (painId === null) {
|
|
510
|
-
unresolved.push({ candidateId, reason: 'pain_unresolvable_from_candidate' });
|
|
511
|
-
continue;
|
|
512
|
-
}
|
|
513
|
-
edges.push({
|
|
514
|
-
painId,
|
|
515
|
-
explicit: false,
|
|
516
|
-
ref: { kind: 'candidate_lineage', candidateId, taskId: candidateTaskId },
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
// 6. Merge by real pain id — all evidence refs survive the merge.
|
|
521
|
-
const merged = new Map();
|
|
522
|
-
for (const edge of edges) {
|
|
523
|
-
const existing = merged.get(edge.painId);
|
|
524
|
-
if (existing) {
|
|
525
|
-
existing.refs.push(edge.ref);
|
|
526
|
-
existing.explicit = existing.explicit || edge.explicit;
|
|
527
|
-
}
|
|
528
|
-
else {
|
|
529
|
-
merged.set(edge.painId, { painId: edge.painId, refs: [edge.ref], explicit: edge.explicit });
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
// 7. Pain events: an edge whose pain has no persisted event is reported,
|
|
533
|
-
// not returned, and not silently dropped.
|
|
534
|
-
const painRows = new Map();
|
|
535
|
-
const selectPain = trajectoryDb.prepare('SELECT id, source, score, severity, text, reason, canonical_pain_id, runtime_task_id, host_kind, created_at FROM pain_events WHERE canonical_pain_id = ? ORDER BY created_at DESC, id DESC LIMIT 1');
|
|
536
|
-
for (const painId of [...merged.keys()]) {
|
|
537
|
-
const row = selectPain.get(painId);
|
|
538
|
-
if (!isRecord(row)) {
|
|
539
|
-
unresolved.push({ painId, reason: 'pain_event_not_found' });
|
|
540
|
-
merged.delete(painId);
|
|
541
|
-
}
|
|
542
|
-
else {
|
|
543
|
-
painRows.set(painId, row);
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
// 8. --pain-id: filters WITHIN the verified association set only.
|
|
547
|
-
if (query.painId !== undefined) {
|
|
548
|
-
if (!merged.has(query.painId)) {
|
|
549
|
-
const exists = isRecord(selectPain.get(query.painId) ?? null);
|
|
550
|
-
return emptyResult({
|
|
551
|
-
query,
|
|
552
|
-
status: 'pain_not_found',
|
|
553
|
-
sources: { ledger: 'ok', trajectoryDb: 'ok', stateDb },
|
|
554
|
-
overwrites: { statusDetail: exists ? 'not_associated' : 'pain_event_not_found' },
|
|
555
|
-
});
|
|
556
|
-
}
|
|
557
|
-
for (const painId of [...merged.keys()]) {
|
|
558
|
-
if (painId !== query.painId)
|
|
559
|
-
merged.delete(painId);
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
// 9. Per-pain enrichment (diagnoses + persisted correction evidence).
|
|
563
|
-
const entries = [];
|
|
564
|
-
for (const [painId, edge] of merged) {
|
|
565
|
-
const row = painRows.get(painId);
|
|
566
|
-
if (!isRecord(row))
|
|
567
|
-
continue; // step 7 guaranteed presence; guard anyway (rc-1)
|
|
568
|
-
const pain = {
|
|
569
|
-
occurredAt: ownString(row, 'created_at'),
|
|
570
|
-
source: ownString(row, 'source'),
|
|
571
|
-
host: ownString(row, 'host_kind') ?? 'unknown',
|
|
572
|
-
score: typeof row.score === 'number' ? row.score : null,
|
|
573
|
-
severity: ownString(row, 'severity'),
|
|
574
|
-
reason: ownString(row, 'reason'),
|
|
575
|
-
text: ownString(row, 'text'),
|
|
576
|
-
rawStatement: null,
|
|
577
|
-
};
|
|
578
|
-
let diagnoses = [];
|
|
579
|
-
// Every branch below assigns this before use (CodeQL useless-init).
|
|
580
|
-
let diagnosesAvailability;
|
|
581
|
-
let correction = null;
|
|
582
|
-
// Initializer is meaningful: a successful read with no persisted
|
|
583
|
-
// correction evidence keeps this 'not_recorded'.
|
|
584
|
-
let correctionAvailability = 'not_recorded';
|
|
585
|
-
if (manager === null) {
|
|
586
|
-
diagnosesAvailability = 'unreadable';
|
|
587
|
-
correctionAvailability = 'unreadable';
|
|
588
|
-
}
|
|
589
|
-
else {
|
|
590
|
-
try {
|
|
591
|
-
const records = await manager.getDiagnosesByPainId(painId);
|
|
592
|
-
diagnoses = records.map((record) => ({
|
|
593
|
-
diagnosisId: record.diagnosisId,
|
|
594
|
-
taskId: record.taskId,
|
|
595
|
-
category: record.category,
|
|
596
|
-
rootCause: record.rootCause,
|
|
597
|
-
supportingEvidence: record.evidence.map((e) => ({ sourceRef: e.sourceRef, note: e.note })),
|
|
598
|
-
confidence: record.confidence,
|
|
599
|
-
isOriginalOwnerStatement: false,
|
|
600
|
-
}));
|
|
601
|
-
diagnosesAvailability = diagnoses.length > 0 ? 'available' : 'not_recorded';
|
|
602
|
-
}
|
|
603
|
-
catch {
|
|
604
|
-
diagnosesAvailability = 'unreadable';
|
|
605
|
-
}
|
|
606
|
-
try {
|
|
607
|
-
const diagnosisTask = await manager.getTask(`diagnosis_${painId}`);
|
|
608
|
-
const payload = diagnosisTask !== null && typeof diagnosisTask.diagnosticJson === 'string'
|
|
609
|
-
? safeParseRecord(diagnosisTask.diagnosticJson)
|
|
610
|
-
: null;
|
|
611
|
-
const persisted = payload !== null ? payload.correctionEvidence : undefined;
|
|
612
|
-
if (isRecord(persisted) && typeof persisted.text === 'string' && persisted.text.length > 0) {
|
|
613
|
-
correction = {
|
|
614
|
-
text: persisted.text,
|
|
615
|
-
...(ownString(persisted, 'classification') !== null ? { classification: ownString(persisted, 'classification') ?? undefined } : {}),
|
|
616
|
-
...(ownString(persisted, 'channel') !== null ? { channel: ownString(persisted, 'channel') ?? undefined } : {}),
|
|
617
|
-
...(ownString(persisted, 'sessionId') !== null ? { sessionId: ownString(persisted, 'sessionId') ?? undefined } : {}),
|
|
618
|
-
...(ownString(persisted, 'occurredAt') !== null ? { occurredAt: ownString(persisted, 'occurredAt') ?? undefined } : {}),
|
|
619
|
-
};
|
|
620
|
-
correctionAvailability = 'available';
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
catch {
|
|
624
|
-
correctionAvailability = 'unreadable';
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
const type = edge.refs.length > 1
|
|
628
|
-
? 'multiple_paths'
|
|
629
|
-
: edge.explicit
|
|
630
|
-
? 'explicit_reuse'
|
|
631
|
-
: 'derived_from';
|
|
632
|
-
const lineage = [];
|
|
633
|
-
for (const ref of edge.refs) {
|
|
634
|
-
if (ref.kind === 'candidate_lineage') {
|
|
635
|
-
lineage.push({ from: `principle:${canonicalId}`, to: ref.candidateId, relation: 'derived_from_pain_ids' });
|
|
636
|
-
lineage.push({ from: ref.candidateId, to: painId, relation: 'task_input_ref' });
|
|
637
|
-
}
|
|
638
|
-
else {
|
|
639
|
-
lineage.push({ from: `principle:${canonicalId}`, to: painId, relation: 'reuse_evidence_pain_id' });
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
entries.push({
|
|
643
|
-
painId,
|
|
644
|
-
association: {
|
|
645
|
-
type,
|
|
646
|
-
confidence: edge.explicit ? 'explicit' : 'lineage_verified',
|
|
647
|
-
evidenceRefs: edge.refs,
|
|
648
|
-
},
|
|
649
|
-
pain,
|
|
650
|
-
diagnoses,
|
|
651
|
-
correctionEvidence: correction,
|
|
652
|
-
availability: { painEvent: 'available', diagnoses: diagnosesAvailability, correctionEvidence: correctionAvailability },
|
|
653
|
-
lineage,
|
|
654
|
-
});
|
|
655
|
-
}
|
|
656
|
-
// 10. Deterministic ranking. Default: explicit evidence first, then
|
|
657
|
-
// newest pain first, then pain id. --context only re-orders this
|
|
658
|
-
// list by local token overlap — it never adds associations.
|
|
659
|
-
const contextTokens = new Set(typeof query.context === 'string' ? tokenize(query.context) : []);
|
|
660
|
-
const contextUsed = contextTokens.size > 0;
|
|
661
|
-
const rankOf = (entry) => (entry.association.confidence === 'explicit' ? 0 : 1);
|
|
662
|
-
const scored = entries.map((entry) => ({
|
|
663
|
-
entry,
|
|
664
|
-
score: contextUsed
|
|
665
|
-
? contextOverlapScore(contextTokens, [entry.pain.reason ?? '', entry.pain.text ?? '', ...entry.diagnoses.map((d) => d.rootCause)].join(' '))
|
|
666
|
-
: 0,
|
|
667
|
-
}));
|
|
668
|
-
scored.sort((a, b) => {
|
|
669
|
-
if (b.score !== a.score)
|
|
670
|
-
return b.score - a.score;
|
|
671
|
-
const rankDelta = rankOf(a.entry) - rankOf(b.entry);
|
|
672
|
-
if (rankDelta !== 0)
|
|
673
|
-
return rankDelta;
|
|
674
|
-
const aTime = a.entry.pain.occurredAt ?? '';
|
|
675
|
-
const bTime = b.entry.pain.occurredAt ?? '';
|
|
676
|
-
if (aTime !== bTime)
|
|
677
|
-
return aTime < bTime ? 1 : -1; // newest first
|
|
678
|
-
return a.entry.painId < b.entry.painId ? -1 : 1;
|
|
679
|
-
});
|
|
680
|
-
const ranked = scored.map((s) => s.entry);
|
|
681
|
-
// 11. Limit + truncation.
|
|
682
|
-
const truncated = ranked.length > query.limit;
|
|
683
|
-
const results = ranked.slice(0, query.limit);
|
|
684
|
-
// 12. Top-level status: distinguish "nothing recorded" from "cannot read".
|
|
685
|
-
let status;
|
|
686
|
-
if (results.length === 0) {
|
|
687
|
-
status = unresolved.length > 0 ? 'partial' : 'no_matches';
|
|
688
|
-
}
|
|
689
|
-
else {
|
|
690
|
-
const degraded = results.some((r) => r.availability.diagnoses === 'unreadable' || r.availability.correctionEvidence === 'unreadable');
|
|
691
|
-
status = degraded ? 'partial' : 'ok';
|
|
692
|
-
}
|
|
693
|
-
return {
|
|
694
|
-
schemaVersion: PAIN_RECALL_SCHEMA_VERSION,
|
|
695
|
-
status,
|
|
696
|
-
principle: {
|
|
697
|
-
requestedId: query.requestedPrincipleId,
|
|
698
|
-
canonicalId,
|
|
699
|
-
identityStatus: 'resolved',
|
|
700
|
-
...(principleText !== null ? { text: principleText } : {}),
|
|
701
|
-
},
|
|
702
|
-
query: {
|
|
703
|
-
limit: query.limit,
|
|
704
|
-
...(query.painId !== undefined ? { painId: query.painId } : {}),
|
|
705
|
-
contextUsedForRanking: contextUsed,
|
|
706
|
-
truncated,
|
|
707
|
-
},
|
|
708
|
-
results,
|
|
709
|
-
summary: { returned: results.length, availableCandidates: ranked.length, truncated },
|
|
710
|
-
sources: { ledger: 'ok', trajectoryDb: 'ok', stateDb },
|
|
711
|
-
unresolvedAssociations: unresolved,
|
|
712
|
-
};
|
|
713
|
-
}
|
|
714
|
-
finally {
|
|
715
|
-
trajectoryDb.close();
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
finally {
|
|
719
|
-
if (manager !== null) {
|
|
720
|
-
await manager.close().catch(() => undefined);
|
|
721
|
-
}
|
|
722
|
-
for (const root of stagedRoots) {
|
|
723
|
-
removeStagingRoot(root);
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
//# sourceMappingURL=pain-recall.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pain-recall.js","sourceRoot":"","sources":["../../src/services/pain-recall.ts"],"names":[],"mappings":"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"}
|