scoutline 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -1
- package/dist/capabilities/investigation.d.ts +134 -0
- package/dist/capabilities/investigation.d.ts.map +1 -0
- package/dist/capabilities/investigation.js +278 -0
- package/dist/capabilities/investigation.js.map +1 -0
- package/dist/commands/investigate.d.ts +232 -0
- package/dist/commands/investigate.d.ts.map +1 -0
- package/dist/commands/investigate.js +838 -0
- package/dist/commands/investigate.js.map +1 -0
- package/dist/commands/vision.d.ts.map +1 -1
- package/dist/commands/vision.js +15 -2
- package/dist/commands/vision.js.map +1 -1
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +373 -6
- package/dist/index.js.map +1 -1
- package/dist/lib/investigate-claims.d.ts +90 -0
- package/dist/lib/investigate-claims.d.ts.map +1 -0
- package/dist/lib/investigate-claims.js +188 -0
- package/dist/lib/investigate-claims.js.map +1 -0
- package/dist/lib/investigate-extract.d.ts +35 -0
- package/dist/lib/investigate-extract.d.ts.map +1 -0
- package/dist/lib/investigate-extract.js +101 -0
- package/dist/lib/investigate-extract.js.map +1 -0
- package/dist/lib/investigate-planner.d.ts +58 -0
- package/dist/lib/investigate-planner.d.ts.map +1 -0
- package/dist/lib/investigate-planner.js +141 -0
- package/dist/lib/investigate-planner.js.map +1 -0
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +4 -1
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/types.d.ts +30 -1
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/types.js.map +1 -1
- package/dist/providers/zai/adapter.d.ts.map +1 -1
- package/dist/providers/zai/adapter.js +217 -3
- package/dist/providers/zai/adapter.js.map +1 -1
- package/dist/providers/zai/layout-parsing.d.ts +76 -0
- package/dist/providers/zai/layout-parsing.d.ts.map +1 -0
- package/dist/providers/zai/layout-parsing.js +151 -0
- package/dist/providers/zai/layout-parsing.js.map +1 -0
- package/dist/providers/zai/media.d.ts +19 -0
- package/dist/providers/zai/media.d.ts.map +1 -1
- package/dist/providers/zai/media.js +61 -0
- package/dist/providers/zai/media.js.map +1 -1
- package/package.json +1 -1
- package/skills/scoutline/SKILL.md +71 -1
package/README.md
CHANGED
|
@@ -416,7 +416,7 @@ executor preflight, Provider selection, and `doctor`.
|
|
|
416
416
|
| `search` | Yes | Yes | Yes | Yes | Yes (incl. `type: "video"`) | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Parallel (declarative semantic), Jina (neural web search) |
|
|
417
417
|
| `vision.interpret-image` (analyze) | Yes | Yes | No | No | No | No | No | No | No | No | No | No | No | No | No | Provider-specific media limits; uncached |
|
|
418
418
|
| `vision.ui-artifact` (ui-to-code) | Yes | Available | No | No | No | No | No | No | No | No | No | No | No | No | No | Live-attested; conformance-gated |
|
|
419
|
-
| `vision.extract-text` | Yes | Pending | No | No | No | No | No | No | No | No | No | No | No | No | No | Implemented, pending live conformance |
|
|
419
|
+
| `vision.extract-text` | Yes (GLM-OCR engine: PDF ≤50MB, images ≤10MB, content-hash cached; exhaustion falls back to the vision model) | Pending | No | No | No | No | No | No | No | No | No | No | No | No | No | Implemented, pending live conformance |
|
|
420
420
|
| `vision.diagnose-error` | Yes | Available | No | No | No | No | No | No | No | No | No | No | No | No | No | Live-attested; conformance-gated |
|
|
421
421
|
| `vision.diagram` | Yes | Pending | No | No | No | No | No | No | No | No | No | No | No | No | No | Implemented, pending live conformance |
|
|
422
422
|
| `vision.chart` | Yes | Pending | No | No | No | No | No | No | No | No | No | No | No | No | No | Implemented, pending live conformance |
|
|
@@ -428,6 +428,7 @@ executor preflight, Provider selection, and `doctor`.
|
|
|
428
428
|
| `crawl` | **No** | **No** | Yes | No | No | Yes (async) | No | No | No | No | No | Yes (sync) | No | **No** | No | Tavily sync; Firecrawl async (resumable after Ctrl-C) |
|
|
429
429
|
| `map` | **No** | **No** | Yes | No | No | Yes | No | No | No | No | No | Yes | No | **No** | No | URL-set discovery; no per-page content |
|
|
430
430
|
| `research` | **No** | **No** | Yes | Yes | **No** | **No** | Yes | Yes | Yes | Yes | Yes | No | No | **No** | No | Tavily, Exa, Parallel, Perplexity (Agent API `high` preset), Jina DeepSearch, You.com, and Linkup research report synthesis |
|
|
431
|
+
| `investigation` (EvidencePack) | Yes | **No** (no reader) | Yes | Yes | **No** (no reader) | Yes | Yes | **No** (no reader) | Yes | Yes | Yes | Yes | **No** (no reader) | **No** (no reader) | **No** (no reader) | Provider-composed — supplied by the search+reader supplier union (Z.AI, Tavily, Exa, Firecrawl, Parallel, Jina AI, You.com, Linkup, Spider.cloud); `--synthesize` is Z.AI-only |
|
|
431
432
|
| `repo search` / `repo read` / `repo tree` / `repo brief` | Yes | **No** | **No** | **No** | **No** | **No** | **No** | **No** | **No** | No | No | No | No | No | No | Participates in selection; only Z.AI supplies `repository-exploration` |
|
|
432
433
|
| `tools`, `tool`, `call` (Raw tools) | Yes | No | No | No | No | No | No | No | No | No | No | No | No | No | No | Z.AI-only; accepts but ignores `--provider` |
|
|
433
434
|
| `code` (Code Mode) | Yes | No | No | No | No | No | No | No | No | No | No | No | No | No | No | Z.AI-only; accepts but ignores `--provider` |
|
|
@@ -525,6 +526,53 @@ the supplier wire supports them (rejected with `UNSUPPORTED_OPTION`
|
|
|
525
526
|
elsewhere — never silently dropped). `science get <identifier>` fetches
|
|
526
527
|
one work by bare DOI, numeric PMID, or arXiv id.
|
|
527
528
|
|
|
529
|
+
### Investigation (`investigate`)
|
|
530
|
+
|
|
531
|
+
`scoutline investigate <question>` runs a local, transparent,
|
|
532
|
+
cache-resumable pipeline ([ADR-0013](https://github.com/vikasagarwal101/scoutline/blob/main/docs/adr/0013-local-investigation-pipeline.md)):
|
|
533
|
+
plan sub-queries → fan-out search → Fusion merge → read the top
|
|
534
|
+
`--sources` (default 5) → deterministic passage extraction → an
|
|
535
|
+
EvidencePack (`schemaVersion` 1). No provider-side job runs — distinct
|
|
536
|
+
from Research, an opaque billed provider job. The pack is data, not
|
|
537
|
+
prose: agents consume it directly and text output modes fall back to
|
|
538
|
+
JSON (agent-synthesis is the default; you write the prose). Warm re-runs
|
|
539
|
+
replay the response cache (`coverage.cacheHits` reflects it).
|
|
540
|
+
|
|
541
|
+
```bash
|
|
542
|
+
scoutline investigate "rust async runtime benchmarks"
|
|
543
|
+
scoutline investigate "rust async | rust tokio" # pipes split explicit sub-queries
|
|
544
|
+
scoutline investigate "topic" --provider tavily,exa --sources 8
|
|
545
|
+
scoutline investigate "topic" --max-chars 20000 --synthesize
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
Sub-query planning precedence: explicit pipes (the `--merge` grammar) >
|
|
549
|
+
`--context <path>` (a local notes file — it never leaves the machine,
|
|
550
|
+
only the derived sub-query strings are searched) > deterministic
|
|
551
|
+
templates of the bare question (original, key terms,
|
|
552
|
+
overview/evidence/criticism; deduped, capped at 5). Provider selection
|
|
553
|
+
reuses search's fan-out activation tiers verbatim (comma-list/`all`
|
|
554
|
+
fan-out, single pin, `config set fanout true`). Cost is stated in one
|
|
555
|
+
stderr notice before any billable work: N sub-queries × M arms billable
|
|
556
|
+
searches + up to K reads.
|
|
557
|
+
|
|
558
|
+
Controls: `--sources <n>`, `--max-chars <n>` (passages trim first, late
|
|
559
|
+
sources drop; the full untrimmed pack is saved and recoverable via
|
|
560
|
+
`scoutline history show <ref>`), `--no-cache`, `--no-journal`, `--save`,
|
|
561
|
+
`--isolated`. Sources surfaced but unread land in `coverage.unread` with
|
|
562
|
+
a reason code — never silently dropped. `--synthesize` attaches an
|
|
563
|
+
additive `brief` via Z.AI chat (Z.AI-only; absent by default; a
|
|
564
|
+
synthesis failure is the run's terminal error, never a degraded pack).
|
|
565
|
+
`--depth`, `--arms`, and `--budget-tokens` are rejected with
|
|
566
|
+
`VALIDATION_ERROR` by design.
|
|
567
|
+
|
|
568
|
+
`--verify` turns the positional into a statement: sentence-claims
|
|
569
|
+
(≤ 8, fail-loud) are searched verbatim and matched to the extracted
|
|
570
|
+
passages; the pack gains an additive `verify` block — per claim, a
|
|
571
|
+
verdict (`corroborated` / `contradicted` / `unresolved`), evidence
|
|
572
|
+
pointers, and a negation-cue count. `contradicted` is a disclosed
|
|
573
|
+
negation-cue heuristic (hint-grade), not semantic judgment;
|
|
574
|
+
`--context` + `--verify` is a mode-conflict VALIDATION_ERROR.
|
|
575
|
+
|
|
528
576
|
## Usage
|
|
529
577
|
|
|
530
578
|
The CLI is self-documenting. Use `--help` at any level:
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EvidencePack schema + total decoder (T1, docs/plans/investigate-pipeline
|
|
3
|
+
* PRD AC-6; ADR-0013 §7).
|
|
4
|
+
*
|
|
5
|
+
* The EvidencePack is the self-contained deliverable of an Investigation
|
|
6
|
+
* (CONTEXT.md glossary): question, sub-queries, sources with per-source
|
|
7
|
+
* content hashes and extracted passages, and a coverage block. The pack is
|
|
8
|
+
* data, not prose — agent-synthesis is the contract; `--synthesize` (T7)
|
|
9
|
+
* attaches a `brief` additively and is not part of this schema.
|
|
10
|
+
*
|
|
11
|
+
* This module declares the pack type, its total decoder, and the
|
|
12
|
+
* contentSha256 shape predicate. It imports NOTHING from other src modules
|
|
13
|
+
* (self-contained by ticket contract; hashing itself lands in T5 — this
|
|
14
|
+
* module only validates hash *shape*).
|
|
15
|
+
*
|
|
16
|
+
* Decoder discipline mirrors capabilities/reader.ts exactly:
|
|
17
|
+
* - accepts `unknown`, returns the pack or `null`, never throws,
|
|
18
|
+
* never trusts a generic cast;
|
|
19
|
+
* - reject primitives and arrays at the top level;
|
|
20
|
+
* - `schemaVersion` MUST be the literal number 1 (rejects "1", 1.5,
|
|
21
|
+
* bigints, any future version);
|
|
22
|
+
* - `title: null` is a valid decoded value (reader parity);
|
|
23
|
+
* - optional fields preserved verbatim when present.
|
|
24
|
+
*/
|
|
25
|
+
/** `[start, end)` character offsets into the source `content` string. */
|
|
26
|
+
export type CharRange = readonly [number, number];
|
|
27
|
+
/**
|
|
28
|
+
* One extracted passage. `quote` is pinned to the content by `charRange`:
|
|
29
|
+
* `content.slice(...charRange) === quote` for every passage (D4). The pin
|
|
30
|
+
* is enforced where content is available (assembly in T5, extraction in
|
|
31
|
+
* T3); the decoder enforces the shape so a decoded pack is at least
|
|
32
|
+
* structurally sound.
|
|
33
|
+
*/
|
|
34
|
+
export interface EvidencePassage {
|
|
35
|
+
readonly quote: string;
|
|
36
|
+
readonly charRange: CharRange;
|
|
37
|
+
}
|
|
38
|
+
/** One read source: reader-envelope fields + passages. */
|
|
39
|
+
export interface EvidenceSource {
|
|
40
|
+
readonly url: string;
|
|
41
|
+
/** The URL the Reader actually fetched (provider rewrite possible). */
|
|
42
|
+
readonly finalUrl: string;
|
|
43
|
+
/** Page title if the provider returned one; `null` if absent (reader parity). */
|
|
44
|
+
readonly title: string | null;
|
|
45
|
+
/** ISO-8601 UTC Z timestamp captured when the read resolved (D5). */
|
|
46
|
+
readonly fetchedAt: string;
|
|
47
|
+
/** Provider id that surfaced the source (search-arm winner). */
|
|
48
|
+
readonly provider: string;
|
|
49
|
+
/** Mirrors the read `format`; `"markdown"` or `"text"`. */
|
|
50
|
+
readonly contentFormat: "markdown" | "text";
|
|
51
|
+
/** Lowercase hex SHA-256 of the UTF-8 normalized content string (D5). */
|
|
52
|
+
readonly contentSha256: string;
|
|
53
|
+
readonly passages: readonly EvidencePassage[];
|
|
54
|
+
}
|
|
55
|
+
/** Coverage block: how much of the planned grid actually produced evidence. */
|
|
56
|
+
export interface EvidenceCoverage {
|
|
57
|
+
/** Number of planned sub-queries. */
|
|
58
|
+
readonly subQueries: number;
|
|
59
|
+
/** Number of search arms actually used. */
|
|
60
|
+
readonly armsUsed: number;
|
|
61
|
+
/** Number of post-cluster candidate sources surfaced. */
|
|
62
|
+
readonly sourcesConsidered: number;
|
|
63
|
+
/** Number of sources whose read resolved successfully. */
|
|
64
|
+
readonly sourcesRead: number;
|
|
65
|
+
/** Count of search arms + reads served warm from cache (D5). */
|
|
66
|
+
readonly cacheHits: number;
|
|
67
|
+
/**
|
|
68
|
+
* Sources surfaced but not read, each with a reason code only —
|
|
69
|
+
* redacted, no error prose crossing the interface (house rule, D5).
|
|
70
|
+
*/
|
|
71
|
+
readonly unread: readonly {
|
|
72
|
+
readonly url: string;
|
|
73
|
+
readonly reason: string;
|
|
74
|
+
}[];
|
|
75
|
+
}
|
|
76
|
+
/** The self-contained Investigation deliverable (PRD AC-6). */
|
|
77
|
+
export interface EvidencePack {
|
|
78
|
+
readonly schemaVersion: 1;
|
|
79
|
+
readonly question: string;
|
|
80
|
+
readonly subQueries: readonly string[];
|
|
81
|
+
readonly sources: readonly EvidenceSource[];
|
|
82
|
+
readonly coverage: EvidenceCoverage;
|
|
83
|
+
/**
|
|
84
|
+
* investigate-verify lane T2 (PRD AC-6): the additive claim-
|
|
85
|
+
* corroboration block. ABSENT on question-mode packs (byte-identity
|
|
86
|
+
* pin); present only when `investigate --verify` assembled the pack.
|
|
87
|
+
*/
|
|
88
|
+
readonly verify?: VerifyBlock;
|
|
89
|
+
}
|
|
90
|
+
/** The deterministic verdict vocabulary (cue heuristic, PRD AC-5). */
|
|
91
|
+
export type ClaimVerdict = "corroborated" | "contradicted" | "unresolved";
|
|
92
|
+
/** One evidence pointer into the pack's own `sources` array. */
|
|
93
|
+
export interface ClaimEvidencePointer {
|
|
94
|
+
readonly sourceIndex: number;
|
|
95
|
+
readonly passageIndex: number;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* One claim row: the claim text, its verdict, the count of cue-bearing
|
|
99
|
+
* matching passages (agent re-judgment input — the cue heuristic is
|
|
100
|
+
* DISCLOSED hint-grade), and first-encounter evidence pointers.
|
|
101
|
+
*/
|
|
102
|
+
export interface ClaimRow {
|
|
103
|
+
readonly text: string;
|
|
104
|
+
readonly verdict: ClaimVerdict;
|
|
105
|
+
readonly negationCues: number;
|
|
106
|
+
readonly evidence: readonly ClaimEvidencePointer[];
|
|
107
|
+
}
|
|
108
|
+
/** The additive verify block: the statement plus one row per claim. */
|
|
109
|
+
export interface VerifyBlock {
|
|
110
|
+
readonly statement: string;
|
|
111
|
+
readonly claims: readonly ClaimRow[];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* `contentSha256` validity: a 64-character lowercase hex string —
|
|
115
|
+
* the exact shape of `createHash("sha256")…digest("hex")` output.
|
|
116
|
+
* Ruling (ticket T1): hex-shape is enforced at decode, so an
|
|
117
|
+
* uppercased, truncated, or non-hex string fails closed. Full
|
|
118
|
+
* recompute-vs-content binding belongs to assembly (T5), which is the
|
|
119
|
+
* only place the paired content string exists.
|
|
120
|
+
*/
|
|
121
|
+
export declare function isValidContentSha256(value: unknown): value is string;
|
|
122
|
+
/**
|
|
123
|
+
* Decode an `unknown` value into a canonical `EvidencePack`. Returns the
|
|
124
|
+
* typed pack on success, `null` for any malformed value. NEVER throws,
|
|
125
|
+
* NEVER trusts a generic cast.
|
|
126
|
+
*
|
|
127
|
+
* `title: null` is valid (reader parity). `sources` and `passages` may be
|
|
128
|
+
* empty arrays (a pack whose every read failed is still a valid, sad pack).
|
|
129
|
+
* `brief` (T7) is additive: unknown keys are NOT rejected — a decoded pack
|
|
130
|
+
* carries exactly the AC-6 keys, and an input carrying extra keys decodes
|
|
131
|
+
* to the canonical subset.
|
|
132
|
+
*/
|
|
133
|
+
export declare function decodeInvestigationPack(value: unknown): EvidencePack | null;
|
|
134
|
+
//# sourceMappingURL=investigation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"investigation.d.ts","sourceRoot":"","sources":["../../src/capabilities/investigation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EvidencePack schema + total decoder (T1, docs/plans/investigate-pipeline
|
|
3
|
+
* PRD AC-6; ADR-0013 §7).
|
|
4
|
+
*
|
|
5
|
+
* The EvidencePack is the self-contained deliverable of an Investigation
|
|
6
|
+
* (CONTEXT.md glossary): question, sub-queries, sources with per-source
|
|
7
|
+
* content hashes and extracted passages, and a coverage block. The pack is
|
|
8
|
+
* data, not prose — agent-synthesis is the contract; `--synthesize` (T7)
|
|
9
|
+
* attaches a `brief` additively and is not part of this schema.
|
|
10
|
+
*
|
|
11
|
+
* This module declares the pack type, its total decoder, and the
|
|
12
|
+
* contentSha256 shape predicate. It imports NOTHING from other src modules
|
|
13
|
+
* (self-contained by ticket contract; hashing itself lands in T5 — this
|
|
14
|
+
* module only validates hash *shape*).
|
|
15
|
+
*
|
|
16
|
+
* Decoder discipline mirrors capabilities/reader.ts exactly:
|
|
17
|
+
* - accepts `unknown`, returns the pack or `null`, never throws,
|
|
18
|
+
* never trusts a generic cast;
|
|
19
|
+
* - reject primitives and arrays at the top level;
|
|
20
|
+
* - `schemaVersion` MUST be the literal number 1 (rejects "1", 1.5,
|
|
21
|
+
* bigints, any future version);
|
|
22
|
+
* - `title: null` is a valid decoded value (reader parity);
|
|
23
|
+
* - optional fields preserved verbatim when present.
|
|
24
|
+
*/
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Field predicates
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
function isPlainObject(value) {
|
|
29
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
30
|
+
}
|
|
31
|
+
function isNonEmptyString(value) {
|
|
32
|
+
return typeof value === "string" && value.length > 0;
|
|
33
|
+
}
|
|
34
|
+
function isFiniteNumber(value) {
|
|
35
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* `contentSha256` validity: a 64-character lowercase hex string —
|
|
39
|
+
* the exact shape of `createHash("sha256")…digest("hex")` output.
|
|
40
|
+
* Ruling (ticket T1): hex-shape is enforced at decode, so an
|
|
41
|
+
* uppercased, truncated, or non-hex string fails closed. Full
|
|
42
|
+
* recompute-vs-content binding belongs to assembly (T5), which is the
|
|
43
|
+
* only place the paired content string exists.
|
|
44
|
+
*/
|
|
45
|
+
export function isValidContentSha256(value) {
|
|
46
|
+
if (typeof value !== "string" || value.length !== 64)
|
|
47
|
+
return false;
|
|
48
|
+
for (const ch of value) {
|
|
49
|
+
const code = ch.charCodeAt(0);
|
|
50
|
+
const isDigit = code >= 48 && code <= 57;
|
|
51
|
+
const isLowerHex = (code >= 97 && code <= 102) || isDigit;
|
|
52
|
+
if (!isLowerHex)
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
// Total decoder
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
function decodeCharRange(value) {
|
|
61
|
+
// PR #264 F2: the documented `[start, end)` invariant, enforced at
|
|
62
|
+
// decode — safe integers, non-negative start, strictly increasing
|
|
63
|
+
// (an empty range cannot quote a non-empty passage).
|
|
64
|
+
return (Array.isArray(value) &&
|
|
65
|
+
value.length === 2 &&
|
|
66
|
+
Number.isSafeInteger(value[0]) &&
|
|
67
|
+
Number.isSafeInteger(value[1]) &&
|
|
68
|
+
value[0] >= 0 &&
|
|
69
|
+
value[1] > value[0]);
|
|
70
|
+
}
|
|
71
|
+
function decodePassage(value) {
|
|
72
|
+
if (!isPlainObject(value))
|
|
73
|
+
return null;
|
|
74
|
+
if (!isNonEmptyString(value.quote))
|
|
75
|
+
return null;
|
|
76
|
+
if (!decodeCharRange(value.charRange))
|
|
77
|
+
return null;
|
|
78
|
+
return { quote: value.quote, charRange: [value.charRange[0], value.charRange[1]] };
|
|
79
|
+
}
|
|
80
|
+
function decodeSource(value) {
|
|
81
|
+
if (!isPlainObject(value))
|
|
82
|
+
return null;
|
|
83
|
+
if (!isNonEmptyString(value.url))
|
|
84
|
+
return null;
|
|
85
|
+
if (!isNonEmptyString(value.finalUrl))
|
|
86
|
+
return null;
|
|
87
|
+
const title = value.title;
|
|
88
|
+
if (title !== null && typeof title !== "string")
|
|
89
|
+
return null;
|
|
90
|
+
if (!isNonEmptyString(value.fetchedAt))
|
|
91
|
+
return null;
|
|
92
|
+
if (!isNonEmptyString(value.provider))
|
|
93
|
+
return null;
|
|
94
|
+
if (value.contentFormat !== "markdown" && value.contentFormat !== "text")
|
|
95
|
+
return null;
|
|
96
|
+
if (!isValidContentSha256(value.contentSha256))
|
|
97
|
+
return null;
|
|
98
|
+
if (!Array.isArray(value.passages))
|
|
99
|
+
return null;
|
|
100
|
+
const passages = [];
|
|
101
|
+
for (const raw of value.passages) {
|
|
102
|
+
const passage = decodePassage(raw);
|
|
103
|
+
if (passage === null)
|
|
104
|
+
return null;
|
|
105
|
+
passages.push(passage);
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
url: value.url,
|
|
109
|
+
finalUrl: value.finalUrl,
|
|
110
|
+
title: title,
|
|
111
|
+
fetchedAt: value.fetchedAt,
|
|
112
|
+
provider: value.provider,
|
|
113
|
+
contentFormat: value.contentFormat,
|
|
114
|
+
contentSha256: value.contentSha256,
|
|
115
|
+
passages,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function decodeCoverage(value) {
|
|
119
|
+
if (!isPlainObject(value))
|
|
120
|
+
return null;
|
|
121
|
+
if (!isFiniteNumber(value.subQueries))
|
|
122
|
+
return null;
|
|
123
|
+
if (!isFiniteNumber(value.armsUsed))
|
|
124
|
+
return null;
|
|
125
|
+
if (!isFiniteNumber(value.sourcesConsidered))
|
|
126
|
+
return null;
|
|
127
|
+
if (!isFiniteNumber(value.sourcesRead))
|
|
128
|
+
return null;
|
|
129
|
+
if (!isFiniteNumber(value.cacheHits))
|
|
130
|
+
return null;
|
|
131
|
+
if (!Array.isArray(value.unread))
|
|
132
|
+
return null;
|
|
133
|
+
const unread = [];
|
|
134
|
+
for (const raw of value.unread) {
|
|
135
|
+
if (!isPlainObject(raw))
|
|
136
|
+
return null;
|
|
137
|
+
if (!isNonEmptyString(raw.url))
|
|
138
|
+
return null;
|
|
139
|
+
if (!isNonEmptyString(raw.reason))
|
|
140
|
+
return null;
|
|
141
|
+
unread.push({ url: raw.url, reason: raw.reason });
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
subQueries: value.subQueries,
|
|
145
|
+
armsUsed: value.armsUsed,
|
|
146
|
+
sourcesConsidered: value.sourcesConsidered,
|
|
147
|
+
sourcesRead: value.sourcesRead,
|
|
148
|
+
cacheHits: value.cacheHits,
|
|
149
|
+
unread,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Decode an `unknown` value into a canonical `EvidencePack`. Returns the
|
|
154
|
+
* typed pack on success, `null` for any malformed value. NEVER throws,
|
|
155
|
+
* NEVER trusts a generic cast.
|
|
156
|
+
*
|
|
157
|
+
* `title: null` is valid (reader parity). `sources` and `passages` may be
|
|
158
|
+
* empty arrays (a pack whose every read failed is still a valid, sad pack).
|
|
159
|
+
* `brief` (T7) is additive: unknown keys are NOT rejected — a decoded pack
|
|
160
|
+
* carries exactly the AC-6 keys, and an input carrying extra keys decodes
|
|
161
|
+
* to the canonical subset.
|
|
162
|
+
*/
|
|
163
|
+
export function decodeInvestigationPack(value) {
|
|
164
|
+
// PR #264 F1: total containment for the never-throws contract — a
|
|
165
|
+
// throwing getter or Proxy trap on untrusted input must surface as
|
|
166
|
+
// a fail-closed null, never as an exception out of the decoder.
|
|
167
|
+
try {
|
|
168
|
+
return decodeInvestigationPackInner(value);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function decodeInvestigationPackInner(value) {
|
|
175
|
+
if (!isPlainObject(value))
|
|
176
|
+
return null;
|
|
177
|
+
if (value.schemaVersion !== 1)
|
|
178
|
+
return null;
|
|
179
|
+
if (!isNonEmptyString(value.question))
|
|
180
|
+
return null;
|
|
181
|
+
if (!Array.isArray(value.subQueries))
|
|
182
|
+
return null;
|
|
183
|
+
for (const q of value.subQueries) {
|
|
184
|
+
if (!isNonEmptyString(q))
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
if (!Array.isArray(value.sources))
|
|
188
|
+
return null;
|
|
189
|
+
const sources = [];
|
|
190
|
+
for (const raw of value.sources) {
|
|
191
|
+
const source = decodeSource(raw);
|
|
192
|
+
if (source === null)
|
|
193
|
+
return null;
|
|
194
|
+
sources.push(source);
|
|
195
|
+
}
|
|
196
|
+
const coverage = decodeCoverage(value.coverage);
|
|
197
|
+
if (coverage === null)
|
|
198
|
+
return null;
|
|
199
|
+
// investigate-verify lane T2 (D4): additive-optional `verify` — absent
|
|
200
|
+
// keeps the canonical subset (question-mode byte identity); present is
|
|
201
|
+
// validated row-by-row and fails closed on any malformed row.
|
|
202
|
+
const verify = decodeVerifyBlock(value.verify, sources.length, (sourceIndex) => sources[sourceIndex] === undefined ? 0 : sources[sourceIndex].passages.length);
|
|
203
|
+
if (verify === undefined)
|
|
204
|
+
return null;
|
|
205
|
+
return {
|
|
206
|
+
schemaVersion: 1,
|
|
207
|
+
question: value.question,
|
|
208
|
+
subQueries: [...value.subQueries],
|
|
209
|
+
sources,
|
|
210
|
+
coverage,
|
|
211
|
+
...(verify !== null ? { verify } : {}),
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
const CLAIM_VERDICTS = ["corroborated", "contradicted", "unresolved"];
|
|
215
|
+
/**
|
|
216
|
+
* Decode the additive verify block. `undefined` = malformed (the caller
|
|
217
|
+
* fails closed); `null` = absent (the canonical subset stands); the
|
|
218
|
+
* decoded block = present + valid.
|
|
219
|
+
*
|
|
220
|
+
* PR #270 babysit: pointer RANGE is cross-checked against the decoded
|
|
221
|
+
* sources of the SAME pack (sourceIndex < sourceCount; passageIndex <
|
|
222
|
+
* that source's passage count) — a shape-safe but out-of-range pointer
|
|
223
|
+
* is malformed, INCLUDING any pointer into a zero-source pack (it can
|
|
224
|
+
* never dereference; assembly emits empty evidence there by
|
|
225
|
+
* construction, so only hand-built input reaches that arm).
|
|
226
|
+
*/
|
|
227
|
+
function decodeVerifyBlock(value, sourceCount, passageCountAt) {
|
|
228
|
+
if (value === undefined)
|
|
229
|
+
return null;
|
|
230
|
+
if (!isPlainObject(value))
|
|
231
|
+
return undefined;
|
|
232
|
+
if (!isNonEmptyString(value.statement))
|
|
233
|
+
return undefined;
|
|
234
|
+
if (!Array.isArray(value.claims))
|
|
235
|
+
return undefined;
|
|
236
|
+
const claims = [];
|
|
237
|
+
for (const raw of value.claims) {
|
|
238
|
+
if (!isPlainObject(raw))
|
|
239
|
+
return undefined;
|
|
240
|
+
if (!isNonEmptyString(raw.text))
|
|
241
|
+
return undefined;
|
|
242
|
+
if (typeof raw.verdict !== "string" || !CLAIM_VERDICTS.includes(raw.verdict)) {
|
|
243
|
+
return undefined;
|
|
244
|
+
}
|
|
245
|
+
if (typeof raw.negationCues !== "number" ||
|
|
246
|
+
!Number.isSafeInteger(raw.negationCues) ||
|
|
247
|
+
raw.negationCues < 0) {
|
|
248
|
+
return undefined;
|
|
249
|
+
}
|
|
250
|
+
if (!Array.isArray(raw.evidence))
|
|
251
|
+
return undefined;
|
|
252
|
+
const evidence = [];
|
|
253
|
+
for (const pointer of raw.evidence) {
|
|
254
|
+
if (!isPlainObject(pointer))
|
|
255
|
+
return undefined;
|
|
256
|
+
if (!isSafeIndex(pointer.sourceIndex) || !isSafeIndex(pointer.passageIndex)) {
|
|
257
|
+
return undefined;
|
|
258
|
+
}
|
|
259
|
+
if (pointer.sourceIndex >= sourceCount ||
|
|
260
|
+
pointer.passageIndex >= passageCountAt(pointer.sourceIndex)) {
|
|
261
|
+
return undefined;
|
|
262
|
+
}
|
|
263
|
+
evidence.push({ sourceIndex: pointer.sourceIndex, passageIndex: pointer.passageIndex });
|
|
264
|
+
}
|
|
265
|
+
claims.push({
|
|
266
|
+
text: raw.text,
|
|
267
|
+
verdict: raw.verdict,
|
|
268
|
+
negationCues: raw.negationCues,
|
|
269
|
+
evidence,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
return { statement: value.statement, claims };
|
|
273
|
+
}
|
|
274
|
+
/** Finite, safe, non-negative integer index (evidence pointer guard). */
|
|
275
|
+
function isSafeIndex(value) {
|
|
276
|
+
return (typeof value === "number" && Number.isSafeInteger(value) && value >= 0);
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=investigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"investigation.js","sourceRoot":"","sources":["../../src/capabilities/investigation.ts"],"names":[],"mappings":"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"}
|