@principles/core 1.297.11 → 1.298.1

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 (79) hide show
  1. package/dist/runtime-v2/activation/activation-dispatcher.d.ts +2 -0
  2. package/dist/runtime-v2/activation/activation-dispatcher.d.ts.map +1 -1
  3. package/dist/runtime-v2/activation/activation-dispatcher.js +60 -22
  4. package/dist/runtime-v2/activation/activation-dispatcher.js.map +1 -1
  5. package/dist/runtime-v2/activation/activation-types.d.ts +12 -2
  6. package/dist/runtime-v2/activation/activation-types.d.ts.map +1 -1
  7. package/dist/runtime-v2/activation/activation-types.js.map +1 -1
  8. package/dist/runtime-v2/activation/index.d.ts +2 -0
  9. package/dist/runtime-v2/activation/index.d.ts.map +1 -1
  10. package/dist/runtime-v2/activation/index.js +2 -0
  11. package/dist/runtime-v2/activation/index.js.map +1 -1
  12. package/dist/runtime-v2/activation/rule-replacement.d.ts +38 -0
  13. package/dist/runtime-v2/activation/rule-replacement.d.ts.map +1 -0
  14. package/dist/runtime-v2/activation/rule-replacement.js +44 -0
  15. package/dist/runtime-v2/activation/rule-replacement.js.map +1 -0
  16. package/dist/runtime-v2/activation/sqlite-activation-state-store.d.ts +9 -1
  17. package/dist/runtime-v2/activation/sqlite-activation-state-store.d.ts.map +1 -1
  18. package/dist/runtime-v2/activation/sqlite-activation-state-store.js +53 -23
  19. package/dist/runtime-v2/activation/sqlite-activation-state-store.js.map +1 -1
  20. package/dist/runtime-v2/activation/writers/rule-host-writer.d.ts.map +1 -1
  21. package/dist/runtime-v2/activation/writers/rule-host-writer.js +15 -2
  22. package/dist/runtime-v2/activation/writers/rule-host-writer.js.map +1 -1
  23. package/dist/runtime-v2/adapter/principle-tree-ledger-adapter.d.ts +2 -0
  24. package/dist/runtime-v2/adapter/principle-tree-ledger-adapter.d.ts.map +1 -1
  25. package/dist/runtime-v2/adapter/principle-tree-ledger-adapter.js +5 -1
  26. package/dist/runtime-v2/adapter/principle-tree-ledger-adapter.js.map +1 -1
  27. package/dist/runtime-v2/index.d.ts +3 -1
  28. package/dist/runtime-v2/index.d.ts.map +1 -1
  29. package/dist/runtime-v2/index.js +2 -1
  30. package/dist/runtime-v2/index.js.map +1 -1
  31. package/dist/runtime-v2/internalization/approved-rule-revision.d.ts +51 -0
  32. package/dist/runtime-v2/internalization/approved-rule-revision.d.ts.map +1 -0
  33. package/dist/runtime-v2/internalization/approved-rule-revision.js +211 -0
  34. package/dist/runtime-v2/internalization/approved-rule-revision.js.map +1 -0
  35. package/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts +1 -1
  36. package/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts.map +1 -1
  37. package/dist/runtime-v2/internalization/artificer-prompt-builder.js +2 -1
  38. package/dist/runtime-v2/internalization/artificer-prompt-builder.js.map +1 -1
  39. package/dist/runtime-v2/internalization/bash-risk.d.ts +4 -0
  40. package/dist/runtime-v2/internalization/bash-risk.d.ts.map +1 -1
  41. package/dist/runtime-v2/internalization/bash-risk.js +42 -0
  42. package/dist/runtime-v2/internalization/bash-risk.js.map +1 -1
  43. package/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
  44. package/dist/runtime-v2/internalization/evaluator-runner.js +4 -1
  45. package/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
  46. package/dist/runtime-v2/internalization/peer-runner-contracts.d.ts +2 -1
  47. package/dist/runtime-v2/internalization/peer-runner-contracts.d.ts.map +1 -1
  48. package/dist/runtime-v2/internalization/peer-runner-contracts.js.map +1 -1
  49. package/dist/runtime-v2/internalization/pitask-metadata.d.ts +21 -0
  50. package/dist/runtime-v2/internalization/pitask-metadata.d.ts.map +1 -1
  51. package/dist/runtime-v2/internalization/pitask-metadata.js +30 -0
  52. package/dist/runtime-v2/internalization/pitask-metadata.js.map +1 -1
  53. package/dist/runtime-v2/internalization/rule-host-contracts.d.ts +2 -0
  54. package/dist/runtime-v2/internalization/rule-host-contracts.d.ts.map +1 -1
  55. package/dist/runtime-v2/internalization/rule-host-input-builder.d.ts.map +1 -1
  56. package/dist/runtime-v2/internalization/rule-host-input-builder.js +6 -0
  57. package/dist/runtime-v2/internalization/rule-host-input-builder.js.map +1 -1
  58. package/dist/runtime-v2/internalization/rulecode-verification-obligations.d.ts.map +1 -1
  59. package/dist/runtime-v2/internalization/rulecode-verification-obligations.js +32 -0
  60. package/dist/runtime-v2/internalization/rulecode-verification-obligations.js.map +1 -1
  61. package/dist/runtime-v2/pain-recall-capability.d.ts +140 -0
  62. package/dist/runtime-v2/pain-recall-capability.d.ts.map +1 -0
  63. package/dist/runtime-v2/pain-recall-capability.js +334 -0
  64. package/dist/runtime-v2/pain-recall-capability.js.map +1 -0
  65. package/dist/runtime-v2/pain-recall-read-model.d.ts +113 -0
  66. package/dist/runtime-v2/pain-recall-read-model.d.ts.map +1 -0
  67. package/dist/runtime-v2/pain-recall-read-model.js +724 -0
  68. package/dist/runtime-v2/pain-recall-read-model.js.map +1 -0
  69. package/dist/runtime-v2/pain-recall-snapshot-hooks.d.ts +39 -0
  70. package/dist/runtime-v2/pain-recall-snapshot-hooks.d.ts.map +1 -0
  71. package/dist/runtime-v2/pain-recall-snapshot-hooks.js +15 -0
  72. package/dist/runtime-v2/pain-recall-snapshot-hooks.js.map +1 -0
  73. package/dist/runtime-v2/proven-channel-baseline.js +1 -1
  74. package/dist/runtime-v2/proven-channel-baseline.js.map +1 -1
  75. package/dist/runtime-v2/store/task/sqlite-approved-rule-revision.d.ts +15 -0
  76. package/dist/runtime-v2/store/task/sqlite-approved-rule-revision.d.ts.map +1 -0
  77. package/dist/runtime-v2/store/task/sqlite-approved-rule-revision.js +39 -0
  78. package/dist/runtime-v2/store/task/sqlite-approved-rule-revision.js.map +1 -0
  79. package/package.json +9 -1
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Pain Recall Capability Facade — SPEC-PD-AGENT-CAPABILITY-API-001 v0.5 §7/§8.
3
+ *
4
+ * The single OD-A projection authority: constructs the protocol-independent
5
+ * `pd.capability.v1` envelope for `pd_recall_principle_pains` from the full
6
+ * PainRecallResult produced by the read model. The envelope is built
7
+ * field-by-field from the frozen od-a-v1 whitelist ("construction IS the
8
+ * whitelist") — DENY fields (canonicalId, painId, evidenceRefs, pain text,
9
+ * diagnoses.*, correctionEvidence.*, lineage hops, statusDetail-as-data, …)
10
+ * are structurally absent, never constructed-then-stripped.
11
+ *
12
+ * Every call re-asserts BOTH the leaf-key path set AND the structural
13
+ * container paths of the produced envelope (array indices normalized to
14
+ * `[]`); any non-whitelisted leaf — or any container that is not a proper
15
+ * ancestor of a whitelisted leaf (this catches a forbidden key hiding in an
16
+ * EMPTY array or object, which a leaf-only walk cannot see) — fails closed:
17
+ * the violating payload is withheld and an `unavailable` envelope with a
18
+ * stable internal error code is returned instead. The production self-check
19
+ * does NOT include the Gate 2 experimental sentinel regex — sentinel
20
+ * scanning is a test technique (see the capability tests).
21
+ *
22
+ * Layer contract (v0.5 §7.1): this facade is protocol-independent. It does
23
+ * NOT build MCP `content` blocks, does NOT set `isError`, and contains no
24
+ * transport/execution-boundary logic — the 32 KiB response budget and the
25
+ * 10 s call deadline are MCP Adapter (Gate 4) responsibilities and must not
26
+ * be implemented here. Read-model execution errors (an unexpected throw)
27
+ * propagate to the Adapter, which maps them per the Gate 4 contract; they
28
+ * are deliberately NOT swallowed into this envelope (v0.5 §7.3).
29
+ *
30
+ * Zero file I/O: everything is an in-memory projection over the read model's
31
+ * result, so this module is not registered in io-seam-registry.json (only
32
+ * files that actually perform controlled I/O are registered).
33
+ *
34
+ * OD-A scope (Owner decision 2026-11-01, v0.5 §8.2): od-a-v1 governs MCP
35
+ * Tool RESPONSE DISCLOSURE only. It is not a global agent data boundary and
36
+ * does not prevent the existing CLI (Skill-guided) from returning the full
37
+ * `pd.pain-recall.v1` output.
38
+ */
39
+ import { type AssociationType, type ItemAvailability, type SourceAvailability } from './pain-recall-read-model.js';
40
+ export declare const CAPABILITY_SCHEMA_VERSION: 'pd.capability.v1';
41
+ export declare const OD_A_DISCLOSURE_PROFILE: 'od-a-v1';
42
+ export declare const RECALL_PAIN_CAPABILITY_ID: 'pd_recall_principle_pains';
43
+ /** Trusted-context input. `workspaceDir` is injected by the Adapter (launch
44
+ * configuration); it must NEVER be a model-supplied tool parameter. */
45
+ export interface PainRecallCapabilityInput {
46
+ readonly workspaceDir: string;
47
+ readonly principleId: string;
48
+ readonly limit?: number;
49
+ }
50
+ export type PainRecallCapabilityStatus = 'ok' | 'no_matches' | 'partial' | 'not_found' | 'unavailable' | 'invalid_input';
51
+ export interface PainRecallCapabilityPrinciple {
52
+ readonly requestedId: string;
53
+ readonly identityStatus: 'resolved' | 'not_found' | 'ambiguous';
54
+ }
55
+ export interface PainRecallCapabilityQuery {
56
+ readonly limit: number;
57
+ readonly contextUsedForRanking: boolean;
58
+ readonly truncated: boolean;
59
+ }
60
+ export interface PainRecallCapabilityResultEntry {
61
+ readonly association: {
62
+ readonly type: AssociationType;
63
+ readonly confidence: 'explicit' | 'lineage_verified';
64
+ };
65
+ readonly availability: {
66
+ readonly painEvent: 'available';
67
+ readonly diagnoses: ItemAvailability;
68
+ readonly correctionEvidence: ItemAvailability;
69
+ };
70
+ }
71
+ export interface PainRecallCapabilityData {
72
+ readonly principle: PainRecallCapabilityPrinciple;
73
+ readonly query: PainRecallCapabilityQuery;
74
+ readonly results: readonly PainRecallCapabilityResultEntry[];
75
+ readonly summary: {
76
+ readonly returned: number;
77
+ readonly availableCandidates: number;
78
+ readonly truncated: boolean;
79
+ };
80
+ readonly sources: {
81
+ readonly ledger: SourceAvailability;
82
+ readonly trajectoryDb: SourceAvailability;
83
+ readonly stateDb: SourceAvailability;
84
+ };
85
+ readonly unresolvedAssociations: readonly {
86
+ readonly reason: string;
87
+ }[];
88
+ }
89
+ export interface PainRecallCapabilityProvenanceSource {
90
+ readonly name: 'ledger' | 'trajectoryDb' | 'stateDb';
91
+ readonly status: SourceAvailability;
92
+ }
93
+ export interface PainRecallCapabilityProvenance {
94
+ readonly workspaceBinding: 'configured';
95
+ readonly sources: readonly PainRecallCapabilityProvenanceSource[];
96
+ }
97
+ export interface PainRecallCapabilityWarning {
98
+ readonly code: string;
99
+ readonly message: string;
100
+ }
101
+ export interface PainRecallCapabilityError {
102
+ readonly code: string;
103
+ readonly message: string;
104
+ }
105
+ export interface PainRecallCapabilityNextAction {
106
+ readonly code: string;
107
+ readonly message: string;
108
+ }
109
+ /** The `pd.capability.v1` envelope (v0.5 §7.2). `data` is non-null for every
110
+ * status except `unavailable` and `invalid_input`, where nothing may be
111
+ * disclosed about the workspace. */
112
+ export interface PainRecallCapabilityResult {
113
+ readonly schemaVersion: typeof CAPABILITY_SCHEMA_VERSION;
114
+ readonly capability: typeof RECALL_PAIN_CAPABILITY_ID;
115
+ readonly disclosureProfile: typeof OD_A_DISCLOSURE_PROFILE;
116
+ readonly status: PainRecallCapabilityStatus;
117
+ readonly data: PainRecallCapabilityData | null;
118
+ readonly provenance: PainRecallCapabilityProvenance;
119
+ readonly warnings: readonly PainRecallCapabilityWarning[];
120
+ readonly error: PainRecallCapabilityError | null;
121
+ readonly nextAction: PainRecallCapabilityNextAction | null;
122
+ }
123
+ /**
124
+ * Recall a principle's verifiably-associated historical pains through the
125
+ * od-a-v1 disclosure profile.
126
+ *
127
+ * Duty sequence (v0.5 §7.1): validate input (fail-closed `invalid_input`,
128
+ * the read model is never called on bad input) → `recallPains` on the trusted
129
+ * workspace → OD-A projection (construction IS the whitelist) → leaf AND
130
+ * structural key-path self-check (violation ⇒ withhold the payload, return
131
+ * `unavailable`) → return.
132
+ *
133
+ * Resource constraint owned here (v0.5 §7.5.2, the only Core-layer limit):
134
+ * `limit ∈ [1, 10]`, default `PAIN_RECALL_DEFAULT_LIMIT` (3); the returned
135
+ * entry count is bounded by the read model's existing truncation semantics
136
+ * (≤ limit ≤ 10). The 32 KiB response budget and the 10 s deadline are NOT
137
+ * implemented here — they are Gate 4 MCP Adapter responsibilities.
138
+ */
139
+ export declare function recallPrinciplePainsCapability(input: PainRecallCapabilityInput): Promise<PainRecallCapabilityResult>;
140
+ //# sourceMappingURL=pain-recall-capability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pain-recall-capability.d.ts","sourceRoot":"","sources":["../../src/runtime-v2/pain-recall-capability.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,334 @@
1
+ /**
2
+ * Pain Recall Capability Facade — SPEC-PD-AGENT-CAPABILITY-API-001 v0.5 §7/§8.
3
+ *
4
+ * The single OD-A projection authority: constructs the protocol-independent
5
+ * `pd.capability.v1` envelope for `pd_recall_principle_pains` from the full
6
+ * PainRecallResult produced by the read model. The envelope is built
7
+ * field-by-field from the frozen od-a-v1 whitelist ("construction IS the
8
+ * whitelist") — DENY fields (canonicalId, painId, evidenceRefs, pain text,
9
+ * diagnoses.*, correctionEvidence.*, lineage hops, statusDetail-as-data, …)
10
+ * are structurally absent, never constructed-then-stripped.
11
+ *
12
+ * Every call re-asserts BOTH the leaf-key path set AND the structural
13
+ * container paths of the produced envelope (array indices normalized to
14
+ * `[]`); any non-whitelisted leaf — or any container that is not a proper
15
+ * ancestor of a whitelisted leaf (this catches a forbidden key hiding in an
16
+ * EMPTY array or object, which a leaf-only walk cannot see) — fails closed:
17
+ * the violating payload is withheld and an `unavailable` envelope with a
18
+ * stable internal error code is returned instead. The production self-check
19
+ * does NOT include the Gate 2 experimental sentinel regex — sentinel
20
+ * scanning is a test technique (see the capability tests).
21
+ *
22
+ * Layer contract (v0.5 §7.1): this facade is protocol-independent. It does
23
+ * NOT build MCP `content` blocks, does NOT set `isError`, and contains no
24
+ * transport/execution-boundary logic — the 32 KiB response budget and the
25
+ * 10 s call deadline are MCP Adapter (Gate 4) responsibilities and must not
26
+ * be implemented here. Read-model execution errors (an unexpected throw)
27
+ * propagate to the Adapter, which maps them per the Gate 4 contract; they
28
+ * are deliberately NOT swallowed into this envelope (v0.5 §7.3).
29
+ *
30
+ * Zero file I/O: everything is an in-memory projection over the read model's
31
+ * result, so this module is not registered in io-seam-registry.json (only
32
+ * files that actually perform controlled I/O are registered).
33
+ *
34
+ * OD-A scope (Owner decision 2026-11-01, v0.5 §8.2): od-a-v1 governs MCP
35
+ * Tool RESPONSE DISCLOSURE only. It is not a global agent data boundary and
36
+ * does not prevent the existing CLI (Skill-guided) from returning the full
37
+ * `pd.pain-recall.v1` output.
38
+ */
39
+ import { recallPains, PAIN_RECALL_DEFAULT_LIMIT, PAIN_RECALL_MIN_LIMIT, PAIN_RECALL_MAX_LIMIT, } from './pain-recall-read-model.js';
40
+ export const CAPABILITY_SCHEMA_VERSION = 'pd.capability.v1';
41
+ export const OD_A_DISCLOSURE_PROFILE = 'od-a-v1';
42
+ export const RECALL_PAIN_CAPABILITY_ID = 'pd_recall_principle_pains';
43
+ /**
44
+ * Frozen od-a-v1 allowed leaf-key paths (array indices normalized to `[]`).
45
+ * Copied field-by-field from the hash-anchored Gate 2 executable projection
46
+ * (`project.mjs` ALLOWED_PATHS) plus the single v0.5 addition
47
+ * `disclosureProfile`. NOT exported: the contract is pinned behaviorally by
48
+ * the capability tests; widening requires a new profile version + Owner
49
+ * decision (v0.5 §7.4). Do not rebuild this list from documentation.
50
+ */
51
+ const ALLOWED_PATHS = new Set([
52
+ 'schemaVersion', 'capability', 'status', 'disclosureProfile',
53
+ 'data.principle.requestedId', 'data.principle.identityStatus',
54
+ 'data.query.limit', 'data.query.contextUsedForRanking', 'data.query.truncated',
55
+ 'data.results[].association.type', 'data.results[].association.confidence',
56
+ 'data.results[].availability.painEvent', 'data.results[].availability.diagnoses',
57
+ 'data.results[].availability.correctionEvidence',
58
+ 'data.summary.returned', 'data.summary.availableCandidates', 'data.summary.truncated',
59
+ 'data.sources.ledger', 'data.sources.trajectoryDb', 'data.sources.stateDb',
60
+ 'data.unresolvedAssociations[].reason',
61
+ 'provenance.workspaceBinding', 'provenance.sources[].name', 'provenance.sources[].status',
62
+ 'warnings[].code', 'warnings[].message',
63
+ 'error', 'error.code', 'error.message',
64
+ 'nextAction', 'nextAction.code', 'nextAction.message',
65
+ ]);
66
+ /**
67
+ * OUTER_STATUS — the single authority table (v0.5 §7.3). `ambiguous_principle`
68
+ * is RESERVED: the read model never produces it today (identity resolves
69
+ * exactly or reports not_found), and this facade must not fabricate the
70
+ * capability; the mapping row exists so a future read-model change surfaces
71
+ * as invalid_input instead of silently passing through. `denied` /
72
+ * `unconfirmed` are NOT enabled in the first release (v0.5 §7.3).
73
+ */
74
+ const OUTER_STATUS = {
75
+ ok: 'ok',
76
+ no_matches: 'no_matches',
77
+ partial: 'partial',
78
+ principle_not_found: 'not_found',
79
+ pain_not_found: 'not_found',
80
+ source_missing: 'unavailable',
81
+ source_unreadable: 'unavailable',
82
+ ambiguous_principle: 'invalid_input', // reserved — not produced (v0.5 F8)
83
+ };
84
+ /** errorFor — status → stable error derivation (Gate 2 semantics, verbatim).
85
+ * `statusDetail` participates ONLY here (pain_not_found code derivation);
86
+ * it is never emitted as a data field (frozen per v0.5 §8.1 detail 1). */
87
+ function errorFor(result) {
88
+ const s = result.status;
89
+ if (s === 'ok' || s === 'no_matches' || s === 'partial')
90
+ return null;
91
+ if (s === 'principle_not_found') {
92
+ return { code: 'principle_not_found', message: 'The requested principle id does not resolve to a canonical ledger principle.' };
93
+ }
94
+ if (s === 'pain_not_found') {
95
+ return {
96
+ code: result.statusDetail ?? 'pain_not_found',
97
+ message: 'The requested pain is not within this principle\'s verified associations.',
98
+ };
99
+ }
100
+ if (s === 'source_missing') {
101
+ return { code: 'source_missing', message: 'A required data source is missing; the query cannot be answered.' };
102
+ }
103
+ if (s === 'source_unreadable') {
104
+ return { code: 'source_unreadable', message: 'A required data source is unreadable; the query cannot be answered.' };
105
+ }
106
+ // Reserved row (ambiguous_principle → invalid_input): a stable refusal
107
+ // without fabricating capability the read model never claimed.
108
+ return { code: 'invalid_input', message: 'The request violates the tool input contract.' };
109
+ }
110
+ /** OD-A projection of a full PainRecallResult into the envelope. Construction
111
+ * IS the whitelist: every field below is an ALLOWED_PATHS leaf; nothing else
112
+ * from `result` is reachable. (Gate 2 projectEnvelope + disclosureProfile +
113
+ * the v0.5 §7.2 data-null rule: an `unavailable` outcome discloses no data.) */
114
+ function projectEnvelope(result) {
115
+ const status = OUTER_STATUS[result.status] ?? 'unavailable';
116
+ return {
117
+ schemaVersion: CAPABILITY_SCHEMA_VERSION,
118
+ capability: RECALL_PAIN_CAPABILITY_ID,
119
+ disclosureProfile: OD_A_DISCLOSURE_PROFILE,
120
+ status,
121
+ // §7.2: data is null for BOTH unavailable and invalid_input (the
122
+ // reserved ambiguous→invalid_input row included — review round 2,
123
+ // P2-3). Every other status carries the projected data object.
124
+ data: status === 'unavailable' || status === 'invalid_input' ? null : {
125
+ principle: {
126
+ requestedId: result.principle.requestedId,
127
+ identityStatus: result.principle.identityStatus,
128
+ },
129
+ query: {
130
+ limit: result.query.limit,
131
+ contextUsedForRanking: result.query.contextUsedForRanking,
132
+ truncated: result.query.truncated,
133
+ },
134
+ results: result.results.map((e) => ({
135
+ association: { type: e.association.type, confidence: e.association.confidence },
136
+ availability: {
137
+ painEvent: e.availability.painEvent,
138
+ diagnoses: e.availability.diagnoses,
139
+ correctionEvidence: e.availability.correctionEvidence,
140
+ },
141
+ })),
142
+ summary: {
143
+ returned: result.summary.returned,
144
+ availableCandidates: result.summary.availableCandidates,
145
+ truncated: result.summary.truncated,
146
+ },
147
+ sources: {
148
+ ledger: result.sources.ledger,
149
+ trajectoryDb: result.sources.trajectoryDb,
150
+ stateDb: result.sources.stateDb,
151
+ },
152
+ unresolvedAssociations: result.unresolvedAssociations.map((u) => ({ reason: u.reason })),
153
+ },
154
+ provenance: {
155
+ workspaceBinding: 'configured',
156
+ sources: [
157
+ { name: 'ledger', status: result.sources.ledger },
158
+ { name: 'trajectoryDb', status: result.sources.trajectoryDb },
159
+ { name: 'stateDb', status: result.sources.stateDb },
160
+ ],
161
+ },
162
+ warnings: [],
163
+ error: errorFor(result),
164
+ nextAction: null,
165
+ };
166
+ }
167
+ /** Deep key-path walk over the envelope for whitelist assertions. Leaves
168
+ * (primitives/null) contribute their exact path; every container additionally
169
+ * contributes a STRUCTURAL path — objects at `prefix`, arrays at
170
+ * `prefix + '[]'` — so a forbidden key cannot hide behind an EMPTY array or
171
+ * empty object (a leaf-only walk would see nothing at all; review round 2,
172
+ * P1-2). Gate 2's leaf-only collectPaths semantics remain for the leaf set. */
173
+ function collectPaths(value, prefix, out) {
174
+ if (Array.isArray(value)) {
175
+ for (const v of value)
176
+ collectPaths(v, prefix + '[]', out);
177
+ return;
178
+ }
179
+ if (value !== null && typeof value === 'object') {
180
+ for (const [k, v] of Object.entries(value))
181
+ collectPaths(v, prefix ? prefix + '.' + k : k, out);
182
+ return;
183
+ }
184
+ out.add(prefix);
185
+ }
186
+ /** All structural container paths of the envelope: objects at their key path,
187
+ * arrays at their `[]`-normalized key path. Empty containers contribute ONLY
188
+ * a structural path — exactly the case a leaf-only walk cannot see. */
189
+ function collectStructuralPaths(value, prefix, out) {
190
+ if (Array.isArray(value)) {
191
+ if (prefix !== '')
192
+ out.add(prefix + '[]');
193
+ for (const v of value)
194
+ collectStructuralPaths(v, prefix + '[]', out);
195
+ return;
196
+ }
197
+ if (value !== null && typeof value === 'object') {
198
+ if (prefix !== '')
199
+ out.add(prefix);
200
+ for (const [k, v] of Object.entries(value))
201
+ collectStructuralPaths(v, prefix ? prefix + '.' + k : k, out);
202
+ return;
203
+ }
204
+ }
205
+ const ALLOWED_PATH_LIST = [...ALLOWED_PATHS];
206
+ /** A structural container path is legal only when it is a proper ancestor of
207
+ * at least one whitelisted leaf path: objects must be followed by a whitelisted
208
+ * `structural.` descendant, arrays by a whitelisted `structural[]…` one. A
209
+ * whitelisted LEAF path made a container (e.g. someone turns `status` into an
210
+ * object) has no such descendant and fails here. */
211
+ function isAllowedStructuralPath(structural, isArray) {
212
+ const marker = isArray ? `${structural}[]` : `${structural}.`;
213
+ return ALLOWED_PATH_LIST.some((p) => p.startsWith(marker));
214
+ }
215
+ /** Production self-check: BOTH leaf paths and structural container paths of
216
+ * the envelope, against the frozen whitelist. Violations are returned to the
217
+ * facade, which withholds the whole payload — the violating paths/values
218
+ * never leave this module.
219
+ *
220
+ * §7.2 null form: `data: null` is the envelope's explicit empty marker for
221
+ * the `unavailable` / `invalid_input` statuses. It surfaces as a bare `data`
222
+ * leaf, which the frozen od-a-v1 path set does not list (the Gate 2
223
+ * prototype never projected a null data) — the whitelist governs the
224
+ * POPULATED shape of `data.*`, so the null marker is exempted here and
225
+ * nowhere else. */
226
+ function collectDisclosureViolations(envelope) {
227
+ const leafPaths = new Set();
228
+ collectPaths(envelope, '', leafPaths);
229
+ if (envelope.data === null)
230
+ leafPaths.delete('data');
231
+ const violations = [...leafPaths].filter((p) => !ALLOWED_PATHS.has(p));
232
+ const structuralPaths = new Set();
233
+ collectStructuralPaths(envelope, '', structuralPaths);
234
+ for (const p of structuralPaths) {
235
+ const isArray = p.endsWith('[]');
236
+ const base = isArray ? p.slice(0, -2) : p;
237
+ if (!isAllowedStructuralPath(base, isArray))
238
+ violations.push(p);
239
+ }
240
+ return violations;
241
+ }
242
+ // ── Input validation (rc-1/rc-2: unknown in, field-by-field guards) ─────────
243
+ const PRINCIPLE_ID_MAX_LENGTH = 200;
244
+ const INPUT_KEYS = new Set(['workspaceDir', 'principleId', 'limit']);
245
+ function truncateForMessage(value, max = 40) {
246
+ return value.length <= max ? value : `${value.slice(0, max)}…`;
247
+ }
248
+ function invalid(reason) {
249
+ return { ok: false, error: { code: 'invalid_input', message: `The request violates the tool input contract: ${reason}` } };
250
+ }
251
+ /**
252
+ * Validate the capability input field by field, rejecting every undeclared
253
+ * property. Fail-closed: any violation prevents the read model from being
254
+ * called at all. Messages name the field and the rule — never the value
255
+ * (bounded output, rc-8; the input is untrusted model output in the Gate 4
256
+ * deployment).
257
+ */
258
+ function validateCapabilityInput(input) {
259
+ if (typeof input !== 'object' || input === null || Array.isArray(input)) {
260
+ return invalid('the input must be an object');
261
+ }
262
+ const record = input;
263
+ for (const key of Object.keys(record)) {
264
+ if (!INPUT_KEYS.has(key)) {
265
+ return invalid(`unknown property "${truncateForMessage(key)}" is not allowed`);
266
+ }
267
+ }
268
+ const { workspaceDir, principleId, limit } = record;
269
+ if (typeof workspaceDir !== 'string' || workspaceDir.length === 0) {
270
+ return invalid('workspaceDir must be a non-empty string (injected trusted context)');
271
+ }
272
+ if (typeof principleId !== 'string' || principleId.length === 0 || principleId.length > PRINCIPLE_ID_MAX_LENGTH) {
273
+ return invalid(`principleId must be a string of 1..${PRINCIPLE_ID_MAX_LENGTH} characters`);
274
+ }
275
+ if (limit !== undefined) {
276
+ if (typeof limit !== 'number' || !Number.isInteger(limit) || limit < PAIN_RECALL_MIN_LIMIT || limit > PAIN_RECALL_MAX_LIMIT) {
277
+ return invalid(`limit must be an integer between ${PAIN_RECALL_MIN_LIMIT} and ${PAIN_RECALL_MAX_LIMIT}`);
278
+ }
279
+ }
280
+ return { ok: true, value: { workspaceDir, principleId, limit: limit ?? PAIN_RECALL_DEFAULT_LIMIT } };
281
+ }
282
+ // ── Fail-closed envelopes ────────────────────────────────────────────────────
283
+ function envelopeShell(status, error) {
284
+ return {
285
+ schemaVersion: CAPABILITY_SCHEMA_VERSION,
286
+ capability: RECALL_PAIN_CAPABILITY_ID,
287
+ disclosureProfile: OD_A_DISCLOSURE_PROFILE,
288
+ status,
289
+ data: null,
290
+ provenance: { workspaceBinding: 'configured', sources: [] },
291
+ warnings: [],
292
+ error,
293
+ nextAction: null,
294
+ };
295
+ }
296
+ // ── Capability entry point ───────────────────────────────────────────────────
297
+ /**
298
+ * Recall a principle's verifiably-associated historical pains through the
299
+ * od-a-v1 disclosure profile.
300
+ *
301
+ * Duty sequence (v0.5 §7.1): validate input (fail-closed `invalid_input`,
302
+ * the read model is never called on bad input) → `recallPains` on the trusted
303
+ * workspace → OD-A projection (construction IS the whitelist) → leaf AND
304
+ * structural key-path self-check (violation ⇒ withhold the payload, return
305
+ * `unavailable`) → return.
306
+ *
307
+ * Resource constraint owned here (v0.5 §7.5.2, the only Core-layer limit):
308
+ * `limit ∈ [1, 10]`, default `PAIN_RECALL_DEFAULT_LIMIT` (3); the returned
309
+ * entry count is bounded by the read model's existing truncation semantics
310
+ * (≤ limit ≤ 10). The 32 KiB response budget and the 10 s deadline are NOT
311
+ * implemented here — they are Gate 4 MCP Adapter responsibilities.
312
+ */
313
+ export async function recallPrinciplePainsCapability(input) {
314
+ const validated = validateCapabilityInput(input);
315
+ if (!validated.ok) {
316
+ return envelopeShell('invalid_input', validated.error);
317
+ }
318
+ const raw = await recallPains(validated.value.workspaceDir, {
319
+ requestedPrincipleId: validated.value.principleId,
320
+ limit: validated.value.limit,
321
+ });
322
+ const envelope = projectEnvelope(raw);
323
+ if (collectDisclosureViolations(envelope).length > 0) {
324
+ // Disclosure assertion failed: the payload is withheld (never returned),
325
+ // and the message stays generic so a violating field cannot leak through
326
+ // the failure channel either (values AND key paths stay internal).
327
+ return envelopeShell('unavailable', {
328
+ code: 'disclosure_assertion_failed',
329
+ message: 'Internal disclosure assertion failed; the response was withheld.',
330
+ });
331
+ }
332
+ return envelope;
333
+ }
334
+ //# sourceMappingURL=pain-recall-capability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pain-recall-capability.js","sourceRoot":"","sources":["../../src/runtime-v2/pain-recall-capability.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,113 @@
1
+ export declare const PAIN_RECALL_SCHEMA_VERSION = "pd.pain-recall.v1";
2
+ export declare const PAIN_RECALL_DEFAULT_LIMIT = 3;
3
+ export declare const PAIN_RECALL_MIN_LIMIT = 1;
4
+ export declare const PAIN_RECALL_MAX_LIMIT = 10;
5
+ export type PainRecallStatus = 'ok' | 'no_matches' | 'principle_not_found' | 'ambiguous_principle' | 'pain_not_found' | 'source_missing' | 'source_unreadable' | 'partial';
6
+ export type SourceAvailability = 'ok' | 'missing' | 'unreadable' | 'not_checked';
7
+ export type AssociationType = 'explicit_reuse' | 'derived_from' | 'multiple_paths';
8
+ export interface RecallEvidenceRef {
9
+ kind: 'reuse_evidence' | 'candidate_lineage';
10
+ candidateId: string;
11
+ taskId?: string;
12
+ decidedAt?: string;
13
+ decisionId?: string;
14
+ }
15
+ export interface RecallAssociation {
16
+ type: AssociationType;
17
+ confidence: 'explicit' | 'lineage_verified';
18
+ evidenceRefs: RecallEvidenceRef[];
19
+ }
20
+ export interface PainEventView {
21
+ occurredAt: string | null;
22
+ source: string | null;
23
+ host: string;
24
+ score: number | null;
25
+ severity: string | null;
26
+ reason: string | null;
27
+ text: string | null;
28
+ /** A verbatim owner statement is only reported via correctionEvidence; the
29
+ * pain row itself never carries one, so this is structurally null. */
30
+ rawStatement: null;
31
+ }
32
+ export interface DiagnosisView {
33
+ diagnosisId: string;
34
+ taskId: string;
35
+ category: string;
36
+ rootCause: string;
37
+ supportingEvidence: readonly {
38
+ sourceRef: string;
39
+ note: string;
40
+ }[];
41
+ confidence: number | null;
42
+ isOriginalOwnerStatement: false;
43
+ }
44
+ export interface CorrectionEvidenceView {
45
+ text: string;
46
+ classification?: string;
47
+ channel?: string;
48
+ sessionId?: string;
49
+ occurredAt?: string;
50
+ }
51
+ export type ItemAvailability = 'available' | 'not_recorded' | 'unreadable';
52
+ export interface RecallLineageHop {
53
+ from: string;
54
+ to: string;
55
+ relation: string;
56
+ }
57
+ export interface PainRecallEntry {
58
+ painId: string;
59
+ association: RecallAssociation;
60
+ pain: PainEventView;
61
+ diagnoses: DiagnosisView[];
62
+ correctionEvidence: CorrectionEvidenceView | null;
63
+ availability: {
64
+ painEvent: 'available';
65
+ diagnoses: ItemAvailability;
66
+ correctionEvidence: ItemAvailability;
67
+ };
68
+ lineage: RecallLineageHop[];
69
+ }
70
+ export interface PainRecallQuery {
71
+ requestedPrincipleId: string;
72
+ painId?: string;
73
+ context?: string;
74
+ /** Validated upstream: integer within [1, 10]. */
75
+ limit: number;
76
+ }
77
+ export interface UnresolvedAssociation {
78
+ painId?: string;
79
+ candidateId?: string;
80
+ reason: string;
81
+ }
82
+ export interface PainRecallResult {
83
+ schemaVersion: string;
84
+ status: PainRecallStatus;
85
+ /** Sub-reason for pain_not_found: not_associated | pain_event_not_found. */
86
+ statusDetail?: string;
87
+ principle: {
88
+ requestedId: string;
89
+ canonicalId: string | null;
90
+ identityStatus: 'resolved' | 'not_found' | 'ambiguous';
91
+ text?: string;
92
+ };
93
+ query: {
94
+ limit: number;
95
+ painId?: string;
96
+ contextUsedForRanking: boolean;
97
+ truncated: boolean;
98
+ };
99
+ results: PainRecallEntry[];
100
+ summary: {
101
+ returned: number;
102
+ availableCandidates: number;
103
+ truncated: boolean;
104
+ };
105
+ sources: {
106
+ ledger: SourceAvailability;
107
+ trajectoryDb: SourceAvailability;
108
+ stateDb: SourceAvailability;
109
+ };
110
+ unresolvedAssociations: UnresolvedAssociation[];
111
+ }
112
+ export declare function recallPains(workspaceDir: string, query: PainRecallQuery): Promise<PainRecallResult>;
113
+ //# sourceMappingURL=pain-recall-read-model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pain-recall-read-model.d.ts","sourceRoot":"","sources":["../../src/runtime-v2/pain-recall-read-model.ts"],"names":[],"mappings":"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"}