@unbrained/pm-cli 2026.8.15 → 2026.8.16
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 +26 -9
- package/dist/cli/error-guidance.d.ts +5 -0
- package/dist/cli/error-guidance.js +15 -2
- package/dist/cli/register-history-author.js +16 -11
- package/dist/cli-bundle/bundle-manifest.json +142 -142
- package/dist/cli-bundle/chunks/{chunk-KIEGUBYQ.js → chunk-47OQEOQB.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-WLPDLNEZ.js → chunk-73UGEBRS.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-QHPCJWEJ.js → chunk-HCIYWD6M.js} +34 -34
- package/dist/cli-bundle/chunks/{chunk-J42EGKDK.js → chunk-I2LUWWR5.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-KLKYLSDX.js → chunk-IC5W2T34.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-AIM6VT2N.js → chunk-PANOOBIS.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-MEM2ZS3O.js → chunk-RIS565OA.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-24GAV7XL.js → chunk-TK6N7HGM.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-TOFG2URD.js +197 -0
- package/dist/cli-bundle/chunks/{chunk-LJHOAVGI.js → chunk-URW4QRMI.js} +47 -41
- package/dist/cli-bundle/chunks/{register-list-query-CT3LFDDN.js → register-list-query-EYCXHZAG.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-NWEVA5YS.js → register-mutation-7YVIG54J.js} +4 -4
- package/dist/cli-bundle/chunks/{register-operations-AHIAG5KM.js → register-operations-KGDNRMCL.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-ZJZFVAKE.js → register-setup-NVXBOD5I.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-KTKH4IMG.js → chunk-4JPEBFFC.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-5NMFSX26.js +155 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ZMFXQ7VF.js → chunk-6ROKKT4X.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-OKA6ELTL.js → chunk-725JSCMP.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-6XKF3PGV.js → chunk-C7JUBRFP.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-KLVUMNXJ.js → chunk-CODV5LUT.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-DQ6SMTBF.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-HAACPSUW.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-EXZA4257.js → chunk-J4UFYHOD.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-7NJ4QYQ2.js → chunk-JX5Z344Q.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-PUISBOPP.js → chunk-L4RDYBIQ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-NSPYTG6G.js → chunk-NJ5RLEFD.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-KT5XMYSX.js → chunk-QYZERYR5.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-M67F5AIN.js → chunk-SSNDYZTM.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-ITAUHSO6.js → chunk-T46KLOIB.js} +45 -45
- package/dist/cli-bundle/focused-chunks/{chunk-WTSER4WJ.js → chunk-TZATVC4G.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-WY3WRPVN.js +2 -0
- package/dist/cli-bundle/main.js +10 -10
- 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 +27 -27
- 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 -32
- 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 +2 -2
- package/dist/core/history/workspace-history.js +32 -10
- package/dist/core/output/output.js +6 -3
- package/dist/core/shared/errors.d.ts +2 -0
- package/dist/core/shared/errors.js +2 -2
- package/dist/core/store/item-store.js +28 -2
- package/dist/sdk/agent/refusal-reachability.d.ts +10 -2
- package/dist/sdk/agent/refusal-reachability.js +71 -3
- package/dist/sdk/author-attribution.d.ts +56 -11
- package/dist/sdk/author-attribution.js +174 -50
- package/dist/sdk/cli-contracts/flag-contracts.js +5 -2
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +9 -2
- package/dist/sdk/cli-contracts/tool-schema.js +12 -4
- package/dist/sdk/completion.js +11 -4
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +38 -14
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +38 -2
- package/dist/sdk/governance/coverage-assurance.d.ts +24 -0
- package/dist/sdk/governance/coverage-assurance.js +61 -0
- package/dist/sdk/governance/extension-host-version.js +20 -9
- package/dist/sdk/index.d.ts +2 -1
- package/dist/sdk/index.js +4 -3
- package/dist/sdk/read-output-contracts.js +5 -3
- package/dist/sdk/runtime.d.ts +2 -5
- package/dist/sdk/runtime.js +3 -2
- package/docs/READ_OUTPUT_CONTRACTS.md +7 -1
- package/docs/RELEASING.md +13 -7
- package/docs/SDK_CONTEXT_INTEGRITY.md +33 -5
- package/docs/SDK_CONTEXT_TRUTH_CONTRACTS.md +13 -5
- package/marketplace.json +2 -2
- package/package.json +1 -1
- 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 +131 -16
- package/dist/cli-bundle/chunks/chunk-DSWDLTDR.js +0 -197
- package/dist/cli-bundle/focused-chunks/chunk-4X57RE4U.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-QLNMCESQ.js +0 -155
- package/dist/cli-bundle/focused-chunks/chunk-SLKC6QLJ.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-U65UC4G3.js +0 -2
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* HistoryEntry format used by item mutations.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
!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]="
|
|
8
|
+
!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]="9027d972-ce29-5511-ba81-27e17d97446e")}catch(e){}}();
|
|
9
9
|
import fs from "node:fs/promises";
|
|
10
10
|
import path from "node:path";
|
|
11
11
|
import { readFileIfExists, writeFileAtomic } from "../fs/fs-utils.js";
|
|
@@ -54,6 +54,28 @@ function workspaceDocuments(document) {
|
|
|
54
54
|
? document.metadata.documents
|
|
55
55
|
: {};
|
|
56
56
|
}
|
|
57
|
+
/** Refuse a workspace mutation or replay whose append-only chain is invalid. */
|
|
58
|
+
function throwWorkspaceHistoryVerificationFailure(errors) {
|
|
59
|
+
throw new PmCliError(`Workspace history verification failed: ${errors.join(", ")}`, EXIT_CODE.CONFLICT, {
|
|
60
|
+
code: "workspace_history_chain_invalid",
|
|
61
|
+
reason: "workspace_history_chain_verification_failed",
|
|
62
|
+
verification_errors: [...errors],
|
|
63
|
+
required: "Repair the _workspace history chain before reading, reconciling, restoring, or appending audited singleton state.",
|
|
64
|
+
why: "Continuing against an unverifiable append-only stream could hide or compound workspace state corruption.",
|
|
65
|
+
examples: [
|
|
66
|
+
"pm history _workspace --verify --json",
|
|
67
|
+
"pm validate --check-history-drift --fix-hints --json",
|
|
68
|
+
],
|
|
69
|
+
nextSteps: [
|
|
70
|
+
"Inspect the exact verification_errors and preserve the corrupt stream as evidence.",
|
|
71
|
+
"Use the history-drift remediation returned by validate before retrying the refused operation.",
|
|
72
|
+
],
|
|
73
|
+
recovery: {
|
|
74
|
+
recovery_mode: "compact",
|
|
75
|
+
next_best_command: "pm history _workspace --verify --json",
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
}
|
|
57
79
|
/** Resolve a governed singleton path and reject paths outside the tracker root. */
|
|
58
80
|
function resolveGovernedDocumentPath(pmRoot, filePath) {
|
|
59
81
|
const absolutePath = path.resolve(filePath);
|
|
@@ -76,7 +98,7 @@ export async function inspectWorkspaceHistoryState(pmRoot) {
|
|
|
76
98
|
const entries = await readHistoryEntries(getWorkspaceHistoryPath(pmRoot), WORKSPACE_HISTORY_ID);
|
|
77
99
|
const verification = verifyHistoryChain(entries);
|
|
78
100
|
if (!verification.ok) {
|
|
79
|
-
|
|
101
|
+
throwWorkspaceHistoryVerificationFailure(verification.errors);
|
|
80
102
|
}
|
|
81
103
|
const documents = workspaceDocuments(entries.length === 0
|
|
82
104
|
? EMPTY_CANONICAL_DOCUMENT
|
|
@@ -123,7 +145,7 @@ async function appendWorkspaceHistoryChangeLocked(change) {
|
|
|
123
145
|
const entries = await readHistoryEntries(historyPath, WORKSPACE_HISTORY_ID);
|
|
124
146
|
const verification = verifyHistoryChain(entries);
|
|
125
147
|
if (!verification.ok) {
|
|
126
|
-
|
|
148
|
+
throwWorkspaceHistoryVerificationFailure(verification.errors);
|
|
127
149
|
}
|
|
128
150
|
const idempotentEntry = change.idempotencyKey === undefined
|
|
129
151
|
? undefined
|
|
@@ -194,7 +216,7 @@ export async function appendWorkspaceAuditEvent(options) {
|
|
|
194
216
|
const entries = await readHistoryEntries(historyPath, WORKSPACE_HISTORY_ID);
|
|
195
217
|
const verification = verifyHistoryChain(entries);
|
|
196
218
|
if (!verification.ok) {
|
|
197
|
-
|
|
219
|
+
throwWorkspaceHistoryVerificationFailure(verification.errors);
|
|
198
220
|
}
|
|
199
221
|
const beforeDocument = entries.length === 0
|
|
200
222
|
? EMPTY_CANONICAL_DOCUMENT
|
|
@@ -303,7 +325,7 @@ export async function reconcileWorkspaceJsonHistory(options) {
|
|
|
303
325
|
const entries = await readHistoryEntries(historyPath, WORKSPACE_HISTORY_ID);
|
|
304
326
|
const verification = verifyHistoryChain(entries);
|
|
305
327
|
if (!verification.ok) {
|
|
306
|
-
|
|
328
|
+
throwWorkspaceHistoryVerificationFailure(verification.errors);
|
|
307
329
|
}
|
|
308
330
|
const beforeDocument = replayWorkspaceEntries(entries);
|
|
309
331
|
const priorDocuments = workspaceDocuments(beforeDocument);
|
|
@@ -349,15 +371,15 @@ export async function restoreWorkspaceJsonFromHistory(options) {
|
|
|
349
371
|
try {
|
|
350
372
|
const { documentPath, absolutePath } = resolveGovernedDocumentPath(options.pmRoot, options.filePath);
|
|
351
373
|
const entries = await readHistoryEntries(getWorkspaceHistoryPath(options.pmRoot), WORKSPACE_HISTORY_ID);
|
|
374
|
+
const verification = verifyHistoryChain(entries);
|
|
375
|
+
if (!verification.ok) {
|
|
376
|
+
throwWorkspaceHistoryVerificationFailure(verification.errors);
|
|
377
|
+
}
|
|
352
378
|
if (!Number.isInteger(options.targetVersion) ||
|
|
353
379
|
options.targetVersion < 1 ||
|
|
354
380
|
options.targetVersion > entries.length) {
|
|
355
381
|
throw new TypeError(`Invalid workspace history target version: ${String(options.targetVersion)}`);
|
|
356
382
|
}
|
|
357
|
-
const verification = verifyHistoryChain(entries);
|
|
358
|
-
if (!verification.ok) {
|
|
359
|
-
throw new TypeError(`Workspace history verification failed: ${verification.errors.join(", ")}`);
|
|
360
|
-
}
|
|
361
383
|
const target = workspaceDocuments(replayWorkspaceEntries(entries, options.targetVersion))[documentPath];
|
|
362
384
|
if (target === undefined) {
|
|
363
385
|
throw new TypeError(`Workspace history version ${options.targetVersion} does not contain ${documentPath}`);
|
|
@@ -408,4 +430,4 @@ export async function restoreWorkspaceJsonFromHistory(options) {
|
|
|
408
430
|
}
|
|
409
431
|
}
|
|
410
432
|
//# sourceMappingURL=workspace-history.js.map
|
|
411
|
-
//# debugId=
|
|
433
|
+
//# debugId=9027d972-ce29-5511-ba81-27e17d97446e
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
* Formats compact human and machine output for Output.
|
|
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]="202cbb3e-71fe-5701-a1f5-eb515bf56561")}catch(e){}}();
|
|
8
8
|
import { getActiveCommandContext, runActiveCommandOverride, runActiveRendererOverride, runActiveServiceOverrideSync, setActiveCommandResult, } from "../extensions/index.js";
|
|
9
9
|
import { EXIT_CODE } from "../shared/constants.js";
|
|
10
10
|
import { isHostOutputSuppressed } from "./output-control.js";
|
|
11
11
|
import { projectMutationResult } from "./mutation-projection.js";
|
|
12
12
|
import { attachReadOutputContracts } from "../../sdk/context-intent-contracts.js";
|
|
13
13
|
import { attachOutputTokenAccounting } from "../../sdk/output-token-accounting.js";
|
|
14
|
-
import { resolveReadOutputEncoding } from "../../sdk/read-output-contracts.js";
|
|
14
|
+
import { isReadOutputBudgetExceeded, resolveReadOutputEncoding, } from "../../sdk/read-output-contracts.js";
|
|
15
15
|
import { encode as encodeToon } from "@toon-format/toon";
|
|
16
16
|
const DECLARED_PROCESS_EXIT_CODES = new Set(Object.values(EXIT_CODE));
|
|
17
17
|
const NATIVE_OUTPUT_MARKER = "__pm_native_output";
|
|
@@ -389,6 +389,9 @@ function formatEffectiveOutput(effectiveResult, nativeOutput, options) {
|
|
|
389
389
|
? projectLinkedTestEvidence(outputResult, options.lean === true)
|
|
390
390
|
: outputResult;
|
|
391
391
|
const intentOutputResult = attachReadOutputContracts(command, resolvedCommandOptions, projectedOutputResult);
|
|
392
|
+
if (isReadOutputBudgetExceeded(intentOutputResult)) {
|
|
393
|
+
process.exitCode ||= EXIT_CODE.USAGE;
|
|
394
|
+
}
|
|
392
395
|
const renderResolvedOutput = (value) => {
|
|
393
396
|
if (format === "toon") {
|
|
394
397
|
const markdownDefault = renderDefaultMarkdownResult(value);
|
|
@@ -465,4 +468,4 @@ export const outputTestOnly = {
|
|
|
465
468
|
renderToonValue,
|
|
466
469
|
};
|
|
467
470
|
//# sourceMappingURL=output.js.map
|
|
468
|
-
//# debugId=
|
|
471
|
+
//# debugId=202cbb3e-71fe-5701-a1f5-eb515bf56561
|
|
@@ -87,6 +87,8 @@ export interface PmCliErrorContext {
|
|
|
87
87
|
nextSteps?: string[];
|
|
88
88
|
/** Exact selectors that could not be matched by a lossless removal. */
|
|
89
89
|
unmatched?: string[];
|
|
90
|
+
/** Exact verifier findings that caused an integrity-sensitive operation to refuse. */
|
|
91
|
+
verification_errors?: string[];
|
|
90
92
|
/** Local dependency targets that could not be resolved before mutation. */
|
|
91
93
|
unresolved_targets?: string[];
|
|
92
94
|
/** Available history bounds for a failed point-in-time read or restore target. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Implements the exported pm cli error runtime abstraction for core/shared/errors.ts. */
|
|
2
2
|
|
|
3
|
-
!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]="
|
|
3
|
+
!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]="bf08255e-7ef4-5929-8431-2df83d98d0ba")}catch(e){}}();
|
|
4
4
|
export class PmCliError extends Error {
|
|
5
5
|
/** Value that configures or reports exit code for this contract. */
|
|
6
6
|
exitCode;
|
|
@@ -18,4 +18,4 @@ export class PmCliError extends Error {
|
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
//# sourceMappingURL=errors.js.map
|
|
21
|
-
//# debugId=
|
|
21
|
+
//# debugId=bf08255e-7ef4-5929-8431-2df83d98d0ba
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Reads and writes tracker storage with format-aware helpers for Item Store.
|
|
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]="d24d61bf-7db8-5f35-8dbc-5ef93ec8220b")}catch(e){}}();
|
|
8
8
|
import fs from "node:fs/promises";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { getActiveExtensionRegistrations, projectAfterCommandItemSnapshot, recordAfterCommandAffectedItem, runActiveOnReadHooks, runActiveBeforeMutationHooks, runActiveOnWriteHooks, runActiveServiceOverride, } from "../extensions/index.js";
|
|
@@ -69,6 +69,15 @@ function trackerRootNotDirectoryError(pmRoot) {
|
|
|
69
69
|
],
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
|
+
function trackerRootUnreadableError(pmRoot) {
|
|
73
|
+
return new PmCliError(`Tracker root is not readable at ${pmRoot}.`, EXIT_CODE.GENERIC_FAILURE, {
|
|
74
|
+
code: "tracker_root_unreadable",
|
|
75
|
+
reason: "unreadable",
|
|
76
|
+
nextSteps: [
|
|
77
|
+
"Grant read and directory-search permission to the tracker root, then retry the SDK read.",
|
|
78
|
+
],
|
|
79
|
+
});
|
|
80
|
+
}
|
|
72
81
|
async function assertMissingMetadataRootAncestors(pmRoot) {
|
|
73
82
|
const filesystemRoot = path.parse(path.resolve(pmRoot)).root;
|
|
74
83
|
let ancestor = path.dirname(path.resolve(pmRoot));
|
|
@@ -114,11 +123,28 @@ async function assertItemMetadataRoot(pmRoot) {
|
|
|
114
123
|
if (isErrno(error, "ENOTDIR")) {
|
|
115
124
|
throw trackerRootNotDirectoryError(pmRoot);
|
|
116
125
|
}
|
|
126
|
+
if (isErrno(error, "EACCES") || isErrno(error, "EPERM")) {
|
|
127
|
+
throw trackerRootUnreadableError(pmRoot);
|
|
128
|
+
}
|
|
117
129
|
throw error;
|
|
118
130
|
}
|
|
119
131
|
if (!stats.isDirectory()) {
|
|
120
132
|
throw trackerRootNotDirectoryError(pmRoot);
|
|
121
133
|
}
|
|
134
|
+
if (process.platform !== "win32" &&
|
|
135
|
+
((stats.mode & 0o444) === 0 || (stats.mode & 0o111) === 0)) {
|
|
136
|
+
throw trackerRootUnreadableError(pmRoot);
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
const directory = await fs.opendir(pmRoot);
|
|
140
|
+
await directory.close();
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
if (isErrno(error, "EACCES") || isErrno(error, "EPERM")) {
|
|
144
|
+
throw trackerRootUnreadableError(pmRoot);
|
|
145
|
+
}
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
122
148
|
}
|
|
123
149
|
/** Implements locate item for the public runtime surface of this module. */
|
|
124
150
|
export async function locateItem(pmRoot, rawId, idPrefix = "pm-", preferredFormat, typeToFolder = TYPE_TO_FOLDER) {
|
|
@@ -684,4 +710,4 @@ export async function deleteItem(params) {
|
|
|
684
710
|
}
|
|
685
711
|
}
|
|
686
712
|
//# sourceMappingURL=item-store.js.map
|
|
687
|
-
//# debugId=
|
|
713
|
+
//# debugId=d24d61bf-7db8-5f35-8dbc-5ef93ec8220b
|
|
@@ -37,9 +37,11 @@ export interface PmRefusalReachabilityReport {
|
|
|
37
37
|
findings: PmRefusalReachabilityFinding[];
|
|
38
38
|
}
|
|
39
39
|
/** Recovery-reference kinds emitted by structured refusal envelopes. */
|
|
40
|
-
export declare const PM_RECOVERY_REFERENCE_KINDS: readonly ["suggested_retry", "candidate_command", "example", "next_step"];
|
|
40
|
+
export declare const PM_RECOVERY_REFERENCE_KINDS: readonly ["suggested_retry", "candidate_command", "example", "next_step", "migration_hint", "restore_with"];
|
|
41
41
|
/** Recovery-reference kind emitted by a refusal. */
|
|
42
42
|
export type PmRecoveryReferenceKind = (typeof PM_RECOVERY_REFERENCE_KINDS)[number];
|
|
43
|
+
/** Behavioral promise attached to a recovery reference. */
|
|
44
|
+
export type PmRecoveryReferenceSemantics = "recovery" | "replacement" | "behavior_preserving";
|
|
43
45
|
/** One derived promise that another invocation or command path is reachable. */
|
|
44
46
|
export interface PmRecoveryReferenceObligation {
|
|
45
47
|
/** Stable reference identifier derived from its emitting envelope. */
|
|
@@ -48,6 +50,8 @@ export interface PmRecoveryReferenceObligation {
|
|
|
48
50
|
probe_id: string;
|
|
49
51
|
/** Typed recovery vocabulary rather than prose inference. */
|
|
50
52
|
kind: PmRecoveryReferenceKind;
|
|
53
|
+
/** Whether the reference recovers, replaces, or preserves the original behavior. */
|
|
54
|
+
semantics: PmRecoveryReferenceSemantics;
|
|
51
55
|
/** Exact emitted command or recovery text. */
|
|
52
56
|
value: string;
|
|
53
57
|
}
|
|
@@ -59,6 +63,8 @@ export interface PmRecoveryReferenceObservation {
|
|
|
59
63
|
reachable: boolean;
|
|
60
64
|
/** How the promise was discharged. */
|
|
61
65
|
proof: "executed" | "declared_command_path" | "linked_execution";
|
|
66
|
+
/** Semantics actually demonstrated by the proof. */
|
|
67
|
+
semantics: PmRecoveryReferenceSemantics;
|
|
62
68
|
}
|
|
63
69
|
/** Coverage totals for one emitted recovery-reference kind. */
|
|
64
70
|
export interface PmRecoveryReferenceKindCoverage {
|
|
@@ -74,7 +80,7 @@ export interface PmRecoveryReferenceKindCoverage {
|
|
|
74
80
|
/** One recovery-reference coverage failure. */
|
|
75
81
|
export interface PmRecoveryReferenceFinding {
|
|
76
82
|
/** Stable finding kind for assurance and CI. */
|
|
77
|
-
kind: "duplicate_obligation" | "duplicate_observation" | "missing_observation" | "unreachable_reference" | "undeclared_observation";
|
|
83
|
+
kind: "duplicate_obligation" | "duplicate_observation" | "missing_observation" | "unreachable_reference" | "wrong_semantics" | "undeclared_observation";
|
|
78
84
|
/** Obligation or observation identifier. */
|
|
79
85
|
reference_id: string;
|
|
80
86
|
/** Human-readable mismatch summary. */
|
|
@@ -95,6 +101,8 @@ export interface PmRecoveryReferenceReport {
|
|
|
95
101
|
/** Stable, sorted conformance findings. */
|
|
96
102
|
findings: PmRecoveryReferenceFinding[];
|
|
97
103
|
}
|
|
104
|
+
/** Derive typed obligations from every recognized recovery field in an emitted envelope. */
|
|
105
|
+
export declare function derivePmRecoveryReferenceObligations(probeId: string, envelope: unknown): PmRecoveryReferenceObligation[];
|
|
98
106
|
/** Compare declared refusal states with real-entrypoint observations. */
|
|
99
107
|
export declare function verifyPmRefusalReachability(catalog: readonly PmErrorCodeContract[], observations: readonly PmRefusalProbeObservation[]): PmRefusalReachabilityReport;
|
|
100
108
|
/** Verify executable and declared-path proof for emitted recovery references. */
|
|
@@ -1,12 +1,68 @@
|
|
|
1
1
|
/** Recovery-reference kinds emitted by structured refusal envelopes. */
|
|
2
2
|
|
|
3
|
-
!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]="
|
|
3
|
+
!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]="e96813c2-e30f-5000-9935-281c564c19aa")}catch(e){}}();
|
|
4
4
|
export const PM_RECOVERY_REFERENCE_KINDS = [
|
|
5
5
|
"suggested_retry",
|
|
6
6
|
"candidate_command",
|
|
7
7
|
"example",
|
|
8
8
|
"next_step",
|
|
9
|
+
"migration_hint",
|
|
10
|
+
"restore_with",
|
|
9
11
|
];
|
|
12
|
+
const RECOVERY_REFERENCE_FIELD_CONTRACTS = {
|
|
13
|
+
suggested_retry: { kind: "suggested_retry", semantics: "recovery" },
|
|
14
|
+
candidate_command: { kind: "candidate_command", semantics: "recovery" },
|
|
15
|
+
candidate_commands: { kind: "candidate_command", semantics: "recovery" },
|
|
16
|
+
example: { kind: "example", semantics: "recovery" },
|
|
17
|
+
examples: { kind: "example", semantics: "recovery" },
|
|
18
|
+
next_step: { kind: "next_step", semantics: "recovery" },
|
|
19
|
+
next_steps: { kind: "next_step", semantics: "recovery" },
|
|
20
|
+
migration_hint: { kind: "migration_hint", semantics: "replacement" },
|
|
21
|
+
migration_hints: { kind: "migration_hint", semantics: "replacement" },
|
|
22
|
+
restore_with: {
|
|
23
|
+
kind: "restore_with",
|
|
24
|
+
semantics: "behavior_preserving",
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
/** Derive typed obligations from every recognized recovery field in an emitted envelope. */
|
|
28
|
+
export function derivePmRecoveryReferenceObligations(probeId, envelope) {
|
|
29
|
+
const obligations = [];
|
|
30
|
+
const visit = (value, path) => {
|
|
31
|
+
if (Array.isArray(value)) {
|
|
32
|
+
value.forEach((entry, index) => visit(entry, [...path, String(index)]));
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (typeof value !== "object" || value === null)
|
|
36
|
+
return;
|
|
37
|
+
for (const [key, entry] of Object.entries(value).sort(([left], [right]) => left.localeCompare(right))) {
|
|
38
|
+
const baseContract = RECOVERY_REFERENCE_FIELD_CONTRACTS[key];
|
|
39
|
+
const contract = baseContract?.kind === "migration_hint" &&
|
|
40
|
+
value.semantics === "behavior_preserving"
|
|
41
|
+
? { ...baseContract, semantics: "behavior_preserving" }
|
|
42
|
+
: baseContract;
|
|
43
|
+
const entries = Array.isArray(entry) ? entry : [entry];
|
|
44
|
+
if (contract !== undefined) {
|
|
45
|
+
entries.forEach((candidate, index) => {
|
|
46
|
+
if (typeof candidate !== "string" || candidate.trim().length === 0)
|
|
47
|
+
return;
|
|
48
|
+
const coordinate = [...path, key, String(index)]
|
|
49
|
+
.map((segment) => encodeURIComponent(segment))
|
|
50
|
+
.join("/");
|
|
51
|
+
obligations.push({
|
|
52
|
+
id: `${probeId}:${contract.kind}:${coordinate}`,
|
|
53
|
+
probe_id: probeId,
|
|
54
|
+
kind: contract.kind,
|
|
55
|
+
semantics: contract.semantics,
|
|
56
|
+
value: candidate,
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
visit(entry, [...path, key]);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
visit(envelope, []);
|
|
64
|
+
return obligations;
|
|
65
|
+
}
|
|
10
66
|
/** Compare declared refusal states with real-entrypoint observations. */
|
|
11
67
|
export function verifyPmRefusalReachability(catalog, observations) {
|
|
12
68
|
const declarations = catalog.flatMap((contract) => (contract.owned_states ?? []).map((state) => ({ contract, state })));
|
|
@@ -129,6 +185,13 @@ export function verifyPmRecoveryReferences(obligations, observations) {
|
|
|
129
185
|
detail: `Recovery reference ${obligation.value} did not reach its promised target.`,
|
|
130
186
|
});
|
|
131
187
|
}
|
|
188
|
+
else if (observation.semantics !== obligation.semantics) {
|
|
189
|
+
findings.push({
|
|
190
|
+
kind: "wrong_semantics",
|
|
191
|
+
reference_id: obligation.id,
|
|
192
|
+
detail: `Recovery reference ${obligation.value} promised ${obligation.semantics}; proof demonstrated ${observation.semantics}.`,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
132
195
|
}
|
|
133
196
|
const coverageByKind = PM_RECOVERY_REFERENCE_KINDS.map((kind) => {
|
|
134
197
|
const kindObligations = obligations.filter((obligation) => obligation.kind === kind);
|
|
@@ -140,7 +203,12 @@ export function verifyPmRecoveryReferences(obligations, observations) {
|
|
|
140
203
|
kind,
|
|
141
204
|
declared: kindObligations.length,
|
|
142
205
|
observed: kindObservations.length,
|
|
143
|
-
passed:
|
|
206
|
+
passed: kindObligations.filter((obligation) => {
|
|
207
|
+
const observation = observationsById.get(obligation.id);
|
|
208
|
+
return (!duplicateIds.has(obligation.id) &&
|
|
209
|
+
observation?.reachable === true &&
|
|
210
|
+
observation.semantics === obligation.semantics);
|
|
211
|
+
}).length,
|
|
144
212
|
};
|
|
145
213
|
});
|
|
146
214
|
findings.sort((left, right) => left.reference_id !== right.reference_id
|
|
@@ -157,4 +225,4 @@ export function verifyPmRecoveryReferences(obligations, observations) {
|
|
|
157
225
|
};
|
|
158
226
|
}
|
|
159
227
|
//# sourceMappingURL=refusal-reachability.js.map
|
|
160
|
-
//# debugId=
|
|
228
|
+
//# debugId=e96813c2-e30f-5000-9935-281c564c19aa
|
|
@@ -46,12 +46,63 @@ export interface AcknowledgeUnknownAuthorEventsOptions {
|
|
|
46
46
|
/** Select every currently actionable, undispositioned event in the tracker. */
|
|
47
47
|
all_actionable?: boolean;
|
|
48
48
|
/** Principal attributed by maintainer review. */
|
|
49
|
-
attributed_author
|
|
49
|
+
attributed_author?: string;
|
|
50
50
|
/** Reviewer appending the disposition event. */
|
|
51
|
-
reviewer
|
|
51
|
+
reviewer?: string;
|
|
52
52
|
/** Evidence-backed rationale for the attribution. */
|
|
53
|
-
reason
|
|
53
|
+
reason?: string;
|
|
54
|
+
/** Resolve and return the selected plan without appending history. */
|
|
55
|
+
dry_run?: boolean;
|
|
56
|
+
/** Fingerprint from the exact preview plan being applied. */
|
|
57
|
+
plan_fingerprint?: string;
|
|
58
|
+
/** Maximum coordinate rows included in the returned plan. */
|
|
59
|
+
coordinate_limit?: number;
|
|
54
60
|
}
|
|
61
|
+
/** One source-bound coordinate in an author-acknowledgement plan. */
|
|
62
|
+
export interface UnknownAuthorAcknowledgmentPlanCoordinate extends UnknownAuthorHistoryEvent {
|
|
63
|
+
/** SHA-256 of the exact immutable JSONL source line. */
|
|
64
|
+
source_event_hash: string;
|
|
65
|
+
/** Whether the row is undispositioned or an explicit apply would supersede it. */
|
|
66
|
+
disposition: "actionable" | "already_acknowledged";
|
|
67
|
+
}
|
|
68
|
+
/** Deterministic preview shared by CLI, SDK, and MCP apply paths. */
|
|
69
|
+
export interface UnknownAuthorAcknowledgmentPlan {
|
|
70
|
+
/** Selector family resolved by the plan. */
|
|
71
|
+
selection: {
|
|
72
|
+
kind: "events" | "all_actionable";
|
|
73
|
+
};
|
|
74
|
+
/** Complete number of unique selected coordinates. */
|
|
75
|
+
selected_count: number;
|
|
76
|
+
/** Selected coordinates not covered by an earlier disposition. */
|
|
77
|
+
actionable_count: number;
|
|
78
|
+
/** Coordinates an explicit-events apply would supersede. */
|
|
79
|
+
already_acknowledged_count: number;
|
|
80
|
+
/** Coordinate rows omitted only from this bounded preview. */
|
|
81
|
+
omitted_count: number;
|
|
82
|
+
/** Stable ordered prefix of the complete selected set. */
|
|
83
|
+
coordinates: UnknownAuthorAcknowledgmentPlanCoordinate[];
|
|
84
|
+
/** SHA-256 over selection kind and every complete source-bound coordinate. */
|
|
85
|
+
plan_fingerprint: string;
|
|
86
|
+
}
|
|
87
|
+
/** Structured preview or apply result for immutable author acknowledgement. */
|
|
88
|
+
export interface UnknownAuthorAcknowledgmentResult {
|
|
89
|
+
/** Whether this invocation was a read-only preview. */
|
|
90
|
+
dry_run: boolean;
|
|
91
|
+
/** Whether an append-only workspace event was written. */
|
|
92
|
+
mutated: boolean;
|
|
93
|
+
/** Number of coordinates written to the appended disposition. */
|
|
94
|
+
acknowledged: number;
|
|
95
|
+
/** Effect-aware command outcome. */
|
|
96
|
+
outcome: "preview" | "effect" | "no_effect" | "partial_effect";
|
|
97
|
+
/** Stable shell and transport exit paired with the outcome. */
|
|
98
|
+
exit_code: 0 | 6 | 7;
|
|
99
|
+
/** Exact plan used for preview or apply. */
|
|
100
|
+
plan: UnknownAuthorAcknowledgmentPlan;
|
|
101
|
+
/** Appended workspace history path when mutation occurred. */
|
|
102
|
+
history_path?: string;
|
|
103
|
+
}
|
|
104
|
+
/** Resolve a deterministic, source-bound author-acknowledgement preview. */
|
|
105
|
+
export declare function planUnknownAuthorHistoryAcknowledgment(pmRoot: string, selector: Pick<AcknowledgeUnknownAuthorEventsOptions, "events" | "all_actionable">, coordinateLimit?: number): Promise<UnknownAuthorAcknowledgmentPlan>;
|
|
55
106
|
/** Resolve the mutually exclusive CLI and SDK acknowledgment selectors. */
|
|
56
107
|
export declare function resolveUnknownAuthorAcknowledgmentSelector(rawEvents: readonly string[], allActionable: boolean): {
|
|
57
108
|
events: UnknownAuthorHistoryEvent[];
|
|
@@ -60,15 +111,9 @@ export declare function resolveUnknownAuthorAcknowledgmentSelector(rawEvents: re
|
|
|
60
111
|
/** Parse user-facing item or workspace history coordinates into SDK events. */
|
|
61
112
|
export declare function parseUnknownAuthorHistoryEventCoordinates(values: readonly string[]): UnknownAuthorHistoryEvent[];
|
|
62
113
|
/** Normalize an untyped transport payload and execute author acknowledgment. */
|
|
63
|
-
export declare function acknowledgeUnknownAuthorHistoryEventsFromTransport(pmRoot: string, input: Record<string, unknown>): Promise<
|
|
64
|
-
acknowledged: number;
|
|
65
|
-
history_path: string;
|
|
66
|
-
}>;
|
|
114
|
+
export declare function acknowledgeUnknownAuthorHistoryEventsFromTransport(pmRoot: string, input: Record<string, unknown>): Promise<UnknownAuthorAcknowledgmentResult>;
|
|
67
115
|
/**
|
|
68
116
|
* Append an audited disposition for immutable unknown-author events without
|
|
69
117
|
* rewriting their original streams.
|
|
70
118
|
*/
|
|
71
|
-
export declare function acknowledgeUnknownAuthorHistoryEvents(pmRoot: string, options: AcknowledgeUnknownAuthorEventsOptions): Promise<
|
|
72
|
-
acknowledged: number;
|
|
73
|
-
history_path: string;
|
|
74
|
-
}>;
|
|
119
|
+
export declare function acknowledgeUnknownAuthorHistoryEvents(pmRoot: string, options: AcknowledgeUnknownAuthorEventsOptions): Promise<UnknownAuthorAcknowledgmentResult>;
|