pi-smart-compact 7.22.0 → 8.0.0-rc.2
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/CHANGELOG.md +53 -0
- package/README.md +174 -55
- package/dist/app/compaction-commit-store.d.ts +19 -0
- package/dist/app/compaction-commit-store.d.ts.map +1 -0
- package/dist/app/mode-policy.d.ts +29 -0
- package/dist/app/mode-policy.d.ts.map +1 -0
- package/dist/app/native-continuity-bridge.d.ts +18 -0
- package/dist/app/native-continuity-bridge.d.ts.map +1 -0
- package/dist/app/pending-slot.d.ts +6 -63
- package/dist/app/pending-slot.d.ts.map +1 -1
- package/dist/app/run-context.d.ts +19 -6
- package/dist/app/run-context.d.ts.map +1 -1
- package/dist/app/run-smart-compact.d.ts +11 -3
- package/dist/app/run-smart-compact.d.ts.map +1 -1
- package/dist/app/session-run-lock.d.ts +21 -0
- package/dist/app/session-run-lock.d.ts.map +1 -0
- package/dist/app/stage-auth.d.ts +3 -0
- package/dist/app/stage-auth.d.ts.map +1 -0
- package/dist/app/steps/extract.d.ts.map +1 -1
- package/dist/app/steps/metrics.d.ts +3 -0
- package/dist/app/steps/metrics.d.ts.map +1 -1
- package/dist/app/steps/persist.d.ts +15 -15
- package/dist/app/steps/persist.d.ts.map +1 -1
- package/dist/app/steps/prepare.d.ts.map +1 -1
- package/dist/app/steps/state.d.ts.map +1 -1
- package/dist/app/steps/synthesize.d.ts.map +1 -1
- package/dist/app/steps/verify.d.ts.map +1 -1
- package/dist/app/steps/window.d.ts +1 -1
- package/dist/app/steps/window.d.ts.map +1 -1
- package/dist/constants.d.ts +13 -4
- package/dist/constants.d.ts.map +1 -1
- package/dist/domain/provider-evaluation.d.ts +49 -0
- package/dist/domain/provider-evaluation.d.ts.map +1 -0
- package/dist/domain/summary-parse.d.ts.map +1 -1
- package/dist/domain/telemetry.d.ts +69 -0
- package/dist/domain/telemetry.d.ts.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3398 -500
- package/dist/infra/context-graph.d.ts +53 -0
- package/dist/infra/context-graph.d.ts.map +1 -0
- package/dist/infra/fs.d.ts +9 -8
- package/dist/infra/fs.d.ts.map +1 -1
- package/dist/infra/llm-client.d.ts +8 -8
- package/dist/infra/llm-client.d.ts.map +1 -1
- package/dist/infra/paths.d.ts +9 -1
- package/dist/infra/paths.d.ts.map +1 -1
- package/dist/infra/services.d.ts +40 -22
- package/dist/infra/services.d.ts.map +1 -1
- package/dist/infra/synthesis-cache.d.ts +19 -0
- package/dist/infra/synthesis-cache.d.ts.map +1 -0
- package/dist/phases/explore.d.ts +4 -4
- package/dist/phases/explore.d.ts.map +1 -1
- package/dist/phases/synthesize.d.ts +5 -5
- package/dist/phases/synthesize.d.ts.map +1 -1
- package/dist/phases/verify.d.ts +5 -5
- package/dist/phases/verify.d.ts.map +1 -1
- package/dist/provider-eval.js +1073 -0
- package/dist/provider-scenario-eval.js +1442 -0
- package/dist/telemetry-report.js +1139 -0
- package/dist/types.d.ts +86 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/dashboard-format.d.ts.map +1 -1
- package/dist/ui/dashboard-insights.d.ts +62 -0
- package/dist/ui/dashboard-insights.d.ts.map +1 -0
- package/dist/ui/metrics-report.d.ts +5 -2
- package/dist/ui/metrics-report.d.ts.map +1 -1
- package/dist/ui/overlays.d.ts +6 -4
- package/dist/ui/overlays.d.ts.map +1 -1
- package/dist/utils/cache.d.ts +5 -3
- package/dist/utils/cache.d.ts.map +1 -1
- package/dist/utils/damage.d.ts +1 -1
- package/dist/utils/damage.d.ts.map +1 -1
- package/dist/utils/helpers.d.ts.map +1 -1
- package/dist/utils/state.d.ts +13 -1
- package/dist/utils/state.d.ts.map +1 -1
- package/dist/utils/tokens.d.ts +7 -18
- package/dist/utils/tokens.d.ts.map +1 -1
- package/dist/utils/type-guards.d.ts.map +1 -1
- package/docs/MIGRATING_TO_V8.md +105 -0
- package/docs/RELEASE.md +102 -22
- package/docs/provider-evaluation-2026-08-06.md +63 -0
- package/package.json +10 -5
- package/dist/infra/llm-retry.d.ts +0 -46
- package/dist/infra/llm-retry.d.ts.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [Unreleased]
|
|
4
|
+
|
|
5
|
+
No changes yet.
|
|
6
|
+
|
|
7
|
+
## [8.0.0-rc.2] - 2026-08-06
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Durable state, fingerprint, context graph, and success telemetry now commit only after a run-id-correlated native `session_compact`; cancellation, failure, shutdown, and stale generations leave no false success state.
|
|
12
|
+
- Semantic verification detects negated/conditional goal, decision, and constraint inversions, inconsistent blocker placeholders, unresolved-error omissions, and fabricated files; deterministic quality-floor replacement is coverage-aware.
|
|
13
|
+
- Canary promotion now requires ≥85 absolute quality, ≥95% success, and ≥70% run-correlated damage-observation coverage in stable and canary cohorts; Data Confidence and Quality Health remain separate.
|
|
14
|
+
- Provider accounting includes uncached input plus cache reads/writes and reserves concurrent/failed-stream output; cross-process 0600 leases enforce the global run limit.
|
|
15
|
+
- Smart Memory requires real interactive host confirmation, treats recall as untrusted evidence, preserves/deduplicates project-scoped manual facts, and bounds structural graph nodes.
|
|
16
|
+
- Zero-call planning rejects token-dense/tool-heavy windows; synthesis caches include every behavior-affecting route/profile/thinking limit; unused route auth resolves lazily; retention protects the two newest user turns.
|
|
17
|
+
- Provider evaluation uses only explicitly stage-local pre-repair synthesis quality instead of copying one final verifier score into every route.
|
|
18
|
+
- Native continuity survives reload/process gaps in a bounded, locked project/session/branch-scoped handoff; apply-confirmed context-graph indexing is deferred and coalesced off the host compaction hook.
|
|
19
|
+
- Backup retention/restoration ignores foreign files in custom directories, filesystem locks fail closed, and atomic-write documentation no longer claims unimplemented fsync durability.
|
|
20
|
+
- Production runs share only bounded provider capability/token-calibration knowledge; transient probe failures cannot poison the capability cache. Removed the unused automatic LLM retry wrapper.
|
|
21
|
+
|
|
22
|
+
## [8.0.0-rc.1] - 2026-08-06
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- **Adaptive modes** — `/smart-compact` and the tool now support `auto`, `balanced`, `aggressive`, `fast`, and `thorough` execution policies with finite call and prompt-token ceilings plus observed output-token stop thresholds. Legacy `light` remains a `thorough` alias.
|
|
27
|
+
- **Continuity Ledger** — previous verified summaries and bounded structured state now carry goals, decisions, constraints, unresolved errors, and open loops forward until explicit resolution.
|
|
28
|
+
- **Aggregate prompt budget** — every LLM request reserves estimated input centrally and reconciles against provider usage; `--max-input-tokens` / `max_input_tokens` can override the mode ceiling.
|
|
29
|
+
- **Codex hybrid output limiter** — custom Codex endpoints receive `max_output_tokens`; ChatGPT subscription Codex uses a configurable per-call stream watchdog and visible-output ceiling because its endpoint rejects all server-side output-cap fields.
|
|
30
|
+
- **Smart Recall context graph** — consumed verified state is indexed into a project-isolated, 2,000-node SQLite FTS5 graph with file-reference edges, weighted same-session/branch retrieval, active fact resolution, and bounded `smart_recall` results.
|
|
31
|
+
- **Explicit project memory** — `smart_save_memory` stores deduplicated, user-confirmed durable facts after configured secret/PII scrubbing; `contextGraphEnabled` disables indexing and both memory tools.
|
|
32
|
+
- **Stage-aware provider routing** — Explore, Synthesis, and Verify can use independent explicitly configured models; all default to the selected model and mode changes never reroute providers.
|
|
33
|
+
- **Provider evaluation harness** — schema-v2 per-stage telemetry feeds an advisory context-pressure × tool-density matrix, plus an explicit paid-API scenario probe; neither path edits routing automatically.
|
|
34
|
+
- **Privacy-safe canary telemetry** — aggregate-only exports omit conversation/session/project data, failures use a stable content-free taxonomy, and explicit stable/canary tags drive Hold/Rollback/Promote gates for quality, failures, latency, tokens, fallback, and damage.
|
|
35
|
+
- **Dashboard trust UX** — TUI/text/HTML surfaces now show an auditable Data Confidence score (≥85 target), quality bands and repair gain, stage/provider/model evidence with quality coverage, stable-vs-canary deltas, rollback triggers, and failure taxonomy.
|
|
36
|
+
- **Session-aware run control** — same-session runs serialize, different sessions share a bounded global concurrency of two, pending state is TTL/LRU bounded, and synthesis caches key by session/branch/model/mode.
|
|
37
|
+
- **Native continuity bridge** — after Pi native compaction, scoped continuity is delivered exactly once at the next agent start instead of being lost or repeatedly injected.
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- **Runaway token consumption** — compaction windows now use Pi's active, compaction-aware entries instead of re-summarizing append-only session history. Retained tokens are re-counted after anchor/tool-call boundary expansion; non-viable automatic windows fall back to native compaction before any LLM call.
|
|
42
|
+
- **Repeated staged runs** — a same-session pending summary is reused rather than regenerated.
|
|
43
|
+
- **Unbounded LLM amplification** — safe defaults now use at most 8 calls, 3 exploration rounds, minimal per-phase reasoning, no automatic whole-request retries, explicit exploration output caps, and prompt caching for the growing exploration loop.
|
|
44
|
+
- **Calibration skew** — request calibration includes system/tools and cached prompt tokens instead of calibrating message text against incomplete usage.
|
|
45
|
+
- **Oversized synthesis chunks** — `maxChunkTokens` is now enforced by splitting large semantic segments; batch output budgets match the requested 2–4 sentence summaries instead of allocating 1,500 tokens per chunk.
|
|
46
|
+
- **Cross-generation context loss** — absent prior facts are no longer interpreted as deleted; cumulative state is conservatively merged and bounded.
|
|
47
|
+
- **Cross-session/branch contamination** — continuity state now carries project/session/branch ancestry scope with Branch > Session > Project precedence; legacy project-wide state is not injected into unrelated work.
|
|
48
|
+
- **Post-compaction false positives** — one normal file re-read or topic mention no longer counts as damage; repeated re-reads and explicit correction language remain actionable signals.
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
|
|
52
|
+
- High-confidence Fast/Aggressive runs can use zero-call deterministic synthesis; the verifier replaces lower-scoring model output with a deterministic quality floor, and Auto planning escalates from continuity/prior-damage risk.
|
|
53
|
+
- Recent-tail retention scales with model context, preserves the two newest user turns when enough history exists, and validates mode-specific post-compaction headroom.
|
|
54
|
+
- Refreshed the development lockfile to Pi `0.84.0`, TypeBox `1.3.11`, and `@types/node` `26.1.2` while preserving Pi host packages as wildcard-only peer dependencies.
|
|
55
|
+
|
|
3
56
|
## [7.22.0] - 2026-07-15
|
|
4
57
|
|
|
5
58
|
### Added
|
package/README.md
CHANGED
|
@@ -31,9 +31,9 @@ pi install git:github.com/alpertarhan/pi-smart-compact
|
|
|
31
31
|
## Quick start
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
|
-
/smart-compact # interactive model +
|
|
35
|
-
/smart-compact
|
|
36
|
-
/smart-compact anthropic/claude-sonnet-4
|
|
34
|
+
/smart-compact # interactive model + mode picker
|
|
35
|
+
/smart-compact auto # adaptive default
|
|
36
|
+
/smart-compact anthropic/claude-sonnet-4 fast # direct model + mode
|
|
37
37
|
/smart-compact balanced --focus=auth # preserve extra auth detail
|
|
38
38
|
/smart-compact metrics # text metrics report
|
|
39
39
|
/smart-compact dashboard # interactive metrics dashboard
|
|
@@ -43,7 +43,7 @@ pi install git:github.com/alpertarhan/pi-smart-compact
|
|
|
43
43
|
|
|
44
44
|
The extension also participates in Pi's native compaction flow automatically
|
|
45
45
|
when actual context usage crosses the configured threshold (60% by default),
|
|
46
|
-
and exposes
|
|
46
|
+
and exposes `smart_compact`, `smart_recall`, and `smart_save_memory` tools for long-running agents.
|
|
47
47
|
|
|
48
48
|
> The tool path stages a safe pending summary. It never compacts the active
|
|
49
49
|
> conversation in the middle of an agent turn.
|
|
@@ -57,6 +57,7 @@ and exposes a `smart_compact` tool for long-running agents.
|
|
|
57
57
|
| File/error omissions can be silent | Verifies coverage and repairs known gaps |
|
|
58
58
|
| One strategy for every session | Chooses single-pass or hierarchical synthesis |
|
|
59
59
|
| No quality feedback | Tracks provenance, damage signals, and metrics |
|
|
60
|
+
| No scoped cross-session recall | Searches a project-isolated SQLite FTS5 context graph |
|
|
60
61
|
|
|
61
62
|
The design principle is simple:
|
|
62
63
|
|
|
@@ -81,9 +82,9 @@ Pi conversation
|
|
|
81
82
|
| Stage | Responsibility |
|
|
82
83
|
| --- | --- |
|
|
83
84
|
| **Extract** | Deterministically catalogs files, errors, decisions, constraints, topics, media metadata, and open loops. This is the verification ground truth. |
|
|
84
|
-
| **Explore** |
|
|
85
|
-
| **Synthesize** | Uses
|
|
86
|
-
| **Verify** |
|
|
85
|
+
| **Explore** | Runs only in `thorough` mode (or when `auto` selects it); cheaper modes use deterministic boundaries. |
|
|
86
|
+
| **Synthesize** | Uses adaptive single-pass or bounded hierarchical synthesis with per-mode call, prompt-token, chunk, and output budgets. |
|
|
87
|
+
| **Verify** | Always applies deterministic repairs. Only `thorough` may spend one additional LLM call on unresolved gaps. |
|
|
87
88
|
|
|
88
89
|
### What survives compaction
|
|
89
90
|
|
|
@@ -94,47 +95,131 @@ Pi conversation
|
|
|
94
95
|
- Open follow-ups, blockers, priorities, and pinned loops
|
|
95
96
|
- Next actions and critical continuation context
|
|
96
97
|
- Changes since the previous compaction
|
|
98
|
+
- A bounded **Continuity Ledger** carrying prior decisions, constraints, unresolved errors, and open loops until explicit resolution
|
|
97
99
|
|
|
98
100
|
Summaries use a canonical H1/H2/H3-aware structure, collision-safe file
|
|
99
101
|
matching, typed verification gaps, and persisted repair provenance.
|
|
100
102
|
|
|
103
|
+
### Smart Recall
|
|
104
|
+
|
|
105
|
+
Applied compactions also index their verified scoped state into a bounded,
|
|
106
|
+
project-isolated SQLite FTS5 context graph. `smart_recall` searches goals,
|
|
107
|
+
decisions, constraints, unresolved errors, open loops, files, and critical
|
|
108
|
+
context across this project's sessions; same-session and same-branch evidence
|
|
109
|
+
ranks first. File relationships add one-hop graph recall without an embedding
|
|
110
|
+
service or extra LLM call.
|
|
111
|
+
|
|
112
|
+
`smart_save_memory` persists or explicitly resolves one user-confirmed decision,
|
|
113
|
+
constraint, preference, warning, procedure, or context fact. It rejects empty inputs,
|
|
114
|
+
scrubs configured secrets/PII, deduplicates exact facts, and must not be used
|
|
115
|
+
for guesses, transient progress, secrets, or code that is cheap to re-read.
|
|
116
|
+
Set `contextGraphEnabled` to `false` to disable indexing and both tools.
|
|
117
|
+
|
|
101
118
|
## Usage surfaces
|
|
102
119
|
|
|
103
120
|
| Surface | Behavior |
|
|
104
121
|
| --- | --- |
|
|
105
122
|
| `/smart-compact` | Explicit manual run. Supports picker UI, direct args, dry-run, focus, and budgets. |
|
|
106
|
-
| `session_before_compact` | Auto path.
|
|
123
|
+
| `session_before_compact` | Auto path. Returns/stages a verification-scored summary under pressure; durable state waits for matching `session_compact`. |
|
|
107
124
|
| `smart_compact` tool | Agent path. Produces a pending summary for Pi's next natural compact; does not compact mid-turn. |
|
|
108
125
|
| `/smart-compact loops` | Project-level open-loop manager: resolve/reopen, priority, pin/unpin. |
|
|
109
126
|
|
|
110
127
|
### Focus and budgets
|
|
111
128
|
|
|
112
129
|
```bash
|
|
113
|
-
/smart-compact
|
|
114
|
-
/smart-compact aggressive --max-
|
|
115
|
-
/smart-compact
|
|
130
|
+
/smart-compact auto --focus=authentication
|
|
131
|
+
/smart-compact aggressive --max-input-tokens=120000
|
|
132
|
+
/smart-compact fast --focus=src/auth.ts --max-calls=3
|
|
133
|
+
/smart-compact thorough
|
|
116
134
|
```
|
|
117
135
|
|
|
118
136
|
- `--focus` assigns more synthesis/exploration budget to a topic or path. It
|
|
119
137
|
does **not** attempt unsupported non-contiguous compaction.
|
|
120
138
|
- `--max-calls` accepts `1–100`.
|
|
121
|
-
- `--max-
|
|
122
|
-
-
|
|
123
|
-
|
|
139
|
+
- `--max-input-tokens` accepts `10000–1000000` aggregate prompt tokens.
|
|
140
|
+
- `--max-latency` accepts `5000–600000` milliseconds as an explicit hard override; mode latency targets are otherwise soft.
|
|
141
|
+
- Budget exhaustion degrades to deterministic summaries instead of dropping context.
|
|
142
|
+
|
|
143
|
+
The tool exposes equivalent `focus`, `max_calls`, `max_input_tokens`, and
|
|
144
|
+
`max_latency_ms` parameters.
|
|
145
|
+
|
|
146
|
+
## Modes
|
|
147
|
+
|
|
148
|
+
| Mode | Calls | Prompt cap | Output cap | Behavior |
|
|
149
|
+
| --- | ---: | ---: | ---: | --- |
|
|
150
|
+
| `auto` | adaptive | adaptive | adaptive | Default; selects from context pressure and deterministic session risk |
|
|
151
|
+
| `balanced` | 6 | 200K | 40K | Token/continuity balance; deterministic boundaries and repair |
|
|
152
|
+
| `aggressive` | 4 | 120K | 25K | Maximum context recovery with a 3K summary and 10K live tail |
|
|
153
|
+
| `fast` | 3 | 100K | 20K | Favors larger single-pass windows and minimum waiting |
|
|
154
|
+
| `thorough` (`slow` alias) | 8 | 300K | 80K | Maximum fidelity; enables Explore and one optional LLM repair |
|
|
155
|
+
|
|
156
|
+
Fast and aggressive modes use a zero-call deterministic summary when extraction confidence is high; otherwise they keep the bounded LLM path. Auto planning also raises fidelity when scoped continuity or prior damage indicates risk. Recent-tail retention scales with model context while preserving the two newest user turns when enough history exists.
|
|
124
157
|
|
|
125
|
-
|
|
126
|
-
|
|
158
|
+
Output caps stop subsequent calls after observed usage reaches the threshold.
|
|
159
|
+
The ChatGPT Codex subscription endpoint rejects `max_output_tokens`,
|
|
160
|
+
`max_tokens`, and `max_completion_tokens`; Smart Compact therefore enforces a
|
|
161
|
+
15–90 second per-call watchdog plus a streamed visible-output ceiling and falls
|
|
162
|
+
back deterministically on abort. Custom Codex endpoints receive
|
|
163
|
+
`max_output_tokens` through Pi AI's payload hook.
|
|
127
164
|
|
|
128
|
-
|
|
165
|
+
Legacy compression profiles remain as advanced/backwards-compatible policy:
|
|
166
|
+
`light` maps to `thorough`; `balanced` and `aggressive` map to their same-named
|
|
167
|
+
modes. The selected model never changes automatically.
|
|
129
168
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
169
|
+
### Stage-aware provider routing
|
|
170
|
+
|
|
171
|
+
All stages use the selected Pi model by default. Routing is explicit and
|
|
172
|
+
independent of modes:
|
|
173
|
+
|
|
174
|
+
| Stage | Config key | Default |
|
|
175
|
+
|---|---|---|
|
|
176
|
+
| Explore / segmentation | `segmentationModel` | selected model |
|
|
177
|
+
| Synthesis / assembly | `summaryModel` | selected model |
|
|
178
|
+
| Verification repair | `verificationModel` | summary/selected model |
|
|
179
|
+
|
|
180
|
+
Every run persists per-stage provider, model, reliability, latency, and token
|
|
181
|
+
telemetry with schema-versioned verifier quality. `bun run provider-eval`
|
|
182
|
+
builds an advisory matrix by context pressure and tool density; it never edits
|
|
183
|
+
configuration or selects a model. Legacy rows contribute operational evidence
|
|
184
|
+
but not quality because old verifier score semantics are incompatible.
|
|
185
|
+
|
|
186
|
+
A reproducible paid-API probe is opt-in only:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
bun run provider-eval:live --live \
|
|
190
|
+
--models=openai/gpt-5.4,anthropic/claude-sonnet-4-6
|
|
191
|
+
```
|
|
135
192
|
|
|
136
|
-
|
|
137
|
-
|
|
193
|
+
It runs three bounded, identical coding-continuity scenarios and reports
|
|
194
|
+
verification score, latency, and token usage. Apply a route manually only after
|
|
195
|
+
representative evidence. See the dated [provider evaluation baseline](./docs/provider-evaluation-2026-08-06.md).
|
|
196
|
+
|
|
197
|
+
### Privacy-safe telemetry and canary gates
|
|
198
|
+
|
|
199
|
+
Raw local JSONL remains available to the interactive dashboard, while
|
|
200
|
+
`bun run telemetry-report` emits aggregate-only telemetry: no session/project
|
|
201
|
+
IDs, prompts, summaries, paths, or error text. Failures use a stable taxonomy
|
|
202
|
+
(cancelled, timeout, rate limit, authentication, budget, output limit,
|
|
203
|
+
provider, persistence, validation, internal).
|
|
204
|
+
|
|
205
|
+
Set `telemetryChannel` to `canary` only on the externally selected canary
|
|
206
|
+
cohort. The report compares schema-v2 canary runs with the stable baseline and
|
|
207
|
+
returns `HOLD`, `ROLLBACK`, or `PROMOTE`. Rollback triggers are: failure rate
|
|
208
|
+
+5pp and ≥10%, verifier quality −5 points, p95 latency +50%, tokens +50%,
|
|
209
|
+
heuristic fallback +10pp, or post-compaction damage +10pp. Promotion requires
|
|
210
|
+
at least 20 canary runs, a stable baseline, ≥70% verifier-quality coverage,
|
|
211
|
+
≥70% run-correlated damage-observation coverage in both cohorts, ≥85 absolute
|
|
212
|
+
canary quality, and ≥95% success. The extension reports the decision; it never
|
|
213
|
+
edits config or deploys automatically.
|
|
214
|
+
|
|
215
|
+
The interactive and HTML dashboards make trust evidence explicit: a **Data
|
|
216
|
+
Confidence** score (target ≥85) combines recent sample size (25 points),
|
|
217
|
+
schema-v2 coverage (25), verifier-quality coverage (20), field completeness
|
|
218
|
+
(20), and seven-day freshness (10). Separate views show repair gain and quality
|
|
219
|
+
bands, stage/provider/model reliability with quality coverage, stable-vs-canary
|
|
220
|
+
deltas, rollback triggers, and the failure taxonomy. Low confidence is shown as
|
|
221
|
+
low—not silently filled from incompatible legacy scores—and includes concrete
|
|
222
|
+
guidance for reaching the target.
|
|
138
223
|
|
|
139
224
|
## Safety and privacy
|
|
140
225
|
|
|
@@ -147,7 +232,8 @@ focus hints, damage feedback, and explicit budgets refine the actual run.
|
|
|
147
232
|
- Mandatory deterministic repair for patchable verification gaps
|
|
148
233
|
- Cross-session guard and five-minute TTL for pending summaries
|
|
149
234
|
- Session-log recovery for older, truncated tool results
|
|
150
|
-
-
|
|
235
|
+
- Marker-owned retention-pruned backups before compaction; foreign files in a
|
|
236
|
+
custom directory are untouched
|
|
151
237
|
|
|
152
238
|
### Secrets and PII
|
|
153
239
|
|
|
@@ -155,7 +241,7 @@ High-confidence secret scrubbing is enabled by default at every relevant trust
|
|
|
155
241
|
boundary:
|
|
156
242
|
|
|
157
243
|
```text
|
|
158
|
-
provider request · extraction cache · backup · state · pending summary
|
|
244
|
+
provider request · extraction cache · backup · state · context graph · pending summary
|
|
159
245
|
```
|
|
160
246
|
|
|
161
247
|
It covers common API keys, cloud/GitHub/Slack tokens, JWTs, bearer tokens,
|
|
@@ -169,11 +255,14 @@ handling or a dedicated DLP system**. See the
|
|
|
169
255
|
### Approval and feedback
|
|
170
256
|
|
|
171
257
|
- `requireApproval: true` adds a fail-closed manual **Apply / Cancel** decision
|
|
172
|
-
after the provenance review screen.
|
|
173
|
-
|
|
258
|
+
after the provenance review screen. Every path stages first; fingerprint,
|
|
259
|
+
continuity state, context graph, and success telemetry commit only after the
|
|
260
|
+
host confirms the matching native `session_compact` event.
|
|
174
261
|
- Online damage monitoring observes the first post-compaction messages and
|
|
175
|
-
records re-read files or repeated context.
|
|
176
|
-
|
|
262
|
+
records re-read files or repeated context. Observations join the originating
|
|
263
|
+
compaction by a local run id; missing evidence lowers coverage rather than
|
|
264
|
+
counting as a clean run. Remediation hints feed affected files into the next
|
|
265
|
+
compaction.
|
|
177
266
|
- `adaptiveDamageFeedback` can opt a project into larger preservation budgets
|
|
178
267
|
after repeated high-damage reports.
|
|
179
268
|
|
|
@@ -199,20 +288,27 @@ Add `smartCompact` to `~/.pi/agent/settings.json`:
|
|
|
199
288
|
```json
|
|
200
289
|
{
|
|
201
290
|
"smartCompact": {
|
|
291
|
+
"mode": "auto",
|
|
202
292
|
"profile": "balanced",
|
|
203
293
|
"summaryModel": null,
|
|
204
294
|
"segmentationModel": null,
|
|
205
|
-
"
|
|
206
|
-
"
|
|
295
|
+
"verificationModel": null,
|
|
296
|
+
"summaryThinkingLevel": "minimal",
|
|
297
|
+
"segmentationThinkingLevel": "minimal",
|
|
207
298
|
"autoTrigger": true,
|
|
208
299
|
"minContextPercent": 60,
|
|
209
300
|
"backupEnabled": true,
|
|
210
301
|
"scrubSecrets": true,
|
|
211
302
|
"scrubPii": false,
|
|
212
303
|
"requireApproval": false,
|
|
213
|
-
"maxLlmCalls":
|
|
304
|
+
"maxLlmCalls": 8,
|
|
305
|
+
"maxLlmInputTokens": 0,
|
|
306
|
+
"codexMaxCallMs": 0,
|
|
214
307
|
"maxLatencyMs": 0,
|
|
215
308
|
"focusWeighting": true,
|
|
309
|
+
"zeroCallEnabled": true,
|
|
310
|
+
"contextGraphEnabled": true,
|
|
311
|
+
"telemetryChannel": "stable",
|
|
216
312
|
"onlineDamageMonitor": true,
|
|
217
313
|
"adaptiveDamageFeedback": false,
|
|
218
314
|
"pinPaths": []
|
|
@@ -235,21 +331,35 @@ use a stronger one:
|
|
|
235
331
|
```
|
|
236
332
|
|
|
237
333
|
`segmentationThinkingLevel` applies to exploration; `summaryThinkingLevel`
|
|
238
|
-
applies to synthesis, assembly, and repair.
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
334
|
+
applies to synthesis, assembly, and repair. Both default to `minimal` because
|
|
335
|
+
reasoning tokens from multi-call compaction add up quickly. Supported values
|
|
336
|
+
are `minimal`, `low`, `medium`, `high`, `xhigh`, and `max`. Set either value to
|
|
337
|
+
`null` to restore the provider's default behavior. An explicit call-level
|
|
338
|
+
reasoning option takes precedence.
|
|
339
|
+
|
|
340
|
+
### Cost safeguards
|
|
341
|
+
|
|
342
|
+
Automatic and tool-triggered runs operate on Pi's current active context, not
|
|
343
|
+
the append-only session history. A same-session staged summary is reused, the
|
|
344
|
+
exploration loop is limited to three rounds, provider and outer retries are
|
|
345
|
+
disabled, and every mode has finite call plus aggregate prompt-token budgets.
|
|
346
|
+
If anchor/tool-call
|
|
347
|
+
protection leaves too much live context to get below the configured trigger,
|
|
348
|
+
Smart Compact spends no LLM tokens and lets Pi's native compactor handle it.
|
|
349
|
+
Manual `/smart-compact` remains an explicit force path.
|
|
242
350
|
|
|
243
351
|
<details>
|
|
244
352
|
<summary><strong>All configuration keys</strong></summary>
|
|
245
353
|
|
|
246
354
|
| Key | Type | Default | Notes |
|
|
247
355
|
| --- | --- | --- | --- |
|
|
248
|
-
| `
|
|
356
|
+
| `mode` | `auto \| balanced \| aggressive \| fast \| thorough` | `auto` | User-facing execution preset |
|
|
357
|
+
| `profile` | `light \| balanced \| aggressive` | `balanced` | Legacy/advanced compression profile; used when mode is absent |
|
|
249
358
|
| `summaryModel` | `string \| null` | `null` | Uses the active session model when null |
|
|
250
|
-
| `segmentationModel` | `string \| null` | `null` | Optional
|
|
251
|
-
| `
|
|
252
|
-
| `
|
|
359
|
+
| `segmentationModel` | `string \| null` | `null` | Optional explicit model for Explore |
|
|
360
|
+
| `verificationModel` | `string \| null` | `null` | Optional explicit model for LLM verification repair |
|
|
361
|
+
| `summaryThinkingLevel` | `minimal \| low \| medium \| high \| xhigh \| max \| null` | `minimal` | Reasoning level for synthesis and repair; provider default when null |
|
|
362
|
+
| `segmentationThinkingLevel` | `minimal \| low \| medium \| high \| xhigh \| max \| null` | `minimal` | Reasoning level for exploration; provider default when null |
|
|
253
363
|
| `autoTrigger` | `boolean` | `true` | Participate in Pi's native compact hook |
|
|
254
364
|
| `autoTriggerTimeoutMs` | `number` | `120000` | Hard timeout for automatic runs |
|
|
255
365
|
| `minContextPercent` | `number` | `60` | Actual context usage gate |
|
|
@@ -260,9 +370,14 @@ option takes precedence over these defaults.
|
|
|
260
370
|
| `requireApproval` | `boolean` | `false` | Manual UI only; cancel/error fails closed |
|
|
261
371
|
| `scrubSecrets` | `boolean` | `true` | High-confidence credential redaction |
|
|
262
372
|
| `scrubPii` | `boolean` | `false` | Email/phone/card-shaped redaction |
|
|
263
|
-
| `maxLlmCalls` | integer `0–100` | `
|
|
373
|
+
| `maxLlmCalls` | integer `0–100` | `8` | Global ceiling combined with the selected mode |
|
|
374
|
+
| `maxLlmInputTokens` | integer `0–1000000` | `0` | `0` uses the selected mode's aggregate prompt-token cap |
|
|
375
|
+
| `codexMaxCallMs` | integer `0` or `5000–300000` | `0` | ChatGPT Codex per-call watchdog; `0` derives 15–90s from requested output tokens |
|
|
264
376
|
| `maxLatencyMs` | `0` or `5000–600000` | `0` | `0` means unlimited |
|
|
265
377
|
| `focusWeighting` | `boolean` | `true` | Weight focused topics/paths higher |
|
|
378
|
+
| `zeroCallEnabled` | `boolean` | `true` | Use deterministic synthesis for high-confidence fast/aggressive runs |
|
|
379
|
+
| `contextGraphEnabled` | `boolean` | `true` | Index verified state and enable project-scoped recall/save tools |
|
|
380
|
+
| `telemetryChannel` | `stable \| canary` | `stable` | Tag local schema-v2 metrics for external canary comparison |
|
|
266
381
|
| `onlineDamageMonitor` | `boolean` | `true` | Observe post-compaction regression signals |
|
|
267
382
|
| `adaptiveDamageFeedback` | `boolean` | `false` | Increase preservation after repeated damage |
|
|
268
383
|
|
|
@@ -277,37 +392,37 @@ The legacy `semanticCompact` root key is still accepted for compatibility.
|
|
|
277
392
|
|
|
278
393
|
```markdown
|
|
279
394
|
## Goal
|
|
280
|
-
|
|
395
|
+
Tighten aggregate token budgets without breaking cancellation.
|
|
281
396
|
|
|
282
397
|
## Constraints & Preferences
|
|
283
398
|
- [requirement] Never compact mid-turn from the tool path.
|
|
284
399
|
|
|
285
400
|
## Progress
|
|
286
401
|
### Done
|
|
287
|
-
- [x]
|
|
402
|
+
- [x] Reserved concurrent output budgets before provider calls.
|
|
288
403
|
### In Progress
|
|
289
|
-
- [ ]
|
|
404
|
+
- [ ] Collect canary evidence for the new limits.
|
|
290
405
|
### Blocked
|
|
291
406
|
- None.
|
|
292
407
|
|
|
293
408
|
## Key Decisions
|
|
294
|
-
- **
|
|
409
|
+
- **Charge failed streams conservatively**: an interrupted stream consumes its output reservation.
|
|
295
410
|
|
|
296
411
|
## Files Modified
|
|
297
|
-
- src/infra/
|
|
298
|
-
- src/
|
|
412
|
+
- src/infra/services.ts
|
|
413
|
+
- src/utils/cache.ts
|
|
299
414
|
|
|
300
415
|
## Open Loops
|
|
301
|
-
- [high]
|
|
416
|
+
- [high] Verify provider usage reconciliation across cache-read/write responses.
|
|
302
417
|
|
|
303
418
|
## Changes Since Last Compaction
|
|
304
|
-
-
|
|
419
|
+
- Concurrent output accounting now fails closed.
|
|
305
420
|
|
|
306
421
|
## Next Steps
|
|
307
|
-
1.
|
|
422
|
+
1. Run the adversarial release gate.
|
|
308
423
|
|
|
309
424
|
## Critical Context
|
|
310
|
-
-
|
|
425
|
+
- Input accounting includes uncached input, cache reads, and cache writes.
|
|
311
426
|
```
|
|
312
427
|
|
|
313
428
|
</details>
|
|
@@ -320,7 +435,7 @@ Add retry/backoff to the LLM client without breaking cancellation.
|
|
|
320
435
|
/smart-compact restore # browse, inspect, and restore backups
|
|
321
436
|
```
|
|
322
437
|
|
|
323
|
-
Metrics include
|
|
438
|
+
Metrics include effective mode, profile, provider, phase timing, token/call estimates,
|
|
324
439
|
verification quality, cache behavior, redactions, adaptation, fallbacks, and
|
|
325
440
|
cancelled runs.
|
|
326
441
|
|
|
@@ -332,12 +447,15 @@ All files live under `~/.pi/agent/`.
|
|
|
332
447
|
| Path | Purpose |
|
|
333
448
|
| --- | --- |
|
|
334
449
|
| `settings.json` | Configuration (read only) |
|
|
335
|
-
| `compact-backups/` |
|
|
450
|
+
| `compact-backups/` | Marker-owned retention-pruned conversation backups |
|
|
336
451
|
| `.cache/compact-extraction-<session>.json` | Incremental extraction cache |
|
|
337
452
|
| `.cache/compact-metrics.jsonl` | Tail-retained metrics log; 5 MiB cap |
|
|
338
453
|
| `.cache/smart-compact-report.html` | Local HTML dashboard |
|
|
339
454
|
| `.cache/smart-compact/projects/<projectId>.json` | Project fingerprint |
|
|
340
|
-
| `.cache/smart-compact/states/<projectId>.json` |
|
|
455
|
+
| `.cache/smart-compact/states/<projectId>/<sessionId>.json` | Scoped compaction state and loop overrides |
|
|
456
|
+
| `.cache/smart-compact/run-locks/` | 0600 cross-process session/global concurrency leases |
|
|
457
|
+
| `.cache/smart-compact/native-continuity/` | 0600 one-shot project/session/branch handoffs |
|
|
458
|
+
| `.cache/smart-compact/context-graph.sqlite` | Project-isolated FTS5 context graph and explicit saved memory |
|
|
341
459
|
| `.cache/smart-compact/damage-reports.jsonl` | Damage reports; 5 MiB cap |
|
|
342
460
|
| `.cache/smart-compact/remediation-<projectId>.json` | Files to preserve after damage |
|
|
343
461
|
|
|
@@ -378,6 +496,7 @@ the build in GitHub Actions.
|
|
|
378
496
|
- [Contributing](https://github.com/alpertarhan/pi-smart-compact/blob/main/CONTRIBUTING.md)
|
|
379
497
|
- [Security](https://github.com/alpertarhan/pi-smart-compact/blob/main/SECURITY.md)
|
|
380
498
|
- [Support](https://github.com/alpertarhan/pi-smart-compact/blob/main/SUPPORT.md)
|
|
499
|
+
- [v8 migration guide](https://github.com/alpertarhan/pi-smart-compact/blob/main/docs/MIGRATING_TO_V8.md)
|
|
381
500
|
- [Release checklist](https://github.com/alpertarhan/pi-smart-compact/blob/main/docs/RELEASE.md)
|
|
382
501
|
|
|
383
502
|
## License
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { PendingCompaction } from "../types.ts";
|
|
2
|
+
export type CommitDiscardReason = "expired" | "evicted" | "aborted" | "shutdown" | "apply-error";
|
|
3
|
+
export interface CompactionCommitStore {
|
|
4
|
+
stage(pending: PendingCompaction): void;
|
|
5
|
+
take(runId: string, sessionId: string): PendingCompaction | null;
|
|
6
|
+
discard(runId: string, reason: CommitDiscardReason): PendingCompaction | null;
|
|
7
|
+
clearSession(sessionId: string, reason?: CommitDiscardReason): PendingCompaction[];
|
|
8
|
+
size(): number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Holds summaries only between session_before_compact and session_compact.
|
|
12
|
+
* Nothing durable is written until `take()` confirms both run and session.
|
|
13
|
+
*/
|
|
14
|
+
export declare function createCompactionCommitStore(options?: {
|
|
15
|
+
ttlMs?: number;
|
|
16
|
+
maxEntries?: number;
|
|
17
|
+
onDiscard?: (pending: PendingCompaction, reason: CommitDiscardReason) => void;
|
|
18
|
+
}): CompactionCommitStore;
|
|
19
|
+
//# sourceMappingURL=compaction-commit-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compaction-commit-store.d.ts","sourceRoot":"","sources":["../../src/app/compaction-commit-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAOrD,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,aAAa,CAAC;AAEjG,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACxC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAAC;IACjE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,GAAG,iBAAiB,GAAG,IAAI,CAAC;IAC9E,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,mBAAmB,GAAG,iBAAiB,EAAE,CAAC;IACnF,IAAI,IAAI,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,GAAE;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;CAC1E,GAAG,qBAAqB,CAgE7B"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { CompactionMode, CompactionState, CompressionProfile, EffectiveCompactionMode, StructuredExtraction } from "../types.ts";
|
|
2
|
+
export interface ModePolicy {
|
|
3
|
+
profile: CompressionProfile;
|
|
4
|
+
maxLlmCalls: number;
|
|
5
|
+
maxInputTokens: number;
|
|
6
|
+
maxOutputTokens: number;
|
|
7
|
+
explore: boolean;
|
|
8
|
+
allowLlmPatch: boolean;
|
|
9
|
+
singlePassMultiplier: number;
|
|
10
|
+
batchOutput: {
|
|
11
|
+
min: number;
|
|
12
|
+
perChunk: number;
|
|
13
|
+
max: number;
|
|
14
|
+
};
|
|
15
|
+
softLatencyMs: number;
|
|
16
|
+
targetContextPercent: number;
|
|
17
|
+
}
|
|
18
|
+
export declare const MODE_POLICIES: Readonly<Record<EffectiveCompactionMode, ModePolicy>>;
|
|
19
|
+
export declare function modeFromLegacyProfile(profile: CompressionProfile): EffectiveCompactionMode;
|
|
20
|
+
/** Cheap preflight choice used before deterministic extraction is available. */
|
|
21
|
+
export declare function resolveMode(requested: CompactionMode, contextPercent: number, extraction?: StructuredExtraction, additionalRisk?: number): EffectiveCompactionMode;
|
|
22
|
+
export declare function deterministicExtractionConfidence(extraction: StructuredExtraction, context?: {
|
|
23
|
+
conversationTokens?: number;
|
|
24
|
+
toolPercent?: number;
|
|
25
|
+
}): number;
|
|
26
|
+
export declare function continuityRisk(state: CompactionState | null): number;
|
|
27
|
+
export declare function batchOutputLimit(mode: EffectiveCompactionMode, chunks: number, providerMax: number): number;
|
|
28
|
+
export declare function effectiveBudget(configured: number, modeDefault: number): number;
|
|
29
|
+
//# sourceMappingURL=mode-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mode-policy.d.ts","sourceRoot":"","sources":["../../src/app/mode-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EAAE,eAAe,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,oBAAoB,EACnG,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5D,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,uBAAuB,EAAE,UAAU,CAAC,CAqB/E,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,kBAAkB,GAAG,uBAAuB,CAE1F;AAED,gFAAgF;AAChF,wBAAgB,WAAW,CACzB,SAAS,EAAE,cAAc,EACzB,cAAc,EAAE,MAAM,EACtB,UAAU,CAAC,EAAE,oBAAoB,EACjC,cAAc,SAAI,GACjB,uBAAuB,CAezB;AAED,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,oBAAoB,EAChC,OAAO,GAAE;IAAE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAClE,MAAM,CAeR;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,GAAG,MAAM,CAOpE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,uBAAuB,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAG3G;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAG/E"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface NativeContinuityScope {
|
|
2
|
+
projectId: string;
|
|
3
|
+
sessionId: string;
|
|
4
|
+
branchHeadId: string;
|
|
5
|
+
}
|
|
6
|
+
export interface NativeContinuityBridge {
|
|
7
|
+
stage(scope: NativeContinuityScope, text: string): void;
|
|
8
|
+
take(scope: NativeContinuityScope): string | null;
|
|
9
|
+
clear(scope?: NativeContinuityScope): void;
|
|
10
|
+
size(): number;
|
|
11
|
+
}
|
|
12
|
+
export declare function createNativeContinuityBridge(opts?: {
|
|
13
|
+
ttlMs?: number;
|
|
14
|
+
maxEntries?: number;
|
|
15
|
+
now?: () => number;
|
|
16
|
+
dir?: string;
|
|
17
|
+
}): NativeContinuityBridge;
|
|
18
|
+
//# sourceMappingURL=native-continuity-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-continuity-bridge.d.ts","sourceRoot":"","sources":["../../src/app/native-continuity-bridge.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AASD,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,KAAK,EAAE,qBAAqB,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACxD,IAAI,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CAAC;IAClD,KAAK,CAAC,KAAK,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAC3C,IAAI,IAAI,MAAM,CAAC;CAChB;AAMD,wBAAgB,4BAA4B,CAAC,IAAI,GAAE;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACT,GAAG,sBAAsB,CAqG9B"}
|
|
@@ -1,46 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pending-compaction slot.
|
|
3
|
-
*
|
|
4
|
-
* A single-element, owner-private state cell that holds the *most recently
|
|
5
|
-
* prepared* `PendingCompaction` until the next `session_before_compact`
|
|
6
|
-
* event consumes it. Concurrency model:
|
|
7
|
-
*
|
|
8
|
-
* - One producer (`runSmartCompact` → `stagePendingCompaction`).
|
|
9
|
-
* - One consumer (`session_before_compact` event handler).
|
|
10
|
-
* - Single-threaded JS event loop; no atomic primitives needed.
|
|
11
|
-
*
|
|
12
|
-
* Design rationale — why an encapsulated factory instead of a mutable
|
|
13
|
-
* `{ value, createdAt }` ref-cell:
|
|
14
|
-
*
|
|
15
|
-
* 1. **Invariant centralization.** The "set → consume → clear" lifecycle
|
|
16
|
-
* lives in one file. Callers cannot accidentally null `value` without
|
|
17
|
-
* also resetting `createdAt`, nor can they read a `value` snapshot
|
|
18
|
-
* against a freshly-overwritten `createdAt` (the original bare-ref
|
|
19
|
-
* shape allowed this race; see B3 in code-review #3).
|
|
20
|
-
*
|
|
21
|
-
* 2. **Observable consume result.** `consume()` returns a discriminated
|
|
22
|
-
* union that records *why* a payload was rejected (empty / expired /
|
|
23
|
-
* session-mismatch). The previous helper folded all three into
|
|
24
|
-
* `null`, which hid information the caller might want to surface as
|
|
25
|
-
* metrics or differentiated notifications.
|
|
26
|
-
*
|
|
27
|
-
* 3. **Atomic snapshot.** Every consume path destructures a single
|
|
28
|
-
* `{ value, createdAt }` snapshot up front so the TTL and id checks
|
|
29
|
-
* operate on a coherent view, even if a future maintainer threads an
|
|
30
|
-
* `await` into the middle of the function.
|
|
31
|
-
*
|
|
32
|
-
* 4. **No host-context coupling.** The slot does NOT call
|
|
33
|
-
* `ctx.ui.notify` itself — the caller decides the UX (silent metric,
|
|
34
|
-
* toast, log line). This keeps the module pure / fully unit-testable
|
|
35
|
-
* without a fake host context.
|
|
36
|
-
*/
|
|
1
|
+
/** Session-scoped pending compaction store with TTL and bounded memory. */
|
|
37
2
|
import type { PendingCompaction } from "../types.ts";
|
|
38
3
|
import { type SessionIdentityContext } from "../infra/session-identity.ts";
|
|
39
|
-
/**
|
|
40
|
-
* Outcome of `PendingSlot.consume()`. Discriminated union so callers can
|
|
41
|
-
* react differently to each rejection reason (e.g. log a stale payload at
|
|
42
|
-
* `warn`, but a cross-session mismatch at `error`).
|
|
43
|
-
*/
|
|
44
4
|
export type ConsumeResult = {
|
|
45
5
|
kind: "ok";
|
|
46
6
|
pending: PendingCompaction;
|
|
@@ -54,35 +14,18 @@ export type ConsumeResult = {
|
|
|
54
14
|
expected: string;
|
|
55
15
|
actual: string;
|
|
56
16
|
};
|
|
57
|
-
/**
|
|
58
|
-
* Public surface of an owned pending-compaction slot. Producers call
|
|
59
|
-
* `set()` once they have a finished summary; consumers call `consume()` at
|
|
60
|
-
* the next compact boundary. `isPresent()` is a non-mutating peek used by
|
|
61
|
-
* the orchestrator for UI wording ("prepared, awaiting native /compact"
|
|
62
|
-
* vs. "run finished").
|
|
63
|
-
*/
|
|
64
17
|
export interface PendingSlot {
|
|
65
18
|
set(pending: PendingCompaction): void;
|
|
66
19
|
consume(ctx: SessionIdentityContext): ConsumeResult;
|
|
67
|
-
clear(): void;
|
|
68
|
-
isPresent(): boolean;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
* or running any guard checks. Intended for *display* paths (e.g. a tool
|
|
72
|
-
* response that wants to surface `tokensBefore` after a prepare-only run).
|
|
73
|
-
* Callers must NOT pass the returned payload to the host — only `consume`
|
|
74
|
-
* enforces the freshness + session-match invariants.
|
|
75
|
-
*/
|
|
76
|
-
peek(): Readonly<PendingCompaction> | null;
|
|
20
|
+
clear(sessionId?: string): void;
|
|
21
|
+
isPresent(sessionId?: string): boolean;
|
|
22
|
+
peek(sessionId?: string): Readonly<PendingCompaction> | null;
|
|
23
|
+
size(): number;
|
|
77
24
|
}
|
|
78
|
-
/**
|
|
79
|
-
* Optional injection seam for `Date.now`. Tests pass a fake clock so they
|
|
80
|
-
* can advance time without `await new Promise(setTimeout)`. Production
|
|
81
|
-
* callers omit this and get real wall-clock time.
|
|
82
|
-
*/
|
|
83
25
|
export interface PendingSlotOptions {
|
|
84
26
|
ttlMs: number;
|
|
85
27
|
now?: () => number;
|
|
28
|
+
maxEntries?: number;
|
|
86
29
|
}
|
|
87
30
|
export declare function createPendingSlot(opts: PendingSlotOptions): PendingSlot;
|
|
88
31
|
//# sourceMappingURL=pending-slot.d.ts.map
|