@weftlet/toolkit 0.4.0 → 0.5.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 +11 -1
- package/dist/application/hydrator.d.ts +2 -0
- package/dist/application/hydrator.js +14 -4
- package/dist/application/overlay.d.ts +3 -1
- package/dist/application/overlay.js +3 -1
- package/dist/application/semantic-run.d.ts +3 -0
- package/dist/configuration/config.js +1 -1
- package/dist/graph/identity-preflight.d.ts +57 -0
- package/dist/graph/identity-preflight.js +71 -0
- package/dist/graph/rdf.d.ts +4 -1
- package/dist/graph/rdf.js +10 -6
- package/dist/graph/validation-progress.d.ts +14 -0
- package/dist/graph/validation-progress.js +18 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/interfaces/cli.js +12 -5
- package/docs/ADR-018-operational-semantic-cache.md +2 -2
- package/docs/ADR-019-semantic-failure-diagnostics.md +2 -2
- package/docs/ADR-020-canonical-physical-file-producers.md +2 -2
- package/docs/ADR-021-identity-preflight-and-validation-timing.md +81 -0
- package/docs/PROVIDERS.md +7 -0
- package/docs/RELEASE-1.0-PLAN.md +58 -41
- package/docs/ROADMAP.md +31 -25
- package/docs/VALIDATION.md +139 -0
- package/docs/extraction-manifest.json +14 -8
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -109,6 +109,16 @@ for preview, retry and explicit legacy-cache adoption instructions.
|
|
|
109
109
|
|
|
110
110
|
## SHACL validation and performance
|
|
111
111
|
|
|
112
|
+
Starting with **0.5.0**, identity preflight runs before ontology/RDF work.
|
|
113
|
+
`hydrate --json --quiet` reports conflicts using opaque references; `--validation-details` explicitly
|
|
114
|
+
includes local identities, producer versions and citations. Validation emits phase-boundary times
|
|
115
|
+
and graph counts, without a percentage or live heartbeat. Full SHACL remains required after a
|
|
116
|
+
passing preflight. See [ADR 021](docs/ADR-021-identity-preflight-and-validation-timing.md).
|
|
117
|
+
|
|
118
|
+
Version 0.5.0 also accepts `semantic.timeoutMs: 600000` for an approved ten-minute extraction
|
|
119
|
+
attempt; the default remains two minutes. See [provider limits and reuse](docs/PROVIDERS.md#limits-and-reuse)
|
|
120
|
+
before retrying with compatible cached artifacts.
|
|
121
|
+
|
|
112
122
|
Starting with 0.3.0, the toolkit indexes a temporary union to accelerate cold validation.
|
|
113
123
|
The toolkit uses JavaScript `rdf-validate-shacl` and an in-memory
|
|
114
124
|
N3 store. Each hydration validates the complete graph; semantic artifact reuse does not make
|
|
@@ -135,7 +145,7 @@ pnpm benchmark:shacl
|
|
|
135
145
|
|
|
136
146
|
Current hydration progress reports phase boundaries. The validator performs synchronous work,
|
|
137
147
|
so an ordinary timer cannot provide an honest heartbeat while that work blocks Node's main
|
|
138
|
-
thread. Worker-based progress,
|
|
148
|
+
thread. Worker-based progress, validation-result reuse and incremental
|
|
139
149
|
validation remain separate T05 work; they do not delay the focused cold-validation release.
|
|
140
150
|
|
|
141
151
|
## Development
|
|
@@ -14,6 +14,8 @@ export interface HydrationOptions {
|
|
|
14
14
|
readonly forceSemantic?: boolean;
|
|
15
15
|
readonly snapshotSuffix?: string;
|
|
16
16
|
readonly requireClean?: boolean;
|
|
17
|
+
/** Explicit local diagnostics may disclose repository identities, producers and citations. */
|
|
18
|
+
readonly validationDetails?: boolean;
|
|
17
19
|
readonly semanticSources?: readonly string[];
|
|
18
20
|
readonly runtimeEvidenceRevision?: RuntimeEvidenceRevision;
|
|
19
21
|
}
|
|
@@ -12,6 +12,8 @@ import { extractRoutingDeclarations, routingExtractorIdentity } from '../extract
|
|
|
12
12
|
import { SemanticProviderError } from '../extraction/semantic-process.js';
|
|
13
13
|
import { hydrateSemanticSources } from './semantic-run.js';
|
|
14
14
|
import { graphAssemblyVersion, graphAssemblyIdentity } from './extraction-identity.js';
|
|
15
|
+
import { assertGraphIdentities } from '../graph/identity-preflight.js';
|
|
16
|
+
import { measureValidationPhase } from '../graph/validation-progress.js';
|
|
15
17
|
export class ContextGraphHydrator {
|
|
16
18
|
dependencies;
|
|
17
19
|
constructor(dependencies) {
|
|
@@ -157,11 +159,19 @@ export class ContextGraphHydrator {
|
|
|
157
159
|
diagnostics.push(...documents.diagnostics);
|
|
158
160
|
diagnostics.push(...routing.diagnostics);
|
|
159
161
|
checkpoint();
|
|
160
|
-
options.onProgress?.({ phase: 'compile-semantic-rdf' });
|
|
161
|
-
const ontology = await this.dependencies.ontologyCompiler.compile(snapshotId, artifacts, context);
|
|
162
162
|
const runtimeEvidence = runtimeRevision.references;
|
|
163
163
|
const runtimeFacts = runtimeEvidenceFacts(context, runtimeEvidence);
|
|
164
164
|
const facts = [...semanticFacts, ...documents.facts, ...extractorFacts, ...routing.facts, ...runtimeFacts].sort((left, right) => left.id.localeCompare(right.id));
|
|
165
|
+
const validationCounts = { factCount: facts.length };
|
|
166
|
+
await measureValidationPhase('validate-identities', validationCounts, options.onProgress, () => {
|
|
167
|
+
const report = assertGraphIdentities(facts, {
|
|
168
|
+
repositoryId: config.repositoryId, includeDetails: options.validationDetails,
|
|
169
|
+
});
|
|
170
|
+
validationCounts.nodeCount = report.nodeCount;
|
|
171
|
+
});
|
|
172
|
+
checkpoint();
|
|
173
|
+
options.onProgress?.({ phase: 'compile-semantic-rdf' });
|
|
174
|
+
const ontology = await this.dependencies.ontologyCompiler.compile(snapshotId, artifacts, context);
|
|
165
175
|
const invariants = (await Promise.all(this.dependencies.invariantEvaluators.map((evaluator) => evaluator.evaluate(snapshotId, facts)))).flat();
|
|
166
176
|
const failures = invariants.filter((invariant) => invariant.status === 'fail');
|
|
167
177
|
if (failures.length > 0) {
|
|
@@ -231,8 +241,8 @@ export class ContextGraphHydrator {
|
|
|
231
241
|
diagnostics,
|
|
232
242
|
};
|
|
233
243
|
checkpoint();
|
|
234
|
-
options.onProgress
|
|
235
|
-
const validation = await
|
|
244
|
+
const graph = await measureValidationPhase('build-rdf-evidence', validationCounts, options.onProgress, () => new RdfEvidenceGraph(snapshot));
|
|
245
|
+
const validation = await graph.validate({ onProgress: (event) => options.onProgress?.({ ...event, nodeCount: validationCounts.nodeCount }) });
|
|
236
246
|
if (!validation.conforms) {
|
|
237
247
|
throw new Error(`Graph extraction failed SHACL validation: ${JSON.stringify(validation.issues)}`);
|
|
238
248
|
}
|
|
@@ -3,4 +3,6 @@ import type { GraphSnapshot } from "@weftlet/core";
|
|
|
3
3
|
import { GitRepository } from "../repository/git.js";
|
|
4
4
|
import { FileSnapshotStore } from "../storage/storage.js";
|
|
5
5
|
/** Conservative code overlay: reindex implementation; invalidate changed prose, never synthesize intent. */
|
|
6
|
-
export declare function buildWorkingOverlay(repository: GitRepository, config: ContextGraphConfig, store: FileSnapshotStore, storageRoot: string, baseSnapshotId: string, agent?: string
|
|
6
|
+
export declare function buildWorkingOverlay(repository: GitRepository, config: ContextGraphConfig, store: FileSnapshotStore, storageRoot: string, baseSnapshotId: string, agent?: string, options?: {
|
|
7
|
+
readonly validationDetails?: boolean;
|
|
8
|
+
}): Promise<GraphSnapshot>;
|
|
@@ -12,13 +12,14 @@ import { inWorkingScope, readWorkingContent } from "../repository/working-conten
|
|
|
12
12
|
import { extractRoutingDeclarations, routingExtractorIdentity } from '../extraction/routing.js';
|
|
13
13
|
import { RdfEvidenceGraph } from '../graph/rdf.js';
|
|
14
14
|
import { graphAssemblyIdentity } from './extraction-identity.js';
|
|
15
|
+
import { assertGraphIdentities } from '../graph/identity-preflight.js';
|
|
15
16
|
const execute = promisify(execFile);
|
|
16
17
|
const implementationExtractors = new Set([
|
|
17
18
|
'repository-file-extractor', 'repository-contract-extractor', 'scip-symbol-extractor',
|
|
18
19
|
routingExtractorIdentity.id,
|
|
19
20
|
]);
|
|
20
21
|
/** Conservative code overlay: reindex implementation; invalidate changed prose, never synthesize intent. */
|
|
21
|
-
export async function buildWorkingOverlay(repository, config, store, storageRoot, baseSnapshotId, agent = 'default') {
|
|
22
|
+
export async function buildWorkingOverlay(repository, config, store, storageRoot, baseSnapshotId, agent = 'default', options = {}) {
|
|
22
23
|
const base = await store.read(baseSnapshotId);
|
|
23
24
|
if (!base || base.manifest.overlayDigest)
|
|
24
25
|
throw new Error('Overlay requires a committed base snapshot');
|
|
@@ -119,6 +120,7 @@ export async function buildWorkingOverlay(repository, config, store, storageRoot
|
|
|
119
120
|
!affected.has(fact.provenance.path) &&
|
|
120
121
|
![fact.subject, fact.object].some((node) => [...affected].some((path) => node.id === `component:file:${path}` || node.id === `document:${path}` || node.label === path))).map((fact) => ({ ...fact, snapshotId }));
|
|
121
122
|
const allFacts = [...retained, ...extracted.facts].sort((a, b) => a.id.localeCompare(b.id));
|
|
123
|
+
assertGraphIdentities(allFacts, { repositoryId: config.repositoryId, includeDetails: options.validationDetails });
|
|
122
124
|
const overlay = {
|
|
123
125
|
...base,
|
|
124
126
|
manifest: {
|
|
@@ -7,6 +7,9 @@ export interface HydrationProgressEvent {
|
|
|
7
7
|
readonly total?: number;
|
|
8
8
|
readonly sourceId?: string;
|
|
9
9
|
readonly elapsedMs?: number;
|
|
10
|
+
readonly status?: 'started' | 'completed' | 'failed';
|
|
11
|
+
readonly factCount?: number;
|
|
12
|
+
readonly nodeCount?: number;
|
|
10
13
|
}
|
|
11
14
|
/** Settle active workers before reporting failure; never publish snapshots here. */
|
|
12
15
|
export declare function hydrateSemanticSources(options: {
|
|
@@ -113,7 +113,7 @@ function validateConfig(value, absolutePath) {
|
|
|
113
113
|
requireConfig(auth.apiKeyEnv === undefined || (typeof auth.apiKeyEnv === 'string' && /^[A-Za-z_][A-Za-z0-9_]*$/.test(auth.apiKeyEnv)), 'semantic.auth.apiKeyEnv must name an environment variable', absolutePath);
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
|
-
for (const [field, max] of [['timeoutMs',
|
|
116
|
+
for (const [field, max] of [['timeoutMs', 600_000], ['retries', 2], ['maxDocuments', 1000], ['maxSourceBytes', 1_048_576]]) {
|
|
117
117
|
const item = value.semantic[field];
|
|
118
118
|
if (item !== undefined)
|
|
119
119
|
requireConfig(Number.isInteger(item) && Number(item) >= (field === 'retries' ? 0 : 1) && Number(item) <= max, `semantic.${field} exceeds supported bounds`, absolutePath);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type ExtractorIdentity, type GraphFact, type GraphNodeKind, type SourceSpan } from '@weftlet/core';
|
|
2
|
+
/** Diagnostic detail is an invocation option, not extraction policy or a cache identity input. */
|
|
3
|
+
export interface GraphIdentityPreflightOptions {
|
|
4
|
+
readonly repositoryId: string;
|
|
5
|
+
readonly includeDetails?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export type ReportedIdentityKind = GraphNodeKind | `unknown-kind-${string}`;
|
|
8
|
+
export interface GraphIdentityOccurrenceDetails {
|
|
9
|
+
readonly nodeId: string;
|
|
10
|
+
readonly nodeKind: GraphNodeKind;
|
|
11
|
+
readonly factId: string;
|
|
12
|
+
readonly extractor: ExtractorIdentity;
|
|
13
|
+
readonly provenance: SourceSpan;
|
|
14
|
+
readonly confidence: number;
|
|
15
|
+
readonly authority?: GraphFact['authority'];
|
|
16
|
+
readonly sourceAuthority?: GraphFact['sourceAuthority'];
|
|
17
|
+
readonly extractionReview?: GraphFact['extractionReview'];
|
|
18
|
+
}
|
|
19
|
+
export interface GraphIdentityOccurrence {
|
|
20
|
+
readonly factIndex: number;
|
|
21
|
+
readonly side: 'subject' | 'object';
|
|
22
|
+
readonly kind: ReportedIdentityKind;
|
|
23
|
+
readonly factRef: string;
|
|
24
|
+
readonly sourceRef: string;
|
|
25
|
+
readonly extractorRef: string;
|
|
26
|
+
readonly details?: GraphIdentityOccurrenceDetails;
|
|
27
|
+
}
|
|
28
|
+
export interface GraphIdentityConflict {
|
|
29
|
+
readonly nodeRef: string;
|
|
30
|
+
readonly kinds: readonly ReportedIdentityKind[];
|
|
31
|
+
readonly occurrences: readonly GraphIdentityOccurrence[];
|
|
32
|
+
readonly details?: {
|
|
33
|
+
readonly nodeId: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export interface GraphIdentityPreflightReport {
|
|
37
|
+
readonly schemaVersion: 1;
|
|
38
|
+
readonly kind: 'graph-identity-preflight';
|
|
39
|
+
readonly category: 'extraction-gap';
|
|
40
|
+
readonly phase: 'validate-identities';
|
|
41
|
+
readonly passed: boolean;
|
|
42
|
+
/** A passing identity preflight never establishes full graph conformance. */
|
|
43
|
+
readonly shaclValidated: false;
|
|
44
|
+
readonly factCount: number;
|
|
45
|
+
readonly nodeCount: number;
|
|
46
|
+
readonly conflictCount: number;
|
|
47
|
+
readonly conflicts: readonly GraphIdentityConflict[];
|
|
48
|
+
}
|
|
49
|
+
/** Find the single-kind constraint's conflicts without constructing RDF or changing any fact. */
|
|
50
|
+
export declare function inspectGraphIdentities(facts: readonly GraphFact[], options: GraphIdentityPreflightOptions): GraphIdentityPreflightReport;
|
|
51
|
+
/** The message is safe even when the caller explicitly requested local report details. */
|
|
52
|
+
export declare class GraphIdentityConflictError extends Error {
|
|
53
|
+
readonly report: GraphIdentityPreflightReport;
|
|
54
|
+
readonly code = "node-kind-conflict";
|
|
55
|
+
constructor(report: GraphIdentityPreflightReport);
|
|
56
|
+
}
|
|
57
|
+
export declare function assertGraphIdentities(facts: readonly GraphFact[], options: GraphIdentityPreflightOptions): GraphIdentityPreflightReport;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { sha256, stableJson } from '@weftlet/core';
|
|
2
|
+
const publicKinds = new Set([
|
|
3
|
+
'Project', 'Document', 'Capability', 'Workflow', 'Component', 'Contract', 'Evidence',
|
|
4
|
+
'Invariant', 'Snapshot', 'Provider', 'PersistenceModel', 'Scope',
|
|
5
|
+
]);
|
|
6
|
+
/** Find the single-kind constraint's conflicts without constructing RDF or changing any fact. */
|
|
7
|
+
export function inspectGraphIdentities(facts, options) {
|
|
8
|
+
const identities = new Map();
|
|
9
|
+
for (const fact of facts)
|
|
10
|
+
for (const node of [fact.subject, fact.object]) {
|
|
11
|
+
let kinds = identities.get(node.id);
|
|
12
|
+
if (!kinds)
|
|
13
|
+
identities.set(node.id, kinds = new Set());
|
|
14
|
+
kinds.add(node.kind);
|
|
15
|
+
}
|
|
16
|
+
const ref = (domain, ...values) => `identity-${domain}-${sha256(stableJson(['graph-identity-preflight-v1', options.repositoryId, domain, ...values]))}`;
|
|
17
|
+
const reportedKind = (kind) => publicKinds.has(kind)
|
|
18
|
+
? kind : `unknown-kind-${sha256(stableJson(['graph-identity-kind-v1', options.repositoryId, kind]))}`;
|
|
19
|
+
const conflicts = new Map();
|
|
20
|
+
for (const [id, kinds] of identities)
|
|
21
|
+
if (kinds.size > 1) {
|
|
22
|
+
conflicts.set(id, { nodeRef: ref('node', id), kinds: [...kinds].map(reportedKind), occurrences: [],
|
|
23
|
+
...(options.includeDetails ? { details: { nodeId: id } } : {}) });
|
|
24
|
+
}
|
|
25
|
+
// The common conflict-free path allocates no evidence reports. Preserve every conflicting
|
|
26
|
+
// occurrence, including duplicate fact IDs and the two ends of a self-reference.
|
|
27
|
+
if (conflicts.size)
|
|
28
|
+
for (const [factIndex, fact] of facts.entries()) {
|
|
29
|
+
const sides = ['subject', 'object'].filter(side => conflicts.has(fact[side].id));
|
|
30
|
+
if (!sides.length)
|
|
31
|
+
continue;
|
|
32
|
+
const references = { factRef: ref('fact', fact.id), sourceRef: ref('source', fact.provenance.path),
|
|
33
|
+
extractorRef: ref('extractor', fact.extractor.id, fact.extractor.version) };
|
|
34
|
+
for (const side of sides) {
|
|
35
|
+
const node = fact[side];
|
|
36
|
+
conflicts.get(node.id).occurrences.push({ factIndex, side, kind: reportedKind(node.kind), ...references,
|
|
37
|
+
...(options.includeDetails ? { details: {
|
|
38
|
+
nodeId: node.id, nodeKind: node.kind, factId: fact.id,
|
|
39
|
+
extractor: { id: fact.extractor.id, version: fact.extractor.version },
|
|
40
|
+
provenance: { path: fact.provenance.path, startLine: fact.provenance.startLine,
|
|
41
|
+
endLine: fact.provenance.endLine, digest: fact.provenance.digest, commitSha: fact.provenance.commitSha },
|
|
42
|
+
confidence: fact.confidence,
|
|
43
|
+
...(fact.authority === undefined ? {} : { authority: fact.authority }),
|
|
44
|
+
...(fact.sourceAuthority === undefined ? {} : { sourceAuthority: fact.sourceAuthority }),
|
|
45
|
+
...(fact.extractionReview === undefined ? {} : { extractionReview: fact.extractionReview }),
|
|
46
|
+
} } : {}) });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return { schemaVersion: 1, kind: 'graph-identity-preflight', category: 'extraction-gap',
|
|
50
|
+
phase: 'validate-identities', passed: conflicts.size === 0, shaclValidated: false,
|
|
51
|
+
factCount: facts.length, nodeCount: identities.size, conflictCount: conflicts.size,
|
|
52
|
+
conflicts: [...conflicts.values()] };
|
|
53
|
+
}
|
|
54
|
+
/** The message is safe even when the caller explicitly requested local report details. */
|
|
55
|
+
export class GraphIdentityConflictError extends Error {
|
|
56
|
+
report;
|
|
57
|
+
code = 'node-kind-conflict';
|
|
58
|
+
constructor(report) {
|
|
59
|
+
super(`Graph identity preflight found ${report.conflictCount} node kind conflict(s) across ${report.factCount} facts. ` +
|
|
60
|
+
'Full SHACL validation was not run. Use --validation-details for local node and cited evidence details. ' +
|
|
61
|
+
'Correct the extractor or assertion identity disagreement, then retry; no graph facts were rewritten by this check.');
|
|
62
|
+
this.report = report;
|
|
63
|
+
this.name = 'GraphIdentityConflictError';
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export function assertGraphIdentities(facts, options) {
|
|
67
|
+
const report = inspectGraphIdentities(facts, options);
|
|
68
|
+
if (!report.passed)
|
|
69
|
+
throw new GraphIdentityConflictError(report);
|
|
70
|
+
return report;
|
|
71
|
+
}
|
package/dist/graph/rdf.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { GraphFact, GraphSnapshot } from "@weftlet/core";
|
|
2
|
+
import { type GraphValidationProgress } from './validation-progress.js';
|
|
2
3
|
export { CG } from './shacl-shapes.js';
|
|
3
4
|
export declare const nodeIri: (id: string) => string;
|
|
4
5
|
export declare const factIri: (id: string) => string;
|
|
@@ -7,7 +8,9 @@ export declare class RdfEvidenceGraph {
|
|
|
7
8
|
readonly snapshot: GraphSnapshot;
|
|
8
9
|
private readonly dataset;
|
|
9
10
|
constructor(snapshot: GraphSnapshot);
|
|
10
|
-
validate(
|
|
11
|
+
validate(options?: {
|
|
12
|
+
readonly onProgress?: (event: GraphValidationProgress) => void;
|
|
13
|
+
}): Promise<{
|
|
11
14
|
conforms: boolean;
|
|
12
15
|
issues: {
|
|
13
16
|
category: "extraction-gap";
|
package/dist/graph/rdf.js
CHANGED
|
@@ -5,6 +5,7 @@ import { contextPackEvidenceAuthority } from "./authority.js";
|
|
|
5
5
|
import { stableJson } from "../infrastructure/util.js";
|
|
6
6
|
import { createRequire } from 'node:module';
|
|
7
7
|
import { CG, RDF, XSD, evidenceShapes } from './shacl-shapes.js';
|
|
8
|
+
import { measureValidationPhase } from './validation-progress.js';
|
|
8
9
|
const { namedNode: iri, literal } = DataFactory;
|
|
9
10
|
export { CG } from './shacl-shapes.js';
|
|
10
11
|
export const nodeIri = (id) => `urn:context-graph:node:${encodeURIComponent(id)}`;
|
|
@@ -61,16 +62,19 @@ export class RdfEvidenceGraph {
|
|
|
61
62
|
this.dataset.addQuad(iri('urn:context-graph:snapshot'), iri(CG + 'configurationDigest'), literal(snapshot.manifest.configurationDigest));
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
|
-
async validate() {
|
|
65
|
+
async validate(options = {}) {
|
|
65
66
|
// These graph-independent shapes already read the dataset as a union. Index
|
|
66
67
|
// that union once so every property lookup avoids scanning one graph per fact.
|
|
67
68
|
// Keep every triple; the original named dataset retains assertion provenance
|
|
68
69
|
// and remains the source for queries and serialization.
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
const counts = { factCount: this.snapshot.facts.length };
|
|
71
|
+
const validationGraph = await measureValidationPhase('build-validation-union', counts, options.onProgress, () => {
|
|
72
|
+
const union = new Store();
|
|
73
|
+
for (const { subject, predicate, object } of this.dataset)
|
|
74
|
+
union.addQuad(subject, predicate, object);
|
|
75
|
+
return union;
|
|
76
|
+
});
|
|
77
|
+
const report = await measureValidationPhase('validate-shacl', counts, options.onProgress, () => new SHACLValidator(new Store(evidenceShapes)).validate(validationGraph));
|
|
74
78
|
const issues = report.results.map((result) => ({
|
|
75
79
|
category: 'extraction-gap',
|
|
76
80
|
focus: result.focusNode?.value,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type GraphValidationPhase = 'validate-identities' | 'build-rdf-evidence' | 'build-validation-union' | 'validate-shacl';
|
|
2
|
+
export interface GraphValidationProgress {
|
|
3
|
+
readonly phase: GraphValidationPhase;
|
|
4
|
+
readonly status: 'started' | 'completed' | 'failed';
|
|
5
|
+
/** Wall time for this phase, not a completion estimate or in-phase heartbeat. */
|
|
6
|
+
readonly elapsedMs: number;
|
|
7
|
+
readonly factCount: number;
|
|
8
|
+
readonly nodeCount?: number;
|
|
9
|
+
}
|
|
10
|
+
/** Phase boundaries remain observable even when an operation blocks same-thread timers. */
|
|
11
|
+
export declare function measureValidationPhase<T>(phase: GraphValidationPhase, counts: {
|
|
12
|
+
readonly factCount: number;
|
|
13
|
+
readonly nodeCount?: number;
|
|
14
|
+
}, onProgress: ((event: GraphValidationProgress) => void) | undefined, operation: () => T | Promise<T>): Promise<T>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Phase boundaries remain observable even when an operation blocks same-thread timers. */
|
|
2
|
+
export async function measureValidationPhase(phase, counts, onProgress, operation) {
|
|
3
|
+
const started = performance.now();
|
|
4
|
+
const emit = (status) => onProgress?.({
|
|
5
|
+
phase, status, ...counts, elapsedMs: Math.max(0, Math.round(performance.now() - started)),
|
|
6
|
+
});
|
|
7
|
+
emit('started');
|
|
8
|
+
let result;
|
|
9
|
+
try {
|
|
10
|
+
result = await operation();
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
emit('failed');
|
|
14
|
+
throw error;
|
|
15
|
+
}
|
|
16
|
+
emit('completed');
|
|
17
|
+
return result;
|
|
18
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,3 +13,5 @@ export * from './application/hydration-plan.js';
|
|
|
13
13
|
export * from './application/cache-adoption.js';
|
|
14
14
|
export * from './application/hydration-failure.js';
|
|
15
15
|
export * from './extraction/semantic-diagnostics.js';
|
|
16
|
+
export * from './graph/identity-preflight.js';
|
|
17
|
+
export * from './graph/validation-progress.js';
|
package/dist/index.js
CHANGED
|
@@ -14,3 +14,5 @@ export * from './application/hydration-plan.js';
|
|
|
14
14
|
export * from './application/cache-adoption.js';
|
|
15
15
|
export * from './application/hydration-failure.js';
|
|
16
16
|
export * from './extraction/semantic-diagnostics.js';
|
|
17
|
+
export * from './graph/identity-preflight.js';
|
|
18
|
+
export * from './graph/validation-progress.js';
|
package/dist/interfaces/cli.js
CHANGED
|
@@ -18,6 +18,7 @@ import { loadConfig } from "../configuration/config.js";
|
|
|
18
18
|
import { planHydration } from '../application/hydration-plan.js';
|
|
19
19
|
import { adoptSemanticCache } from '../application/cache-adoption.js';
|
|
20
20
|
import { SemanticHydrationError } from '../application/hydration-failure.js';
|
|
21
|
+
import { GraphIdentityConflictError } from '../graph/identity-preflight.js';
|
|
21
22
|
function valueAfter(args, name) {
|
|
22
23
|
const index = args.indexOf(name);
|
|
23
24
|
return index >= 0 ? args[index + 1] : undefined;
|
|
@@ -82,7 +83,7 @@ function formatHydrationPlan(plan) {
|
|
|
82
83
|
async function main() {
|
|
83
84
|
const args = process.argv.slice(2);
|
|
84
85
|
if (args.includes('--help') || !args.length) {
|
|
85
|
-
process.stdout.write('weftlet init|config show|config validate|doctor|hydrate|cache adopt|overlay|impact scan|sparql|validate|govern|visualize|diagnostics show|invariant check|clean-compare|ontology compile\nUse --config <file>; queries accept --snapshot <id>. impact scan accepts --changed-file, --capability, --max-facts, --max-depth, --continuation.\nhydrate --plan [--json] [--ref <commit>] [--force-semantic] previews scope, cache and budgets without model calls or graph writes. Preview readiness is advisory and does not add a hydration gate.\nhydrate --json --quiet emits structured semantic failures on stderr with no progress lines; failure stdout stays empty. hydrate --plan maps opaque source IDs to local document paths.\ncache adopt --from-config <previous.json> [--config <current.json>] [--ref <commit>] [--dry-run] returns JSON and copies only validated compatible artifacts, without model calls or snapshot writes. --dry-run performs no cache writes. Agent configurations accept the same --owner-doc, --task and --capability selection as hydrate.\ninit [--yes] [--directory <project>] [--config <file>] [--repository-id <id>] [--code-root <path>] [--semantic-source <path>] [--evidence-root <path>] [--model <name>] [--no-gitignore]\nSource flags may be repeated. init never overwrites an existing config. See README.md for examples.\n');
|
|
86
|
+
process.stdout.write('weftlet init|config show|config validate|doctor|hydrate|cache adopt|overlay|impact scan|sparql|validate|govern|visualize|diagnostics show|invariant check|clean-compare|ontology compile\nUse --config <file>; queries accept --snapshot <id>. impact scan accepts --changed-file, --capability, --max-facts, --max-depth, --continuation.\nhydrate --plan [--json] [--ref <commit>] [--force-semantic] previews scope, cache and budgets without model calls or graph writes. Preview readiness is advisory and does not add a hydration gate.\nhydrate --json --quiet emits structured semantic failures on stderr with no progress lines; failure stdout stays empty. hydrate --plan maps opaque source IDs to local document paths.\nhydrate|overlay --validation-details explicitly includes local node/fact identities, extractor names and source citations in identity-conflict errors; default reports use opaque references. This flag writes no diagnostic file. Use --json --quiet for structured identity-conflict stderr and empty failure stdout. Validation timings report phase boundaries, not a live heartbeat or percentage.\ncache adopt --from-config <previous.json> [--config <current.json>] [--ref <commit>] [--dry-run] returns JSON and copies only validated compatible artifacts, without model calls or snapshot writes. --dry-run performs no cache writes. Agent configurations accept the same --owner-doc, --task and --capability selection as hydrate.\ninit [--yes] [--directory <project>] [--config <file>] [--repository-id <id>] [--code-root <path>] [--semantic-source <path>] [--evidence-root <path>] [--model <name>] [--no-gitignore]\nSource flags may be repeated. init never overwrites an existing config. See README.md for examples.\n');
|
|
86
87
|
return;
|
|
87
88
|
}
|
|
88
89
|
if (args[0] === 'init') {
|
|
@@ -171,7 +172,7 @@ async function main() {
|
|
|
171
172
|
const base = valueAfter(args, '--base-snapshot');
|
|
172
173
|
if (!base)
|
|
173
174
|
throw new Error('overlay requires --base-snapshot <committed snapshot ID>');
|
|
174
|
-
const result = await buildWorkingOverlay(application.repository, application.config, application.snapshotStore, application.storageRoot, base, valueAfter(args, '--agent'));
|
|
175
|
+
const result = await buildWorkingOverlay(application.repository, application.config, application.snapshotStore, application.storageRoot, base, valueAfter(args, '--agent'), { validationDetails: args.includes('--validation-details') });
|
|
175
176
|
process.stdout.write(`${JSON.stringify(result.manifest, null, 2)}\n`);
|
|
176
177
|
return;
|
|
177
178
|
}
|
|
@@ -187,8 +188,11 @@ async function main() {
|
|
|
187
188
|
headName: scope?.headName ?? application.headName,
|
|
188
189
|
semanticSources: scope?.semanticSources,
|
|
189
190
|
forceSemantic: args.includes('--force-semantic'),
|
|
191
|
+
validationDetails: args.includes('--validation-details'),
|
|
190
192
|
signal: controller.signal,
|
|
191
193
|
onProgress: args.includes('--quiet') ? undefined : (event) => process.stderr.write(`[context-graph] ${event.phase}${event.total === undefined ? '' : ` ${event.completed}/${event.total}`}` +
|
|
194
|
+
`${event.status === undefined ? '' : ` ${event.status}`}` +
|
|
195
|
+
`${event.factCount === undefined ? '' : ` facts=${event.factCount}`}${event.nodeCount === undefined ? '' : ` nodes=${event.nodeCount}`}` +
|
|
192
196
|
`${event.sourceId === undefined ? '' : ` ${event.sourceId}`}${event.elapsedMs === undefined ? '' : ` ${event.elapsedMs} ms`}\n`),
|
|
193
197
|
});
|
|
194
198
|
process.stdout.write(`${JSON.stringify({
|
|
@@ -257,8 +261,11 @@ async function main() {
|
|
|
257
261
|
throw new Error('Usage: weftlet hydrate|clean-compare|impact scan|diagnostics show --snapshot <id>|invariant check|ontology compile|visualize --output <file.html|file.dot|file.svg>');
|
|
258
262
|
}
|
|
259
263
|
main().catch((error) => {
|
|
260
|
-
process.stderr.write(`${error instanceof
|
|
261
|
-
? process.argv.includes('--json')
|
|
262
|
-
|
|
264
|
+
process.stderr.write(`${error instanceof GraphIdentityConflictError
|
|
265
|
+
? process.argv.includes('--json') || process.argv.includes('--validation-details')
|
|
266
|
+
? JSON.stringify(error.report, null, 2) : error.message
|
|
267
|
+
: error instanceof SemanticHydrationError
|
|
268
|
+
? process.argv.includes('--json') ? JSON.stringify(error.report, null, 2) : error.message
|
|
269
|
+
: error instanceof Error ? (error.stack ?? error.message) : String(error)}\n`);
|
|
263
270
|
process.exitCode = 1;
|
|
264
271
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# ADR-018: Preserve Codex artifacts across operational configuration changes
|
|
2
2
|
|
|
3
|
-
Status: accepted and
|
|
4
|
-
|
|
3
|
+
Status: accepted and shipped in 0.4.0; release and validation evidence is recorded in
|
|
4
|
+
[validation](VALIDATION.md).
|
|
5
5
|
|
|
6
6
|
## Problem
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# ADR-019: Safe semantic failure diagnostics and settled progress
|
|
2
2
|
|
|
3
|
-
Status:
|
|
4
|
-
|
|
3
|
+
Status: shipped in 0.4.0; validation and publication are recorded in [validation](VALIDATION.md).
|
|
4
|
+
This decision does not change extraction identity.
|
|
5
5
|
|
|
6
6
|
## Problem
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# ADR-020: One physical-file policy for deterministic producers and adapters
|
|
2
2
|
|
|
3
|
-
Status:
|
|
4
|
-
separately in [validation](VALIDATION.md).
|
|
3
|
+
Status: upstream fix shipped in 0.4.0; release evidence and pending consumer adapter/hydration
|
|
4
|
+
acceptance are recorded separately in [validation](VALIDATION.md).
|
|
5
5
|
|
|
6
6
|
## Reported defect and ownership
|
|
7
7
|
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# ADR-021: Early identity conflicts and honest validation phase timing
|
|
2
|
+
|
|
3
|
+
Status: implemented in development source after 0.4.0. Publication and consumer acceptance
|
|
4
|
+
are separate checkpoints in [validation](VALIDATION.md). This is the bounded T05a increment.
|
|
5
|
+
|
|
6
|
+
## Decision
|
|
7
|
+
|
|
8
|
+
Before ontology compilation, invariant evaluation or RDF construction, scan every assembled
|
|
9
|
+
fact's subject and object identity for multiple kinds. The scan covers semantic, document,
|
|
10
|
+
static, adapter, routing and runtime facts, including conceptual identities. Working overlays
|
|
11
|
+
run the same check over retained and newly extracted facts before RDF construction/publication.
|
|
12
|
+
No fact, kind, ID, citation or authority is changed or discarded by the check.
|
|
13
|
+
This runs after semantic/static extraction; it is separate from no-model `hydrate --plan`.
|
|
14
|
+
|
|
15
|
+
`inspectGraphIdentities(facts, { repositoryId, includeDetails? })` returns a report;
|
|
16
|
+
`assertGraphIdentities` throws `GraphIdentityConflictError` on conflicts. Both are public toolkit
|
|
17
|
+
exports. A passing report has `passed: true` and **`shaclValidated: false`**. Consistent kinds
|
|
18
|
+
alone do not establish canonical classification, correct intent, valid citations or conformance.
|
|
19
|
+
The existing full RDF/SHACL path and shapes remain mandatory for successful publication. Direct
|
|
20
|
+
`RdfEvidenceGraph.validate()` and the saved `validate` command still run all checks and return
|
|
21
|
+
their existing verdict format. There is no validation cache, incremental validator or backend change.
|
|
22
|
+
|
|
23
|
+
The two-pass scan is linear in fact occurrences. The common conflict-free path creates no
|
|
24
|
+
per-evidence diagnostic records. On failure it reports every conflicting identity and occurrence,
|
|
25
|
+
including both ends of a self-reference, repeated fact IDs and late conflicts. Counts are complete;
|
|
26
|
+
there is no hidden document, hop or diagnostic cutoff. Reports retain input indices and side so
|
|
27
|
+
duplicate assertion IDs cannot conceal a producer's occurrence.
|
|
28
|
+
|
|
29
|
+
## Privacy and attribution
|
|
30
|
+
|
|
31
|
+
There was no general configurable diagnostic privacy policy. This increment therefore makes
|
|
32
|
+
local detail an explicit invocation option, without adding an extraction/configuration field.
|
|
33
|
+
Default reports contain repository-scoped opaque node, fact, source and extractor references,
|
|
34
|
+
counts and recognized kind names. Unknown kind strings are hashed as well. References correlate
|
|
35
|
+
records; they are not encryption or proof that a low-entropy identifier cannot be guessed.
|
|
36
|
+
|
|
37
|
+
`hydrate --json --quiet` emits a typed identity-failure report on stderr with empty stdout.
|
|
38
|
+
Use `--validation-details` on `hydrate` or `overlay` only when local identities and citations
|
|
39
|
+
may be displayed. That option includes exact node/fact IDs, extractor identity/version, citation
|
|
40
|
+
path/lines/digest/commit, confidence and the original optional authority/review fields. It does
|
|
41
|
+
not include labels, node attributes, source text, prompts or raw provider output. Absent authority
|
|
42
|
+
fields stay absent; source approval is never promoted into assertion approval.
|
|
43
|
+
|
|
44
|
+
The programmatic equivalent is `HydrationOptions.validationDetails` or the overlay's final
|
|
45
|
+
options argument. Detail changes do not enter snapshot, provider or semantic-cache identities.
|
|
46
|
+
The error message stays safe even when its report includes explicitly requested local details.
|
|
47
|
+
No diagnostic file is written automatically. Existing non-identity SHACL errors retain their
|
|
48
|
+
existing detailed behavior; this is not a claim that every command/error has been redacted.
|
|
49
|
+
|
|
50
|
+
## Timing and failure preservation
|
|
51
|
+
|
|
52
|
+
Hydration reports started/completed/failed boundaries and elapsed wall time for identity
|
|
53
|
+
preflight, RDF construction, union construction and full SHACL. Counts describe graph size,
|
|
54
|
+
not validator completion. A completed SHACL phase means the validator returned, including a
|
|
55
|
+
nonconforming verdict. `RdfEvidenceGraph.validate({ onProgress })` exposes its union/SHACL phases.
|
|
56
|
+
|
|
57
|
+
The synchronous JavaScript work can block same-thread timers. These events are not heartbeats,
|
|
58
|
+
percentages, new timeout controls or interruptible worker execution. Worker isolation remains a
|
|
59
|
+
separate decision. The public profiling harness records preflight and validation phase timings
|
|
60
|
+
alongside its existing construction, resource and runtime measurements.
|
|
61
|
+
|
|
62
|
+
Failure preserves completed semantic artifacts and prior snapshots/heads. Correcting and
|
|
63
|
+
versioning an adapter still requires a fresh assembly and full validation, but compatible
|
|
64
|
+
semantic artifacts can be reused. This preflight does not rewrite cached model assertions or
|
|
65
|
+
choose an authoritative business rule. Evidence disagreements must be resolved at their owner.
|
|
66
|
+
|
|
67
|
+
No extraction/assembly version changes are needed: accepted graph facts, cache identities,
|
|
68
|
+
RDF serialization and conformance constraints are unchanged. The check rejects an existing
|
|
69
|
+
single-kind violation earlier; it does not make old snapshots satisfy current validation.
|
|
70
|
+
|
|
71
|
+
## Evidence and remaining work
|
|
72
|
+
|
|
73
|
+
Tests cover full cross-source attribution, conceptual and physical nodes, exact authority,
|
|
74
|
+
default privacy, late conflicts, duplicates/self-references, immutable artifacts/snapshots,
|
|
75
|
+
corrected retries and non-kind failures that still reach full SHACL. CLI and packed-consumer
|
|
76
|
+
cases use actual TypeScript SCIP and public adapters. Existing positive/negative named-dataset
|
|
77
|
+
SHACL equivalence tests remain unchanged except for an additional timing/parity case.
|
|
78
|
+
|
|
79
|
+
Broader T05 work remains: worker-based progress/cancellation, repeated/changed-input performance
|
|
80
|
+
evaluation, and evidence-driven decisions about conformance-result reuse or incremental/native
|
|
81
|
+
backends. This increment does not infer private consumer performance from public fixtures.
|
package/docs/PROVIDERS.md
CHANGED
|
@@ -87,6 +87,13 @@ Codex attempt (or module execution), no retries, and the configured concurrency
|
|
|
87
87
|
before any model call. `maxDocuments`, `maxSourceBytes`, `timeoutMs`, and `retries` may be configured
|
|
88
88
|
within validated limits. Review scope and cost before raising them; these byte/document limits
|
|
89
89
|
are not dollar or token estimates. Ask the operator before substantial paid runs.
|
|
90
|
+
Starting with 0.5.0, `semantic.timeoutMs` accepts integer values from 1 through **600000**
|
|
91
|
+
(ten minutes); 0.4.0 and earlier reject values above 300000. The default remains 120000.
|
|
92
|
+
For the approved ten-minute retry, set `"timeoutMs": 600000` inside the existing `semantic`
|
|
93
|
+
configuration, preview reuse with `hydrate --plan`, then rerun hydration without forcing
|
|
94
|
+
re-extraction. The limit applies to each Codex attempt, or the whole module execution, rather
|
|
95
|
+
than the entire hydration. Codex authentication/discovery checks retain their separate five-second
|
|
96
|
+
bounds. This setting does not raise a CI job's overall timeout or change retry policy.
|
|
90
97
|
Only explicit transient exit status 75 is retryable, at most twice; authentication, invalid
|
|
91
98
|
output, cancellation and ambiguous failures are not retried. Ctrl-C cancels live CLI extraction.
|
|
92
99
|
Indexing cancellation is checked between phases, not inside the indexer process.
|
package/docs/RELEASE-1.0-PLAN.md
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
# Consumer hardening and the 1.0 release plan
|
|
2
2
|
|
|
3
|
-
Status: maintainer-directed work; release checkpoint on 2026-10-26 after verified 0.
|
|
4
|
-
**
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
Status: maintainer-directed work; release checkpoint on 2026-10-26 after verified 0.4.0 publication.
|
|
4
|
+
**T08's upstream deterministic physical-file fix has shipped; the maintainer reports the consumer
|
|
5
|
+
updated and working on 2026-10-27. Detailed full hydration/repeat evidence remains pending.** T04 was completed before
|
|
6
|
+
the T08 fix as requested.
|
|
7
|
+
|
|
8
|
+
**Release priority T09:** 0.4.0 rejects the approved ten-minute extraction timeout. Support for
|
|
9
|
+
`semantic.timeoutMs: 600000` is implemented for the next release alongside ready T05a work;
|
|
10
|
+
the consumer's ten-minute retry has not run. This bounded blocker precedes T06/T07.
|
|
11
|
+
|
|
12
|
+
The original report concerned `@weftlet/toolkit@0.2.0`. T01's upstream document-identity patch
|
|
13
|
+
shipped in 0.2.1; T02 and T05's focused cold-validation optimization shipped in 0.3.0.
|
|
14
|
+
T03 operational cache reuse, T04 semantic failure diagnostics and T08's public core file factory
|
|
15
|
+
shipped in 0.4.0. Broader T05 follow-ups, T06 documentation consistency and T07 document coverage
|
|
16
|
+
remain open. Official 1.0 follows the agreed remaining scope and genuine consumer acceptance,
|
|
17
|
+
with its exact release scope reviewed when the evidence is available.
|
|
13
18
|
|
|
14
19
|
This is the near-term release task list. The [Weftlet 2.0 product plan](WEFTLET-2.0-PLAN.md)
|
|
15
20
|
remains a separate future direction for generation, approvals, a companion website and hosted
|
|
@@ -36,21 +41,23 @@ integration. Consumer acceptance is reported separately from upstream determinis
|
|
|
36
41
|
|
|
37
42
|
| ID | Task | Priority/status | Dependencies and release boundary |
|
|
38
43
|
| --- | --- | --- | --- |
|
|
39
|
-
| **
|
|
44
|
+
| **T09** | Accept the approved ten-minute extraction timeout | **Source fix implemented; release pending** | Raise only the config ceiling to 600000; preserve defaults/cache/retry behavior; consumer retry has not run |
|
|
45
|
+
| **T08** | Canonical physical-file kinds and public adapter factory | **Shipped in 0.4.0; consumer reported working; detailed acceptance pending** | Public core factory and neutral producers agree; record consumer commit, adapter tests and full hydration/repeat evidence |
|
|
40
46
|
| **T01** | Coherent repository-document identity and kind | **Upstream patch shipped in 0.2.1; consumer acceptance pending** | SHACL and assertions preserved; genuine consumer re-run is still required |
|
|
41
47
|
| **T02** | No-model hydration/setup preview | Shipped in 0.3.0 | Shared selection/cache inspection, human/JSON plans; extend with T07 traversal coverage |
|
|
42
|
-
| **T03** | Artifact reuse across operational configuration changes |
|
|
43
|
-
| **T04** | Actionable, privacy-safe timeout diagnostics |
|
|
44
|
-
| **T05** | Early identity checks and validation progress/profiling | **Cold
|
|
48
|
+
| **T03** | Artifact reuse across operational configuration changes | Shipped in 0.4.0 | Built-in Codex user artifacts share five operational changes; custom providers remain conservative; exact legacy recovery without model calls |
|
|
49
|
+
| **T04** | Actionable, privacy-safe timeout diagnostics | Shipped in 0.4.0 | Safe source IDs, settled counts, failure classification and T02/T03 recovery; no extraction/cache identity change |
|
|
50
|
+
| **T05** | Early identity checks and validation progress/profiling | **Cold fix shipped in 0.3.0; T05a merged with local/hosted checks passing, unreleased** | Full validation preserved; worker progress, reuse and broader profiling remain separate |
|
|
45
51
|
| **T06** | Packaged release-documentation consistency | Open; README version pins removed in 0.2.1 | Automated archive/version consistency check remains to be implemented |
|
|
46
52
|
| **T07** | Coverage-aware traversal from SOT/roadmap entry points | Planned bounded feature work | Use canonical identity from T01, preview from T02 and incremental reuse from T03; split selection/classification/extraction changes |
|
|
47
53
|
|
|
48
|
-
T02 and the focused T05 fix
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
tags are recorded in [validation](VALIDATION.md).
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
T02 and the focused T05 fix shipped in 0.3.0; T03, T04 and T08 shipped in
|
|
55
|
+
[0.4.0](https://github.com/jchewitt/weftlet/releases/tag/%40weftlet/toolkit%400.4.0), following
|
|
56
|
+
local/hosted checks, independent archive review and fresh packed/public-registry installation.
|
|
57
|
+
Source, registry integrity, provenance and release tags are recorded in [validation](VALIDATION.md).
|
|
58
|
+
Broader T05, T06 and T07 remain bounded follow-ups.
|
|
59
|
+
The consumer must migrate its framework adapter to the public core factory, then complete full
|
|
60
|
+
hydration and repeat reuse; upstream fixtures do not establish that result.
|
|
54
61
|
|
|
55
62
|
## T08 — Resolve deterministic physical-file kind conflicts
|
|
56
63
|
|
|
@@ -64,12 +71,12 @@ routes physical-file producers through one policy, preserves strict SHACL/proven
|
|
|
64
71
|
and distinguishes historical graph versions from current validation. Public tests include real
|
|
65
72
|
SCIP and actual extractor composition, plus negative overlay validation without routing.
|
|
66
73
|
|
|
67
|
-
|
|
68
|
-
fresh
|
|
69
|
-
plus its own framework adapter migration and composed Prisma/DI/decorator
|
|
70
|
-
followed by full hydration and repeat reuse.
|
|
71
|
-
adapter patch closes both ownership boundaries.
|
|
72
|
-
work to work around the proven deterministic defect.
|
|
74
|
+
The 0.4.0 release passed local publication checks, hosted Ubuntu/Windows checks, independent archive
|
|
75
|
+
review and fresh packed/public-registry installation. Consumer acceptance still requires the
|
|
76
|
+
published packages plus its own framework adapter migration and composed Prisma/DI/decorator
|
|
77
|
+
spec/test regressions, followed by full hydration and repeat reuse.
|
|
78
|
+
Neither an upstream-only release nor a local-only adapter patch closes both ownership boundaries.
|
|
79
|
+
Do not rewrite semantic caches or force model work to work around the proven deterministic defect.
|
|
73
80
|
|
|
74
81
|
## T01 — Resolve repository-document identity conflicts
|
|
75
82
|
|
|
@@ -110,7 +117,8 @@ Upstream completion evidence:
|
|
|
110
117
|
[validation record](VALIDATION.md) for commits, checks and result boundaries.
|
|
111
118
|
|
|
112
119
|
The private consumer has not yet supplied a successful full hydration/repeat with the identity
|
|
113
|
-
patch. Use
|
|
120
|
+
patch. Use both 0.4.0 packages and migrate the framework adapter to the public core factory;
|
|
121
|
+
this release retains the cold-validation improvement and adds the T08 deterministic producer fix.
|
|
114
122
|
Upstream publication and regression success do not close that acceptance gate or diagnose the
|
|
115
123
|
separate full-graph validation latency observation.
|
|
116
124
|
|
|
@@ -126,9 +134,9 @@ Missing or unsupported-only selectors and bounded agent omissions remain visible
|
|
|
126
134
|
incomplete plans need review and exit 1. They do not introduce new hydration gates that would
|
|
127
135
|
break deletion of the last document. Budget, duplicate-ID and corrupt/unavailable cache errors
|
|
128
136
|
block planning checks without truncating selected sources. An explicit empty source list selects
|
|
129
|
-
none. Requested refs
|
|
130
|
-
semantic artifacts remain reusable. T03
|
|
131
|
-
validation-document separation
|
|
137
|
+
none. Requested refs govern agent scope. Release 0.3.0 introduced graph-v6; 0.4.0 advances assembly
|
|
138
|
+
to graph-v7 for T08 while compatible semantic artifacts remain reusable. T03 operational cache
|
|
139
|
+
reuse shipped in 0.4.0; T07 traversal/default validation-document separation remains open.
|
|
132
140
|
|
|
133
141
|
Acceptance:
|
|
134
142
|
|
|
@@ -143,8 +151,8 @@ Acceptance:
|
|
|
143
151
|
|
|
144
152
|
## T03 — Reuse valid artifacts after operational changes
|
|
145
153
|
|
|
146
|
-
|
|
147
|
-
and hosted Ubuntu/Windows checks
|
|
154
|
+
Shipped in 0.4.0 after merging [PR 22](https://github.com/jchewitt/weftlet/pull/22) and passing
|
|
155
|
+
local publication and hosted Ubuntu/Windows checks; release evidence is in [validation](VALIDATION.md).
|
|
148
156
|
[ADR 018](ADR-018-operational-semantic-cache.md) separates built-in Codex user artifacts from
|
|
149
157
|
full snapshot profiles. Timeout, retry, concurrency and document/byte limits can change without
|
|
150
158
|
hiding completed artifacts. Model/policy/authentication descriptors and unknown fields remain
|
|
@@ -179,8 +187,8 @@ Acceptance:
|
|
|
179
187
|
|
|
180
188
|
## T04 — Explain timeouts and recovery
|
|
181
189
|
|
|
182
|
-
|
|
183
|
-
and hosted Ubuntu/Windows checks
|
|
190
|
+
Shipped in 0.4.0 after merging [PR 25](https://github.com/jchewitt/weftlet/pull/25) and passing
|
|
191
|
+
local publication and hosted Ubuntu/Windows checks; release evidence is in [validation](VALIDATION.md).
|
|
184
192
|
[ADR 019](ADR-019-semantic-failure-diagnostics.md) records opaque source IDs and explicit local
|
|
185
193
|
preview mapping, final counts after active workers settle, safe typed errors and recovery.
|
|
186
194
|
Concurrent sibling cancellation preserves the initiating failure. Completed writes stay counted
|
|
@@ -205,17 +213,26 @@ Acceptance:
|
|
|
205
213
|
|
|
206
214
|
## T05 — Detect inexpensive conflicts early and explain validation work
|
|
207
215
|
|
|
216
|
+
T05a implements [early identity attribution and phase timing](ADR-021-identity-preflight-and-validation-timing.md)
|
|
217
|
+
after 0.4.0, merged with local and hosted Ubuntu/Windows checks passing but not yet published.
|
|
218
|
+
Hydration and overlays reject all conflicting subject/object kinds before RDF construction;
|
|
219
|
+
opaque default reports have explicit local detail opt-in.
|
|
220
|
+
Completed semantic artifacts and prior snapshots remain intact. Valid preflight results still
|
|
221
|
+
require full SHACL. Timings report actual phase boundaries, not in-phase heartbeat or percentage.
|
|
222
|
+
This does not close the broader evaluation/reuse/backend items below or claim publication.
|
|
223
|
+
|
|
208
224
|
The implementation uses JavaScript on Node:
|
|
209
225
|
`rdf-validate-shacl` validates an in-memory N3 dataset. Hydration constructs and validates the
|
|
210
226
|
entire assembled graph, including when semantic artifacts were reused. There is no persistent
|
|
211
227
|
GraphDB backend or incremental validation. Querying a saved snapshot does not rerun SHACL.
|
|
212
228
|
|
|
213
|
-
The maintainer
|
|
229
|
+
The maintainer originally reported that validation pushed the consumer's overall generation beyond its
|
|
214
230
|
30-minute timeout, preventing snapshot publication and making adoption unusable. That report made
|
|
215
231
|
cold validation a release priority ahead of the remaining 1.0 work. Upstream has measured a specific
|
|
216
232
|
named-graph lookup cost in public synthetic fixtures, but has not measured that consumer graph or
|
|
217
233
|
diagnosed its complete timeout. The focused cold-validation fix shipped in 0.3.0, ahead of the
|
|
218
|
-
remaining 1.0 tasks.
|
|
234
|
+
remaining 1.0 tasks. The consumer is now reported working after 0.4.0; exact performance and
|
|
235
|
+
repeat-hydration acceptance evidence remains unrecorded. Broader T05 items stay open.
|
|
219
236
|
|
|
220
237
|
[ADR 017](ADR-017-shacl-validation-union.md) records the implemented cold-validation optimization:
|
|
221
238
|
build a temporary union of every SPO triple for the same validator/shapes, while keeping original
|
|
@@ -226,15 +243,15 @@ took 0.467 seconds. A 10,000-fact unique-node union case used about 1.3 GiB proc
|
|
|
226
243
|
are synthetic phase measurements, not a private consumer reproduction or end-to-end guarantee.
|
|
227
244
|
|
|
228
245
|
The focused change still validates the whole graph each time. It does not add Rust, GraphDB,
|
|
229
|
-
incremental validation or a validation-result cache.
|
|
230
|
-
|
|
246
|
+
incremental validation or a validation-result cache. T05a now adds early checks and phase timing;
|
|
247
|
+
worker progress and broader observability/reuse remain follow-ups. Native code or a database does
|
|
231
248
|
not by itself establish faster or correct incremental SHACL.
|
|
232
249
|
|
|
233
250
|
Acceptance:
|
|
234
251
|
|
|
235
|
-
- Early errors identify the conflicting identity/kinds and relevant evidence
|
|
236
|
-
|
|
237
|
-
substitute for RDF/SHACL validation.
|
|
252
|
+
- Early errors identify the conflicting identity/kinds and relevant evidence through opaque
|
|
253
|
+
defaults and explicit local detail opt-in. Preserve all underlying assertions for diagnosis;
|
|
254
|
+
early checks are not a substitute for RDF/SHACL validation.
|
|
238
255
|
- Report elapsed time and honest progress for long validation. Current phase boundaries remain
|
|
239
256
|
the supported progress signal: the synchronous validator blocks same-thread timers. Evaluate
|
|
240
257
|
bounded worker execution before promising an in-phase heartbeat or cancellation; never display
|
package/docs/ROADMAP.md
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
# Delivery roadmap
|
|
2
2
|
|
|
3
|
-
Release checkpoint: 2026-10-26, after verified 0.
|
|
3
|
+
Release checkpoint: 2026-10-26, after verified 0.4.0 publication. Evidence is recorded in
|
|
4
4
|
[validation](VALIDATION.md); this roadmap is not a live registry status.
|
|
5
5
|
|
|
6
6
|
Project: `jchewitt/weftlet`. Extraction provenance is recorded in the
|
|
7
7
|
[source inventory](SOURCE-INVENTORY.md).
|
|
8
8
|
|
|
9
|
+
Current release priority: the consumer's approved ten-minute retry is blocked by 0.4.0's
|
|
10
|
+
five-minute configuration ceiling. T09 raises the accepted timeout to 600000 ms and will ship
|
|
11
|
+
with ready T05a work. The actual consumer retry has not run; this does not change default limits.
|
|
12
|
+
|
|
9
13
|
Forward direction is captured in the [Weftlet 2.0 product plan](WEFTLET-2.0-PLAN.md):
|
|
10
14
|
consumer hardening, cited code-derived drafts, scoped approvals and reconciliation, an optional
|
|
11
15
|
review website, source publication, managed AI and guided setup. “2.0” is a planning label;
|
|
12
|
-
the verified release at this checkpoint is 0.
|
|
16
|
+
the verified release at this checkpoint is 0.4.0. The received consumer findings are tracked in the
|
|
13
17
|
[consumer hardening and 1.0 task list](RELEASE-1.0-PLAN.md): the document-identity patch is
|
|
14
18
|
published and passes upstream checks; genuine consumer acceptance remains pending. T02's
|
|
15
|
-
no-model preview and T05's cold-validation improvement shipped in 0.3.0.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
The 2.0 plan distinguishes proposed work from delivered capability.
|
|
19
|
+
no-model preview and T05's cold-validation improvement shipped in 0.3.0. T03 operational cache
|
|
20
|
+
reuse, T04 timeout diagnostics and T08 deterministic physical-file consistency shipped in 0.4.0.
|
|
21
|
+
Document coverage, broader validation follow-ups and genuine consumer acceptance remain open
|
|
22
|
+
before official 1.0. The 2.0 plan distinguishes proposed work from delivered capability.
|
|
19
23
|
|
|
20
24
|
The maintainer reported SHACL pushing generation past a 30-minute timeout before graph
|
|
21
25
|
publication. T02 and the focused T05 optimization shipped together in 0.3.0 through
|
|
@@ -32,25 +36,27 @@ in one temporary validation graph, preserving the same shapes and canonical name
|
|
|
32
36
|
Bounded public experiments measured substantial cold-path improvement, alongside about 1.3 GiB
|
|
33
37
|
RSS in the prototype at 10,000 unique-node facts; the production harness including serialization
|
|
34
38
|
peaked near 1.6 GiB. They do not reproduce the private consumer's overall timeout.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
remain
|
|
53
|
-
|
|
39
|
+
T05a adds [early identity checks and phase timing](ADR-021-identity-preflight-and-validation-timing.md)
|
|
40
|
+
after 0.4.0, merged with local/hosted checks passing and publication pending. Full validation
|
|
41
|
+
remains mandatory. In-phase worker progress, result reuse and incremental validation remain
|
|
42
|
+
open; no Rust engine, graph database or
|
|
43
|
+
validation-result cache is introduced by these increments.
|
|
44
|
+
|
|
45
|
+
[T03 operational cache reuse](ADR-018-operational-semantic-cache.md) shipped in 0.4.0. Built-in
|
|
46
|
+
Codex user artifacts can survive changes to timeout/retry/concurrency/document/byte limits while
|
|
47
|
+
snapshots retain their full configuration identity. Exact legacy reads and explicit no-model
|
|
48
|
+
adoption preserve prior artifacts; custom providers remain conservative.
|
|
49
|
+
[T04 diagnostics](ADR-019-semantic-failure-diagnostics.md) shipped in the same release, adding
|
|
50
|
+
safe failure reports, opaque source mapping and settled progress without changing extraction/cache
|
|
51
|
+
identity. Broader T05 and T06/T07 work remain open.
|
|
52
|
+
|
|
53
|
+
[T08 physical-file kind consistency](ADR-020-canonical-physical-file-producers.md) also shipped in
|
|
54
|
+
0.4.0 after local/hosted Ubuntu/Windows checks, independent archive review and fresh packed and
|
|
55
|
+
public-registry installation. The public core factory and deterministic producers share one policy
|
|
56
|
+
under strict SHACL. Historical snapshots remain queryable, with version guards for current validation.
|
|
57
|
+
On 2026-10-27 the maintainer reported the consumer updated and working; exact adapter and full
|
|
58
|
+
hydration/repeat evidence remain unrecorded. This fix preserves semantic artifacts and
|
|
59
|
+
does not reinterpret model assertions to hide conflicts.
|
|
54
60
|
|
|
55
61
|
| Milestone | Delivered and checked | Remaining limits |
|
|
56
62
|
| --- | --- | --- |
|
package/docs/VALIDATION.md
CHANGED
|
@@ -8,6 +8,145 @@ The milestone entries below record the original cloud checks. Subsequent
|
|
|
8
8
|
establishes live Codex success on Windows and the full deterministic checks on WSL,
|
|
9
9
|
while identifying remaining native Windows issues.
|
|
10
10
|
|
|
11
|
+
## Ten-minute timeout blocker, 2026-10-27
|
|
12
|
+
|
|
13
|
+
The maintainer reports that published 0.4.0 rejects the approved `semantic.timeoutMs: 600000`.
|
|
14
|
+
The consumer's ten-minute retry has **not run**. This is a configuration ceiling defect, separate
|
|
15
|
+
from the corrected physical-file kinds and earlier positive consumer update below.
|
|
16
|
+
|
|
17
|
+
The source patch raises only the accepted maximum from 300000 to 600000 ms. Omitted timeout
|
|
18
|
+
still defaults to 120000; finite positive integer validation, retries, cancellation and the
|
|
19
|
+
separate authentication/discovery limits are unchanged. No provider/prompt/artifact identity
|
|
20
|
+
changes or forced model re-extraction are introduced.
|
|
21
|
+
|
|
22
|
+
Focused checks pass: config acceptance/boundary rejection, Codex propagation across retries,
|
|
23
|
+
per-call override/cancellation, a cancellable module deadline, and real artifact reuse/preview
|
|
24
|
+
after an interrupted run switches to 600000. The provider tests use an injected runner/local
|
|
25
|
+
module and finish immediately; they are not a live ten-minute extraction. Independent review
|
|
26
|
+
found no blocker. Local `pnpm context-graph:publication-check` passed: 408 deterministic tests
|
|
27
|
+
(17 core, 391 toolkit), one optional OML skip, 13 unchanged advisory architecture findings,
|
|
28
|
+
inventory, licenses and fresh packed-consumer checks. The installed CLI accepts 600000 in
|
|
29
|
+
no-model preview and reports the same limit on an immediate missing-provider failure.
|
|
30
|
+
All 79 original source path/hash pairs remain intact. Hosted checks and publication are recorded
|
|
31
|
+
after completion; the consumer's live ten-minute retry remains unrun.
|
|
32
|
+
|
|
33
|
+
## Consumer update after 0.4.0, 2026-10-27
|
|
34
|
+
|
|
35
|
+
The maintainer reports that the consumer updated and appears to be working. This is positive
|
|
36
|
+
consumer feedback after the T08 release. No exact consumer commit, graph scope, adapter test
|
|
37
|
+
report, full-run timing or repeated-hydration report was supplied with that update, so those
|
|
38
|
+
detailed acceptance results remain unrecorded. No private consumer files were inspected or changed.
|
|
39
|
+
|
|
40
|
+
## T05a identity preflight and validation phase timing, 2026-10-27
|
|
41
|
+
|
|
42
|
+
Implemented in development source after 0.4.0; no new publication is claimed.
|
|
43
|
+
[ADR 021](ADR-021-identity-preflight-and-validation-timing.md) records the bounded scope:
|
|
44
|
+
complete identity/kind attribution before compilation/RDF, explicit local diagnostic detail,
|
|
45
|
+
and elapsed phase boundaries. Full SHACL shapes, accepted facts and cache identities are unchanged.
|
|
46
|
+
|
|
47
|
+
- Twelve pure preflight cases pass: both endpoints, cross-source kinds, conceptual IDs,
|
|
48
|
+
duplicates/self-references, all late conflicts, exact copied provenance/authority, absent
|
|
49
|
+
authority preservation and opaque defaults including unknown kinds. A pass explicitly says
|
|
50
|
+
`shaclValidated: false`; it does not infer canonical classification or approved intent.
|
|
51
|
+
- Two hydration composition cases pass with actual committed file/contract/document producers
|
|
52
|
+
and a deterministic semantic provider. A kind conflict skips compilation, invariants and RDF;
|
|
53
|
+
previous head/snapshot and completed artifact bytes remain intact. Correcting the fixture
|
|
54
|
+
reuses the artifact and runs full SHACL. Invalid confidence with consistent kinds still fails
|
|
55
|
+
real SHACL. Indexing is stubbed in these scheduling cases; real SCIP is covered separately.
|
|
56
|
+
- Four CLI subprocess cases pass with real SCIP and public adapters: default human/JSON privacy,
|
|
57
|
+
explicit exact attribution, empty failure stdout, preserved artifacts/snapshots, overlay detail
|
|
58
|
+
propagation and valid full-validation timing. The existing four semantic-failure CLI cases pass.
|
|
59
|
+
- All 26 full SHACL parity/timing cases pass, including original named-dataset positive/negative
|
|
60
|
+
equivalence and the 2,200-fact late failure. Phase events do not change verdicts or serialization;
|
|
61
|
+
completed means the operation returned, not that its graph conformed.
|
|
62
|
+
- Local `pnpm context-graph:publication-check` passed: 403 deterministic tests (17 core,
|
|
63
|
+
386 toolkit), one optional OML skip, 13 unchanged advisory architecture findings, inventory,
|
|
64
|
+
licenses and fresh packed-consumer checks. The installed public API detects kind conflicts,
|
|
65
|
+
preserves exact opt-in citations, reports phase timing and still rejects the same pair under
|
|
66
|
+
full SHACL. All 79 original extraction source path/hash pairs remain intact.
|
|
67
|
+
- Independent runtime/test review found no blocker. No live model or private consumer
|
|
68
|
+
performance result is implied.
|
|
69
|
+
|
|
70
|
+
[PR 30](https://github.com/jchewitt/weftlet/pull/30) merged at
|
|
71
|
+
`c8db1f0b871f5e6f3d1d2e9eda1b045aa45469df`. Exact feature head
|
|
72
|
+
`dc01421aa3953963e411430266b9035f2852cfd8` passed hosted Ubuntu and native Windows checks
|
|
73
|
+
in [push run 40451305862](https://github.com/jchewitt/weftlet/actions/runs/40451305862) and
|
|
74
|
+
[PR run 40451332221](https://github.com/jchewitt/weftlet/actions/runs/40451332221).
|
|
75
|
+
T05a is merged but unpublished; npm 0.4.0 remains the verified public release.
|
|
76
|
+
|
|
77
|
+
A bounded public profile ran the unique-node fixture in three fresh processes: 500 facts,
|
|
78
|
+
the same 500 facts again, then 501 facts. Command: `node scripts/benchmark-shacl.mjs --counts 500
|
|
79
|
+
--topologies unique --modes optimized --deadline-ms 15000` (use 501 for the final case), after
|
|
80
|
+
`pnpm build`. Linux x64, Node 24.19.0, N3 2.7.2 and rdf-validate-shacl 0.6.5; built RDF module
|
|
81
|
+
SHA-256 `8a66e0266d812b742103d42de3572faf4ab9873d0f37424b563962ea7473fae1`.
|
|
82
|
+
|
|
83
|
+
| Facts / nodes | Preflight ms | RDF construction ms | Union ms | SHACL ms | Process peak RSS KiB |
|
|
84
|
+
| --- | ---: | ---: | ---: | ---: | ---: |
|
|
85
|
+
| 500 / 1,000 | 0.84 | 67.90 | 32 | 186 | 330,496 |
|
|
86
|
+
| 500 / 1,000 repeat | 0.74 | 57.15 | 32 | 174 | 334,356 |
|
|
87
|
+
| 501 / 1,002 | 0.74 | 59.88 | 54 | 185 | 333,584 |
|
|
88
|
+
|
|
89
|
+
All three ran full validation and preserved serialization; the repeated input's serialization
|
|
90
|
+
digest matched, and the added-fact digest differed. These single-run smoke measurements establish
|
|
91
|
+
phase visibility, not a speedup or production capacity. RSS includes imports, fixture and
|
|
92
|
+
serialization; no successful-result reuse or dependency-aware incremental validation was used.
|
|
93
|
+
|
|
94
|
+
## 0.4.0 publication and installed-package checks, 2026-10-26
|
|
95
|
+
|
|
96
|
+
`@weftlet/core@0.4.0` and `@weftlet/toolkit@0.4.0` ship T03 operational cache reuse,
|
|
97
|
+
T04 semantic failure diagnostics and T08 canonical physical-file kinds. This is an upstream
|
|
98
|
+
release; private consumer adapter migration and full hydration acceptance remain pending.
|
|
99
|
+
|
|
100
|
+
[Release PR 23](https://github.com/jchewitt/weftlet/pull/23) merged at
|
|
101
|
+
`9c6c2625ce2f5d3a28d2be40610130c745b416d4`. Trusted publishing
|
|
102
|
+
[run 40421791942](https://github.com/jchewitt/weftlet/actions/runs/40421791942)
|
|
103
|
+
completed preparation, publication and release records on attempt 1. Both versions are public
|
|
104
|
+
and tagged `latest`; downloaded registry archives are byte-identical to the independently
|
|
105
|
+
reviewed archives. npm provenance identifies that merge commit and workflow attempt. The
|
|
106
|
+
[core](https://github.com/jchewitt/weftlet/releases/tag/%40weftlet/core%400.4.0) and
|
|
107
|
+
[toolkit](https://github.com/jchewitt/weftlet/releases/tag/%40weftlet/toolkit%400.4.0)
|
|
108
|
+
package tags and GitHub Releases resolve to the same commit.
|
|
109
|
+
|
|
110
|
+
- Exact reviewed version head `8ea26c7f538202b4acb67ceeda6adbf220a85e93` passed
|
|
111
|
+
`pnpm release:prepare`: 384 deterministic tests (17 core, 367 toolkit), one optional OML skip,
|
|
112
|
+
13 advisory architecture findings, inventory, licenses and fresh packed-consumer checks.
|
|
113
|
+
Hosted Ubuntu and native Windows checks passed in
|
|
114
|
+
[run 40421253221](https://github.com/jchewitt/weftlet/actions/runs/40421253221).
|
|
115
|
+
- Independent source/archive review found no release blocker. Core contains 13 files/8,212 bytes;
|
|
116
|
+
toolkit contains 213 files/244,424 bytes. Archive digests match the reviewed manifest; all
|
|
117
|
+
non-manifest files match the reviewed checkout. Public exports, CLI/runtime assets, Apache-2.0
|
|
118
|
+
licenses and attribution are present. Core has no runtime dependencies; toolkit requires
|
|
119
|
+
core `^0.4.0`. No forbidden local-state entries or credential-signature matches were found.
|
|
120
|
+
All 79 original extraction source path/hash pairs are unchanged.
|
|
121
|
+
- A separate offline rehearsal installed those exact archives with lifecycle scripts disabled.
|
|
122
|
+
Its public fixture produced 54 facts, including four contract consumers, 24 SCIP facts and two
|
|
123
|
+
public adapter facts. Strict SHACL, immutable repeat reuse and provider-unavailable saved reads
|
|
124
|
+
passed. This rehearsal is distinct from public-registry acceptance.
|
|
125
|
+
- Fresh public-registry installation passed on Linux/Node 24.19.0 with lifecycle scripts disabled.
|
|
126
|
+
Its lockfile registry URLs and SHA-512 values match the reviewed archives. The committed public
|
|
127
|
+
fixture produced 54 total facts, including two semantic facts, four contract consumers, 24 real SCIP facts,
|
|
128
|
+
two public adapter facts and nine document facts; the impact query returned 53 facts.
|
|
129
|
+
Cold hydration extracted two artifacts; repeat hydration extracted zero and reused both with
|
|
130
|
+
identical snapshot identity, content digest and stored bytes. Removing the provider module
|
|
131
|
+
preserved no-model preview and saved queries, with no additional provider invocations.
|
|
132
|
+
Fixture commit: `41d0c4fa68f7a358d52471dbbd2a6186adb22fa5`; content digest:
|
|
133
|
+
`f5a8fbde346d070074164edf970bfd98246c4e34718b43f5850757501daf50ca`.
|
|
134
|
+
|
|
135
|
+
The installed-package fixture uses a deterministic public provider, actual contract/document
|
|
136
|
+
extractors, real TypeScript SCIP and a public adapter that imports only the core file factory.
|
|
137
|
+
It checks retained citations, digests and authority, strict RDF/SHACL, projection/query results,
|
|
138
|
+
repeat artifact reuse and unchanged snapshot bytes. It makes no live model calls and does not
|
|
139
|
+
establish private adapter correctness, semantic quality or the consumer's full-graph performance.
|
|
140
|
+
The T03/T04 test checkpoints below remain the evidence for operational Codex cache partitioning
|
|
141
|
+
and structured failure handling; ordinary fixture reuse is not a substitute for those tests.
|
|
142
|
+
|
|
143
|
+
Reviewed and public archive integrity:
|
|
144
|
+
|
|
145
|
+
| Package | SHA-512 integrity |
|
|
146
|
+
| --- | --- |
|
|
147
|
+
| `@weftlet/core@0.4.0` | `sha512-hNiLpfFaL/o+uQJlRdW+jN/cdMIY8QxTAgwTA7F1kN8f1KhHWH8qsxc4RgC8mP+4huLsWLk8m0v14xrq5prMdA==` |
|
|
148
|
+
| `@weftlet/toolkit@0.4.0` | `sha512-UrHRBuz3v7Olfqk0iaSyvZ1+9xnCHMAjh0ZGj+HWde4zAR0M2zEHjeOxkyC2B2d63gPAqttlQ5kzpauRdfd0Jg==` |
|
|
149
|
+
|
|
11
150
|
## T08 deterministic physical-file kinds, 2026-10-26
|
|
12
151
|
|
|
13
152
|
Implemented after 0.3.0; this checkpoint does not claim npm publication or private consumer
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
"destinationPath": "package.json",
|
|
109
109
|
"sourceSha256": "a575dbb2fed8c554b95e8e9b3e03a0c21cab1be7249860bbebc18e046b2ff78d",
|
|
110
110
|
"modified": true,
|
|
111
|
-
"destinationSha256": "
|
|
111
|
+
"destinationSha256": "3e56a3b6a6200e15f684bb490360f2aec0d305dc6c475a176971b188ac5b725d"
|
|
112
112
|
},
|
|
113
113
|
{
|
|
114
114
|
"sourcePath": "tools/context-graph/packages/core/LICENSE",
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
"destinationPath": "packages/core/package.json",
|
|
144
144
|
"sourceSha256": "2a29066eb8452f22fafcb06bb035a84dda93c5705dba32aba600a1b7e5aaf19c",
|
|
145
145
|
"modified": true,
|
|
146
|
-
"destinationSha256": "
|
|
146
|
+
"destinationSha256": "cde075a193be99f3d50895d9f764e8fd5848f54a2e5acb0155ce69f454bf8623"
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
149
|
"sourcePath": "tools/context-graph/packages/core/src/core.ts",
|
|
@@ -192,7 +192,7 @@
|
|
|
192
192
|
"destinationPath": "scripts/check-publication.mjs",
|
|
193
193
|
"sourceSha256": "88692c21d34cef2d2e5b20c92ab3ec26cbe6336889dbb7b534c681ded7f466b2",
|
|
194
194
|
"modified": true,
|
|
195
|
-
"destinationSha256": "
|
|
195
|
+
"destinationSha256": "6cc62cdbd4bed65d8eff4749fba7003b3fa59c2e5ddcf8e333950468c40986bf"
|
|
196
196
|
},
|
|
197
197
|
{
|
|
198
198
|
"sourcePath": "tools/context-graph/scripts/generate-third-party-notices.mjs",
|
|
@@ -241,21 +241,21 @@
|
|
|
241
241
|
"destinationPath": "src/interfaces/cli.ts",
|
|
242
242
|
"sourceSha256": "c68f5f35a5325cc03811b0d4ffb6d58c31a9b4e6115fcb2c5e4fda9560a34714",
|
|
243
243
|
"modified": true,
|
|
244
|
-
"destinationSha256": "
|
|
244
|
+
"destinationSha256": "21cdbc817983e788a5aac48ea8b32c55a7dda98868eb48b5df470c8d99eea44a"
|
|
245
245
|
},
|
|
246
246
|
{
|
|
247
247
|
"sourcePath": "tools/context-graph/src/config.test.ts",
|
|
248
248
|
"destinationPath": "src/configuration/config.test.ts",
|
|
249
249
|
"sourceSha256": "70bcda6d6b48ff6fa03223c9420fe3e0e3e32c688e0a14f11034515e0707dee4",
|
|
250
250
|
"modified": true,
|
|
251
|
-
"destinationSha256": "
|
|
251
|
+
"destinationSha256": "f9bedfd754d937023f7d06ff9a0fb8e9e4c9d122178446d2e70ac6914e184156"
|
|
252
252
|
},
|
|
253
253
|
{
|
|
254
254
|
"sourcePath": "tools/context-graph/src/config.ts",
|
|
255
255
|
"destinationPath": "src/configuration/config.ts",
|
|
256
256
|
"sourceSha256": "e9ee8cf2134d274aa6f6a21545959fbec97e958181d9032c073293f28e04d6ca",
|
|
257
257
|
"modified": true,
|
|
258
|
-
"destinationSha256": "
|
|
258
|
+
"destinationSha256": "7c79bcd696102f89d3dcadaf01ab2311f68b37172b54b21a667de7f15bdec69a"
|
|
259
259
|
},
|
|
260
260
|
{
|
|
261
261
|
"sourcePath": "tools/context-graph/src/core.ts",
|
|
@@ -318,14 +318,14 @@
|
|
|
318
318
|
"destinationPath": "src/application/hydrator.ts",
|
|
319
319
|
"sourceSha256": "bb41c5b53b26da10274d8b967b99c78ff12b485df16bfc66445252e35c94fb9d",
|
|
320
320
|
"modified": true,
|
|
321
|
-
"destinationSha256": "
|
|
321
|
+
"destinationSha256": "ef6e21f322915b3bf25589d748f379becea5a0ef188bf875caaca10cc479cd2c"
|
|
322
322
|
},
|
|
323
323
|
{
|
|
324
324
|
"sourcePath": "tools/context-graph/src/index.ts",
|
|
325
325
|
"destinationPath": "src/index.ts",
|
|
326
326
|
"sourceSha256": "a3545649f67fc0bf0496298e3f1dca1e91aa7cb68ec112c34b99a5785fa83f3c",
|
|
327
327
|
"modified": true,
|
|
328
|
-
"destinationSha256": "
|
|
328
|
+
"destinationSha256": "b185467e660715806fc914bef5db068e90199ee32b0226452d4adb4c09991d8b"
|
|
329
329
|
},
|
|
330
330
|
{
|
|
331
331
|
"sourcePath": "tools/context-graph/src/mcp-facade.ts",
|
|
@@ -613,6 +613,7 @@
|
|
|
613
613
|
"docs/ADR-018-operational-semantic-cache.md",
|
|
614
614
|
"docs/ADR-019-semantic-failure-diagnostics.md",
|
|
615
615
|
"docs/ADR-020-canonical-physical-file-producers.md",
|
|
616
|
+
"docs/ADR-021-identity-preflight-and-validation-timing.md",
|
|
616
617
|
"docs/CLOUD-ENVIRONMENT.md",
|
|
617
618
|
"docs/CONSUMER-TRIAL.md",
|
|
618
619
|
"docs/ENVIRONMENT-VALIDATION.md",
|
|
@@ -778,15 +779,19 @@
|
|
|
778
779
|
"src/governance/governance.ts",
|
|
779
780
|
"src/governance/physical-file-kinds.test.ts",
|
|
780
781
|
"src/graph/authority.ts",
|
|
782
|
+
"src/graph/identity-preflight.test.ts",
|
|
783
|
+
"src/graph/identity-preflight.ts",
|
|
781
784
|
"src/graph/ranking.test.ts",
|
|
782
785
|
"src/graph/ranking.ts",
|
|
783
786
|
"src/graph/rdf.ts",
|
|
784
787
|
"src/graph/shacl-shapes.ts",
|
|
788
|
+
"src/graph/validation-progress.ts",
|
|
785
789
|
"src/infrastructure/module-resolution.ts",
|
|
786
790
|
"src/interfaces/cache-adoption.test.ts",
|
|
787
791
|
"src/interfaces/doctor.ts",
|
|
788
792
|
"src/interfaces/hydration-failure.test.ts",
|
|
789
793
|
"src/interfaces/hydration-plan.test.ts",
|
|
794
|
+
"src/interfaces/identity-preflight.test.ts",
|
|
790
795
|
"src/interfaces/init.test.ts",
|
|
791
796
|
"src/interfaces/init.ts",
|
|
792
797
|
"src/mcp.ts",
|
|
@@ -802,6 +807,7 @@
|
|
|
802
807
|
"tests/extractor-compatibility.test.ts",
|
|
803
808
|
"tests/hydration-failure.test.ts",
|
|
804
809
|
"tests/hydration-plan.test.ts",
|
|
810
|
+
"tests/identity-preflight.test.ts",
|
|
805
811
|
"tests/module-boundaries.test.ts",
|
|
806
812
|
"tests/physical-file-kinds.test.ts",
|
|
807
813
|
"tests/rdf-ontology.test.ts",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weftlet/toolkit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Evidence-backed context graphs for AI development agents: product intent, contracts, code, tests and runtime behavior",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"n3": "2.7.2",
|
|
64
64
|
"rdf-validate-shacl": "0.6.5",
|
|
65
65
|
"sparqljs": "3.7.4",
|
|
66
|
-
"@weftlet/core": "^0.
|
|
66
|
+
"@weftlet/core": "^0.5.0"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@changesets/cli": "3.0.3",
|