@unbrained/pm-cli 2026.9.3 → 2026.9.4
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/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +27 -0
- package/dist/cli-bundle/bundle-manifest.json +146 -146
- package/dist/cli-bundle/chunks/{chunk-E5RBBCXO.js → chunk-6XSKPNCF.js} +75 -75
- package/dist/cli-bundle/chunks/chunk-A24WAVE6.js +8 -0
- package/dist/cli-bundle/chunks/{chunk-DKGP3QLE.js → chunk-HI6BHPCU.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-Y4PJ6HPK.js → chunk-I2AS367G.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-IEHHE6GA.js → chunk-OGBVU67G.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-EDPIS7EB.js → chunk-RI4XNOYS.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-TXW6VL33.js +38 -0
- package/dist/cli-bundle/chunks/{chunk-LENC656S.js → chunk-V72UV7QS.js} +76 -79
- package/dist/cli-bundle/chunks/chunk-VGLHECAP.js +9 -0
- package/dist/cli-bundle/chunks/{chunk-34HASX3S.js → chunk-X6CMGV6L.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-UPPM2FOZ.js → chunk-YW4QK2G7.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-W2ZTOMKP.js → register-list-query-Z5YYSJJG.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-RVND5NCG.js → register-mutation-ELSP6I4I.js} +2 -2
- package/dist/cli-bundle/chunks/{register-operations-TTROIVC4.js → register-operations-OH7R3ZT4.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-D3ZFHY3L.js → register-setup-E2AE72QG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-Q45NHPF2.js → chunk-25UJBH4M.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-4HJFY4MB.js → chunk-3646BZ4W.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-TXE4TSHM.js → chunk-4YRAVI43.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-M5M6SVHS.js → chunk-53IHPICX.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-5P4HVOWG.js +176 -0
- package/dist/cli-bundle/focused-chunks/chunk-636VVQ7F.js +54 -0
- package/dist/cli-bundle/focused-chunks/{chunk-D7KXFBXV.js → chunk-6PWPQKDN.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-S27XMBIN.js → chunk-7N2TV7WZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-5RFXUPN5.js → chunk-AJR3OP2E.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-KZ2NB3ET.js → chunk-B3A6MJYE.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-BWKHEIVF.js → chunk-BFDDJ2T2.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-4WR46RMG.js → chunk-BHUIRZWQ.js} +8 -8
- package/dist/cli-bundle/focused-chunks/{chunk-4RRHC3S4.js → chunk-JADHHPY6.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-GT7MXDLW.js → chunk-MHKUIPJW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-NBMJD6MK.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-NSKBLHVI.js +20 -0
- package/dist/cli-bundle/focused-chunks/{chunk-OL5EH6I3.js → chunk-P2GOAOQN.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-UCLO3XDU.js → chunk-YARWJM2B.js} +2 -2
- package/dist/cli-bundle/main.js +2 -2
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +1 -1
- package/dist/cli-bundle/sdk-core.js +28 -31
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +42 -37
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +10 -10
- package/dist/core/diagnostics/remediation.js +4 -4
- package/dist/core/history/history.d.ts +37 -1
- package/dist/core/history/history.js +278 -58
- package/dist/core/history/replay.js +68 -34
- package/dist/core/lock/lock.d.ts +10 -0
- package/dist/core/lock/lock.js +42 -3
- package/dist/core/shared/author.d.ts +3 -1
- package/dist/core/shared/author.js +111 -23
- package/dist/sdk/environment/agent-environment.d.ts +296 -0
- package/dist/sdk/environment/agent-environment.js +467 -0
- package/dist/sdk/environment/project-runtime-compatibility.d.ts +19 -1
- package/dist/sdk/environment/project-runtime-compatibility.js +118 -21
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +14 -2
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +14 -14
- package/dist/sdk/governance/health.js +13 -44
- package/dist/sdk/governance/merge-receipt-history.d.ts +62 -0
- package/dist/sdk/governance/merge-receipt-history.js +207 -0
- package/dist/sdk/governance/provenance-health.js +9 -3
- package/dist/sdk/history-compact.js +14 -5
- package/dist/sdk/history-redact.js +58 -23
- package/dist/sdk/history-repair.js +16 -6
- package/dist/sdk/index.d.ts +2 -0
- package/dist/sdk/index.js +4 -2
- package/dist/sdk/merge/driver.d.ts +3 -1
- package/dist/sdk/merge/driver.js +9 -9
- package/dist/sdk/merge/index.d.ts +1 -1
- package/dist/sdk/merge/index.js +3 -3
- package/dist/sdk/merge/receipts.d.ts +17 -6
- package/dist/sdk/merge/receipts.js +246 -75
- package/dist/sdk/merge/reconcile.d.ts +9 -7
- package/dist/sdk/merge/reconcile.js +175 -12
- package/dist/sdk/merge/three-way.d.ts +22 -2
- package/dist/sdk/merge/three-way.js +92 -25
- package/dist/sdk/runtime-primitives.d.ts +2 -2
- package/dist/sdk/runtime-primitives.js +4 -4
- package/dist/types.d.ts +25 -0
- package/dist/types.js +2 -2
- package/docs/AGENT_ENVIRONMENTS.md +47 -0
- package/docs/AGENT_PROVENANCE_ADR.md +17 -2
- package/docs/CONTEXT_INTEGRITY_CONTRACTS.md +38 -1
- package/docs/MERGE_SAFETY.md +119 -23
- package/docs/README.md +1 -0
- package/docs/SDK_CONTEXT_EVIDENCE_CONTRACTS.md +24 -2
- package/docs/SDK_RUNTIME_BOUNDARIES.md +17 -1
- package/docs/examples/sdk-agent-environment/README.md +14 -0
- package/docs/examples/sdk-agent-environment/package.json +8 -0
- package/docs/examples/sdk-agent-environment/run-agent-environment.mjs +154 -0
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +4 -3
- package/marketplace.json +2 -2
- package/package.json +2 -2
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/sdk/public-surface.json +534 -24
- package/dist/cli-bundle/chunks/chunk-AY324UJ5.js +0 -9
- package/dist/cli-bundle/chunks/chunk-L7B7343B.js +0 -8
- package/dist/cli-bundle/chunks/chunk-LISESA7W.js +0 -35
- package/dist/cli-bundle/focused-chunks/chunk-3ZBI35HU.js +0 -176
- package/dist/cli-bundle/focused-chunks/chunk-GHCZ3YFR.js +0 -20
- package/dist/cli-bundle/focused-chunks/chunk-KBLZRU62.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-QKHCSUGJ.js +0 -51
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sdk/governance/merge-receipt-history
|
|
3
|
+
*
|
|
4
|
+
* Classifies privacy-safe merge receipt references embedded in history.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="1e73338f-221a-580f-85a8-6f2a488fb89d")}catch(e){}}();
|
|
8
|
+
import { createHash } from "node:crypto";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { compareTimestampStrings, isRfc3339DateTime, } from "../../core/shared/time.js";
|
|
11
|
+
import { isSafeReceiptId } from "../merge/receipts.js";
|
|
12
|
+
/** First commit timestamp at which merge receipts gained a tracked durable copy. */
|
|
13
|
+
export const DURABLE_MERGE_RECEIPT_INTRODUCED_AT = "2026-08-09T16:15:18.000Z";
|
|
14
|
+
const PRE_DURABLE_DISPOSITION_ELIGIBLE = Symbol("pre-durable-disposition-eligible");
|
|
15
|
+
/** Return whether an unknown value is a non-array record. */
|
|
16
|
+
function isRecord(value) {
|
|
17
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18
|
+
}
|
|
19
|
+
/** Return a bounded dense list of unique, non-empty field names. */
|
|
20
|
+
function isFieldArray(value) {
|
|
21
|
+
if (!Array.isArray(value) || value.length > 256)
|
|
22
|
+
return false;
|
|
23
|
+
const fields = new Set();
|
|
24
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
25
|
+
const field = value[index];
|
|
26
|
+
if (!(index in value) ||
|
|
27
|
+
typeof field !== "string" ||
|
|
28
|
+
field.length === 0 ||
|
|
29
|
+
field.length > 256 ||
|
|
30
|
+
field.includes("\0") ||
|
|
31
|
+
fields.has(field)) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
fields.add(field);
|
|
35
|
+
}
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
/** Return whether an unknown value is one complete legacy field decision. */
|
|
39
|
+
function isLegacyDecision(value) {
|
|
40
|
+
if (!isRecord(value))
|
|
41
|
+
return false;
|
|
42
|
+
return (typeof value.field === "string" &&
|
|
43
|
+
value.field.length > 0 &&
|
|
44
|
+
value.field.length <= 256 &&
|
|
45
|
+
!value.field.includes("\0") &&
|
|
46
|
+
typeof value.retained_hash === "string" &&
|
|
47
|
+
/^[a-f0-9]{64}$/u.test(value.retained_hash) &&
|
|
48
|
+
typeof value.discarded_hash === "string" &&
|
|
49
|
+
/^[a-f0-9]{64}$/u.test(value.discarded_hash));
|
|
50
|
+
}
|
|
51
|
+
/** Return whether a legacy item path is normalized, bounded, and item-scoped. */
|
|
52
|
+
function isLegacyItemPath(value, historyItemId) {
|
|
53
|
+
if (typeof value !== "string")
|
|
54
|
+
return false;
|
|
55
|
+
const normalized = path.posix.normalize(value);
|
|
56
|
+
return (value.length <= 4_096 &&
|
|
57
|
+
!value.includes("\\") &&
|
|
58
|
+
!value.includes("\0") &&
|
|
59
|
+
!path.posix.isAbsolute(value) &&
|
|
60
|
+
normalized === value &&
|
|
61
|
+
!normalized.startsWith("../") &&
|
|
62
|
+
(path.posix.basename(normalized) === `${historyItemId}.toon` ||
|
|
63
|
+
path.posix.basename(normalized) === `${historyItemId}.md`));
|
|
64
|
+
}
|
|
65
|
+
/** Return whether a preferred-era summary has one safe canonical identity. */
|
|
66
|
+
function hasLegacyReceiptIdentity(value, historyItemId) {
|
|
67
|
+
return (typeof value.receipt_id === "string" &&
|
|
68
|
+
isSafeReceiptId(value.receipt_id) &&
|
|
69
|
+
(value.preferred === "ours" || value.preferred === "theirs") &&
|
|
70
|
+
value.requested_preference === undefined &&
|
|
71
|
+
value.conflict_resolution === undefined &&
|
|
72
|
+
value.item_id === historyItemId &&
|
|
73
|
+
isLegacyItemPath(value.item_path, historyItemId));
|
|
74
|
+
}
|
|
75
|
+
/** Return whether preferred-era summary collections are dense and self-consistent. */
|
|
76
|
+
function hasLegacyReceiptCollections(value) {
|
|
77
|
+
const conflictFields = value.conflict_fields;
|
|
78
|
+
const fieldsFromTheirs = value.fields_from_theirs;
|
|
79
|
+
const unionFields = value.union_fields;
|
|
80
|
+
const decisions = value.decisions;
|
|
81
|
+
const decisionFields = Array.isArray(decisions)
|
|
82
|
+
? new Set(decisions.flatMap((decision) => isLegacyDecision(decision) ? [decision.field] : []))
|
|
83
|
+
: new Set();
|
|
84
|
+
return (isFieldArray(conflictFields) &&
|
|
85
|
+
isFieldArray(fieldsFromTheirs) &&
|
|
86
|
+
isFieldArray(unionFields) &&
|
|
87
|
+
Array.isArray(decisions) &&
|
|
88
|
+
decisions.length > 0 &&
|
|
89
|
+
decisions.length <= 256 &&
|
|
90
|
+
Object.keys(decisions).length === decisions.length &&
|
|
91
|
+
decisions.every(isLegacyDecision) &&
|
|
92
|
+
decisionFields.size === decisions.length &&
|
|
93
|
+
conflictFields.length === decisionFields.size &&
|
|
94
|
+
conflictFields.every((field) => decisionFields.has(field)));
|
|
95
|
+
}
|
|
96
|
+
/** Return whether one summary is a complete, self-contained preferred-era receipt. */
|
|
97
|
+
export function isLegacyMergeReceiptSummary(value, historyItemId) {
|
|
98
|
+
return (hasLegacyReceiptIdentity(value, historyItemId) &&
|
|
99
|
+
hasLegacyReceiptCollections(value));
|
|
100
|
+
}
|
|
101
|
+
/** Return whether a summary matches the final clone-local-only schema before durable receipts. */
|
|
102
|
+
export function isPreDurableCloneLocalReceiptSummary(value, historyItemId) {
|
|
103
|
+
return (typeof value.receipt_id === "string" &&
|
|
104
|
+
isSafeReceiptId(value.receipt_id) &&
|
|
105
|
+
(value.preferred === "ours" || value.preferred === "theirs") &&
|
|
106
|
+
value.requested_preference === undefined &&
|
|
107
|
+
(value.conflict_resolution === "preferred_side" ||
|
|
108
|
+
value.conflict_resolution === "stable_value_order") &&
|
|
109
|
+
value.item_id === historyItemId &&
|
|
110
|
+
isLegacyItemPath(value.item_path, historyItemId) &&
|
|
111
|
+
hasLegacyReceiptCollections(value));
|
|
112
|
+
}
|
|
113
|
+
/** Return whether an extracted reference carried a validated pre-durable summary. */
|
|
114
|
+
export function isPreDurableDispositionEligibleReference(reference) {
|
|
115
|
+
return (reference[PRE_DURABLE_DISPOSITION_ELIGIBLE] === true);
|
|
116
|
+
}
|
|
117
|
+
/** Extract receipt ids and legacy compatibility disposition from one history entry. */
|
|
118
|
+
export function extractHistoryMergeReceiptReferences(value, historyItemId) {
|
|
119
|
+
if (!isRecord(value) || !isRecord(value.context))
|
|
120
|
+
return [];
|
|
121
|
+
const merge = value.context.merge;
|
|
122
|
+
if (!isRecord(merge) || !Array.isArray(merge.receipts))
|
|
123
|
+
return [];
|
|
124
|
+
return merge.receipts.flatMap((receipt) => {
|
|
125
|
+
if (!isRecord(receipt) ||
|
|
126
|
+
typeof receipt.receipt_id !== "string" ||
|
|
127
|
+
receipt.receipt_id.trim().length === 0) {
|
|
128
|
+
return [];
|
|
129
|
+
}
|
|
130
|
+
const reference = {
|
|
131
|
+
receiptId: receipt.receipt_id,
|
|
132
|
+
legacySummaryAccepted: isLegacyMergeReceiptSummary(receipt, historyItemId),
|
|
133
|
+
[PRE_DURABLE_DISPOSITION_ELIGIBLE]: isPreDurableCloneLocalReceiptSummary(receipt, historyItemId),
|
|
134
|
+
...(typeof value.ts === "string" && isRfc3339DateTime(value.ts)
|
|
135
|
+
? { eventTimestamp: value.ts }
|
|
136
|
+
: {}),
|
|
137
|
+
};
|
|
138
|
+
return [reference];
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
/** Extract validated explicit missing-receipt dispositions from one merge audit event. */
|
|
142
|
+
export function extractHistoryMergeReceiptDispositions(value, historyItemId, historyLine) {
|
|
143
|
+
if (!isRecord(value) || value.op !== "merge_reconcile")
|
|
144
|
+
return [];
|
|
145
|
+
if (!isRecord(value.context) || !isRecord(value.context.merge))
|
|
146
|
+
return [];
|
|
147
|
+
const dispositions = value.context.merge.missing_receipt_dispositions;
|
|
148
|
+
if (!Array.isArray(dispositions) || dispositions.length > 256)
|
|
149
|
+
return [];
|
|
150
|
+
return dispositions.flatMap((disposition) => {
|
|
151
|
+
if (!isRecord(disposition) ||
|
|
152
|
+
typeof disposition.receipt_id !== "string" ||
|
|
153
|
+
!isSafeReceiptId(disposition.receipt_id) ||
|
|
154
|
+
typeof disposition.original_history_line !== "number" ||
|
|
155
|
+
!Number.isSafeInteger(disposition.original_history_line) ||
|
|
156
|
+
disposition.original_history_line < 1 ||
|
|
157
|
+
typeof disposition.original_event_ts !== "string" ||
|
|
158
|
+
!isRfc3339DateTime(disposition.original_event_ts) ||
|
|
159
|
+
disposition.reason !== "legacy_clone_local_only") {
|
|
160
|
+
return [];
|
|
161
|
+
}
|
|
162
|
+
return [
|
|
163
|
+
{
|
|
164
|
+
itemId: historyItemId,
|
|
165
|
+
receiptId: disposition.receipt_id,
|
|
166
|
+
originalHistoryLine: disposition.original_history_line,
|
|
167
|
+
originalEventTimestamp: disposition.original_event_ts,
|
|
168
|
+
auditHistoryLine: historyLine,
|
|
169
|
+
reason: disposition.reason,
|
|
170
|
+
},
|
|
171
|
+
];
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
/** Classify scanned references without treating complete legacy summaries as absent. */
|
|
175
|
+
export function classifyHistoryMergeReceiptReferences(references, availableReceiptIds, dispositions = []) {
|
|
176
|
+
const dispositionAuditLineByCoordinate = new Map();
|
|
177
|
+
for (const disposition of dispositions) {
|
|
178
|
+
const coordinate = `${disposition.itemId}\0${disposition.originalHistoryLine}\0${disposition.receiptId}\0${disposition.originalEventTimestamp}`;
|
|
179
|
+
dispositionAuditLineByCoordinate.set(coordinate, Math.max(dispositionAuditLineByCoordinate.get(coordinate) ?? 0, disposition.auditHistoryLine));
|
|
180
|
+
}
|
|
181
|
+
const dispositionAccepts = (reference) => isPreDurableDispositionEligibleReference(reference) &&
|
|
182
|
+
reference.eventTimestamp !== undefined &&
|
|
183
|
+
compareTimestampStrings(reference.eventTimestamp, DURABLE_MERGE_RECEIPT_INTRODUCED_AT) < 0 &&
|
|
184
|
+
(dispositionAuditLineByCoordinate.get(`${reference.itemId}\0${reference.line}\0${reference.receiptId}\0${reference.eventTimestamp}`) ?? 0) > reference.line;
|
|
185
|
+
const missing = references
|
|
186
|
+
.filter((reference) => !reference.legacySummaryAccepted &&
|
|
187
|
+
!availableReceiptIds.has(reference.receiptId) &&
|
|
188
|
+
!dispositionAccepts(reference))
|
|
189
|
+
.map((reference) => ({
|
|
190
|
+
item_id: reference.itemId,
|
|
191
|
+
history_line: reference.line,
|
|
192
|
+
...(isSafeReceiptId(reference.receiptId)
|
|
193
|
+
? { receipt_id: reference.receiptId }
|
|
194
|
+
: {
|
|
195
|
+
receipt_reference_hash: createHash("sha256")
|
|
196
|
+
.update(reference.receiptId)
|
|
197
|
+
.digest("hex"),
|
|
198
|
+
}),
|
|
199
|
+
}));
|
|
200
|
+
return {
|
|
201
|
+
missing,
|
|
202
|
+
acceptedLegacyCount: references.filter((reference) => reference.legacySummaryAccepted).length,
|
|
203
|
+
acceptedDispositionCount: references.filter(dispositionAccepts).length,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=merge-receipt-history.js.map
|
|
207
|
+
//# debugId=1e73338f-221a-580f-85a8-6f2a488fb89d
|
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
* Reads bounded, privacy-safe provenance resolver outcomes for health checks.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="cb3bf7ee-808f-5ff6-af84-edb034760c54")}catch(e){}}();
|
|
8
8
|
import fs from "node:fs/promises";
|
|
9
9
|
import path from "node:path";
|
|
10
|
+
import { resealHistoryRewrite, verifyHistoryRecordHash, } from "../../core/history/history.js";
|
|
10
11
|
const DEFAULT_PROVENANCE_HISTORY_BYTE_LIMIT = 8_388_608;
|
|
11
12
|
const ATTEMPTED_PROVENANCE_OUTCOME_STATUSES = new Set(["resolved", "failed"]);
|
|
12
13
|
const INVALID_PROVENANCE_VALUE_CLASSIFIERS = [
|
|
@@ -45,6 +46,8 @@ export function normalizeInvalidHistoryProvenance(entries) {
|
|
|
45
46
|
: undefined;
|
|
46
47
|
if (provenance === undefined)
|
|
47
48
|
return entry;
|
|
49
|
+
if (!verifyHistoryRecordHash(entry).ok)
|
|
50
|
+
return entry;
|
|
48
51
|
const retained = {};
|
|
49
52
|
let eventChanged = false;
|
|
50
53
|
for (const [dimension, observation] of Object.entries(provenance)) {
|
|
@@ -78,7 +81,10 @@ export function normalizeInvalidHistoryProvenance(entries) {
|
|
|
78
81
|
else {
|
|
79
82
|
next.agent_provenance = retained;
|
|
80
83
|
}
|
|
81
|
-
return next
|
|
84
|
+
return resealHistoryRewrite(entry, next, {
|
|
85
|
+
retainPriorRecord: true,
|
|
86
|
+
retainPriorRecordHash: false,
|
|
87
|
+
});
|
|
82
88
|
});
|
|
83
89
|
return {
|
|
84
90
|
entries: normalized,
|
|
@@ -274,4 +280,4 @@ export async function scanProvenanceResolverHealth(pmRoot, eventLimit = 10_000)
|
|
|
274
280
|
};
|
|
275
281
|
}
|
|
276
282
|
//# sourceMappingURL=provenance-health.js.map
|
|
277
|
-
//# debugId=
|
|
283
|
+
//# debugId=cb3bf7ee-808f-5ff6-af84-edb034760c54
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
* Implements the pm history compact command surface and its agent-facing runtime behavior.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7570ecac-7f15-5a1b-9b2d-2f1744a00720")}catch(e){}}();
|
|
8
8
|
import { assertInitializedTracker } from "./environment/tracker-preflight.js";
|
|
9
9
|
import fs from "node:fs/promises";
|
|
10
10
|
import path from "node:path";
|
|
11
|
-
import { createHistoryEntry } from "../core/history/history.js";
|
|
11
|
+
import { createHistoryEntry, hashHistoryStream, resealHistoryRewrite, } from "../core/history/history.js";
|
|
12
12
|
import { selectHistoryCompactBulkTargets, } from "../core/history/history-compact-bulk.js";
|
|
13
13
|
import { executeHistoryRewrite, writeHistoryRawWithRollback, } from "../core/history/history-rewrite.js";
|
|
14
14
|
import { cloneEmptyReplayDocument, historyEntriesToRaw, replayHash, replayToItemDocument, toReplayDocument, verifyHistoryChain, } from "../core/history/replay.js";
|
|
@@ -106,11 +106,11 @@ function reanchorRetainedEntries(retainedEntries, seed, retainedEntryOffset) {
|
|
|
106
106
|
for (const [index, entry] of retainedEntries.entries()) {
|
|
107
107
|
const beforeHash = replayHash(replay);
|
|
108
108
|
replay = applyHistoryPatch(replay, entry.patch, retainedEntryOffset + index + 1, entry.op);
|
|
109
|
-
rewritten.push({
|
|
109
|
+
rewritten.push(resealHistoryRewrite(entry, {
|
|
110
110
|
...entry,
|
|
111
111
|
before_hash: beforeHash,
|
|
112
112
|
after_hash: replayHash(replay),
|
|
113
|
-
});
|
|
113
|
+
}));
|
|
114
114
|
}
|
|
115
115
|
return {
|
|
116
116
|
entries: rewritten,
|
|
@@ -169,6 +169,15 @@ function buildHistoryCompactEntries(params) {
|
|
|
169
169
|
before: replayToItemDocument(cloneEmptyReplayDocument()),
|
|
170
170
|
after: replayToItemDocument(checkpoint),
|
|
171
171
|
message: buildHistoryCompactBaselineMessage(params.boundary),
|
|
172
|
+
context: {
|
|
173
|
+
history_compaction: {
|
|
174
|
+
contract_version: 1,
|
|
175
|
+
pruned_entry_count: params.boundary.compactCount,
|
|
176
|
+
pruned_stream_digest: hashHistoryStream(params.historyEntries.slice(0, params.boundary.compactCount)),
|
|
177
|
+
retained_proof: "stream_digest_and_checkpoint",
|
|
178
|
+
limitation: "individual_pruned_entries_require_pre_compaction_stream",
|
|
179
|
+
},
|
|
180
|
+
},
|
|
172
181
|
});
|
|
173
182
|
const rewrittenEntries = [baselineEntry, ...reanchored.entries];
|
|
174
183
|
if (!params.dryRun) {
|
|
@@ -521,4 +530,4 @@ export async function runHistoryCompactBulk(options, global) {
|
|
|
521
530
|
};
|
|
522
531
|
}
|
|
523
532
|
//# sourceMappingURL=history-compact.js.map
|
|
524
|
-
//# debugId=
|
|
533
|
+
//# debugId=7570ecac-7f15-5a1b-9b2d-2f1744a00720
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
* Implements the pm history redact command surface and its agent-facing runtime behavior.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="bd1e86b0-6696-5fba-8dd4-b9636bf3ee60")}catch(e){}}();
|
|
8
8
|
import { assertInitializedTracker } from "./environment/tracker-preflight.js";
|
|
9
9
|
import fs from "node:fs/promises";
|
|
10
10
|
import { pathExists, readFileIfExists, writeFileAtomic, } from "../core/fs/fs-utils.js";
|
|
11
|
-
import { createHistoryEntry } from "../core/history/history.js";
|
|
11
|
+
import { createHistoryEntry, resealHistoryRewrite, verifyHistoryRecordHash, } from "../core/history/history.js";
|
|
12
12
|
import { invalidateHistoryDriftCacheForPath } from "../core/history/drift-cache.js";
|
|
13
13
|
import { executeHistoryRewrite } from "../core/history/history-rewrite.js";
|
|
14
14
|
import { EMPTY_REPLAY_DOCUMENT, historyEntriesToRaw, replayHash, replayToItemDocument, verifyHistoryChain, } from "../core/history/replay.js";
|
|
@@ -189,6 +189,22 @@ function redactUnknownValue(value, rules, replacement) {
|
|
|
189
189
|
replacements: 0,
|
|
190
190
|
};
|
|
191
191
|
}
|
|
192
|
+
function redactHistoryPatch(patch, rules, replacement) {
|
|
193
|
+
let replacements = 0;
|
|
194
|
+
const redactedPatch = patch.map((operation) => {
|
|
195
|
+
/* c8 ignore start -- patch operations without `value` are covered in lower-level patch adapters. */
|
|
196
|
+
if (!Object.prototype.hasOwnProperty.call(operation, "value")) {
|
|
197
|
+
return operation;
|
|
198
|
+
}
|
|
199
|
+
/* c8 ignore stop */
|
|
200
|
+
const redactedValue = redactUnknownValue(operation.value, rules, replacement);
|
|
201
|
+
replacements += redactedValue.replacements;
|
|
202
|
+
return redactedValue.replacements > 0
|
|
203
|
+
? { ...operation, value: redactedValue.value }
|
|
204
|
+
: operation;
|
|
205
|
+
});
|
|
206
|
+
return { patch: redactedPatch, replacements };
|
|
207
|
+
}
|
|
192
208
|
function inspectHistoryIntegrity(entries) {
|
|
193
209
|
let replay = structuredClone(EMPTY_REPLAY_DOCUMENT);
|
|
194
210
|
let hashMismatchesBefore = 0;
|
|
@@ -214,6 +230,7 @@ function inspectHistoryIntegrity(entries) {
|
|
|
214
230
|
function redactHistoryEntry(entry, rules, replacement) {
|
|
215
231
|
let replacements = 0;
|
|
216
232
|
let changed = false;
|
|
233
|
+
let reanchorEvidenceRedacted = false;
|
|
217
234
|
let nextMessage = entry.message;
|
|
218
235
|
if (typeof entry.message === "string") {
|
|
219
236
|
const redactedMessage = redactStringValue(entry.message, rules, replacement);
|
|
@@ -223,31 +240,41 @@ function redactHistoryEntry(entry, rules, replacement) {
|
|
|
223
240
|
changed = true;
|
|
224
241
|
}
|
|
225
242
|
}
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
243
|
+
const redactedPatch = redactHistoryPatch(entry.patch, rules, replacement);
|
|
244
|
+
replacements += redactedPatch.replacements;
|
|
245
|
+
changed ||= redactedPatch.replacements > 0;
|
|
246
|
+
const nextReanchorEvidence = entry.reanchor_evidence?.map((evidence) => {
|
|
247
|
+
const redactedEvidencePatch = evidence.patch
|
|
248
|
+
? redactHistoryPatch(evidence.patch, rules, replacement)
|
|
249
|
+
: { patch: undefined, replacements: 0 };
|
|
250
|
+
const redactedEvidenceRecord = evidence.record
|
|
251
|
+
? redactUnknownValue(evidence.record, rules, replacement)
|
|
252
|
+
: { value: undefined, replacements: 0 };
|
|
253
|
+
replacements += redactedEvidencePatch.replacements;
|
|
254
|
+
replacements += redactedEvidenceRecord.replacements;
|
|
255
|
+
const evidenceChanged = redactedEvidencePatch.replacements > 0 ||
|
|
256
|
+
redactedEvidenceRecord.replacements > 0;
|
|
257
|
+
changed ||= evidenceChanged;
|
|
258
|
+
if (!evidenceChanged)
|
|
259
|
+
return evidence;
|
|
260
|
+
reanchorEvidenceRedacted = true;
|
|
261
|
+
const { patch: _sensitivePatch, record: _sensitiveRecord, record_hash: _priorRecordHash, record_hash_version: _priorRecordHashVersion, ...digestOnlyEvidence } = evidence;
|
|
262
|
+
return redactedEvidencePatch.replacements > 0
|
|
263
|
+
? digestOnlyEvidence
|
|
264
|
+
: { ...digestOnlyEvidence, patch: evidence.patch };
|
|
242
265
|
});
|
|
243
266
|
return {
|
|
244
267
|
entry: {
|
|
245
268
|
...entry,
|
|
246
269
|
message: nextMessage,
|
|
247
|
-
patch:
|
|
270
|
+
patch: redactedPatch.patch,
|
|
271
|
+
...(nextReanchorEvidence
|
|
272
|
+
? { reanchor_evidence: nextReanchorEvidence }
|
|
273
|
+
: {}),
|
|
248
274
|
},
|
|
249
275
|
replacements,
|
|
250
276
|
changed,
|
|
277
|
+
reanchorEvidenceRedacted,
|
|
251
278
|
};
|
|
252
279
|
}
|
|
253
280
|
function rewriteHistoryEntries(entries, rules, replacement) {
|
|
@@ -256,7 +283,12 @@ function rewriteHistoryEntries(entries, rules, replacement) {
|
|
|
256
283
|
let replacements = 0;
|
|
257
284
|
const rewrittenEntries = [];
|
|
258
285
|
for (let index = 0; index < entries.length; index += 1) {
|
|
259
|
-
const
|
|
286
|
+
const original = entries[index];
|
|
287
|
+
const recordVerification = verifyHistoryRecordHash(original);
|
|
288
|
+
if (!recordVerification.ok) {
|
|
289
|
+
throw new PmCliError(`history-redact refuses invalid immutable record ${index + 1} (${recordVerification.error}).`, EXIT_CODE.GENERIC_FAILURE);
|
|
290
|
+
}
|
|
291
|
+
const redacted = redactHistoryEntry(original, rules, replacement);
|
|
260
292
|
replacements += redacted.replacements;
|
|
261
293
|
if (redacted.changed) {
|
|
262
294
|
entriesChanged += 1;
|
|
@@ -264,11 +296,14 @@ function rewriteHistoryEntries(entries, rules, replacement) {
|
|
|
264
296
|
const beforeHash = replayHash(replay);
|
|
265
297
|
replay = applyHistoryPatch(replay, redacted.entry.patch, index + 1, redacted.entry.op);
|
|
266
298
|
const afterHash = replayHash(replay);
|
|
267
|
-
rewrittenEntries.push({
|
|
299
|
+
rewrittenEntries.push(resealHistoryRewrite(original, {
|
|
268
300
|
...redacted.entry,
|
|
269
301
|
before_hash: beforeHash,
|
|
270
302
|
after_hash: afterHash,
|
|
271
|
-
}
|
|
303
|
+
}, {
|
|
304
|
+
retainPriorRecord: redacted.changed,
|
|
305
|
+
retainPriorRecordHash: !redacted.changed,
|
|
306
|
+
}));
|
|
272
307
|
}
|
|
273
308
|
return {
|
|
274
309
|
entries: rewrittenEntries,
|
|
@@ -606,4 +641,4 @@ export const _testOnly = {
|
|
|
606
641
|
redactUnknownValue,
|
|
607
642
|
};
|
|
608
643
|
//# sourceMappingURL=history-redact.js.map
|
|
609
|
-
//# debugId=
|
|
644
|
+
//# debugId=bd1e86b0-6696-5fba-8dd4-b9636bf3ee60
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the pm history repair command surface and its agent-facing runtime behavior.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="cb0b0e36-3135-5fc4-a0ae-f4e5b974e57f")}catch(e){}}();
|
|
8
8
|
import { assertInitializedTracker } from "./environment/tracker-preflight.js";
|
|
9
9
|
import { realpath } from "node:fs/promises";
|
|
10
10
|
import path from "node:path";
|
|
@@ -13,21 +13,24 @@ import { patchPathToChangedField } from "../core/history/history-diff.js";
|
|
|
13
13
|
import { pathExists, readFileIfExists } from "../core/fs/fs-utils.js";
|
|
14
14
|
import { executeHistoryRewrite, writeHistoryRawWithRollback, } from "../core/history/history-rewrite.js";
|
|
15
15
|
import { historyEntriesToRaw, normalizeReplayPatchOps, reanchorHistoryEntries, replayHashVerificationCandidates, resolveHistoryRepairItemHashVersion, toReplayDocument, verifyHistoryChain, verifyHistoryChainWithVersion, } from "../core/history/replay.js";
|
|
16
|
+
import { sealHistoryRecord, } from "../core/history/history.js";
|
|
17
|
+
import { classifyHistoryEvent } from "../core/history/event-classification.js";
|
|
16
18
|
import { scanHistoryDrift } from "../core/history/drift-scan.js";
|
|
17
19
|
import { invalidateHistoryDriftCache } from "../core/history/drift-cache.js";
|
|
18
20
|
import { readHistoryEntries } from "../core/history/read.js";
|
|
19
21
|
import { resolveItemTypeRegistry } from "../core/item/type-registry.js";
|
|
20
22
|
import { EXIT_CODE } from "../core/shared/constants.js";
|
|
21
23
|
import { PmCliError } from "../core/shared/errors.js";
|
|
24
|
+
import { sha256Hex, stableStringify } from "../core/shared/serialization.js";
|
|
22
25
|
import { resolveAuthor } from "../core/shared/author.js";
|
|
23
26
|
import { nowIso } from "../core/shared/time.js";
|
|
24
|
-
import { sha256Hex, stableStringify } from "../core/shared/serialization.js";
|
|
25
27
|
import { getActiveExtensionRegistrations, runActiveOnWriteHooks, } from "../core/extensions/index.js";
|
|
26
28
|
import { listAllItemMetadataWithBody, readLocatedItem, } from "../core/store/item-store.js";
|
|
27
29
|
import { resolvePmRoot } from "../core/store/paths.js";
|
|
28
30
|
import { readSettings } from "../core/store/settings.js";
|
|
29
31
|
import { resolveHistorySubject } from "./history-redact.js";
|
|
30
32
|
import { inspectMergeReceiptEvidence, summarizeMergeReceipt, } from "./merge/receipts.js";
|
|
33
|
+
import { encodeItemScalarDecisionValue, hashItemScalarDecisionValue, } from "./merge/three-way.js";
|
|
31
34
|
import { listInvalidProvenanceHistoryStreamIds, normalizeInvalidHistoryProvenance, } from "./governance/provenance-health.js";
|
|
32
35
|
function replayFieldValue(document, field) {
|
|
33
36
|
return field === "body"
|
|
@@ -169,7 +172,10 @@ async function verifyReceiptAgainstSnapshot(params) {
|
|
|
169
172
|
const currentMetadata = params.currentItemReplay.metadata;
|
|
170
173
|
const valuesMatch = declaredFields.every((field) => {
|
|
171
174
|
const value = field === "body" ? params.currentItemReplay.body : currentMetadata[field];
|
|
172
|
-
return
|
|
175
|
+
return [
|
|
176
|
+
hashItemScalarDecisionValue(value),
|
|
177
|
+
sha256Hex(stableStringify(encodeItemScalarDecisionValue(value))),
|
|
178
|
+
].includes(hashes[field]);
|
|
173
179
|
});
|
|
174
180
|
return valuesMatch ? { receipt: params.receipt, declaredFields } : null;
|
|
175
181
|
}
|
|
@@ -316,7 +322,7 @@ function buildHistoryRepairEntries(params) {
|
|
|
316
322
|
const previousAfterHash = params.reanchorEntries[params.reanchorEntries.length - 1].after_hash;
|
|
317
323
|
const semanticIndex = beforeHashes.indexOf(previousAfterHash);
|
|
318
324
|
const afterHashes = replayHashVerificationCandidates(afterReplay, params.itemHashVersion);
|
|
319
|
-
|
|
325
|
+
const auditEntry = {
|
|
320
326
|
ts: nowIso(),
|
|
321
327
|
author: params.author,
|
|
322
328
|
op: params.auditOperation,
|
|
@@ -332,7 +338,11 @@ function buildHistoryRepairEntries(params) {
|
|
|
332
338
|
...(params.auditContext === undefined
|
|
333
339
|
? {}
|
|
334
340
|
: { context: params.auditContext }),
|
|
335
|
-
}
|
|
341
|
+
};
|
|
342
|
+
rewrittenEntries.push(sealHistoryRecord({
|
|
343
|
+
...auditEntry,
|
|
344
|
+
event_class: classifyHistoryEvent(auditEntry),
|
|
345
|
+
}));
|
|
336
346
|
return { rewrittenEntries, auditEntryAdded: true };
|
|
337
347
|
}
|
|
338
348
|
function collectHistoryRepairWarnings(changed, skippedOps, reconciliation) {
|
|
@@ -598,4 +608,4 @@ export async function runHistoryRepairAll(options, global) {
|
|
|
598
608
|
};
|
|
599
609
|
}
|
|
600
610
|
//# sourceMappingURL=history-repair.js.map
|
|
601
|
-
//# debugId=
|
|
611
|
+
//# debugId=cb0b0e36-3135-5fc4-a0ae-f4e5b974e57f
|
package/dist/sdk/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export * from "./mcp/apps.js";
|
|
|
14
14
|
export * from "./mcp/skills.js";
|
|
15
15
|
export * from "./cli-contracts/grammar-contracts.js";
|
|
16
16
|
export * from "./agent-session-context.js";
|
|
17
|
+
export * from "./environment/agent-environment.js";
|
|
17
18
|
export type { PmCommandCapabilityContract, PmCommandCapabilityFamily, PmCommandVisibilityContract, PmCommandVisibilityTier, PmMcpPromptArgumentContract, PmMcpPromptContract, PmMcpResourceContract, PmMcpToolProfile, } from "./agent-capability-contracts.js";
|
|
18
19
|
export { isErrnoError, limitAnnotationEntries, parseAnnotationTextInput, readAnnotationEntries, normalizeAnnotationTransportOptions, resolveAnnotationInput, resolveAnnotationIndex, runAnnotationCommand, wrapOwnershipConflict, type AnnotationCommandConfig, type AnnotationCommandOptions, type AnnotationCommandResult, type AnnotationEntry, type AnnotationInput, type AnnotationHistoryRestoration, type AnnotationMutationReceipt, type AnnotationOmissionReceipt, type AnnotationSourceOptions, type OwnershipConflictGuidance, } from "./annotations.js";
|
|
19
20
|
export { acknowledgeUnknownAuthorHistoryEvents, acknowledgeUnknownAuthorHistoryEventsFromTransport, inspectHistoryAuthorStream, parseUnknownAuthorHistoryEventCoordinates, planUnknownAuthorHistoryAcknowledgment, resolveUnknownAuthorAcknowledgmentSelector, scanHistoryAuthorAttribution, type AcknowledgeUnknownAuthorEventsOptions, type HistoryAuthorAttributionScan, type UnknownAuthorAcknowledgmentPlan, type UnknownAuthorAcknowledgmentPlanCoordinate, type UnknownAuthorAcknowledgmentResult, type UnknownAuthorHistoryEvent, } from "./author-attribution.js";
|
|
@@ -75,6 +76,7 @@ export * from "./governance/assurance-runtime.js";
|
|
|
75
76
|
export * from "./governance/assurance-presets.js";
|
|
76
77
|
export * from "./governance/boundary-fixtures.js";
|
|
77
78
|
export * from "./governance/defect-recurrence.js";
|
|
79
|
+
export * from "./governance/merge-receipt-history.js";
|
|
78
80
|
export * from "./compile-cache.js";
|
|
79
81
|
export * from "./environment/project-runtime-compatibility.js";
|
|
80
82
|
export * from "./environment/source-context.js";
|
package/dist/sdk/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Defines public SDK APIs and package-author helpers for Index.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ea74fa78-184f-55e7-8c8e-fb912f4d26d8")}catch(e){}}();
|
|
8
8
|
export { PM_COMMAND_CAPABILITY_CONTRACTS, PM_COMMAND_VISIBILITY_CONTRACTS, PM_MCP_PROMPT_CONTRACTS, PM_MCP_RESOURCE_CONTRACTS, PM_MCP_TOOL_COMMAND_CONTRACTS, listPmCommandsForFamily, listPmCommandsForTier, listPmMcpToolsForProfile, renderPmCommandVisibilityMarkdown, resolvePmCommandCapabilityFamily, resolvePmCommandVisibilityTier, } from "./agent-capability-contracts.js";
|
|
9
9
|
export * from "./mcp/protocol.js";
|
|
10
10
|
export * from "./mcp/interactions.js";
|
|
@@ -16,6 +16,7 @@ export * from "./mcp/apps.js";
|
|
|
16
16
|
export * from "./mcp/skills.js";
|
|
17
17
|
export * from "./cli-contracts/grammar-contracts.js";
|
|
18
18
|
export * from "./agent-session-context.js";
|
|
19
|
+
export * from "./environment/agent-environment.js";
|
|
19
20
|
export { isErrnoError, limitAnnotationEntries, parseAnnotationTextInput, readAnnotationEntries, normalizeAnnotationTransportOptions, resolveAnnotationInput, resolveAnnotationIndex, runAnnotationCommand, wrapOwnershipConflict, } from "./annotations.js";
|
|
20
21
|
export { acknowledgeUnknownAuthorHistoryEvents, acknowledgeUnknownAuthorHistoryEventsFromTransport, inspectHistoryAuthorStream, parseUnknownAuthorHistoryEventCoordinates, planUnknownAuthorHistoryAcknowledgment, resolveUnknownAuthorAcknowledgmentSelector, scanHistoryAuthorAttribution, } from "./author-attribution.js";
|
|
21
22
|
export { BUILTIN_CORPUS_SHAPES, PM_CORPUS_SHAPE_SCHEMA, buildCorpusShapeItemPlan, createCorpusShapeMeasurement, defineCorpusShape, listBuiltinCorpusShapes, measureCorpusShapePlan, resolveBuiltinCorpusShape, } from "./corpus-shape.js";
|
|
@@ -72,6 +73,7 @@ export * from "./governance/assurance-runtime.js";
|
|
|
72
73
|
export * from "./governance/assurance-presets.js";
|
|
73
74
|
export * from "./governance/boundary-fixtures.js";
|
|
74
75
|
export * from "./governance/defect-recurrence.js";
|
|
76
|
+
export * from "./governance/merge-receipt-history.js";
|
|
75
77
|
export * from "./compile-cache.js";
|
|
76
78
|
export * from "./environment/project-runtime-compatibility.js";
|
|
77
79
|
export * from "./environment/source-context.js";
|
|
@@ -179,4 +181,4 @@ export * from "./mcp/discovery.js";
|
|
|
179
181
|
export * from "./query.js";
|
|
180
182
|
export * from "./testing.js";
|
|
181
183
|
//# sourceMappingURL=index.js.map
|
|
182
|
-
//# debugId=
|
|
184
|
+
//# debugId=ea74fa78-184f-55e7-8c8e-fb912f4d26d8
|
|
@@ -56,7 +56,9 @@ export interface MergeDriverResult {
|
|
|
56
56
|
item?: {
|
|
57
57
|
fields_from_theirs: string[];
|
|
58
58
|
union_fields: string[];
|
|
59
|
-
conflict_resolution: "
|
|
59
|
+
conflict_resolution: "latest_document_update";
|
|
60
|
+
/** Item scalars ignore branch-direction preference under the convergent recency policy. */
|
|
61
|
+
requested_preference_applied: false;
|
|
60
62
|
};
|
|
61
63
|
/** JSON-merge key accounting; present only for the json artifact. */
|
|
62
64
|
json?: {
|
package/dist/sdk/merge/driver.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* merge never corrupts tracker storage the way raw conflict markers do.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
12
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="5dc5f70c-0b04-51bb-983b-49b15be11587")}catch(e){}}();
|
|
13
13
|
import { readFile, writeFile } from "node:fs/promises";
|
|
14
14
|
import path from "node:path";
|
|
15
15
|
import { getActiveExtensionRegistrations } from "../../core/extensions/index.js";
|
|
@@ -18,11 +18,10 @@ import { pathExists } from "../../core/fs/fs-utils.js";
|
|
|
18
18
|
import { parseItemDocument } from "../../core/item/item-format.js";
|
|
19
19
|
import { EXIT_CODE } from "../../core/shared/constants.js";
|
|
20
20
|
import { PmCliError } from "../../core/shared/errors.js";
|
|
21
|
-
import { sha256Hex, stableStringify } from "../../core/shared/serialization.js";
|
|
22
21
|
import { nowIso } from "../../core/shared/time.js";
|
|
23
22
|
import { getSettingsPath, resolvePmRoot } from "../../core/store/paths.js";
|
|
24
23
|
import { readSettings } from "../../core/store/settings.js";
|
|
25
|
-
import { mergeHistoryStreams, mergeItemDocuments, mergeJsonDocuments, mergeRelationshipEventStreams, } from "./three-way.js";
|
|
24
|
+
import { hashItemScalarDecisionValue, mergeHistoryStreams, mergeItemDocuments, mergeJsonDocuments, mergeRelationshipEventStreams, } from "./three-way.js";
|
|
26
25
|
import { summarizeMergeReceipt, writeMergeReceipt, } from "./receipts.js";
|
|
27
26
|
/** Supported values accepted by the merge driver artifact contract across CLI, SDK, and MCP surfaces. */
|
|
28
27
|
export const MERGE_DRIVER_ARTIFACT_VALUES = [
|
|
@@ -131,14 +130,15 @@ export async function runMergeDriver(options, global) {
|
|
|
131
130
|
schema: settings?.schema,
|
|
132
131
|
extensionFieldNames,
|
|
133
132
|
preferred,
|
|
134
|
-
conflictResolution: "
|
|
133
|
+
conflictResolution: "latest_document_update",
|
|
135
134
|
});
|
|
136
135
|
merged = itemMerge.merged;
|
|
137
136
|
conflicts.push(...itemMerge.conflict_fields);
|
|
138
137
|
result.item = {
|
|
139
138
|
fields_from_theirs: itemMerge.fields_from_theirs,
|
|
140
139
|
union_fields: itemMerge.union_fields,
|
|
141
|
-
conflict_resolution: "
|
|
140
|
+
conflict_resolution: "latest_document_update",
|
|
141
|
+
requested_preference_applied: false,
|
|
142
142
|
};
|
|
143
143
|
if (options.itemPath !== undefined) {
|
|
144
144
|
const mergedDocument = parseItemDocument(merged, {
|
|
@@ -158,12 +158,12 @@ export async function runMergeDriver(options, global) {
|
|
|
158
158
|
cwd: process.cwd(),
|
|
159
159
|
itemPath: options.itemPath,
|
|
160
160
|
preferred,
|
|
161
|
-
conflictResolution: "
|
|
161
|
+
conflictResolution: "latest_document_update",
|
|
162
162
|
fieldsFromTheirs: itemMerge.fields_from_theirs,
|
|
163
163
|
unionFields: itemMerge.union_fields,
|
|
164
164
|
mergedFieldHashes: Object.fromEntries(receiptFields.map((field) => [
|
|
165
165
|
field,
|
|
166
|
-
|
|
166
|
+
hashItemScalarDecisionValue(field === "body" ? mergedDocument.body : mergedMetadata[field]),
|
|
167
167
|
])),
|
|
168
168
|
decisions: itemMerge.conflict_decisions,
|
|
169
169
|
};
|
|
@@ -191,7 +191,7 @@ export async function runMergeDriver(options, global) {
|
|
|
191
191
|
const receiptGuidance = result.receipt === undefined
|
|
192
192
|
? 'Run "pm merge report" to inspect clone-local merge evidence.'
|
|
193
193
|
: `Run "pm merge report" and correlate receipt ${result.receipt.receipt_id} with item ${result.receipt.item_id}; clone-local discarded values are never copied into this result.`;
|
|
194
|
-
guidance.push(`Both branches changed ${conflicts.join(", ")}; the item driver kept the
|
|
194
|
+
guidance.push(`Both branches changed ${conflicts.join(", ")}; the item driver kept the value from the later document update, with stable value order only as an equal-timestamp tie-break. --prefer does not apply to convergent item scalar conflicts. ${receiptGuidance} Review the merged file, re-apply the discarded change if needed, then "git add" it.`);
|
|
195
195
|
}
|
|
196
196
|
if (artifact === "history" && result.history?.reanchored) {
|
|
197
197
|
guidance.push('The merged history chain was re-anchored. Run "pm merge reconcile --dry-run" to inspect the complete post-merge repair, then "pm merge reconcile" to apply it; use --force only after explicitly accepting reported discards.');
|
|
@@ -208,4 +208,4 @@ export async function runMergeDriver(options, global) {
|
|
|
208
208
|
};
|
|
209
209
|
}
|
|
210
210
|
//# sourceMappingURL=driver.js.map
|
|
211
|
-
//# debugId=
|
|
211
|
+
//# debugId=5dc5f70c-0b04-51bb-983b-49b15be11587
|