@typedstandards/civic-typed-harness 0.1.0 → 0.3.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/CHANGELOG.md +109 -0
- package/README.md +28 -10
- package/dist/capture/provenance.d.ts +17 -6
- package/dist/capture/provenance.js +42 -32
- package/dist/capture/trace.d.ts +6 -4
- package/dist/capture/trace.js +7 -5
- package/dist/format/dathere.d.ts +8 -6
- package/dist/format/dathere.js +8 -6
- package/dist/format/sources.d.ts +5 -4
- package/dist/format/sources.js +9 -7
- package/dist/format/vocabulary.d.ts +56 -11
- package/dist/format/vocabulary.js +59 -21
- package/dist/required-config.assert.d.ts +1 -0
- package/dist/required-config.assert.js +27 -0
- package/dist/rubric/adversarial-eval-core.d.ts +7 -3
- package/dist/rubric/adversarial-eval-core.js +5 -1
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,115 @@
|
|
|
3
3
|
Factual record of what changed per published version. Section references are
|
|
4
4
|
to the Typed Standards specification unless noted otherwise.
|
|
5
5
|
|
|
6
|
+
## 0.3.0 — 2026-08-20
|
|
7
|
+
|
|
8
|
+
**Settlement-era civic vocabulary + produce-core 0.3.0**
|
|
9
|
+
([civic-ai-tools#160](https://github.com/npstorey/civic-ai-tools/issues/160) —
|
|
10
|
+
the 2026-08-19 vocabulary settlement, [ADR-0025](../../docs/adr/0025-vocabulary-settlement-evidence-excision.md);
|
|
11
|
+
canonical mapping in the specification's **Appendix J**, migration class
|
|
12
|
+
*frozen-in-signed-artifacts*). Minor, not breaking: no existing export is
|
|
13
|
+
removed or retyped, and no already-published package changes.
|
|
14
|
+
|
|
15
|
+
- **New emissions mint the settlement-era vocabulary.** `CIVIC_NS` becomes
|
|
16
|
+
`https://civicaitools.org/ns/civic/` (was
|
|
17
|
+
`https://civicaitools.org/ns/evidence/`) and `CIVIC_URN_PREFIX` becomes
|
|
18
|
+
`urn:civic-record` (was `urn:civic-evidence`). Every id emitted by
|
|
19
|
+
`buildProvenanceGraph` and every `civic:` `@context` entry moves with them.
|
|
20
|
+
**A package produced by this version is not byte-identical to one produced
|
|
21
|
+
by 0.2.0 from the same inputs** — the graph is inside the hashed envelope,
|
|
22
|
+
so its envelope hash differs. Packages already signed under 0.2.0 are
|
|
23
|
+
untouched and remain verifiable exactly as published.
|
|
24
|
+
- **The prior era stays available, exported, and reproducible.** New:
|
|
25
|
+
`PRIOR_ERA_CIVIC_NS`, `PRIOR_ERA_CIVIC_URN_PREFIX`, the `CivicVocabulary`
|
|
26
|
+
type, `makeCivicVocabulary(ns, urnPrefix)`, and the two bound eras
|
|
27
|
+
`CIVIC_VOCABULARY` / `PRIOR_ERA_CIVIC_VOCABULARY`. `ProvenanceConfig` gains
|
|
28
|
+
an optional `vocabulary` field defaulting to `CIVIC_VOCABULARY`. Supplying
|
|
29
|
+
`PRIOR_ERA_CIVIC_VOCABULARY` reproduces a pre-settlement record
|
|
30
|
+
byte-for-byte — the only sanctioned use; it is never for new emissions.
|
|
31
|
+
Unlike the other `ProvenanceConfig` fields this one is defaulted rather than
|
|
32
|
+
required: emitting the current vocabulary is not the silent-attribution
|
|
33
|
+
hazard ADR-0024 guards against.
|
|
34
|
+
- **Unchanged signatures.** `civicUrn`, `civicModelUrn`, `civicSourceAgentUrn`,
|
|
35
|
+
`civicPlatformUrn`, and `makeCivicProvContext` keep their exact signatures
|
|
36
|
+
and now delegate to `CIVIC_VOCABULARY`, so callers of the settlement era need
|
|
37
|
+
no edits.
|
|
38
|
+
- **`buildEvaluationPrompt` takes `RecordPackage`** — produce-core 0.3.0's
|
|
39
|
+
settlement-era name for the same object (Appendix J, *alias-and-deprecate*).
|
|
40
|
+
`EvidencePackage` remains a deprecated upstream alias of that exact type, so
|
|
41
|
+
existing callers still compile; the rubric test suite deliberately stays on
|
|
42
|
+
the prior name as the executable alias proof.
|
|
43
|
+
- **Dependency floor raised:** `@typedstandards/produce-core` `^0.2.0` →
|
|
44
|
+
`^0.3.0`, and the `@typedstandards/verify-core` devDependency `^0.8.0` →
|
|
45
|
+
`^0.9.0` to match the version produce-core 0.3.0 resolves (same-commit
|
|
46
|
+
manifest bump across a minor boundary). No behavior-affecting patch bumps
|
|
47
|
+
ride along.
|
|
48
|
+
- **Both eras are under test.** The two captured fixtures
|
|
49
|
+
(`reference-golden.json`, `website-golden.json`) predate the settlement and
|
|
50
|
+
are not edited: their byte- and hash-parity legs now run with the prior-era
|
|
51
|
+
vocabulary injected, and a settlement-era leg asserts the same reference
|
|
52
|
+
bytes with exactly the two Appendix J literals substituted, with the hashes
|
|
53
|
+
recomputed from those substituted bytes by verify-core's shared chain. The
|
|
54
|
+
per-canonicalization-rule consequence is pinned explicitly: under
|
|
55
|
+
`legacy-json/v1` the era flip moves `contentHash` (the whole package is
|
|
56
|
+
fingerprinted, provenance included); under `dathere-ag-jupyter/v1` it does
|
|
57
|
+
not (only the executed notebook is). The envelope hash moves under both.
|
|
58
|
+
- **Purity guard widened:** the capture/format boundary test now bars
|
|
59
|
+
vocabulary literals of **both** eras from `src/capture/**`. The invariant is
|
|
60
|
+
"vocabulary lives only in `format/vocabulary.ts`", not "the prior-era strings
|
|
61
|
+
are gone" — both eras are real vocabulary now, and either could be redefined
|
|
62
|
+
in the wrong module.
|
|
63
|
+
|
|
64
|
+
## 0.2.0 — 2026-08-17
|
|
65
|
+
|
|
66
|
+
**Breaking: identity-bearing config is now required**
|
|
67
|
+
([civic-ai-tools#153](https://github.com/npstorey/civic-ai-tools/issues/153) —
|
|
68
|
+
the [ADR-0024](../../docs/adr/0024-evidence-path-configuration.md) posture at
|
|
69
|
+
the domain layer: configuration that reaches signed output is absent-or-error,
|
|
70
|
+
never defaulted). 0.1.0 applied the civicaitools.org reference deployment's
|
|
71
|
+
identity via silently-applied default parameters; 0.2.0 removes every such
|
|
72
|
+
default, so a bare call fails typecheck instead of attributing output to the
|
|
73
|
+
reference deployment.
|
|
74
|
+
|
|
75
|
+
- **Breaking — the config parameter is required in five API families:**
|
|
76
|
+
- `buildProvenanceGraph(trace, input, config)` — `ProvenanceConfig`
|
|
77
|
+
required (was defaulted to `CIVICAITOOLS_PROVENANCE_CONFIG`).
|
|
78
|
+
- `buildDatHereEnvironment(model, skillMcpServerUrl, config)` and
|
|
79
|
+
`deriveDatHereEnvelopeFields(input, config)` —
|
|
80
|
+
`DatHereEnvironmentConfig` required (was defaulted to
|
|
81
|
+
`CIVICAITOOLS_ENVIRONMENT_CONFIG`; the `host` field lands under the
|
|
82
|
+
envelope hash, so this default was the sharpest instance).
|
|
83
|
+
- `new TraceBuilder(config)` — `TraceBuilderConfig` required (was
|
|
84
|
+
defaulted to `CIVICAITOOLS_TRACE_CONFIG`). The intra-config
|
|
85
|
+
`now`/`randomBytes` operational fallbacks are unchanged — they are not
|
|
86
|
+
identity.
|
|
87
|
+
- `isDatasetKeyedSource(sourceId, registry)`,
|
|
88
|
+
`displayNameForSource(sourceId, registry)`,
|
|
89
|
+
`formatDataSourcesSummary(entries, registry)` — `CivicSourceRegistry`
|
|
90
|
+
required in all three (was defaulted to `CIVIC_SOURCE_REGISTRY`).
|
|
91
|
+
- **Breaking — the model-agent description is omitted when unset.** The
|
|
92
|
+
module-private fallback description is deleted.
|
|
93
|
+
`ProvenanceConfig.modelAgentDescription` stays optional, but when unset the
|
|
94
|
+
PROV model agent now carries **no** `dcterms:description` field at all
|
|
95
|
+
(honest absence, not an empty string — ADR-0024 §B) instead of the fallback
|
|
96
|
+
text. `CIVICAITOOLS_PROVENANCE_CONFIG` now carries
|
|
97
|
+
`modelAgentDescription: 'Large language model via OpenRouter'`, so
|
|
98
|
+
reference-config output is byte-identical to 0.1.0.
|
|
99
|
+
- **The reference-value exports remain.** `CIVICAITOOLS_PROVENANCE_CONFIG`,
|
|
100
|
+
`CIVICAITOOLS_ENVIRONMENT_CONFIG`, `CIVICAITOOLS_TRACE_CONFIG`, and
|
|
101
|
+
`CIVIC_SOURCE_REGISTRY` are still exported — they are the reference
|
|
102
|
+
deployment's values, which the reference app passes explicitly; they are no
|
|
103
|
+
longer applied on any caller's behalf.
|
|
104
|
+
- **Migration:** pass the exported reference configs to reproduce 0.1.x
|
|
105
|
+
behavior byte-for-byte (see README §"Migrating from 0.1.x"). Golden
|
|
106
|
+
fixtures are unchanged; byte parity now comes from tests passing the
|
|
107
|
+
reference config explicitly, never from restored defaults.
|
|
108
|
+
- **Enforcement:** `src/required-config.assert.ts` encodes the acceptance
|
|
109
|
+
condition — one `@ts-expect-error` bare call per changed signature —
|
|
110
|
+
so reintroducing a default parameter fails `npm run typecheck` and
|
|
111
|
+
`npm run build`.
|
|
112
|
+
- Dependencies unchanged (`@typedstandards/produce-core` `^0.2.0` remains the
|
|
113
|
+
single runtime dependency).
|
|
114
|
+
|
|
6
115
|
## 0.1.0 — 2026-08-02
|
|
7
116
|
|
|
8
117
|
Initial release: the civic **domain harness** for Typed Standards evidence
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @typedstandards/civic-typed-harness
|
|
2
2
|
|
|
3
|
-
The civic **domain harness** for [Typed Standards](../../docs/architecture/typed-standards-specification.md)
|
|
3
|
+
The civic **domain harness** for [Typed Standards](../../docs/architecture/typed-standards-specification.md) record packages — the DOMAIN side of the format/domain line drawn in [ADR-0021](../../docs/adr/0021-produce-core-extraction.md), relocated from the reference app as an installable package ([ADR-0022](../../docs/adr/0022-civic-typed-harness-packaging.md)). The operating rule: **the harness derives, the core assembles** — everything here produces domain-derived values (civic vocabulary terms, datHere policy fields, provenance graphs, capture artifacts) that feed [`@typedstandards/produce-core`](https://www.npmjs.com/package/@typedstandards/produce-core)'s neutral envelope assembly.
|
|
4
4
|
|
|
5
5
|
> **Name.** The package landed in-repo under the working name `civic-typed-harness` with the final npm name deferred (ADR-0022 §B). It publishes as **`@typedstandards/civic-typed-harness`** — the standard's scope with the full layer-3 basename; the rationale, the alternatives scored, and the named reversal condition are recorded in the planning-side naming memo and summarized in the [ADR-0022 addendum](../../docs/adr/0022-civic-typed-harness-packaging.md#addendum-2026-08-02--final-npm-name).
|
|
6
6
|
|
|
@@ -8,24 +8,42 @@ The civic **domain harness** for [Typed Standards](../../docs/architecture/typed
|
|
|
8
8
|
|
|
9
9
|
| Module group | Modules | What it is |
|
|
10
10
|
|---|---|---|
|
|
11
|
-
| **`src/format/`** — the civic format-extension | `vocabulary.ts`, `sources.ts`, `dathere.ts`, `profiles.ts` | What extends the *standard*: the `civic:` JSON-LD namespace and `urn:civic-
|
|
11
|
+
| **`src/format/`** — the civic format-extension | `vocabulary.ts`, `sources.ts`, `dathere.ts`, `profiles.ts` | What extends the *standard*: the `civic:` JSON-LD namespace and `urn:civic-record:` id scheme (both in two eras — new emissions mint the settlement-era terms, the prior-era terms stay exported and reproducible because they are frozen inside already-signed records; spec Appendix J), the civic source registry, the datHere envelope-policy derivations (producerProfile, canonicalization rule, summary emission, environment extension), and the captureMethod vocabulary surface. |
|
|
12
12
|
| **`src/capture/`** — the capture machinery | `trace.ts`, `skill-metadata.ts`, `data-sources.ts`, `provenance.ts` | What *produces* under it: the OTel `TraceBuilder`, skill-metadata extraction, data-source population, and the provenance **builder** — which imports its vocabulary from the format group and walks the trace. |
|
|
13
13
|
| **`src/rubric/`** — the adversarial rubric | `adversarial-eval-core.ts` | The civic six-criterion evaluation rubric (pure core: rubric text, pinned version hash, prompt builder, response parser). The model runner and result emission stay implementation-side. |
|
|
14
14
|
|
|
15
15
|
**The internal boundary is load-bearing:** no capture module defines vocabulary, and no format-extension module walks a trace — this sentence reserves a future split of the format-extension group into its own package (a civic extension *of Typed Standards*, distinct from the civic *harness* proper) as a mechanical move rather than a re-partition. The boundary is enforced by `src/purity.test.ts`.
|
|
16
16
|
|
|
17
|
-
## Config, not constants
|
|
17
|
+
## Config, not constants — and required, never defaulted
|
|
18
18
|
|
|
19
|
-
Every value that names a deployment is a **typed config input
|
|
19
|
+
Every value that names a deployment is a **required typed config input**. As of 0.2.0 the harness never applies a deployment identity on a caller's behalf: a call that omits the config **fails typecheck** ([ADR-0024](../../docs/adr/0024-evidence-path-configuration.md)'s posture at the domain layer — configuration that reaches signed output is absent-or-error, never defaulted; the removal of the 0.1.x defaults is [civic-ai-tools#153](https://github.com/npstorey/civic-ai-tools/issues/153)). The `CIVICAITOOLS_*` exports are the civicaitools.org **reference deployment's values** — the reference app passes them explicitly; any other instance supplies its own.
|
|
20
20
|
|
|
21
|
-
|
|
|
21
|
+
| Identity-bearing input | Config type | Reference-value export |
|
|
22
22
|
|---|---|---|
|
|
23
|
-
| Platform-agent identity/URL | `PlatformAgentConfig` | `CIVICAITOOLS_PLATFORM_AGENT` |
|
|
23
|
+
| Platform-agent identity/URL | `PlatformAgentConfig` (`ProvenanceConfig.platformAgent`) | `CIVICAITOOLS_PLATFORM_AGENT` |
|
|
24
24
|
| MCP source registry (server URLs, catalog types, display names) | `CivicSourceRegistry` | `CIVIC_SOURCE_REGISTRY` |
|
|
25
|
-
| Tool-name → source-id resolver | `ToolSourceResolver` | `civicToolSourceResolver` |
|
|
26
|
-
| Environment-extension `host` | `DatHereEnvironmentConfig` | `CIVICAITOOLS_ENVIRONMENT_CONFIG` |
|
|
25
|
+
| Tool-name → source-id resolver (a caller-supplied input, not a silent default) | `ToolSourceResolver` | `civicToolSourceResolver` |
|
|
26
|
+
| Environment-extension `host` (lands under the envelope hash) | `DatHereEnvironmentConfig` | `CIVICAITOOLS_ENVIRONMENT_CONFIG` |
|
|
27
27
|
| Trace `service.name` / scope identity | `TraceBuilderConfig` | `CIVICAITOOLS_TRACE_CONFIG` |
|
|
28
|
-
|
|
|
28
|
+
| Model-agent `dcterms:description` | `ProvenanceConfig.modelAgentDescription` (optional field) | carried in `CIVICAITOOLS_PROVENANCE_CONFIG` |
|
|
29
|
+
| Provenance build (platform agent + source registry + model-agent description) | `ProvenanceConfig` | `CIVICAITOOLS_PROVENANCE_CONFIG` |
|
|
30
|
+
|
|
31
|
+
`modelAgentDescription` is the one **optional** field among these: when unset, the PROV model agent carries no `dcterms:description` at all — the field is omitted from the graph (honest absence), never filled with a fallback. The `now`/`randomBytes` fields on `TraceBuilderConfig` are operational fallbacks (runtime clock/CSPRNG), not identity, and keep their intra-config defaults.
|
|
32
|
+
|
|
33
|
+
### Migrating from 0.1.x
|
|
34
|
+
|
|
35
|
+
0.1.x applied the reference deployment's identity via silent default parameters; 0.2.0 removes every such default — the breaking change is the point: a bare call that would have embedded civicaitools.org's identity in the output now fails to compile. To reproduce 0.1.x behavior byte-for-byte, pass the exported reference configs explicitly:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
// 0.1.x — compiled, and silently attributed output to the reference deployment:
|
|
39
|
+
const graph = buildProvenanceGraph(trace, input);
|
|
40
|
+
|
|
41
|
+
// 0.2.0 — the same output, byte-identical, with the identity stated:
|
|
42
|
+
import { CIVICAITOOLS_PROVENANCE_CONFIG } from '@typedstandards/civic-typed-harness';
|
|
43
|
+
const graph = buildProvenanceGraph(trace, input, CIVICAITOOLS_PROVENANCE_CONFIG);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Likewise: `buildDatHereEnvironment` / `deriveDatHereEnvelopeFields` take `CIVICAITOOLS_ENVIRONMENT_CONFIG`, `new TraceBuilder(...)` takes `CIVICAITOOLS_TRACE_CONFIG`, and `isDatasetKeyedSource` / `displayNameForSource` / `formatDataSourcesSummary` take `CIVIC_SOURCE_REGISTRY`. The acceptance condition is encoded in `src/required-config.assert.ts`: reintroducing any of the removed defaults fails `npm run typecheck`.
|
|
29
47
|
|
|
30
48
|
## Purity contract (harness-grade)
|
|
31
49
|
|
|
@@ -37,7 +55,7 @@ Runtime dependency: **`@typedstandards/produce-core` (`^0.2.0`) only.** The veri
|
|
|
37
55
|
|
|
38
56
|
## Byte-compatibility
|
|
39
57
|
|
|
40
|
-
The port is tested for **byte parity** against golden outputs captured from the reference implementation (`src/__fixtures__/website-golden.json`): with the
|
|
58
|
+
The port is tested for **byte parity** against golden outputs captured from the reference implementation (`src/__fixtures__/website-golden.json`): with the reference config passed explicitly, `buildProvenanceGraph` and `buildDataSources` reproduce the app's output byte-for-byte, and `RUBRIC_VERSION_SHA256` is asserted against the exact reference digest (moving the rubric changes no hashes). Both captured fixtures predate the 2026-08-19 vocabulary settlement, so their byte-parity legs run with `PRIOR_ERA_CIVIC_VOCABULARY` injected — the fixtures are never rewritten — beside a settlement-era leg asserting the same bytes with exactly the two Appendix J literals substituted. Fixture-level byte-compat against produce-core's `reference-golden.json` (`src/golden-reproduction.test.ts`) and the produce→verify composition round-trip (`src/composition-roundtrip.test.ts`) landed in S2 P2 and run with the suite.
|
|
41
59
|
|
|
42
60
|
## Develop
|
|
43
61
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ProvGraph, type ProvNode } from '@typedstandards/produce-core';
|
|
2
|
-
import { type PlatformAgentConfig } from '../format/vocabulary.ts';
|
|
2
|
+
import { type CivicVocabulary, type PlatformAgentConfig } from '../format/vocabulary.ts';
|
|
3
3
|
import { type CivicSourceRegistry } from '../format/sources.ts';
|
|
4
4
|
export type { ProvGraph, ProvNode };
|
|
5
5
|
/** Package-level inputs to the graph build. */
|
|
@@ -19,7 +19,7 @@ export interface ProvenanceInput {
|
|
|
19
19
|
}
|
|
20
20
|
/** Instance configuration for the graph build (config-not-constants). */
|
|
21
21
|
export interface ProvenanceConfig {
|
|
22
|
-
/** Platform-agent identity — the deployment publishing the
|
|
22
|
+
/** Platform-agent identity — the deployment publishing the record. */
|
|
23
23
|
platformAgent: PlatformAgentConfig;
|
|
24
24
|
/** Source registry supplying agent titles and MCP server URLs. */
|
|
25
25
|
sourceRegistry: CivicSourceRegistry;
|
|
@@ -30,11 +30,22 @@ export interface ProvenanceConfig {
|
|
|
30
30
|
* overrides when present (the skill is fetched from that source's MCP
|
|
31
31
|
* server). Default `socrata`. */
|
|
32
32
|
skillSourceId?: string;
|
|
33
|
-
/** `dcterms:description` of the model agent.
|
|
34
|
-
*
|
|
33
|
+
/** `dcterms:description` of the model agent. When unset, the model agent
|
|
34
|
+
* carries no `dcterms:description` at all — the field is omitted from the
|
|
35
|
+
* graph (honest omission), never filled with a fallback. */
|
|
35
36
|
modelAgentDescription?: string;
|
|
37
|
+
/** Vocabulary era to emit (spec Appendix J). Defaults to the settlement-era
|
|
38
|
+
* `CIVIC_VOCABULARY` — the only value a new emission may use. Supply
|
|
39
|
+
* `PRIOR_ERA_CIVIC_VOCABULARY` ONLY to reproduce or verify a record signed
|
|
40
|
+
* before the 2026-08-19 settlement, whose identifiers are frozen under the
|
|
41
|
+
* hash it was signed with. Unlike the other fields here this is not
|
|
42
|
+
* deployment identity, so it is defaulted rather than required: emitting
|
|
43
|
+
* the current vocabulary is never the silent-attribution hazard ADR-0024
|
|
44
|
+
* guards against. */
|
|
45
|
+
vocabulary?: CivicVocabulary;
|
|
36
46
|
}
|
|
37
|
-
/**
|
|
47
|
+
/** The civicaitools.org reference deployment's values. Passed explicitly by
|
|
48
|
+
* the reference app — never applied as a default. */
|
|
38
49
|
export declare const CIVICAITOOLS_PROVENANCE_CONFIG: ProvenanceConfig;
|
|
39
50
|
/**
|
|
40
51
|
* Build a W3C PROV-O JSON-LD graph from an OTel trace and package metadata.
|
|
@@ -45,4 +56,4 @@ export declare const CIVICAITOOLS_PROVENANCE_CONFIG: ProvenanceConfig;
|
|
|
45
56
|
* - Prompt, skill guidance, data responses, output → prov:Entity
|
|
46
57
|
* - LLM model, MCP server, platform → prov:Agent
|
|
47
58
|
*/
|
|
48
|
-
export declare function buildProvenanceGraph(trace: Record<string, unknown>, input: ProvenanceInput, config
|
|
59
|
+
export declare function buildProvenanceGraph(trace: Record<string, unknown>, input: ProvenanceInput, config: ProvenanceConfig): ProvGraph;
|
|
@@ -9,20 +9,23 @@
|
|
|
9
9
|
//
|
|
10
10
|
// Config-not-constants: the platform-agent identity, the source-agent
|
|
11
11
|
// registry (server URLs), and the model-agent description are typed config
|
|
12
|
-
// inputs
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
12
|
+
// inputs, and the config is REQUIRED — no deployment identity is ever
|
|
13
|
+
// applied silently (ADR-0024 posture at the domain layer).
|
|
14
|
+
// `CIVICAITOOLS_PROVENANCE_CONFIG` is the reference deployment's values,
|
|
15
|
+
// which the reference app passes explicitly; with it, the builder reproduces
|
|
16
|
+
// the reference implementation's output byte-for-byte (property insertion
|
|
17
|
+
// order is preserved throughout — the legacy hash chain's byte contract).
|
|
16
18
|
import { makeProvGraph, makeEntityNode, makeActivityNode, makeAgentNode, provRef, provUsed, provWasGeneratedBy, provWasDerivedFrom, provWasAssociatedWith, xsdDateTime, } from '@typedstandards/produce-core';
|
|
17
19
|
import { hash } from "./trace.js";
|
|
18
|
-
import {
|
|
20
|
+
import { CIVIC_VOCABULARY, CIVICAITOOLS_PLATFORM_AGENT, } from "../format/vocabulary.js";
|
|
19
21
|
import { CIVIC_SOURCE_REGISTRY, FALLBACK_SOURCE_ID, isDatasetKeyedSource, } from "../format/sources.js";
|
|
20
|
-
/**
|
|
22
|
+
/** The civicaitools.org reference deployment's values. Passed explicitly by
|
|
23
|
+
* the reference app — never applied as a default. */
|
|
21
24
|
export const CIVICAITOOLS_PROVENANCE_CONFIG = {
|
|
22
25
|
platformAgent: CIVICAITOOLS_PLATFORM_AGENT,
|
|
23
26
|
sourceRegistry: CIVIC_SOURCE_REGISTRY,
|
|
27
|
+
modelAgentDescription: 'Large language model via OpenRouter',
|
|
24
28
|
};
|
|
25
|
-
const DEFAULT_MODEL_AGENT_DESCRIPTION = 'Large language model via OpenRouter';
|
|
26
29
|
// --- Helpers ---
|
|
27
30
|
function getAttr(attrs, key) {
|
|
28
31
|
const attr = attrs.find(a => a.key === key);
|
|
@@ -42,7 +45,7 @@ function nanoToIso(nano) {
|
|
|
42
45
|
* - Prompt, skill guidance, data responses, output → prov:Entity
|
|
43
46
|
* - LLM model, MCP server, platform → prov:Agent
|
|
44
47
|
*/
|
|
45
|
-
export function buildProvenanceGraph(trace, input, config
|
|
48
|
+
export function buildProvenanceGraph(trace, input, config) {
|
|
46
49
|
const otel = trace;
|
|
47
50
|
const spans = otel?.resourceSpans?.[0]?.scopeSpans?.[0]?.spans || [];
|
|
48
51
|
const { packageId, promptHash, promptText, outputText, model, portal } = input;
|
|
@@ -50,11 +53,14 @@ export function buildProvenanceGraph(trace, input, config = CIVICAITOOLS_PROVENA
|
|
|
50
53
|
const registry = config.sourceRegistry;
|
|
51
54
|
const fallbackSourceId = config.fallbackSourceId ?? FALLBACK_SOURCE_ID;
|
|
52
55
|
const skillSourceId = config.skillSourceId ?? FALLBACK_SOURCE_ID;
|
|
53
|
-
|
|
56
|
+
// Vocabulary era — settlement-era unless a prior-era reproduction asks
|
|
57
|
+
// otherwise. Every id and the `@context` below route through it, so a graph
|
|
58
|
+
// never mixes eras.
|
|
59
|
+
const vocab = config.vocabulary ?? CIVIC_VOCABULARY;
|
|
54
60
|
const graph = [];
|
|
55
61
|
// --- Entities ---
|
|
56
62
|
// User prompt
|
|
57
|
-
graph.push(makeEntityNode(
|
|
63
|
+
graph.push(makeEntityNode(vocab.urn(packageId, 'prompt', promptHash), {
|
|
58
64
|
'civic:contentHash': `sha256:${promptHash}`,
|
|
59
65
|
'dcterms:description': 'User query prompt',
|
|
60
66
|
...(promptText ? { 'prov:value': promptText } : {}),
|
|
@@ -67,25 +73,29 @@ export function buildProvenanceGraph(trace, input, config = CIVICAITOOLS_PROVENA
|
|
|
67
73
|
const skillHash = skillSpan ? getAttr(skillSpan.attributes, 'skill.text_hash') : undefined;
|
|
68
74
|
const skillServerUrl = skillSpan ? getAttr(skillSpan.attributes, 'skill.mcp_server_url') : undefined;
|
|
69
75
|
if (skillHash) {
|
|
70
|
-
graph.push(makeEntityNode(
|
|
76
|
+
graph.push(makeEntityNode(vocab.urn(packageId, 'skill', skillHash), {
|
|
71
77
|
'civic:contentHash': `sha256:${skillHash}`,
|
|
72
78
|
'dcterms:description': 'Composed MCP skill guidance (system prompt)',
|
|
73
79
|
}, ['prov:Plan']));
|
|
74
80
|
}
|
|
75
81
|
// Final output
|
|
76
|
-
graph.push(makeEntityNode(
|
|
82
|
+
graph.push(makeEntityNode(vocab.urn(packageId, 'output', outputHash), {
|
|
77
83
|
'civic:contentHash': `sha256:${outputHash}`,
|
|
78
84
|
'dcterms:description': 'AI-generated analysis output',
|
|
79
85
|
}));
|
|
80
86
|
// --- Agents ---
|
|
81
|
-
// LLM model
|
|
82
|
-
|
|
87
|
+
// LLM model. The description is emitted only when the config supplies one —
|
|
88
|
+
// absent otherwise (honest omission, same idiom as deriveProducerProfile /
|
|
89
|
+
// deriveSummaryEmission in ../format/dathere.ts).
|
|
90
|
+
const modelUrn = vocab.modelUrn(model);
|
|
83
91
|
graph.push(makeAgentNode(modelUrn, {
|
|
84
92
|
'dcterms:title': model,
|
|
85
|
-
|
|
93
|
+
...(config.modelAgentDescription
|
|
94
|
+
? { 'dcterms:description': config.modelAgentDescription }
|
|
95
|
+
: {}),
|
|
86
96
|
}, ['prov:SoftwareAgent']));
|
|
87
97
|
// MCP server agents — one per distinct data source that appears in the
|
|
88
|
-
// trace. Tool spans carry `mcp.source`;
|
|
98
|
+
// trace. Tool spans carry `mcp.source`; records captured before
|
|
89
99
|
// source tagging have no source attribute, so they fall back to the
|
|
90
100
|
// configured fallback source (socrata — the only source at the time) for
|
|
91
101
|
// backwards compatibility. Agent coordinates come from the source registry;
|
|
@@ -94,7 +104,7 @@ export function buildProvenanceGraph(trace, input, config = CIVICAITOOLS_PROVENA
|
|
|
94
104
|
const sourceAgentMap = {};
|
|
95
105
|
for (const [id, info] of Object.entries(registry)) {
|
|
96
106
|
sourceAgentMap[id] = {
|
|
97
|
-
urn:
|
|
107
|
+
urn: vocab.sourceAgentUrn(id),
|
|
98
108
|
title: info.agentTitle,
|
|
99
109
|
serverUrl: id === skillSourceId ? skillServerUrl || info.serverUrl : info.serverUrl,
|
|
100
110
|
};
|
|
@@ -106,7 +116,7 @@ export function buildProvenanceGraph(trace, input, config = CIVICAITOOLS_PROVENA
|
|
|
106
116
|
}
|
|
107
117
|
for (const sourceId of sourcesInTrace) {
|
|
108
118
|
const meta = sourceAgentMap[sourceId] ?? {
|
|
109
|
-
urn:
|
|
119
|
+
urn: vocab.sourceAgentUrn(encodeURIComponent(sourceId)),
|
|
110
120
|
title: `${sourceId} MCP Server`,
|
|
111
121
|
serverUrl: sourceId,
|
|
112
122
|
};
|
|
@@ -123,10 +133,10 @@ export function buildProvenanceGraph(trace, input, config = CIVICAITOOLS_PROVENA
|
|
|
123
133
|
const id = sourceId || fallbackSourceId;
|
|
124
134
|
return (sourceAgentMap[id]?.urn
|
|
125
135
|
?? sourceAgentMap[fallbackSourceId]?.urn
|
|
126
|
-
??
|
|
136
|
+
?? vocab.sourceAgentUrn(encodeURIComponent(id)));
|
|
127
137
|
}
|
|
128
138
|
// Platform
|
|
129
|
-
graph.push(makeAgentNode(
|
|
139
|
+
graph.push(makeAgentNode(vocab.platformUrn(config.platformAgent.id), {
|
|
130
140
|
'dcterms:title': config.platformAgent.title,
|
|
131
141
|
'civic:url': config.platformAgent.url,
|
|
132
142
|
}, ['prov:SoftwareAgent']));
|
|
@@ -135,11 +145,11 @@ export function buildProvenanceGraph(trace, input, config = CIVICAITOOLS_PROVENA
|
|
|
135
145
|
const inferenceSpans = spans.filter(s => s.name === 'llm_inference');
|
|
136
146
|
const inferenceUrns = [];
|
|
137
147
|
for (const span of inferenceSpans) {
|
|
138
|
-
const spanUrn =
|
|
148
|
+
const spanUrn = vocab.urn(packageId, 'inference', span.spanId);
|
|
139
149
|
inferenceUrns.push(spanUrn);
|
|
140
|
-
const used = [provRef(
|
|
150
|
+
const used = [provRef(vocab.urn(packageId, 'prompt', promptHash))];
|
|
141
151
|
if (skillHash) {
|
|
142
|
-
used.push(provRef(
|
|
152
|
+
used.push(provRef(vocab.urn(packageId, 'skill', skillHash)));
|
|
143
153
|
}
|
|
144
154
|
const promptTokens = getAttr(span.attributes, 'gen_ai.response.prompt_tokens');
|
|
145
155
|
const completionTokens = getAttr(span.attributes, 'gen_ai.response.completion_tokens');
|
|
@@ -160,7 +170,7 @@ export function buildProvenanceGraph(trace, input, config = CIVICAITOOLS_PROVENA
|
|
|
160
170
|
// MCP tool call spans
|
|
161
171
|
const dataResponseUrns = [];
|
|
162
172
|
for (const span of toolSpans) {
|
|
163
|
-
const toolCallUrn =
|
|
173
|
+
const toolCallUrn = vocab.urn(packageId, 'tool-call', span.spanId);
|
|
164
174
|
const argsStr = getAttr(span.attributes, 'tool.arguments') || '{}';
|
|
165
175
|
const queryHash = hash(argsStr);
|
|
166
176
|
const responseHash = getAttr(span.attributes, 'tool.response_hash');
|
|
@@ -177,19 +187,19 @@ export function buildProvenanceGraph(trace, input, config = CIVICAITOOLS_PROVENA
|
|
|
177
187
|
const precedingInference = inferenceSpans
|
|
178
188
|
.filter(is => Number(is.endTimeUnixNano || '0') <= toolStart)
|
|
179
189
|
.sort((a, b) => Number(b.endTimeUnixNano || '0') - Number(a.endTimeUnixNano || '0'))[0];
|
|
180
|
-
const queryUrn =
|
|
190
|
+
const queryUrn = vocab.urn(packageId, 'query', queryHash);
|
|
181
191
|
graph.push(makeEntityNode(queryUrn, {
|
|
182
192
|
'civic:contentHash': `sha256:${queryHash}`,
|
|
183
193
|
'civic:toolName': toolName,
|
|
184
194
|
'civic:operationType': opType,
|
|
185
195
|
'dcterms:description': `MCP tool arguments (${opType})`,
|
|
186
196
|
...(precedingInference
|
|
187
|
-
? provWasGeneratedBy(
|
|
197
|
+
? provWasGeneratedBy(vocab.urn(packageId, 'inference', precedingInference.spanId))
|
|
188
198
|
: {}),
|
|
189
199
|
}));
|
|
190
200
|
// Data response entity
|
|
191
201
|
if (responseHash) {
|
|
192
|
-
const dataUrn =
|
|
202
|
+
const dataUrn = vocab.urn(packageId, 'data', responseHash);
|
|
193
203
|
dataResponseUrns.push(dataUrn);
|
|
194
204
|
// Description varies by source — dataset-keyed sources (Socrata) have
|
|
195
205
|
// a portal domain; aggregate/unknown sources are described by their
|
|
@@ -243,8 +253,8 @@ export function buildProvenanceGraph(trace, input, config = CIVICAITOOLS_PROVENA
|
|
|
243
253
|
const generatorSpan = synthesisSpan || lastInference;
|
|
244
254
|
if (generatorSpan) {
|
|
245
255
|
const generatorUrn = synthesisSpan
|
|
246
|
-
?
|
|
247
|
-
:
|
|
256
|
+
? vocab.urn(packageId, 'synthesis', synthesisSpan.spanId)
|
|
257
|
+
: vocab.urn(packageId, 'inference', generatorSpan.spanId);
|
|
248
258
|
// Add synthesis activity if it exists
|
|
249
259
|
if (synthesisSpan) {
|
|
250
260
|
graph.push(makeActivityNode(generatorUrn, {
|
|
@@ -259,7 +269,7 @@ export function buildProvenanceGraph(trace, input, config = CIVICAITOOLS_PROVENA
|
|
|
259
269
|
}));
|
|
260
270
|
}
|
|
261
271
|
// Output wasGeneratedBy
|
|
262
|
-
graph.push(makeEntityNode(
|
|
272
|
+
graph.push(makeEntityNode(vocab.urn(packageId, 'output', outputHash), {
|
|
263
273
|
...provWasGeneratedBy(generatorUrn),
|
|
264
274
|
...(dataResponseUrns.length > 0
|
|
265
275
|
? provWasDerivedFrom(dataResponseUrns)
|
|
@@ -282,9 +292,9 @@ export function buildProvenanceGraph(trace, input, config = CIVICAITOOLS_PROVENA
|
|
|
282
292
|
'prov:qualifiedAssociation': {
|
|
283
293
|
'@type': 'prov:Association',
|
|
284
294
|
'prov:agent': provRef(modelUrn),
|
|
285
|
-
'prov:hadPlan': provRef(
|
|
295
|
+
'prov:hadPlan': provRef(vocab.urn(packageId, 'skill', skillHash)),
|
|
286
296
|
},
|
|
287
297
|
}));
|
|
288
298
|
}
|
|
289
|
-
return makeProvGraph(
|
|
299
|
+
return makeProvGraph(vocab.context(), graph);
|
|
290
300
|
}
|
package/dist/capture/trace.d.ts
CHANGED
|
@@ -50,7 +50,9 @@ export type TraceRandomBytes = (byteLength: number) => Uint8Array;
|
|
|
50
50
|
/**
|
|
51
51
|
* TraceBuilder identity + determinism inputs. The identity strings name the
|
|
52
52
|
* capturing service, so they are per-instance config (config-not-constants);
|
|
53
|
-
* the
|
|
53
|
+
* the reference deployment's values are `CIVICAITOOLS_TRACE_CONFIG` below.
|
|
54
|
+
* The identity fields are required; `now`/`randomBytes` are operational
|
|
55
|
+
* fallbacks, not identity, and default to the runtime's clock and CSPRNG.
|
|
54
56
|
*/
|
|
55
57
|
export interface TraceBuilderConfig {
|
|
56
58
|
/** OTel resource `service.name`. */
|
|
@@ -67,8 +69,8 @@ export interface TraceBuilderConfig {
|
|
|
67
69
|
* `crypto.getRandomValues` (Web Crypto — Node 18+ and every browser). */
|
|
68
70
|
randomBytes?: TraceRandomBytes;
|
|
69
71
|
}
|
|
70
|
-
/**
|
|
71
|
-
*
|
|
72
|
+
/** The civicaitools.org reference deployment's capture identity. Passed
|
|
73
|
+
* explicitly by the reference app — never applied as a default. */
|
|
72
74
|
export declare const CIVICAITOOLS_TRACE_CONFIG: TraceBuilderConfig;
|
|
73
75
|
export declare class TraceBuilder {
|
|
74
76
|
readonly traceId: string;
|
|
@@ -77,7 +79,7 @@ export declare class TraceBuilder {
|
|
|
77
79
|
private readonly config;
|
|
78
80
|
private readonly now;
|
|
79
81
|
private readonly randomBytes;
|
|
80
|
-
constructor(config
|
|
82
|
+
constructor(config: TraceBuilderConfig);
|
|
81
83
|
private randomHex;
|
|
82
84
|
private nowNano;
|
|
83
85
|
/**
|
package/dist/capture/trace.js
CHANGED
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
// implements and @typedstandards/produce-core re-exports (0.2.0), removing
|
|
6
6
|
// the module's only `node:crypto` use — the harness is browser-safe.
|
|
7
7
|
// - The resource/scope identity constants (`service.name`, scope
|
|
8
|
-
// name/version, semconv version) are typed config inputs
|
|
9
|
-
//
|
|
8
|
+
// name/version, semconv version) are REQUIRED typed config inputs
|
|
9
|
+
// (config-not-constants, S2 brief §2); the reference deployment's values
|
|
10
|
+
// are exported as `CIVICAITOOLS_TRACE_CONFIG` for explicit use, never
|
|
11
|
+
// applied as a default.
|
|
10
12
|
//
|
|
11
13
|
// Clock + RNG are INHERENT to capture (span timestamps and ids are what
|
|
12
14
|
// capture *is*): this module is the sanctioned exception to the package's
|
|
@@ -32,8 +34,8 @@ function attrsFromRecord(attrs) {
|
|
|
32
34
|
export function hash(content) {
|
|
33
35
|
return sha256Hex(content);
|
|
34
36
|
}
|
|
35
|
-
/**
|
|
36
|
-
*
|
|
37
|
+
/** The civicaitools.org reference deployment's capture identity. Passed
|
|
38
|
+
* explicitly by the reference app — never applied as a default. */
|
|
37
39
|
export const CIVICAITOOLS_TRACE_CONFIG = {
|
|
38
40
|
serviceName: 'civic-ai-tools-website',
|
|
39
41
|
scopeName: 'civic-ai-tools-evidence',
|
|
@@ -53,7 +55,7 @@ export class TraceBuilder {
|
|
|
53
55
|
config;
|
|
54
56
|
now;
|
|
55
57
|
randomBytes;
|
|
56
|
-
constructor(config
|
|
58
|
+
constructor(config) {
|
|
57
59
|
this.config = config;
|
|
58
60
|
this.now = config.now ?? Date.now;
|
|
59
61
|
this.randomBytes = config.randomBytes ?? defaultRandomBytes;
|
package/dist/format/dathere.d.ts
CHANGED
|
@@ -5,16 +5,18 @@ export declare const DATHERE_CONTENT_PROFILE = "datHere";
|
|
|
5
5
|
export declare const DATHERE_PRODUCER_PROFILE = "ai-assisted-analysis/datHere";
|
|
6
6
|
/** Reverse-DNS key of the auto-emitted environment extension. */
|
|
7
7
|
export declare const ENVIRONMENT_EXTENSION_KEY = "org.civicaitools.environment";
|
|
8
|
-
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
/** The civicaitools.org reference deployment's value for the environment
|
|
9
|
+
* extension's `host` field. Config-not-constants — every instance supplies
|
|
10
|
+
* its own via `DatHereEnvironmentConfig`; the `host` lands under the
|
|
11
|
+
* envelope hash, so it is never applied silently. */
|
|
11
12
|
export declare const CIVICAITOOLS_ENVIRONMENT_HOST = "civicaitools.org";
|
|
12
13
|
/** Per-instance configuration for the environment extension. */
|
|
13
14
|
export interface DatHereEnvironmentConfig {
|
|
14
15
|
/** Publishing host recorded in `org.civicaitools.environment.host`. */
|
|
15
16
|
host: string;
|
|
16
17
|
}
|
|
17
|
-
/** The civicaitools.org
|
|
18
|
+
/** The civicaitools.org reference deployment's values. Passed explicitly by
|
|
19
|
+
* the reference app — never applied as a default. */
|
|
18
20
|
export declare const CIVICAITOOLS_ENVIRONMENT_CONFIG: DatHereEnvironmentConfig;
|
|
19
21
|
/**
|
|
20
22
|
* Derive the envelope's `producerProfile` (ADR-0006): the explicit value when
|
|
@@ -48,7 +50,7 @@ export declare function deriveSummaryEmission(contentProfile?: string, summary?:
|
|
|
48
50
|
* skill-fetch span URL (the analysis's primary MCP server). Fields captured
|
|
49
51
|
* honestly: `modelVersion` and `host`.
|
|
50
52
|
*/
|
|
51
|
-
export declare function buildDatHereEnvironment(model: string, skillMcpServerUrl: string | undefined, config
|
|
53
|
+
export declare function buildDatHereEnvironment(model: string, skillMcpServerUrl: string | undefined, config: DatHereEnvironmentConfig): Record<string, unknown>;
|
|
52
54
|
/** Input to the composite datHere-policy derivation. */
|
|
53
55
|
export interface DatHerePolicyInput {
|
|
54
56
|
/** Model identifier (becomes `environment.modelVersion`). */
|
|
@@ -80,4 +82,4 @@ export interface DatHereEnvelopeFields {
|
|
|
80
82
|
* the legacy canonicalization rule and any caller-supplied extensions —
|
|
81
83
|
* byte-identical envelopes via the core's conditional spreads.
|
|
82
84
|
*/
|
|
83
|
-
export declare function deriveDatHereEnvelopeFields(input: DatHerePolicyInput, config
|
|
85
|
+
export declare function deriveDatHereEnvelopeFields(input: DatHerePolicyInput, config: DatHereEnvironmentConfig): DatHereEnvelopeFields;
|
package/dist/format/dathere.js
CHANGED
|
@@ -25,11 +25,13 @@ export const DATHERE_CONTENT_PROFILE = 'datHere';
|
|
|
25
25
|
export const DATHERE_PRODUCER_PROFILE = 'ai-assisted-analysis/datHere';
|
|
26
26
|
/** Reverse-DNS key of the auto-emitted environment extension. */
|
|
27
27
|
export const ENVIRONMENT_EXTENSION_KEY = 'org.civicaitools.environment';
|
|
28
|
-
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
28
|
+
/** The civicaitools.org reference deployment's value for the environment
|
|
29
|
+
* extension's `host` field. Config-not-constants — every instance supplies
|
|
30
|
+
* its own via `DatHereEnvironmentConfig`; the `host` lands under the
|
|
31
|
+
* envelope hash, so it is never applied silently. */
|
|
31
32
|
export const CIVICAITOOLS_ENVIRONMENT_HOST = 'civicaitools.org';
|
|
32
|
-
/** The civicaitools.org
|
|
33
|
+
/** The civicaitools.org reference deployment's values. Passed explicitly by
|
|
34
|
+
* the reference app — never applied as a default. */
|
|
33
35
|
export const CIVICAITOOLS_ENVIRONMENT_CONFIG = {
|
|
34
36
|
host: CIVICAITOOLS_ENVIRONMENT_HOST,
|
|
35
37
|
};
|
|
@@ -78,7 +80,7 @@ export function deriveSummaryEmission(contentProfile, summary) {
|
|
|
78
80
|
* skill-fetch span URL (the analysis's primary MCP server). Fields captured
|
|
79
81
|
* honestly: `modelVersion` and `host`.
|
|
80
82
|
*/
|
|
81
|
-
export function buildDatHereEnvironment(model, skillMcpServerUrl, config
|
|
83
|
+
export function buildDatHereEnvironment(model, skillMcpServerUrl, config) {
|
|
82
84
|
const mcpServers = [];
|
|
83
85
|
if (skillMcpServerUrl) {
|
|
84
86
|
mcpServers.push({ url: skillMcpServerUrl });
|
|
@@ -97,7 +99,7 @@ export function buildDatHereEnvironment(model, skillMcpServerUrl, config = CIVIC
|
|
|
97
99
|
* the legacy canonicalization rule and any caller-supplied extensions —
|
|
98
100
|
* byte-identical envelopes via the core's conditional spreads.
|
|
99
101
|
*/
|
|
100
|
-
export function deriveDatHereEnvelopeFields(input, config
|
|
102
|
+
export function deriveDatHereEnvelopeFields(input, config) {
|
|
101
103
|
const extensions = { ...(input.extensions ?? {}) };
|
|
102
104
|
if (input.contentProfile === DATHERE_CONTENT_PROFILE) {
|
|
103
105
|
extensions[ENVIRONMENT_EXTENSION_KEY] = buildDatHereEnvironment(input.model, input.skillMcpServerUrl, config);
|
package/dist/format/sources.d.ts
CHANGED
|
@@ -21,14 +21,15 @@ export interface CivicSourceInfo {
|
|
|
21
21
|
/** A source registry: source id → coordinates. Insertion order is emission
|
|
22
22
|
* order for aggregate `dataSources` entries. */
|
|
23
23
|
export type CivicSourceRegistry = Record<string, CivicSourceInfo>;
|
|
24
|
-
/** The civic
|
|
24
|
+
/** The civic reference registry — the three demo sources. Passed explicitly
|
|
25
|
+
* by the reference app — never applied as a default. */
|
|
25
26
|
export declare const CIVIC_SOURCE_REGISTRY: CivicSourceRegistry;
|
|
26
27
|
/** The source id untagged/pre-M9.1 captures fall back to. Socrata was the
|
|
27
28
|
* only source when those packages were written. */
|
|
28
29
|
export declare const FALLBACK_SOURCE_ID = "socrata";
|
|
29
30
|
/** Is this source dataset-keyed (one `dataSources` entry per dataset) rather
|
|
30
31
|
* than aggregate? Unknown ids are neither — they contribute no entry. */
|
|
31
|
-
export declare function isDatasetKeyedSource(sourceId: string, registry
|
|
32
|
+
export declare function isDatasetKeyedSource(sourceId: string, registry: CivicSourceRegistry): boolean;
|
|
32
33
|
/**
|
|
33
34
|
* Resolve an MCP tool name to a source id, or `undefined` when unknown.
|
|
34
35
|
* The data-source population function (capture group) takes one of these as
|
|
@@ -47,8 +48,8 @@ export declare const civicToolSourceResolver: ToolSourceResolver;
|
|
|
47
48
|
* capitalised form of the raw id so new sources render sensibly before the
|
|
48
49
|
* registry is updated. Missing ids coerce to the fallback source (pre-M9.3
|
|
49
50
|
* packages have no `sourceId` on dataSources entries). */
|
|
50
|
-
export declare function displayNameForSource(sourceId: string | undefined | null, registry
|
|
51
|
+
export declare function displayNameForSource(sourceId: string | undefined | null, registry: CivicSourceRegistry): string;
|
|
51
52
|
/** Format a `dataSources` array as a compact, de-duplicated summary string
|
|
52
53
|
* (middle-dot separated). Returns `null` when the array is empty or missing,
|
|
53
54
|
* letting callers render a fallback. */
|
|
54
|
-
export declare function formatDataSourcesSummary(entries: DataSourceEntry[] | undefined, registry
|
|
55
|
+
export declare function formatDataSourcesSummary(entries: DataSourceEntry[] | undefined, registry: CivicSourceRegistry): string | null;
|
package/dist/format/sources.js
CHANGED
|
@@ -8,10 +8,12 @@
|
|
|
8
8
|
// app's MCP registry itself stays app-side; this is the harness's civic
|
|
9
9
|
// DEFAULT — callers supply their own resolver to add or replace sources).
|
|
10
10
|
//
|
|
11
|
-
// Endpoint URLs name
|
|
12
|
-
// typed config input (config-not-constants, S2 brief §2)
|
|
13
|
-
//
|
|
14
|
-
|
|
11
|
+
// Endpoint URLs name a deployment's data plane, so the registry is a
|
|
12
|
+
// REQUIRED typed config input (config-not-constants, S2 brief §2); the civic
|
|
13
|
+
// demo map is exported as `CIVIC_SOURCE_REGISTRY` for explicit use, never
|
|
14
|
+
// applied as a default.
|
|
15
|
+
/** The civic reference registry — the three demo sources. Passed explicitly
|
|
16
|
+
* by the reference app — never applied as a default. */
|
|
15
17
|
export const CIVIC_SOURCE_REGISTRY = {
|
|
16
18
|
socrata: {
|
|
17
19
|
displayName: 'Socrata',
|
|
@@ -39,7 +41,7 @@ export const CIVIC_SOURCE_REGISTRY = {
|
|
|
39
41
|
export const FALLBACK_SOURCE_ID = 'socrata';
|
|
40
42
|
/** Is this source dataset-keyed (one `dataSources` entry per dataset) rather
|
|
41
43
|
* than aggregate? Unknown ids are neither — they contribute no entry. */
|
|
42
|
-
export function isDatasetKeyedSource(sourceId, registry
|
|
44
|
+
export function isDatasetKeyedSource(sourceId, registry) {
|
|
43
45
|
const info = registry[sourceId];
|
|
44
46
|
return info !== undefined && info.aggregatePortalUrl === undefined;
|
|
45
47
|
}
|
|
@@ -65,7 +67,7 @@ export const civicToolSourceResolver = (toolName) => CIVIC_TOOL_SOURCE_MAP[toolN
|
|
|
65
67
|
* capitalised form of the raw id so new sources render sensibly before the
|
|
66
68
|
* registry is updated. Missing ids coerce to the fallback source (pre-M9.3
|
|
67
69
|
* packages have no `sourceId` on dataSources entries). */
|
|
68
|
-
export function displayNameForSource(sourceId, registry
|
|
70
|
+
export function displayNameForSource(sourceId, registry) {
|
|
69
71
|
const id = sourceId || FALLBACK_SOURCE_ID;
|
|
70
72
|
return (registry[id]?.displayName
|
|
71
73
|
?? id
|
|
@@ -77,7 +79,7 @@ export function displayNameForSource(sourceId, registry = CIVIC_SOURCE_REGISTRY)
|
|
|
77
79
|
/** Format a `dataSources` array as a compact, de-duplicated summary string
|
|
78
80
|
* (middle-dot separated). Returns `null` when the array is empty or missing,
|
|
79
81
|
* letting callers render a fallback. */
|
|
80
|
-
export function formatDataSourcesSummary(entries, registry
|
|
82
|
+
export function formatDataSourcesSummary(entries, registry) {
|
|
81
83
|
if (!entries || entries.length === 0)
|
|
82
84
|
return null;
|
|
83
85
|
const seen = new Set();
|
|
@@ -1,24 +1,68 @@
|
|
|
1
1
|
/** The `civic:` JSON-LD namespace URI. Part of the civic vocabulary itself
|
|
2
2
|
* (it names the term set, not a deployment), so it is a constant, not a
|
|
3
|
-
* config input. */
|
|
4
|
-
export declare const CIVIC_NS = "https://civicaitools.org/ns/
|
|
5
|
-
/**
|
|
3
|
+
* config input. Settlement-era value (Appendix J). */
|
|
4
|
+
export declare const CIVIC_NS = "https://civicaitools.org/ns/civic/";
|
|
5
|
+
/** Root of the `urn:civic-record:` id scheme. Settlement-era value
|
|
6
|
+
* (Appendix J). */
|
|
7
|
+
export declare const CIVIC_URN_PREFIX = "urn:civic-record";
|
|
8
|
+
/** The prior-era `civic:` namespace URI, frozen inside records signed before
|
|
9
|
+
* the 2026-08-19 settlement. Never emitted for new packages. */
|
|
10
|
+
export declare const PRIOR_ERA_CIVIC_NS = "https://civicaitools.org/ns/evidence/";
|
|
11
|
+
/** The prior-era id-scheme root, frozen inside records signed before the
|
|
12
|
+
* 2026-08-19 settlement. Never emitted for new packages. */
|
|
13
|
+
export declare const PRIOR_ERA_CIVIC_URN_PREFIX = "urn:civic-evidence";
|
|
14
|
+
/**
|
|
15
|
+
* One era of the civic vocabulary: the two literals plus the emitters bound
|
|
16
|
+
* to them. The vocabulary is not deployment configuration (a deployment does
|
|
17
|
+
* not choose its own term set); this seam exists only so a prior-era package
|
|
18
|
+
* can be reproduced with the exact vocabulary it was signed under.
|
|
19
|
+
*/
|
|
20
|
+
export interface CivicVocabulary {
|
|
21
|
+
/** The `civic:` JSON-LD namespace URI for this era. */
|
|
22
|
+
readonly ns: string;
|
|
23
|
+
/** The id-scheme root for this era. */
|
|
24
|
+
readonly urnPrefix: string;
|
|
25
|
+
/** The civic record-package JSON-LD `@context`: prov / xsd / civic /
|
|
26
|
+
* dcterms, in the reference emission order (legacy-chain byte discipline —
|
|
27
|
+
* insertion order is the byte contract). */
|
|
28
|
+
context(): Record<string, string>;
|
|
29
|
+
/** Package-scoped node id: `<prefix>:<packageId>:<type>:<id>`. */
|
|
30
|
+
urn(packageId: string, type: string, id: string): string;
|
|
31
|
+
/** Model-agent id: `<prefix>:model:<modelId>` (slashes in the model
|
|
32
|
+
* identifier collapse to dashes). */
|
|
33
|
+
modelUrn(model: string): string;
|
|
34
|
+
/** MCP source-agent id: `<prefix>:mcp-server:<sourceId>`. Known source ids
|
|
35
|
+
* are emitted raw (they are already URN-safe by construction); callers
|
|
36
|
+
* emitting an UNKNOWN id must encode it first (the capture-side builder
|
|
37
|
+
* uses `encodeURIComponent`, matching the reference behavior). */
|
|
38
|
+
sourceAgentUrn(sourceId: string): string;
|
|
39
|
+
/** Platform-agent id: `<prefix>:platform:<platformId>`. */
|
|
40
|
+
platformUrn(platformId: string): string;
|
|
41
|
+
}
|
|
42
|
+
/** Bind the emitters to one era's two literals. */
|
|
43
|
+
export declare function makeCivicVocabulary(ns: string, urnPrefix: string): CivicVocabulary;
|
|
44
|
+
/** The settlement-era vocabulary — what every new emission uses. */
|
|
45
|
+
export declare const CIVIC_VOCABULARY: CivicVocabulary;
|
|
46
|
+
/** The prior-era vocabulary, valid forever inside records signed before the
|
|
47
|
+
* settlement. Supply it to reproduce or verify such a record byte-for-byte;
|
|
48
|
+
* never to mint a new package. */
|
|
49
|
+
export declare const PRIOR_ERA_CIVIC_VOCABULARY: CivicVocabulary;
|
|
50
|
+
/** The civic record-package JSON-LD `@context`: prov / xsd / civic /
|
|
6
51
|
* dcterms, in the reference emission order (legacy-chain byte discipline —
|
|
7
|
-
* insertion order is the byte contract).
|
|
52
|
+
* insertion order is the byte contract). Settlement era; for a prior-era
|
|
53
|
+
* graph use `PRIOR_ERA_CIVIC_VOCABULARY.context()`. */
|
|
8
54
|
export declare function makeCivicProvContext(): Record<string, string>;
|
|
9
|
-
/**
|
|
10
|
-
export declare const CIVIC_URN_PREFIX = "urn:civic-evidence";
|
|
11
|
-
/** Package-scoped node id: `urn:civic-evidence:<packageId>:<type>:<id>`. */
|
|
55
|
+
/** Package-scoped node id: `urn:civic-record:<packageId>:<type>:<id>`. */
|
|
12
56
|
export declare function civicUrn(packageId: string, type: string, id: string): string;
|
|
13
|
-
/** Model-agent id: `urn:civic-
|
|
57
|
+
/** Model-agent id: `urn:civic-record:model:<modelId>` (slashes in the
|
|
14
58
|
* model identifier collapse to dashes). */
|
|
15
59
|
export declare function civicModelUrn(model: string): string;
|
|
16
|
-
/** MCP source-agent id: `urn:civic-
|
|
60
|
+
/** MCP source-agent id: `urn:civic-record:mcp-server:<sourceId>`. Known
|
|
17
61
|
* source ids are emitted raw (they are already URN-safe by construction);
|
|
18
62
|
* callers emitting an UNKNOWN id must encode it first (the capture-side
|
|
19
63
|
* builder uses `encodeURIComponent`, matching the reference behavior). */
|
|
20
64
|
export declare function civicSourceAgentUrn(sourceId: string): string;
|
|
21
|
-
/** Platform-agent id: `urn:civic-
|
|
65
|
+
/** Platform-agent id: `urn:civic-record:platform:<platformId>`. */
|
|
22
66
|
export declare function civicPlatformUrn(platformId: string): string;
|
|
23
67
|
/**
|
|
24
68
|
* Platform-agent identity — WHO published, as a PROV agent. A typed config
|
|
@@ -26,7 +70,8 @@ export declare function civicPlatformUrn(platformId: string): string;
|
|
|
26
70
|
* the civicaitools.org demo values are the exported default below.
|
|
27
71
|
*/
|
|
28
72
|
export interface PlatformAgentConfig {
|
|
29
|
-
/** Stable platform id — becomes `urn:civic-
|
|
73
|
+
/** Stable platform id — becomes `urn:civic-record:platform:<id>` (prior-era
|
|
74
|
+
* graphs carry the same id under the prior-era prefix). */
|
|
30
75
|
id: string;
|
|
31
76
|
/** Human-readable platform title (`dcterms:title`). */
|
|
32
77
|
title: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Civic PROV-O vocabulary (FORMAT-EXTENSION group) — the `civic:` JSON-LD
|
|
2
|
-
// namespace, the `urn:civic-
|
|
2
|
+
// namespace, the `urn:civic-record:` id scheme, and the platform-agent
|
|
3
3
|
// identity shape. Relocated from civic-ai-tools-website
|
|
4
4
|
// `src/lib/evidence/provenance.ts` (`:51` urn scheme, `:179–184` platform
|
|
5
5
|
// agent, `:384–391` context) per the S2 brief §1.
|
|
@@ -7,43 +7,81 @@
|
|
|
7
7
|
// This module defines vocabulary; it never walks a trace. The capture-side
|
|
8
8
|
// provenance BUILDER (src/capture/provenance.ts) imports its terms from here —
|
|
9
9
|
// that direction is the package's internal module boundary.
|
|
10
|
+
//
|
|
11
|
+
// TWO ERAS (spec Appendix J — the 2026-08-19 vocabulary settlement, migration
|
|
12
|
+
// class "frozen-in-signed-artifacts"). New emissions mint the SETTLEMENT-era
|
|
13
|
+
// terms (`CIVIC_NS` / `CIVIC_URN_PREFIX` below, the module's canonical
|
|
14
|
+
// values). The PRIOR-era terms are frozen inside every already-signed record —
|
|
15
|
+
// rewriting them would change the envelope hash and invalidate the signature —
|
|
16
|
+
// so they remain valid forever and are exported here too: reproducing or
|
|
17
|
+
// verifying a prior-era package byte-for-byte requires emitting its vocabulary
|
|
18
|
+
// exactly as it was signed. Era is not a trust signal (Appendix J §J.4 rule 2);
|
|
19
|
+
// prior-era injection exists for reproduction and verification, never for new
|
|
20
|
+
// emissions.
|
|
10
21
|
import { makeProvContext, PROV_NS, XSD_NS, DCTERMS_NS } from '@typedstandards/produce-core';
|
|
11
22
|
/** The `civic:` JSON-LD namespace URI. Part of the civic vocabulary itself
|
|
12
23
|
* (it names the term set, not a deployment), so it is a constant, not a
|
|
13
|
-
* config input. */
|
|
14
|
-
export const CIVIC_NS = 'https://civicaitools.org/ns/
|
|
15
|
-
/**
|
|
24
|
+
* config input. Settlement-era value (Appendix J). */
|
|
25
|
+
export const CIVIC_NS = 'https://civicaitools.org/ns/civic/';
|
|
26
|
+
/** Root of the `urn:civic-record:` id scheme. Settlement-era value
|
|
27
|
+
* (Appendix J). */
|
|
28
|
+
export const CIVIC_URN_PREFIX = 'urn:civic-record';
|
|
29
|
+
/** The prior-era `civic:` namespace URI, frozen inside records signed before
|
|
30
|
+
* the 2026-08-19 settlement. Never emitted for new packages. */
|
|
31
|
+
export const PRIOR_ERA_CIVIC_NS = 'https://civicaitools.org/ns/evidence/';
|
|
32
|
+
/** The prior-era id-scheme root, frozen inside records signed before the
|
|
33
|
+
* 2026-08-19 settlement. Never emitted for new packages. */
|
|
34
|
+
export const PRIOR_ERA_CIVIC_URN_PREFIX = 'urn:civic-evidence';
|
|
35
|
+
/** Bind the emitters to one era's two literals. */
|
|
36
|
+
export function makeCivicVocabulary(ns, urnPrefix) {
|
|
37
|
+
return {
|
|
38
|
+
ns,
|
|
39
|
+
urnPrefix,
|
|
40
|
+
context: () => makeProvContext({
|
|
41
|
+
prov: PROV_NS,
|
|
42
|
+
xsd: XSD_NS,
|
|
43
|
+
civic: ns,
|
|
44
|
+
dcterms: DCTERMS_NS,
|
|
45
|
+
}),
|
|
46
|
+
urn: (packageId, type, id) => `${urnPrefix}:${packageId}:${type}:${id}`,
|
|
47
|
+
modelUrn: (model) => `${urnPrefix}:model:${model.replace(/\//g, '-')}`,
|
|
48
|
+
sourceAgentUrn: (sourceId) => `${urnPrefix}:mcp-server:${sourceId}`,
|
|
49
|
+
platformUrn: (platformId) => `${urnPrefix}:platform:${platformId}`,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** The settlement-era vocabulary — what every new emission uses. */
|
|
53
|
+
export const CIVIC_VOCABULARY = makeCivicVocabulary(CIVIC_NS, CIVIC_URN_PREFIX);
|
|
54
|
+
/** The prior-era vocabulary, valid forever inside records signed before the
|
|
55
|
+
* settlement. Supply it to reproduce or verify such a record byte-for-byte;
|
|
56
|
+
* never to mint a new package. */
|
|
57
|
+
export const PRIOR_ERA_CIVIC_VOCABULARY = makeCivicVocabulary(PRIOR_ERA_CIVIC_NS, PRIOR_ERA_CIVIC_URN_PREFIX);
|
|
58
|
+
// --- Settlement-era convenience bindings (unchanged signatures) ---
|
|
59
|
+
/** The civic record-package JSON-LD `@context`: prov / xsd / civic /
|
|
16
60
|
* dcterms, in the reference emission order (legacy-chain byte discipline —
|
|
17
|
-
* insertion order is the byte contract).
|
|
61
|
+
* insertion order is the byte contract). Settlement era; for a prior-era
|
|
62
|
+
* graph use `PRIOR_ERA_CIVIC_VOCABULARY.context()`. */
|
|
18
63
|
export function makeCivicProvContext() {
|
|
19
|
-
return
|
|
20
|
-
prov: PROV_NS,
|
|
21
|
-
xsd: XSD_NS,
|
|
22
|
-
civic: CIVIC_NS,
|
|
23
|
-
dcterms: DCTERMS_NS,
|
|
24
|
-
});
|
|
64
|
+
return CIVIC_VOCABULARY.context();
|
|
25
65
|
}
|
|
26
|
-
/**
|
|
27
|
-
export const CIVIC_URN_PREFIX = 'urn:civic-evidence';
|
|
28
|
-
/** Package-scoped node id: `urn:civic-evidence:<packageId>:<type>:<id>`. */
|
|
66
|
+
/** Package-scoped node id: `urn:civic-record:<packageId>:<type>:<id>`. */
|
|
29
67
|
export function civicUrn(packageId, type, id) {
|
|
30
|
-
return
|
|
68
|
+
return CIVIC_VOCABULARY.urn(packageId, type, id);
|
|
31
69
|
}
|
|
32
|
-
/** Model-agent id: `urn:civic-
|
|
70
|
+
/** Model-agent id: `urn:civic-record:model:<modelId>` (slashes in the
|
|
33
71
|
* model identifier collapse to dashes). */
|
|
34
72
|
export function civicModelUrn(model) {
|
|
35
|
-
return
|
|
73
|
+
return CIVIC_VOCABULARY.modelUrn(model);
|
|
36
74
|
}
|
|
37
|
-
/** MCP source-agent id: `urn:civic-
|
|
75
|
+
/** MCP source-agent id: `urn:civic-record:mcp-server:<sourceId>`. Known
|
|
38
76
|
* source ids are emitted raw (they are already URN-safe by construction);
|
|
39
77
|
* callers emitting an UNKNOWN id must encode it first (the capture-side
|
|
40
78
|
* builder uses `encodeURIComponent`, matching the reference behavior). */
|
|
41
79
|
export function civicSourceAgentUrn(sourceId) {
|
|
42
|
-
return
|
|
80
|
+
return CIVIC_VOCABULARY.sourceAgentUrn(sourceId);
|
|
43
81
|
}
|
|
44
|
-
/** Platform-agent id: `urn:civic-
|
|
82
|
+
/** Platform-agent id: `urn:civic-record:platform:<platformId>`. */
|
|
45
83
|
export function civicPlatformUrn(platformId) {
|
|
46
|
-
return
|
|
84
|
+
return CIVIC_VOCABULARY.platformUrn(platformId);
|
|
47
85
|
}
|
|
48
86
|
/** Demo default: the civicaitools.org reference deployment's identity. */
|
|
49
87
|
export const CIVICAITOOLS_PLATFORM_AGENT = {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Type-level acceptance gate for the 0.2.0 breaking change (civic-ai-tools#153,
|
|
2
|
+
// findings A3–A7): identity-bearing config is a REQUIRED parameter — a bare
|
|
3
|
+
// call that omits it must FAIL typecheck. Each `@ts-expect-error` below
|
|
4
|
+
// asserts exactly that: if a silently-applied default parameter is ever
|
|
5
|
+
// reintroduced, the bare call becomes legal, the directive turns unused, and
|
|
6
|
+
// `npm run typecheck` / `npm run build` fail.
|
|
7
|
+
//
|
|
8
|
+
// Compile-time only: the guard function is never exported and never invoked,
|
|
9
|
+
// and the `declare`d values have no runtime existence.
|
|
10
|
+
import { buildProvenanceGraph, buildDatHereEnvironment, deriveDatHereEnvelopeFields, TraceBuilder, isDatasetKeyedSource, displayNameForSource, formatDataSourcesSummary, } from "./index.js";
|
|
11
|
+
function rejectsBareCalls() {
|
|
12
|
+
// @ts-expect-error A3 — buildProvenanceGraph: the ProvenanceConfig is required
|
|
13
|
+
buildProvenanceGraph(trace, provenanceInput);
|
|
14
|
+
// @ts-expect-error A4 — buildDatHereEnvironment: the DatHereEnvironmentConfig is required
|
|
15
|
+
buildDatHereEnvironment('model/slug', undefined);
|
|
16
|
+
// @ts-expect-error A4 — deriveDatHereEnvelopeFields: the DatHereEnvironmentConfig is required
|
|
17
|
+
deriveDatHereEnvelopeFields(policyInput);
|
|
18
|
+
// @ts-expect-error A6 — TraceBuilder: the TraceBuilderConfig is required
|
|
19
|
+
new TraceBuilder();
|
|
20
|
+
// @ts-expect-error A7 — isDatasetKeyedSource: the CivicSourceRegistry is required
|
|
21
|
+
isDatasetKeyedSource('socrata');
|
|
22
|
+
// @ts-expect-error A7 — displayNameForSource: the CivicSourceRegistry is required
|
|
23
|
+
displayNameForSource('socrata');
|
|
24
|
+
// @ts-expect-error A7 — formatDataSourcesSummary: the CivicSourceRegistry is required
|
|
25
|
+
formatDataSourcesSummary(entries);
|
|
26
|
+
}
|
|
27
|
+
void rejectsBareCalls;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type RecordPackage, type EvaluationResults } from '@typedstandards/produce-core';
|
|
2
2
|
/** Rubric identifier carried as the `scoringRubric` payload field and the
|
|
3
3
|
* methodology `testSet`. Six criteria, 1-10 each, plus aggregate. */
|
|
4
4
|
export declare const RUBRIC_ID = "civicaitools-adversarial-rubric/six-criterion-v1";
|
|
@@ -8,8 +8,12 @@ export declare const EVALUATION_RUBRIC = "You are an independent evaluator asses
|
|
|
8
8
|
* once at module load. Any wording change to the rubric produces a new
|
|
9
9
|
* version, so an attestation pins the exact prompt set that scored it. */
|
|
10
10
|
export declare const RUBRIC_VERSION_SHA256: string;
|
|
11
|
-
/** Build the user-turn evaluation content from a package's signed fields.
|
|
12
|
-
|
|
11
|
+
/** Build the user-turn evaluation content from a package's signed fields.
|
|
12
|
+
* Takes `RecordPackage` — produce-core 0.3.0's settlement-era name for the
|
|
13
|
+
* same object (spec Appendix J, migration class alias-and-deprecate). The
|
|
14
|
+
* prior name is a deprecated alias of this exact type upstream, so existing
|
|
15
|
+
* callers still compile unchanged. */
|
|
16
|
+
export declare function buildEvaluationPrompt(pkg: RecordPackage): string;
|
|
13
17
|
export type ParsedEvaluation = {
|
|
14
18
|
ok: true;
|
|
15
19
|
results: EvaluationResults;
|
|
@@ -59,7 +59,11 @@ Respond in this exact JSON format (no markdown fences, just raw JSON):
|
|
|
59
59
|
* once at module load. Any wording change to the rubric produces a new
|
|
60
60
|
* version, so an attestation pins the exact prompt set that scored it. */
|
|
61
61
|
export const RUBRIC_VERSION_SHA256 = sha256Hex(EVALUATION_RUBRIC);
|
|
62
|
-
/** Build the user-turn evaluation content from a package's signed fields.
|
|
62
|
+
/** Build the user-turn evaluation content from a package's signed fields.
|
|
63
|
+
* Takes `RecordPackage` — produce-core 0.3.0's settlement-era name for the
|
|
64
|
+
* same object (spec Appendix J, migration class alias-and-deprecate). The
|
|
65
|
+
* prior name is a deprecated alias of this exact type upstream, so existing
|
|
66
|
+
* callers still compile unchanged. */
|
|
63
67
|
export function buildEvaluationPrompt(pkg) {
|
|
64
68
|
const toolCallSummary = pkg.queries
|
|
65
69
|
.map((q, i) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typedstandards/civic-typed-harness",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Civic-domain harness for Typed Standards evidence packages — the DOMAIN layer of the ADR-0021 format/domain line: civic PROV-O vocabulary and provenance builder, datHere envelope-policy derivations, and the capture machinery (trace builder, skill-metadata extraction, data-source population, adversarial rubric core). Derives; @typedstandards/produce-core assembles.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Nathan Storey",
|
|
@@ -33,9 +33,10 @@
|
|
|
33
33
|
"prepublishOnly": "npm run clean && npm run build"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@typedstandards/produce-core": "^0.
|
|
36
|
+
"@typedstandards/produce-core": "^0.3.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
+
"@typedstandards/verify-core": "^0.9.0",
|
|
39
40
|
"@typescript-eslint/parser": "^8",
|
|
40
41
|
"eslint": "^9",
|
|
41
42
|
"typescript": "^5.9.3"
|