Skip to content

Plans 165–167: portable export + schema-driven extraction - #292

Merged
jeduden merged 12 commits into
mainfrom
claude/markdown-schema-conversion-socJI
May 16, 2026
Merged

Plans 165–167: portable export + schema-driven extraction#292
jeduden merged 12 commits into
mainfrom
claude/markdown-schema-conversion-socJI

Conversation

@jeduden

@jeduden jeduden commented May 15, 2026

Copy link
Copy Markdown
Owner

Summary

A small family of roadmap plans for getting data and portable Markdown out of mdsmith documents. (Plan IDs are 165–167 — 163/164 are used by other plans that landed on main, so these were renumbered during a rebase.)

Changes

  • plan/165_portable-markdown-export.md — a mdsmith export <file> subcommand: a source-to-source transform that strips <?…?> directive markers, keeps generated bodies, and inlines <?include?> to produce portable, directive-free Markdown. Deliberately not a fourth extract format — it needs no schema/kind and no conformance gate. Marker stripping is driven by gensection.FindMarkerPairs (MarkerPair.StartLine/EndLine) so only engine-recognized markers are removed and literal-content marker-like text survives.
  • plan/166_schema-driven-data-extraction.md — core feature. A default binding layer derives a data tree directly from the schema hierarchy (root frontmatter object plus projected sections beside it; keys from heading slugs; scopes with repeat: {min, max} become arrays whose elements retain each {placeholder} as a name: value field). Aligned with the landed plan-156 entry-shape unification: there is no preamble: key — a heading: null no-heading section's content projects into its enclosing object. extract <kind> --format json|yaml|msgpack <file> is gated on a passing schema match and reuses the validated *schema.MatchTree. Lua deferred.
  • plan/167_custom-binding-overrides.md — follow-up. Opt-in bind: key (*string, so unset vs. explicit-empty differ) overrides the default key or hoists children, layered on the single keyFor(node) seam from plan 166.
  • PLAN.md — catalog regenerated; every plan ID is unique.

