@unbrained/pm-cli 2026.8.24 → 2026.8.26
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 +46 -0
- package/dist/cli-bundle/bundle-manifest.json +149 -149
- package/dist/cli-bundle/chunks/chunk-E2GCFJSU.js +35 -0
- package/dist/cli-bundle/chunks/{chunk-TEQDR5KI.js → chunk-ES25LX3D.js} +62 -62
- package/dist/cli-bundle/chunks/{chunk-I5Q7QSZX.js → chunk-FRDWWB6R.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-X7WWQDYQ.js → chunk-ICQ3RVIY.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-YOLLRCLY.js → chunk-IV64RJVE.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-L22NP5MA.js → chunk-KBFP3E4E.js} +86 -86
- package/dist/cli-bundle/chunks/{chunk-AGUL3HUT.js → chunk-MVYLQ67M.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-DJNJBWAQ.js → chunk-S4U76VZF.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-IW72J5FW.js → chunk-UKBCRPA2.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-WRHJ3MB6.js +8 -0
- package/dist/cli-bundle/chunks/{chunk-ZAVCS2GH.js → chunk-ZNRLJ54C.js} +60 -60
- package/dist/cli-bundle/chunks/{register-list-query-37A4P6O4.js → register-list-query-EMCPMICY.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-TBJDHYIT.js → register-mutation-OJ67ABCB.js} +3 -3
- package/dist/cli-bundle/chunks/{register-operations-WRZNEBUM.js → register-operations-H2GLP7LT.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-H4PDLACD.js → register-setup-GLZAHLVI.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-IMWTYKII.js → chunk-4K2II4TV.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-4XNH2HM7.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-GJR6YEMR.js → chunk-57XY346D.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-4WP7LNE3.js → chunk-66VGB23P.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-72T6JGAE.js +50 -0
- package/dist/cli-bundle/focused-chunks/{chunk-BFA6KKCI.js → chunk-7I23XGWO.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-6Z24ZMU3.js → chunk-7YCDTCBC.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-O4ZXNJMT.js → chunk-A644DUFQ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-FXDLT6FL.js +16 -0
- package/dist/cli-bundle/focused-chunks/{chunk-RASVBJX5.js → chunk-IBHXMFE7.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-LMKG3DFE.js +5 -0
- package/dist/cli-bundle/focused-chunks/{chunk-6MUTDXMP.js → chunk-LV5N3LK5.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-CWCN5RLO.js → chunk-MMXUPDDJ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-WZLSSGEU.js → chunk-OHIHZ7HS.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-P2E6LDAE.js +19 -0
- package/dist/cli-bundle/focused-chunks/{chunk-IZNRRCU3.js → chunk-TMJDFHVD.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-QBP5FSBX.js → chunk-UYBA57GY.js} +4 -4
- package/dist/cli-bundle/focused-chunks/{chunk-MNPECIRL.js → chunk-YO3ZF3FI.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 +2 -2
- package/dist/cli-bundle/sdk-core.js +41 -41
- 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 +32 -33
- 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 +7 -6
- package/dist/core/diagnostics/remediation.js +17 -2
- package/dist/core/extensions/manifest-schema.d.ts +20 -0
- package/dist/core/extensions/manifest-schema.js +28 -10
- package/dist/mcp/http-server.d.ts +60 -0
- package/dist/mcp/http-server.js +451 -0
- package/dist/mcp/legacy-adapter.d.ts +50 -0
- package/dist/mcp/legacy-adapter.js +64 -0
- package/dist/mcp/server.d.ts +42 -9
- package/dist/mcp/server.js +457 -58
- package/dist/sdk/agent/refusal-closure-census.d.ts +6 -2
- package/dist/sdk/agent/refusal-closure-census.js +16 -8
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +10 -0
- package/dist/sdk/cli-contracts/runtime-contracts.js +20 -3
- package/dist/sdk/compose.d.ts +4 -1
- package/dist/sdk/compose.js +23 -36
- package/dist/sdk/extension/author-manifest.d.ts +22 -0
- package/dist/sdk/extension/author-manifest.js +93 -0
- package/dist/sdk/extension.js +6 -3
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +67 -28
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +30 -3
- package/dist/sdk/governance/health.js +103 -11
- package/dist/sdk/governance/validate.js +15 -9
- package/dist/sdk/history-repair.d.ts +24 -0
- package/dist/sdk/history-repair.js +145 -4
- package/dist/sdk/index.d.ts +6 -0
- package/dist/sdk/index.js +8 -2
- package/dist/sdk/mcp/authorization.d.ts +134 -0
- package/dist/sdk/mcp/authorization.js +405 -0
- package/dist/sdk/mcp/interactions.d.ts +118 -0
- package/dist/sdk/mcp/interactions.js +337 -0
- package/dist/sdk/mcp/protocol.d.ts +142 -0
- package/dist/sdk/mcp/protocol.js +174 -0
- package/dist/sdk/mcp/subscriptions.d.ts +65 -0
- package/dist/sdk/mcp/subscriptions.js +212 -0
- package/dist/sdk/mcp/tasks.d.ts +107 -0
- package/dist/sdk/mcp/tasks.js +431 -0
- package/dist/sdk/mcp/transport.d.ts +30 -0
- package/dist/sdk/mcp/transport.js +261 -0
- package/dist/sdk/merge/driver.js +25 -4
- package/dist/sdk/merge/receipt-file-boundary.d.ts +21 -0
- package/dist/sdk/merge/receipt-file-boundary.js +47 -0
- package/dist/sdk/merge/receipts.d.ts +40 -1
- package/dist/sdk/merge/receipts.js +343 -36
- package/dist/sdk/merge/reconcile.js +117 -47
- package/dist/sdk/read-output/continuation.d.ts +15 -2
- package/dist/sdk/read-output/continuation.js +86 -6
- package/dist/sdk/read-output-contracts.d.ts +4 -1
- package/dist/sdk/read-output-contracts.js +9 -6
- package/dist/sdk/runtime-primitives.d.ts +1 -1
- package/dist/sdk/runtime-primitives.js +3 -3
- package/dist/sdk/test/execution.d.ts +6 -0
- package/dist/sdk/test/execution.js +32 -3
- package/docs/AGENT_PROVENANCE_ADR.md +6 -4
- package/docs/AGENT_RUNTIME_PRIMITIVES.md +6 -5
- package/docs/CLAUDE_CODE_PLUGIN.md +12 -5
- package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +8 -0
- package/docs/EXTENSIONS.md +3 -4
- package/docs/MCP_2026_07_28.md +138 -0
- package/docs/MCP_2026_07_28_CONFORMANCE.md +30 -0
- package/docs/MCP_REMOTE_TRANSPORT_SECURITY.md +180 -0
- package/docs/MERGE_SAFETY.md +34 -5
- package/docs/OUTPUT_PROJECTION_CONTRACTS.md +13 -1
- package/docs/README.md +4 -0
- package/docs/READ_OUTPUT_CONTRACTS.md +25 -2
- package/docs/RELEASING.md +3 -2
- package/docs/SDK.md +22 -1
- package/docs/SDK_AGENT_SESSION_CONTEXT.md +18 -13
- package/docs/SDK_MCP_INTERACTIONS.md +227 -0
- package/docs/TESTING.md +4 -0
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +13 -8
- package/marketplace.json +2 -2
- package/package.json +7 -5
- 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/scripts/finalize-build.mjs +1 -0
- package/sdk/public-surface.json +762 -15
- package/dist/cli-bundle/chunks/chunk-MKE6MD2K.js +0 -36
- package/dist/cli-bundle/chunks/chunk-NXBFO63A.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-FCTT4CZU.js +0 -5
- package/dist/cli-bundle/focused-chunks/chunk-Q63PSLO4.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-QV5UP27O.js +0 -51
- package/dist/cli-bundle/focused-chunks/chunk-RPRLENVA.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-TOFVXBWA.js +0 -19
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the pm health 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]="652d1b49-f9d1-55a7-84b5-ff3cf57648ad")}catch(e){}}();
|
|
8
8
|
import fs from "node:fs/promises";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { assertInitializedTracker } from "../environment/tracker-preflight.js";
|
|
@@ -41,11 +41,13 @@ import { scanHistoryAuthorAttribution, } from "../author-attribution.js";
|
|
|
41
41
|
import { readManagedExtensionState } from "../extension.js";
|
|
42
42
|
import { scanProvenanceResolverHealth } from "./provenance-health.js";
|
|
43
43
|
import { applyStoredExtensionMigrationState } from "../extension/migrations.js";
|
|
44
|
+
import { inspectExtensionAuthorManifest } from "../extension/author-manifest.js";
|
|
44
45
|
import { buildCapabilityContractMetadata, buildRegistrationCollisionRemediation, collectUnknownCapabilityGuidance, } from "../extension/doctor.js";
|
|
45
46
|
import { scanStaleInProgressItems, } from "./stale-work.js";
|
|
46
47
|
import { scanTrackedRuntimeCache } from "./tracked-runtime-cache.js";
|
|
47
48
|
import { auditMergeDriverConfiguration, findGitWorkspaceRoot, } from "../merge/install.js";
|
|
48
|
-
import {
|
|
49
|
+
import { inspectMergeReceiptEvidence, partitionMergeReceipts, } from "../merge/receipts.js";
|
|
50
|
+
import { runHistoryRepair } from "../history-repair.js";
|
|
49
51
|
import { resolveWorkspaceRelationshipKindRegistry } from "../graph/assembly.js";
|
|
50
52
|
import { analyzeHierarchyIntegrity, } from "../graph/hierarchy-integrity.js";
|
|
51
53
|
const PM_TELEMETRY_SOURCE_CONTEXT_SET = new Set(PM_TELEMETRY_SOURCE_CONTEXT_VALUES);
|
|
@@ -333,6 +335,11 @@ function buildHierarchyIntegrityWarnings(analysis) {
|
|
|
333
335
|
: `integrity_hierarchy_divergence:${finding.child_id}`),
|
|
334
336
|
];
|
|
335
337
|
}
|
|
338
|
+
function buildMergeReceiptEvidenceWarnings(invalidEvidenceCount) {
|
|
339
|
+
return invalidEvidenceCount === 0
|
|
340
|
+
? []
|
|
341
|
+
: [`merge_receipt_evidence_invalid:${invalidEvidenceCount}`];
|
|
342
|
+
}
|
|
336
343
|
async function buildIntegrityCheck(pmRoot, typeToFolder, schema, requireMergeDrivers, items) {
|
|
337
344
|
const itemScan = await scanItemIntegrity(pmRoot, typeToFolder, schema);
|
|
338
345
|
const historyScan = await scanHistoryIntegrity(pmRoot);
|
|
@@ -344,12 +351,11 @@ async function buildIntegrityCheck(pmRoot, typeToFolder, schema, requireMergeDri
|
|
|
344
351
|
const mergeDriverAudit = gitWorkspaceRoot === null
|
|
345
352
|
? null
|
|
346
353
|
: await auditMergeDriverConfiguration(gitWorkspaceRoot);
|
|
347
|
-
const
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
});
|
|
354
|
+
const mergeReceiptEvidence = await inspectMergeReceiptEvidence(gitWorkspaceRoot ?? pmRoot, {
|
|
355
|
+
includeLossless: true,
|
|
356
|
+
pmRoot,
|
|
357
|
+
});
|
|
358
|
+
const pendingMergeReceipts = mergeReceiptEvidence.receipts;
|
|
353
359
|
const { pendingDecisions: pendingMergeDecisions, lossless: losslessMergeReceipts, } = partitionMergeReceipts(pendingMergeReceipts);
|
|
354
360
|
const mergeDriverInstallationMissing = mergeDriverAudit?.status === "missing" &&
|
|
355
361
|
mergeDriverAudit.missing_keys.length === 5 &&
|
|
@@ -379,6 +385,10 @@ async function buildIntegrityCheck(pmRoot, typeToFolder, schema, requireMergeDri
|
|
|
379
385
|
...(pendingMergeDecisions.length > 0
|
|
380
386
|
? [`merge_decisions_unreviewed:${pendingMergeDecisions.length}`]
|
|
381
387
|
: []),
|
|
388
|
+
...(losslessMergeReceipts.length > 0
|
|
389
|
+
? [`merge_receipts_pending:${losslessMergeReceipts.length}`]
|
|
390
|
+
: []),
|
|
391
|
+
...buildMergeReceiptEvidenceWarnings(mergeReceiptEvidence.invalid_evidence_count),
|
|
382
392
|
];
|
|
383
393
|
const normalizedWarnings = [...new Set(warnings)].sort((left, right) => left.localeCompare(right));
|
|
384
394
|
const actionableWarnings = normalizedWarnings.filter((warning) => !warning.startsWith("integrity_legacy_hierarchy_"));
|
|
@@ -409,6 +419,7 @@ async function buildIntegrityCheck(pmRoot, typeToFolder, schema, requireMergeDri
|
|
|
409
419
|
mergeDriverAudit.drifted_keys.length,
|
|
410
420
|
pending_merge_decisions: pendingMergeDecisions.length,
|
|
411
421
|
lossless_merge_receipts: losslessMergeReceipts.length,
|
|
422
|
+
invalid_merge_receipt_evidence: mergeReceiptEvidence.invalid_evidence_count,
|
|
412
423
|
},
|
|
413
424
|
item_unreadable: itemScan.unreadable,
|
|
414
425
|
item_conflict_markers: itemScan.conflictMarkers,
|
|
@@ -443,6 +454,8 @@ async function buildIntegrityCheck(pmRoot, typeToFolder, schema, requireMergeDri
|
|
|
443
454
|
},
|
|
444
455
|
},
|
|
445
456
|
warnings: normalizedWarnings,
|
|
457
|
+
gitWorkspaceRoot,
|
|
458
|
+
pendingMergeReceipts,
|
|
446
459
|
};
|
|
447
460
|
}
|
|
448
461
|
/* c8 ignore start -- activate export shape variants are exercised through integration load tests */
|
|
@@ -637,6 +650,7 @@ function buildExtensionHealthTriageSummary(warnings, loadFailureCount, activatio
|
|
|
637
650
|
};
|
|
638
651
|
}
|
|
639
652
|
async function buildExtensionCheck(pmRoot, settings, noExtensionsFlag) {
|
|
653
|
+
const authorManifest = await inspectExtensionAuthorManifest(resolveWorkspaceRoot(pmRoot));
|
|
640
654
|
const loadResult = await loadExtensions({
|
|
641
655
|
pmRoot,
|
|
642
656
|
settings,
|
|
@@ -723,6 +737,7 @@ async function buildExtensionCheck(pmRoot, settings, noExtensionsFlag) {
|
|
|
723
737
|
]
|
|
724
738
|
: [];
|
|
725
739
|
const extensionWarnings = [
|
|
740
|
+
...authorManifest.warnings,
|
|
726
741
|
...loadResult.warnings,
|
|
727
742
|
...activationDetails.warnings,
|
|
728
743
|
...migrationStatus.warnings,
|
|
@@ -745,6 +760,7 @@ async function buildExtensionCheck(pmRoot, settings, noExtensionsFlag) {
|
|
|
745
760
|
loaded: loadedSummaries,
|
|
746
761
|
warnings: extensionWarnings,
|
|
747
762
|
activation: activationDetails,
|
|
763
|
+
author_manifest: authorManifest,
|
|
748
764
|
triage: extensionTriage,
|
|
749
765
|
...(migrationStatus.summary.pending_count > 0
|
|
750
766
|
? {
|
|
@@ -890,6 +906,7 @@ const HEALTH_DETAIL_SUMMARIZERS = {
|
|
|
890
906
|
registration_counts: activation.registration_counts,
|
|
891
907
|
migration_status: summarizeActivationMigrationStatus(activation.migration_status),
|
|
892
908
|
},
|
|
909
|
+
author_manifest: details.author_manifest,
|
|
893
910
|
triage: details.triage,
|
|
894
911
|
capability_contract: details.capability_contract,
|
|
895
912
|
capability_guidance: summarizeRecordList(details.capability_guidance, limit),
|
|
@@ -949,6 +966,7 @@ const HEALTH_DETAIL_SUMMARIZERS = {
|
|
|
949
966
|
checked_items: details.checked_items,
|
|
950
967
|
counts: details.counts,
|
|
951
968
|
drifted_items: summarizeStringList(details.drifted_items, limit),
|
|
969
|
+
merge_receipt_attributed_items: summarizeStringList(details.merge_receipt_attributed_items, limit),
|
|
952
970
|
missing_streams: summarizeStringList(details.missing_streams, limit),
|
|
953
971
|
unreadable_streams: summarizeStringList(details.unreadable_streams, limit),
|
|
954
972
|
hash_mismatches: summarizeStringList(details.hash_mismatches, limit),
|
|
@@ -1922,7 +1940,9 @@ function buildHealthFindings(params) {
|
|
|
1922
1940
|
function rewriteBulkHealthRemediation(params) {
|
|
1923
1941
|
if (params.check.name === "history_drift" && params.historyDriftedCount > 1) {
|
|
1924
1942
|
for (const code of Object.keys(params.remediationMap)) {
|
|
1925
|
-
|
|
1943
|
+
if (code !== "history_drift_merge_receipt") {
|
|
1944
|
+
params.remediationMap[code] = "pm history-repair --all";
|
|
1945
|
+
}
|
|
1926
1946
|
}
|
|
1927
1947
|
}
|
|
1928
1948
|
if (params.check.name === "storage" && params.overThresholdCount > 1) {
|
|
@@ -1945,6 +1965,67 @@ function attachHealthRemediationMaps(params) {
|
|
|
1945
1965
|
}
|
|
1946
1966
|
}
|
|
1947
1967
|
}
|
|
1968
|
+
async function correlateMergeReceiptHistoryDriftItems(params) {
|
|
1969
|
+
if (params.gitWorkspaceRoot === null ||
|
|
1970
|
+
params.pendingMergeReceipts.length === 0) {
|
|
1971
|
+
return [];
|
|
1972
|
+
}
|
|
1973
|
+
const details = params.historyDriftCheck.check.details;
|
|
1974
|
+
const hashMismatches = Array.isArray(details.hash_mismatches)
|
|
1975
|
+
? details.hash_mismatches.filter((entry) => typeof entry === "string")
|
|
1976
|
+
: [];
|
|
1977
|
+
const unsafeStreamIds = new Set([
|
|
1978
|
+
details.missing_streams,
|
|
1979
|
+
details.unreadable_streams,
|
|
1980
|
+
details.chain_mismatches,
|
|
1981
|
+
].flatMap((value) => (Array.isArray(value) ? value : [])));
|
|
1982
|
+
const cloneLocalReceiptsByItem = new Map();
|
|
1983
|
+
for (const receipt of params.pendingMergeReceipts) {
|
|
1984
|
+
if (receipt.evidence_source !== "clone_local")
|
|
1985
|
+
continue;
|
|
1986
|
+
const receipts = cloneLocalReceiptsByItem.get(receipt.item_id) ?? [];
|
|
1987
|
+
receipts.push(receipt);
|
|
1988
|
+
cloneLocalReceiptsByItem.set(receipt.item_id, receipts);
|
|
1989
|
+
}
|
|
1990
|
+
const attributed = [];
|
|
1991
|
+
for (const id of hashMismatches) {
|
|
1992
|
+
if (unsafeStreamIds.has(id))
|
|
1993
|
+
continue;
|
|
1994
|
+
const receipts = cloneLocalReceiptsByItem.get(id);
|
|
1995
|
+
if (!receipts || receipts.length === 0)
|
|
1996
|
+
continue;
|
|
1997
|
+
try {
|
|
1998
|
+
const repair = await runHistoryRepair(id, {
|
|
1999
|
+
dryRun: true,
|
|
2000
|
+
mergeReceiptProof: {
|
|
2001
|
+
gitWorkspaceRoot: params.gitWorkspaceRoot,
|
|
2002
|
+
receipts,
|
|
2003
|
+
},
|
|
2004
|
+
}, params.global);
|
|
2005
|
+
if (repair.merge_receipt_proof?.trusted)
|
|
2006
|
+
attributed.push(id);
|
|
2007
|
+
}
|
|
2008
|
+
catch {
|
|
2009
|
+
// Fail closed: generic history-repair guidance remains authoritative.
|
|
2010
|
+
}
|
|
2011
|
+
}
|
|
2012
|
+
return [...new Set(attributed)].sort((left, right) => left.localeCompare(right));
|
|
2013
|
+
}
|
|
2014
|
+
function applyMergeReceiptHistoryDriftAttribution(historyDriftCheck, attributedItems) {
|
|
2015
|
+
const attributed = new Set(attributedItems);
|
|
2016
|
+
historyDriftCheck.warnings = [
|
|
2017
|
+
...historyDriftCheck.warnings.filter((warning) => {
|
|
2018
|
+
if (!warning.startsWith("history_drift_hash_mismatch:"))
|
|
2019
|
+
return true;
|
|
2020
|
+
return !attributed.has(warning.slice(warning.indexOf(":") + 1));
|
|
2021
|
+
}),
|
|
2022
|
+
...attributedItems.map((id) => `history_drift_merge_receipt:${id}`),
|
|
2023
|
+
].sort((left, right) => left.localeCompare(right));
|
|
2024
|
+
historyDriftCheck.check.details = {
|
|
2025
|
+
...historyDriftCheck.check.details,
|
|
2026
|
+
merge_receipt_attributed_items: attributedItems,
|
|
2027
|
+
};
|
|
2028
|
+
}
|
|
1948
2029
|
function projectHealthResult(result, options, summaryMode) {
|
|
1949
2030
|
const warningCount = result.warning_count ?? result.warnings.length;
|
|
1950
2031
|
const boundedResult = {
|
|
@@ -2030,11 +2111,22 @@ export async function runHealth(global, options = {}) {
|
|
|
2030
2111
|
const provenanceWarnings = provenanceResolverHealth.warnings;
|
|
2031
2112
|
const locksCheck = await buildLocksCheck(pmRoot);
|
|
2032
2113
|
const integrityCheck = skipPolicy.skipIntegrity
|
|
2033
|
-
?
|
|
2114
|
+
? {
|
|
2115
|
+
...buildSkippedHealthCheck("integrity"),
|
|
2116
|
+
gitWorkspaceRoot: null,
|
|
2117
|
+
pendingMergeReceipts: [],
|
|
2118
|
+
}
|
|
2034
2119
|
: await buildIntegrityCheck(pmRoot, typeRegistry.type_to_folder, settings.schema, options.requireMergeDrivers === true, items);
|
|
2035
2120
|
const historyDriftCheck = skipPolicy.skipDrift
|
|
2036
2121
|
? buildSkippedHealthCheck("history_drift")
|
|
2037
2122
|
: await buildHistoryDriftCheck(pmRoot, itemsWithBody);
|
|
2123
|
+
const mergeReceiptAttributedHistoryDriftItems = await correlateMergeReceiptHistoryDriftItems({
|
|
2124
|
+
gitWorkspaceRoot: integrityCheck.gitWorkspaceRoot,
|
|
2125
|
+
pendingMergeReceipts: integrityCheck.pendingMergeReceipts,
|
|
2126
|
+
historyDriftCheck,
|
|
2127
|
+
global,
|
|
2128
|
+
});
|
|
2129
|
+
applyMergeReceiptHistoryDriftAttribution(historyDriftCheck, mergeReceiptAttributedHistoryDriftItems);
|
|
2038
2130
|
const vectorizationCheck = skipPolicy.skipVectors
|
|
2039
2131
|
? buildSkippedHealthCheck("vectorization")
|
|
2040
2132
|
: await buildVectorizationCheck(pmRoot, settings, itemsWithBody, refreshPolicy, options.verboseStaleItems === true);
|
|
@@ -2142,4 +2234,4 @@ export const _testOnlyHealthCommand = {
|
|
|
2142
2234
|
warningCode,
|
|
2143
2235
|
};
|
|
2144
2236
|
//# sourceMappingURL=health.js.map
|
|
2145
|
-
//# debugId=
|
|
2237
|
+
//# debugId=652d1b49-f9d1-55a7-84b5-ff3cf57648ad
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the pm validate 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]="3d7d6f15-7587-5c22-8deb-373bfd063d2b")}catch(e){}}();
|
|
8
8
|
import { assertInitializedTracker } from "../environment/tracker-preflight.js";
|
|
9
9
|
import fs from "node:fs/promises";
|
|
10
10
|
import { realpathSync } from "node:fs";
|
|
@@ -34,7 +34,7 @@ import { buildMissingLinkedPathRows, summarizeMissingLinkedPathRows, } from "../
|
|
|
34
34
|
import { assertProjectionModeChoice, } from "../output-projection.js";
|
|
35
35
|
import { collectDanglingDependencyReferences } from "../graph/assembly.js";
|
|
36
36
|
import { auditMergeAttributeFence, auditMergeDriverConfiguration, findGitWorkspaceRoot, resolveProjectMergeTypeFolders, } from "../merge/install.js";
|
|
37
|
-
import {
|
|
37
|
+
import { inspectMergeReceiptEvidence, partitionMergeReceipts, } from "../merge/receipts.js";
|
|
38
38
|
import { scanStorageIntegrity } from "./storage-integrity.js";
|
|
39
39
|
import { scanTrackedRuntimeCache } from "./tracked-runtime-cache.js";
|
|
40
40
|
import { scanHistoryAuthorAttribution } from "../author-attribution.js";
|
|
@@ -1991,6 +1991,11 @@ export const _testOnlyValidateCommand = {
|
|
|
1991
1991
|
summarizeDuplicateIssueCodes,
|
|
1992
1992
|
toMeaningfulString,
|
|
1993
1993
|
};
|
|
1994
|
+
function appendInvalidMergeReceiptEvidenceWarning(warnings, invalidEvidenceCount) {
|
|
1995
|
+
if (invalidEvidenceCount > 0) {
|
|
1996
|
+
warnings.push(`merge_receipt_evidence_invalid:${invalidEvidenceCount}`);
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1994
1999
|
/** Build the post-merge storage-integrity check (GH-603/GH-607/GH-609/GH-611): provably corrupted storage — unreadable item documents, on-disk-vs-parsed census mismatches, history conflict markers, resurrected deletes, and unparseable config/schema files — fails validate as an error instead of hiding behind ok:true. The `history_repair_reconciliations` count is informational: it surfaces post-repair divergence without permanently failing repaired workspaces. */
|
|
1995
2000
|
async function buildStorageIntegrityCheck(pmRoot, items, typeToFolder, settings) {
|
|
1996
2001
|
const scan = await scanStorageIntegrity(pmRoot, new Set(items.map((item) => item.id)), typeToFolder, {
|
|
@@ -2032,16 +2037,16 @@ async function buildStorageIntegrityCheck(pmRoot, items, typeToFolder, settings)
|
|
|
2032
2037
|
if (mergeDriverAudit !== null && mergeDriverAudit.status !== "ok") {
|
|
2033
2038
|
warnings.push(`validate_merge_driver_configuration:${mergeDriverAudit.missing_keys.length + mergeDriverAudit.drifted_keys.length}`);
|
|
2034
2039
|
}
|
|
2035
|
-
const
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
});
|
|
2040
|
+
const mergeReceiptEvidence = await inspectMergeReceiptEvidence(gitWorkspaceRoot ?? pmRoot, {
|
|
2041
|
+
includeLossless: true,
|
|
2042
|
+
pmRoot,
|
|
2043
|
+
});
|
|
2044
|
+
const pendingMergeReceipts = mergeReceiptEvidence.receipts;
|
|
2041
2045
|
const { pendingDecisions: pendingMergeDecisions, lossless: losslessMergeReceipts, } = partitionMergeReceipts(pendingMergeReceipts);
|
|
2042
2046
|
if (pendingMergeDecisions.length > 0) {
|
|
2043
2047
|
warnings.push(`validate_merge_decisions_unreviewed:${pendingMergeDecisions.length}`);
|
|
2044
2048
|
}
|
|
2049
|
+
appendInvalidMergeReceiptEvidenceWarning(warnings, mergeReceiptEvidence.invalid_evidence_count);
|
|
2045
2050
|
const status = errorCount > 0 ? "error" : warnings.length > 0 ? "warn" : "ok";
|
|
2046
2051
|
return {
|
|
2047
2052
|
check: {
|
|
@@ -2060,6 +2065,7 @@ async function buildStorageIntegrityCheck(pmRoot, items, typeToFolder, settings)
|
|
|
2060
2065
|
...new Set(pendingMergeDecisions.map((receipt) => receipt.item_id)),
|
|
2061
2066
|
].sort((left, right) => left.localeCompare(right)),
|
|
2062
2067
|
lossless_merge_receipt_count: losslessMergeReceipts.length,
|
|
2068
|
+
invalid_merge_receipt_evidence_count: mergeReceiptEvidence.invalid_evidence_count,
|
|
2063
2069
|
lossless_merge_receipt_items: [
|
|
2064
2070
|
...new Set(losslessMergeReceipts.map((receipt) => receipt.item_id)),
|
|
2065
2071
|
].sort((left, right) => left.localeCompare(right)),
|
|
@@ -2280,4 +2286,4 @@ export async function runValidate(options, global, services = {}) {
|
|
|
2280
2286
|
}
|
|
2281
2287
|
/* c8 ignore stop */
|
|
2282
2288
|
//# sourceMappingURL=validate.js.map
|
|
2283
|
-
//# debugId=
|
|
2289
|
+
//# debugId=3d7d6f15-7587-5c22-8deb-373bfd063d2b
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type ReplayDocument } from "../core/history/replay.js";
|
|
2
2
|
import type { GlobalOptions } from "../core/shared/command-types.js";
|
|
3
3
|
import type { HistoryEntry } from "../types/index.js";
|
|
4
|
+
import { type MergeDecisionReceipt } from "./merge/receipts.js";
|
|
4
5
|
import { type ProvenanceNormalizationReceipt } from "./governance/provenance-health.js";
|
|
5
6
|
/** Documents the history repair command options payload exchanged by command, SDK, and package integrations. */
|
|
6
7
|
export interface HistoryRepairCommandOptions {
|
|
@@ -22,6 +23,16 @@ export interface HistoryRepairCommandOptions {
|
|
|
22
23
|
forceAuditEntry?: boolean;
|
|
23
24
|
/** Remove bounded-domain-invalid provenance observations and record an aggregate privacy-safe audit receipt. */
|
|
24
25
|
normalizeProvenance?: boolean;
|
|
26
|
+
/** Internal receipt evidence revalidated against the exact item snapshot used by this repair. */
|
|
27
|
+
mergeReceiptProof?: {
|
|
28
|
+
gitWorkspaceRoot: string | null;
|
|
29
|
+
receipts: MergeDecisionReceipt[];
|
|
30
|
+
};
|
|
31
|
+
/** Internal per-item receipt proof index used by bounded bulk reconciliation. */
|
|
32
|
+
mergeReceiptProofById?: Record<string, {
|
|
33
|
+
gitWorkspaceRoot: string | null;
|
|
34
|
+
receipts: MergeDecisionReceipt[];
|
|
35
|
+
}>;
|
|
25
36
|
}
|
|
26
37
|
/** Documents the history repair result payload exchanged by command, SDK, and package integrations. */
|
|
27
38
|
export interface HistoryRepairResult {
|
|
@@ -60,11 +71,22 @@ export interface HistoryRepairResult {
|
|
|
60
71
|
};
|
|
61
72
|
/** Present when reconciling the chain with the on-disk item discards the replayed effect of earlier history events (GH-603): names the reverted fields and the authors whose mutations the reconciliation overwrites, so cross-author data loss after a lossy merge is loud instead of silent. */
|
|
62
73
|
reconciliation?: HistoryRepairReconciliationReport;
|
|
74
|
+
/** Present when merge reconciliation supplied receipt evidence for this item. */
|
|
75
|
+
merge_receipt_proof?: MergeReceiptProofResult;
|
|
63
76
|
/** Value that configures or reports warnings for this contract. */
|
|
64
77
|
warnings: string[];
|
|
65
78
|
/** ISO 8601 timestamp recording when generated occurred. */
|
|
66
79
|
generated_at: string;
|
|
67
80
|
}
|
|
81
|
+
/** Fail-closed proof that clone-local driver receipts exactly cover the current reconciliation fields and values. */
|
|
82
|
+
export interface MergeReceiptProofResult {
|
|
83
|
+
/** Whether exact receipt identity, path, field, and value-hash evidence proves the snapshot. */
|
|
84
|
+
trusted: boolean;
|
|
85
|
+
/** Stable explanation for the trust decision. */
|
|
86
|
+
reason: "trusted_clone_local_driver_evidence" | "git_workspace_unavailable" | "item_path_unavailable" | "no_item_receipts" | "no_receipt_set_proves_snapshot";
|
|
87
|
+
/** Exact receipt identities accepted as proof; empty when proof is refused. */
|
|
88
|
+
receipt_ids: string[];
|
|
89
|
+
}
|
|
68
90
|
/** Documents one history event attributed to fields changed by reconciliation. */
|
|
69
91
|
export interface HistoryRepairDiscardedEvent {
|
|
70
92
|
/** 1-based index of the event in the (re-anchored) history stream. */
|
|
@@ -121,6 +143,8 @@ export interface HistoryRepairAllStreamResult {
|
|
|
121
143
|
reconciled_with_item?: boolean;
|
|
122
144
|
/** Cross-author data-loss detail when reconciliation overwrites replayed mutations. */
|
|
123
145
|
reconciliation?: HistoryRepairReconciliationReport;
|
|
146
|
+
/** Exact receipt proof used to authorize this stream, when supplied. */
|
|
147
|
+
merge_receipt_proof?: MergeReceiptProofResult;
|
|
124
148
|
/** Stream-specific repair warnings retained by the bulk workflow. */
|
|
125
149
|
warnings?: string[];
|
|
126
150
|
/** Value that configures or reports error for this contract. */
|
|
@@ -4,8 +4,10 @@
|
|
|
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]="7a21ee76-ed53-57a0-9776-c787297ed7b6")}catch(e){}}();
|
|
8
8
|
import { assertInitializedTracker } from "./environment/tracker-preflight.js";
|
|
9
|
+
import { realpath } from "node:fs/promises";
|
|
10
|
+
import path from "node:path";
|
|
9
11
|
import jsonPatch from "fast-json-patch";
|
|
10
12
|
import { patchPathToChangedField } from "../core/history/history-diff.js";
|
|
11
13
|
import { pathExists, readFileIfExists } from "../core/fs/fs-utils.js";
|
|
@@ -19,11 +21,13 @@ import { EXIT_CODE } from "../core/shared/constants.js";
|
|
|
19
21
|
import { PmCliError } from "../core/shared/errors.js";
|
|
20
22
|
import { resolveAuthor } from "../core/shared/author.js";
|
|
21
23
|
import { nowIso } from "../core/shared/time.js";
|
|
24
|
+
import { sha256Hex, stableStringify } from "../core/shared/serialization.js";
|
|
22
25
|
import { getActiveExtensionRegistrations, runActiveOnWriteHooks, } from "../core/extensions/index.js";
|
|
23
26
|
import { listAllItemMetadataWithBody, readLocatedItem, } from "../core/store/item-store.js";
|
|
24
27
|
import { resolvePmRoot } from "../core/store/paths.js";
|
|
25
28
|
import { readSettings } from "../core/store/settings.js";
|
|
26
29
|
import { resolveHistorySubject } from "./history-redact.js";
|
|
30
|
+
import { summarizeMergeReceipt, } from "./merge/receipts.js";
|
|
27
31
|
import { listInvalidProvenanceHistoryStreamIds, normalizeInvalidHistoryProvenance, } from "./governance/provenance-health.js";
|
|
28
32
|
function replayFieldValue(document, field) {
|
|
29
33
|
return field === "body"
|
|
@@ -135,6 +139,130 @@ export function analyzeReconciliationDiscard(entries, finalReplay, currentItemRe
|
|
|
135
139
|
: null,
|
|
136
140
|
};
|
|
137
141
|
}
|
|
142
|
+
async function canonicalRealPath(value) {
|
|
143
|
+
try {
|
|
144
|
+
return await realpath(value);
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
async function verifyReceiptAgainstSnapshot(params) {
|
|
151
|
+
if (params.receipt.evidence_source !== "clone_local")
|
|
152
|
+
return null;
|
|
153
|
+
const receiptPath = await canonicalRealPath(path.resolve(params.gitWorkspaceRoot, params.receipt.item_path));
|
|
154
|
+
if (receiptPath !== params.currentPath)
|
|
155
|
+
return null;
|
|
156
|
+
const declaredFields = [
|
|
157
|
+
...new Set([
|
|
158
|
+
...params.receipt.fields_from_theirs,
|
|
159
|
+
...params.receipt.union_fields,
|
|
160
|
+
...params.receipt.decisions.map((decision) => decision.field),
|
|
161
|
+
]),
|
|
162
|
+
].sort((left, right) => left.localeCompare(right));
|
|
163
|
+
const hashes = params.receipt.merged_field_hashes;
|
|
164
|
+
if (!hashes || declaredFields.length === 0)
|
|
165
|
+
return null;
|
|
166
|
+
const hashFields = Object.keys(hashes).sort((left, right) => left.localeCompare(right));
|
|
167
|
+
if (declaredFields.length !== hashFields.length ||
|
|
168
|
+
declaredFields.some((field, index) => field !== hashFields[index])) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
const currentMetadata = params.currentItemReplay.metadata;
|
|
172
|
+
const valuesMatch = declaredFields.every((field) => {
|
|
173
|
+
const value = field === "body" ? params.currentItemReplay.body : currentMetadata[field];
|
|
174
|
+
return hashes[field] === sha256Hex(stableStringify(value));
|
|
175
|
+
});
|
|
176
|
+
return valuesMatch ? { receipt: params.receipt, declaredFields } : null;
|
|
177
|
+
}
|
|
178
|
+
async function verifyMergeReceiptProof(params) {
|
|
179
|
+
if (params.proof.gitWorkspaceRoot === null) {
|
|
180
|
+
return {
|
|
181
|
+
trusted: false,
|
|
182
|
+
reason: "git_workspace_unavailable",
|
|
183
|
+
receipt_ids: [],
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
if (params.itemPath === null || params.currentItemReplay === null) {
|
|
187
|
+
return {
|
|
188
|
+
trusted: false,
|
|
189
|
+
reason: "item_path_unavailable",
|
|
190
|
+
receipt_ids: [],
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
const itemReceipts = params.proof.receipts.filter((receipt) => receipt.item_id === params.id);
|
|
194
|
+
if (itemReceipts.length === 0) {
|
|
195
|
+
return { trusted: false, reason: "no_item_receipts", receipt_ids: [] };
|
|
196
|
+
}
|
|
197
|
+
const currentPath = await realpath(params.itemPath);
|
|
198
|
+
const trustedReceipts = [];
|
|
199
|
+
for (const receipt of itemReceipts) {
|
|
200
|
+
const trusted = await verifyReceiptAgainstSnapshot({
|
|
201
|
+
receipt,
|
|
202
|
+
gitWorkspaceRoot: params.proof.gitWorkspaceRoot,
|
|
203
|
+
currentPath,
|
|
204
|
+
currentItemReplay: params.currentItemReplay,
|
|
205
|
+
});
|
|
206
|
+
if (trusted)
|
|
207
|
+
trustedReceipts.push(trusted);
|
|
208
|
+
}
|
|
209
|
+
const trustedFields = new Set(trustedReceipts.flatMap(({ declaredFields }) => declaredFields));
|
|
210
|
+
const reconciliationFields = params.reconciliation?.reconciled_fields;
|
|
211
|
+
if (trustedReceipts.length > 0 &&
|
|
212
|
+
(reconciliationFields === undefined ||
|
|
213
|
+
(reconciliationFields.length > 0 &&
|
|
214
|
+
reconciliationFields.every((field) => trustedFields.has(field))))) {
|
|
215
|
+
return {
|
|
216
|
+
trusted: true,
|
|
217
|
+
reason: "trusted_clone_local_driver_evidence",
|
|
218
|
+
receipt_ids: trustedReceipts.map(({ receipt }) => receipt.id),
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
return {
|
|
222
|
+
trusted: false,
|
|
223
|
+
reason: "no_receipt_set_proves_snapshot",
|
|
224
|
+
receipt_ids: [],
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
async function resolveHistoryRepairMergeEvidence(params) {
|
|
228
|
+
const subjectMergeReceipts = params.options.mergeReceiptProof?.receipts.filter((receipt) => receipt.item_id === params.subjectId) ?? [];
|
|
229
|
+
const mergeReceiptProof = params.options.mergeReceiptProof
|
|
230
|
+
? await verifyMergeReceiptProof({
|
|
231
|
+
proof: {
|
|
232
|
+
...params.options.mergeReceiptProof,
|
|
233
|
+
receipts: subjectMergeReceipts,
|
|
234
|
+
},
|
|
235
|
+
id: params.subjectId,
|
|
236
|
+
itemPath: params.itemReplayContext.currentItemPath,
|
|
237
|
+
currentItemReplay: params.itemReplayContext.currentItemReplay,
|
|
238
|
+
reconciliation: params.reconciliation,
|
|
239
|
+
})
|
|
240
|
+
: undefined;
|
|
241
|
+
if (mergeReceiptProof &&
|
|
242
|
+
!mergeReceiptProof.trusted &&
|
|
243
|
+
params.options.dryRun !== true &&
|
|
244
|
+
params.options.force !== true) {
|
|
245
|
+
throw new PmCliError(`Merge receipt evidence for ${params.subjectId} does not prove the exact item snapshot (${mergeReceiptProof.reason}).`, EXIT_CODE.CONFLICT, {
|
|
246
|
+
code: "merge_reconcile_receipt_evidence_untrusted",
|
|
247
|
+
required: "Use clone-local driver evidence whose canonical path, declared fields, and merged-value hashes match the current item, or review the mismatch and rerun with --force.",
|
|
248
|
+
recovery: { suggested_retry: "pm merge reconcile --dry-run" },
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
const provenMergeReceipts = mergeReceiptProof?.trusted
|
|
252
|
+
? subjectMergeReceipts.filter((receipt) => mergeReceiptProof.receipt_ids.includes(receipt.id))
|
|
253
|
+
: [];
|
|
254
|
+
return {
|
|
255
|
+
mergeReceiptProof,
|
|
256
|
+
effectiveAuditContext: provenMergeReceipts.length > 0 && params.options.force !== true
|
|
257
|
+
? {
|
|
258
|
+
...params.options.auditContext,
|
|
259
|
+
merge: {
|
|
260
|
+
receipts: provenMergeReceipts.map(summarizeMergeReceipt),
|
|
261
|
+
},
|
|
262
|
+
}
|
|
263
|
+
: params.options.auditContext,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
138
266
|
async function loadHistoryRepairItemReplay(subject, settings, historyEntries, itemHashVersion) {
|
|
139
267
|
const currentItemPath = subject.located?.itemPath ?? null;
|
|
140
268
|
const loadedItem = subject.located
|
|
@@ -275,6 +403,12 @@ export async function runHistoryRepair(id, options, global) {
|
|
|
275
403
|
const reconciliation = reconcileNeeded && itemReplayContext.currentItemReplay
|
|
276
404
|
? analyzeReconciliationDiscard(reanchor.entries, finalReplay, itemReplayContext.currentItemReplay)
|
|
277
405
|
: undefined;
|
|
406
|
+
const { mergeReceiptProof, effectiveAuditContext } = await resolveHistoryRepairMergeEvidence({
|
|
407
|
+
options,
|
|
408
|
+
subjectId: subject.id,
|
|
409
|
+
itemReplayContext,
|
|
410
|
+
reconciliation,
|
|
411
|
+
});
|
|
278
412
|
const changed = [
|
|
279
413
|
reanchor.entriesRehashed > 0,
|
|
280
414
|
reanchor.entriesPatchRepaired > 0,
|
|
@@ -301,10 +435,10 @@ export async function runHistoryRepair(id, options, global) {
|
|
|
301
435
|
auditOperation: options.auditOperation ?? "history_repair",
|
|
302
436
|
auditContext: provenanceNormalization.receipt.changed
|
|
303
437
|
? {
|
|
304
|
-
...
|
|
438
|
+
...effectiveAuditContext,
|
|
305
439
|
provenance_normalization: provenanceNormalization.receipt,
|
|
306
440
|
}
|
|
307
|
-
:
|
|
441
|
+
: effectiveAuditContext,
|
|
308
442
|
itemHashVersion,
|
|
309
443
|
explicitItemHashVersion: reanchor.explicitItemHashVersion,
|
|
310
444
|
});
|
|
@@ -360,6 +494,7 @@ export async function runHistoryRepair(id, options, global) {
|
|
|
360
494
|
...provenanceNormalization.receipt,
|
|
361
495
|
},
|
|
362
496
|
...(reconciliation ? { reconciliation } : {}),
|
|
497
|
+
...(mergeReceiptProof ? { merge_receipt_proof: mergeReceiptProof } : {}),
|
|
363
498
|
warnings: [...new Set(warnings)].sort((left, right) => left.localeCompare(right)),
|
|
364
499
|
generated_at: nowIso(),
|
|
365
500
|
};
|
|
@@ -397,6 +532,9 @@ export async function runHistoryRepairAll(options, global) {
|
|
|
397
532
|
...options,
|
|
398
533
|
auditContext: options.auditContextById?.[driftedId],
|
|
399
534
|
auditContextById: undefined,
|
|
535
|
+
mergeReceiptProof: options.mergeReceiptProofById?.[driftedId] ??
|
|
536
|
+
options.mergeReceiptProof,
|
|
537
|
+
mergeReceiptProofById: undefined,
|
|
400
538
|
}, global);
|
|
401
539
|
/* c8 ignore next -- mixed repaired/clean outcomes depend on live drift composition. */
|
|
402
540
|
const outcome = result.changed ? "repaired" : "skipped_clean";
|
|
@@ -411,6 +549,9 @@ export async function runHistoryRepairAll(options, global) {
|
|
|
411
549
|
...(result.reconciliation
|
|
412
550
|
? { reconciliation: result.reconciliation }
|
|
413
551
|
: {}),
|
|
552
|
+
...(result.merge_receipt_proof
|
|
553
|
+
? { merge_receipt_proof: result.merge_receipt_proof }
|
|
554
|
+
: {}),
|
|
414
555
|
warnings: result.warnings,
|
|
415
556
|
});
|
|
416
557
|
}
|
|
@@ -440,4 +581,4 @@ export async function runHistoryRepairAll(options, global) {
|
|
|
440
581
|
};
|
|
441
582
|
}
|
|
442
583
|
//# sourceMappingURL=history-repair.js.map
|
|
443
|
-
//# debugId=
|
|
584
|
+
//# debugId=7a21ee76-ed53-57a0-9776-c787297ed7b6
|
package/dist/sdk/index.d.ts
CHANGED
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
* Defines public SDK APIs and package-author helpers for Index.
|
|
5
5
|
*/
|
|
6
6
|
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";
|
|
7
|
+
export * from "./mcp/protocol.js";
|
|
8
|
+
export * from "./mcp/interactions.js";
|
|
9
|
+
export * from "./mcp/tasks.js";
|
|
10
|
+
export * from "./mcp/subscriptions.js";
|
|
11
|
+
export * from "./mcp/transport.js";
|
|
12
|
+
export * from "./mcp/authorization.js";
|
|
7
13
|
export * from "./cli-contracts/grammar-contracts.js";
|
|
8
14
|
export * from "./agent-session-context.js";
|
|
9
15
|
export type { PmCommandCapabilityContract, PmCommandCapabilityFamily, PmCommandVisibilityContract, PmCommandVisibilityTier, PmMcpPromptArgumentContract, PmMcpPromptContract, PmMcpResourceContract, PmMcpToolProfile, } from "./agent-capability-contracts.js";
|
package/dist/sdk/index.js
CHANGED
|
@@ -4,8 +4,14 @@
|
|
|
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]="bfa96f97-ffdf-54f9-b632-006f5dfe2ee3")}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
|
+
export * from "./mcp/protocol.js";
|
|
10
|
+
export * from "./mcp/interactions.js";
|
|
11
|
+
export * from "./mcp/tasks.js";
|
|
12
|
+
export * from "./mcp/subscriptions.js";
|
|
13
|
+
export * from "./mcp/transport.js";
|
|
14
|
+
export * from "./mcp/authorization.js";
|
|
9
15
|
export * from "./cli-contracts/grammar-contracts.js";
|
|
10
16
|
export * from "./agent-session-context.js";
|
|
11
17
|
export { isErrnoError, limitAnnotationEntries, parseAnnotationTextInput, readAnnotationEntries, normalizeAnnotationTransportOptions, resolveAnnotationInput, resolveAnnotationIndex, runAnnotationCommand, wrapOwnershipConflict, } from "./annotations.js";
|
|
@@ -167,4 +173,4 @@ export * from "./governance.js";
|
|
|
167
173
|
export * from "./query.js";
|
|
168
174
|
export * from "./testing.js";
|
|
169
175
|
//# sourceMappingURL=index.js.map
|
|
170
|
-
//# debugId=
|
|
176
|
+
//# debugId=bfa96f97-ffdf-54f9-b632-006f5dfe2ee3
|