Repository navigation
test(contracts): check mergeThreeWay against the shared merge vectors - #165
Conversation
AgentKit and SkillX both rebase a personal kit overlay with a three-way line merge. Run SkillX's mergeThreeWay over a copy of AgentKit's three-way-merge-v1 conformance vectors so the two merges stay byte-identical: clean merge text, conflict base ranges, adjacency, insertion points, line endings and a missing final newline.
clark-cant
left a comment
There was a problem hiding this comment.
Summary
Adds packages/contracts/src/fixtures/three-way-merge-v1-vectors.json (18 cases, schema agentkit.three-way-merge-vectors/v1) and a 30-line test that runs mergeThreeWay over every case, asserting either the clean text or the 0-based base ranges of each conflict. No production code changes.
Risk level: Low — additive test + fixture, single package, CI green (web-contracts-cli SUCCESS on 12e4bc8).
Mandatory gates
- Duplicate / prior implementation: clear. Only this PR matches "three-way merge vectors" across all PR states. Existing coverage in
patch-merge.test.ts(4 cases: disjoint, overlap, adjacent fail-closed, identical-change) is a subset of what the vectors pin, not a parallel implementation. - Project standards:
docs/code-standards.mdpresent. Test file is 30 LOC (well under the 200 LOC limit); noany, no@ts-ignore, no new abstraction, no new dependency.@skillx/contractsisprivate: true, so the fixtures directory has no publish-surface concern. - Strategic necessity: clear value. The repo's own
mergeThreeWaydocblock andrebase.tsalready depend on adjacency fail-closed semantics; pinning them against AgentKit's shared vectors is exactly the guard needed for the personal-kit rebase work (#108 / agentkit #2848), and breaks are caught by CI rather than by a downstream rebase.
Findings
Critical: none.
Important: none.
Suggestion
- Conflict payload is not asserted.
three-way-merge-vectors.test.tscompares only{ baseStart, baseEnd }. A regression that keeps the ranges but corruptsbase/ours/theirs(the text a later merge-conflict UI orrebase.tscaller surfaces) would still pass all 18 cases. Consider asserting the full conflict payload on at leasttwo conflictsanddelete against edit, where the payload is the interesting part. - Vector provenance is not pinned. The docblock states the fixture is a byte-for-byte copy of AgentKit's
docs/conformance/skill-lifecycle/three-way-merge-v1-vectors.jsonand that it is "replaced only by a newer copy". Nothing records which AgentKit commit that copy came from, so the next sync is unverifiable from the diff. Asource: { repo, commit }field (or a comment with the commit SHA) makes the copy auditable. Note: I could not confirm the copy myself —bestagentkits/agentkitcontents API returns 404 at that path for my token (private repo or moved path) — please confirm provenance once when merging. schemais the only version guard. That is fine for v1; if a v2 schema lands, the schema assertion fails loudly, which is the desired behaviour. No change requested.
Verdict
Approve — suggestions only, no blocking findings. Verified independently on the PR head: the fixture parses with 18 uniquely named cases, the schema string matches agentkit.three-way-merge-vectors/v1, the implementation at packages/contracts/src/personal-kit/three-way-merge.ts returns { clean: true, text } / { clean: false, conflicts } with [baseStart, baseEnd) documented as 0-based (so the vector expectations are expressed in the implementation's own convention), and the line endings are bytes / empty base cases behave as the code describes.
Posted by /ck:review-pr at 2026-10-29T19:12:00Z
Summary
packages/contracts/src/fixtures/three-way-merge-v1-vectors.json, a byte-for-byte copy of AgentKit'sdocs/conformance/skill-lifecycle/three-way-merge-v1-vectors.json(18 cases).three-way-merge-vectors.test.ts, which runsmergeThreeWayover every case: clean merge text, or the 0-based base ranges of every conflict.A personal kit rebase must merge the same overlay identically in AgentKit (
skilloverlaymerge3) and SkillX. The vectors pin disjoint and adjacent edits, insertions at one point, identical changes, deletes against edits, repeated-line alignment, CRLF as bytes, a missing final newline and an empty base. No production code changes: the currentmergeThreeWayalready passes every case.Companion AgentKit change: bestagentkits/agentkit epic #2848 (personal kit overlay sync/rebase).
Test plan
pnpm exec vitest run packages/contracts/src/personal-kit/three-way-merge-vectors.test.ts(19 passed)pnpm --filter @skillx/contracts typecheck