@unbrained/pm-cli 2026.9.3 → 2026.9.5
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/.agents/skills/HARNESS_COMPATIBILITY.md +1 -1
- package/.agents/skills/README.md +2 -2
- package/.agents/skills/pm-developer/SKILL.md +4 -1
- package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +10 -0
- package/.agents/skills/pm-developer/references/GRAPH_AND_RELATIONSHIPS.md +3 -1
- package/.agents/skills/pm-extensions/SKILL.md +2 -2
- package/.agents/skills/pm-extensions/references/LIFECYCLE.md +3 -3
- package/.agents/skills/pm-extensions/references/TROUBLESHOOTING.md +3 -3
- package/.agents/skills/pm-user/SKILL.md +2 -0
- package/.agents/skills/pm-user/references/BACKLOG_SHAPING.md +5 -0
- package/.agents/skills/pm-user/references/WORKFLOWS.md +20 -5
- package/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +52 -0
- package/dist/cli/commander-usage.d.ts +2 -0
- package/dist/cli/commander-usage.js +15 -12
- package/dist/cli/help-json-payload.js +12 -7
- package/dist/cli/main.js +15 -6
- package/dist/cli/register-list-query.js +4 -2
- package/dist/cli/register-mutation.js +4 -2
- package/dist/cli/register-operations.js +6 -2
- package/dist/cli-bundle/bundle-manifest.json +154 -154
- package/dist/cli-bundle/chunks/{chunk-EDPIS7EB.js → chunk-3HBDTJRK.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-66VPKFP2.js +5 -0
- package/dist/cli-bundle/chunks/{chunk-Y4PJ6HPK.js → chunk-HUAQITVW.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-DKGP3QLE.js → chunk-IBYREGSP.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-LUI4E32I.js +231 -0
- package/dist/cli-bundle/chunks/{chunk-UPPM2FOZ.js → chunk-QPZHQY2O.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-34HASX3S.js → chunk-SF6SM6U5.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-SVK5Y64D.js +40 -0
- package/dist/cli-bundle/chunks/chunk-V5GBD5KV.js +9 -0
- package/dist/cli-bundle/chunks/{chunk-LENC656S.js → chunk-WWAEGW4V.js} +67 -70
- package/dist/cli-bundle/chunks/chunk-ZRAQS3UA.js +8 -0
- package/dist/cli-bundle/chunks/{register-list-query-W2ZTOMKP.js → register-list-query-AYKGODWT.js} +3 -3
- package/dist/cli-bundle/chunks/{register-mutation-RVND5NCG.js → register-mutation-YZYG53SQ.js} +4 -4
- package/dist/cli-bundle/chunks/register-operations-KFSCC7QV.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-D3ZFHY3L.js → register-setup-UJCRVGBG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-24IG6ONG.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-M5M6SVHS.js → chunk-3ASU6WGI.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-3ITLIBKS.js +56 -0
- package/dist/cli-bundle/focused-chunks/chunk-3NQD5YDG.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-S27XMBIN.js → chunk-4OSHLNUE.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-65N6JHAN.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-5RFXUPN5.js → chunk-B2TTQGFG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-GUBM3RGY.js +20 -0
- package/dist/cli-bundle/focused-chunks/{chunk-Q45NHPF2.js → chunk-H5FOGAVD.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-JX3RCVCX.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-D7KXFBXV.js → chunk-KWWCBWFO.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-MV752SUC.js +12 -0
- package/dist/cli-bundle/focused-chunks/chunk-PKIPMCFS.js +6 -0
- package/dist/cli-bundle/focused-chunks/{chunk-4HJFY4MB.js → chunk-QL66QNWG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-RJMR2JIF.js +9 -0
- package/dist/cli-bundle/focused-chunks/chunk-WIUPWIZR.js +177 -0
- package/dist/cli-bundle/focused-chunks/chunk-WOCIPMW7.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-GT7MXDLW.js → chunk-YEF5PQQ2.js} +2 -2
- package/dist/cli-bundle/main.js +22 -15
- 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 +29 -32
- 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 +45 -37
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +10 -10
- package/dist/core/diagnostics/remediation.js +4 -4
- package/dist/core/extensions/extension-types.d.ts +2 -0
- package/dist/core/extensions/extension-types.js +2 -2
- package/dist/core/history/drift-scan.d.ts +5 -0
- package/dist/core/history/drift-scan.js +16 -6
- package/dist/core/history/event-classification.d.ts +1 -1
- package/dist/core/history/event-classification.js +3 -2
- package/dist/core/history/history.d.ts +37 -1
- package/dist/core/history/history.js +311 -59
- package/dist/core/history/identity.d.ts +15 -0
- package/dist/core/history/identity.js +31 -0
- package/dist/core/history/projection.js +50 -17
- package/dist/core/history/read.js +6 -3
- package/dist/core/history/replay.d.ts +1 -2
- package/dist/core/history/replay.js +70 -36
- package/dist/core/history/version-address.d.ts +13 -0
- package/dist/core/history/version-address.js +33 -0
- package/dist/core/item/actionability.d.ts +21 -1
- package/dist/core/item/actionability.js +45 -10
- package/dist/core/item/id.js +8 -4
- package/dist/core/item/item-type-definition.d.ts +2 -0
- package/dist/core/item/item-type-definition.js +9 -2
- package/dist/core/item/type-registry.d.ts +5 -1
- package/dist/core/item/type-registry.js +9 -4
- package/dist/core/lock/lock.d.ts +10 -0
- package/dist/core/lock/lock.js +42 -3
- package/dist/core/shared/author.d.ts +3 -1
- package/dist/core/shared/author.js +111 -23
- package/dist/core/shared/errors.d.ts +8 -0
- package/dist/core/shared/errors.js +2 -2
- package/dist/core/store/item-store.d.ts +14 -0
- package/dist/core/store/item-store.js +48 -10
- package/dist/core/store/settings-validator.js +3 -2
- package/dist/sdk/actionability.d.ts +1 -1
- package/dist/sdk/actionability.js +3 -3
- package/dist/sdk/cli-contracts/command-aliases.js +11 -2
- package/dist/sdk/cli-contracts/completeness.js +4 -3
- package/dist/sdk/cli-contracts/flag-contracts.js +29 -5
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +19 -12
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +14 -2
- package/dist/sdk/cli-contracts/tool-schema.d.ts +2 -2
- package/dist/sdk/cli-contracts/tool-schema.js +19 -6
- package/dist/sdk/context-intent-contracts.js +3 -3
- package/dist/sdk/context-usage.js +9 -11
- package/dist/sdk/define.d.ts +1 -1
- package/dist/sdk/define.js +2 -2
- package/dist/sdk/environment/agent-environment.d.ts +296 -0
- package/dist/sdk/environment/agent-environment.js +467 -0
- package/dist/sdk/environment/project-runtime-compatibility.d.ts +19 -1
- package/dist/sdk/environment/project-runtime-compatibility.js +118 -21
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +98 -38
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +50 -2
- package/dist/sdk/governance/health.js +13 -44
- package/dist/sdk/governance/merge-receipt-history.d.ts +62 -0
- package/dist/sdk/governance/merge-receipt-history.js +207 -0
- package/dist/sdk/governance/provenance-health.js +9 -3
- package/dist/sdk/governance/validate-history-drift.js +16 -5
- package/dist/sdk/guide-topics.js +116 -2
- package/dist/sdk/history/salvage.d.ts +35 -0
- package/dist/sdk/history/salvage.js +248 -0
- package/dist/sdk/history-compact.js +41 -37
- package/dist/sdk/history-read.d.ts +3 -2
- package/dist/sdk/history-read.js +6 -3
- package/dist/sdk/history-redact.js +58 -23
- package/dist/sdk/history-repair.d.ts +5 -0
- package/dist/sdk/history-repair.js +28 -6
- package/dist/sdk/index.d.ts +2 -0
- package/dist/sdk/index.js +4 -2
- package/dist/sdk/lifecycle/claim.d.ts +4 -0
- package/dist/sdk/lifecycle/claim.js +9 -3
- package/dist/sdk/lifecycle/restore.d.ts +1 -0
- package/dist/sdk/lifecycle/restore.js +19 -7
- package/dist/sdk/merge/driver.d.ts +3 -1
- package/dist/sdk/merge/driver.js +9 -9
- package/dist/sdk/merge/index.d.ts +1 -1
- package/dist/sdk/merge/index.js +3 -3
- package/dist/sdk/merge/receipts.d.ts +17 -6
- package/dist/sdk/merge/receipts.js +246 -75
- package/dist/sdk/merge/reconcile.d.ts +9 -7
- package/dist/sdk/merge/reconcile.js +175 -12
- package/dist/sdk/merge/three-way.d.ts +22 -2
- package/dist/sdk/merge/three-way.js +92 -25
- package/dist/sdk/output-projection.d.ts +3 -1
- package/dist/sdk/output-projection.js +11 -3
- package/dist/sdk/public-surface.json +1 -0
- package/dist/sdk/query/context.d.ts +9 -0
- package/dist/sdk/query/context.js +33 -21
- package/dist/sdk/query/get.d.ts +2 -2
- package/dist/sdk/query/get.js +4 -3
- package/dist/sdk/query/history.d.ts +11 -0
- package/dist/sdk/query/history.js +34 -10
- package/dist/sdk/query/next.d.ts +15 -1
- package/dist/sdk/query/next.js +43 -20
- package/dist/sdk/query.d.ts +1 -0
- package/dist/sdk/query.js +3 -2
- package/dist/sdk/runtime-primitives.d.ts +3 -3
- package/dist/sdk/runtime-primitives.js +5 -5
- package/dist/types.d.ts +27 -0
- package/dist/types.js +2 -2
- package/docs/AGENT_ENVIRONMENTS.md +47 -0
- package/docs/AGENT_GUIDE.md +36 -0
- package/docs/AGENT_PROVENANCE_ADR.md +17 -2
- package/docs/CONTEXT_INTEGRITY_CONTRACTS.md +38 -1
- package/docs/HISTORY_RECOVERY.md +146 -0
- package/docs/MERGE_SAFETY.md +119 -23
- package/docs/README.md +2 -0
- package/docs/RELEASING.md +25 -11
- package/docs/SDK_CONTEXT_EVIDENCE_CONTRACTS.md +24 -2
- package/docs/SDK_CONTEXT_TRUTH_CONTRACTS.md +24 -1
- package/docs/SDK_EXECUTION_CONTRACTS.md +105 -0
- package/docs/SDK_RUNTIME_BOUNDARIES.md +17 -1
- package/docs/TESTING.md +5 -0
- package/docs/agent-task-token-baseline.json +17 -17
- package/docs/agent-task-transcripts.json +2 -1
- package/docs/examples/sdk-agent-environment/README.md +14 -0
- package/docs/examples/sdk-agent-environment/package.json +8 -0
- package/docs/examples/sdk-agent-environment/run-agent-environment.mjs +154 -0
- package/docs/generated/FLAG_LEXICON_BUDGETS.md +10 -10
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +12 -3
- package/marketplace.json +2 -2
- package/package.json +5 -6
- 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-claude/skills/pm-audit/SKILL.md +2 -2
- package/plugins/pm-claude/skills/pm-developer/SKILL.md +2 -2
- package/plugins/pm-claude/skills/pm-planner/SKILL.md +2 -2
- package/plugins/pm-claude/skills/pm-release/SKILL.md +2 -2
- package/plugins/pm-claude/skills/pm-workflow/SKILL.md +3 -3
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/pm-codex/skills/pm-auditor/SKILL.md +2 -2
- package/plugins/pm-codex/skills/pm-native/SKILL.md +3 -4
- package/plugins/pm-codex/skills/pm-release/SKILL.md +2 -2
- package/scripts/finalize-build.mjs +13 -1
- package/dist/cli-bundle/chunks/chunk-AY324UJ5.js +0 -9
- package/dist/cli-bundle/chunks/chunk-E5RBBCXO.js +0 -230
- package/dist/cli-bundle/chunks/chunk-IEHHE6GA.js +0 -5
- package/dist/cli-bundle/chunks/chunk-L7B7343B.js +0 -8
- package/dist/cli-bundle/chunks/chunk-LISESA7W.js +0 -35
- package/dist/cli-bundle/chunks/register-operations-TTROIVC4.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-3ZBI35HU.js +0 -176
- package/dist/cli-bundle/focused-chunks/chunk-4RRHC3S4.js +0 -6
- package/dist/cli-bundle/focused-chunks/chunk-4WR46RMG.js +0 -9
- package/dist/cli-bundle/focused-chunks/chunk-BWKHEIVF.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-GHCZ3YFR.js +0 -20
- package/dist/cli-bundle/focused-chunks/chunk-KBLZRU62.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-KZ2NB3ET.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-OL5EH6I3.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-QKHCSUGJ.js +0 -51
- package/dist/cli-bundle/focused-chunks/chunk-TXE4TSHM.js +0 -12
- package/dist/cli-bundle/focused-chunks/chunk-UCLO3XDU.js +0 -2
- package/sdk/public-surface.json +0 -32524
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* prefer the typed operations exported by the main SDK barrel.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
!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]="
|
|
10
|
+
!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]="619b20e3-78d9-55bd-9d2d-857a3bc1bee8")}catch(e){}}();
|
|
11
11
|
export { createCheckpointId, loadMutationCheckpoint, restoreCheckpointItems, writeMutationCheckpoint, } from "../core/checkpoint/mutation-checkpoint.js";
|
|
12
12
|
export { flattenFlagListValue, resolveFlagValueKind, } from "../core/extensions/flag-value-types.js";
|
|
13
13
|
export { createUnknownSubcommandError, } from "./agent/subcommand-recovery.js";
|
|
@@ -19,10 +19,10 @@ export { isFileMissingError, pathExists, readFileIfExists, removeFileIfExists, w
|
|
|
19
19
|
export { normalizeBulkIdsValue, parseBulkIdsText, resolveCliBulkIdsInput, } from "../core/io/bulk-ids-input.js";
|
|
20
20
|
export { computeHistoryDiff, patchPathToChangedField, } from "../core/history/history-diff.js";
|
|
21
21
|
export { enforceHistoryStreamPolicyForItem, enforceHistoryStreamPolicyForItems, } from "../core/history/history-stream-policy.js";
|
|
22
|
-
export { appendHistoryEntry, CURRENT_HISTORY_ITEM_HASH_VERSION, createHistoryEntry, hashDocument, hashDocumentForVersion, hashEmptyDocument, SUPPORTED_HISTORY_ITEM_HASH_VERSIONS, } from "../core/history/history.js";
|
|
22
|
+
export { appendHistoryEntry, CURRENT_HISTORY_ITEM_HASH_VERSION, CURRENT_HISTORY_RECORD_HASH_VERSION, createHistoryEntry, hashDocument, hashDocumentForVersion, hashEmptyDocument, hashHistoryPatch, hashHistoryRecord, hashHistoryStream, resealHistoryRewrite, sealHistoryRecord, SUPPORTED_HISTORY_ITEM_HASH_VERSIONS, SUPPORTED_HISTORY_RECORD_HASH_VERSIONS, verifyHistoryRecordHash, verifyHistoryRewriteEvidence, } from "../core/history/history.js";
|
|
23
23
|
export { readHistoryEntries } from "../core/history/read.js";
|
|
24
24
|
export { appendWorkspaceAuditEvent, appendWorkspaceHistoryChange, getWorkspaceHistoryPath, inspectWorkspaceHistoryState, mutateWorkspaceJsonWithHistory, reconcileWorkspaceJsonHistory, restoreWorkspaceJsonFromHistory, WORKSPACE_HISTORY_ID, writeWorkspaceJsonWithHistory, } from "../core/history/workspace-history.js";
|
|
25
|
-
export { normalizeReplayPatchOps, replayToCanonicalItemDocument, replayToItemDocument, toReplayDocument, verifyHistoryChain, verifyHistoryChainWithVersion, } from "../core/history/replay.js";
|
|
25
|
+
export { normalizeReplayPatchOps, reanchorHistoryEntries, replayToCanonicalItemDocument, replayToItemDocument, toReplayDocument, verifyHistoryChain, verifyHistoryChainWithVersion, } from "../core/history/replay.js";
|
|
26
26
|
export { resolveBodyFileContent } from "../core/io/body-file.js";
|
|
27
27
|
export { generateItemId, normalizeItemId, normalizeRawItemId, } from "../core/item/id.js";
|
|
28
28
|
export { canonicalDocument, normalizeItemMetadata, parseItemDocument, serializeItemDocument, } from "../core/item/item-format.js";
|
|
@@ -36,7 +36,7 @@ export { isTerminalStatus, normalizeStatusForRegistry, normalizeStatusInput, } f
|
|
|
36
36
|
export { COMMON_MUTATION_COMMAND_OPTION_KEYS, canonicalizeCommandOptionKey, commandOptionFlagLabel, resolveCommandOptionPolicyState, resolveItemTypeRegistry, resolveTypeDefinition, resolveTypeName, validateTypeOptions, } from "../core/item/type-registry.js";
|
|
37
37
|
export { resolveTypeSynonym } from "../core/item/type-synonyms.js";
|
|
38
38
|
export { acquireLock } from "../core/lock/lock.js";
|
|
39
|
-
export { printError, printResult, writeStdout } from "../core/output/output.js";
|
|
39
|
+
export { printError, printResult, writeStderr, writeStdout } from "../core/output/output.js";
|
|
40
40
|
export { renderRowsAsCsv, renderRowsAsTable } from "../core/output/tabular.js";
|
|
41
41
|
export { parseLimit } from "../core/shared/numeric-parsers.js";
|
|
42
42
|
export { resolveConfiguredPmPackageRoot, resolvePmCliVersion, resolvePmPackageRootFromModule, } from "../core/packages/root.js";
|
|
@@ -82,4 +82,4 @@ export { maybeRunFirstUseTelemetryPrompt } from "../core/telemetry/consent.js";
|
|
|
82
82
|
export { deriveTelemetryCommandResolution, } from "../core/telemetry/observability.js";
|
|
83
83
|
export { emitTelemetryErrorEvent, finishTelemetryCommand, startTelemetryCommand, } from "../core/telemetry/runtime.js";
|
|
84
84
|
//# sourceMappingURL=runtime-primitives.js.map
|
|
85
|
-
//# debugId=
|
|
85
|
+
//# debugId=619b20e3-78d9-55bd-9d2d-857a3bc1bee8
|
package/dist/types.d.ts
CHANGED
|
@@ -428,6 +428,8 @@ export interface ItemTypeDefinition {
|
|
|
428
428
|
description?: string;
|
|
429
429
|
/** Status assigned to newly created items of this type when `--status` is not provided. Falls back to the workflow's open status when unset or invalid. */
|
|
430
430
|
default_status?: string;
|
|
431
|
+
/** Agent work can be dispatched automatically; human work needs a decision, and gates track outcomes. Omission inherits the built-in role or defaults custom types to agent work. */
|
|
432
|
+
execution_role?: "agent" | "human" | "gate";
|
|
431
433
|
/** Value that configures or reports folder for this contract. */
|
|
432
434
|
folder?: string;
|
|
433
435
|
/** Value that configures or reports aliases for this contract. */
|
|
@@ -789,6 +791,25 @@ export interface HistoryPatchOp {
|
|
|
789
791
|
/** Value that configures or reports value for this contract. */
|
|
790
792
|
value?: unknown;
|
|
791
793
|
}
|
|
794
|
+
/** Immutable evidence retained whenever history maintenance replaces anchors or patch operations. */
|
|
795
|
+
export interface HistoryReanchorEvidence {
|
|
796
|
+
/** Before-state anchor present on the record before re-anchoring. */
|
|
797
|
+
before_hash: string;
|
|
798
|
+
/** After-state anchor present on the record before re-anchoring. */
|
|
799
|
+
after_hash: string;
|
|
800
|
+
/** Item hash epoch present before re-anchoring. */
|
|
801
|
+
item_hash_version?: number;
|
|
802
|
+
/** Hash of the original patch, retained even when redaction forbids retaining its values. */
|
|
803
|
+
patch_hash: string;
|
|
804
|
+
/** Original patch operations when repair replaced or skipped recorded intent. */
|
|
805
|
+
patch?: HistoryPatchOp[];
|
|
806
|
+
/** Record-integrity epoch protecting the pre-re-anchor record. */
|
|
807
|
+
record_hash_version?: number;
|
|
808
|
+
/** Record hash protecting the pre-re-anchor attribution and operation metadata. */
|
|
809
|
+
record_hash?: string;
|
|
810
|
+
/** Exact prior sealed record when maintenance can retain its non-sensitive payload. */
|
|
811
|
+
record?: HistoryEntry;
|
|
812
|
+
}
|
|
792
813
|
/** Documents the history entry payload exchanged by command, SDK, and package integrations. */
|
|
793
814
|
export interface HistoryEntry {
|
|
794
815
|
/** Value that configures or reports ts for this contract. */
|
|
@@ -839,6 +860,12 @@ export interface HistoryEntry {
|
|
|
839
860
|
after_hash: string;
|
|
840
861
|
/** Version of the item canonicalization used by before_hash and after_hash. Absent on legacy streams. */
|
|
841
862
|
item_hash_version?: number;
|
|
863
|
+
/** Version of the canonical immutable-record envelope. Absent on legacy entries whose coverage is item-state-only. */
|
|
864
|
+
record_hash_version?: number;
|
|
865
|
+
/** SHA-256 hash covering this event's immutable metadata, patch, and item anchors. */
|
|
866
|
+
record_hash?: string;
|
|
867
|
+
/** Append-only evidence for every prior anchor or patch representation replaced by maintenance. */
|
|
868
|
+
reanchor_evidence?: HistoryReanchorEvidence[];
|
|
842
869
|
/** Human-readable explanation suitable for logs and agent-facing output. */
|
|
843
870
|
message?: string;
|
|
844
871
|
/** Structured audit metadata that does not alter replayed item state. */
|
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]="8173bdb0-39c8-56c0-85c2-5c39f5c213cc")}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=8173bdb0-39c8-56c0-85c2-5c39f5c213cc
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# SDK Agent Environments
|
|
2
|
+
|
|
3
|
+
Tracker: [pm-e1vkee](../.agents/pm/features/pm-e1vkee.toon), [pm-gd6vnn](../.agents/pm/features/pm-gd6vnn.toon), [pm-li2fj5](../.agents/pm/features/pm-li2fj5.toon), [pm-t8a0x1](../.agents/pm/features/pm-t8a0x1.toon)
|
|
4
|
+
|
|
5
|
+
## Agent Quick Context
|
|
6
|
+
|
|
7
|
+
`@unbrained/pm-cli/sdk` provides three composable contracts for building reproducible project-management environments without a machine-learning runtime dependency:
|
|
8
|
+
|
|
9
|
+
- an observation contract declares every read ceiling, emitted-byte calibration, corpus-size dependence, and an ordered degradation ladder;
|
|
10
|
+
- a verdict contract evaluates named, versioned predicates over recorded state and returns `satisfied`, `violated`, or `not_applicable` without producing a reward signal;
|
|
11
|
+
- an episode specification combines a deterministic workspace recipe, canonical task items, observable and withheld fields, hard limits, and an adapter for ordinary `PmClient` actions.
|
|
12
|
+
|
|
13
|
+
The executable [public-SDK example](examples/sdk-agent-environment/README.md) runs the complete reset → observe → act → verdict → close loop in a temporary pm workspace.
|
|
14
|
+
|
|
15
|
+
## Contract Boundaries
|
|
16
|
+
|
|
17
|
+
Observation cost is knowable before a read. `describeObservationCost()` returns the sum of the declared read ceilings plus the calibrated expected emitted bytes. `serveDeclaredObservation()` measures stable serialized bytes, attempts tiers in declaration order, names the served tier, and returns a payload-free refusal if no tier fits.
|
|
18
|
+
|
|
19
|
+
Verdicts only inspect the adapter's `WorkspaceRecordedState`. Evidence identifies the exact snapshot and JSON pointer while a digest avoids copying field values into the result. The interpreter is deterministic and read-only; `policy: "verdict_only_no_reward"` makes the non-reward boundary machine-readable.
|
|
20
|
+
|
|
21
|
+
Episodes never grant a second mutation vocabulary. The adapter's `execute()` method should call ordinary public `PmClient` methods, so lifecycle validation, history, extensions, and policy remain authoritative. Each session owns its counters and trajectory, allowing concurrent runs without shared episode state.
|
|
22
|
+
|
|
23
|
+
Withheld grading fields cannot also be observable. Every tier field must be declared observable, and projection copies only the selected tier fields. Hard action and observation limits fail closed.
|
|
24
|
+
|
|
25
|
+
## Minimal Shape
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import {
|
|
29
|
+
defineEpisodeSpecification,
|
|
30
|
+
openPmEpisode,
|
|
31
|
+
type EpisodeRuntimeAdapter,
|
|
32
|
+
} from "@unbrained/pm-cli/sdk";
|
|
33
|
+
|
|
34
|
+
const specification = defineEpisodeSpecification({
|
|
35
|
+
// Versioned recipe, task set, observation, verdict, and limits.
|
|
36
|
+
});
|
|
37
|
+
const session = await openPmEpisode(
|
|
38
|
+
specification,
|
|
39
|
+
adapter satisfies EpisodeRuntimeAdapter<MyAction>,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
await session.observe();
|
|
43
|
+
await session.step({ kind: "close" });
|
|
44
|
+
const evidence = await session.close();
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Use the same specification and adapter boundary for benchmarks, evaluations, training data collection, or scale-transfer experiments. Consumer intent changes through `mode`; the pm action and evidence contracts do not.
|
package/docs/AGENT_GUIDE.md
CHANGED
|
@@ -195,6 +195,32 @@ post-merge observations on GitHub without changing repository state when no
|
|
|
195
195
|
tracked closeout update is required. See [Releasing](RELEASING.md#reviewed-delivery-closeout)
|
|
196
196
|
for the release contract.
|
|
197
197
|
|
|
198
|
+
## Review and Analyzer Proof
|
|
199
|
+
|
|
200
|
+
Use the [review helper](../scripts/reviews/pr-review-loop.mjs) to wait for
|
|
201
|
+
terminal checks, then inspect its paginated inventory of comments, reviews,
|
|
202
|
+
inline threads, edits, reactions, and resolution state. Inspect failed-check
|
|
203
|
+
details in the receipt even when the helper itself exits successfully.
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
node scripts/reviews/pr-review-loop.mjs watch --pr <number> --repo unbraind/pm-cli --interval 60
|
|
207
|
+
node scripts/release/hosted-analysis-gate.mjs --repo unbraind/pm-cli --sha <full-40-character-head-sha> --json
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Both receipts must pass for the exact current head before merge. A successful
|
|
211
|
+
CodeFactor check can still contain a notice: the stricter analyzer gate requires
|
|
212
|
+
zero outstanding annotations and verifies DeepScan plus branch protection.
|
|
213
|
+
Do not substitute a green check conclusion for that proof. This escape and its
|
|
214
|
+
correction are recorded in [pm-08mt4k](../.agents/pm/issues/pm-08mt4k.toon).
|
|
215
|
+
|
|
216
|
+
Use the helper's `acknowledge-inline` operation for actionable inline findings
|
|
217
|
+
and `acknowledge` for top-level comments or review summaries. Rate valid feedback
|
|
218
|
+
positively and explain false or stale findings on their actual review surface.
|
|
219
|
+
After each push, request the reviewers again and wait for terminal results;
|
|
220
|
+
provider quota or skipped reviews are limitations, not approvals. Before merge,
|
|
221
|
+
run `inventory` once more to catch new or edited feedback, and require all
|
|
222
|
+
findings to have an explicit disposition.
|
|
223
|
+
|
|
198
224
|
## Documentation Rules for Agents
|
|
199
225
|
|
|
200
226
|
- Keep [README](../README.md) short.
|
|
@@ -205,6 +231,16 @@ for the release contract.
|
|
|
205
231
|
- Link docs back to the active item with `pm docs`.
|
|
206
232
|
- Do not link public docs to ignored local operations artifacts or private evidence logs.
|
|
207
233
|
|
|
234
|
+
## Scheduling and Handoff
|
|
235
|
+
|
|
236
|
+
Read [SDK execution contracts](SDK_EXECUTION_CONTRACTS.md) before building an
|
|
237
|
+
agent work allocator. Use `next` and `claim --next` for executable work; inspect
|
|
238
|
+
`decision_needed`, `gate_needed`, and `containers` when no recommendation is
|
|
239
|
+
available. Only opt into those buckets when the current task calls for them.
|
|
240
|
+
Use `pause-task` to stop work; `release` alone preserves in-progress status.
|
|
241
|
+
Context summary totals describe the matching population, while `returned_focus`
|
|
242
|
+
describes the bounded selection.
|
|
243
|
+
|
|
208
244
|
## Safe Defaults
|
|
209
245
|
|
|
210
246
|
Use these defaults unless the task requires otherwise:
|
|
@@ -10,7 +10,9 @@ 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). Stable Claude session
|
|
14
|
+
discovery across child working directories is tracked by
|
|
15
|
+
[pm-l7m7k5](../.agents/pm/issues/pm-l7m7k5.toon). Cross-harness adapters and
|
|
14
16
|
operator-managed probe/vocabulary controls are tracked by
|
|
15
17
|
[pm-c0lrdm](../.agents/pm/features/pm-c0lrdm.toon) and
|
|
16
18
|
[pm-yds9dt](../.agents/pm/chores/pm-yds9dt.toon).
|
|
@@ -56,7 +58,13 @@ from literal descriptor keys, trusted caller data, or a named bounded resolver.
|
|
|
56
58
|
Detection does not spawn processes, traverse process trees, evaluate user
|
|
57
59
|
regexes, or access the network. The built-in Claude and Codex resolvers read
|
|
58
60
|
only bounded windows of the current session's harness-owned JSONL file. Claude
|
|
59
|
-
|
|
61
|
+
resolves an explicitly supplied transcript first, then the direct workspace
|
|
62
|
+
coordinate, then performs a deterministic scan of at most 512 immediate
|
|
63
|
+
project directories for the unique stable session id. This keeps provenance
|
|
64
|
+
attached when the invocation cwd moves into a child package. No match is
|
|
65
|
+
reported as `resolver_input_missing`; multiple matches are ambiguous and remain
|
|
66
|
+
`resolver_failed` instead of selecting an arbitrary transcript. Claude uses the
|
|
67
|
+
bounded session window to recover its recorded model/version. Codex uses the
|
|
60
68
|
recent tail plus a bounded initial-head fallback for oversized sessions to
|
|
61
69
|
recover allow-listed `turn_context.model` and `turn_context.effort` values.
|
|
62
70
|
Both cap traversal, file bytes, lines, and line length, ignore all other fields,
|
|
@@ -70,6 +78,13 @@ the existing domain-separated, truncated `agent_instance` digest. Public
|
|
|
70
78
|
telemetry continues to use installation-scoped hashes or presence booleans; it
|
|
71
79
|
does not export raw provenance values.
|
|
72
80
|
|
|
81
|
+
Health counts resolvers with an available input, plus failed or ambiguous
|
|
82
|
+
resolution attempts, as attempts. A sustained attempted-but-zero-success series
|
|
83
|
+
remains advisory: it truthfully identifies parser, filesystem, ambiguity, or
|
|
84
|
+
provider-shape drift without treating missing descriptive metadata as
|
|
85
|
+
authorization or item-state corruption. Missing-input and probes-disabled
|
|
86
|
+
events are classified separately and do not inflate that warning.
|
|
87
|
+
|
|
73
88
|
## Compatibility
|
|
74
89
|
|
|
75
90
|
All new history fields are optional. Readers must accept:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Context Integrity Contracts
|
|
2
2
|
|
|
3
|
-
Tracker references: [pm-4fwgaz](../.agents/pm/issues/pm-4fwgaz.toon), [pm-qqoumq](../.agents/pm/issues/pm-qqoumq.toon), [pm-fpdk37](../.agents/pm/issues/pm-fpdk37.toon), [pm-jn1x30](../.agents/pm/issues/pm-jn1x30.toon),
|
|
3
|
+
Tracker references: [pm-4fwgaz](../.agents/pm/issues/pm-4fwgaz.toon), [pm-qqoumq](../.agents/pm/issues/pm-qqoumq.toon), [pm-fpdk37](../.agents/pm/issues/pm-fpdk37.toon), [pm-jn1x30](../.agents/pm/issues/pm-jn1x30.toon), [pm-0wfdim](../.agents/pm/issues/pm-0wfdim.toon), [pm-javbsq](../.agents/pm/issues/pm-javbsq.toon), and [pm-aka8m7](../.agents/pm/issues/pm-aka8m7.toon).
|
|
4
4
|
|
|
5
5
|
## Agent Quick Context
|
|
6
6
|
|
|
@@ -53,6 +53,43 @@ History writers using item-hash epoch 2 always emit `item_hash_version: 2`. An e
|
|
|
53
53
|
|
|
54
54
|
Repair keeps implicit legacy streams implicit and byte-stable when no drift exists. Unsupported explicit epochs still fail with a typed `unsupported_item_hash_version` diagnostic instead of being rewritten.
|
|
55
55
|
|
|
56
|
+
| Writer/runtime range | Item-hash output | Read contract |
|
|
57
|
+
| ---------------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
58
|
+
| Legacy writers before an explicit marker | implicit epoch 1 | Modern readers retain legacy canonicalization candidates. |
|
|
59
|
+
| Observed 2026.8.24 through 2026.8.28 | explicit epoch 2 | Modern readers accept both field-frozen and expanded epoch-2 forms without mixing forms inside one entry. |
|
|
60
|
+
| 2026.8.31 and newer | explicit epoch 3 | Exact pins and bounded ranges that cannot select an epoch-3 reader cause current runtimes to reject the write before mutation. |
|
|
61
|
+
|
|
62
|
+
The table records confirmed release boundaries rather than inventing an exact
|
|
63
|
+
first release for legacy epoch 1 or epoch 2. The SDK exports
|
|
64
|
+
`HISTORY_ITEM_HASH_VERSION_3_INTRODUCED_IN`, and runtime compatibility checks
|
|
65
|
+
use that boundary for package-manager-neutral write refusal.
|
|
66
|
+
|
|
67
|
+
## Whole-Record History Integrity
|
|
68
|
+
|
|
69
|
+
Item anchors prove the replayed project state; they do not prove who recorded an
|
|
70
|
+
event, when it happened, which operation produced it, or which provenance and
|
|
71
|
+
context were attached. New events therefore use a separate record-integrity
|
|
72
|
+
epoch. `record_hash_version: 1` seals every immutable field while preserving the
|
|
73
|
+
item-hash epoch as an independent compatibility contract.
|
|
74
|
+
|
|
75
|
+
`verifyHistoryRecordHash()` reports `record_and_item_state` for a valid sealed
|
|
76
|
+
event and `item_state_only` for a legacy event with neither record-envelope
|
|
77
|
+
field. Half-present, unsupported, and mismatched envelopes fail closed. The
|
|
78
|
+
public SDK also exports the record and patch hashing, sealing,
|
|
79
|
+
`verifyHistoryRewriteEvidence()`, rewrite-resealing, stream-digest, and
|
|
80
|
+
reanchoring primitives so packages and embedded hosts do not need private core
|
|
81
|
+
imports or their own canonicalization.
|
|
82
|
+
|
|
83
|
+
Maintenance retains prior anchors and patch digests in `reanchor_evidence`.
|
|
84
|
+
When policy permits, it also retains the exact prior sealed record so
|
|
85
|
+
metadata-only rewrites remain independently verifiable. Privacy-sensitive
|
|
86
|
+
redaction and provenance normalization deliberately retain digest-only evidence
|
|
87
|
+
instead of embedding the removed value. This separates two claims: the current
|
|
88
|
+
chain is replay-consistent, and a rewrite preserved evidence of what it
|
|
89
|
+
replaced. Compaction records a digest of its pruned prefix and explicitly states
|
|
90
|
+
that individual pruned entries require the pre-compaction stream; it never
|
|
91
|
+
upgrades intentional information loss into a stronger assurance claim.
|
|
92
|
+
|
|
56
93
|
## Verification Boundary
|
|
57
94
|
|
|
58
95
|
The regression suite covers each contract at its public SDK or command boundary. Release verification additionally installs the packed package into a temporary project and exercises sparse reads, remote docs, graph impact, extension diagnostics, and history repair without touching the repository tracker.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# History durability and recovery
|
|
2
|
+
|
|
3
|
+
Tracked by [pm-96fsma](../.agents/pm/issues/pm-96fsma.toon),
|
|
4
|
+
[pm-m0yjtg](../.agents/pm/issues/pm-m0yjtg.toon),
|
|
5
|
+
[pm-qw1uw6](../.agents/pm/issues/pm-qw1uw6.toon),
|
|
6
|
+
[pm-e3gn0z](../.agents/pm/issues/pm-e3gn0z.toon), and
|
|
7
|
+
[pm-wlqxg3](../.agents/pm/tasks/pm-wlqxg3.toon).
|
|
8
|
+
|
|
9
|
+
Project management depends on trustworthy context. History is not just an
|
|
10
|
+
activity feed: it is the reconstructable source for prior item states, including
|
|
11
|
+
their evidence, relationships, and lifecycle transitions. Recovery must not
|
|
12
|
+
manufacture missing context or silently change an item's identity.
|
|
13
|
+
|
|
14
|
+
## Stable addresses after compaction
|
|
15
|
+
|
|
16
|
+
`pm get <id> --at <version>` and `pm restore <id> <version>` use durable,
|
|
17
|
+
one-based version addresses. Compaction checkpoints the last compacted state
|
|
18
|
+
at its original version. Retained entries keep their addresses, including after
|
|
19
|
+
repeated compactions. Versions before the checkpoint fail with
|
|
20
|
+
`history_version_pruned`; they never select a different retained entry.
|
|
21
|
+
|
|
22
|
+
The checkpoint records `history_compaction.version_offset`. Add that offset to
|
|
23
|
+
a physical one-based stream position to obtain its durable version. `pm history`
|
|
24
|
+
reports `version_addressing`, and compact rows include their `version` alongside
|
|
25
|
+
the physical `index`. Verification error ordinals and diff indices remain
|
|
26
|
+
physical positions in the current stream. The checkpoint timestamp is the last
|
|
27
|
+
compacted entry's timestamp; the maintenance audit event records compaction time.
|
|
28
|
+
|
|
29
|
+
Legacy checkpoints without a recorded offset cannot prove their original
|
|
30
|
+
numeric addresses. Numeric reads fail with `history_version_mapping_unavailable`.
|
|
31
|
+
Use a retained timestamp instead; the SDK then returns `as_of_version: null`.
|
|
32
|
+
SDK consumers must handle this nullable value. `target.historyIndex` is always
|
|
33
|
+
the resolved physical zero-based position, not an original version number.
|
|
34
|
+
Default and timestamp-based compaction remain available for these legacy
|
|
35
|
+
streams. They preserve an unknown offset as `null`, including no-op results;
|
|
36
|
+
compaction never manufactures a numeric mapping from physical positions.
|
|
37
|
+
|
|
38
|
+
## Recover an unreadable item file
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pm history <id> --full
|
|
42
|
+
pm restore <id> <version>
|
|
43
|
+
pm history <id> --verify --strict-exit
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Restore accepts an absent file or an unparsable item document when intact
|
|
47
|
+
history can reconstruct it. It verifies the history before using the recovered
|
|
48
|
+
state, preserves the original unreadable bytes for rollback, and uses the normal
|
|
49
|
+
ownership and lock checks. Successful recovery reports
|
|
50
|
+
`restore_unreadable_item_recovered`. Permission errors and unresolved merge
|
|
51
|
+
conflicts are not treated as missing files. A missing initial baseline returns
|
|
52
|
+
`history_baseline_unavailable` with recovery guidance rather than inventing
|
|
53
|
+
metadata from a partial patch.
|
|
54
|
+
|
|
55
|
+
CLI shape errors name the item ID, file path, and zero-length files. The SDK
|
|
56
|
+
error context also includes byte length and an explicit empty-file flag.
|
|
57
|
+
`pm health --check-only` names malformed item paths and invalid
|
|
58
|
+
history lines without mutating either file; use those diagnostics to select the
|
|
59
|
+
specific recovery operation above.
|
|
60
|
+
|
|
61
|
+
Invalid UTF-8 is a separate refusal (`item_document_encoding_invalid`), not a
|
|
62
|
+
recoverable text parse failure. Preserve a binary backup before recovering such
|
|
63
|
+
a file; text decoding must never silently replace original bytes.
|
|
64
|
+
Its SDK error context identifies the item ID, path, byte length, and nonempty
|
|
65
|
+
state just as text-shape diagnostics do.
|
|
66
|
+
|
|
67
|
+
## Recover an invalid history tail
|
|
68
|
+
|
|
69
|
+
Keep a local backup before applying destructive history maintenance. Preview
|
|
70
|
+
exactly one stream, inspect the receipt, then explicitly apply:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pm history-repair <id> --salvage-tail --dry-run --json
|
|
74
|
+
pm history-repair <id> --salvage-tail --json
|
|
75
|
+
pm history <id> --verify --strict-exit
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Salvage requires a nonempty, hash-verified prefix and retains its bytes unchanged.
|
|
79
|
+
The receipt records the first invalid physical line, discarded UTF-8 byte count,
|
|
80
|
+
discarded-suffix SHA-256, and retained record count. An appended `history_salvage`
|
|
81
|
+
event records that receipt without copying potentially private damaged contents.
|
|
82
|
+
Salvage does not rehash prior entries, reconcile item state, or normalize
|
|
83
|
+
provenance. It refuses bulk selection, conflicting repair modes, merge conflict
|
|
84
|
+
markers, parseable records after corruption, and potentially complete records
|
|
85
|
+
with attached corruption. Recover those cases from version control or a backup.
|
|
86
|
+
Non-UTF-8 streams are also refused, so receipt hashes and rollback snapshots
|
|
87
|
+
always describe the original bytes rather than a lossy decoded approximation.
|
|
88
|
+
|
|
89
|
+
The public SDK uses the same operation:
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import { PmClient } from "@unbrained/pm-cli";
|
|
93
|
+
|
|
94
|
+
const client = new PmClient({ pmRoot: "/project/.agents/pm" });
|
|
95
|
+
const preview = await client.historyRepair("pm-example", {
|
|
96
|
+
salvageTail: true,
|
|
97
|
+
dryRun: true,
|
|
98
|
+
});
|
|
99
|
+
console.log(preview.salvage);
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The CLI and MCP expose this SDK-owned contract; package authors do not need a
|
|
103
|
+
separate recovery implementation.
|
|
104
|
+
|
|
105
|
+
## Permanent item identities
|
|
106
|
+
|
|
107
|
+
Deleting an item retains its identity reservation through its history file.
|
|
108
|
+
Generated IDs skip those reservations, even under reproducible execution.
|
|
109
|
+
Explicit recreation fails with `item_identity_reserved`; use restore to recover
|
|
110
|
+
the original subject, or create a new ID for unrelated work.
|
|
111
|
+
The first `create` append exclusively creates its effective history file, so
|
|
112
|
+
concurrent SDK callers and extension redirects cannot both reserve it. A failed
|
|
113
|
+
partial first write keeps the reservation for diagnosis; it is never deleted
|
|
114
|
+
to make the identity reusable. Subsequent large-record appenders still need the
|
|
115
|
+
normal item lock or an equivalent caller-owned serialization boundary.
|
|
116
|
+
|
|
117
|
+
Verification refuses a second `create` event, including one imported through
|
|
118
|
+
branch union, and names both physical ordinals. Point-in-time reads cannot cross
|
|
119
|
+
that discontinuity silently. Recover the original streams rather than rehashing
|
|
120
|
+
two unrelated subjects into a single supposedly valid item.
|
|
121
|
+
|
|
122
|
+
`pm validate --check-history-drift` reports this as an error, with item ID,
|
|
123
|
+
original and repeated genesis ordinals, and the observed sequence. The public
|
|
124
|
+
`findHistoryIdentityDiscontinuities` SDK primitive provides the same evidence
|
|
125
|
+
for importers. A delete followed by create is distinguished from multiple creates
|
|
126
|
+
or a checkpoint followed by create; these observations do not prove which
|
|
127
|
+
writer or branch introduced the records. Old drift caches are invalidated, and
|
|
128
|
+
known-invalid streams are reread even in metadata-cache mode.
|
|
129
|
+
|
|
130
|
+
## Regression verification
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
node scripts/run-tests.mjs test -- tests/integration/history-durability.integration.spec.ts
|
|
134
|
+
node scripts/run-tests.mjs test -- tests/integration/history-maintenance-replay.integration.spec.ts
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The fixture drives real CLI lifecycle mutations, independently captures each
|
|
138
|
+
serialized state, removes the live item file, and compares every addressable
|
|
139
|
+
version against those captures. Companion cases exercise repeated compaction,
|
|
140
|
+
legacy mapping refusal, seeded identity reuse, invalid-tail preservation,
|
|
141
|
+
unreadable-file recovery, and missing baselines. Maintenance fixtures additionally
|
|
142
|
+
perform redaction and a real divergent Git merge, compare every version with an
|
|
143
|
+
independent strict patch fold, and compare the final state with a separately
|
|
144
|
+
read item. Concurrent writes and binary corruption are negative controls, not
|
|
145
|
+
mocked successful outcomes. All fixtures use temporary trackers, never repository
|
|
146
|
+
tracker data.
|