@unbrained/pm-cli 2026.8.22 → 2026.8.24
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 +42 -1
- package/dist/cli/description-stdin.js +5 -4
- package/dist/cli/error-guidance.d.ts +13 -0
- package/dist/cli/error-guidance.js +62 -6
- package/dist/cli/extension-command-help.d.ts +5 -0
- package/dist/cli/extension-command-help.js +6 -2
- package/dist/cli/help-content.d.ts +5 -0
- package/dist/cli/help-content.js +56 -3
- package/dist/cli/help-json-payload.d.ts +5 -2
- package/dist/cli/help-json-payload.js +57 -17
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.js +39 -5
- package/dist/cli/register-annotations.js +5 -5
- package/dist/cli/register-mutation.js +77 -31
- package/dist/cli/register-operations.d.ts +73 -0
- package/dist/cli/register-operations.js +39 -14
- package/dist/cli/register-setup.js +3 -3
- package/dist/cli/schema-registration-helpers.d.ts +8 -1
- package/dist/cli/schema-registration-helpers.js +14 -5
- package/dist/cli-bundle/bundle-manifest.json +155 -155
- package/dist/cli-bundle/chunks/chunk-AGUL3HUT.js +3 -0
- package/dist/cli-bundle/chunks/{chunk-WG4STC36.js → chunk-DJNJBWAQ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-MYYI3ZOA.js → chunk-I5Q7QSZX.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-IW72J5FW.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-BWX4SK46.js → chunk-L22NP5MA.js} +66 -66
- package/dist/cli-bundle/chunks/chunk-MKE6MD2K.js +36 -0
- package/dist/cli-bundle/chunks/{chunk-MZTZQTMS.js → chunk-NXBFO63A.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-TEQDR5KI.js +202 -0
- package/dist/cli-bundle/chunks/chunk-X7WWQDYQ.js +2 -0
- package/dist/cli-bundle/chunks/chunk-YOLLRCLY.js +13 -0
- package/dist/cli-bundle/chunks/{chunk-U6GQ4VMV.js → chunk-ZAVCS2GH.js} +4 -4
- package/dist/cli-bundle/chunks/{register-list-query-HZKBQNWW.js → register-list-query-37A4P6O4.js} +2 -2
- package/dist/cli-bundle/chunks/register-mutation-TBJDHYIT.js +20 -0
- package/dist/cli-bundle/chunks/register-operations-WRZNEBUM.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-QK4OTOXN.js → register-setup-H4PDLACD.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-GMYPD4FX.js → chunk-4WP7LNE3.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-6MUTDXMP.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-6Z24ZMU3.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-2ARQGDDW.js → chunk-BFA6KKCI.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-CWCN5RLO.js +26 -0
- package/dist/cli-bundle/focused-chunks/chunk-FCTT4CZU.js +5 -0
- package/dist/cli-bundle/focused-chunks/chunk-GJR6YEMR.js +156 -0
- package/dist/cli-bundle/focused-chunks/{chunk-2POVTNLY.js → chunk-IMWTYKII.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-D6RBZEJJ.js → chunk-IZNRRCU3.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-PMGJUFNQ.js → chunk-MNPECIRL.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-A2BC5PQL.js → chunk-O4ZXNJMT.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-Q63PSLO4.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-QBP5FSBX.js +4 -0
- package/dist/cli-bundle/focused-chunks/{chunk-R6SR45XU.js → chunk-QV5UP27O.js} +48 -47
- package/dist/cli-bundle/focused-chunks/chunk-RASVBJX5.js +8 -0
- package/dist/cli-bundle/focused-chunks/{chunk-E2EWYPY6.js → chunk-RPRLENVA.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-TOFVXBWA.js +19 -0
- package/dist/cli-bundle/focused-chunks/{chunk-6S2MO3Q3.js → chunk-WZLSSGEU.js} +2 -2
- package/dist/cli-bundle/main.js +18 -17
- 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 +33 -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 +6 -5
- package/dist/core/config/nested-settings.js +8 -2
- package/dist/core/config/positional-value.d.ts +1 -1
- package/dist/core/config/positional-value.js +5 -2
- package/dist/core/extensions/command-metadata-contract.d.ts +10 -0
- package/dist/core/extensions/command-metadata-contract.js +23 -0
- package/dist/core/extensions/command-visibility-tier.js +12 -2
- package/dist/core/extensions/extension-types.d.ts +6 -0
- package/dist/core/extensions/extension-types.js +2 -2
- package/dist/core/extensions/loader.js +4 -3
- package/dist/core/history/history.js +3 -3
- package/dist/core/io/body-file.js +7 -2
- package/dist/core/io/bulk-ids-input.d.ts +24 -0
- package/dist/core/io/bulk-ids-input.js +113 -0
- package/dist/core/item/item-format.js +66 -12
- package/dist/core/item/parse.d.ts +22 -2
- package/dist/core/item/parse.js +97 -4
- package/dist/core/reproducibility/context.d.ts +4 -0
- package/dist/core/reproducibility/context.js +14 -8
- package/dist/core/shared/author.d.ts +55 -1
- package/dist/core/shared/author.js +333 -16
- package/dist/core/shared/constants.js +3 -2
- package/dist/core/store/settings-validator.d.ts +1 -0
- package/dist/core/store/settings-validator.js +6 -3
- package/dist/core/store/settings.js +5 -2
- package/dist/mcp/server.d.ts +4 -3
- package/dist/mcp/server.js +44 -16
- package/dist/sdk/agent/identity-config.d.ts +63 -0
- package/dist/sdk/agent/identity-config.js +107 -0
- package/dist/sdk/agent/refusal-closure-census.d.ts +66 -0
- package/dist/sdk/agent/refusal-closure-census.js +144 -0
- package/dist/sdk/agent/refusal-corpus-contracts.d.ts +76 -0
- package/dist/sdk/agent/refusal-corpus-contracts.js +194 -0
- package/dist/sdk/agent-capability-contracts.d.ts +34 -1
- package/dist/sdk/agent-capability-contracts.js +104 -6
- package/dist/sdk/annotations.d.ts +2 -0
- package/dist/sdk/annotations.js +25 -7
- package/dist/sdk/cli-contracts/agent-output-contracts.js +6 -4
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +4 -0
- package/dist/sdk/cli-contracts/enum-contracts.js +9 -2
- package/dist/sdk/cli-contracts/flag-contracts.js +9 -2
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +4 -4
- package/dist/sdk/cli-contracts/registration-helpers.js +5 -2
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +58 -2
- package/dist/sdk/cli-contracts/tool-schema.d.ts +1 -1
- package/dist/sdk/cli-contracts/tool-schema.js +14 -3
- package/dist/sdk/cli-contracts/typed-action-inputs.d.ts +4 -1
- package/dist/sdk/cli-contracts/typed-action-inputs.js +2 -2
- package/dist/sdk/cli-contracts.d.ts +3 -3
- package/dist/sdk/cli-contracts.js +4 -4
- package/dist/sdk/comments.js +15 -7
- package/dist/sdk/config.d.ts +6 -1
- package/dist/sdk/config.js +119 -14
- package/dist/sdk/context-intent-contracts.js +4 -2
- package/dist/sdk/core-governance.d.ts +1 -1
- package/dist/sdk/core-governance.js +3 -3
- package/dist/sdk/extension/scaffold.js +11 -5
- package/dist/sdk/flag-invocation-contracts.d.ts +2 -0
- package/dist/sdk/flag-invocation-contracts.js +30 -3
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +83 -2
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +87 -2
- package/dist/sdk/governance/assurance-action.js +30 -10
- package/dist/sdk/governance/validate.d.ts +2 -2
- package/dist/sdk/governance/validate.js +39 -14
- package/dist/sdk/guide-topics.d.ts +0 -5
- package/dist/sdk/guide-topics.js +28 -2
- package/dist/sdk/history-compact.d.ts +2 -1
- package/dist/sdk/history-compact.js +24 -5
- package/dist/sdk/history-mcp.js +11 -10
- package/dist/sdk/index.d.ts +8 -2
- package/dist/sdk/index.js +9 -3
- package/dist/sdk/item-transaction.js +19 -12
- package/dist/sdk/lifecycle/append.js +4 -4
- package/dist/sdk/lifecycle/close-many.js +16 -7
- package/dist/sdk/lifecycle/create.js +33 -22
- package/dist/sdk/lifecycle/plan.js +24 -6
- package/dist/sdk/lifecycle/update-many.js +15 -8
- package/dist/sdk/lifecycle/update.d.ts +2 -0
- package/dist/sdk/lifecycle/update.js +37 -25
- package/dist/sdk/merge/three-way.js +105 -26
- package/dist/sdk/read-output-budget.d.ts +21 -0
- package/dist/sdk/read-output-budget.js +39 -2
- package/dist/sdk/read-output-contracts.d.ts +5 -3
- package/dist/sdk/read-output-contracts.js +20 -12
- package/dist/sdk/reproducibility/process.d.ts +19 -0
- package/dist/sdk/reproducibility/process.js +88 -0
- package/dist/sdk/runtime-extended-actions.js +5 -3
- package/dist/sdk/runtime-input.d.ts +4 -0
- package/dist/sdk/runtime-input.js +98 -23
- package/dist/sdk/runtime-primitives.d.ts +3 -2
- package/dist/sdk/runtime-primitives.js +5 -4
- package/dist/sdk/runtime.js +11 -23
- package/dist/sdk/scheduling-shortcuts.js +5 -3
- package/dist/sdk/structured-mutations.js +10 -3
- package/dist/sdk/test/batch.d.ts +6 -0
- package/dist/sdk/test/batch.js +15 -3
- package/dist/sdk/test/entry.d.ts +1 -1
- package/dist/sdk/test/entry.js +3 -2
- package/dist/sdk/test/execution.d.ts +28 -3
- package/dist/sdk/test/execution.js +193 -34
- package/dist/sdk/test/parsers.d.ts +6 -0
- package/dist/sdk/test/parsers.js +21 -2
- package/dist/sdk/test/trust.d.ts +33 -0
- package/dist/sdk/test/trust.js +207 -0
- package/dist/sdk/workspace-contracts.d.ts +3 -0
- package/dist/sdk/workspace-contracts.js +3 -2
- package/dist/types.d.ts +23 -0
- package/dist/types.js +2 -2
- package/docs/AGENT_PROVENANCE_ADR.md +41 -5
- package/docs/CONFIGURATION.md +4 -0
- package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +19 -2
- package/docs/MERGE_SAFETY.md +15 -1
- package/docs/README.md +2 -0
- package/docs/READ_OUTPUT_CONTRACTS.md +11 -1
- package/docs/RELEASING.md +40 -21
- package/docs/REPRODUCIBLE_WORKSPACES.md +42 -8
- package/docs/SCRIPTING.md +62 -3
- package/docs/SDK.md +17 -0
- package/docs/SDK_AGENT_SESSION_CONTEXT.md +6 -4
- package/docs/SDK_EVIDENCE_TRACEABILITY.md +1 -1
- package/docs/TESTING.md +75 -8
- package/docs/agent-task-token-baseline.json +2 -2
- package/docs/generated/AGENT_CAPABILITY_ROUTING.md +17 -0
- package/docs/generated/AGENT_COMMAND_SURFACE.md +1 -1
- package/docs/generated/FLAG_LEXICON_BUDGETS.md +2 -2
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +355 -0
- 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/README.md +9 -11
- package/packages/pm-command-kit/extensions/command-kit/index.ts +3 -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/extensions/guide-shell/index.ts +10 -0
- 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/generate-agent-capability-surfaces.mjs +27 -1
- package/sdk/public-surface.json +642 -28
- package/dist/cli-bundle/chunks/chunk-EMWDM5FI.js +0 -13
- package/dist/cli-bundle/chunks/chunk-HYG6LRL4.js +0 -200
- package/dist/cli-bundle/chunks/chunk-QI2CT3IX.js +0 -2
- package/dist/cli-bundle/chunks/chunk-SMWXHMVB.js +0 -35
- package/dist/cli-bundle/chunks/chunk-VMMIL3SI.js +0 -2
- package/dist/cli-bundle/chunks/chunk-YBPJAOQQ.js +0 -3
- package/dist/cli-bundle/chunks/register-mutation-HTKEEGRD.js +0 -20
- package/dist/cli-bundle/chunks/register-operations-6EMRWJJY.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-2AZT5WXZ.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-3LKU6PTJ.js +0 -4
- package/dist/cli-bundle/focused-chunks/chunk-5SHSBMX2.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-C4S4A4JJ.js +0 -5
- package/dist/cli-bundle/focused-chunks/chunk-L5LDSRO2.js +0 -155
- package/dist/cli-bundle/focused-chunks/chunk-MB37AYN6.js +0 -26
- package/dist/cli-bundle/focused-chunks/chunk-MCOR37QK.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-PH2OXXVZ.js +0 -18
- package/dist/cli-bundle/focused-chunks/chunk-WZE4LIPW.js +0 -8
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sdk/test/trust
|
|
3
|
+
*
|
|
4
|
+
* Provides provenance and clone-local trust decisions for stored linked-test
|
|
5
|
+
* commands. Tracker items remain portable while execution acknowledgements stay
|
|
6
|
+
* outside the merge-unioned project record.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
!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]="30a61f26-5db8-50ba-af37-1990a4742ce8")}catch(e){}}();
|
|
10
|
+
import { execFile } from "node:child_process";
|
|
11
|
+
import { readFile } from "node:fs/promises";
|
|
12
|
+
import path from "node:path";
|
|
13
|
+
import { promisify } from "node:util";
|
|
14
|
+
import { ensureDir, writeFileAtomic, } from "../../core/fs/fs-utils.js";
|
|
15
|
+
import { sha256Hex, stableStringify } from "../../core/shared/serialization.js";
|
|
16
|
+
import { isTimestampLiteral } from "../../core/shared/time.js";
|
|
17
|
+
import { getRuntimePath } from "../../core/store/paths.js";
|
|
18
|
+
const execFileAsync = promisify(execFile);
|
|
19
|
+
const LINKED_TEST_TRUST_LEDGER_VERSION = 1;
|
|
20
|
+
const LINKED_TEST_TRUST_LEDGER_FILE = "linked-test-trust.json";
|
|
21
|
+
function trustLedgerPath(pmRoot) {
|
|
22
|
+
return path.join(getRuntimePath(pmRoot), LINKED_TEST_TRUST_LEDGER_FILE);
|
|
23
|
+
}
|
|
24
|
+
function emptyTrustLedger() {
|
|
25
|
+
return { version: LINKED_TEST_TRUST_LEDGER_VERSION, acknowledged: {} };
|
|
26
|
+
}
|
|
27
|
+
async function readTrustLedger(pmRoot) {
|
|
28
|
+
try {
|
|
29
|
+
const parsed = JSON.parse(await readFile(trustLedgerPath(pmRoot), "utf8"));
|
|
30
|
+
if (parsed.version !== LINKED_TEST_TRUST_LEDGER_VERSION ||
|
|
31
|
+
typeof parsed.acknowledged !== "object" ||
|
|
32
|
+
parsed.acknowledged === null ||
|
|
33
|
+
Array.isArray(parsed.acknowledged)) {
|
|
34
|
+
return emptyTrustLedger();
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
version: LINKED_TEST_TRUST_LEDGER_VERSION,
|
|
38
|
+
acknowledged: parsed.acknowledged,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// A missing, corrupt, or unreadable ledger grants no acknowledgements.
|
|
43
|
+
// The local/source-ref provenance checks remain independent of this file.
|
|
44
|
+
return emptyTrustLedger();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Resolve the current Git branch without invoking a shell. */
|
|
48
|
+
export async function resolveLinkedTestSourceRef(cwd = process.cwd()) {
|
|
49
|
+
const hostedRef = process.env.GITHUB_HEAD_REF?.trim() || process.env.GITHUB_REF_NAME?.trim();
|
|
50
|
+
if (hostedRef && hostedRef !== "merge") {
|
|
51
|
+
return hostedRef;
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
const { stdout } = await execFileAsync("git", ["symbolic-ref", "--quiet", "--short", "HEAD"], { cwd, encoding: "utf8", windowsHide: true, timeout: 10_000 });
|
|
55
|
+
const ref = stdout.trim();
|
|
56
|
+
/* c8 ignore start -- successful git symbolic-ref output is non-empty by contract */
|
|
57
|
+
if (ref.length === 0)
|
|
58
|
+
return undefined;
|
|
59
|
+
/* c8 ignore stop */
|
|
60
|
+
return ref;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Resolve the source checkout shared by linked-test provenance and execution. */
|
|
67
|
+
export function resolveLinkedTestSourceWorkspaceRoot(cwd = process.cwd()) {
|
|
68
|
+
return process.env.PM_SOURCE_WORKSPACE_ROOT?.trim() || cwd;
|
|
69
|
+
}
|
|
70
|
+
function hasValidLinkedTestProvenance(provenance) {
|
|
71
|
+
if (provenance === null || typeof provenance !== "object")
|
|
72
|
+
return false;
|
|
73
|
+
return (typeof provenance.author === "string" &&
|
|
74
|
+
provenance.author.trim().length > 0 &&
|
|
75
|
+
typeof provenance.created_at === "string" &&
|
|
76
|
+
isTimestampLiteral(provenance.created_at) &&
|
|
77
|
+
(provenance.source_kind === "local_mutation" ||
|
|
78
|
+
provenance.source_kind === "merge_union"));
|
|
79
|
+
}
|
|
80
|
+
/** Build the optional ref portion shared by clone-local trust decisions. */
|
|
81
|
+
function linkedTestTrustRefs(sourceRef, currentSourceRef) {
|
|
82
|
+
return {
|
|
83
|
+
...(sourceRef ? { source_ref: sourceRef } : {}),
|
|
84
|
+
...(currentSourceRef ? { current_source_ref: currentSourceRef } : {}),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/** Attach immutable author/time/ref provenance to newly stored commands. */
|
|
88
|
+
export function attachLinkedTestProvenance(tests, author, createdAt, sourceRef) {
|
|
89
|
+
return tests?.map((test) => test.command && !test.provenance
|
|
90
|
+
? {
|
|
91
|
+
...test,
|
|
92
|
+
provenance: {
|
|
93
|
+
author,
|
|
94
|
+
created_at: createdAt,
|
|
95
|
+
source_kind: "local_mutation",
|
|
96
|
+
...(sourceRef ? { source_ref: sourceRef } : {}),
|
|
97
|
+
},
|
|
98
|
+
}
|
|
99
|
+
: test);
|
|
100
|
+
}
|
|
101
|
+
/** Attach provenance while avoiding Git inspection for an empty mutation. */
|
|
102
|
+
export async function attachLinkedTestMutationProvenance(tests, author, createdAt) {
|
|
103
|
+
if (!tests || tests.length === 0)
|
|
104
|
+
return tests;
|
|
105
|
+
const sourceWorkspaceRoot = resolveLinkedTestSourceWorkspaceRoot();
|
|
106
|
+
return attachLinkedTestProvenance(tests, author, createdAt, await resolveLinkedTestSourceRef(sourceWorkspaceRoot));
|
|
107
|
+
}
|
|
108
|
+
/** Produce the clone-local trust identity for one linked-test entry. */
|
|
109
|
+
export function linkedTestTrustFingerprint(test) {
|
|
110
|
+
return sha256Hex(stableStringify({
|
|
111
|
+
command: test.command ?? null,
|
|
112
|
+
path: test.path ?? null,
|
|
113
|
+
scope: test.scope,
|
|
114
|
+
pm_context_mode: test.pm_context_mode ?? null,
|
|
115
|
+
workspace_context_mode: test.workspace_context_mode ?? null,
|
|
116
|
+
env_set: test.env_set ?? null,
|
|
117
|
+
env_clear: test.env_clear ?? null,
|
|
118
|
+
shared_host_safe: test.shared_host_safe ?? null,
|
|
119
|
+
provenance: test.provenance ?? null,
|
|
120
|
+
provenance_invalid: test.provenance_invalid ?? null,
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
/** Resolve whether one stored command is trusted by this clone. */
|
|
124
|
+
export async function resolveLinkedTestTrust(pmRoot, test, currentSourceRef) {
|
|
125
|
+
const ledger = await readTrustLedger(pmRoot);
|
|
126
|
+
return resolveLinkedTestTrustFromLedger(test, currentSourceRef, ledger);
|
|
127
|
+
}
|
|
128
|
+
function resolveLinkedTestTrustFromLedger(test, currentSourceRef, ledger) {
|
|
129
|
+
const fingerprint = linkedTestTrustFingerprint(test);
|
|
130
|
+
const sourceRef = test.provenance?.source_ref;
|
|
131
|
+
if (test.provenance === undefined &&
|
|
132
|
+
test.provenance_invalid !== true) {
|
|
133
|
+
return { fingerprint, trusted: true, reason: "legacy" };
|
|
134
|
+
}
|
|
135
|
+
const acknowledged = Object.hasOwn(ledger.acknowledged, fingerprint);
|
|
136
|
+
if (test.provenance_invalid === true ||
|
|
137
|
+
!hasValidLinkedTestProvenance(test.provenance)) {
|
|
138
|
+
if (acknowledged) {
|
|
139
|
+
return {
|
|
140
|
+
fingerprint,
|
|
141
|
+
trusted: true,
|
|
142
|
+
reason: "acknowledged",
|
|
143
|
+
...linkedTestTrustRefs(undefined, currentSourceRef),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
fingerprint,
|
|
148
|
+
trusted: false,
|
|
149
|
+
reason: "invalid_provenance",
|
|
150
|
+
...linkedTestTrustRefs(undefined, currentSourceRef),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
if (test.provenance.source_kind === "local_mutation" &&
|
|
154
|
+
sourceRef === undefined) {
|
|
155
|
+
return {
|
|
156
|
+
fingerprint,
|
|
157
|
+
trusted: true,
|
|
158
|
+
reason: "local_mutation",
|
|
159
|
+
...linkedTestTrustRefs(undefined, currentSourceRef),
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
if (test.provenance.source_kind === "local_mutation" &&
|
|
163
|
+
sourceRef !== undefined &&
|
|
164
|
+
sourceRef === currentSourceRef) {
|
|
165
|
+
return {
|
|
166
|
+
fingerprint,
|
|
167
|
+
trusted: true,
|
|
168
|
+
reason: "local_source_ref",
|
|
169
|
+
source_ref: sourceRef,
|
|
170
|
+
current_source_ref: currentSourceRef,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
if (acknowledged) {
|
|
174
|
+
return {
|
|
175
|
+
fingerprint,
|
|
176
|
+
trusted: true,
|
|
177
|
+
reason: "acknowledged",
|
|
178
|
+
...linkedTestTrustRefs(sourceRef, currentSourceRef),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
fingerprint,
|
|
183
|
+
trusted: false,
|
|
184
|
+
reason: "foreign_source_ref",
|
|
185
|
+
...linkedTestTrustRefs(sourceRef, currentSourceRef),
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/** Resolve a collection with one ledger read for validation and batch runs. */
|
|
189
|
+
export async function resolveLinkedTestTrustBatch(pmRoot, tests, currentSourceRef) {
|
|
190
|
+
const ledger = await readTrustLedger(pmRoot);
|
|
191
|
+
return tests.map((test) => resolveLinkedTestTrustFromLedger(test, currentSourceRef, ledger));
|
|
192
|
+
}
|
|
193
|
+
/** Persist explicit clone-local acknowledgement for selected linked tests. */
|
|
194
|
+
export async function acknowledgeLinkedTests(pmRoot, tests, acknowledgedAt) {
|
|
195
|
+
const ledger = await readTrustLedger(pmRoot);
|
|
196
|
+
const fingerprints = tests
|
|
197
|
+
.filter((test) => typeof test.command === "string" && test.command.length > 0)
|
|
198
|
+
.map(linkedTestTrustFingerprint);
|
|
199
|
+
for (const fingerprint of fingerprints) {
|
|
200
|
+
ledger.acknowledged[fingerprint] = { acknowledged_at: acknowledgedAt };
|
|
201
|
+
}
|
|
202
|
+
await ensureDir(path.dirname(trustLedgerPath(pmRoot)));
|
|
203
|
+
await writeFileAtomic(trustLedgerPath(pmRoot), `${JSON.stringify(ledger, null, 2)}\n`);
|
|
204
|
+
return { acknowledged: fingerprints.length, fingerprints };
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=trust.js.map
|
|
207
|
+
//# debugId=30a61f26-5db8-50ba-af37-1990a4742ce8
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Declares live workspace customization metadata for SDK and MCP consumers.
|
|
5
5
|
*/
|
|
6
6
|
import type { RegisteredExtensionCommandDefinition } from "../core/extensions/extension-types.js";
|
|
7
|
+
import type { PmCommandCapabilityFamily } from "./agent-capability-contracts.js";
|
|
7
8
|
import { type RuntimeFieldDefinitionResolved } from "../core/schema/runtime-schema.js";
|
|
8
9
|
import type { RuntimeFieldType } from "../types/index.js";
|
|
9
10
|
/** Runtime custom-field metadata exposed to SDK and MCP consumers. */
|
|
@@ -46,6 +47,8 @@ export interface WorkspaceExtensionCommandContract {
|
|
|
46
47
|
description?: string;
|
|
47
48
|
/** Minimum agent surface tier requested by the extension. */
|
|
48
49
|
tier: "core" | "standard" | "full" | "internal";
|
|
50
|
+
/** Capability family declared by the extension. */
|
|
51
|
+
family: PmCommandCapabilityFamily;
|
|
49
52
|
}
|
|
50
53
|
/** Project resolved custom-field definitions into the public workspace shape. */
|
|
51
54
|
export declare function buildWorkspaceFieldContracts(definitions: RuntimeFieldDefinitionResolved[]): WorkspaceFieldContract[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!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]="
|
|
2
|
+
!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]="10052b6f-216f-5b50-81ec-ee373cc13d17")}catch(e){}}();
|
|
3
3
|
import { runtimeFieldOptionTarget, } from "../core/schema/runtime-schema.js";
|
|
4
4
|
/** Project resolved custom-field definitions into the public workspace shape. */
|
|
5
5
|
export function buildWorkspaceFieldContracts(definitions) {
|
|
@@ -27,7 +27,8 @@ export function buildWorkspaceExtensionCommandContracts(definitions) {
|
|
|
27
27
|
})),
|
|
28
28
|
description: definition.description,
|
|
29
29
|
tier: definition.tier ?? "standard",
|
|
30
|
+
family: definition.family ?? "extensions",
|
|
30
31
|
}));
|
|
31
32
|
}
|
|
32
33
|
//# sourceMappingURL=workspace-contracts.js.map
|
|
33
|
-
//# debugId=
|
|
34
|
+
//# debugId=10052b6f-216f-5b50-81ec-ee373cc13d17
|
package/dist/types.d.ts
CHANGED
|
@@ -166,6 +166,17 @@ export interface LinkedFile {
|
|
|
166
166
|
/** Value that configures or reports note for this contract. */
|
|
167
167
|
note?: string;
|
|
168
168
|
}
|
|
169
|
+
/** Valid immutable provenance captured when a linked command enters tracker data. */
|
|
170
|
+
export interface LinkedTestProvenance {
|
|
171
|
+
/** Author identity recorded by the originating mutation. */
|
|
172
|
+
author: string;
|
|
173
|
+
/** ISO 8601 time at which the command entered tracker data. */
|
|
174
|
+
created_at: string;
|
|
175
|
+
/** Mutation path that introduced the command. */
|
|
176
|
+
source_kind: "local_mutation" | "merge_union";
|
|
177
|
+
/** Best-effort Git branch or hosted head ref of the originating mutation. */
|
|
178
|
+
source_ref?: string;
|
|
179
|
+
}
|
|
169
180
|
/** Documents the linked test payload exchanged by command, SDK, and package integrations. */
|
|
170
181
|
export interface LinkedTest {
|
|
171
182
|
/** Value that configures or reports command for this contract. */
|
|
@@ -178,6 +189,12 @@ export interface LinkedTest {
|
|
|
178
189
|
timeout_seconds?: number;
|
|
179
190
|
/** Strategy used to control pm context behavior. */
|
|
180
191
|
pm_context_mode?: "schema" | "tracker" | "auto";
|
|
192
|
+
/** Strategy used for source-workspace visibility and command working directory. */
|
|
193
|
+
workspace_context_mode?: "source" | "isolated" | "snapshot";
|
|
194
|
+
/** Immutable provenance captured when the linked command enters tracker data. */
|
|
195
|
+
provenance?: LinkedTestProvenance;
|
|
196
|
+
/** Explicit fail-closed marker retained when stored provenance is malformed. */
|
|
197
|
+
provenance_invalid?: true;
|
|
181
198
|
/** Value that configures or reports env set for this contract. */
|
|
182
199
|
env_set?: Record<string, string>;
|
|
183
200
|
/** Value that configures or reports env clear for this contract. */
|
|
@@ -566,6 +583,10 @@ export interface ItemTestRunExecution {
|
|
|
566
583
|
requested_pm_context_mode?: "schema" | "tracker" | "auto";
|
|
567
584
|
/** Effective context mode used by the linked command. */
|
|
568
585
|
pm_context_mode?: "schema" | "tracker" | "auto";
|
|
586
|
+
/** Effective source-workspace mode used by the linked command. */
|
|
587
|
+
workspace_context_mode?: "source" | "isolated" | "snapshot";
|
|
588
|
+
/** Trust classification applied before execution. */
|
|
589
|
+
trust_reason?: "legacy" | "local_mutation" | "local_source_ref" | "acknowledged" | "invalid_provenance" | "foreign_source_ref";
|
|
569
590
|
}
|
|
570
591
|
/** Documents the item test run summary payload exchanged by command, SDK, and package integrations. */
|
|
571
592
|
export interface ItemTestRunSummary {
|
|
@@ -1121,6 +1142,8 @@ export interface PmSettings {
|
|
|
1121
1142
|
/** Value that configures or reports testing for this contract. */
|
|
1122
1143
|
testing: {
|
|
1123
1144
|
record_results_to_items: boolean;
|
|
1145
|
+
/** Permit explicit one-shot execution of commands not yet trusted by this clone. */
|
|
1146
|
+
allow_untrusted_linked_tests: boolean;
|
|
1124
1147
|
};
|
|
1125
1148
|
/** Value that configures or reports telemetry for this contract. */
|
|
1126
1149
|
telemetry: {
|
package/dist/types.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
/** Supported values accepted by the builtin item type contract. */
|
|
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]="64223a83-1287-57ac-915d-dbd5e375a6eb")}catch(e){}}();
|
|
9
9
|
export const BUILTIN_ITEM_TYPE_VALUES = [
|
|
10
10
|
"Epic",
|
|
11
11
|
"Feature",
|
|
@@ -243,4 +243,4 @@ export const CONTEXT_SECTION_VALUES = [
|
|
|
243
243
|
"tests",
|
|
244
244
|
];
|
|
245
245
|
//# sourceMappingURL=types.js.map
|
|
246
|
-
//# debugId=
|
|
246
|
+
//# debugId=64223a83-1287-57ac-915d-dbd5e375a6eb
|
|
@@ -10,7 +10,10 @@ Implementation lineage:
|
|
|
10
10
|
resolution and patch-free historical reads implemented by
|
|
11
11
|
[pm-ffz0a9](../.agents/pm/issues/pm-ffz0a9.toon),
|
|
12
12
|
[pm-v8gfi7](../.agents/pm/issues/pm-v8gfi7.toon), and
|
|
13
|
-
[pm-3yxwv5](../.agents/pm/issues/pm-3yxwv5.toon).
|
|
13
|
+
[pm-3yxwv5](../.agents/pm/issues/pm-3yxwv5.toon). Cross-harness adapters and
|
|
14
|
+
operator-managed probe/vocabulary controls are tracked by
|
|
15
|
+
[pm-c0lrdm](../.agents/pm/features/pm-c0lrdm.toon) and
|
|
16
|
+
[pm-yds9dt](../.agents/pm/chores/pm-yds9dt.toon).
|
|
14
17
|
|
|
15
18
|
Status: accepted amendment to
|
|
16
19
|
[pm-qwuber](../.agents/pm/decisions/pm-qwuber.toon). The original stable-author
|
|
@@ -51,10 +54,13 @@ Provenance values are descriptive context, never authentication or
|
|
|
51
54
|
authorization principals. Values are trimmed, length-bounded, and obtained only
|
|
52
55
|
from literal descriptor keys, trusted caller data, or a named bounded resolver.
|
|
53
56
|
Detection does not spawn processes, traverse process trees, evaluate user
|
|
54
|
-
regexes, or access the network. The built-in Claude
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
regexes, or access the network. The built-in Claude and Codex resolvers read
|
|
58
|
+
only bounded windows of the current session's harness-owned JSONL file. Claude
|
|
59
|
+
uses the recent tail to recover its recorded model/version. Codex uses the
|
|
60
|
+
recent tail plus a bounded initial-head fallback for oversized sessions to
|
|
61
|
+
recover allow-listed `turn_context.model` and `turn_context.effort` values.
|
|
62
|
+
Both cap traversal, file bytes, lines, and line length, ignore all other fields,
|
|
63
|
+
never follow symlinks, and fail closed. `agent_identity.probes_enabled` or
|
|
58
64
|
`PM_AGENT_PROBES=off` disables every local resolver without disabling ordinary
|
|
59
65
|
environment, argv, client, or host detection.
|
|
60
66
|
|
|
@@ -113,6 +119,11 @@ fabricate precision that was never captured.
|
|
|
113
119
|
The aggregate and core SDK entrypoints export:
|
|
114
120
|
|
|
115
121
|
- `AGENT_PROVENANCE_DIMENSIONS`;
|
|
122
|
+
- `BUILTIN_AGENT_PROVENANCE_ADAPTERS`,
|
|
123
|
+
`listAgentProvenanceAdapters()`, and
|
|
124
|
+
`registerAgentProvenanceAdapters()`;
|
|
125
|
+
- `normalizeAgentProvenanceAdapterValue()` for stable model-family and effort
|
|
126
|
+
vocabulary projections that retain the bounded raw observation;
|
|
116
127
|
- `detectAgentIdentity()` and `detectHarnessIdentity()`;
|
|
117
128
|
- `analyzeAgentProvenanceDescriptorCoverage()` for the descriptor capability
|
|
118
129
|
matrix and negative controls;
|
|
@@ -138,6 +149,31 @@ Legacy author interpretation is workspace-owned data under
|
|
|
138
149
|
version and whether a harness was `recorded`, resolved by `vocabulary`, or
|
|
139
150
|
remains `unresolved`; immutable authors and hashes are never rewritten.
|
|
140
151
|
|
|
152
|
+
`pm config get agent-identity-vocabulary`, `config list`, and `config export`
|
|
153
|
+
publish only its `version` and `alias_count`. Typed mutations use the existing
|
|
154
|
+
config transport:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
pm config set agent-identity-probes-enabled false
|
|
158
|
+
pm config set agent-identity-vocabulary --policy preview-add \
|
|
159
|
+
--value "Legacy Codex=codex" --criterion "Legacy Codex" --criterion "Alice"
|
|
160
|
+
pm config set agent-identity-vocabulary --policy add \
|
|
161
|
+
--value "Legacy Codex=codex"
|
|
162
|
+
pm config set agent-identity-vocabulary --policy remove --value "Legacy Codex"
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`preview-*` policies perform no write and report the exact residual unique
|
|
166
|
+
author count without returning author spellings. Real add/remove/clear changes
|
|
167
|
+
bump the vocabulary revision once; identical adds and absent removes are
|
|
168
|
+
idempotent. Aliases for already canonical `harness:<name>` authors fail closed.
|
|
169
|
+
|
|
170
|
+
Every built-in interactive harness has a contract-versioned adapter with an
|
|
171
|
+
implementation version, priority, covered dimensions, source classes,
|
|
172
|
+
normalization revisions, confidence, waivers, and immutable probe bounds.
|
|
173
|
+
Packages may register a new namespace or explicitly replace a built-in only at
|
|
174
|
+
a higher priority. Equal-priority ambiguity and descriptor mismatch fail
|
|
175
|
+
closed, and the disposer restores the prior adapter.
|
|
176
|
+
|
|
141
177
|
The SDK/CLI matrix classifies every input as shared, positional, transport,
|
|
142
178
|
presentation, local adapter, scope selector, compatibility alias, or SDK-native.
|
|
143
179
|
An unknown CLI flag fails closed as `unclassified`. Committed test baselines cap
|
package/docs/CONFIGURATION.md
CHANGED
|
@@ -29,6 +29,7 @@ pm config project export --json
|
|
|
29
29
|
pm config project get item-format --json
|
|
30
30
|
pm config project set item-format --format toon
|
|
31
31
|
pm config project set test-result-tracking --policy enabled
|
|
32
|
+
pm config project set untrusted-linked-test-execution --policy disabled
|
|
32
33
|
```
|
|
33
34
|
|
|
34
35
|
`config set <key> <value>` also accepts the value as a positional argument; pm routes
|
|
@@ -85,6 +86,7 @@ When `settings.json` cannot be loaded, `pm` falls back to built-in defaults and
|
|
|
85
86
|
| `history.compact_policy.max_entries` | when the policy is enabled, the entry count above which a stream is flagged by `pm health` and the default `pm history-compact --all-over` threshold (default `500`) |
|
|
86
87
|
| `history.compact_policy.trigger` | policy intent when enabled: `health_warn` (advisory only) or `auto` (scheduled sweeps expected) |
|
|
87
88
|
| `testing.record_results_to_items` | persist bounded linked-test summaries |
|
|
89
|
+
| `testing.allow_untrusted_linked_tests` | permit the explicit `pm test --allow-untrusted-linked-tests` one-run override (default `false`; does not trust or execute commands by itself) |
|
|
88
90
|
| `validation.sprint_release_format` | `warn` or `strict_error` |
|
|
89
91
|
| `validation.parent_reference` | `warn` or `strict_error` (`strict_error` is the built-in default; `pm create --allow-missing-parent` is the explicit escape hatch) |
|
|
90
92
|
| `item_types.definitions[]` | custom item types and type options |
|
|
@@ -115,6 +117,7 @@ pm config project set schema_unknown_field_policy reject # (schema.unknown_fie
|
|
|
115
117
|
pm config project set governance-duplicate-detection-mode strict # (governance.duplicate_detection_mode) off | advisory | strict
|
|
116
118
|
pm config project set governance-duplicate-detection-threshold 0.8 # (governance.duplicate_detection_threshold) ratio 0..1
|
|
117
119
|
pm config project set governance-duplicate-detection-limit 3 # (governance.duplicate_detection_limit) integer 0..20
|
|
120
|
+
pm config project set untrusted-linked-test-execution disabled # (testing.allow_untrusted_linked_tests) enabled | disabled
|
|
118
121
|
```
|
|
119
122
|
|
|
120
123
|
Duplicate governance uses the shared SDK scorer and bounded metadata query
|
|
@@ -227,6 +230,7 @@ pm config project set sprint-release-format-policy --policy warn
|
|
|
227
230
|
pm config project set parent-reference-policy --policy strict_error
|
|
228
231
|
pm config project set history-missing-stream-policy --policy auto_create
|
|
229
232
|
pm config project set test-result-tracking --policy enabled
|
|
233
|
+
pm config project set untrusted-linked-test-execution --policy disabled
|
|
230
234
|
```
|
|
231
235
|
|
|
232
236
|
Use standalone checks when validating a repository:
|
|
@@ -58,6 +58,15 @@ estimates, applied stages, and omitted top-level fields. Minimal fallbacks bound
|
|
|
58
58
|
the named omission list and disclose any additional count through
|
|
59
59
|
`omitted_fields_overflow_count`.
|
|
60
60
|
|
|
61
|
+
Structured CLI refusals also include a compact `refusal` identity with the
|
|
62
|
+
failing command/flag/operand surface, rejected scalar when observable, complete
|
|
63
|
+
legal domain when one exists, and the process exit code. Recovery-bearing
|
|
64
|
+
errors use the `recovery_bundle` diagnostic class. Collection degradation may
|
|
65
|
+
compact explanatory domains inside `recovery`, but `refusal.legal_domain`
|
|
66
|
+
remains complete and `recovery.suggested_retry_args` is atomic: the projector
|
|
67
|
+
either retains the executable argv or removes the recovery rather than slicing
|
|
68
|
+
it into a dead command.
|
|
69
|
+
|
|
61
70
|
The deterministic ladder is:
|
|
62
71
|
|
|
63
72
|
1. full diagnostic;
|
|
@@ -73,8 +82,12 @@ envelope.
|
|
|
73
82
|
|
|
74
83
|
## Executable Assurance
|
|
75
84
|
|
|
76
|
-
`pnpm quality:recovery-closure` builds the current CLI and replays
|
|
77
|
-
contracts in isolated trackers
|
|
85
|
+
`pnpm quality:recovery-closure` builds the current CLI and replays 117 refusal
|
|
86
|
+
contracts in isolated trackers: 18 closed-domain rows, 88 required-argument
|
|
87
|
+
omissions derived from core executable positional signatures, seven
|
|
88
|
+
closed-action families, and four tracker-preflight states. Package-owned
|
|
89
|
+
commands enter executable coverage when their package runtime is active rather
|
|
90
|
+
than being misreported as core. Ten representative, high-frequency failure
|
|
78
91
|
paths are also ratcheted by
|
|
79
92
|
`scripts/release/diagnostic-output-baseline.json`. The gate requires every row
|
|
80
93
|
to remain within the SDK-declared JSON ceiling and retain a mechanically
|
|
@@ -85,6 +98,10 @@ The baseline is a coverage ratchet, not permission to weaken a ceiling. Its
|
|
|
85
98
|
negative control requires a missing baseline probe to fail. The existing
|
|
86
99
|
refusal-closure negative controls independently prove that incomplete domains,
|
|
87
100
|
broken retries, and malformed recovery envelopes remain blocking findings.
|
|
101
|
+
The grammar corpus additionally hashes authoritative tracker state around each
|
|
102
|
+
refusal; schema, items, history, settings, and package state must not change.
|
|
103
|
+
Ephemeral runtime lock/cache directories are excluded from that semantic
|
|
104
|
+
snapshot.
|
|
88
105
|
|
|
89
106
|
Run the focused proof with:
|
|
90
107
|
|
package/docs/MERGE_SAFETY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Multi-Branch Tracker Merge Safety
|
|
2
2
|
|
|
3
|
-
Tracked by [pm-wc1r](../.agents/pm/features/pm-wc1r.toon), with the integrity and concurrency fixes [pm-9q2t](../.agents/pm/issues/pm-9q2t.toon), [pm-cxyv](../.agents/pm/issues/pm-cxyv.toon), [pm-gpo7](../.agents/pm/issues/pm-gpo7.toon), [pm-m3nl](../.agents/pm/issues/pm-m3nl.toon), [pm-wwfd](../.agents/pm/issues/pm-wwfd.toon), and [pm-xdn6](../.agents/pm/issues/pm-xdn6.toon). Fresh-init fence ownership is tracked by [pm-1w3ljt](../.agents/pm/issues/pm-1w3ljt.toon); runtime-cache index governance by [pm-hous](../.agents/pm/issues/pm-hous.toon); local allocation safety by [pm-khdq](../.agents/pm/issues/pm-khdq.toon); fence-coverage completeness and drift detection by [pm-i4fx](../.agents/pm/issues/pm-i4fx.toon); package-defined item coverage by [pm-5rexki](../.agents/pm/issues/pm-5rexki.toon); non-item JSON coverage by [pm-gjicmx](../.agents/pm/issues/pm-gjicmx.toon); portable driver identity by [pm-w91mvg](../.agents/pm/issues/pm-w91mvg.toon); pending receipt validation by [pm-ysqb6n](../.agents/pm/issues/pm-ysqb6n.toon); receipt classification by [pm-jtwsct](../.agents/pm/issues/pm-jtwsct.toon); direction-independent item conflict selection by [pm-dlx7v7](../.agents/pm/issues/pm-dlx7v7.toon); corrected reconciliation guidance by [pm-lwmstb](../.agents/pm/issues/pm-lwmstb.toon); cross-branch id collision safety by [pm-pibw](../.agents/pm/issues/pm-pibw.toon); auditable merge history by [pm-9j2r3b](../.agents/pm/tasks/pm-9j2r3b.toon); durable conflict decisions by [pm-rh98vo](../.agents/pm/issues/pm-rh98vo.toon); continuous conformance by [pm-76dnfg](../.agents/pm/tasks/pm-76dnfg.toon); workspace-wide CI enforcement by [pm-pdr8t1](../.agents/pm/tasks/pm-pdr8t1.toon); post-merge reconciliation by [pm-mfkv92](../.agents/pm/issues/pm-mfkv92.toon); this repository's own adoption by [pm-iwsj](../.agents/pm/chores/pm-iwsj.toon).
|
|
3
|
+
Tracked by [pm-wc1r](../.agents/pm/features/pm-wc1r.toon), with the integrity and concurrency fixes [pm-9q2t](../.agents/pm/issues/pm-9q2t.toon), [pm-cxyv](../.agents/pm/issues/pm-cxyv.toon), [pm-gpo7](../.agents/pm/issues/pm-gpo7.toon), [pm-m3nl](../.agents/pm/issues/pm-m3nl.toon), [pm-wwfd](../.agents/pm/issues/pm-wwfd.toon), and [pm-xdn6](../.agents/pm/issues/pm-xdn6.toon). Fresh-init fence ownership is tracked by [pm-1w3ljt](../.agents/pm/issues/pm-1w3ljt.toon); runtime-cache index governance by [pm-hous](../.agents/pm/issues/pm-hous.toon); local allocation safety by [pm-khdq](../.agents/pm/issues/pm-khdq.toon); fence-coverage completeness and drift detection by [pm-i4fx](../.agents/pm/issues/pm-i4fx.toon); package-defined item coverage by [pm-5rexki](../.agents/pm/issues/pm-5rexki.toon); non-item JSON coverage by [pm-gjicmx](../.agents/pm/issues/pm-gjicmx.toon); portable driver identity by [pm-w91mvg](../.agents/pm/issues/pm-w91mvg.toon); pending receipt validation by [pm-ysqb6n](../.agents/pm/issues/pm-ysqb6n.toon); receipt classification by [pm-jtwsct](../.agents/pm/issues/pm-jtwsct.toon); direction-independent item conflict selection by [pm-dlx7v7](../.agents/pm/issues/pm-dlx7v7.toon); corrected reconciliation guidance by [pm-lwmstb](../.agents/pm/issues/pm-lwmstb.toon); cross-branch id collision safety by [pm-pibw](../.agents/pm/issues/pm-pibw.toon); auditable merge history by [pm-9j2r3b](../.agents/pm/tasks/pm-9j2r3b.toon); durable conflict decisions by [pm-rh98vo](../.agents/pm/issues/pm-rh98vo.toon); continuous conformance by [pm-76dnfg](../.agents/pm/tasks/pm-76dnfg.toon); workspace-wide CI enforcement by [pm-pdr8t1](../.agents/pm/tasks/pm-pdr8t1.toon); post-merge reconciliation by [pm-mfkv92](../.agents/pm/issues/pm-mfkv92.toon); linked-command execution trust by [pm-ed28wi](../.agents/pm/issues/pm-ed28wi.toon); this repository's own adoption by [pm-iwsj](../.agents/pm/chores/pm-iwsj.toon).
|
|
4
4
|
|
|
5
5
|
pm stores project context as reviewable repository files. Concurrent agents can therefore use ordinary branches and worktrees, but tracker artifacts need semantic merge behavior: raw line merging cannot preserve TOON collection counts, JSON object structure, or append-only history hash chains.
|
|
6
6
|
|
|
@@ -61,6 +61,20 @@ pm merge install --dry-run --json
|
|
|
61
61
|
| tracker `**/*.jsonl` except the later `history/*.jsonl` override | `pm-relationship` | Covers default and package-owned custom relationship event paths, unions divergent suffixes by `eventId` (timestamp-ordered, ours-first on ties), and renumbers `sequence` consecutively so the strict-sequence store loader accepts the merged stream. |
|
|
62
62
|
| root `settings.json` and nested `**/*.json` | `pm-json` | Recursively merges objects per key. Arrays compose when both branches preserve the base and add distinct entries, so independent extension installs and evaluation additions merge without weakening edit/removal conflict detection. |
|
|
63
63
|
|
|
64
|
+
The `tests` collection has an additional execution-safety rule. Its semantic
|
|
65
|
+
identity excludes provenance so the same command/context does not duplicate
|
|
66
|
+
when branches record different authorship metadata. A test definition newly
|
|
67
|
+
contributed by the other merge side is persisted with
|
|
68
|
+
`provenance.source_kind=merge_union` while retaining its author, creation time,
|
|
69
|
+
and source ref. `pm test --run` and `pm test-all` refuse that command before
|
|
70
|
+
spawning a process until the receiving clone acknowledges its fingerprint or
|
|
71
|
+
uses the two-part project-policy plus per-run override documented in
|
|
72
|
+
[Testing](TESTING.md#linked-test-command-trust). `pm validate
|
|
73
|
+
--check-command-references` reports outstanding entries. This is the threat
|
|
74
|
+
boundary for append-like data that becomes executable after a merge; ordinary
|
|
75
|
+
notes, files, and other non-executable collections retain normal set-union
|
|
76
|
+
behavior.
|
|
77
|
+
|
|
64
78
|
When both sides change the same item scalar differently, the driver writes the same stable value regardless of which branch Git labels ours or theirs, but exits nonzero. Item results and receipts expose the caller's `requested_preference`; the per-decision `retained` and `discarded` values or hashes are authoritative because stable value order can retain either side. Readers normalize the legacy receipt key `preferred`, while new receipts no longer emit it. JSON leaf conflicts retain the explicit preferred-side policy. Git keeps either path conflicted so a human or coordinating agent must review the discarded value and explicitly `git add` the resolution. This correction is tracked by [pm-qckpnq](../.agents/pm/issues/pm-qckpnq.toon).
|
|
65
79
|
|
|
66
80
|
The driver result's `guidance` always points unresolved conflicts to `pm merge report`. When a clone-local receipt exists, guidance includes its privacy-safe receipt and item ids for exact correlation; discarded values remain confined to the local receipt and never appear in generic logs or tracker history. Tracked by [pm-fbrz7p](../.agents/pm/issues/pm-fbrz7p.toon).
|
package/docs/README.md
CHANGED
|
@@ -50,6 +50,8 @@ pm guide release --json
|
|
|
50
50
|
- [Output Token Accounting](OUTPUT_TOKEN_ACCOUNTING.md) - opt-in CLI/MCP byte attribution, bounded receipt overhead, and release-level tokens-per-task baselines.
|
|
51
51
|
- [SDK Context Platform](SDK_CONTEXT.md) - task-oriented entry point for authoritative reads, ranking, package workflows, diagnostics, recovery, and verification.
|
|
52
52
|
- [Self-Describing Context Contracts](SELF_DESCRIBING_CONTEXT_CONTRACTS.md) - intent-scoped reads, semantic flag invocation metadata, visibility parity, and generated error vocabulary.
|
|
53
|
+
- [Generated Agent Capability Routing](generated/AGENT_CAPABILITY_ROUTING.md) - contract-derived command families shared by help, guide, skills, completion, MCP, and extensions.
|
|
54
|
+
- [Generated Refusal Closure Census](generated/REFUSAL_CLOSURE_CENSUS.md) - complete error-catalog join to executable refusal evidence and explicit uncovered obligations.
|
|
53
55
|
- [Universal Read Output Contracts](READ_OUTPUT_CONTRACTS.md) - cross-command include, amount, cost, and encoding controls for CLI, SDK, MCP, and packages.
|
|
54
56
|
- [Diagnostic Output Contracts](DIAGNOSTIC_OUTPUT_CONTRACTS.md) - action-first error budgets, deterministic degradation, SDK projection, and executable refusal assurance.
|
|
55
57
|
- [Mutation Integrity](MUTATION_INTEGRITY.md) - shared CLI/SDK/MCP author, secret, append-only disposition, and stale-work guardrails.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Universal Read Output Contracts
|
|
2
2
|
|
|
3
|
-
Tracker references: [pm-hb7ug8](../.agents/pm/features/pm-hb7ug8.toon), [pm-cxr0jb](../.agents/pm/features/pm-cxr0jb.toon), [pm-hid9g1](../.agents/pm/features/pm-hid9g1.toon), [pm-h8tpeh](../.agents/pm/features/pm-h8tpeh.toon), [pm-5t33or](../.agents/pm/features/pm-5t33or.toon), [pm-srns](../.agents/pm/issues/pm-srns.toon), [pm-sb0tns](../.agents/pm/issues/pm-sb0tns.toon), [pm-gjjurs](../.agents/pm/issues/pm-gjjurs.toon), [pm-eugaqy](../.agents/pm/issues/pm-eugaqy.toon), [pm-jt8aa2](../.agents/pm/issues/pm-jt8aa2.toon), [pm-kyjdne](../.agents/pm/issues/pm-kyjdne.toon), [pm-8nev0o](../.agents/pm/issues/pm-8nev0o.toon), [pm-e5gl05](../.agents/pm/issues/pm-e5gl05.toon), [pm-cha95z](../.agents/pm/tasks/pm-cha95z.toon),
|
|
3
|
+
Tracker references: [pm-hb7ug8](../.agents/pm/features/pm-hb7ug8.toon), [pm-cxr0jb](../.agents/pm/features/pm-cxr0jb.toon), [pm-hid9g1](../.agents/pm/features/pm-hid9g1.toon), [pm-h8tpeh](../.agents/pm/features/pm-h8tpeh.toon), [pm-5t33or](../.agents/pm/features/pm-5t33or.toon), [pm-srns](../.agents/pm/issues/pm-srns.toon), [pm-sb0tns](../.agents/pm/issues/pm-sb0tns.toon), [pm-gjjurs](../.agents/pm/issues/pm-gjjurs.toon), [pm-eugaqy](../.agents/pm/issues/pm-eugaqy.toon), [pm-jt8aa2](../.agents/pm/issues/pm-jt8aa2.toon), [pm-kyjdne](../.agents/pm/issues/pm-kyjdne.toon), [pm-8nev0o](../.agents/pm/issues/pm-8nev0o.toon), [pm-e5gl05](../.agents/pm/issues/pm-e5gl05.toon), [pm-cha95z](../.agents/pm/tasks/pm-cha95z.toon), [pm-2qvq7a](../.agents/pm/issues/pm-2qvq7a.toon), and [pm-xam9bt](../.agents/pm/issues/pm-xam9bt.toon).
|
|
4
4
|
|
|
5
5
|
## Agent Quick Context
|
|
6
6
|
|
|
@@ -164,6 +164,16 @@ an unbounded multi-megabyte response;
|
|
|
164
164
|
`recovery_budget_multiplier: 1` declares that each next page retains the same
|
|
165
165
|
useful-result ceiling.
|
|
166
166
|
|
|
167
|
+
When compaction affects a nested collection that is not declared resumable,
|
|
168
|
+
the recovery budget is derived from the larger of the binding ceiling plus one
|
|
169
|
+
and the measured pre-compaction result. The SDK adds a 25% envelope margin and
|
|
170
|
+
rounds up to 100 tokens. The CLI, SDK, and MCP bindings therefore receive the
|
|
171
|
+
same finite value, which is strictly larger than the request that already
|
|
172
|
+
truncated. If safe-integer arithmetic cannot represent that value, recovery
|
|
173
|
+
uses `unbounded` explicitly. `resolveReadOutputRecoveryBudget()` exposes the
|
|
174
|
+
versioned pure calculation to package authors; there is no hard-coded smaller
|
|
175
|
+
retry and no recovery cycle.
|
|
176
|
+
|
|
167
177
|
Assurance declares `budget_retention_policy: verdict_priority`: failing block,
|
|
168
178
|
warn, and observe rows precede retired and passing rows while preserving order
|
|
169
179
|
within each class. `assertions_total` remains the pre-projection denominator,
|