Design points

  • 166/167 are schema→data; 165 is source→source. Kept as separate commands so the schema-projection gate isn't coupled onto a plain-document transform.
  • Default-first for extraction: usable the moment a kind has a schema; custom shaping is plan 167 or a downstream tool (jq/yq).
  • Composition-aware: 166 consumes the composed Schema from kind-schema composition (PR Implement schema composition across multiple kinds (plan 156) #288), expressed as a filename link in the Sequencing section because two plan files share id: 156.

This PR is roadmap/docs only — no behavior change yet.

https://claude.ai/code/session_01Ar54BuJr8fFB9KzJGvLvYR

Copilot AI review requested due to automatic review settings May 15, 2026 10:07
@codecov

codecov Bot commented May 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.26%. Comparing base (4a38260) to head (c0b5d68).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
Components Coverage Δ
Go 96.22% <ø> (+<0.01%) ⬆️
TypeScript 99.35% <ø> (ø)

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds Plan 163 to the project roadmap, describing a schema-driven extraction feature (mdsmith extract) that would project validated Markdown (kinds + schemas) into structured data outputs (JSON/YAML/Lua/msgpack).

Changes:

  • Added plan/163_schema-driven-data-extraction.md describing the new bind: concept and the proposed extractor + CLI design.
  • Updated PLAN.md to include Plan 163 in the catalog table.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
plan/163_schema-driven-data-extraction.md New plan document defining the bind: projection concept, extraction mapping rules, and implementation task breakdown.
PLAN.md Catalog table now includes the new Plan 163 entry.

Comment thread plan/163_schema-driven-data-extraction.md Outdated
Comment thread plan/163_schema-driven-data-extraction.md Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread plan/164_custom-binding-overrides.md Outdated
Comment thread PLAN.md Outdated
@jeduden jeduden changed the title Plan 163: Schema-driven data extraction (mdsmith extract) Plans 163 + 164: schema-driven data extraction (mdsmith extract) May 15, 2026
Copilot AI review requested due to automatic review settings May 15, 2026 10:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

plan/163_schema-driven-data-extraction.md:136

  • Task 4 refers to projecting repeats: true scopes, but repeats is an old key name and is currently rejected in the schema parser; repeating is expressed via repeat: { ... }. Please update the task text to use the current repeat-cardinality terminology so it matches the schema model the extractor will consume.
4. **Repeating scopes and placeholders.** Project
   `repeats: true` scopes as arrays; each element retains
   every captured `{field}` as a `name: value` field,

Comment thread plan/163_schema-driven-data-extraction.md Outdated
Comment thread plan/166_schema-driven-data-extraction.md
Copilot AI review requested due to automatic review settings May 15, 2026 11:22
@jeduden jeduden changed the title Plans 163 + 164: schema-driven data extraction (mdsmith extract) Plans 163–165: schema-driven extraction + portable Markdown export May 15, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread PLAN.md Outdated
claude added 7 commits May 16, 2026 10:09
Introduces a `bind:` projection layer on schema scopes and
content entries plus an `extract` subcommand that turns a
kind-conformant Markdown file into JSON/YAML/Lua/msgpack.
Sequenced on top of the schema-composition rework (plan
156) and content-schema work (plan 149).

https://claude.ai/code/session_01Ar54BuJr8fFB9KzJGvLvYR
… 164

- Default projection derives the data tree from the
  schema hierarchy; no annotations required.
- Custom bindings move to follow-up plan 164, layered on
  a single keyFor() seam.
- Address Copilot review: disambiguate the duplicate
  plan-156 id via explicit file link; name the concrete
  schema.MatchTree type returned by an extended
  schema.Validate.

https://claude.ai/code/session_01Ar54BuJr8fFB9KzJGvLvYR
Addresses Copilot review: a plain string cannot represent
"unset" vs `bind: ""` (hoist), so Bind is now *string.

https://claude.ai/code/session_01Ar54BuJr8fFB9KzJGvLvYR
- Repeating-scope elements always retain each placeholder
  as a name:value field.
- Root holds `frontmatter` plus projected sections beside
  it (no nesting under a single key).
- Preamble projected under `preamble`; wildcard/unlisted
  skipped.
- Defer Lua; ship json/yaml/msgpack.

https://claude.ai/code/session_01Ar54BuJr8fFB9KzJGvLvYR
The schema parser rejects the legacy `repeats` key;
repeating cardinality is `repeat: {min, max}`.

https://claude.ai/code/session_01Ar54BuJr8fFB9KzJGvLvYR
A source-to-source `export` subcommand that strips
directive markers, keeps generated bodies, and inlines
includes — distinct from schema extraction (163/164).

https://claude.ai/code/session_01Ar54BuJr8fFB9KzJGvLvYR
…eamble key

Plan 156 entry-unification landed in main (PR #295): the
standalone preamble: key is gone, replaced by heading:
null. Project the no-heading section's content into the
enclosing object instead of a preamble wrapper key.

https://claude.ai/code/session_01Ar54BuJr8fFB9KzJGvLvYR
@jeduden
jeduden force-pushed the claude/markdown-schema-conversion-socJI branch from 64eb45d to e199eb2 Compare May 16, 2026 10:11
@jeduden
jeduden requested a review from Copilot May 16, 2026 10:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (1)

plan/165_portable-markdown-export.md:101

  • Acceptance criteria currently say “all directive markers removed” while also requiring “Nested same-type literal-content markers are preserved.” Since the preserved markers still look like <?…?> lines, this is internally inconsistent. Consider tightening the wording to distinguish between (a) directive markers that the parser/engine recognizes as real directive start/end markers (which should be stripped) vs. (b) marker-like text treated as literal content (which should remain).
- [ ] `mdsmith export <file>` emits the file with all
      directive markers removed and generated bodies
      kept; `<?include?>` content is inlined.
- [ ] The source file is never modified.
- [ ] Stale directive bodies are regenerated before
      stripping, so the output is never stale.
- [ ] Nested same-type literal-content markers are
      preserved.

Comment thread PLAN.md Outdated
Comment thread plan/166_schema-driven-data-extraction.md Outdated
Comment thread plan/167_custom-binding-overrides.md
Comment thread plan/165_portable-markdown-export.md Outdated
Rebasing onto main pulled in plan/163_public-markdown-library and
plan/164_github-ui-releases-and-split-website, colliding with the new
plans. Renumber schema-extraction 163->166 and custom-bindings 164->167
(export stays 165, no collision); update cross-references and depends-on.

Plan 165: marker stripping is driven by gensection.FindMarkerPairs
(MarkerPair.StartLine/EndLine), not lint.File.GeneratedRanges (which
only records include/catalog body ranges). Tighten the acceptance
criteria to distinguish engine-recognized markers from literal-content
marker-like text.

https://claude.ai/code/session_01Ar54BuJr8fFB9KzJGvLvYR

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (2)

plan/167_custom-binding-overrides.md:35

  • This bullet references “collision diagnostic from plan 163”, but the collision diagnostic being extended/relied on is part of the extraction work in Plan 166. Keeping plan IDs consistent here matters because plan 163 is a different feature area (public markdown library).
- Composition rule: two kinds binding one composed node
  to different names is a compose-time error, reusing the
  collision diagnostic from plan 163.

plan/167_custom-binding-overrides.md:59

  • Acceptance criteria still say “otherwise identical to plan 163”, but the default-binding baseline for this plan is Plan 166. This is likely a renumbering leftover and should be corrected to avoid ambiguity during implementation/review.
- [ ] `bind:` overrides the default key; output is
      otherwise identical to plan 163.
- [ ] `bind: ""` hoists a node's children into its

Comment thread plan/167_custom-binding-overrides.md Outdated
Comment thread plan/166_schema-driven-data-extraction.md
Comment thread PLAN.md
…s-on

Renumbering leftovers: three "plan 163" references in plan 167 (keyFor
seam origin, collision diagnostic, acceptance criterion) now point to
the renumbered extraction plan 166. Drop ambiguous id 156 from plan
166's depends-on (two plan files share id 156); the composition
dependency stays expressed as a filename link in the Sequencing section.

https://claude.ai/code/session_01Ar54BuJr8fFB9KzJGvLvYR
@jeduden
jeduden requested a review from Copilot May 16, 2026 10:22
@jeduden jeduden changed the title Plans 163–165: schema-driven extraction + portable Markdown export Plans 165–167: portable export + schema-driven extraction May 16, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread PLAN.md
Auto-regenerating directive bodies on export is surprising and masks
drift. Default mode now fails on a stale body (exit non-zero, no
output); --fix opts into in-memory regeneration; --no-check skips the
check. The two flags are mutually exclusive. Tasks, acceptance
criteria, and decisions updated.

https://claude.ai/code/session_01Ar54BuJr8fFB9KzJGvLvYR

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread plan/165_portable-markdown-export.md Outdated
Tasks 1 and 4 disagreed on the return shape. Settle on
Export(f, mode) ([]byte, []lint.Diagnostic), mirroring plan 166's
Extract: a non-empty diagnostic slice means refusal (nil bytes); a
stale body in Check mode appends a directive-positioned diagnostic;
hard error is reserved for I/O only.

https://claude.ai/code/session_01Ar54BuJr8fFB9KzJGvLvYR

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread plan/165_portable-markdown-export.md Outdated
…e set

Export operates on an in-memory *lint.File, so it does no I/O and
returns no error; reads/writes are the CLI layer's job (real error
there). Spell out the success vs refusal contract: success = non-nil
bytes + nil diagnostics; refusal = nil bytes + non-empty diagnostics.

https://claude.ai/code/session_01Ar54BuJr8fFB9KzJGvLvYR

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@jeduden
jeduden merged commit 13268a4 into main May 16, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants