freshcontext-mcp 0.3.19 → 0.3.21
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/FRESHCONTEXT_SPEC.md +317 -0
- package/METHODOLOGY.md +381 -0
- package/README.md +55 -5
- package/SECURITY.md +9 -7
- package/dist/adapters/arxiv.d.ts +15 -0
- package/dist/adapters/arxiv.js +3 -2
- package/dist/adapters/changelog.d.ts +2 -0
- package/dist/adapters/changelog.js +4 -2
- package/dist/adapters/finance.d.ts +2 -0
- package/dist/adapters/finance.js +1 -1
- package/dist/adapters/gdelt.d.ts +2 -0
- package/dist/adapters/gdelt.js +1 -1
- package/dist/adapters/gebiz.d.ts +2 -0
- package/dist/adapters/gebiz.js +1 -1
- package/dist/adapters/github.d.ts +2 -0
- package/dist/adapters/govcontracts.d.ts +2 -0
- package/dist/adapters/hackernews.d.ts +2 -0
- package/dist/adapters/jobs.d.ts +2 -0
- package/dist/adapters/jobs.js +6 -6
- package/dist/adapters/packageTrends.d.ts +2 -0
- package/dist/adapters/productHunt.d.ts +2 -0
- package/dist/adapters/reddit.d.ts +8 -0
- package/dist/adapters/reddit.js +12 -5
- package/dist/adapters/registry.d.ts +19 -0
- package/dist/adapters/repoSearch.d.ts +2 -0
- package/dist/adapters/repoSearch.js +1 -1
- package/dist/adapters/scholar.d.ts +2 -0
- package/dist/adapters/secFilings.d.ts +2 -0
- package/dist/adapters/secFilings.js +1 -1
- package/dist/adapters/yc.d.ts +2 -0
- package/dist/core/decay.d.ts +5 -0
- package/dist/core/decision.d.ts +3 -0
- package/dist/core/decision.js +1 -3
- package/dist/core/envelope.d.ts +5 -0
- package/dist/core/envelope.js +9 -1
- package/dist/core/explain.d.ts +12 -0
- package/dist/core/guards.d.ts +1 -0
- package/dist/core/index.d.ts +14 -0
- package/dist/core/index.js +2 -0
- package/dist/core/pipeline.d.ts +3 -0
- package/dist/core/pipeline.js +8 -0
- package/dist/core/provenance.d.ts +5 -0
- package/dist/core/provenanceReadiness.d.ts +2 -0
- package/dist/core/provenanceReadiness.js +220 -0
- package/dist/core/rank.d.ts +4 -0
- package/dist/core/readable.d.ts +2 -0
- package/dist/core/readable.js +75 -0
- package/dist/core/signal.d.ts +3 -0
- package/dist/core/sourceProfiles.d.ts +4 -0
- package/dist/core/types.d.ts +239 -0
- package/dist/core/utility.d.ts +2 -0
- package/dist/rest/handler.d.ts +1 -0
- package/dist/security.d.ts +15 -0
- package/dist/security.js +3 -1
- package/dist/server.d.ts +2 -0
- package/dist/server.js +2 -2
- package/dist/tools/evaluateContext.d.ts +21 -0
- package/dist/tools/evaluateContext.js +22 -1
- package/dist/tools/freshnessStamp.d.ts +1 -0
- package/dist/types.d.ts +1 -0
- package/docs/API_DESIGN.md +28 -1
- package/docs/CLIENT_SETUP.md +166 -0
- package/docs/CODEX_MCP_USAGE.md +4 -4
- package/docs/CORE_API.md +69 -5
- package/docs/CORE_MCP_BOUNDARY.md +13 -4
- package/docs/FUTURE_LANES.md +26 -3
- package/docs/HA_PRI_V2_DESIGN.md +7 -1
- package/docs/HA_PRI_V2_PRODUCTION_ENFORCEMENT_PLAN.md +414 -0
- package/docs/HUMAN_READABLE_OUTPUT_CONTRACT.md +293 -0
- package/docs/RELEASE_INTEGRITY.md +1 -1
- package/docs/RELEASE_NOTES.md +33 -5
- package/docs/SIGNAL_CONTRACT.md +200 -2
- package/package-script-guard.mjs +59 -3
- package/package.json +33 -13
- package/server.json +2 -2
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# Human-Readable Output Contract
|
|
2
|
+
|
|
3
|
+
Status: implemented MVP contract.
|
|
4
|
+
|
|
5
|
+
This document describes the reader-facing output layer over FreshContext Core decisions. The MVP is implemented as an additive Core helper and `evaluate_context` structured JSON field. It does not change Core behavior, ranking, decision labels, utility math, Worker behavior, package version, deployment state, or public site copy.
|
|
6
|
+
|
|
7
|
+
FreshContext is not truth itself. FreshContext records why context was trusted, down-ranked, questioned, refreshed, watched, backgrounded, or excluded before an AI system uses it.
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
FreshContext Core already returns machine decisions, reasons, warnings, utility, freshness, confidence, Source Profile context, and provenance material. The human-readable output layer should make those results understandable without exposing every internal score first.
|
|
12
|
+
|
|
13
|
+
The output should answer:
|
|
14
|
+
|
|
15
|
+
- Can I use this context?
|
|
16
|
+
- Why was this source treated this way?
|
|
17
|
+
- What reached the model?
|
|
18
|
+
- What was kept out?
|
|
19
|
+
- Can another agent inherit this context safely?
|
|
20
|
+
|
|
21
|
+
## Audiences
|
|
22
|
+
|
|
23
|
+
- Normal readers need a short status, reason, and warning.
|
|
24
|
+
- Analysts and buyers need an evidence table that shows why each source was treated differently.
|
|
25
|
+
- Developers need a stable JSON shape for future SDK, API, MCP, and CLI formatting.
|
|
26
|
+
- Multi-agent workflows need enough identity and judgment metadata for one agent to hand context to another without losing evidence boundaries.
|
|
27
|
+
|
|
28
|
+
## Non-Goals
|
|
29
|
+
|
|
30
|
+
This contract does not:
|
|
31
|
+
|
|
32
|
+
- certify truth
|
|
33
|
+
- provide professional guidance in legal, clinical, tax, employment, academic, or financial domains
|
|
34
|
+
- change Core scoring or ranking
|
|
35
|
+
- make utility control decision labels
|
|
36
|
+
- wire adapters into Core
|
|
37
|
+
- add `evaluate_source`
|
|
38
|
+
- define a live hosted API response
|
|
39
|
+
- replace Signal Contract v1
|
|
40
|
+
- claim Ha-Pri v2 production enforcement
|
|
41
|
+
|
|
42
|
+
## Decision Vocabulary
|
|
43
|
+
|
|
44
|
+
FreshContext should keep the current Core machine decisions as the stable machine layer.
|
|
45
|
+
|
|
46
|
+
| Machine decision | Reader label | Meaning | Human action | Agent action | Must not claim |
|
|
47
|
+
| --- | --- | --- | --- | --- | --- |
|
|
48
|
+
| `use_first` | Use first | Strong, current context for the task. | Read or place this near the top of the working context. | Prioritize in the context bundle. | This is guaranteed true. |
|
|
49
|
+
| `cite_as_primary` | Primary source | Relevant, current, and traceable enough to use as main evidence. | Use as main evidence while applying normal review. | Use as primary citation evidence. | This source proves the claim by itself. |
|
|
50
|
+
| `cite_as_supporting` | Supporting source | Useful evidence, but not enough to stand alone as the latest or strongest support. | Pair with a clearer, newer, or more authoritative source. | Include as supporting context, not sole evidence. | This is sufficient primary evidence. |
|
|
51
|
+
| `use_as_background` | Background only | Relevant context, but not strong enough for current-evidence claims. | Use for framing, history, or orientation. | Keep lower in the context bundle. | This is current proof. |
|
|
52
|
+
| `needs_verification` | Needs verification | Possibly useful, but timing, confidence, or traceability is uncertain. | Verify before relying on it. | Do not use as trusted primary context. | This source is false. |
|
|
53
|
+
| `needs_refresh` | Needs refresh | Possibly useful, but too stale or date-uncertain for this source type. | Re-query or find a newer source. | Refresh retrieval before use. | This source is useless or false. |
|
|
54
|
+
| `watch_only` | Watch only | Interesting signal, but not strong enough to prioritize. | Monitor or keep as weak signal. | Keep out of primary reasoning unless requested. | This is actionable evidence. |
|
|
55
|
+
| `exclude` | Excluded | Failed, too weak, unsafe, or not useful enough for the final context bundle. | Keep out unless manually reviewed. | Do not pass to the model as useful context. | This is legally or factually invalid. |
|
|
56
|
+
|
|
57
|
+
## Reader Card
|
|
58
|
+
|
|
59
|
+
The Reader Card is for normal humans. It should be short and decision-first.
|
|
60
|
+
|
|
61
|
+
Example:
|
|
62
|
+
|
|
63
|
+
```txt
|
|
64
|
+
Status: Primary source
|
|
65
|
+
|
|
66
|
+
Why:
|
|
67
|
+
Recent, directly relevant, and traceable enough for main evidence.
|
|
68
|
+
|
|
69
|
+
Watch-outs:
|
|
70
|
+
FreshContext does not certify truth.
|
|
71
|
+
|
|
72
|
+
What FreshContext did:
|
|
73
|
+
Ranked this source above weaker, stale, or unclear candidates before model use.
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Recommended fields:
|
|
77
|
+
|
|
78
|
+
- `status`
|
|
79
|
+
- `why`
|
|
80
|
+
- `watch_outs`
|
|
81
|
+
- `what_freshcontext_did`
|
|
82
|
+
|
|
83
|
+
The Reader Card should not lead with raw scores unless a technical user asks for them.
|
|
84
|
+
|
|
85
|
+
The current MVP is the `readable` object returned inside each structured `evaluate_context` result:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"decision": "cite_as_primary",
|
|
90
|
+
"label": "Cite as primary",
|
|
91
|
+
"readable": {
|
|
92
|
+
"label": "Primary source",
|
|
93
|
+
"summary": "This source is strong enough to use as main evidence.",
|
|
94
|
+
"why": [
|
|
95
|
+
"Strong semantic match and current freshness for arxiv.",
|
|
96
|
+
"source profile academic_research uses lenient date policy",
|
|
97
|
+
"intent profile citation_check selected"
|
|
98
|
+
],
|
|
99
|
+
"action": "Use this as main evidence while preserving citation and provenance.",
|
|
100
|
+
"warnings": [
|
|
101
|
+
"FreshContext judges citation readiness and context usefulness; it does not certify truth."
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`readable.why` is capped at five reasons to keep output readable and deterministic.
|
|
108
|
+
|
|
109
|
+
The readable object translates Core decisions into user-facing language. It does not change ranking, decision labels, utility scoring, or source intake.
|
|
110
|
+
|
|
111
|
+
## Analyst Evidence Table
|
|
112
|
+
|
|
113
|
+
The Analyst Evidence Table is for buyers, reviewers, and smart non-technical readers who need to compare multiple sources.
|
|
114
|
+
|
|
115
|
+
Recommended columns:
|
|
116
|
+
|
|
117
|
+
| Column | Plain meaning |
|
|
118
|
+
| --- | --- |
|
|
119
|
+
| Decision | How FreshContext says this context should be treated. |
|
|
120
|
+
| Source | Where the context came from. |
|
|
121
|
+
| Usefulness | How helpful the context is for this question. |
|
|
122
|
+
| Freshness | Whether the timing is current enough for this use. |
|
|
123
|
+
| Confidence | How reliable the context signal appears. |
|
|
124
|
+
| Provenance | Whether source identity and audit metadata are preserved. |
|
|
125
|
+
| Reason | Short explanation of the treatment label. |
|
|
126
|
+
| Warning | Non-advice or verification warning, if any. |
|
|
127
|
+
|
|
128
|
+
Example row:
|
|
129
|
+
|
|
130
|
+
```txt
|
|
131
|
+
Primary source | arxiv.org/... | High | Current | High | Clear | Recent, direct academic source | Does not certify truth
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Developer JSON Contract
|
|
135
|
+
|
|
136
|
+
This is a proposed future response shape for SDK, API, MCP, and CLI formatting. It is not a live API contract yet.
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"context_id": "ctx_...",
|
|
141
|
+
"decision": "cite_as_primary",
|
|
142
|
+
"reader_label": "Primary source",
|
|
143
|
+
"summary": "Recent, directly relevant source with clear provenance.",
|
|
144
|
+
"source": {
|
|
145
|
+
"id": "src_...",
|
|
146
|
+
"url": "https://example.com/source",
|
|
147
|
+
"type": "academic_research",
|
|
148
|
+
"title": "Example source"
|
|
149
|
+
},
|
|
150
|
+
"scores": {
|
|
151
|
+
"rank": 0.92,
|
|
152
|
+
"freshness": 87,
|
|
153
|
+
"utility": 81,
|
|
154
|
+
"confidence": "high"
|
|
155
|
+
},
|
|
156
|
+
"provenance": {
|
|
157
|
+
"published_at": "2026-06-01T00:00:00.000Z",
|
|
158
|
+
"retrieved_at": "2026-06-09T00:00:00.000Z",
|
|
159
|
+
"hash": "sha256:..."
|
|
160
|
+
},
|
|
161
|
+
"reasons": [
|
|
162
|
+
"Strong semantic match and current freshness for arxiv."
|
|
163
|
+
],
|
|
164
|
+
"warnings": [
|
|
165
|
+
"FreshContext judges citation readiness and context usefulness; it does not certify truth."
|
|
166
|
+
],
|
|
167
|
+
"handoff": {
|
|
168
|
+
"safe_for_agent_handoff": true,
|
|
169
|
+
"handoff_notes": []
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
The JSON layer should preserve the current Core decision label while adding a reader label and summary. It should not rename the machine decision.
|
|
175
|
+
|
|
176
|
+
## Multi-Agent Handoff Contract
|
|
177
|
+
|
|
178
|
+
A multi-agent handoff should let Agent B understand what Agent A used, rejected, or questioned without re-reading the whole original prompt.
|
|
179
|
+
|
|
180
|
+
Required fields to consider:
|
|
181
|
+
|
|
182
|
+
- `context_id`
|
|
183
|
+
- `source_id`
|
|
184
|
+
- `decision`
|
|
185
|
+
- `reader_label`
|
|
186
|
+
- `source_profile`
|
|
187
|
+
- `intent_profile`
|
|
188
|
+
- `freshness_state`
|
|
189
|
+
- `confidence_state`
|
|
190
|
+
- `utility_state`
|
|
191
|
+
- `provenance_hash`
|
|
192
|
+
- `published_at`
|
|
193
|
+
- `retrieved_at`
|
|
194
|
+
- `judged_at`
|
|
195
|
+
- `judged_by`
|
|
196
|
+
- `handoff_safe`
|
|
197
|
+
- `handoff_reason`
|
|
198
|
+
- `reasons`
|
|
199
|
+
- `warnings`
|
|
200
|
+
- `excluded_context_refs`
|
|
201
|
+
|
|
202
|
+
Example:
|
|
203
|
+
|
|
204
|
+
```json
|
|
205
|
+
{
|
|
206
|
+
"context_id": "ctx_123",
|
|
207
|
+
"source_id": "src_456",
|
|
208
|
+
"decision": "needs_verification",
|
|
209
|
+
"reader_label": "Needs verification",
|
|
210
|
+
"source_profile": "company_intel",
|
|
211
|
+
"intent_profile": "business_due_diligence",
|
|
212
|
+
"freshness_state": "unknown",
|
|
213
|
+
"confidence_state": "medium",
|
|
214
|
+
"utility_state": "partly useful",
|
|
215
|
+
"provenance_hash": "sha256:...",
|
|
216
|
+
"published_at": null,
|
|
217
|
+
"retrieved_at": "2026-06-09T00:00:00.000Z",
|
|
218
|
+
"judged_at": "2026-06-09T00:00:00.000Z",
|
|
219
|
+
"judged_by": "freshcontext-core",
|
|
220
|
+
"handoff_safe": false,
|
|
221
|
+
"handoff_reason": "Useful but missing source date; verify before primary use.",
|
|
222
|
+
"reasons": [
|
|
223
|
+
"published_at/content_date was invalid; cleared"
|
|
224
|
+
],
|
|
225
|
+
"warnings": [
|
|
226
|
+
"FreshContext supports context triage only; it is not professional legal, tax, or financial guidance."
|
|
227
|
+
],
|
|
228
|
+
"excluded_context_refs": []
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Utility Language
|
|
233
|
+
|
|
234
|
+
Utility means usefulness for the current question. It does not mean truth.
|
|
235
|
+
|
|
236
|
+
Allowed wording:
|
|
237
|
+
|
|
238
|
+
- High utility: useful for this question
|
|
239
|
+
- Medium utility: partly useful
|
|
240
|
+
- Low utility: weak fit for this question
|
|
241
|
+
|
|
242
|
+
Forbidden wording:
|
|
243
|
+
|
|
244
|
+
- true
|
|
245
|
+
- verified truth
|
|
246
|
+
- claims that accuracy is guaranteed
|
|
247
|
+
- claims that a source has official approval
|
|
248
|
+
- claims that FreshContext has settled the answer
|
|
249
|
+
|
|
250
|
+
Utility can appear in explanations and reasons, but it must not be described as controlling default decision labels unless a future policy pass explicitly changes that behavior.
|
|
251
|
+
|
|
252
|
+
## Provenance Language
|
|
253
|
+
|
|
254
|
+
Provenance means traceable source identity and audit material. It does not mean magical truth.
|
|
255
|
+
|
|
256
|
+
Allowed wording:
|
|
257
|
+
|
|
258
|
+
- clear provenance
|
|
259
|
+
- unclear provenance
|
|
260
|
+
- source identity preserved
|
|
261
|
+
- retrieval time recorded
|
|
262
|
+
- source timestamp recorded
|
|
263
|
+
- deterministic audit hash
|
|
264
|
+
|
|
265
|
+
Forbidden wording:
|
|
266
|
+
|
|
267
|
+
- absolute tamper resistance
|
|
268
|
+
- truth certification claims
|
|
269
|
+
- legal verification claims
|
|
270
|
+
- outside audit claims
|
|
271
|
+
- origin-authenticated unless a future signing model provides that guarantee
|
|
272
|
+
|
|
273
|
+
## Forbidden Claims
|
|
274
|
+
|
|
275
|
+
FreshContext output must not claim:
|
|
276
|
+
|
|
277
|
+
- it determines truth
|
|
278
|
+
- it proves correctness
|
|
279
|
+
- it replaces human review
|
|
280
|
+
- it is a legal, medical, tax, employment, academic, or investment advisor
|
|
281
|
+
- it validates facts beyond the provided context metadata
|
|
282
|
+
- it guarantees source authenticity
|
|
283
|
+
- it has production Ha-Pri v2 enforcement unless that enforcement is actually implemented
|
|
284
|
+
|
|
285
|
+
## Future Implementation Passes
|
|
286
|
+
|
|
287
|
+
Suggested next passes:
|
|
288
|
+
|
|
289
|
+
- Pass 14-D: review whether the Analyst Evidence Table should become a helper or stay documentation-only.
|
|
290
|
+
- Pass 14-E: decide whether to add human-readable text lines to `evaluate_context`, or keep the readable layer JSON-only.
|
|
291
|
+
- Later: design Diagnostic Mode on top of `why`, `warnings`, and replay mismatch evidence.
|
|
292
|
+
|
|
293
|
+
The MVP is intentionally small: it translates existing judgment into readable output without changing the judgment itself.
|
|
@@ -22,7 +22,7 @@ This document describes release hardening practices for future FreshContext pack
|
|
|
22
22
|
- Confirm fresh consumer `npm audit --omit=dev` is clean.
|
|
23
23
|
- Run a stale-claim scan across public docs and package-facing files.
|
|
24
24
|
- Run a secret scan before sharing archives, diligence folders, or package artifacts.
|
|
25
|
-
- Keep operational demo runbooks, buyer scripts, outreach plans, diligence checklists, and
|
|
25
|
+
- Keep operational demo runbooks, buyer scripts, outreach plans, diligence checklists, and private commercial materials outside the public npm package.
|
|
26
26
|
|
|
27
27
|
## Package Exclusion Checks
|
|
28
28
|
|
package/docs/RELEASE_NOTES.md
CHANGED
|
@@ -1,8 +1,36 @@
|
|
|
1
|
-
# FreshContext Release Notes
|
|
2
|
-
|
|
3
|
-
## 0.3.
|
|
4
|
-
|
|
5
|
-
FreshContext 0.3.
|
|
1
|
+
# FreshContext Release Notes
|
|
2
|
+
|
|
3
|
+
## 0.3.21
|
|
4
|
+
|
|
5
|
+
FreshContext 0.3.21 adds provenance readiness and readable handoff safety for judged context.
|
|
6
|
+
|
|
7
|
+
### Provenance Readiness
|
|
8
|
+
|
|
9
|
+
- Adds a Core `provenance_readiness` sidecar that classifies caller-provided context as `complete`, `partial`, `incomplete`, `unknown`, or `derived`.
|
|
10
|
+
- Keeps provenance readiness additive: it does not fetch sources, verify truth, change ranking, change utility scoring, or change decision-label policy.
|
|
11
|
+
- Preserves stable structured `evaluate_context` output while adding provenance readiness to each result.
|
|
12
|
+
|
|
13
|
+
### Public Contract and Boundary Gates
|
|
14
|
+
|
|
15
|
+
- Adds compatibility coverage for pre-provenance `evaluate_context` payloads.
|
|
16
|
+
- Locks Core public imports, package fixture behavior, and the `freshcontext-mcp/core` subpath surface.
|
|
17
|
+
- Audits the adapter boundary so Core remains the judgment layer, while the 21 reference tools remain optional source-intake adapters.
|
|
18
|
+
|
|
19
|
+
### Readable Handoff Safety
|
|
20
|
+
|
|
21
|
+
- Adds `readable.handoff.safe_for_agent_handoff` and `readable.handoff.reason` to structured readable output.
|
|
22
|
+
- Derives handoff safety only from the existing decision and `provenance_readiness`.
|
|
23
|
+
- Does not add multi-agent orchestration, batch handoff counts, new MCP tools, or adapter orchestration.
|
|
24
|
+
|
|
25
|
+
### Release Gate
|
|
26
|
+
|
|
27
|
+
- Adds stress coverage for ugly provenance, scoring, decision, readable output, and handoff edge cases.
|
|
28
|
+
- Pins the policy that minimal title-only legacy input is valid but needs verification.
|
|
29
|
+
- Confirms MCP smoke remains at 22 tools and package/server metadata align at 0.3.21 for this release prep.
|
|
30
|
+
|
|
31
|
+
## 0.3.19
|
|
32
|
+
|
|
33
|
+
FreshContext 0.3.19 syncs the public MCP package with the new generic `evaluate_context` interface.
|
|
6
34
|
|
|
7
35
|
### Context Evaluation Front Door
|
|
8
36
|
|
package/docs/SIGNAL_CONTRACT.md
CHANGED
|
@@ -1,9 +1,33 @@
|
|
|
1
1
|
# FreshContext Signal Contract v1
|
|
2
2
|
|
|
3
|
-
FreshContext Signal Contract v1
|
|
3
|
+
FreshContext Signal Contract v1 is the current FreshContext input standard: the stable shape for candidate context that should be judged before it reaches a model.
|
|
4
|
+
|
|
5
|
+
In plain terms:
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
candidate context -> Signal Contract v1 -> FreshContext judgment -> decision-ready context
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The Signal Contract is live product architecture. It is used by Core normalization, `evaluate_context`, bring-your-own-context demos, reference adapter signal paths, and future batch validation.
|
|
12
|
+
|
|
13
|
+
Do not rename this with future-signal terminology. Future context signals, control signals, provenance confidence signals, and richer decision metadata are optional future layers on top of this stable input shape. They are not replacements for Signal Contract v1 and are not required fields today.
|
|
4
14
|
|
|
5
15
|
It is an additive Core API. It does not change MCP tool schemas, Worker runtime behavior, D1 schema, Store scoring, feeds, or deployment behavior.
|
|
6
16
|
|
|
17
|
+
Provenance readiness is an output-side judgment over this signal material. It can warn about weak source identity or missing timing metadata without adding new required input fields.
|
|
18
|
+
|
|
19
|
+
## Batch Validation Harness
|
|
20
|
+
|
|
21
|
+
Source checkouts include a small validation harness for testing larger Signal Contract v1 batches:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm run batch:validate -- examples/batches/signal-contract-v1.academic.json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The harness reads caller-provided JSON, evaluates it through Core, summarizes status/date/decision counts, and prints a structured evidence block. It does not add required fields to the Signal Contract and does not fetch, crawl, scan folders, or call reference adapters.
|
|
28
|
+
|
|
29
|
+
Replay output includes concise decision explanations and small reason-code lists for top results and human-review mismatches. These are reporting aids for auditability: they surface whether relevance, freshness, date confidence, status, utility, score normalization, or Source Profile behavior influenced a treatment label. They do not change Core scoring, ranking, normalization, or decision thresholds, and they do not certify truth.
|
|
30
|
+
|
|
7
31
|
## Contract Version
|
|
8
32
|
|
|
9
33
|
```ts
|
|
@@ -18,7 +42,7 @@ contract_version: "freshcontext.signal.v1"
|
|
|
18
42
|
|
|
19
43
|
## Input Shape
|
|
20
44
|
|
|
21
|
-
`FreshContextSignalInput` accepts the common fields used by adapters, agents, ranking, and future Store wiring:
|
|
45
|
+
`FreshContextSignalInput` accepts the common fields used by adapters, agents, ranking, `evaluate_context`, and future Store wiring:
|
|
22
46
|
|
|
23
47
|
```ts
|
|
24
48
|
interface FreshContextSignalInput {
|
|
@@ -40,6 +64,20 @@ interface FreshContextSignalInput {
|
|
|
40
64
|
|
|
41
65
|
`published_at` is the canonical signal timestamp. `content_date` is accepted as an adapter/envelope compatibility alias.
|
|
42
66
|
|
|
67
|
+
Minimal caller-provided input usually looks like:
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"title": "Example source",
|
|
72
|
+
"content": "Candidate context text...",
|
|
73
|
+
"source": "https://example.com/source",
|
|
74
|
+
"source_type": "official_docs",
|
|
75
|
+
"published_at": "2026-06-01T00:00:00.000Z",
|
|
76
|
+
"retrieved_at": "2026-06-09T00:00:00.000Z",
|
|
77
|
+
"semantic_score": 0.92
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
43
81
|
## Normalized Output
|
|
44
82
|
|
|
45
83
|
`normalizeSignal(input, options?)` returns a `FreshContextSignal`:
|
|
@@ -73,6 +111,156 @@ interface FreshContextSignal {
|
|
|
73
111
|
- `metadata` is shallow-copied so normalization does not mutate caller-owned objects.
|
|
74
112
|
- `reasons` records meaningful normalization changes.
|
|
75
113
|
|
|
114
|
+
## Examples
|
|
115
|
+
|
|
116
|
+
These examples are intentionally small. They show the current contract shape, not future optional metadata.
|
|
117
|
+
|
|
118
|
+
### Valid Candidate Signals
|
|
119
|
+
|
|
120
|
+
Academic research:
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"title": "A fresh retrieval-augmented generation benchmark",
|
|
125
|
+
"content": "The paper reports a 2026 benchmark for retrieval-augmented generation systems.",
|
|
126
|
+
"source": "https://arxiv.org/abs/2606.00001",
|
|
127
|
+
"source_type": "arxiv",
|
|
128
|
+
"published_at": "2026-06-01T09:00:00.000Z",
|
|
129
|
+
"retrieved_at": "2026-06-09T12:00:00.000Z",
|
|
130
|
+
"semantic_score": 0.94,
|
|
131
|
+
"metadata": {
|
|
132
|
+
"profile": "academic_research"
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Official docs:
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"title": "API changelog",
|
|
142
|
+
"content": "The official changelog documents the current API behavior.",
|
|
143
|
+
"source": "https://docs.example.com/changelog",
|
|
144
|
+
"source_type": "official_docs",
|
|
145
|
+
"published_at": "2026-06-08T10:00:00.000Z",
|
|
146
|
+
"retrieved_at": "2026-06-09T12:00:00.000Z",
|
|
147
|
+
"semantic_score": 0.88
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Jobs/opportunities:
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"title": "AI tools engineer",
|
|
156
|
+
"content": "A current remote role for an AI tools engineer.",
|
|
157
|
+
"source": "https://jobs.example.com/ai-tools-engineer",
|
|
158
|
+
"source_type": "jobs",
|
|
159
|
+
"published_at": "2026-06-07T08:00:00.000Z",
|
|
160
|
+
"retrieved_at": "2026-06-09T12:00:00.000Z",
|
|
161
|
+
"semantic_score": 0.86
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Market/finance:
|
|
166
|
+
|
|
167
|
+
```json
|
|
168
|
+
{
|
|
169
|
+
"title": "Company quarterly update",
|
|
170
|
+
"content": "The company reported current quarter revenue and guidance.",
|
|
171
|
+
"source": "https://investors.example.com/q2-update",
|
|
172
|
+
"source_type": "finance",
|
|
173
|
+
"published_at": "2026-06-09T07:00:00.000Z",
|
|
174
|
+
"retrieved_at": "2026-06-09T12:00:00.000Z",
|
|
175
|
+
"semantic_score": 0.83
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Social pulse:
|
|
180
|
+
|
|
181
|
+
```json
|
|
182
|
+
{
|
|
183
|
+
"title": "Developer discussion",
|
|
184
|
+
"content": "Developers are discussing setup friction and recent adoption.",
|
|
185
|
+
"source": "https://news.ycombinator.com/item?id=123456",
|
|
186
|
+
"source_type": "hackernews",
|
|
187
|
+
"published_at": "2026-06-09T11:00:00.000Z",
|
|
188
|
+
"retrieved_at": "2026-06-09T12:00:00.000Z",
|
|
189
|
+
"semantic_score": 0.71
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Invalid Or Risky Candidate Signals
|
|
194
|
+
|
|
195
|
+
Missing date:
|
|
196
|
+
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"title": "Relevant source with no date",
|
|
200
|
+
"content": "Useful candidate context, but no publication timestamp is available.",
|
|
201
|
+
"source": "https://example.com/no-date",
|
|
202
|
+
"source_type": "official_docs",
|
|
203
|
+
"retrieved_at": "2026-06-09T12:00:00.000Z",
|
|
204
|
+
"semantic_score": 0.78
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Invalid timestamp:
|
|
209
|
+
|
|
210
|
+
```json
|
|
211
|
+
{
|
|
212
|
+
"title": "Invalid date source",
|
|
213
|
+
"content": "Candidate context with malformed date metadata.",
|
|
214
|
+
"source": "https://example.com/bad-date",
|
|
215
|
+
"source_type": "official_docs",
|
|
216
|
+
"published_at": "not-a-date",
|
|
217
|
+
"retrieved_at": "2026-06-09T12:00:00.000Z",
|
|
218
|
+
"semantic_score": 0.78
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Meaningfully future-dated timestamp:
|
|
223
|
+
|
|
224
|
+
```json
|
|
225
|
+
{
|
|
226
|
+
"title": "Future-dated source",
|
|
227
|
+
"content": "Candidate context whose publication timestamp is after retrieval time.",
|
|
228
|
+
"source": "https://example.com/future-date",
|
|
229
|
+
"source_type": "official_docs",
|
|
230
|
+
"published_at": "2026-06-09T12:06:00.000Z",
|
|
231
|
+
"retrieved_at": "2026-06-09T12:00:00.000Z",
|
|
232
|
+
"semantic_score": 0.78
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Failed/error-looking content:
|
|
237
|
+
|
|
238
|
+
```json
|
|
239
|
+
{
|
|
240
|
+
"title": "Blocked source",
|
|
241
|
+
"content": "[Error] upstream timeout",
|
|
242
|
+
"source": "https://example.com/blocked",
|
|
243
|
+
"source_type": "official_docs",
|
|
244
|
+
"published_at": "2026-06-09T10:00:00.000Z",
|
|
245
|
+
"retrieved_at": "2026-06-09T12:00:00.000Z",
|
|
246
|
+
"semantic_score": 0.91
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Out-of-range semantic score:
|
|
251
|
+
|
|
252
|
+
```json
|
|
253
|
+
{
|
|
254
|
+
"title": "Overscored source",
|
|
255
|
+
"content": "Candidate context with an out-of-range relevance score.",
|
|
256
|
+
"source": "https://example.com/overscored",
|
|
257
|
+
"source_type": "official_docs",
|
|
258
|
+
"published_at": "2026-06-09T10:00:00.000Z",
|
|
259
|
+
"retrieved_at": "2026-06-09T12:00:00.000Z",
|
|
260
|
+
"semantic_score": 1.7
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
76
264
|
## Relationship to Existing Core Types
|
|
77
265
|
|
|
78
266
|
The signal contract does not replace existing Core types:
|
|
@@ -87,3 +275,13 @@ The contract gives these surfaces a shared signal vocabulary without requiring S
|
|
|
87
275
|
## Boundary
|
|
88
276
|
|
|
89
277
|
Signal Contract v1 does not determine truth, certify data, or provide legal, medical, tax, or financial advice. It provides normalized context metadata for freshness, provenance, relevance, and workflow review.
|
|
278
|
+
|
|
279
|
+
## Future Metadata Boundary
|
|
280
|
+
|
|
281
|
+
Future context signals, control signals, ingestion quality signals, structure preservation signals, and provenance confidence signals may later improve decisions such as `cite_as_primary`, `needs_refresh`, `needs_verification`, or `exclude`.
|
|
282
|
+
|
|
283
|
+
Those are roadmap metadata layers. They should remain optional until tests prove they improve decisions. The public input contract should stay boring and stable:
|
|
284
|
+
|
|
285
|
+
```text
|
|
286
|
+
title + content + source + source_type + published_at + retrieved_at + semantic_score
|
|
287
|
+
```
|
package/package-script-guard.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
|
+
import { join } from "node:path";
|
|
4
5
|
|
|
5
6
|
const SOURCE_CHECKOUT_MESSAGE = [
|
|
6
7
|
"This npm script is for the FreshContext source checkout.",
|
|
@@ -45,6 +46,17 @@ const commands = {
|
|
|
45
46
|
args: ["examples/evaluate-file.ts", "examples/sources.academic.example.json"],
|
|
46
47
|
passThroughArgs: true,
|
|
47
48
|
},
|
|
49
|
+
"batch:validate": {
|
|
50
|
+
required: ["examples/validate-signal-batch.ts"],
|
|
51
|
+
command: "tsx",
|
|
52
|
+
args: ["examples/validate-signal-batch.ts"],
|
|
53
|
+
passThroughArgs: true,
|
|
54
|
+
},
|
|
55
|
+
"core:fixture": {
|
|
56
|
+
required: ["scripts/pack-core-fixture.mjs", "dist/core/index.js"],
|
|
57
|
+
command: "node",
|
|
58
|
+
args: ["scripts/pack-core-fixture.mjs"],
|
|
59
|
+
},
|
|
48
60
|
"smoke:stdio": {
|
|
49
61
|
required: ["scripts/smoke-stdio.mjs"],
|
|
50
62
|
command: "node",
|
|
@@ -93,12 +105,22 @@ const commands = {
|
|
|
93
105
|
"tests/arxivSignals.test.ts",
|
|
94
106
|
"tests/arxivDecisionIntegration.test.ts",
|
|
95
107
|
"tests/core.test.ts",
|
|
108
|
+
"tests/haPriV2GoldenVectors.test.ts",
|
|
109
|
+
"tests/signalContractExamples.test.ts",
|
|
110
|
+
"tests/batchValidationHarness.test.ts",
|
|
96
111
|
"tests/rank.test.ts",
|
|
97
112
|
"tests/workerEnvelope.test.ts",
|
|
113
|
+
"tests/packageScriptGuard.test.mjs",
|
|
114
|
+
"tests/corePackageFixture.test.mjs",
|
|
115
|
+
"tests/readableOutput.test.ts",
|
|
116
|
+
"tests/provenanceReadiness.test.ts",
|
|
117
|
+
"tests/adapterNetworkBoundary.test.ts",
|
|
118
|
+
"tests/workerRouteSecurity.test.ts",
|
|
98
119
|
"tests/workerCoreEnvelopeParity.test.ts",
|
|
99
120
|
"tests/coreEnvelopeOptions.test.ts",
|
|
100
121
|
"tests/mathSpine.test.ts",
|
|
101
122
|
"tests/coreApiContract.test.ts",
|
|
123
|
+
"tests/coreSubpathExport.test.mjs",
|
|
102
124
|
"tests/corePipeline.test.ts",
|
|
103
125
|
"tests/decision.test.ts",
|
|
104
126
|
"tests/evaluateContextTool.test.ts",
|
|
@@ -124,13 +146,47 @@ if (!hasSourceCheckoutFiles) {
|
|
|
124
146
|
process.exit(0);
|
|
125
147
|
}
|
|
126
148
|
|
|
149
|
+
function resolveCommand(command, args) {
|
|
150
|
+
if (command === "node") return { command: process.execPath, args };
|
|
151
|
+
|
|
152
|
+
const localNodeEntrypoints = {
|
|
153
|
+
tsx: join("node_modules", "tsx", "dist", "cli.mjs"),
|
|
154
|
+
tsc: join("node_modules", "typescript", "bin", "tsc"),
|
|
155
|
+
};
|
|
156
|
+
const nodeEntrypoint = localNodeEntrypoints[command];
|
|
157
|
+
if (nodeEntrypoint && existsSync(nodeEntrypoint)) {
|
|
158
|
+
return { command: process.execPath, args: [nodeEntrypoint, ...args] };
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const localBin = process.platform === "win32"
|
|
162
|
+
? join("node_modules", ".bin", `${command}.cmd`)
|
|
163
|
+
: join("node_modules", ".bin", command);
|
|
164
|
+
|
|
165
|
+
if (existsSync(localBin)) return { command: localBin, args };
|
|
166
|
+
if (process.platform === "win32" && !command.endsWith(".cmd")) {
|
|
167
|
+
return { command: `${command}.cmd`, args };
|
|
168
|
+
}
|
|
169
|
+
return { command, args };
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function validatePassThroughArgs(args) {
|
|
173
|
+
for (const arg of args) {
|
|
174
|
+
if (arg.includes("\0")) {
|
|
175
|
+
console.error("FreshContext package script arguments cannot contain null bytes.");
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return args;
|
|
180
|
+
}
|
|
181
|
+
|
|
127
182
|
const args = [
|
|
128
183
|
...config.args,
|
|
129
|
-
...(config.passThroughArgs ? process.argv.slice(3) : []),
|
|
184
|
+
...(config.passThroughArgs ? validatePassThroughArgs(process.argv.slice(3)) : []),
|
|
130
185
|
];
|
|
131
|
-
const
|
|
186
|
+
const invocation = resolveCommand(config.command, args);
|
|
187
|
+
const child = spawnSync(invocation.command, invocation.args, {
|
|
132
188
|
stdio: "inherit",
|
|
133
|
-
shell:
|
|
189
|
+
shell: false,
|
|
134
190
|
});
|
|
135
191
|
|
|
136
192
|
if (child.error) {
|