Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
a2b7d29
feat(types,pack-kg,db,query): align entity kind and type contract wit…
ohdearquant May 24, 2026
64b268d
feat(khive-fold): ADR-024 alignment F128-F134
ohdearquant May 24, 2026
f32b9c7
fix(khive-runtime): apply F130 Vec→Result adapter in registry
ohdearquant May 24, 2026
b9ba5de
feat(khive-score): ADR-006 alignment F032-F037 — deterministic scorin…
ohdearquant May 24, 2026
1441098
test(db,query): add entity_type regression tests for storage round-tr…
ohdearquant May 24, 2026
4d4861f
fix(khive-pack-brain): rename initial/step to init/reduce for F128 al…
ohdearquant May 24, 2026
d5700e2
feat(adr): edge ontology, lifecycle, and bulk link semantics
ohdearquant May 24, 2026
afdc984
fix(adr): address critic MAJ findings for edge validation and bulk link
ohdearquant May 24, 2026
c9ddbe7
feat(adr): note kind, storage, and curation operations (closes #314)
ohdearquant May 24, 2026
fa0b97d
feat(adr): storage capability traits and sparse vector contract (clus…
ohdearquant May 24, 2026
20a8599
feat(event): align event model with ADR-004/022/032/041/042/046 contr…
ohdearquant May 24, 2026
9520123
fix(score,adr-006): align with Lean proof — remove QuantKey, distingu…
ohdearquant May 24, 2026
89b66f3
style: cargo fmt fix on score.rs underflow test
ohdearquant May 24, 2026
ea9af4a
Integrate cluster-02 (#336): ADR-006/024 alignment — DeterministicSco…
ohdearquant May 24, 2026
9f925cf
Merge integration/v1-adr-alignment (cluster-02 landed)
ohdearquant May 24, 2026
0682702
test(contract): include entity_type in expected node property valid-l…
ohdearquant May 24, 2026
7626835
ci: trigger workflow on integration/* branches too
ohdearquant May 24, 2026
308d5f0
Integrate cluster-01 (#337): ADR-001 entity_type + ADR-008 query colu…
ohdearquant May 24, 2026
8d931b8
merge: integrate v1-adr-alignment, renumber V5→V6 for edge lifecycle,…
ohdearquant May 24, 2026
5c9c9cc
test(contract): replace concept-to-concept depends_on with enables (A…
ohdearquant May 24, 2026
826e28d
fix(tests): align with ADR-001 entity_type signature + ADR-002 endpoi…
ohdearquant May 24, 2026
dc8c0b4
fix(adr): close codex-v2 cluster-03 findings (F010/F011/F012/F161/F20…
ohdearquant May 24, 2026
a220de4
Show adr-001-015-alignment: integrate impl-c03 (edge ontology, lifecy…
ohdearquant May 24, 2026
e21e01d
merge: integrate c01+c02+c03 into c04, resolve 8 conflicts
ohdearquant May 24, 2026
63247b7
fix: remove NoteKind re-export (pack-owned, not types-crate) + delete…
ohdearquant May 24, 2026
b347c5e
fix(c04): resolve merge conflicts with c03 (HandlerDef, edge lifecycl…
ohdearquant May 24, 2026
f5cf9a6
fix(curation): reject self-merge + fix edge rewire NOT NULL constraint
ohdearquant May 24, 2026
90a22cf
fix(runtime): reject invalid namespace at dispatch boundary, update s…
ohdearquant May 24, 2026
a5a21b2
feat(adr): namespace token and runtime API migration (closes #317)
ohdearquant May 24, 2026
01d594a
Merge remote-tracking branch 'origin/integration/v1-adr-alignment' in…
ohdearquant May 24, 2026
c704fe4
fix(c04): address codex findings — kind-routed delete, Page<Note>, tr…
ohdearquant May 24, 2026
ffedb1b
fix(c05): update VectorStore test calls for new insert/search signatures
ohdearquant May 24, 2026
fdac565
Merge remote-tracking branch 'origin/integration/v1-adr-alignment' in…
ohdearquant May 24, 2026
f1abc02
fix(c06): use event.payload (not .data) in fold test — Event.data doe…
ohdearquant May 24, 2026
99db1e4
fix(runtime): seal NamespaceToken constructors, error on invalid name…
ohdearquant May 24, 2026
20ec310
fix(c04): complete test migration + seal kind_status + fmt
ohdearquant May 24, 2026
6606f9e
fix(c05): retrieval adapter migration, filter guard, sparse kind, fmt
ohdearquant May 24, 2026
36ecc6a
docs(runtime): update quick-start snippet for NamespaceToken API
ohdearquant May 24, 2026
1fc2b60
fix(c06): emit curation events, fix brain provenance, expose event fi…
ohdearquant May 24, 2026
29281b3
fix(pack-kg): use custom serde deserializer for tri-state nullable f64
ohdearquant May 24, 2026
2239433
fix(runtime,pack-kg): address codex round-2 findings — full event pay…
ohdearquant May 24, 2026
ce0a74e
fix(storage): address codex round-2 findings — fmt, trait signature, …
ohdearquant May 24, 2026
00ead6e
test(pack-kg): tri-state UpdateParams.salience/decay_factor regressio…
ohdearquant May 24, 2026
6df5b0b
Show adr-001-015-alignment: integrate impl-c04 (note kind, storage, c…
ohdearquant May 24, 2026
1d18abf
fix(db): use pragma_table_info for vec0 schema detection (codex round…
ohdearquant May 24, 2026
b571ae2
fix(runtime): merge_entity policy event payload uses wire-canonical s…
ohdearquant May 24, 2026
d905b5d
feat(npm): per-platform Rust binary packaging via optionalDependencie…
ohdearquant May 24, 2026
9b48e8a
feat(vcs): align khive-vcs to git-native VCS contract (ADR-010/ADR-020)
ohdearquant May 24, 2026
ba4b35f
feat(adr-030): implement Checkpoint protocol and fix proof path refer…
ohdearquant May 24, 2026
6d097ba
feat(brain): profile-oriented orchestration per ADR-032 (cluster-19)
ohdearquant May 24, 2026
7e62d6c
fix(npm): resolve codex round-1 CRIT/MAJ findings for PR #351
ohdearquant May 25, 2026
30f1716
merge(integration): resolve c04+c07 conflicts — NamespaceToken + note…
ohdearquant May 25, 2026
23a8bf7
fix(brain): correct unbind AND semantics and archived-default resolut…
ohdearquant May 25, 2026
96c26bb
Show adr-001-015-alignment: integrate impl-c05 (storage capability + …
ohdearquant May 25, 2026
a7777e2
fix(c17): close codex round-1 MAJ/minor findings for PR #353
ohdearquant May 25, 2026
ec4f27c
fix(c25): remove .gitkeep in publish phase + fix shim mode (codex rou…
ohdearquant May 25, 2026
3196bdd
Show adr-001-015-alignment: integrate impl-c06 (event observable + pr…
ohdearquant May 25, 2026
0523546
Show adr-001-015-alignment: integrate impl-c10 (vcs git-native + lega…
ohdearquant May 25, 2026
f29b62b
Show adr-001-015-alignment: integrate impl-c25 (per-platform rust bin…
ohdearquant May 25, 2026
25d90eb
Show adr-001-015-alignment: integrate impl-c19 (brain profile orchest…
ohdearquant May 25, 2026
863524d
Show adr-001-015-alignment: integrate impl-c17 (retrieval checkpoints…
ohdearquant May 25, 2026
6fad6f7
fix(db): update migration ledger comment from ADR-022 to ADR-015 (F085)
ohdearquant May 25, 2026
db6fedf
fix(adr): deno fmt re-pad ADR-015 migration ledger table (codex round…
ohdearquant May 25, 2026
82925cd
Show adr-001-015-alignment: integrate impl-c24 (schema migration ledger)
ohdearquant May 25, 2026
50864e0
feat(adr): runtime backend + substrate coordinator (cluster-08)
ohdearquant May 25, 2026
8dba08f
feat(adr): GTD pack schema plan and lifecycle audit (cluster-15)
ohdearquant May 25, 2026
f2d2f83
feat(query): query layer contract — F045/F047/F048/F218 (cluster-09)
ohdearquant May 25, 2026
6a545b4
Show adr-001-015-alignment: integrate impl-c23 (import/export/remote …
ohdearquant May 25, 2026
9ab48a2
docs(runtime): clarify schema_plan() is not yet applied at startup
ohdearquant May 25, 2026
dc46467
feat(types/runtime): HandlerDef pack contract — VerbCategory, Validat…
ohdearquant May 25, 2026
6a61e77
docs(cli): correct ADR-055→ADR-036 citation drift (codex round-1 MIN-1)
ohdearquant May 25, 2026
3db44e9
feat(kkernel): add engine + admin commands (cluster-21, ADR-034/035/0…
ohdearquant May 25, 2026
f1e00f7
Show adr-001-015-alignment: integrate impl-c15 (gtd schema + lifecycl…
ohdearquant May 25, 2026
f1c2c5d
feat(packs): ADR-023/ADR-027/ADR-040 dynamic pack loading + comm/sche…
ohdearquant May 25, 2026
4475f49
docs(runtime): clarify schema_plan is not yet applied at runtime (c11…
ohdearquant May 25, 2026
9381c2c
fix(query): wire synthetic edge to events/notes tables, reject OR-spa…
ohdearquant May 25, 2026
c567f4d
Show adr-001-015-alignment: integrate impl-c11 (HandlerDef pack contr…
ohdearquant May 25, 2026
ff2f0e7
fix(c14): restore c24 ADR-015 ledger amendment + add comm read/reply …
ohdearquant May 25, 2026
523a607
Show adr-001-015-alignment: integrate impl-c14 (dynamic pack loading …
ohdearquant May 25, 2026
ee9ac36
feat(memory): align recall pipeline to ADR-021/ADR-033 (cluster-18)
ohdearquant May 25, 2026
71639e0
fixup(c14): add category field to new pack HandlerDef literals
ohdearquant May 25, 2026
5cbb9d8
fix(gtd): apply cargo fmt to integration test imports (post-rebase cl…
ohdearquant May 25, 2026
1682234
Show adr-001-015-alignment: integrate impl-c18 (memory recall + reran…
ohdearquant May 25, 2026
7d7af35
Show adr-001-015-alignment: integrate impl-c09 (query layer contract)
ohdearquant May 25, 2026
653ceba
Show adr-001-015-alignment: integrate impl-c21 (kkernel engine + admi…
ohdearquant May 25, 2026
2c6433a
feat(runtime/mcp): pack verb registry, wire names, and introspection …
ohdearquant May 25, 2026
adcf8c3
feat(db): add V14 embedding model registry migration (ADR-043, cluste…
ohdearquant May 25, 2026
c358414
feat(request/runtime/mcp): execution modes + presentation envelope (c…
ohdearquant May 25, 2026
5769eac
fix(db): address c20 codex round-1 findings (CRIT-1/2, MAJ-1, MIN-1/2)
ohdearquant May 25, 2026
bed9b46
Show adr-001-015-alignment: integrate impl-c20 (embedding model regis…
ohdearquant May 25, 2026
e9ca15e
Show adr-001-015-alignment: integrate impl-c12 (pack verb registry + …
ohdearquant May 25, 2026
b7f3cfc
Show adr-001-015-alignment: integrate impl-c13 (request execution + p…
ohdearquant May 25, 2026
3cdbf86
feat(adr): event-sourced proposals — pack-kg verbs + V15 migration (c…
ohdearquant May 25, 2026
30e4cef
fix(pack-kg): close actor-override security bypass in propose/review/…
ohdearquant May 25, 2026
85993fe
Show adr-001-015-alignment: integrate impl-c22 (event-sourced proposals)
ohdearquant May 25, 2026
408354d
Show adr-001-015-alignment: integrate impl-c08 (runtime backend + sub…
ohdearquant May 25, 2026
8319402
Show adr-001-015-alignment: integrate impl-c23 (import/export/sync ph…
ohdearquant May 25, 2026
c79d715
docs(adr-015): append V14 + V15 ledger entries (integration codex MAJOR)
ohdearquant May 25, 2026
1ee7709
fix(runtime): build_edge/link_many require NamespaceToken (ADR-007 co…
ohdearquant May 25, 2026
3ec2e72
fix(kkernel): convert fake-success scaffolds to honest not-implemente…
ohdearquant May 25, 2026
1cbab62
Remove obsolete proof files and scripts related to khive formal proof…
ohdearquant May 25, 2026
5acd033
chore(release): bump khive workspace to 0.2.1, lattice-embed to 0.2.3
ohdearquant May 25, 2026
80d19b1
chore(meta): update homepage to https://github.com/ohdearquant
ohdearquant May 25, 2026
3539204
chore(meta): de-brand khive.ai references → GitHub URLs
ohdearquant May 25, 2026
a59e234
fix(ci): remove dead check-proof-references.sh call
ohdearquant May 25, 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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: CI

on:
push:
branches: [main]
branches: [main, "integration/**"]
pull_request:
branches: [main]
branches: [main, "integration/**"]

env:
CARGO_TERM_COLOR: always
Expand Down
235 changes: 201 additions & 34 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
name: Release

# Triggered by a version tag push (e.g. v0.2.0).
# Builds Rust binaries per-platform, publishes each @khive/kernel-{platform}
# npm subpackage, then publishes the umbrella khive package.
#
# Per ADR-026 §"Atomic release semantics": all subpackage publishes must
# succeed before the umbrella publishes. This is enforced by separating the
# workflow into two phases:
#
# Phase 1 (build-platform matrix): compile binaries, stage into subpackage
# bin/, remove .gitkeep, and upload the whole subpackage as a GH Actions
# artifact. No `npm publish` happens here.
#
# Phase 2 (publish-all, single job): downloads all six platform artifacts,
# updates versions, publishes the six subpackages, then publishes the
# umbrella — in a single sequential job. If any subpackage publish fails,
# the umbrella is never published. Because publishing is serialised in one
# job, partial failure cannot leave mismatched versions permanently on the
# registry (any already-published subpackage can be unpublished within 72h
# via `npm unpublish` before the version is re-released).
#
# This satisfies the ADR guarantee: partial failure leaves the user able to
# install the previous khive version unchanged.

on:
push:
tags:
Expand All @@ -8,63 +31,207 @@ on:
permissions:
contents: write

env:
CARGO_TERM_COLOR: always

jobs:
compile:
# ─────────────────────────────────────────────────────────────────────────
# Phase 1: Build Rust binaries per platform and upload as GH artifacts.
# No npm publish happens here — that is deferred to Phase 2.
# ─────────────────────────────────────────────────────────────────────────
build-platform:
strategy:
fail-fast: true
matrix:
include:
- os: macos-latest
- platform: darwin-arm64
os: macos-latest
target: aarch64-apple-darwin
binary: khive-darwin-arm64
- os: macos-13
cross: false

- platform: darwin-x64
os: macos-latest
target: x86_64-apple-darwin
binary: khive-darwin-x64
- os: ubuntu-latest
cross: false

- platform: linux-x64-gnu
os: ubuntu-latest
target: x86_64-unknown-linux-gnu
binary: khive-linux-x64
- os: ubuntu-latest
cross: false

- platform: linux-x64-musl
os: ubuntu-latest
target: x86_64-unknown-linux-musl
cross: true

- platform: linux-arm64
os: ubuntu-latest
target: aarch64-unknown-linux-gnu
binary: khive-linux-arm64
- os: windows-latest
cross: true

- platform: win32-x64
os: windows-latest
target: x86_64-pc-windows-msvc
binary: khive-win32-x64.exe
cross: false

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v4
- uses: denoland/setup-deno@v2

- uses: dtolnay/rust-toolchain@1.94.1
with:
deno-version: v2.x
- name: Compile
targets: ${{ matrix.target }}

- name: Install cargo-zigbuild (cross-compile targets only)
if: ${{ matrix.cross }}
run: pip3 install ziglang && cargo install cargo-zigbuild

- name: Build binaries (native)
if: ${{ !matrix.cross }}
working-directory: crates
run: |
cargo build --release --target ${{ matrix.target }} -p kkernel -p khive-mcp

- name: Build binaries (zigbuild cross)
if: ${{ matrix.cross }}
working-directory: crates
run: |
deno compile \
--allow-read --allow-write --allow-run --allow-env \
--target ${{ matrix.target }} \
--output npm/bin/${{ matrix.binary }} \
cli/main.ts
- uses: actions/upload-artifact@v4
cargo zigbuild --release --target ${{ matrix.target }} -p kkernel -p khive-mcp

- name: Stage binaries into subpackage bin/
shell: bash
run: |
PKG_DIR="npm/kernel-${{ matrix.platform }}/bin"
SRC="crates/target/${{ matrix.target }}/release"
# Remove the placeholder so it is not shipped in the published tarball (MIN-1).
rm -f "${PKG_DIR}/.gitkeep"
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
cp "${SRC}/kkernel.exe" "${PKG_DIR}/kkernel.exe"
cp "${SRC}/khive-mcp.exe" "${PKG_DIR}/khive-mcp.exe"
else
cp "${SRC}/kkernel" "${PKG_DIR}/kkernel"
cp "${SRC}/khive-mcp" "${PKG_DIR}/khive-mcp"
chmod +x "${PKG_DIR}/kkernel" "${PKG_DIR}/khive-mcp"
fi

- name: Upload subpackage artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.binary }}
path: npm/bin/${{ matrix.binary }}
name: kernel-${{ matrix.platform }}
path: npm/kernel-${{ matrix.platform }}/
# Retain for 1 day — only needed during this release run.
retention-days: 1

publish:
needs: compile
# ─────────────────────────────────────────────────────────────────────────
# Phase 2: Publish all subpackages + umbrella atomically in a single job.
# Runs only after ALL Phase 1 jobs succeed (needs: build-platform with
# fail-fast: true propagates any single failure here).
# ─────────────────────────────────────────────────────────────────────────
publish-all:
needs: build-platform
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
path: npm/bin
merge-multiple: true
- name: Set version from tag
run: |
VERSION="${GITHUB_REF#refs/tags/v}"
jq --arg v "$VERSION" '.version = $v' npm/package.json > tmp.json
mv tmp.json npm/package.json

- uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://registry.npmjs.org
- name: Publish

# Extract the version from the git tag (strip leading "v").
# Passed via env var to avoid shell-interpolation issues in node -e (MIN-3).
- name: Extract version
run: |
echo "VERSION=${GITHUB_REF#refs/tags/v}" >> "$GITHUB_ENV"

# Download all six platform artifacts into their respective directories.
- name: Download all platform artifacts
uses: actions/download-artifact@v4
with:
# Download to npm/ — each artifact named kernel-{platform} lands in
# npm/kernel-{platform}/ matching the checkout layout.
path: npm/
# pattern matches kernel-* artifacts from Phase 1
pattern: kernel-*

# actions/checkout@v4 above restored npm/kernel-*/bin/.gitkeep (it's tracked
# in git so the bin/ dirs exist for new clones). actions/download-artifact
# does not delete it. Remove it here so the published tarball ships only
# the platform binary, not the placeholder. (NEW-1 round-2 fix.)
- name: Remove .gitkeep placeholders before publish
run: rm -f npm/kernel-*/bin/.gitkeep

# Set the version in each subpackage's package.json.
# VERSION and PKG_JSON are passed via env vars to avoid shell-interpolation
# of special characters inside the node -e script (MIN-3).
- name: Set subpackage versions
run: |
for platform in darwin-arm64 darwin-x64 linux-x64-gnu linux-x64-musl linux-arm64 win32-x64; do
PKG_JSON="npm/kernel-${platform}/package.json" VERSION="${{ env.VERSION }}" node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync(process.env.PKG_JSON));
pkg.version = process.env.VERSION;
fs.writeFileSync(process.env.PKG_JSON, JSON.stringify(pkg, null, 2) + '\n');
"
done

# Publish all six subpackages. If any fails, subsequent steps (including
# umbrella publish) do not run. GitHub Actions sequential steps in a
# single job guarantee this ordering.
- name: Publish @khive/kernel-darwin-arm64
working-directory: npm/kernel-darwin-arm64
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish @khive/kernel-darwin-x64
working-directory: npm/kernel-darwin-x64
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish @khive/kernel-linux-x64-gnu
working-directory: npm/kernel-linux-x64-gnu
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish @khive/kernel-linux-x64-musl
working-directory: npm/kernel-linux-x64-musl
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish @khive/kernel-linux-arm64
working-directory: npm/kernel-linux-arm64
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish @khive/kernel-win32-x64
working-directory: npm/kernel-win32-x64
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

# Only reached if all six subpackage publishes succeeded.
- name: Set umbrella version and pin subpackage versions
env:
VERSION: ${{ env.VERSION }}
run: |
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('npm/package.json'));
pkg.version = process.env.VERSION;
for (const k of Object.keys(pkg.optionalDependencies || {})) {
pkg.optionalDependencies[k] = process.env.VERSION;
}
fs.writeFileSync('npm/package.json', JSON.stringify(pkg, null, 2) + '\n');
"

- name: Publish khive (umbrella)
working-directory: npm
run: npm publish --access public
env:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,5 @@ docs/adr/_review/

# Compiled CLI binaries (built by scripts/compile.sh, not committed)
npm/bin/khive-*
# Exception: npm/bin/khive-mcp is the Node shim for the MCP binary, not a compiled binary.
!npm/bin/khive-mcp
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: check clippy test contract-test fmt fmt-check build clean ci docs-check publish publish-dry local
.PHONY: check clippy test contract-test fmt fmt-check build clean ci docs-check publish publish-dry local proof-check

check:
cd crates && cargo check --workspace
Expand All @@ -23,6 +23,9 @@ fmt-check:
build:
cd crates && cargo build --workspace --release

proof-check:
./scripts/check-proof-references.sh

clean:
cd crates && cargo clean

Expand Down
2 changes: 1 addition & 1 deletion cli/deno.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@khive/cli",
"version": "0.2.0",
"version": "0.2.1",
"description": "khive — research knowledge graph CLI",
"license": "Apache-2.0",
"tasks": {
Expand Down
10 changes: 3 additions & 7 deletions cli/kg/doctor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@ export async function inspectKg(repoRoot: string): Promise<DoctorReport> {
code: "DUPLICATE_ID",
file: ENTITIES_FILE,
line: entry.line,
message:
`Duplicate entity id '${id}' (first seen on line ${entityFirstLine.get(id)})`,
message: `Duplicate entity id '${id}' (first seen on line ${entityFirstLine.get(id)})`,
});
} else {
entityIds.add(id);
Expand Down Expand Up @@ -237,8 +236,7 @@ export async function inspectKg(repoRoot: string): Promise<DoctorReport> {
code: "DUPLICATE_NATURAL_KEY",
file: EDGES_FILE,
line: entry.line,
message:
`Duplicate edge (source=${source}, target=${target}, relation=${relation})`,
message: `Duplicate edge (source=${source}, target=${target}, relation=${relation})`,
});
} else {
naturalKeys.add(naturalKey);
Expand Down Expand Up @@ -292,9 +290,7 @@ function formatDoctor(report: DoctorReport, json: boolean): string {
];

for (const issue of report.issues) {
const loc = issue.line !== undefined
? `${issue.file}:${issue.line}`
: issue.file;
const loc = issue.line !== undefined ? `${issue.file}:${issue.line}` : issue.file;
const prefix = issue.severity === "error" ? "ERROR" : "WARN ";
lines.push(` [${prefix}] ${issue.code}: ${issue.message} (${loc})`);
}
Expand Down
8 changes: 4 additions & 4 deletions cli/kg/doctor_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ async function setupKg(
edges: unknown[],
): Promise<void> {
await Deno.mkdir(`${dir}/.khive/kg`, { recursive: true });
const entitiesNdjson =
entities.map((e) => JSON.stringify(e)).join("\n") + (entities.length > 0 ? "\n" : "");
const edgesNdjson =
edges.map((e) => JSON.stringify(e)).join("\n") + (edges.length > 0 ? "\n" : "");
const entitiesNdjson = entities.map((e) => JSON.stringify(e)).join("\n") +
(entities.length > 0 ? "\n" : "");
const edgesNdjson = edges.map((e) => JSON.stringify(e)).join("\n") +
(edges.length > 0 ? "\n" : "");
await Deno.writeTextFile(`${dir}/.khive/kg/entities.ndjson`, entitiesNdjson);
await Deno.writeTextFile(`${dir}/.khive/kg/edges.ndjson`, edgesNdjson);
}
Expand Down
11 changes: 11 additions & 0 deletions cli/kg/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,17 @@ export async function runExport(repoRoot: string, args: string[]): Promise<void>
return;
}

if (format !== "ndjson") {
// ADR-036 §8: the --format flag on export is reserved; any non-ndjson value
// is rejected with a "not yet implemented" error until P1/P2 adapters ship.
console.error(
`Error: --format ${JSON.stringify(format)} is not yet implemented for export.\n` +
`Supported: ndjson (default), archive.\n` +
`Non-NDJSON export formats are deferred to P1/P2 (ADR-036 §8).`,
);
Deno.exit(1);
}

// Default: canonical NDJSON export
try {
await exportCanonical(repoRoot);
Expand Down
Loading
Loading