ds4-context-engine 0.3.0-alpha.2 → 0.3.0-alpha.4
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 +5 -4
- package/docs/COMPACTION.md +4 -2
- package/docs/CONTEXT_PERSISTENCE_TOOL.md +18 -16
- package/docs/DOGFOODING_0.3.0_ALPHA.md +4 -3
- package/docs/releases/0.3.0-alpha.1.md +1 -1
- package/docs/releases/0.3.0-alpha.2.md +4 -3
- package/docs/releases/0.3.0-alpha.3.md +60 -0
- package/docs/releases/0.3.0-alpha.4.md +59 -0
- package/package.json +2 -2
- package/src/extension/context-persistence-contract.ts +21 -10
- package/src/pi-adapter/compaction-coordinator.ts +2 -2
- package/src/pi-adapter/summary-generator.ts +13 -4
- package/src/pi-adapter/version.ts +1 -1
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ bounded active context with provenance
|
|
|
16
16
|
Pi provider
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
> **Project status:** Stable `0.2.0` includes M0–M20 and frozen 0.2 contracts.
|
|
19
|
+
> **Project status:** Stable `0.2.0` includes M0–M20 and frozen 0.2 contracts. Published prerelease `0.3.0-alpha.3` adds privacy-safe exact-value repair diagnostics and tighter summary prompting while preserving strict compaction validation, Pi fallback, canonical records, SQLite schema 15, and runtime contracts. npm `alpha` points to `0.3.0-alpha.3`, `latest` remains `0.2.0`, and the maintenance line targets Pi `0.84.3`.
|
|
20
20
|
|
|
21
21
|
## Why DS4
|
|
22
22
|
|
|
@@ -92,7 +92,7 @@ The stable `0.2.0` packages (`ds4-context-engine`, `ds4-context-core`, and `ds4-
|
|
|
92
92
|
To dogfood the published alpha without replacing a global stable installation, pin it in a disposable project:
|
|
93
93
|
|
|
94
94
|
```bash
|
|
95
|
-
pi install -l npm:ds4-context-engine@0.3.0-alpha.
|
|
95
|
+
pi install -l npm:ds4-context-engine@0.3.0-alpha.3
|
|
96
96
|
```
|
|
97
97
|
|
|
98
98
|
Follow the [0.3 alpha dogfooding runbook](docs/DOGFOODING_0.3.0_ALPHA.md); use synthetic data and a dedicated session directory.
|
|
@@ -416,7 +416,7 @@ npm run schema:context-persistence
|
|
|
416
416
|
npm run latency:check -- /path/to/exact/ds4-context-core@0.1.2
|
|
417
417
|
npm run pack:check
|
|
418
418
|
# Post-publication, with an exact version rather than a dist-tag:
|
|
419
|
-
npm run registry:check -- 0.3.0-alpha.
|
|
419
|
+
npm run registry:check -- 0.3.0-alpha.3
|
|
420
420
|
npm pack --dry-run
|
|
421
421
|
npm pack --dry-run --workspace ds4-context-core
|
|
422
422
|
npm pack --dry-run --workspace ds4-context-reference-adapter
|
|
@@ -468,6 +468,7 @@ scripts package and release-readiness checks
|
|
|
468
468
|
- [0.2.0 release readiness](docs/RELEASE_READINESS_0.2.0.md)
|
|
469
469
|
- [0.2.0 release notes](docs/releases/0.2.0.md)
|
|
470
470
|
- [0.2.0-rc.1 release notes](docs/releases/0.2.0-rc.1.md)
|
|
471
|
+
- [0.3.0-alpha.3 prerelease notes](docs/releases/0.3.0-alpha.3.md)
|
|
471
472
|
- [0.3.0-alpha.2 prerelease notes](docs/releases/0.3.0-alpha.2.md)
|
|
472
473
|
- [0.3.0-alpha.1 prerelease notes](docs/releases/0.3.0-alpha.1.md)
|
|
473
474
|
- [Architecture decisions](docs/ADR/README.md)
|
|
@@ -477,7 +478,7 @@ scripts package and release-readiness checks
|
|
|
477
478
|
|
|
478
479
|
The original M0–M13 roadmap is complete. `ds4-context-core` contains the compiled runtime-neutral implementation. M14 context-quality metrics, M15 rich symbol indexing, M16 hybrid semantic retrieval, M17 cross-session project memory, M18 learned-ranking shadow evaluation, M19's runtime adapter/conformance kit, and M20 opt-in local KV eligibility/replay are implemented on `main`. Learned active ranking remains promotion-gated, Pi reports local KV as unsupported, and static ranking/native completion stay authoritative on every failure.
|
|
479
480
|
|
|
480
|
-
The [0.2.0 roadmap](docs/ROADMAP_0.2.0.md) is complete. Prerelease `0.3.0-alpha.
|
|
481
|
+
The [0.2.0 roadmap](docs/ROADMAP_0.2.0.md) is complete. Prerelease `0.3.0-alpha.3` retains the confirmed [context persistence tool](docs/CONTEXT_PERSISTENCE_TOOL.md) hardening from alpha.2 and adds privacy-safe [compaction](docs/COMPACTION.md) repair diagnostics without weakening exact-value grounding or Pi fallback. Stable canonical/configuration/SQLite/runtime contracts remain unchanged. The [0.2 readiness record](docs/RELEASE_READINESS_0.2.0.md) remains the compatibility baseline. Sensitive or transport-specific behavior remains opt-in, and the 0.1 lexical planner stays available as the deterministic fallback.
|
|
481
482
|
|
|
482
483
|
## Contributing
|
|
483
484
|
|
package/docs/COMPACTION.md
CHANGED
|
@@ -32,7 +32,9 @@ Any mapping, model, output-limit, validation, or storage error returns `undefine
|
|
|
32
32
|
## Critical Exact Values
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
Every section must occur once, in order, and contain content or `- None`. DS4 replaces each unique `Files Read` and `Files Modified` section with one exact path per bullet from Pi's sanitized file-operation inventory before validation; missing or duplicate sections still fail. Backticked exact values must occur in the serialized segment source, ordered child-summary content, or those known file-operation paths. A bounded unsupported exact-value bullet is removed as a whole and recorded as a validation warning; unsupported prose, more than eight affected bullets, or removal above 25% still fails closed to Pi. Segment and aggregate outputs are validated independently; either unrepaired failure prevents the whole graph batch from being installed.
|
|
35
|
+
Every section must occur once, in order, and contain content or `- None`. DS4 replaces each unique `Files Read` and `Files Modified` section with one exact path per bullet from Pi's sanitized file-operation inventory before validation; missing or duplicate sections still fail. Backticked exact values must occur in the serialized segment source, ordered child-summary content, or those known file-operation paths. A bounded unsupported exact-value bullet is removed as a whole and recorded as a validation warning; unsupported prose, more than eight affected bullets, or removal above 25% still fails closed to Pi. The prompt explicitly asks the model to omit a bullet whose complete backticked span cannot be copied verbatim. Segment and aggregate outputs are validated independently; either unrepaired failure prevents the whole graph batch from being installed.
|
|
36
|
+
|
|
37
|
+
An unrepaired exact-value failure reports only the stage, issue code, categorical repair status, unsupported-span count, and affected-bullet count. Repair statuses distinguish an unsupported location, more than eight bullets, removal above 25%, and an unexpected invalid second validation. The disputed text is intentionally absent from logs, UI notifications, and diagnostics because it may contain sensitive source material.
|
|
36
38
|
|
|
37
39
|
## Provenance and recovery
|
|
38
40
|
|
|
@@ -74,4 +76,4 @@ It requests compaction at most once per session leaf. Pi's native threshold and
|
|
|
74
76
|
/context summaries
|
|
75
77
|
```
|
|
76
78
|
|
|
77
|
-
The preview reports thresholds and eligibility; Pi remains authoritative for the exact cut point.
|
|
79
|
+
The preview reports thresholds and eligibility; Pi remains authoritative for the exact cut point. Routine `summary_graph_prepared` and `summary_graph_committed` lifecycle events are emitted only at `debug`; fallback, failure, persistence, and reconciliation problems remain actionable warnings. The proactive-threshold TUI notification remains a user-visible `info` notice because it explains why an automatic compaction started.
|
|
@@ -19,22 +19,24 @@ Memory is quoted durable factual, decision, or historical data. It supports `ses
|
|
|
19
19
|
|
|
20
20
|
## Actions
|
|
21
21
|
|
|
22
|
-
| Action | Class | Purpose |
|
|
23
|
-
| --- | --- | --- |
|
|
24
|
-
| `pins_list` | read | List visible Pins with metadata and revisions |
|
|
25
|
-
| `pins_find` | read | Bounded Pin search with sanitized previews |
|
|
26
|
-
| `pin_add` | canonical write | Append a new Pin |
|
|
27
|
-
| `pin_supersede` | canonical write | Replace one exact active Pin immutably |
|
|
28
|
-
| `pin_unpin` | canonical write | Append a deleted lifecycle status |
|
|
29
|
-
| `memory_list` | read | List visible Memory with metadata and revisions |
|
|
30
|
-
| `memory_find` | read | Bounded Memory search with sanitized previews |
|
|
31
|
-
| `memory_add` | canonical write | Append session/project Memory |
|
|
32
|
-
| `memory_supersede` | canonical write | Replace one exact active Memory item immutably |
|
|
33
|
-
| `memory_invalidate` | canonical write | Append an invalid lifecycle status |
|
|
34
|
-
| `memory_expire` | canonical write | Append an expired lifecycle status |
|
|
35
|
-
| `memory_sources` | read | List cross-session sources through volatile references |
|
|
36
|
-
| `memory_source_exclude` | derived write | Exclude one source in local SQLite policy |
|
|
37
|
-
| `memory_source_include` | derived write | Restore one source in local SQLite policy |
|
|
22
|
+
| Action | Class | Parameters | Purpose |
|
|
23
|
+
| --- | --- | --- | --- |
|
|
24
|
+
| `pins_list` | read | optional `activeOnly`, `maxResults` | List visible Pins with metadata and revisions |
|
|
25
|
+
| `pins_find` | read | `query`; optional `activeOnly`, `maxResults` | Bounded Pin search with sanitized previews |
|
|
26
|
+
| `pin_add` | canonical write | `content`; optional `scope`, `classification` | Append a new Pin |
|
|
27
|
+
| `pin_supersede` | canonical write | `id`, `targetRevision`, `content`; optional `classification` | Replace one exact active Pin immutably |
|
|
28
|
+
| `pin_unpin` | canonical write | `id`, `targetRevision`; optional `reason` | Append a deleted lifecycle status |
|
|
29
|
+
| `memory_list` | read | optional `activeOnly`, `maxResults` | List visible Memory with metadata and revisions |
|
|
30
|
+
| `memory_find` | read | `query`; optional `activeOnly`, `maxResults` | Bounded Memory search with sanitized previews |
|
|
31
|
+
| `memory_add` | canonical write | `content`; optional `scope`, `key`, `classification` | Append session/project Memory |
|
|
32
|
+
| `memory_supersede` | canonical write | `id`, `targetRevision`, `content`; optional `classification` | Replace one exact active Memory item immutably |
|
|
33
|
+
| `memory_invalidate` | canonical write | `id`, `targetRevision`; optional `reason` | Append an invalid lifecycle status |
|
|
34
|
+
| `memory_expire` | canonical write | `id`, `targetRevision`; optional `reason` | Append an expired lifecycle status |
|
|
35
|
+
| `memory_sources` | read | optional `maxResults` | List cross-session sources through volatile references |
|
|
36
|
+
| `memory_source_exclude` | derived write | `id`, `targetRevision`; optional `reason` | Exclude one source in local SQLite policy |
|
|
37
|
+
| `memory_source_include` | derived write | `id`, `targetRevision` | Restore one source in local SQLite policy |
|
|
38
|
+
|
|
39
|
+
The transport schema stays flat for compatibility across supported providers, but DS4 applies the parameter matrix above before runtime access. A known action with an inapplicable field returns `unsupported-parameter`; a known action missing an action-required field returns `missing-required-parameter`. These diagnostics never identify or echo fields or values. Malformed transport input retains the generic `invalid-parameters` category. The output-only egress sentinel is checked before action-specific categorization so it remains `egress-placeholder` even when supplied in an inapplicable field.
|
|
38
40
|
|
|
39
41
|
Read results are keyset-bounded and metadata-only. List results never include Pin content, Memory claims, keys, paths, source session IDs, reasons, complete errors, or totals requiring an unbounded count. Find results may include a short provider-safe preview in text; `details.items` remains metadata-only.
|
|
40
42
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Dogfooding DS4 0.3.0 Alpha
|
|
2
2
|
|
|
3
|
-
This runbook validates the published `ds4-context-engine@0.3.0-alpha.
|
|
3
|
+
This runbook validates the published `ds4-context-engine@0.3.0-alpha.3` package through sustained real Pi use. It complements automated tests and release smoke checks; it does not replace them.
|
|
4
4
|
|
|
5
5
|
The primary target is the model-callable `context_persistence` surface. Pi JSONL must remain canonical and append-only, SQLite must remain rebuildable, and no model-callable write may occur without a fresh positive local UI decision.
|
|
6
6
|
|
|
@@ -9,7 +9,8 @@ The primary target is the model-callable `context_persistence` surface. Pi JSONL
|
|
|
9
9
|
- Use the exact prerelease version, not the mutable `alpha` dist-tag.
|
|
10
10
|
- Use a disposable trusted project and a dedicated session directory.
|
|
11
11
|
- Use synthetic, non-secret Pin/Memory content. Local TUI dialogs and JSON event streams may display current tool arguments.
|
|
12
|
-
- Published alpha.1 had a retry limitation: copying `[omitted-by-ds4-egress-policy]` from sanitized history could present a confirmation for the literal marker. Alpha.2
|
|
12
|
+
- Published alpha.1 had a retry limitation: copying `[omitted-by-ds4-egress-policy]` from sanitized history could present a confirmation for the literal marker. Alpha.2 and later reserve that output-only marker and must reject it as `egress-placeholder` before runtime access, confirmation, canonical append, or derived-policy update.
|
|
13
|
+
- Alpha.3 keeps exact-value summary validation strict. An unrepaired failure may expose only its stage, issue code, repair category, and counts; disputed exact text must not appear in diagnostics.
|
|
13
14
|
- Do not use `--no-session` except for the explicit fail-closed test. Without a persistent Pi JSONL destination, both reads and writes return `runtime-unavailable`.
|
|
14
15
|
- Do not retry `committed_projection_pending` or `indeterminate`. Inspect state with a read, `/context health`, or `/context rebuild-index` first.
|
|
15
16
|
- Use `/context` only for local inspection and recovery. Mutations under test must go through `context_persistence` so the confirmation and provider-egress boundaries are exercised.
|
|
@@ -26,7 +27,7 @@ mkdir -p /tmp/ds4-alpha-dogfood
|
|
|
26
27
|
cd /tmp/ds4-alpha-dogfood
|
|
27
28
|
git init
|
|
28
29
|
mkdir -p sessions evidence
|
|
29
|
-
pi install -l npm:ds4-context-engine@0.3.0-alpha.
|
|
30
|
+
pi install -l npm:ds4-context-engine@0.3.0-alpha.3
|
|
30
31
|
pi list
|
|
31
32
|
pi --version
|
|
32
33
|
```
|
|
@@ -41,7 +41,7 @@ The reference adapter remains on its append-only `ds4-runtime-session-v1` histor
|
|
|
41
41
|
|
|
42
42
|
## Known alpha.1 limitation
|
|
43
43
|
|
|
44
|
-
The published alpha.1 historical sanitizer replaces sensitive tool arguments with `[omitted-by-ds4-egress-policy]`. If a model copies that output-only marker into a later write—most plausibly after a cancelled confirmation—alpha.1 can show a new confirmation for the literal marker. Dogfooders must refuse that dialog; accepting it can append the marker as content or metadata, although it does not recover the omitted value.
|
|
44
|
+
The published alpha.1 historical sanitizer replaces sensitive tool arguments with `[omitted-by-ds4-egress-policy]`. If a model copies that output-only marker into a later write—most plausibly after a cancelled confirmation—alpha.1 can show a new confirmation for the literal marker. Dogfooders must refuse that dialog; accepting it can append the marker as content or metadata, although it does not recover the omitted value. Published `0.3.0-alpha.2` rejects any incoming string argument containing the marker as `egress-placeholder` before confirmation or persistence. The immutable alpha.1 package is not replaced.
|
|
45
45
|
|
|
46
46
|
## Package/version policy
|
|
47
47
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# DS4 Context Engine 0.3.0-alpha.2
|
|
2
2
|
|
|
3
|
-
Status:
|
|
3
|
+
Status: published prerelease on 2026-08-27; tag `v0.3.0-alpha.2`.
|
|
4
4
|
|
|
5
5
|
This coordinated prerelease hardens the `context_persistence` provider-egress boundary discovered during alpha.1 dogfooding. It adds no new persistence format, migration, default-on feature, or model-callable action.
|
|
6
6
|
|
|
@@ -28,7 +28,7 @@ ds4-context-reference-adapter
|
|
|
28
28
|
ds4-context-engine
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
Both adapters depend exactly on `ds4-context-core@0.3.0-alpha.2`.
|
|
31
|
+
Both adapters depend exactly on `ds4-context-core@0.3.0-alpha.2`. The packages were published manually under the explicit npm `alpha` dist-tag while `latest` remains `0.2.0`. GitHub Actions remains validation-only with OIDC and package-write permissions denied.
|
|
32
32
|
|
|
33
33
|
## Dogfood evidence
|
|
34
34
|
|
|
@@ -48,8 +48,9 @@ Local candidate verification on Node.js `26.5.1`:
|
|
|
48
48
|
- The committed candidate was replayed from detached clean checkout `30a5f0f`; `npm ci`, the 64-file/286-test suite, schema gate, package verification, and `git diff --check` passed.
|
|
49
49
|
- `git diff --check`: passed.
|
|
50
50
|
- Protected CI, compatibility golden, Pi fixture, and migration files: unchanged.
|
|
51
|
+
- `npm run registry:check -- 0.3.0-alpha.2`: passed against all three exact published versions; `alpha` resolves to `0.3.0-alpha.2` and `latest` remains `0.2.0` for every package.
|
|
51
52
|
|
|
52
|
-
Exact registry verification
|
|
53
|
+
Exact registry verification passed before the annotated tag and GitHub prerelease were created.
|
|
53
54
|
|
|
54
55
|
## Documentation
|
|
55
56
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# DS4 Context Engine 0.3.0-alpha.3
|
|
2
|
+
|
|
3
|
+
Status: published prerelease on 2026-08-30; tag `v0.3.0-alpha.3`.
|
|
4
|
+
|
|
5
|
+
This coordinated prerelease hardens proactive compaction after investigation of an intermittent `unsupported-exact-value` fallback. It preserves strict exact-value grounding and Pi fallback behavior while making repair failures diagnosable without exposing disputed source text.
|
|
6
|
+
|
|
7
|
+
## Fixed
|
|
8
|
+
|
|
9
|
+
- Tells the summary model to verify every complete backticked span verbatim and omit the whole bullet when the span is unsupported.
|
|
10
|
+
- Distinguishes bounded repair outcomes as `unsupported-location`, `too-many-bullets`, `removal-too-large`, and `post-prune-invalid`.
|
|
11
|
+
- Reports only compaction stage, validation issue code, categorical repair status, unsupported-span count, and affected-bullet count.
|
|
12
|
+
- Keeps rejected exact values out of logs, UI notifications, and diagnostics because they may contain sensitive source material.
|
|
13
|
+
- Preserves the existing limit of eight affected bullets, the 25% removal ceiling, strict second validation, and fallback to Pi default compaction.
|
|
14
|
+
|
|
15
|
+
No verbatim-comparison false positive was reproduced. A remaining unrepaired `unsupported-exact-value` result therefore continues to indicate unsupported prose, exceeded repair bounds, or an invalid post-prune summary rather than being accepted speculatively.
|
|
16
|
+
|
|
17
|
+
## Compatibility and persistence
|
|
18
|
+
|
|
19
|
+
The summary contract and canonical compaction storage format are unchanged. Pi JSONL remains canonical and append-only; an invalid DS4 summary is never installed. SQLite remains a disposable projection. Schema 15, migrations 1–15, `ds4-context-config-v1`, `runtime-adapter-v1`, `ds4-context-persistence-tool-v1`, and `ds4-context-persistence-result-v1` are unchanged.
|
|
20
|
+
|
|
21
|
+
The change adds metadata-only diagnostic categories and no model-callable action, persistence mutation, default-on feature, or weaker validation path.
|
|
22
|
+
|
|
23
|
+
## Package/version policy
|
|
24
|
+
|
|
25
|
+
The coordinated version is `0.3.0-alpha.3` for:
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
ds4-context-core
|
|
29
|
+
ds4-context-reference-adapter
|
|
30
|
+
ds4-context-engine
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Both adapters depend exactly on `ds4-context-core@0.3.0-alpha.3`. The packages were published manually under the explicit npm `alpha` dist-tag while `latest` remains `0.2.0`. GitHub Actions remains validation-only with OIDC and package-write permissions denied.
|
|
34
|
+
|
|
35
|
+
## Validation evidence
|
|
36
|
+
|
|
37
|
+
Local candidate verification on Node.js `26.5.1`:
|
|
38
|
+
|
|
39
|
+
- `npm ci`: passed.
|
|
40
|
+
- `npm run check`: 64 files and 288 tests passed.
|
|
41
|
+
- Focused compaction coverage: prompt grounding, bounded repair categories, second validation, privacy-safe diagnostics, and Pi fallback passed.
|
|
42
|
+
- `npm run quality:compare`: candidate quality `0.9875` versus baseline `0.808156`.
|
|
43
|
+
- `npm run schema:context-persistence`: 1,197 bytes and 300 estimated tokens; below the 1,500 absolute and 320 relative limits.
|
|
44
|
+
- `npm run latency:check -- <exact ds4-context-core@0.1.2>`: passed with ratio `1.052586`, at or below `1.10`.
|
|
45
|
+
- `npm run pack:check`: verified core (203 files), reference adapter (7 files), and Pi adapter (60 files) in a clean consumer.
|
|
46
|
+
- `npm pack --dry-run --json` for all three packages: passed with the same bounded inventories.
|
|
47
|
+
- The committed candidate was replayed from detached clean checkout `3e7bb32`; `npm ci`, the 64-file/288-test suite, quality, schema, package verification, and `git diff --check` passed.
|
|
48
|
+
- `git diff --check`: passed.
|
|
49
|
+
- Protected CI, compatibility golden, Pi fixture, migration, canonical Pin/Memory, and persistence-tool contract files: unchanged.
|
|
50
|
+
|
|
51
|
+
- `npm run registry:check -- 0.3.0-alpha.3`: passed against all three exact published versions; `alpha` resolves to `0.3.0-alpha.3` and `latest` remains `0.2.0` for every package.
|
|
52
|
+
|
|
53
|
+
Exact registry verification passed before the annotated tag and GitHub prerelease were created.
|
|
54
|
+
|
|
55
|
+
## Documentation
|
|
56
|
+
|
|
57
|
+
- [`../COMPACTION.md`](../COMPACTION.md)
|
|
58
|
+
- [`../PRIVACY.md`](../PRIVACY.md)
|
|
59
|
+
- [`../RELEASING.md`](../RELEASING.md)
|
|
60
|
+
- [`0.3.0-alpha.2.md`](0.3.0-alpha.2.md)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# DS4 Context Engine 0.3.0-alpha.4
|
|
2
|
+
|
|
3
|
+
Status: validated release candidate; not yet published.
|
|
4
|
+
|
|
5
|
+
This coordinated prerelease improves model-callable `context_persistence` guidance and categorical validation diagnostics, and removes routine successful compaction lifecycle events from normal `info` output. It preserves strict persistence confirmation, canonical Pi JSONL semantics, privacy-safe egress, compaction validation, and Pi fallback behavior.
|
|
6
|
+
|
|
7
|
+
## Fixed
|
|
8
|
+
|
|
9
|
+
- Describes the valid parameter set for every `context_persistence` action in the tool guidance and public action matrix.
|
|
10
|
+
- Distinguishes a known action with an inapplicable field as `unsupported-parameter` and a missing action-required field as `missing-required-parameter`.
|
|
11
|
+
- Keeps validation failures categorical: rejected field names and values are absent from current results, sanitized history, diagnostics, and logs.
|
|
12
|
+
- Continues to reject the output-only egress sentinel before action-specific validation, including when it appears in an otherwise inapplicable field.
|
|
13
|
+
- Emits routine `compaction.summary_graph_prepared` and `compaction.summary_graph_committed` lifecycle events only at `debug` instead of the default `info` level.
|
|
14
|
+
- Preserves actionable compaction fallback, failure, persistence, and reconciliation events at `warn`; the proactive-threshold TUI notice remains user-visible because it explains why automatic compaction started.
|
|
15
|
+
|
|
16
|
+
## Compatibility and persistence
|
|
17
|
+
|
|
18
|
+
The flat tool schema, fourteen actions, `ds4-context-persistence-tool-v1`, and `ds4-context-persistence-result-v1` identifiers are unchanged. The new validation categories are metadata-only and do not add a write path or alter confirmation requirements.
|
|
19
|
+
|
|
20
|
+
Pi JSONL remains canonical and append-only. All model-callable writes still require fresh local UI confirmation and fail closed without UI or canonical persistence. SQLite remains a disposable projection. Schema 15, migrations 1–15, `ds4-context-config-v1`, and `runtime-adapter-v1` are unchanged. Strict compaction validation and fallback to Pi default compaction are unchanged.
|
|
21
|
+
|
|
22
|
+
## Package/version policy
|
|
23
|
+
|
|
24
|
+
The coordinated version is `0.3.0-alpha.4` for:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
ds4-context-core
|
|
28
|
+
ds4-context-reference-adapter
|
|
29
|
+
ds4-context-engine
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Both adapters depend exactly on `ds4-context-core@0.3.0-alpha.4`. Publication must use the explicit npm `alpha` dist-tag so `latest` remains `0.2.0`. GitHub Actions remains validation-only with OIDC and package-write permissions denied.
|
|
33
|
+
|
|
34
|
+
## Validation evidence
|
|
35
|
+
|
|
36
|
+
Local candidate verification on Node.js `26.5.1`:
|
|
37
|
+
|
|
38
|
+
- `npm ci`: passed.
|
|
39
|
+
- `npm run check`: 64 files and 290 tests passed.
|
|
40
|
+
- Focused persistence coverage: action-field guidance, unsupported/missing parameter categories, egress-sentinel priority, metadata-only failures, and sanitized historical diagnostics passed.
|
|
41
|
+
- Focused compaction coverage: successful lifecycle events are absent at `info`, present at `debug`, and fallback remains `warn`.
|
|
42
|
+
- `npm run quality:compare`: candidate quality `0.9875` versus baseline `0.808156`.
|
|
43
|
+
- `npm run schema:context-persistence`: 1,266 bytes and 317 estimated tokens; below the 1,500 absolute and 320 relative limits.
|
|
44
|
+
- `npm run latency:check -- <exact ds4-context-core@0.1.2>`: passed with ratio `0.923285`, at or below `1.10`.
|
|
45
|
+
- `npm run pack:check`: verified core (203 files), reference adapter (7 files), and Pi adapter (61 files) in a clean consumer.
|
|
46
|
+
- `npm pack --dry-run --json` for all three packages: passed with the same bounded inventories.
|
|
47
|
+
- The committed candidate was replayed from detached clean checkout `6fcf514`; `npm ci`, the 64-file/290-test suite, quality, schema, package verification, tarball review, and `git diff --check` passed.
|
|
48
|
+
- `git diff --check`: passed.
|
|
49
|
+
- Protected CI, compatibility golden, Pi fixture, migration, canonical Pin/Memory, and persistence result-contract files: unchanged.
|
|
50
|
+
|
|
51
|
+
Clean committed-candidate replay and exact registry verification are required before tag or GitHub prerelease creation.
|
|
52
|
+
|
|
53
|
+
## Documentation
|
|
54
|
+
|
|
55
|
+
- [`../CONTEXT_PERSISTENCE_TOOL.md`](../CONTEXT_PERSISTENCE_TOOL.md)
|
|
56
|
+
- [`../COMPACTION.md`](../COMPACTION.md)
|
|
57
|
+
- [`../PRIVACY.md`](../PRIVACY.md)
|
|
58
|
+
- [`../RELEASING.md`](../RELEASING.md)
|
|
59
|
+
- [`0.3.0-alpha.3.md`](0.3.0-alpha.3.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ds4-context-engine",
|
|
3
|
-
"version": "0.3.0-alpha.
|
|
3
|
+
"version": "0.3.0-alpha.4",
|
|
4
4
|
"description": "Non-destructive, provider-independent context management for Pi.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
]
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"ds4-context-core": "0.3.0-alpha.
|
|
61
|
+
"ds4-context-core": "0.3.0-alpha.4"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
64
|
"@earendil-works/pi-ai": "0.84.3",
|
|
@@ -4,12 +4,13 @@ export const CONTEXT_PERSISTENCE_TOOL_CONTRACT = "ds4-context-persistence-tool-v
|
|
|
4
4
|
export const CONTEXT_PERSISTENCE_RESULT_CONTRACT = "ds4-context-persistence-result-v1" as const;
|
|
5
5
|
export const CONTEXT_PERSISTENCE_EGRESS_SENTINEL = "[omitted-by-ds4-egress-policy]" as const;
|
|
6
6
|
export const CONTEXT_PERSISTENCE_TOOL_NAME = "context_persistence" as const;
|
|
7
|
-
export const CONTEXT_PERSISTENCE_DESCRIPTION = "Inspect DS4 Pins/Memory.
|
|
7
|
+
export const CONTEXT_PERSISTENCE_DESCRIPTION = "Inspect DS4 Pins/Memory. Use action fields only. Writes require explicit user request and local UI confirmation." as const;
|
|
8
8
|
export const CONTEXT_PERSISTENCE_PROMPT_SNIPPET = "Inspect or manage user-confirmed DS4 pins and durable memory" as const;
|
|
9
9
|
export const CONTEXT_PERSISTENCE_PROMPT_GUIDELINES = [
|
|
10
10
|
"Use context_persistence only to inspect DS4 persistent state or when the user explicitly requests a persistence mutation.",
|
|
11
11
|
"After an explicit persistence request, call the write action directly; context_persistence itself obtains the required local UI confirmation, so do not ask for separate confirmation in chat.",
|
|
12
12
|
"Never reuse an egress omission marker as tool input; use fresh user-provided text or ask the user to restate it.",
|
|
13
|
+
"Send only fields valid for the selected action: find requires query; add requires content; supersede requires id, targetRevision, and content; lifecycle and source-policy changes require id and targetRevision.",
|
|
13
14
|
"Never create a pin or memory merely because information appears useful.",
|
|
14
15
|
"Use pins for confirmed constraints or instructions that must remain prominent. Use memory for durable facts, decisions, and historical knowledge.",
|
|
15
16
|
"Default new persistence to session scope. Use project or branch scope only when explicitly requested or unambiguous; durable Memory does not support branch scope.",
|
|
@@ -58,9 +59,17 @@ export const CONTEXT_PERSISTENCE_PARAMS = Type.Object({
|
|
|
58
59
|
})),
|
|
59
60
|
id: Type.Optional(Type.String({ minLength: 1, maxLength: 128 })),
|
|
60
61
|
targetRevision: Type.Optional(Type.String({ minLength: 1, maxLength: 64 })),
|
|
61
|
-
content: Type.Optional(Type.String({
|
|
62
|
+
content: Type.Optional(Type.String({
|
|
63
|
+
minLength: 1,
|
|
64
|
+
maxLength: 20_000,
|
|
65
|
+
description: "Add/replace only",
|
|
66
|
+
})),
|
|
62
67
|
key: Type.Optional(Type.String({ minLength: 1, maxLength: 256 })),
|
|
63
|
-
query: Type.Optional(Type.String({
|
|
68
|
+
query: Type.Optional(Type.String({
|
|
69
|
+
minLength: 2,
|
|
70
|
+
maxLength: 200,
|
|
71
|
+
description: "Find; required",
|
|
72
|
+
})),
|
|
64
73
|
reason: Type.Optional(Type.String({
|
|
65
74
|
minLength: 1,
|
|
66
75
|
maxLength: 500,
|
|
@@ -114,6 +123,8 @@ const REQUIRED_FIELDS = {
|
|
|
114
123
|
|
|
115
124
|
export type ContextPersistenceValidationCode =
|
|
116
125
|
| "invalid-parameters"
|
|
126
|
+
| "missing-required-parameter"
|
|
127
|
+
| "unsupported-parameter"
|
|
117
128
|
| "invalid-scope"
|
|
118
129
|
| "egress-placeholder";
|
|
119
130
|
|
|
@@ -139,19 +150,19 @@ export function validateContextPersistenceParams(
|
|
|
139
150
|
): ContextPersistenceValidation {
|
|
140
151
|
if (!params || !isAction(params.action)) return { ok: false, errorCode: "invalid-parameters" };
|
|
141
152
|
const keys = Object.keys(params) as (keyof ContextPersistenceParams)[];
|
|
142
|
-
const allowed = new Set<keyof ContextPersistenceParams>(ALLOWED_FIELDS[params.action]);
|
|
143
|
-
if (keys.some((key) => !allowed.has(key))) {
|
|
144
|
-
return { ok: false, errorCode: "invalid-parameters" };
|
|
145
|
-
}
|
|
146
|
-
if (REQUIRED_FIELDS[params.action].some((key) => params[key] === undefined)) {
|
|
147
|
-
return { ok: false, errorCode: "invalid-parameters" };
|
|
148
|
-
}
|
|
149
153
|
if (keys.some((key) => {
|
|
150
154
|
const value = params[key];
|
|
151
155
|
return typeof value === "string" && value.includes(CONTEXT_PERSISTENCE_EGRESS_SENTINEL);
|
|
152
156
|
})) {
|
|
153
157
|
return { ok: false, errorCode: "egress-placeholder" };
|
|
154
158
|
}
|
|
159
|
+
const allowed = new Set<keyof ContextPersistenceParams>(ALLOWED_FIELDS[params.action]);
|
|
160
|
+
if (keys.some((key) => !allowed.has(key))) {
|
|
161
|
+
return { ok: false, errorCode: "unsupported-parameter" };
|
|
162
|
+
}
|
|
163
|
+
if (REQUIRED_FIELDS[params.action].some((key) => params[key] === undefined)) {
|
|
164
|
+
return { ok: false, errorCode: "missing-required-parameter" };
|
|
165
|
+
}
|
|
155
166
|
if (params.scope === "branch" && params.action === "memory_add") {
|
|
156
167
|
return { ok: false, errorCode: "invalid-scope" };
|
|
157
168
|
}
|
|
@@ -360,7 +360,7 @@ export class CompactionCoordinator {
|
|
|
360
360
|
tokensBefore: event.preparation.tokensBefore,
|
|
361
361
|
requestedAt,
|
|
362
362
|
};
|
|
363
|
-
this.dependencies.logger.
|
|
363
|
+
this.dependencies.logger.debug("compaction.summary_graph_prepared", {
|
|
364
364
|
activeSummaryId: activeNode.id,
|
|
365
365
|
segmentSummaryId: segmentId,
|
|
366
366
|
graphLevel: activeNode.graphLevel,
|
|
@@ -460,7 +460,7 @@ export class CompactionCoordinator {
|
|
|
460
460
|
requestedAt: metadata.generatedAt,
|
|
461
461
|
completedAt: this.dependencies.now(),
|
|
462
462
|
};
|
|
463
|
-
this.dependencies.logger.
|
|
463
|
+
this.dependencies.logger.debug("compaction.summary_graph_committed", {
|
|
464
464
|
activeSummaryId: metadata.summaryId,
|
|
465
465
|
segmentSummaryId: metadata.segmentSummaryId,
|
|
466
466
|
graphLevel: metadata.graphLevel,
|
|
@@ -5,8 +5,8 @@ import type {
|
|
|
5
5
|
SessionBeforeCompactEvent,
|
|
6
6
|
} from "@earendil-works/pi-coding-agent";
|
|
7
7
|
import {
|
|
8
|
+
analyzeUnsupportedExactValueBullets,
|
|
8
9
|
groundSummaryFileSections,
|
|
9
|
-
pruneUnsupportedExactValueBullets,
|
|
10
10
|
validateSummary,
|
|
11
11
|
type SummaryValidationInput,
|
|
12
12
|
type SummaryValidationResult,
|
|
@@ -102,13 +102,16 @@ export async function generateValidatedSummary(
|
|
|
102
102
|
message: "Deterministic validation disabled by configuration",
|
|
103
103
|
}],
|
|
104
104
|
};
|
|
105
|
+
let exactRepair: ReturnType<typeof analyzeUnsupportedExactValueBullets> | undefined;
|
|
106
|
+
let exactRepairFailure: "post-prune-invalid" | undefined;
|
|
105
107
|
if (validation.status === "invalid") {
|
|
106
108
|
const errors = validation.issues.filter((issue) => issue.severity === "error");
|
|
107
109
|
const exactOnly = errors.length > 0
|
|
108
110
|
&& errors.every((issue) => issue.code === "unsupported-exact-value");
|
|
109
|
-
|
|
110
|
-
?
|
|
111
|
+
exactRepair = exactOnly
|
|
112
|
+
? analyzeUnsupportedExactValueBullets(content, validationInput)
|
|
111
113
|
: undefined;
|
|
114
|
+
const pruned = exactRepair?.result;
|
|
112
115
|
if (pruned) {
|
|
113
116
|
const repairedValidation = validateSummary(pruned.content, validationInput);
|
|
114
117
|
if (repairedValidation.status !== "invalid") {
|
|
@@ -124,12 +127,18 @@ export async function generateValidatedSummary(
|
|
|
124
127
|
},
|
|
125
128
|
],
|
|
126
129
|
};
|
|
130
|
+
} else {
|
|
131
|
+
validation = repairedValidation;
|
|
132
|
+
exactRepairFailure = "post-prune-invalid";
|
|
127
133
|
}
|
|
128
134
|
}
|
|
129
135
|
}
|
|
130
136
|
if (validation.status === "invalid") {
|
|
131
137
|
const codes = unique(validation.issues.map((issue) => issue.code)).join(", ");
|
|
132
|
-
|
|
138
|
+
const repairDiagnostics = exactRepair
|
|
139
|
+
? `; repair=${exactRepairFailure ?? exactRepair.status}; unsupportedSpans=${exactRepair.unsupportedSpans}; affectedBullets=${exactRepair.affectedBullets}`
|
|
140
|
+
: "";
|
|
141
|
+
throw new Error(`Compaction ${input.stage} summary validation failed: ${codes}${repairDiagnostics}`);
|
|
133
142
|
}
|
|
134
143
|
return { content, validation, usage: response.usage };
|
|
135
144
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const EXTENSION_VERSION = "0.3.0-alpha.
|
|
1
|
+
export const EXTENSION_VERSION = "0.3.0-alpha.4";
|
|
2
2
|
export const SUPPORTED_PI_VERSION = "0.84.3";
|
|
3
3
|
export const OBSERVER_PLANNER_VERSION = "observer-model-aware-v1";
|
|
4
4
|
export const PLANNER_VERSION = "managed-learned-ranking-v1";
|