feat(request,kkernel): write-key conflict detection, TOML rule loader (#347, #382, #483)#503
Conversation
Merge sequence
Merge #499 first — PRs #500, #502, #503 depend on it (GitHub auto-retargets on merge). |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ee317a335a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| Some(ArgValue::Value(Value::String(r))), | ||
| ) = (src, tgt, rel) | ||
| { | ||
| keys.push(format!("edge-natural:{s}:{t}:{r}")); |
There was a problem hiding this comment.
Include namespace in edge conflict keys
When a request batch links the same (source_id, target_id, relation) in two different explicit namespace values, this key treats them as the same write even though dispatch resolves params["namespace"] per op and the graph edge uniqueness is scoped by namespace. That makes valid multi-tenant batches fail preflight with false conflict errors; include the resolved/default namespace in the edge-natural key before comparing.
Useful? React with 👍 / 👎.
| let src = op.args.get("source_id"); | ||
| let tgt = op.args.get("target_id"); | ||
| let rel = op.args.get("relation"); | ||
| if let ( | ||
| Some(ArgValue::Value(Value::String(s))), | ||
| Some(ArgValue::Value(Value::String(t))), | ||
| Some(ArgValue::Value(Value::String(r))), | ||
| ) = (src, tgt, rel) | ||
| { | ||
| keys.push(format!("edge-natural:{s}:{t}:{r}")); |
There was a problem hiding this comment.
Derive conflict keys from bulk link entries
For link(links=[...]) calls, the singleton source_id/target_id/relation args are absent, so this branch returns no write key and a sibling link(source_id=..., target_id=..., relation=...) to the same edge triple can still dispatch concurrently. Since the KG link handler accepts bulk entries and writes those same natural edge keys, the preflight needs to iterate the links array and emit a key for each entry.
Useful? React with 👍 / 👎.
ee317a3 to
a3600e0
Compare
…#347, #382, #483) - WriteKeyConflict error + check_write_key_conflicts() preflight in request DSL (#347) - Replace stub configurable_rule_checks with full TOML-based KG lint rule loader (#382) - Update AGENTS.md tool-schema table for new params (#483) Closes #347, #382, #483 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…s, fix rules default path
ADR-038 Finding 1: write-key conflict detection was dead code. Wire
`write_keys_for_op_pub` into `run_parsed` parallel branch — conflicting ops
get per-op `{ok: false}` entries; non-conflicting ops execute normally.
Preserves `results.length == summary.total` (ADR-016 contract).
ADR-038 Finding 2: old batch-abort approach diverged from ADR-038 per-op
semantics. Now only conflicting ops fail; sibling ops run as normal.
Finding 4: `link` source/target were treated as entity-level write keys,
causing false positives when updating an entity and linking from it in the
same batch. Fix: use substrate-prefixed keys (`entity:<uuid>` for entity ops,
`edge-natural:<src>:<tgt>:<rel>` for link ops).
Finding 5: default rules path was `rules.yaml` but `configurable_rule_checks`
rejects YAML. Change default and help text to `rules.toml`.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
a3600e0 to
ab65944
Compare
The 5000×384 Vamana build+recall test takes ~60s, too slow for CI. Mark with #[ignore] so it only runs via `cargo test --ignored`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
check_write_key_conflicts()detects conflicting write keys in batch ops before executionCloses #347, #382, #483
Stacked on #499 (authorize → Result), independent of #500-#502
Test plan
cargo check --workspacepassescargo test -p khive-request -p kkernelpasses🤖 Generated with Claude Code