@davidorex/pi-context 0.29.0 → 0.30.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 +19 -0
- package/README.md +28 -16
- package/dist/block-api.d.ts +12 -3
- package/dist/block-api.d.ts.map +1 -1
- package/dist/block-api.js +16 -5
- package/dist/block-api.js.map +1 -1
- package/dist/context-sdk.d.ts +99 -4
- package/dist/context-sdk.d.ts.map +1 -1
- package/dist/context-sdk.js +183 -13
- package/dist/context-sdk.js.map +1 -1
- package/dist/context.d.ts +43 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +41 -0
- package/dist/context.js.map +1 -1
- package/dist/ops-registry.d.ts +180 -4
- package/dist/ops-registry.d.ts.map +1 -1
- package/dist/ops-registry.js +529 -106
- package/dist/ops-registry.js.map +1 -1
- package/dist/read-element.d.ts +48 -0
- package/dist/read-element.d.ts.map +1 -1
- package/dist/read-element.js +88 -30
- package/dist/read-element.js.map +1 -1
- package/dist/write-schema-migration-tool.d.ts +2 -1
- package/dist/write-schema-migration-tool.d.ts.map +1 -1
- package/dist/write-schema-migration-tool.js +13 -10
- package/dist/write-schema-migration-tool.js.map +1 -1
- package/package.json +1 -1
- package/skills/pi-context/SKILL.md +56 -1
package/dist/context-sdk.d.ts
CHANGED
|
@@ -473,9 +473,100 @@ export declare function appendRelationByRef(cwd: string, rel: {
|
|
|
473
473
|
child: string;
|
|
474
474
|
relation_type: string;
|
|
475
475
|
ordinal?: number;
|
|
476
|
-
}, ctx?: DispatchContext
|
|
476
|
+
}, ctx?: DispatchContext, opts?: {
|
|
477
|
+
dryRun?: boolean;
|
|
478
|
+
}): {
|
|
477
479
|
appended: boolean;
|
|
478
480
|
edge: Edge;
|
|
481
|
+
dryRun?: boolean;
|
|
482
|
+
};
|
|
483
|
+
/**
|
|
484
|
+
* Friendly-selector relation removal — the porcelain twin of
|
|
485
|
+
* {@link appendRelationByRef}. Resolves `parent` / `child` STRING selectors to
|
|
486
|
+
* structured `EdgeEndpoint`s via the SAME `resolveRelationSelector` the append
|
|
487
|
+
* porcelain uses, then delegates to the raw `removeRelation` plumbing, which
|
|
488
|
+
* matches on the `identityKey` dedup identity (so a `removeRelationByRef` of the
|
|
489
|
+
* selectors an `appendRelationByRef` wrote removes exactly that edge — the
|
|
490
|
+
* porcelain layers stay symmetric). Returns `{ removed, edge }` where `edge` is
|
|
491
|
+
* the RESOLVED structured edge that was matched against (so callers can report /
|
|
492
|
+
* dry-run-validate the structured form), and `removed` is false on the
|
|
493
|
+
* idempotent no-match no-op.
|
|
494
|
+
*/
|
|
495
|
+
export declare function removeRelationByRef(cwd: string, rel: {
|
|
496
|
+
parent: string;
|
|
497
|
+
child: string;
|
|
498
|
+
relation_type: string;
|
|
499
|
+
}, ctx?: DispatchContext, opts?: {
|
|
500
|
+
dryRun?: boolean;
|
|
501
|
+
}): {
|
|
502
|
+
removed: boolean;
|
|
503
|
+
edge: Edge;
|
|
504
|
+
dryRun?: boolean;
|
|
505
|
+
};
|
|
506
|
+
/**
|
|
507
|
+
* Friendly-selector ATOMIC relation replace — a single load → filter-out-old →
|
|
508
|
+
* push-new → write cycle (no half-state: the old edge and the new edge never
|
|
509
|
+
* coexist on disk, and the file is rewritten exactly ONCE). Resolves the `old`
|
|
510
|
+
* and `new` selector triples via the SAME `resolveRelationSelector` the append /
|
|
511
|
+
* remove porcelain use. The old edge is matched on the `identityKey` dedup
|
|
512
|
+
* identity (parent, child, relation_type — `ordinal`-insensitive, symmetric with
|
|
513
|
+
* append-dedup / remove); the new edge is pushed verbatim (carrying its optional
|
|
514
|
+
* `ordinal`). If the resolved new edge collides on identity with a surviving edge
|
|
515
|
+
* it is de-duplicated against the post-filter set so the write stays
|
|
516
|
+
* exact-duplicate-free, matching `appendRelations` semantics.
|
|
517
|
+
*
|
|
518
|
+
* Returns `{ replaced, removed, oldEdge, newEdge }`: `removed` reflects whether
|
|
519
|
+
* the old edge was actually present (false → the old edge was absent, so this is
|
|
520
|
+
* effectively an append of `newEdge`); `replaced` is true when the resolved new
|
|
521
|
+
* edge was written (false only when it collided with an already-present surviving
|
|
522
|
+
* edge → a no-op add). `ctx` threads to `writeRelations` for attestation parity.
|
|
523
|
+
*/
|
|
524
|
+
export declare function replaceRelationByRef(cwd: string, rels: {
|
|
525
|
+
old: {
|
|
526
|
+
parent: string;
|
|
527
|
+
child: string;
|
|
528
|
+
relation_type: string;
|
|
529
|
+
};
|
|
530
|
+
new: {
|
|
531
|
+
parent: string;
|
|
532
|
+
child: string;
|
|
533
|
+
relation_type: string;
|
|
534
|
+
ordinal?: number;
|
|
535
|
+
};
|
|
536
|
+
}, ctx?: DispatchContext, opts?: {
|
|
537
|
+
dryRun?: boolean;
|
|
538
|
+
}): {
|
|
539
|
+
replaced: boolean;
|
|
540
|
+
removed: boolean;
|
|
541
|
+
oldEdge: Edge;
|
|
542
|
+
newEdge: Edge;
|
|
543
|
+
dryRun?: boolean;
|
|
544
|
+
};
|
|
545
|
+
/**
|
|
546
|
+
* Friendly-selector BULK relation append over the raw {@link appendRelations}
|
|
547
|
+
* (whole-file additive write with per-(parent, child, relation_type) dedup,
|
|
548
|
+
* skipping edges already on disk OR earlier in the same batch). Resolves each
|
|
549
|
+
* `edges[]` selector triple via the SAME `resolveRelationSelector` the
|
|
550
|
+
* single-edge porcelain uses, then hands the resolved `Edge[]` to
|
|
551
|
+
* `appendRelations`. Returns `{ appended, skipped, edges }` — `edges` being the
|
|
552
|
+
* resolved structured edges handed to the raw layer (so callers can report /
|
|
553
|
+
* dry-run-validate the structured form). Same deferred-integrity semantics as
|
|
554
|
+
* `appendRelations` (AJV-shape + duplicate-no-op only; relation_type
|
|
555
|
+
* registration / endpoint resolution / cycle checks deferred to
|
|
556
|
+
* `validateContext`).
|
|
557
|
+
*/
|
|
558
|
+
export declare function appendRelationsByRef(cwd: string, edges: {
|
|
559
|
+
parent: string;
|
|
560
|
+
child: string;
|
|
561
|
+
relation_type: string;
|
|
562
|
+
ordinal?: number;
|
|
563
|
+
}[], ctx?: DispatchContext, opts?: {
|
|
564
|
+
dryRun?: boolean;
|
|
565
|
+
}): {
|
|
566
|
+
appended: number;
|
|
567
|
+
skipped: number;
|
|
568
|
+
edges: Edge[];
|
|
569
|
+
dryRun?: boolean;
|
|
479
570
|
};
|
|
480
571
|
/**
|
|
481
572
|
* Classification of an endpoint by {@link resolveRef}:
|
|
@@ -596,8 +687,12 @@ export interface CompleteTaskResult {
|
|
|
596
687
|
}
|
|
597
688
|
/**
|
|
598
689
|
* Gate task completion on verification. Reads the verification block to confirm
|
|
599
|
-
* a passing verification entry exists
|
|
600
|
-
*
|
|
690
|
+
* a passing verification entry exists, asserts a `verification_verifies_item`
|
|
691
|
+
* closure-table edge links that verification (parent) to this task (child), then
|
|
692
|
+
* atomically updates the task status to "completed". The edge IS the linkage —
|
|
693
|
+
* no `verification` field is embedded on the task (the verification → task
|
|
694
|
+
* `verification.target`/`target_type` fields were removed from the verification
|
|
695
|
+
* schema in favor of the edge; this gate reads the edge, not the removed fields).
|
|
601
696
|
*/
|
|
602
|
-
export declare function completeTask(cwd: string, taskId: string, verificationId: string): CompleteTaskResult;
|
|
697
|
+
export declare function completeTask(cwd: string, taskId: string, verificationId: string, ctx?: DispatchContext): CompleteTaskResult;
|
|
603
698
|
//# sourceMappingURL=context-sdk.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-sdk.d.ts","sourceRoot":"","sources":["../src/context-sdk.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"context-sdk.d.ts","sourceRoot":"","sources":["../src/context-sdk.ts"],"names":[],"mappings":"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"}
|
package/dist/context-sdk.js
CHANGED
|
@@ -6,13 +6,16 @@
|
|
|
6
6
|
import { execSync } from "node:child_process";
|
|
7
7
|
import fs from "node:fs";
|
|
8
8
|
import path from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
9
10
|
import { readBlock, readBlockForDir, updateItemInBlock } from "./block-api.js";
|
|
10
|
-
import { appendRelation, endpointKey, findUnmaterializedAssets, isSkeletonConfig, loadConfig, loadRelations, validateRelations, } from "./context.js";
|
|
11
|
+
import { appendRelation, appendRelations, endpointIdentity, endpointKey, findUnmaterializedAssets, isSkeletonConfig, loadConfig, loadRelations, removeRelation, validateRelations, writeRelations, } from "./context.js";
|
|
11
12
|
import { resolveContextDir, SCHEMAS_DIR, schemaPath, schemasDir, tryResolveContextDir } from "./context-dir.js";
|
|
12
13
|
import { loadRegistry, resolveAlias, resolveSubstrateDir } from "./context-registry.js";
|
|
13
14
|
import { cleanGitEnv } from "./git-env.js";
|
|
14
15
|
import { getLensValidators } from "./lens-validator.js";
|
|
16
|
+
import { findReferencesInRepo } from "./lens-view.js";
|
|
15
17
|
import { addressInto, discoverArrayKey, pageArray } from "./read-element.js";
|
|
18
|
+
import { validateFromFile } from "./schema-validator.js";
|
|
16
19
|
import { findNestedIdBearingArrays } from "./schema-write.js";
|
|
17
20
|
import { resolveStatusVocabulary } from "./status-vocab.js";
|
|
18
21
|
import { topoSort } from "./topo.js";
|
|
@@ -1111,6 +1114,25 @@ export function resolveRelationSelector(cwd, selector) {
|
|
|
1111
1114
|
const oid = loc && typeof loc.item.oid === "string" ? loc.item.oid : selector;
|
|
1112
1115
|
return { kind: "item", oid, refname: selector };
|
|
1113
1116
|
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Resolve the bundled relations schema file (top-level `Edge[]` array schema)
|
|
1119
|
+
* — the SAME schema `loadRelations` / `writeRelations` validate against (see
|
|
1120
|
+
* `context.ts` `bundledSchemaPath("relations")`). Resolved relative to this
|
|
1121
|
+
* module so it works from both `src/` (tsx --test) and `dist/` (after tsc) —
|
|
1122
|
+
* the `schemas/` dir lives one directory up in either case. Used by the
|
|
1123
|
+
* `dryRun` preview branch of the relation porcelain to apply the write path's
|
|
1124
|
+
* validation WITHOUT writing (TASK-010: the shared library preview the
|
|
1125
|
+
* orchestrator scripts and the `--dryRun` ops both call).
|
|
1126
|
+
*/
|
|
1127
|
+
function relationsSchemaPath() {
|
|
1128
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
1129
|
+
return path.resolve(here, "..", "schemas", "relations.schema.json");
|
|
1130
|
+
}
|
|
1131
|
+
/** Dedup identity key for an edge — the SAME (parent, child, relation_type)
|
|
1132
|
+
* identity the raw append/remove plumbing matches on (ordinal-insensitive). */
|
|
1133
|
+
function edgeIdentityKey(edge) {
|
|
1134
|
+
return `${endpointIdentity(edge.parent)} ${endpointIdentity(edge.child)} ${edge.relation_type}`;
|
|
1135
|
+
}
|
|
1114
1136
|
/**
|
|
1115
1137
|
* Friendly-selector relation append (Cycle 5 porcelain). Resolves `parent` /
|
|
1116
1138
|
* `child` STRING selectors to structured `EdgeEndpoint`s via
|
|
@@ -1123,16 +1145,157 @@ export function resolveRelationSelector(cwd, selector) {
|
|
|
1123
1145
|
* actually written (so callers can report / dry-run-validate the structured
|
|
1124
1146
|
* form).
|
|
1125
1147
|
*/
|
|
1126
|
-
export function appendRelationByRef(cwd, rel, ctx) {
|
|
1148
|
+
export function appendRelationByRef(cwd, rel, ctx, opts) {
|
|
1127
1149
|
const edge = {
|
|
1128
1150
|
parent: resolveRelationSelector(cwd, rel.parent),
|
|
1129
1151
|
child: resolveRelationSelector(cwd, rel.child),
|
|
1130
1152
|
relation_type: rel.relation_type,
|
|
1131
1153
|
...(rel.ordinal !== undefined ? { ordinal: rel.ordinal } : {}),
|
|
1132
1154
|
};
|
|
1155
|
+
if (opts?.dryRun) {
|
|
1156
|
+
// Preview parity: run the SAME validation the write path applies (the
|
|
1157
|
+
// prospective Edge[] against the whole relations schema — what
|
|
1158
|
+
// loadRelations/writeRelations validate) but write nothing. The
|
|
1159
|
+
// would-decision uses the SAME dedup identity the raw append matches on.
|
|
1160
|
+
const existing = loadRelations(cwd);
|
|
1161
|
+
const prospective = [...existing, edge];
|
|
1162
|
+
validateFromFile(relationsSchemaPath(), prospective, "relations[edge]");
|
|
1163
|
+
const newId = edgeIdentityKey(edge);
|
|
1164
|
+
const duplicate = existing.some((e) => edgeIdentityKey(e) === newId);
|
|
1165
|
+
return { appended: !duplicate, edge, dryRun: true };
|
|
1166
|
+
}
|
|
1133
1167
|
const { appended } = appendRelation(cwd, edge, ctx);
|
|
1134
1168
|
return { appended, edge };
|
|
1135
1169
|
}
|
|
1170
|
+
/**
|
|
1171
|
+
* Friendly-selector relation removal — the porcelain twin of
|
|
1172
|
+
* {@link appendRelationByRef}. Resolves `parent` / `child` STRING selectors to
|
|
1173
|
+
* structured `EdgeEndpoint`s via the SAME `resolveRelationSelector` the append
|
|
1174
|
+
* porcelain uses, then delegates to the raw `removeRelation` plumbing, which
|
|
1175
|
+
* matches on the `identityKey` dedup identity (so a `removeRelationByRef` of the
|
|
1176
|
+
* selectors an `appendRelationByRef` wrote removes exactly that edge — the
|
|
1177
|
+
* porcelain layers stay symmetric). Returns `{ removed, edge }` where `edge` is
|
|
1178
|
+
* the RESOLVED structured edge that was matched against (so callers can report /
|
|
1179
|
+
* dry-run-validate the structured form), and `removed` is false on the
|
|
1180
|
+
* idempotent no-match no-op.
|
|
1181
|
+
*/
|
|
1182
|
+
export function removeRelationByRef(cwd, rel, ctx, opts) {
|
|
1183
|
+
const edge = {
|
|
1184
|
+
parent: resolveRelationSelector(cwd, rel.parent),
|
|
1185
|
+
child: resolveRelationSelector(cwd, rel.child),
|
|
1186
|
+
relation_type: rel.relation_type,
|
|
1187
|
+
};
|
|
1188
|
+
if (opts?.dryRun) {
|
|
1189
|
+
// Preview parity: compute the prospective post-removal Edge[] and validate
|
|
1190
|
+
// it against the whole relations schema (write-path validation), write
|
|
1191
|
+
// nothing. `removed` reflects whether a matching edge is present on the
|
|
1192
|
+
// SAME dedup identity the raw remove matches on.
|
|
1193
|
+
const existing = loadRelations(cwd);
|
|
1194
|
+
const targetId = edgeIdentityKey(edge);
|
|
1195
|
+
const matches = existing.some((e) => edgeIdentityKey(e) === targetId);
|
|
1196
|
+
const prospective = existing.filter((e) => edgeIdentityKey(e) !== targetId);
|
|
1197
|
+
validateFromFile(relationsSchemaPath(), prospective, "relations[edge]");
|
|
1198
|
+
return { removed: matches, edge, dryRun: true };
|
|
1199
|
+
}
|
|
1200
|
+
const { removed } = removeRelation(cwd, edge, ctx);
|
|
1201
|
+
return { removed, edge };
|
|
1202
|
+
}
|
|
1203
|
+
/**
|
|
1204
|
+
* Friendly-selector ATOMIC relation replace — a single load → filter-out-old →
|
|
1205
|
+
* push-new → write cycle (no half-state: the old edge and the new edge never
|
|
1206
|
+
* coexist on disk, and the file is rewritten exactly ONCE). Resolves the `old`
|
|
1207
|
+
* and `new` selector triples via the SAME `resolveRelationSelector` the append /
|
|
1208
|
+
* remove porcelain use. The old edge is matched on the `identityKey` dedup
|
|
1209
|
+
* identity (parent, child, relation_type — `ordinal`-insensitive, symmetric with
|
|
1210
|
+
* append-dedup / remove); the new edge is pushed verbatim (carrying its optional
|
|
1211
|
+
* `ordinal`). If the resolved new edge collides on identity with a surviving edge
|
|
1212
|
+
* it is de-duplicated against the post-filter set so the write stays
|
|
1213
|
+
* exact-duplicate-free, matching `appendRelations` semantics.
|
|
1214
|
+
*
|
|
1215
|
+
* Returns `{ replaced, removed, oldEdge, newEdge }`: `removed` reflects whether
|
|
1216
|
+
* the old edge was actually present (false → the old edge was absent, so this is
|
|
1217
|
+
* effectively an append of `newEdge`); `replaced` is true when the resolved new
|
|
1218
|
+
* edge was written (false only when it collided with an already-present surviving
|
|
1219
|
+
* edge → a no-op add). `ctx` threads to `writeRelations` for attestation parity.
|
|
1220
|
+
*/
|
|
1221
|
+
export function replaceRelationByRef(cwd, rels, ctx, opts) {
|
|
1222
|
+
const oldEdge = {
|
|
1223
|
+
parent: resolveRelationSelector(cwd, rels.old.parent),
|
|
1224
|
+
child: resolveRelationSelector(cwd, rels.old.child),
|
|
1225
|
+
relation_type: rels.old.relation_type,
|
|
1226
|
+
};
|
|
1227
|
+
const newEdge = {
|
|
1228
|
+
parent: resolveRelationSelector(cwd, rels.new.parent),
|
|
1229
|
+
child: resolveRelationSelector(cwd, rels.new.child),
|
|
1230
|
+
relation_type: rels.new.relation_type,
|
|
1231
|
+
...(rels.new.ordinal !== undefined ? { ordinal: rels.new.ordinal } : {}),
|
|
1232
|
+
};
|
|
1233
|
+
const existing = loadRelations(cwd);
|
|
1234
|
+
const oldKey = edgeIdentityKey(oldEdge);
|
|
1235
|
+
const newKey = edgeIdentityKey(newEdge);
|
|
1236
|
+
const filtered = existing.filter((e) => edgeIdentityKey(e) !== oldKey);
|
|
1237
|
+
const removed = filtered.length !== existing.length;
|
|
1238
|
+
const collides = filtered.some((e) => edgeIdentityKey(e) === newKey);
|
|
1239
|
+
const next = collides ? filtered : [...filtered, newEdge];
|
|
1240
|
+
if (opts?.dryRun) {
|
|
1241
|
+
// Preview parity: validate the prospective post-replace Edge[] against the
|
|
1242
|
+
// whole relations schema (write-path validation), write nothing. The
|
|
1243
|
+
// would-decisions (`removed`/`replaced`) are the SAME values the write
|
|
1244
|
+
// path computes.
|
|
1245
|
+
validateFromFile(relationsSchemaPath(), next, "relations[edge]");
|
|
1246
|
+
return { replaced: !collides, removed, oldEdge, newEdge, dryRun: true };
|
|
1247
|
+
}
|
|
1248
|
+
writeRelations(cwd, next, ctx);
|
|
1249
|
+
return { replaced: !collides, removed, oldEdge, newEdge };
|
|
1250
|
+
}
|
|
1251
|
+
/**
|
|
1252
|
+
* Friendly-selector BULK relation append over the raw {@link appendRelations}
|
|
1253
|
+
* (whole-file additive write with per-(parent, child, relation_type) dedup,
|
|
1254
|
+
* skipping edges already on disk OR earlier in the same batch). Resolves each
|
|
1255
|
+
* `edges[]` selector triple via the SAME `resolveRelationSelector` the
|
|
1256
|
+
* single-edge porcelain uses, then hands the resolved `Edge[]` to
|
|
1257
|
+
* `appendRelations`. Returns `{ appended, skipped, edges }` — `edges` being the
|
|
1258
|
+
* resolved structured edges handed to the raw layer (so callers can report /
|
|
1259
|
+
* dry-run-validate the structured form). Same deferred-integrity semantics as
|
|
1260
|
+
* `appendRelations` (AJV-shape + duplicate-no-op only; relation_type
|
|
1261
|
+
* registration / endpoint resolution / cycle checks deferred to
|
|
1262
|
+
* `validateContext`).
|
|
1263
|
+
*/
|
|
1264
|
+
export function appendRelationsByRef(cwd, edges, ctx, opts) {
|
|
1265
|
+
const resolved = edges.map((rel) => ({
|
|
1266
|
+
parent: resolveRelationSelector(cwd, rel.parent),
|
|
1267
|
+
child: resolveRelationSelector(cwd, rel.child),
|
|
1268
|
+
relation_type: rel.relation_type,
|
|
1269
|
+
...(rel.ordinal !== undefined ? { ordinal: rel.ordinal } : {}),
|
|
1270
|
+
}));
|
|
1271
|
+
if (opts?.dryRun) {
|
|
1272
|
+
// Preview parity: replay the bulk dedup the raw appendRelations applies —
|
|
1273
|
+
// skip an edge whose identity is already on disk OR earlier in THIS batch
|
|
1274
|
+
// (a `seen` Set seeded from the existing on-disk identities) — accumulate
|
|
1275
|
+
// the non-dup prospective Edge[], validate it against the whole relations
|
|
1276
|
+
// schema (write-path validation), write nothing.
|
|
1277
|
+
const existing = loadRelations(cwd);
|
|
1278
|
+
const seen = new Set(existing.map((e) => edgeIdentityKey(e)));
|
|
1279
|
+
let appended = 0;
|
|
1280
|
+
let skipped = 0;
|
|
1281
|
+
const prospective = [...existing];
|
|
1282
|
+
for (const edge of resolved) {
|
|
1283
|
+
const key = edgeIdentityKey(edge);
|
|
1284
|
+
if (seen.has(key)) {
|
|
1285
|
+
skipped++;
|
|
1286
|
+
}
|
|
1287
|
+
else {
|
|
1288
|
+
seen.add(key);
|
|
1289
|
+
prospective.push(edge);
|
|
1290
|
+
appended++;
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
validateFromFile(relationsSchemaPath(), prospective, "relations[edge]");
|
|
1294
|
+
return { appended, skipped, edges: resolved, dryRun: true };
|
|
1295
|
+
}
|
|
1296
|
+
const { appended, skipped } = appendRelations(cwd, resolved, ctx);
|
|
1297
|
+
return { appended, skipped, edges: resolved };
|
|
1298
|
+
}
|
|
1136
1299
|
/**
|
|
1137
1300
|
* Build (or fetch from the per-pass cache) the {@link SubstrateIndex} for a
|
|
1138
1301
|
* REGISTERED foreign substrate. Resolves the substrate dir from the registry,
|
|
@@ -1710,10 +1873,14 @@ export function validateContext(cwd) {
|
|
|
1710
1873
|
}
|
|
1711
1874
|
/**
|
|
1712
1875
|
* Gate task completion on verification. Reads the verification block to confirm
|
|
1713
|
-
* a passing verification entry exists
|
|
1714
|
-
*
|
|
1876
|
+
* a passing verification entry exists, asserts a `verification_verifies_item`
|
|
1877
|
+
* closure-table edge links that verification (parent) to this task (child), then
|
|
1878
|
+
* atomically updates the task status to "completed". The edge IS the linkage —
|
|
1879
|
+
* no `verification` field is embedded on the task (the verification → task
|
|
1880
|
+
* `verification.target`/`target_type` fields were removed from the verification
|
|
1881
|
+
* schema in favor of the edge; this gate reads the edge, not the removed fields).
|
|
1715
1882
|
*/
|
|
1716
|
-
export function completeTask(cwd, taskId, verificationId) {
|
|
1883
|
+
export function completeTask(cwd, taskId, verificationId, ctx) {
|
|
1717
1884
|
// 1. Read and validate verification entry
|
|
1718
1885
|
let verData;
|
|
1719
1886
|
try {
|
|
@@ -1727,9 +1894,6 @@ export function completeTask(cwd, taskId, verificationId) {
|
|
|
1727
1894
|
if (!verification) {
|
|
1728
1895
|
throw new Error(`Verification '${verificationId}' not found in verification block`);
|
|
1729
1896
|
}
|
|
1730
|
-
if (verification.target !== taskId || verification.target_type !== "task") {
|
|
1731
|
-
throw new Error(`Verification '${verificationId}' targets '${verification.target}' (${verification.target_type}), not task '${taskId}'`);
|
|
1732
|
-
}
|
|
1733
1897
|
if (verification.status !== "passed") {
|
|
1734
1898
|
throw new Error(`Verification '${verificationId}' status is '${verification.status}', not 'passed' — cannot complete task`);
|
|
1735
1899
|
}
|
|
@@ -1753,11 +1917,17 @@ export function completeTask(cwd, taskId, verificationId) {
|
|
|
1753
1917
|
if (currentStatus === "cancelled") {
|
|
1754
1918
|
throw new Error(`Task '${taskId}' is already cancelled`);
|
|
1755
1919
|
}
|
|
1756
|
-
// 3.
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1920
|
+
// 3. Assert the verification_verifies_item edge: verification (parent) →
|
|
1921
|
+
// task (child). The closure-table edge — not a verification field — is the
|
|
1922
|
+
// canonical linkage. Inbound edges point AT the task; compare the parent
|
|
1923
|
+
// endpoint via endpointKey (the codebase's endpoint-comparison idiom).
|
|
1924
|
+
const verifiesEdge = findReferencesInRepo(cwd, taskId, "inbound").find((e) => e.relation_type === "verification_verifies_item" && endpointKey(e.parent) === verificationId);
|
|
1925
|
+
if (!verifiesEdge) {
|
|
1926
|
+
throw new Error(`verification '${verificationId}' does not verify task '${taskId}' — no verification_verifies_item edge; file the link (append-relation parent=${verificationId} child=${taskId} relation_type=verification_verifies_item) before completing`);
|
|
1927
|
+
}
|
|
1928
|
+
// 4. Update task status. The edge is the linkage — no `verification` field is
|
|
1929
|
+
// embedded (a populated additionalProperties:false tasks schema would reject it).
|
|
1930
|
+
updateItemInBlock(cwd, "tasks", "tasks", (t) => t.id === taskId, { status: "completed" }, ctx);
|
|
1761
1931
|
return {
|
|
1762
1932
|
taskId,
|
|
1763
1933
|
verificationId,
|