Implements the 3 HIGH fixes agent_qa found via the RALPH test cycle (analysis theirs,
implementation here), fixtures-first.
- T2E-1 [converter]: a multi-paragraph callout collapsed to one paragraph on round-trip.
markdown-converter `case "callout"` now joins block children with "\n>\n" (a blank ">"
separator), byte-identical to the blockquote serializer, so two paragraphs survive
re-import. Fixture 12-callout-multiblock; two existing tests updated (their old
expectations encoded the collapse bug).
- T6-listnest [converter]: a callout/blockquote nested in a list item corrupted on
round-trip (callout type lost, `[!type]` leaked into text — confirmed DB corruption).
Add bridgeNestedCallouts: a post-marked, nesting-agnostic JSDOM pass that reconstructs
callouts from `[!type]`-opening blockquotes at ANY depth (the indented ` > [!type]`
form the column-0-anchored preprocessor misses), emitting the same callout div as the
top-level path (disjoint inputs, no double-processing). Strict `^[!type]` guard, so a
real blockquote — or one with `[!` mid-line — is NOT converted. Fixture 13-callout-in-list
+ a no-lead control + false-positive controls (proven non-vacuous).
- D-P3-1 [git-sync]: a "ghost" file (a tracked id that was never a page) was silently
absence-deleted on pull-reconcile -> data loss. Add GitSyncClient.pageIdsExist (datasource:
workspace-scoped SELECT over any space incl. trashed/moved, non-UUID ids filtered first);
cycle.ts computes the candidate-delete set and passes existing ids as `deletableIds` into
planReconciliation, which now absence-deletes ONLY real page rows — a ghost is preserved.
A cycle-level e2e test proves the ghost survives runCycle end-to-end.
Suites green: prosemirror-markdown 687, git-sync 272 (no type errors), datasource 36,
orchestrator 26; both packages tsc clean. Scope: the 3 fixes + tests/fixtures only, no
develop re-merge. T4E-esc (LOW escaping) left for the maintainer, per agent_qa.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
git-sync's converter-core (src/lib) was a byte-identical duplicate of the new
@docmost/prosemirror-markdown package (created in the previous commit). Switch
git-sync to consume the package and delete its copy — ending the duplication
that the whole #293 effort targets. Pure no-op: NO format/behavior change.
- git-sync depends on @docmost/prosemirror-markdown (workspace:*); engine
(stabilize/push/pull) + src/index barrel + 12 engine tests re-point their
converter imports to the package.
- Delete git-sync/src/lib (8 files) and the 23 duplicate converter-core test
files + their fixtures — the converter and its ~440 tests now live once, in the
package. git-sync keeps only its ENGINE tests, which exercise the converter
through the package (the no-op proof). Kept roundtrip-helpers.ts (an engine
test imports firstDivergence from it; pure helper, no double-run).
- Added docmostExtensions to the package barrel (a kept engine schema-validity
test needs it).
Verified: editor-ext + prosemirror-markdown + git-sync all tsc EXIT 0;
git-sync vitest 28 files, 268 passed, 0 failures (engine cycle/roundtrip/push/
pull/reconcile green = no-op proof); prosemirror-markdown vitest still 443 passed
| 1 expected-fail; pnpm --frozen-lockfile EXIT 0; no ../lib refs remain in git-sync.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The git-sync converter + engine source lived only on the #119 branch; develop
had just the dead compiled build/. Bring the whole package (src + ~700 tests)
onto develop under CI, with NO consumer wired — git-sync stays fully inert in
develop (nothing in apps/server imports it), so runtime behavior is unchanged.
This unblocks #293 (extract the shared converter package from the landed source)
and lets #119's functionality land LAST, already writing the canonical format
(per the #326 landing order).
- packages/git-sync: src (lib converter + engine) + test corpus + configs.
- Remove develop's dead committed packages/git-sync/build/; gitignore it
(built in CI/Docker via pnpm build, never committed — no src/build drift).
- pnpm-lock.yaml: add the @docmost/git-sync importer (a missing workspace
package in the lock is a CI blocker). `pnpm install --frozen-lockfile` passes.
- NO server integration / loader / Dockerfile runtime changes (those come with
#119 at step 6).
Verified: tsc clean; vitest 711 passed | 1 expected-fail, 0 failures, 0 type
errors; pnpm --frozen-lockfile EXIT 0; apps/server has no git-sync import.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>