@compaction/cli 0.2.0 → 0.3.0
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/README.md +41 -12
- package/dist/cli/commands/activity.d.ts +8 -0
- package/dist/cli/commands/activity.js +35 -0
- package/dist/cli/commands/apply-context.js +68 -0
- package/dist/cli/commands/billing-delta.js +12 -1
- package/dist/cli/commands/capture-claude-code.d.ts +44 -0
- package/dist/cli/commands/capture-claude-code.js +206 -0
- package/dist/cli/commands/capture.js +283 -1
- package/dist/cli/commands/compact.js +9 -5
- package/dist/cli/commands/dev.d.ts +17 -0
- package/dist/cli/commands/dev.js +131 -0
- package/dist/cli/commands/gateway.d.ts +31 -0
- package/dist/cli/commands/gateway.js +312 -0
- package/dist/cli/commands/hooks.d.ts +5 -0
- package/dist/cli/commands/hooks.js +181 -0
- package/dist/cli/commands/init.js +422 -17
- package/dist/cli/commands/input-compaction-ab.d.ts +2 -0
- package/dist/cli/commands/input-compaction-ab.js +125 -0
- package/dist/cli/commands/optimize-hosted.d.ts +54 -0
- package/dist/cli/commands/optimize-hosted.js +123 -0
- package/dist/cli/commands/optimize.js +8 -0
- package/dist/cli/commands/output-shaping-ab.d.ts +2 -0
- package/dist/cli/commands/output-shaping-ab.js +132 -0
- package/dist/cli/commands/output-shaping.d.ts +7 -0
- package/dist/cli/commands/output-shaping.js +43 -0
- package/dist/cli/commands/policies.d.ts +2 -0
- package/dist/cli/commands/policies.js +80 -0
- package/dist/cli/commands/precall.d.ts +19 -0
- package/dist/cli/commands/precall.js +436 -0
- package/dist/cli/commands/recommend.js +1 -1
- package/dist/cli/commands/run.js +297 -12
- package/dist/cli/commands/upgrade-status.d.ts +42 -0
- package/dist/cli/commands/upgrade-status.js +152 -0
- package/dist/cli/cursor-export-read.d.ts +13 -0
- package/dist/cli/cursor-export-read.js +53 -0
- package/dist/cli/cursor-live-preflight.d.ts +19 -0
- package/dist/cli/cursor-live-preflight.js +46 -0
- package/dist/cli/index.js +36 -2
- package/dist/cli/onboarding/GatewayTui.d.ts +33 -0
- package/dist/cli/onboarding/GatewayTui.js +113 -0
- package/dist/cli/onboarding/model.d.ts +32 -1
- package/dist/cli/onboarding/model.js +27 -2
- package/dist/cli/terminal-logo.d.ts +27 -0
- package/dist/cli/terminal-logo.js +49 -0
- package/dist/core/activity-event.d.ts +107 -0
- package/dist/core/activity-event.js +182 -0
- package/dist/core/activity-store.d.ts +63 -0
- package/dist/core/activity-store.js +254 -0
- package/dist/core/activity-view.d.ts +76 -0
- package/dist/core/activity-view.js +120 -0
- package/dist/core/api-client/index.d.ts +3 -1
- package/dist/core/api-client/index.js +4 -0
- package/dist/core/api-client/payload.d.ts +5 -1
- package/dist/core/api-client/payload.js +8 -6
- package/dist/core/api-client/persisted-config.d.ts +57 -0
- package/dist/core/api-client/persisted-config.js +156 -0
- package/dist/core/api-client/tool.d.ts +29 -0
- package/dist/core/api-client/tool.js +50 -0
- package/dist/core/api-client/types.d.ts +15 -4
- package/dist/core/auto-apply-ask.d.ts +58 -0
- package/dist/core/auto-apply-ask.js +105 -0
- package/dist/core/auto-apply-gates.d.ts +76 -0
- package/dist/core/auto-apply-gates.js +113 -0
- package/dist/core/before-call-activity.d.ts +35 -0
- package/dist/core/before-call-activity.js +103 -0
- package/dist/core/before-call-recovery.d.ts +19 -0
- package/dist/core/before-call-recovery.js +46 -0
- package/dist/core/before-call-stdin.d.ts +59 -0
- package/dist/core/before-call-stdin.js +78 -0
- package/dist/core/before-call.d.ts +149 -0
- package/dist/core/before-call.js +358 -0
- package/dist/core/billing-delta/billing-delta-record.d.ts +28 -0
- package/dist/core/billing-delta/billing-delta-record.js +26 -0
- package/dist/core/capture-record.d.ts +40 -0
- package/dist/core/capture-record.js +55 -0
- package/dist/core/claude-code-before-call.d.ts +37 -0
- package/dist/core/claude-code-before-call.js +120 -0
- package/dist/core/claude-code-connect.d.ts +31 -0
- package/dist/core/claude-code-connect.js +87 -0
- package/dist/core/claude-code-hook-record.d.ts +71 -0
- package/dist/core/claude-code-hook-record.js +0 -0
- package/dist/core/claude-code-hooks.d.ts +77 -0
- package/dist/core/claude-code-hooks.js +141 -0
- package/dist/core/codex-capture.d.ts +45 -0
- package/dist/core/codex-capture.js +204 -0
- package/dist/core/command-runner.js +5 -1
- package/dist/core/compaction-artifacts.d.ts +51 -0
- package/dist/core/compaction-artifacts.js +242 -0
- package/dist/core/compactor.d.ts +9 -0
- package/dist/core/compactor.js +95 -0
- package/dist/core/cross-surface-event.d.ts +306 -0
- package/dist/core/cross-surface-event.js +330 -0
- package/dist/core/cursor-capture.d.ts +54 -0
- package/dist/core/cursor-capture.js +215 -0
- package/dist/core/cursor-preflight-probe.d.ts +8 -0
- package/dist/core/cursor-preflight-probe.js +88 -0
- package/dist/core/cursor-preflight.d.ts +86 -0
- package/dist/core/cursor-preflight.js +126 -0
- package/dist/core/gateway/apply-activation.d.ts +39 -0
- package/dist/core/gateway/apply-activation.js +84 -0
- package/dist/core/gateway/apply-policy.d.ts +64 -0
- package/dist/core/gateway/apply-policy.js +221 -0
- package/dist/core/gateway/apply-receipt.d.ts +36 -0
- package/dist/core/gateway/apply-receipt.js +75 -0
- package/dist/core/gateway/cache-proof.d.ts +45 -0
- package/dist/core/gateway/cache-proof.js +65 -0
- package/dist/core/gateway/configure.d.ts +50 -0
- package/dist/core/gateway/configure.js +169 -0
- package/dist/core/gateway/openai-usage.d.ts +56 -0
- package/dist/core/gateway/openai-usage.js +128 -0
- package/dist/core/gateway/receipt.d.ts +138 -0
- package/dist/core/gateway/receipt.js +120 -0
- package/dist/core/gateway/recovery.d.ts +23 -0
- package/dist/core/gateway/recovery.js +68 -0
- package/dist/core/gateway/server.d.ts +51 -0
- package/dist/core/gateway/server.js +276 -0
- package/dist/core/gateway/status.d.ts +45 -0
- package/dist/core/gateway/status.js +109 -0
- package/dist/core/hook-usage-aggregate.d.ts +47 -0
- package/dist/core/hook-usage-aggregate.js +161 -0
- package/dist/core/input-compaction-ab.d.ts +111 -0
- package/dist/core/input-compaction-ab.js +158 -0
- package/dist/core/local-run-record.d.ts +109 -0
- package/dist/core/local-run-record.js +223 -0
- package/dist/core/output-shaping-ab.d.ts +140 -0
- package/dist/core/output-shaping-ab.js +146 -0
- package/dist/core/output-shaping-attach.d.ts +31 -0
- package/dist/core/output-shaping-attach.js +57 -0
- package/dist/core/output-shaping.d.ts +56 -0
- package/dist/core/output-shaping.js +89 -0
- package/dist/core/policy-middleware.d.ts +121 -0
- package/dist/core/policy-middleware.js +919 -0
- package/dist/core/policy-preferences.d.ts +99 -0
- package/dist/core/policy-preferences.js +232 -0
- package/dist/core/run-aggregator.d.ts +11 -1
- package/dist/core/run-aggregator.js +29 -2
- package/dist/core/run-flow-report.d.ts +82 -0
- package/dist/core/run-flow-report.js +71 -0
- package/dist/core/safety-report.js +8 -1
- package/dist/core/shim-capture-bridge.d.ts +32 -0
- package/dist/core/shim-capture-bridge.js +88 -0
- package/dist/core/skill-injection-policy.d.ts +72 -0
- package/dist/core/skill-injection-policy.js +183 -0
- package/dist/core/spend-attribution.js +1 -1
- package/dist/core/token-accounting.d.ts +1 -1
- package/dist/core/tool-shim.d.ts +129 -0
- package/dist/core/tool-shim.js +447 -0
- package/dist/core/trace-parser.d.ts +13 -13
- package/dist/core/trace-parser.js +6 -6
- package/dist/core/types.d.ts +12 -2
- package/dist/core/waste-detector.d.ts +20 -0
- package/dist/core/waste-detector.js +160 -6
- package/package.json +1 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output-shaping policy family — deterministic, rule-based (PUBLIC CLI/SDK code, engine-free).
|
|
3
|
+
*
|
|
4
|
+
* Design: `docs/design/output-shaping-policy-family.md` (accepted; implementation authorized 2026-06-29).
|
|
5
|
+
* This is **increment 1**: the public/free deterministic policies that produce a CONTENT-FREE
|
|
6
|
+
* output-shaping **instruction block** to attach to a request **BEFORE generation** (the only mechanism
|
|
7
|
+
* that can reduce provider output tokens — post-generation processing does NOT).
|
|
8
|
+
*
|
|
9
|
+
* HONESTY (binding):
|
|
10
|
+
* - This module produces INSTRUCTIONS + attribution labels only. It computes **NO output-savings number**
|
|
11
|
+
* and makes **NO claim** that output was reduced. An output-savings number requires (separately, in the
|
|
12
|
+
* private/proprietary engine) a **measured A/B** (provider-reported output; N≥3/arm, ±2·SE excludes
|
|
13
|
+
* zero) **AND** the **eval-gated short-but-sufficient** check. Until both pass, savings are unavailable.
|
|
14
|
+
* - The short-but-sufficient **eval** (policy #6 in the design) is the **private eval-gated verification**
|
|
15
|
+
* — it is NOT in this public module; this module only emits the shaping instructions + their attribution.
|
|
16
|
+
* - Content-free: instructions are generic shaping text; no prompt/completion/trace content.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* The deterministic rule-based output-shaping policies (the public/free tier). The learned tier and the
|
|
20
|
+
* eval-gated verification are private/proprietary (Track A) — not here.
|
|
21
|
+
*/
|
|
22
|
+
export const OUTPUT_SHAPING_POLICIES = [
|
|
23
|
+
{
|
|
24
|
+
policy_name: "concise_response",
|
|
25
|
+
policy_family: "output_shaping",
|
|
26
|
+
risk_level: "low",
|
|
27
|
+
defaultOn: true,
|
|
28
|
+
description: "Ask for a concise answer where the task allows (no padding, no restating the prompt).",
|
|
29
|
+
instruction: () => "Answer concisely: omit preamble and restatement of the request; give only what the task needs."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
policy_name: "verbosity_budget",
|
|
33
|
+
policy_family: "output_shaping",
|
|
34
|
+
risk_level: "low",
|
|
35
|
+
defaultOn: true,
|
|
36
|
+
description: "Set a soft target on response length (a budget, not a hard cap).",
|
|
37
|
+
instruction: (budget) => typeof budget === "number" && budget > 0
|
|
38
|
+
? `Aim to stay within roughly ${budget} output tokens; prioritize the most task-relevant content if space is tight.`
|
|
39
|
+
: "Keep the response as short as is sufficient for the task; do not pad to fill space."
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
policy_name: "structured_output_constraints",
|
|
43
|
+
policy_family: "output_shaping",
|
|
44
|
+
risk_level: "low",
|
|
45
|
+
defaultOn: true,
|
|
46
|
+
description: "Prefer a bounded, structured format (lists/sections) that reduces filler.",
|
|
47
|
+
instruction: () => "Prefer a tight structured format (short bullets or labeled sections) over long prose where it fits the task."
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
policy_name: "redundant_chatter_suppression",
|
|
51
|
+
policy_family: "output_shaping",
|
|
52
|
+
risk_level: "low",
|
|
53
|
+
defaultOn: true,
|
|
54
|
+
description: "Suppress boilerplate, preamble, apologies, and repetition.",
|
|
55
|
+
instruction: () => "Skip boilerplate, apologies, and repetition; do not summarize what you just said."
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
policy_name: "safe_tool_output_filtering",
|
|
59
|
+
policy_family: "output_shaping",
|
|
60
|
+
// Slightly higher risk: trimming tool output can drop detail, so it is OFF by default and only
|
|
61
|
+
// requests omission of clearly-redundant tool echo — recoverability of task-critical detail first.
|
|
62
|
+
risk_level: "medium",
|
|
63
|
+
defaultOn: false,
|
|
64
|
+
description: "Request omission of clearly-redundant tool-output echo (recoverability preserved first).",
|
|
65
|
+
instruction: () => "Do not echo large tool outputs verbatim; reference them and include only the task-relevant lines."
|
|
66
|
+
}
|
|
67
|
+
];
|
|
68
|
+
/** Note attached to every emitted block: this is a request-shaping instruction, not a savings claim. */
|
|
69
|
+
export const OUTPUT_SHAPING_HONESTY_NOTE = "Attach BEFORE generation (post-generation processing does not reduce provider output tokens). " +
|
|
70
|
+
"No output-token savings are claimed: a savings figure requires a measured before/after (provider-reported) " +
|
|
71
|
+
"and eval-confirmed sufficiency — neither is asserted here.";
|
|
72
|
+
/**
|
|
73
|
+
* Build the content-free output-shaping instruction block + attribution from the deterministic family.
|
|
74
|
+
* Produces instructions only — NO savings number, NO claim of reduction.
|
|
75
|
+
*/
|
|
76
|
+
export function buildOutputShapingPolicy(opts = {}) {
|
|
77
|
+
const selected = opts.policies && opts.policies.length > 0
|
|
78
|
+
? OUTPUT_SHAPING_POLICIES.filter((p) => opts.policies.includes(p.policy_name))
|
|
79
|
+
: OUTPUT_SHAPING_POLICIES.filter((p) => p.defaultOn);
|
|
80
|
+
const lines = selected.map((p) => `- ${p.instruction(opts.verbosityBudgetTokens)}`);
|
|
81
|
+
const instructions = selected.length === 0
|
|
82
|
+
? ""
|
|
83
|
+
: ["Output-shaping policy (apply to your response):", ...lines].join("\n");
|
|
84
|
+
return {
|
|
85
|
+
instructions,
|
|
86
|
+
applied: selected.map((p) => ({ policy_name: p.policy_name, policy_family: p.policy_family, risk_level: p.risk_level }))
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=output-shaping.js.map
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { COMPACTION_POLICY_NAME, SKILL_INJECTION_POLICY_NAME, SUPPORTED_COMPACTION_POLICY_NAMES, isSupportedCompactionPolicyName } from "./policy-types.js";
|
|
2
|
+
import type { PolicyMiddlewareStateCapsule, ReplacedRange, ReplacementMode, SkillInjectionProvenance, SourcePointer, SupportedCompactionPolicyName } from "./policy-types.js";
|
|
3
|
+
import type { AgentTrace, CostEstimate, TokenEstimate, TraceMessage } from "./types.js";
|
|
4
|
+
export { COMPACTION_POLICY_NAME, SKILL_INJECTION_POLICY_NAME, SUPPORTED_COMPACTION_POLICY_NAMES, isSupportedCompactionPolicyName };
|
|
5
|
+
export type { PolicyMiddlewareStateCapsule, ReplacedRange, ReplacementMode, SkillInjectionProvenance, SourcePointer, SupportedCompactionPolicyName };
|
|
6
|
+
export interface CompactionPolicyThresholds {
|
|
7
|
+
minDuplicateTokens?: number;
|
|
8
|
+
minDuplicateCharacters?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface CompactionPolicyConfig {
|
|
11
|
+
policyName?: typeof COMPACTION_POLICY_NAME;
|
|
12
|
+
}
|
|
13
|
+
export interface PolicyMiddlewareInput {
|
|
14
|
+
trace?: AgentTrace;
|
|
15
|
+
messages?: TraceMessage[];
|
|
16
|
+
model?: string;
|
|
17
|
+
policy?: CompactionPolicyConfig;
|
|
18
|
+
thresholds?: CompactionPolicyThresholds;
|
|
19
|
+
/**
|
|
20
|
+
* APPROVAL-GATED (design §4). When true, ALSO apply the second policy
|
|
21
|
+
* `repeated_skill_injection_to_state_capsule`, compacting byte-identical same-skill later
|
|
22
|
+
* role:user skill injections into state capsules pointing at the first copy. DEFAULT false:
|
|
23
|
+
* with no approval this run compacts NO skill injections. This flag is set ONLY on explicit
|
|
24
|
+
* approval in optimization-approval.ts. There is NO auto-apply path that sets it unattended.
|
|
25
|
+
*/
|
|
26
|
+
compactSkillInjections?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface PolicyMiddlewareResult {
|
|
29
|
+
compactedTrace?: AgentTrace;
|
|
30
|
+
compactedMessages: TraceMessage[];
|
|
31
|
+
stateCapsules: PolicyMiddlewareStateCapsule[];
|
|
32
|
+
compactedMessageIds: string[];
|
|
33
|
+
tokenEstimateBefore: TokenEstimate;
|
|
34
|
+
tokenEstimateAfter: TokenEstimate;
|
|
35
|
+
tokensSaved: number;
|
|
36
|
+
costEstimateBefore: CostEstimate;
|
|
37
|
+
costEstimateAfter: CostEstimate;
|
|
38
|
+
savingsEstimate: number;
|
|
39
|
+
appliedPolicyName: typeof COMPACTION_POLICY_NAME;
|
|
40
|
+
/**
|
|
41
|
+
* Names of every policy that compacted at least one message in this run (design §Q1
|
|
42
|
+
* sequential composition). Always includes the tool-output policy name; additionally
|
|
43
|
+
* includes the skill-injection policy name when `compactSkillInjections` was enabled
|
|
44
|
+
* AND it compacted ≥1 byte-identical injection. Used by the safety report's
|
|
45
|
+
* supported-policy-set checks. Default (no approval) runs contain only the tool-output name.
|
|
46
|
+
*/
|
|
47
|
+
appliedPolicyNames: SupportedCompactionPolicyName[];
|
|
48
|
+
/** State capsules produced by the skill-injection policy only (disjoint from tool-output). */
|
|
49
|
+
skillInjectionCapsules: PolicyMiddlewareStateCapsule[];
|
|
50
|
+
safetyNotes: string[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Error thrown when the provenance-completeness write-time invariant is violated.
|
|
54
|
+
* See `docs/ops/provenance-completeness-invariant.md`.
|
|
55
|
+
*/
|
|
56
|
+
export declare class ProvenanceCompletenessError extends Error {
|
|
57
|
+
constructor(message: string);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Provenance-completeness write-boundary guard (design: docs/ops/provenance-completeness-invariant.md).
|
|
61
|
+
*
|
|
62
|
+
* Invariant: `compaction_changed_content ⟹ provenance_present`. The "content actually
|
|
63
|
+
* changed" trigger is derived by comparing each original message's payload against the final
|
|
64
|
+
* compacted payload (`diffMessagesByContent`) — NOT from `compactedMessageIds` collected
|
|
65
|
+
* from the capsules. Deriving the trigger from the capsules is tautological: if a regressed
|
|
66
|
+
* path drops/empties the capsule provenance while STILL replacing message content, the
|
|
67
|
+
* capsule-derived id set goes empty and the guard would no-op, missing exactly the
|
|
68
|
+
* changed-but-zero-provenance case it exists to reject. Comparing real content instead means a
|
|
69
|
+
* replaced message is "changed" regardless of whether any capsule exists for it.
|
|
70
|
+
*
|
|
71
|
+
* When content changed (by either real content change OR a capsule-claimed compacted id — the
|
|
72
|
+
* union, so no existing check is weakened), EVERY changed message id MUST have a covering state
|
|
73
|
+
* capsule, AND EVERY changed message MUST carry `metadata.compaction` with a resolvable
|
|
74
|
+
* `rawSourcePointer` + content hash (mirrors the required recoverability checks in
|
|
75
|
+
* safety-report.ts). On violation, FAIL CLOSED: throw, so a changed-but-zero/incomplete-provenance
|
|
76
|
+
* result can never be emitted as a silent no-op the eval harness cannot distinguish from a true no-op.
|
|
77
|
+
*
|
|
78
|
+
* The content-change comparison runs over `max(original.length, compacted.length)` positions
|
|
79
|
+
* (`diffMessagesByContent`) and enforces the COMPLETE honest-writer invariant: a 1:1 id-preserving
|
|
80
|
+
* positional map of original→compacted. A position with the SAME id whose content was replaced is a
|
|
81
|
+
* coverable change; ANYTHING that is not 1:1 id-preserving is a STRUCTURAL divergence that can carry
|
|
82
|
+
* no covering provenance and fails the guard closed — a DROPPED position (original present, compacted
|
|
83
|
+
* absent), an ADDED position (compacted present, original absent), AND a same-length position whose
|
|
84
|
+
* compacted id differs from the original id at that slot (a swap/substitution/duplication, i.e. one
|
|
85
|
+
* original dropped and a different id inserted at equal length). The last case is rejected BEFORE the
|
|
86
|
+
* id-based checks precisely because a capsule/metadata that exists for the DISPLACING id sources from
|
|
87
|
+
* a different original and can never make the displaced original recoverable. This closes the
|
|
88
|
+
* previously-missed cases where a regressed writer silently DROPS a message, or keeps the array length
|
|
89
|
+
* while substituting/duplicating an id, and the surviving capsules/ids happen to cover the wrong id.
|
|
90
|
+
*
|
|
91
|
+
* This is a NO-OP for every honest run: the shipped writer co-produces a covering capsule and
|
|
92
|
+
* `metadata.compaction` (with rawSourcePointer + contentSha256) for every compacted span, so
|
|
93
|
+
* every content-changed id is fully covered. The guard only fires on a regressed/malformed/
|
|
94
|
+
* hand-constructed path. `originalMessages` is optional for backward compatibility; when omitted,
|
|
95
|
+
* the guard falls back to the capsule-derived ids alone (the pre-hardening behavior).
|
|
96
|
+
*
|
|
97
|
+
* OCCURRENCE-AWARE COVERAGE — HASH BINDING (closes the shared-id residual, 2026-06-15). Message
|
|
98
|
+
* ids are NON-UNIQUE (a Claude turn's text + tool_use blocks share one id). A malformed
|
|
99
|
+
* same-length output can DROP one shared-id position and DUPLICATE the other into its slot: every
|
|
100
|
+
* position still has a matching id (the structural check passes, since both share the id), and the
|
|
101
|
+
* displaced position carries the duplicate's valid metadata, so an id-keyed coverage check is
|
|
102
|
+
* satisfied by a capsule belonging to a DIFFERENT occurrence while the displaced original stays
|
|
103
|
+
* unrecoverable. Merely COUNTING distinct covering capsules per id is ALSO insufficient (Codex P2,
|
|
104
|
+
* PR #280): a malformed output can keep BOTH shared-id capsules present (count satisfied) yet
|
|
105
|
+
* duplicate one occurrence's compacted message + metadata into the other's slot. To close this,
|
|
106
|
+
* when `originalMessages` is provided the coverage is matched per OCCURRENCE BY ORIGINAL-CONTENT
|
|
107
|
+
* HASH: each changed POSITION p (index + id, original payload P_orig) is bound to a DISTINCT,
|
|
108
|
+
* not-yet-consumed capsule whose `sourcePointer.contentSha256` hashes to the content that capsule
|
|
109
|
+
* replaced at p (whole P_orig for a whole-message capsule, a replaced sub-range of P_orig for an
|
|
110
|
+
* embedded one), AND p's OWN `metadata.compaction` pointer must hash to that same original. A
|
|
111
|
+
* shared-id duplication fails because the displaced slot's pointer hashes to a DIFFERENT
|
|
112
|
+
* occurrence's payload, not to its own original, so it FAILS CLOSED; an honest duplicate-id
|
|
113
|
+
* compaction (two messages sharing an id, each its own hash-correct capsule) still PASSES. The
|
|
114
|
+
* honest writer emits, per compacted target, exactly one capsule + metadata whose contentSha256 is
|
|
115
|
+
* that target's original payload hash, so every changed position binds 1:1 — a true no-op. (Binding
|
|
116
|
+
* is by original-content HASH, not by `sourcePointer.messageIndex`, which records the SOURCE payload
|
|
117
|
+
* index, not the changed/target position — an index match would break honest whole-message/embedded
|
|
118
|
+
* runs.)
|
|
119
|
+
*/
|
|
120
|
+
export declare function assertProvenanceCompleteness(compactedMessages: TraceMessage[], stateCapsules: PolicyMiddlewareStateCapsule[], compactedMessageIds: string[], originalMessages?: TraceMessage[]): void;
|
|
121
|
+
export declare function applyCompactionPolicy(input: PolicyMiddlewareInput): PolicyMiddlewareResult;
|