Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
beeae2c
docs(rfcs): vendor OT-RFC-43/44/45 alongside the implementation
Jun 3, 2026
042b312
feat(publisher,node-ui): Design B — one file = one Knowledge Asset, a…
Jun 3, 2026
22f0def
fix(publisher,cli): complete Design B multi-entity publish — close th…
Jun 3, 2026
8c11163
fix: address PR 968 multi-root publish feedback
Jun 3, 2026
7fe5566
feat(cli): GitHub-shaped /api/knowledge-assets HTTP surface (OT-RFC-4…
Jun 3, 2026
d9a4023
fix: restore direct publish multi-root guard
Jun 3, 2026
787a5ce
feat: implement wm/pull-from — seed a WM draft from SWM/VM (OT-RFC-43…
Jun 3, 2026
f832772
feat(cli/sdk): add GitHub-shaped knowledge-assets methods to ApiClien…
Jun 3, 2026
02af3ac
fix(publisher): correct Design B kaCount handling in StorageACK (full…
Jun 3, 2026
3a30ad9
fix: align knowledge asset SDK payloads
Jun 3, 2026
cf27fdf
docs(evm): OT-RFC-45 owner-only update-authority NatSpec fix
Jun 4, 2026
5a8ebf6
feat(evm): OT-RFC-43 Option-1 deterministic author-namespaced KA iden…
Jun 4, 2026
8fb931e
feat: durable per-author KA-number allocator for OT-RFC-43 Option-1 (…
Jun 4, 2026
a122a44
fix: full-precision uint64 id encoding on the publish gossip path (OT…
Jun 4, 2026
e8aa60f
fix: preserve file KA compatibility roots
Jun 4, 2026
9fb7f86
feat(sdk): wire GitHub-shaped knowledge-assets methods into node-ui, …
Jun 4, 2026
a0354a5
refactor: rename autoPartition -> skolemizeByEntity (OT-RFC-44 §4 / O…
Jun 3, 2026
2a68912
fix: keep publisher autoPartition alias
Jun 3, 2026
f13f243
fix(sdk): expose finalize/publish options on KA clients (PR #978 review)
Jun 4, 2026
237fa45
WIP(predicate-rename): dual-write foundation + migration helpers (OT-…
Jun 3, 2026
0360866
feat(predicate-rename): complete the dual-WRITE phase across all emit…
Jun 3, 2026
e283e35
fix: dual-read entity metadata cleanup
Jun 4, 2026
97d9d77
fix: reuse shared entity predicates in metadata
Jun 4, 2026
34b2be9
fix: harden knowledge asset client option payloads
Jun 4, 2026
e14be21
fix: dual-read entity predicates during restatement
Jun 4, 2026
e5783fe
fix: validate KA finalize attestation payloads
Jun 4, 2026
a9c0091
fix: validate MCP KA client inputs
Jun 4, 2026
dd0491c
feat: Option-1 reservedKaId supply chain + 256-bit id wire (close the…
Jun 4, 2026
0057f93
Merge remote-tracking branch 'origin/feat/v10-rename-entity-predicate…
Jun 4, 2026
dd23c8f
Merge branch 'feat/v10-option1-supply-chain' into integration/v10-devnet
Jun 4, 2026
14d4fed
fix: quiet deprecated KA counter scans
Jun 4, 2026
ece6474
chore(devnet): pin minimumRequiredSignatures = 3 (NEVER lower) — real…
Jun 4, 2026
b84bd25
feat: OT-RFC-43 A2 (per-layer pointers + create-vs-update routing + p…
Jun 4, 2026
5d8cd77
test(chain): re-pin DKGKnowledgeAssets ABI digest for OT-RFC-43 Optio…
Jun 4, 2026
6ccc8fd
test: adjust proto + e2e harness to OT-RFC-43 Option-1 256-bit/reserv…
Jun 4, 2026
a332f26
feat: V10 UPDATE StorageACK peer collection — updates meet the real 3…
Jun 4, 2026
3861487
Merge pull request #982 from OriginTrail/fix/pr980-ci-test-harness
branarakic Jun 4, 2026
2e498a5
fix(ci): green PR #980's 4 remaining checks (allocator wiring + minSi…
branarakic Jun 4, 2026
e4888ce
feat(evm): route submitProof verification through the per-challenge K…
branarakic Jun 4, 2026
c649a06
feat(#968 salvage): Design-B multi-entity resolveKA read + aggregate …
branarakic Jun 4, 2026
da42659
feat(allocator): land OT-RFC-43 Option-1 KA-number floor-correctness …
branarakic Jun 4, 2026
d60c59a
fix(#972): pull-from reads the seal from the correct subject + valida…
branarakic Jun 4, 2026
7a67bc4
fix: WM→SWM→VM publish flow — node-ui lifecycle + on-chain auto-regis…
branarakic Jun 4, 2026
b28790b
feat(#971 salvage): validate + normalize vm/publish options on the /a…
branarakic Jun 4, 2026
106b3a2
feat(#972): vm/publish HTTP status reflects the actual publish outcom…
branarakic Jun 4, 2026
4a66224
land: #978 SDK client validation + #970 docs (verified review-fix rec…
branarakic Jun 4, 2026
a56ee6e
feat(agent-tools): migrate assertion lifecycle tools to the v10 KA ro…
branarakic Jun 4, 2026
360cb4f
feat(ka-routes): Stage 1.1 — bring existing KA routes to legacy parit…
Jun 5, 2026
d905ac2
refactor(ka-routes): Stage 1.2 — extract shared assertion helpers int…
Jun 5, 2026
ab52138
feat(ka-routes): Stage 1.3 — port import-artifact + semantic-enrichme…
Jun 5, 2026
6640989
feat(ka-routes): Stage 1.4 — port import-file (multipart) + extractio…
Jun 5, 2026
65d3ecf
feat(ka-routes): Stage 1.5 — port promote-async queue as swm/share-as…
Jun 5, 2026
b94539d
test(ka-routes): Stage 1 tests — 61 KA route cases (parity + all 6 ne…
Jun 6, 2026
2626691
feat(ka-routes): Stage 2 — repoint all ~80 consumers onto /api/knowle…
Jun 6, 2026
7de31f1
test(ka-routes): Stage 3 — migrate route-level tests to KA + repoint …
Jun 6, 2026
3b5c47f
feat(ka-routes)!: Stage 4 — delete legacy assertion.ts; preserve /api…
Jun 6, 2026
1381386
fix(storage): blank-node-safe SPARQL delete + backend conformance mat…
branarakic Jun 5, 2026
f776921
Merge branch 'feat/unify-knowledge-assets-routes' into integration-in…
Jun 6, 2026
b628a0b
fix(node-ui): repoint browser ui/api.ts off retired /api/assertion ro…
Jun 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions devnet/_bootstrap/bootstrap.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -324,19 +324,20 @@ async function main() {
},
];
const createRes = await fetch(
`http://127.0.0.1:${core.apiPort}/api/assertion/create`,
`http://127.0.0.1:${core.apiPort}/api/knowledge-assets`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${agent.authToken}`,
},
// KA create auto-finalizes when `quads` are supplied; `alsoShareSwm`
// is the WM→SWM transition that the legacy `promote: true` flag did.
body: JSON.stringify({
name,
contextGraphId: CONTEXT_GRAPH,
quads,
finalize: true,
promote: true,
alsoShareSwm: true,
}),
},
);
Expand Down
25 changes: 14 additions & 11 deletions devnet/rich-scenario/automated.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,15 +310,16 @@ async function assertionCreate(
ts: number,
): Promise<string> {
const { quads, rootSubject } = buildQuads(cgId, name, ts);
const res = await apiFetch(node, '/api/assertion/create', {
// KA create auto-finalizes when `quads` are supplied; `alsoShareSwm` is the
// WM→SWM transition that the legacy `promote: true` flag performed.
const res = await apiFetch(node, '/api/knowledge-assets', {
method: 'POST',
bearer: agentToken,
body: JSON.stringify({
name,
contextGraphId: cgId,
quads,
finalize: true,
...(promote ? { promote: true } : {}),
...(promote ? { alsoShareSwm: true } : {}),
}),
});
if (!res.ok) {
Expand Down Expand Up @@ -701,14 +702,14 @@ describe('Devnet rich scenario (~10 min)', () => {
for (let i = 0; i < WM_COUNT; i++) {
const name = `bulk-wm-${run.stamp}-${i}`;
const { quads } = buildBulkQuads(name, batchTs + i);
const res = await apiFetch(core1, '/api/assertion/create', {
// KA create auto-finalizes (seals to WM) when `quads` are supplied.
const res = await apiFetch(core1, '/api/knowledge-assets', {
method: 'POST',
bearer: token,
body: JSON.stringify({
name,
contextGraphId: BULK_CG,
quads,
finalize: true,
}),
});
if (!res.ok) {
Expand All @@ -721,15 +722,16 @@ describe('Devnet rich scenario (~10 min)', () => {
for (let i = 0; i < SWM_COUNT; i++) {
const name = `bulk-swm-${run.stamp}-${i}`;
const { quads } = buildBulkQuads(name, batchTs + 100 + i);
const res = await apiFetch(core1, '/api/assertion/create', {
// KA create auto-finalizes when `quads` are supplied; `alsoShareSwm`
// performs the WM→SWM transition (legacy `promote: true`).
const res = await apiFetch(core1, '/api/knowledge-assets', {
method: 'POST',
bearer: token,
body: JSON.stringify({
name,
contextGraphId: BULK_CG,
quads,
finalize: true,
promote: true,
alsoShareSwm: true,
}),
});
if (!res.ok) {
Expand All @@ -742,15 +744,16 @@ describe('Devnet rich scenario (~10 min)', () => {
for (let i = 0; i < VM_COUNT; i++) {
const name = `bulk-vm-${run.stamp}-${i}`;
const { quads, rootSubject } = buildBulkQuads(name, batchTs + 200 + i);
const createRes = await apiFetch(core1, '/api/assertion/create', {
// KA create auto-finalizes + `alsoShareSwm` promotes to SWM; the
// separate /api/shared-memory/publish below lifts SWM→VM.
const createRes = await apiFetch(core1, '/api/knowledge-assets', {
method: 'POST',
bearer: token,
body: JSON.stringify({
name,
contextGraphId: BULK_CG,
quads,
finalize: true,
promote: true,
alsoShareSwm: true,
}),
});
if (!createRes.ok) {
Expand Down
35 changes: 20 additions & 15 deletions devnet/v10-core-flows/automated.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,14 @@ async function fullPublish(api: string, token: string, name: string): Promise<{
{ subject, predicate: 'http://schema.org/name', object: `"${name}"`, graph: '' },
{ subject, predicate: 'http://schema.org/value', object: '"epoch-pool fuel"', graph: '' },
];
let r = await postJson(api, '/api/assertion/create', { contextGraphId: cgId, name }, token);
expect(r.status, `create failed: ${JSON.stringify(r.body)}`).toBe(200);
r = await postJson(api, `/api/assertion/${name}/write`, { contextGraphId: cgId, quads }, token);
let r = await postJson(api, '/api/knowledge-assets', { contextGraphId: cgId, name }, token);
// KA create returns 201 (resource created) vs the legacy route's 200.
expect(r.status, `create failed: ${JSON.stringify(r.body)}`).toBe(201);
r = await postJson(api, `/api/knowledge-assets/${name}/wm/write`, { contextGraphId: cgId, quads }, token);
expect(r.status, `write failed: ${JSON.stringify(r.body)}`).toBe(200);
r = await postJson(api, `/api/assertion/${name}/finalize`, { contextGraphId: cgId }, token);
r = await postJson(api, `/api/knowledge-assets/${name}/wm/finalize`, { contextGraphId: cgId }, token);
expect(r.status, `finalize failed: ${JSON.stringify(r.body)}`).toBe(200);
r = await postJson(api, `/api/assertion/${name}/promote`, { contextGraphId: cgId }, token);
r = await postJson(api, `/api/knowledge-assets/${name}/swm/share`, { contextGraphId: cgId }, token);
expect(r.status, `promote failed: ${JSON.stringify(r.body)}`).toBe(200);
r = await postJson(api, '/api/shared-memory/publish', { contextGraphId: cgId, assertionName: name }, token);
expect(r.status, `publish failed: ${JSON.stringify(r.body)}`).toBe(200);
Expand Down Expand Up @@ -357,26 +358,29 @@ describe('1. chained sign-at-creation assertion lifecycle', () => {
);
await sleep(500); // SSE warm-up

let r = await postJson(NODE1_API, '/api/assertion/create', { contextGraphId: CONTEXT_GRAPH, name: assertionName }, state.node1Token);
expect(r.status, `create: ${JSON.stringify(r.body)}`).toBe(200);
let r = await postJson(NODE1_API, '/api/knowledge-assets', { contextGraphId: CONTEXT_GRAPH, name: assertionName }, state.node1Token);
// KA create returns 201 (resource created) vs the legacy route's 200.
expect(r.status, `create: ${JSON.stringify(r.body)}`).toBe(201);
expect(r.body.assertionUri).toContain(assertionName);

const quads = [
{ subject: 'urn:test:lifecycle:s1', predicate: 'http://schema.org/name', object: '"Sign-at-creation lifecycle test"', graph: '' },
{ subject: 'urn:test:lifecycle:s2', predicate: 'http://schema.org/sameAs', object: 'urn:test:lifecycle:s1', graph: '' },
];
r = await postJson(NODE1_API, `/api/assertion/${assertionName}/write`, { contextGraphId: CONTEXT_GRAPH, quads }, state.node1Token);
r = await postJson(NODE1_API, `/api/knowledge-assets/${assertionName}/wm/write`, { contextGraphId: CONTEXT_GRAPH, quads }, state.node1Token);
expect(r.status, `write: ${JSON.stringify(r.body)}`).toBe(200);
expect(r.body.written).toBe(2);

r = await postJson(NODE1_API, `/api/assertion/${assertionName}/finalize`, { contextGraphId: CONTEXT_GRAPH }, state.node1Token);
r = await postJson(NODE1_API, `/api/knowledge-assets/${assertionName}/wm/finalize`, { contextGraphId: CONTEXT_GRAPH }, state.node1Token);
expect(r.status, `finalize: ${JSON.stringify(r.body)}`).toBe(200);
// wm/finalize returns the full seal payload (PR #971): merkleRoot, eip712Digest, schemeVersion, etc.
expect(r.body.merkleRoot).toMatch(/^0x[0-9a-f]{64}$/);
expect(r.body.eip712Digest).toMatch(/^0x[0-9a-f]{64}$/);
expect(r.body.schemeVersion).toBe(1);

r = await postJson(NODE1_API, `/api/assertion/${assertionName}/promote`, { contextGraphId: CONTEXT_GRAPH }, state.node1Token);
r = await postJson(NODE1_API, `/api/knowledge-assets/${assertionName}/swm/share`, { contextGraphId: CONTEXT_GRAPH }, state.node1Token);
expect(r.status, `promote: ${JSON.stringify(r.body)}`).toBe(200);
// swm/share returns { swmShared, promotedCount }.
expect(r.body.promotedCount).toBe(2);

await sleep(1500); // let trailing events arrive
Expand All @@ -397,8 +401,9 @@ describe('2. failed publish does not leak triples into verified-memory (RC11 / P
const subject = `urn:test:edge:rc11:${Date.now().toString(36)}`;
const witnessLiteral = `"PR2 failed-publish witness ${Date.now().toString(36)}"`;

let r = await postJson(NODE5_API, '/api/assertion/create', { contextGraphId: CONTEXT_GRAPH, name: assertionName }, state.node5Token);
expect(r.status, `edge create: ${JSON.stringify(r.body)}`).toBe(200);
let r = await postJson(NODE5_API, '/api/knowledge-assets', { contextGraphId: CONTEXT_GRAPH, name: assertionName }, state.node5Token);
// KA create returns 201 (resource created) vs the legacy route's 200.
expect(r.status, `edge create: ${JSON.stringify(r.body)}`).toBe(201);

// The witness literal is unique per run so the verified-memory query
// below can isolate THIS publish's quads from any bootstrap data
Expand All @@ -407,11 +412,11 @@ describe('2. failed publish does not leak triples into verified-memory (RC11 / P
{ subject, predicate: 'http://schema.org/name', object: witnessLiteral, graph: '' },
{ subject, predicate: 'http://schema.org/author', object: '"edge-node-5"', graph: '' },
];
r = await postJson(NODE5_API, `/api/assertion/${assertionName}/write`, { contextGraphId: CONTEXT_GRAPH, quads }, state.node5Token);
r = await postJson(NODE5_API, `/api/knowledge-assets/${assertionName}/wm/write`, { contextGraphId: CONTEXT_GRAPH, quads }, state.node5Token);
expect(r.status).toBe(200);
r = await postJson(NODE5_API, `/api/assertion/${assertionName}/finalize`, { contextGraphId: CONTEXT_GRAPH }, state.node5Token);
r = await postJson(NODE5_API, `/api/knowledge-assets/${assertionName}/wm/finalize`, { contextGraphId: CONTEXT_GRAPH }, state.node5Token);
expect(r.status).toBe(200);
r = await postJson(NODE5_API, `/api/assertion/${assertionName}/promote`, { contextGraphId: CONTEXT_GRAPH }, state.node5Token);
r = await postJson(NODE5_API, `/api/knowledge-assets/${assertionName}/swm/share`, { contextGraphId: CONTEXT_GRAPH }, state.node5Token);
expect(r.status).toBe(200);

// Post-RFC-38 an edge node (identityId=0) may still reach `confirmed`
Expand Down
20 changes: 11 additions & 9 deletions devnet/v10-stress/automated.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -993,8 +993,9 @@ describe('V10 chain — stress + scenario validation', () => {
console.log(`phase 2: WM-only batch (${wmOnly} assertions on core1)...`);
for (let i = 0; i < wmOnly; i++) {
const name = `wm-only-${runTag}-${i}`;
// KA create auto-finalizes (seals to WM) when `quads` are supplied.
const r = await fetch(
`http://127.0.0.1:${core1.apiPort}/api/assertion/create`,
`http://127.0.0.1:${core1.apiPort}/api/knowledge-assets`,
{
method: 'POST',
headers: {
Expand All @@ -1005,7 +1006,6 @@ describe('V10 chain — stress + scenario validation', () => {
name,
contextGraphId: CONTEXT_GRAPH,
quads: buildQuads(name),
finalize: true,
}),
},
);
Expand Down Expand Up @@ -1045,8 +1045,10 @@ describe('V10 chain — stress + scenario validation', () => {
console.log(`phase 2: VM custodial (mode B) batch (${vmCustodial} assertions via core2)...`);
for (let i = 0; i < vmCustodial; i++) {
const name = `vm-custodial-${runTag}-${i}`;
// KA create auto-finalizes when `quads` are supplied; `alsoShareSwm`
// performs the WM→SWM transition (legacy `promote: true`).
const createRes = await fetch(
`http://127.0.0.1:${core2.apiPort}/api/assertion/create`,
`http://127.0.0.1:${core2.apiPort}/api/knowledge-assets`,
{
method: 'POST',
headers: {
Expand All @@ -1057,8 +1059,7 @@ describe('V10 chain — stress + scenario validation', () => {
name,
contextGraphId: CONTEXT_GRAPH,
quads: buildQuads(name),
finalize: true,
promote: true,
alsoShareSwm: true,
}),
},
);
Expand Down Expand Up @@ -1211,8 +1212,10 @@ describe('V10 chain — stress + scenario validation', () => {
console.log(`phase 2: WM→SWM batch (${wmSwm} assertions on core1)...`);
for (let i = 0; i < wmSwm; i++) {
const name = `wm-swm-${runTag}-${i}`;
// KA create auto-finalizes when `quads` are supplied; `alsoShareSwm`
// performs the WM→SWM transition (legacy `promote: true`).
const r = await fetch(
`http://127.0.0.1:${core1.apiPort}/api/assertion/create`,
`http://127.0.0.1:${core1.apiPort}/api/knowledge-assets`,
{
method: 'POST',
headers: {
Expand All @@ -1223,8 +1226,7 @@ describe('V10 chain — stress + scenario validation', () => {
name,
contextGraphId: CONTEXT_GRAPH,
quads: buildQuads(name),
finalize: true,
promote: true,
alsoShareSwm: true,
}),
},
);
Expand Down Expand Up @@ -1293,7 +1295,7 @@ describe('V10 chain — stress + scenario validation', () => {
`\`publishFromFinalizedAssertion\` (\`packages/agent/src/dkg-agent.ts:4383\`) calls ` +
`\`publishFromSharedMemory(contextGraphId, 'all', ...)\` with the literal selection \`'all'\`. ` +
`It does NOT filter SWM content to the named assertion's quads. ` +
`Reproduction: promote N assertions (\`POST /api/assertion/create { ..., finalize: true, promote: true }\` × N) ` +
`Reproduction: promote N assertions (\`POST /api/knowledge-assets { ..., quads, alsoShareSwm: true }\` × N) ` +
`then publish ONE of them by name (\`POST /api/shared-memory/publish { assertionName }\`). ` +
`The publish bundles all N assertions' quads into one KC and the response status is \`tentative\` ` +
`with \`kaId: "0"\` (sentinel), because the merkle root the publisher derives over the actual ` +
Expand Down
Loading
Loading