ds4-context-engine 0.1.1 → 0.2.0-beta.1
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 +79 -13
- package/docs/ARCHITECTURE.md +33 -16
- package/docs/CONTEXT_MANIFEST.md +3 -1
- package/docs/CONTEXT_PLANNER.md +9 -1
- package/docs/CONTEXT_QUALITY.md +91 -0
- package/docs/HYBRID_RETRIEVAL.md +117 -0
- package/docs/LEARNED_RANKING.md +90 -0
- package/docs/MEMORY_AND_PINS.md +11 -5
- package/docs/PORTABLE_CORE.md +9 -5
- package/docs/PROJECT_KNOWLEDGE.md +29 -17
- package/docs/RELEASING.md +18 -13
- package/docs/RETRIEVAL.md +1 -1
- package/docs/ROADMAP_0.2.0.md +12 -0
- package/docs/RUNTIME_ADAPTER_KIT.md +143 -0
- package/docs/STORAGE.md +35 -7
- package/package.json +12 -7
- package/quality/corpus-v1.json +208 -0
- package/quality/semantic-corpus-v1.json +84 -0
- package/quality/symbol-corpus-v1.json +38 -0
- package/scripts/compare-context-quality.mjs +23 -0
- package/src/extension/commands.ts +213 -1
- package/src/extension/index.ts +1 -0
- package/src/extension/runtime.ts +658 -17
- package/src/pi-adapter/local-embedding.ts +132 -0
- package/src/pi-adapter/memory-adapter.ts +18 -8
- package/src/pi-adapter/project-memory-sync.ts +499 -0
- package/src/pi-adapter/ranking-adapter.ts +72 -0
- package/src/pi-adapter/runtime-contract.ts +86 -0
- package/src/pi-adapter/version.ts +3 -3
package/docs/STORAGE.md
CHANGED
|
@@ -8,7 +8,9 @@ Pi's session JSONL is canonical for conversations and live project files are can
|
|
|
8
8
|
/context rebuild-index
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
The extension never edits or rewrites Pi JSONL or project source files. Manual memory/pin commands append versioned Pi `CustomEntry` records through Pi's official `appendEntry()` API.
|
|
11
|
+
The extension never edits or rewrites Pi JSONL or project source files. Manual memory/pin commands and learned-ranking feedback append versioned classified Pi `CustomEntry` records through Pi's official `appendEntry()` API.
|
|
12
|
+
|
|
13
|
+
The M19 non-Pi reference adapter owns a separate `ds4-runtime-session-v1` JSONL source selected by its host runtime. Its header binds runtime/session identity and the exact canonical project root; following records contain provenance-checked canonical messages. DS4 snapshots and capability diagnostics are disposable. `createReferenceHistory()` refuses overwrite, append uses a dedicated provenance-checked operation, files are mode `0600` where supported, and rebuild never edits this runtime-owned canonical file. Reference JSONL is not imported into Pi or `context.db`.
|
|
12
14
|
|
|
13
15
|
## Session index
|
|
14
16
|
|
|
@@ -45,19 +47,33 @@ Malformed newline-terminated records are skipped consistently and counted. A val
|
|
|
45
47
|
|
|
46
48
|
## Project knowledge index
|
|
47
49
|
|
|
48
|
-
Schema v7 adds `project_states`, `project_files`, `project_snippets`, and `project_snippets_fts`. The state row records canonical root plus Git branch/HEAD/dirty paths. Current file rows store SHA-256, size, mtime, language, indexed Git HEAD, tracked/modified state
|
|
50
|
+
Schema v7 adds `project_states`, `project_files`, `project_snippets`, and `project_snippets_fts`. The state row records canonical root plus Git branch/HEAD/dirty paths. Current file rows store SHA-256, size, mtime, language, indexed Git HEAD, tracked/modified state and lifecycle. Snippet rows store the immutable file hash, line range, source text, estimate and stale bit.
|
|
51
|
+
|
|
52
|
+
Schema v12 extends snippet rows with text/symbol chunk kind, parser ID, stable symbol ID, simple and qualified names, kind, signature, parent, imports and references. The exact-name indexes and all parser output are disposable. Built-in TypeScript/JavaScript/Python/Go structural parsing has no native dependency; unsupported, invalid or declaration-free files retain bounded v7 text windows.
|
|
49
53
|
|
|
50
|
-
Changed hashes never overwrite old snippet rows silently: prior rows become stale and new hash-derived snippet IDs become current. Deleted, renamed, oversized, binary, symlinked
|
|
54
|
+
Changed hashes never overwrite old snippet rows silently: only the changed path's prior rows become stale and new hash-derived snippet/symbol IDs become current. Unrelated files preserve their rows and IDs. Deleted, renamed, oversized, binary, symlinked or newly sensitive files similarly invalidate prior snippets. Exact path/symbol and FTS queries join current files and require `stale = 0`; stale FTS rows may remain locally for derived-history diagnostics but cannot enter context.
|
|
51
55
|
|
|
52
56
|
Project source text is duplicated in SQLite only to provide local FTS and bounded snippet injection. Deleting the database loses no source truth. `/context rebuild-index` clears/rebuilds current projections from trusted live files. No project table is read or written while Pi reports the project untrusted.
|
|
53
57
|
|
|
58
|
+
## Derived embedding index
|
|
59
|
+
|
|
60
|
+
Schema v13 adds `derived_embeddings` for opt-in M16 historical/project vectors. The compound key contains source kind/scope/key/hash, chunking version, embedding provider/model and dimensions. Rows store only source grouping metadata, numeric vector JSON and indexing time; no query text, copied evidence text, provider response ID or remote handle is added.
|
|
61
|
+
|
|
62
|
+
Current source keys and hashes prune obsolete vectors without touching unrelated sources. Provider/model/dimension profiles coexist, so changing one profile does not rewrite another. Query vectors live only in a bounded volatile cache. The table is ignored when semantic retrieval is disabled and can always be recreated from Pi JSONL plus trusted live project files and the configured runtime embedding port.
|
|
63
|
+
|
|
64
|
+
Remote embedding text is privacy-filtered before the port is called. `local-only` values are omitted entirely and allowed values are secret-redacted. These rules govern transport; SQLite remains a local disposable projection.
|
|
65
|
+
|
|
54
66
|
## Memory and pin event projection
|
|
55
67
|
|
|
56
68
|
Schema v9 adds append-only `memory_mutations` and `pin_mutations`, each keyed to the canonical scoped `entries.entry_key` for its Pi custom entry. Mutation payloads describe immutable add, explicit supersede, or lifecycle status operations. `entry_order` preserves causal order when several Pi entries share one millisecond timestamp.
|
|
57
69
|
|
|
58
70
|
`memory_items`, `memory_sources`, `memory_fts`, and `pins` are materialized transactionally by replaying every known mutation. Materialized memory records retain normalized keys, origin session, source entries, optional privacy classification, active/superseded/invalid/expired status and immutable replacement links. Pins retain session/branch/project scope, creation leaf, optional classification, source entry/file and active/superseded/deleted lifecycle. Classification lives in canonical mutation JSON and derived `metadata_json`; M10 required no schema migration beyond v9.
|
|
59
71
|
|
|
60
|
-
Before replay, the current session's mutation rows are replaced from its complete Pi entry tree. Other indexed sessions remain available,
|
|
72
|
+
Before replay, the current session's mutation rows are replaced from its complete Pi entry tree. Other indexed sessions remain available, preserving the 0.1 project-scope behavior.
|
|
73
|
+
|
|
74
|
+
Schema v15 adds `project_memory_sessions`, `project_memory_source_exclusions`, and mutation creation-parent columns. When `memory.crossSession` is opted in, DS4 enumerates at most `memory.maxProjectSessions` sibling Pi JSONL files, validates each header against the exact trusted canonical project path, indexes only changed suffixes, and materializes their explicit mutations. Source rows retain header/checkpoint hashes, offsets, record/mutation counts, malformed-line counts, status and bounded error text. Exclusions are local derived policy; mutation content remains only in canonical JSONL and existing local projection tables.
|
|
75
|
+
|
|
76
|
+
A missing, moved, truncated, identity-mismatched or corrupt sibling source stops contributing unverifiable project-scoped mutations without discarding its isolated session-scoped projection. The active session retains its last transactional projection if an auxiliary cross-session refresh fails. Restored files rebuild deterministically. Deleting the database loses no canonical mutation; source discovery recreates the complete project projection without opening every source session. Unbacked legacy pre-v9 materialized rows are inspectable immediately after migration but are not treated as canonical during a later full replay.
|
|
61
77
|
|
|
62
78
|
Custom entries have empty lexical search text and never enter Pi context directly. The managed planner creates bounded, source-labelled synthetic pin/memory messages. Context Manifests store only metadata and hashes, never content/claims.
|
|
63
79
|
|
|
@@ -67,9 +83,21 @@ Schema v10 extends `context_manifests` and `token_calibration` with separate unc
|
|
|
67
83
|
|
|
68
84
|
Calibration rows are derived telemetry, isolated by exact provider/model and bounded to the latest configured window at read time. The runtime recomputes median/MAD outlier filtering deterministically; no learned model or mutable provider state is stored. Deleting the database loses calibration and cache history but never session content. Ephemeral sessions and configurations that disable manifest persistence keep only a bounded in-memory window.
|
|
69
85
|
|
|
86
|
+
## Context quality samples
|
|
87
|
+
|
|
88
|
+
Schema v11 adds bounded `context_quality_samples` for opt-in M14 measurement. Rows contain only metric/corpus/planner/profile versions, source-kind/token/budget/decision counts, normalized outcome labels and separate planning duration. Prompt text, evidence text, paths, memory claims, provider payloads, response IDs and raw source IDs are never stored. Invalid or corrupt rows are skipped during aggregation.
|
|
89
|
+
|
|
90
|
+
The table is a disposable replay projection. Deleting it loses no canonical state; replaying the versioned sanitized corpus recreates byte-stable non-timing aggregates. Runtime samples without expected-evidence labels remain explicitly unlabeled. See [`CONTEXT_QUALITY.md`](CONTEXT_QUALITY.md).
|
|
91
|
+
|
|
92
|
+
## Learned-ranking labels and model artifact
|
|
93
|
+
|
|
94
|
+
M18 adds no SQLite table. Classified `ds4-context-ranking-feedback-v1` Pi custom entries are canonical and contain only version/hash/label metadata plus ten bounded numeric features. Stable repository and candidate identities are SHA-256 hashes; raw prompt, evidence, claim, path and symbol text are absent. Sanitized replay labels use the same entry schema and explicitly identify their label source.
|
|
95
|
+
|
|
96
|
+
The trained `ds4-context/ranking-model.json` file is a disposable private artifact containing schema/algorithm versions, bounded weights, aggregate training counts, optional promotion-gate metrics and a stable-payload checksum. Deleting or corrupting it restores static ranking; canonical labels remain available for local retraining. Shadow comparison stores only aggregate disagreement in Context Manifests. No label, feature vector or candidate ID is copied into a manifest. See [`LEARNED_RANKING.md`](LEARNED_RANKING.md).
|
|
97
|
+
|
|
70
98
|
## Native continuation state
|
|
71
99
|
|
|
72
|
-
M12 adds no
|
|
100
|
+
M12 adds no continuation table. It was introduced at schema v10; M14 adds quality samples in v11, M15 adds project-symbol columns/indexes in v12, and M16 adds only disposable vectors in v13. The active process keeps only deterministic SHA-256 hashes of the previous full request items and serialized response items, a hash of non-input request options, completion time, and the minimum provider response handle needed for `previous_response_id`.
|
|
73
101
|
|
|
74
102
|
The volatile state is cleared on lifecycle/model/branch/compaction boundaries and is not reconstructed on resume. The first request after a cold start is therefore always the complete managed replay. Pi may persist its normal `AssistantMessage.responseId` in canonical JSONL, but DS4 does not create a custom entry, copy that ID into SQLite/manifest/logs, or depend on it for recovery.
|
|
75
103
|
|
|
@@ -83,7 +111,7 @@ A full index rebuild replays all message entries, recreates missing qualifying o
|
|
|
83
111
|
|
|
84
112
|
## Context manifests
|
|
85
113
|
|
|
86
|
-
For persisted sessions, each `context` hook stores a metadata-only manifest containing token counts, session/project/pin/memory source and atomic-group IDs, inclusion/exclusion reasons, classifications and scores, original/selected counts, exact-model override/calibration/adaptive budgets, model-switch/cache disposition, provider destination/allow names, privacy counters, optional continuation mode/item counts/retry reasons, project revision/hash/line references, tool names, a SHA-256 prompt hash, and planner/policy versions. Prompt text, message text, pin content, memory claims, project snippet text, tool arguments, image data, rendered provider payloads, and provider response/conversation IDs are not stored in the manifest.
|
|
114
|
+
For persisted sessions, each `context` hook stores a metadata-only manifest containing token counts, session/project/pin/memory source and atomic-group IDs, inclusion/exclusion reasons, classifications and scores, original/selected counts, exact-model override/calibration/adaptive budgets, aggregate learned-ranking status/disagreement, model-switch/cache disposition, provider destination/allow names, privacy counters, optional continuation mode/item counts/retry reasons, project revision/hash/line references, tool names, a SHA-256 prompt hash, and planner/policy versions. Prompt text, message text, pin content, memory claims, project snippet text, tool arguments, image data, rendered provider payloads, and provider response/conversation IDs are not stored in the manifest.
|
|
87
115
|
|
|
88
116
|
`before_provider_request` updates the pending manifest with final-check/redaction counters but never the provider payload. The following finalized assistant response updates it with uncached input, cache-read, cache-write and total provider input usage, then adds at most one exact-model calibration sample. Ephemeral sessions retain this information only in memory.
|
|
89
117
|
|
|
@@ -99,4 +127,4 @@ Schema-v2 `CompactionEntry.details.ds4ContextEngine` records the active/segment
|
|
|
99
127
|
|
|
100
128
|
A full rebuild does not blindly delete unchanged entries. It upserts all observed entries, marks them in a temporary seen-set, and removes only stale rows. This preserves foreign-key provenance for unchanged source entries. FTS rows and checkpoint state update in the same transaction.
|
|
101
129
|
|
|
102
|
-
Session reconciliation is transactional. Memory/pin mutation replacement and full materialization
|
|
130
|
+
Session reconciliation is transactional. Memory/pin mutation replacement, checkpoint update, source exclusion and full materialization each occur under the shared write coordinator. Each quality upsert and bounded-retention prune share one transaction; quality failures do not affect manifests or planning. Each changed project file is also replaced transactionally with its snippets and FTS rows; embedding upserts and canonical-source pruning are transactional; artifact object/reference metadata and project deletion batches are atomic. A filesystem artifact write precedes its metadata transaction, so an interrupted metadata write may leave only an unreferenced content-addressed cache file; canonical JSONL remains sufficient for recovery. If parsing, validation, or SQLite writing fails, the prior derived state remains available. Artifact/project failures contribute no replacement/snippets; planner failures discard all synthetic evidence; Pi continues with its native context.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ds4-context-engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0-beta.1",
|
|
4
4
|
"description": "Non-destructive, provider-independent context management for Pi.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
"files": [
|
|
30
30
|
"src",
|
|
31
31
|
"docs",
|
|
32
|
+
"quality",
|
|
33
|
+
"scripts/compare-context-quality.mjs",
|
|
32
34
|
"README.md",
|
|
33
35
|
"LICENSE"
|
|
34
36
|
],
|
|
@@ -37,12 +39,15 @@
|
|
|
37
39
|
},
|
|
38
40
|
"scripts": {
|
|
39
41
|
"build:core": "npm run build --workspace ds4-context-core",
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
42
|
+
"build:reference-adapter": "npm run build --workspace ds4-context-reference-adapter",
|
|
43
|
+
"build:adapters": "npm run build:reference-adapter",
|
|
44
|
+
"typecheck": "npm run build:core && npm run build:adapters && tsc --noEmit",
|
|
45
|
+
"test": "npm run build:core && npm run build:adapters && vitest run",
|
|
46
|
+
"test:watch": "npm run build:core && npm run build:adapters && vitest",
|
|
47
|
+
"check": "npm run build:core && npm run build:adapters && tsc --noEmit && vitest run",
|
|
48
|
+
"quality:compare": "node scripts/compare-context-quality.mjs",
|
|
44
49
|
"pack:check": "node scripts/verify-packages.mjs",
|
|
45
|
-
"prepare": "npm run build:core"
|
|
50
|
+
"prepare": "npm run build:core && npm run build:adapters"
|
|
46
51
|
},
|
|
47
52
|
"pi": {
|
|
48
53
|
"extensions": [
|
|
@@ -50,7 +55,7 @@
|
|
|
50
55
|
]
|
|
51
56
|
},
|
|
52
57
|
"dependencies": {
|
|
53
|
-
"ds4-context-core": "0.
|
|
58
|
+
"ds4-context-core": "0.2.0-beta.1"
|
|
54
59
|
},
|
|
55
60
|
"peerDependencies": {
|
|
56
61
|
"@earendil-works/pi-ai": "0.84.3",
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"corpusVersion": "ds4-quality-corpus-v1",
|
|
4
|
+
"description": "Synthetic metadata-only replay fixtures for deterministic DS4 context-quality comparisons.",
|
|
5
|
+
"fixtures": [
|
|
6
|
+
{
|
|
7
|
+
"schemaVersion": 1,
|
|
8
|
+
"corpusVersion": "ds4-quality-corpus-v1",
|
|
9
|
+
"sampleId": "fixture:retrieval-budget",
|
|
10
|
+
"plannerVersion": "managed-v1",
|
|
11
|
+
"profileKey": "fixture/model-128k",
|
|
12
|
+
"task": {
|
|
13
|
+
"taskId": "task:retrieval-budget",
|
|
14
|
+
"taskType": "debugging",
|
|
15
|
+
"queryTags": ["exact-symbol", "historical-decision"]
|
|
16
|
+
},
|
|
17
|
+
"expectedEvidenceSourceIds": ["entry:decision-a"],
|
|
18
|
+
"candidates": [
|
|
19
|
+
{
|
|
20
|
+
"id": "candidate:current-a",
|
|
21
|
+
"kind": "current",
|
|
22
|
+
"tokens": 80,
|
|
23
|
+
"groupId": "group:current-a",
|
|
24
|
+
"sourceIds": ["entry:request-a"],
|
|
25
|
+
"staticScore": 1000,
|
|
26
|
+
"candidateScore": 1000,
|
|
27
|
+
"currentRequest": true
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"id": "candidate:recent-a",
|
|
31
|
+
"kind": "recent",
|
|
32
|
+
"tokens": 120,
|
|
33
|
+
"groupId": "group:recent-a",
|
|
34
|
+
"sourceIds": ["entry:recent-a"],
|
|
35
|
+
"staticScore": 100,
|
|
36
|
+
"candidateScore": 40
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "candidate:retrieval-a",
|
|
40
|
+
"kind": "retrieval",
|
|
41
|
+
"tokens": 100,
|
|
42
|
+
"groupId": "group:retrieval-a",
|
|
43
|
+
"sourceIds": ["entry:decision-a"],
|
|
44
|
+
"staticScore": 85,
|
|
45
|
+
"candidateScore": 180
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"totalBudgetTokens": 210,
|
|
49
|
+
"categoryBudgets": {
|
|
50
|
+
"recent": 160,
|
|
51
|
+
"retrieval": 120
|
|
52
|
+
},
|
|
53
|
+
"outcomeLabels": ["expected:decision-recovered"]
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"schemaVersion": 1,
|
|
57
|
+
"corpusVersion": "ds4-quality-corpus-v1",
|
|
58
|
+
"sampleId": "fixture:atomic-tools",
|
|
59
|
+
"plannerVersion": "managed-v1",
|
|
60
|
+
"profileKey": "fixture/model-32k",
|
|
61
|
+
"task": {
|
|
62
|
+
"taskId": "task:atomic-tools",
|
|
63
|
+
"taskType": "tool-debugging",
|
|
64
|
+
"queryTags": ["atomic-tool-group"]
|
|
65
|
+
},
|
|
66
|
+
"expectedEvidenceSourceIds": ["entry:tool-call", "entry:tool-result"],
|
|
67
|
+
"candidates": [
|
|
68
|
+
{
|
|
69
|
+
"id": "candidate:current-b",
|
|
70
|
+
"kind": "current",
|
|
71
|
+
"tokens": 40,
|
|
72
|
+
"groupId": "group:current-b",
|
|
73
|
+
"sourceIds": ["entry:request-b"],
|
|
74
|
+
"staticScore": 1000,
|
|
75
|
+
"candidateScore": 1000,
|
|
76
|
+
"currentRequest": true
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"id": "candidate:tool-call",
|
|
80
|
+
"kind": "retrieval",
|
|
81
|
+
"tokens": 60,
|
|
82
|
+
"groupId": "group:tool-exchange",
|
|
83
|
+
"sourceIds": ["entry:tool-call"],
|
|
84
|
+
"staticScore": 90,
|
|
85
|
+
"candidateScore": 120
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"id": "candidate:tool-result",
|
|
89
|
+
"kind": "retrieval",
|
|
90
|
+
"tokens": 100,
|
|
91
|
+
"groupId": "group:tool-exchange",
|
|
92
|
+
"sourceIds": ["entry:tool-result"],
|
|
93
|
+
"staticScore": 90,
|
|
94
|
+
"candidateScore": 120
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"id": "candidate:background-b",
|
|
98
|
+
"kind": "recent",
|
|
99
|
+
"tokens": 170,
|
|
100
|
+
"groupId": "group:background-b",
|
|
101
|
+
"sourceIds": ["entry:background-b"],
|
|
102
|
+
"staticScore": 80,
|
|
103
|
+
"candidateScore": 20
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"totalBudgetTokens": 220,
|
|
107
|
+
"categoryBudgets": {
|
|
108
|
+
"recent": 180,
|
|
109
|
+
"retrieval": 180
|
|
110
|
+
},
|
|
111
|
+
"outcomeLabels": ["expected:atomic-selection"]
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"schemaVersion": 1,
|
|
115
|
+
"corpusVersion": "ds4-quality-corpus-v1",
|
|
116
|
+
"sampleId": "fixture:duplicate-evidence",
|
|
117
|
+
"plannerVersion": "managed-v1",
|
|
118
|
+
"profileKey": "fixture/model-200k",
|
|
119
|
+
"task": {
|
|
120
|
+
"taskId": "task:duplicate-evidence",
|
|
121
|
+
"taskType": "refactoring",
|
|
122
|
+
"queryTags": ["decision-recall", "duplicate-control"]
|
|
123
|
+
},
|
|
124
|
+
"expectedEvidenceSourceIds": ["entry:decision-b", "entry:decision-c"],
|
|
125
|
+
"candidates": [
|
|
126
|
+
{
|
|
127
|
+
"id": "candidate:current-c",
|
|
128
|
+
"kind": "current",
|
|
129
|
+
"tokens": 50,
|
|
130
|
+
"groupId": "group:current-c",
|
|
131
|
+
"sourceIds": ["entry:request-c"],
|
|
132
|
+
"staticScore": 1000,
|
|
133
|
+
"candidateScore": 1000,
|
|
134
|
+
"currentRequest": true
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"id": "candidate:decision-b-primary",
|
|
138
|
+
"kind": "retrieval",
|
|
139
|
+
"tokens": 80,
|
|
140
|
+
"groupId": "group:decision-b-primary",
|
|
141
|
+
"sourceIds": ["entry:decision-b"],
|
|
142
|
+
"staticScore": 100,
|
|
143
|
+
"candidateScore": 100
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"id": "candidate:decision-b-duplicate",
|
|
147
|
+
"kind": "retrieval",
|
|
148
|
+
"tokens": 80,
|
|
149
|
+
"groupId": "group:decision-b-duplicate",
|
|
150
|
+
"sourceIds": ["entry:decision-b"],
|
|
151
|
+
"staticScore": 99,
|
|
152
|
+
"candidateScore": 10
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"id": "candidate:decision-c",
|
|
156
|
+
"kind": "retrieval",
|
|
157
|
+
"tokens": 80,
|
|
158
|
+
"groupId": "group:decision-c",
|
|
159
|
+
"sourceIds": ["entry:decision-c"],
|
|
160
|
+
"staticScore": 98,
|
|
161
|
+
"candidateScore": 99
|
|
162
|
+
}
|
|
163
|
+
],
|
|
164
|
+
"totalBudgetTokens": 210,
|
|
165
|
+
"categoryBudgets": {
|
|
166
|
+
"retrieval": 160
|
|
167
|
+
},
|
|
168
|
+
"outcomeLabels": ["expected:no-duplicate"]
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"schemaVersion": 1,
|
|
172
|
+
"corpusVersion": "ds4-quality-corpus-v1",
|
|
173
|
+
"sampleId": "fixture:mandatory-overflow",
|
|
174
|
+
"plannerVersion": "managed-v1",
|
|
175
|
+
"profileKey": "fixture/model-32k",
|
|
176
|
+
"task": {
|
|
177
|
+
"taskId": "task:mandatory-overflow",
|
|
178
|
+
"taskType": "overflow-safety",
|
|
179
|
+
"queryTags": ["fail-open", "current-request"]
|
|
180
|
+
},
|
|
181
|
+
"expectedEvidenceSourceIds": [],
|
|
182
|
+
"candidates": [
|
|
183
|
+
{
|
|
184
|
+
"id": "candidate:current-d",
|
|
185
|
+
"kind": "current",
|
|
186
|
+
"tokens": 300,
|
|
187
|
+
"groupId": "group:current-d",
|
|
188
|
+
"sourceIds": ["entry:request-d"],
|
|
189
|
+
"staticScore": 1000,
|
|
190
|
+
"candidateScore": 1000,
|
|
191
|
+
"currentRequest": true
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"id": "candidate:history-d",
|
|
195
|
+
"kind": "history",
|
|
196
|
+
"tokens": 50,
|
|
197
|
+
"groupId": "group:history-d",
|
|
198
|
+
"sourceIds": ["entry:history-d"],
|
|
199
|
+
"staticScore": 10,
|
|
200
|
+
"candidateScore": 10
|
|
201
|
+
}
|
|
202
|
+
],
|
|
203
|
+
"totalBudgetTokens": 200,
|
|
204
|
+
"categoryBudgets": {},
|
|
205
|
+
"outcomeLabels": ["expected:fail-open"]
|
|
206
|
+
}
|
|
207
|
+
]
|
|
208
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"corpusVersion": "ds4-semantic-corpus-v1",
|
|
4
|
+
"baseQualityCorpusVersion": "ds4-quality-corpus-v1",
|
|
5
|
+
"description": "Synthetic sanitized M16 retrieval fixtures evaluated with the M14 evidence recall and irrelevant-token metrics.",
|
|
6
|
+
"fixtures": [
|
|
7
|
+
{
|
|
8
|
+
"id": "semantic-auth-renewal",
|
|
9
|
+
"query": "renew authorization credentials after expiry",
|
|
10
|
+
"exactIdentifiers": [],
|
|
11
|
+
"expectedEvidenceIds": ["evidence:auth-refresh"],
|
|
12
|
+
"maxResults": 1,
|
|
13
|
+
"candidates": [
|
|
14
|
+
{
|
|
15
|
+
"id": "evidence:auth-refresh",
|
|
16
|
+
"text": "OAuth token refresh handles expired authentication secrets.",
|
|
17
|
+
"tokens": 24
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": "evidence:schema",
|
|
21
|
+
"text": "SQLite migration creates a project metadata table.",
|
|
22
|
+
"tokens": 28
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"id": "semantic-cache-reuse",
|
|
28
|
+
"query": "reuse previously computed responses to reduce latency",
|
|
29
|
+
"exactIdentifiers": [],
|
|
30
|
+
"expectedEvidenceIds": ["evidence:cache"],
|
|
31
|
+
"maxResults": 1,
|
|
32
|
+
"candidates": [
|
|
33
|
+
{
|
|
34
|
+
"id": "evidence:cache",
|
|
35
|
+
"text": "Memoized output caching avoids repeated work and improves performance.",
|
|
36
|
+
"tokens": 30
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "evidence:logging",
|
|
40
|
+
"text": "Structured logs record request metadata for diagnostics.",
|
|
41
|
+
"tokens": 26
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"id": "exact-path-priority",
|
|
47
|
+
"query": "inspect src/Auth.ts before changing token renewal",
|
|
48
|
+
"exactIdentifiers": ["src/Auth.ts"],
|
|
49
|
+
"expectedEvidenceIds": ["evidence:exact-path"],
|
|
50
|
+
"maxResults": 1,
|
|
51
|
+
"candidates": [
|
|
52
|
+
{
|
|
53
|
+
"id": "evidence:exact-path",
|
|
54
|
+
"text": "src/Auth.ts exports a small compatibility wrapper.",
|
|
55
|
+
"tokens": 20
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"id": "evidence:semantic-neighbor",
|
|
59
|
+
"text": "Authentication credential refresh renews expired OAuth tokens.",
|
|
60
|
+
"tokens": 34
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": "semantic-storage-failure",
|
|
66
|
+
"query": "debug persistence failures in the local datastore",
|
|
67
|
+
"exactIdentifiers": [],
|
|
68
|
+
"expectedEvidenceIds": ["evidence:sqlite-error"],
|
|
69
|
+
"maxResults": 1,
|
|
70
|
+
"candidates": [
|
|
71
|
+
{
|
|
72
|
+
"id": "evidence:sqlite-error",
|
|
73
|
+
"text": "SQLite database exceptions are isolated and fall back safely.",
|
|
74
|
+
"tokens": 32
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "evidence:ui",
|
|
78
|
+
"text": "Terminal colors and status labels are rendered by the UI.",
|
|
79
|
+
"tokens": 30
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"corpusVersion": "ds4-symbol-corpus-v1",
|
|
4
|
+
"fixtures": [
|
|
5
|
+
{
|
|
6
|
+
"id": "typescript-comments-and-methods",
|
|
7
|
+
"language": "typescript",
|
|
8
|
+
"filePath": "src/service.ts",
|
|
9
|
+
"content": "import { Client } from \"./client.js\";\n// class PhantomComment {}\nconst sample = \"function PhantomString() {}\";\nexport class Service {\n async run(client: Client): Promise<Result> {\n return client.execute();\n }\n}\n",
|
|
10
|
+
"expectedSymbols": ["sample", "Service", "Service.run"],
|
|
11
|
+
"forbiddenSymbols": ["PhantomComment", "PhantomString"]
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"id": "javascript-declarations",
|
|
15
|
+
"language": "javascript",
|
|
16
|
+
"filePath": "src/worker.js",
|
|
17
|
+
"content": "const text = 'class StringOnly {}';\nexport function buildWorker(options) {\n return createWorker(options);\n}\nexport const stopWorker = () => terminateWorker();\n",
|
|
18
|
+
"expectedSymbols": ["text", "buildWorker", "stopWorker"],
|
|
19
|
+
"forbiddenSymbols": ["StringOnly"]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "python-indentation",
|
|
23
|
+
"language": "python",
|
|
24
|
+
"filePath": "src/processor.py",
|
|
25
|
+
"content": "from app.client import Client\n# def phantom_comment(): pass\nclass Processor:\n def process(self, client: Client):\n return client.execute()\n\ndef create_processor():\n return Processor()\n",
|
|
26
|
+
"expectedSymbols": ["Processor", "Processor.process", "create_processor"],
|
|
27
|
+
"forbiddenSymbols": ["phantom_comment"]
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"id": "go-receiver-method",
|
|
31
|
+
"language": "go",
|
|
32
|
+
"filePath": "service/service.go",
|
|
33
|
+
"content": "package service\n\nimport (\n \"context\"\n \"example/client\"\n)\n\n// type Phantom struct{}\ntype Service struct { client *client.Client }\n\nfunc (s *Service) Run(ctx context.Context) error {\n return s.client.Execute(ctx)\n}\n",
|
|
34
|
+
"expectedSymbols": ["Service", "Service.Run"],
|
|
35
|
+
"forbiddenSymbols": ["Phantom"]
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { performance } from "node:perf_hooks";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import {
|
|
5
|
+
compareQualityStrategies,
|
|
6
|
+
staticRankingStrategy,
|
|
7
|
+
taskWeightedCandidateStrategy,
|
|
8
|
+
} from "ds4-context-core/quality/context-quality";
|
|
9
|
+
import { stableStringify } from "ds4-context-core/shared/stable-json";
|
|
10
|
+
|
|
11
|
+
const corpusUrl = new URL("../quality/corpus-v1.json", import.meta.url);
|
|
12
|
+
const corpus = JSON.parse(readFileSync(fileURLToPath(corpusUrl), "utf8"));
|
|
13
|
+
const startedAt = performance.now();
|
|
14
|
+
const report = compareQualityStrategies(corpus, [
|
|
15
|
+
staticRankingStrategy(),
|
|
16
|
+
taskWeightedCandidateStrategy(),
|
|
17
|
+
]);
|
|
18
|
+
const durationMs = performance.now() - startedAt;
|
|
19
|
+
|
|
20
|
+
process.stdout.write(`${stableStringify(report)}\n`);
|
|
21
|
+
if (process.argv.includes("--timing")) {
|
|
22
|
+
process.stderr.write(`quality comparison wall-clock: ${durationMs.toFixed(3)} ms\n`);
|
|
23
|
+
}
|