Skip to content

pd-m4: teach progressive disclosure the convention kind#152

Merged
josealekhine merged 2 commits into
mainfrom
design/pd-m4-conventions
Jul 25, 2026
Merged

pd-m4: teach progressive disclosure the convention kind#152
josealekhine merged 2 commits into
mainfrom
design/pd-m4-conventions

Conversation

@josealekhine

Copy link
Copy Markdown
Member

Summary

Progressive-disclosure milestone 4 teaches the mover to digest
CONVENTIONS.md, whose entries are curated ## sections rather than
the timestamped ## [ entries of LEARNINGS/DECISIONS. The two parse
paths collapse into one, parametrized on a per-kind entry prefix, and the
real .context/CONVENTIONS.md is folded from 390 lines into a 22-line
root plus five theme files. Bundled alongside (human-approved jumbo): a
make site version gate that stops silent generator drift, and two
supporting fixes.

Changes

  • Convention-kind digestion (internal/disclosure): EntryPrefix(Kind)
    parametrizes one parse path (parseRegions); parseConvention deleted
    and Reconstruct de-branched. Staging enumerates ## sections by
    title identity (no timestamp), skipping the structural ## Themes and
    HTML-comment examples via a deliberately dumb line scanner. Validate
    generalized to the per-kind prefix with a new dup-title fail-loud
    (ErrDuplicateStagedTitle); Apply digests conventions end-to-end.
    Retires ConventionLinePrefix / HeadingRecent. — serves
    specs/progressive-disclosure.md
  • Add-path (ctx convention add): --section is now required and
    rejects placeholder values (a catch-all section is where an undecided
    caller dumps everything); a bullet lands at the top of its H2 section,
    keeping it enumerable and above ## Themes. --section Themes declares
    a theme on all three canonical kinds — writes both the gist bullet and
    the theme file so the gist↔file pairing invariant holds at once. —
    serves specs/progressive-disclosure.md
  • Skill + rollout: ctx-digest gains the convention path, the
    dup-title guard, and a fix to its plan-JSON example (entries are
    objects, not strings — the documented string form had failed
    json.Unmarshal since M3); Copilot skills synced. Real
    .context/CONVENTIONS.md folded into 5 themes (code-style, layout,
    workflow, docs, cli). — serves specs/progressive-disclosure.md
  • Toolchain gate: zensical is an exact pin in the tooling manifest;
    make site refuses to build unless the local generator matches, via
    check-tools.sh --only zensical --strict, catching drift in both
    directions (behind = silent regression, ahead = unreviewed rebuild).
    Pin and installer read one source of truth. — serves
    specs/check-tools.md
  • Supporting fixes: docs site rebuilt with zensical 0.0.51 and a dead
    blog link fragment corrected; a sibling-project design detail that
    leaked into the pd-m4 plan scrubbed to describe the design on ctx's own
    merits (serves specs/public-repo-hygiene.md); temp-repo tests set
    local commit.gpgsign=false so go test never reaches for the GPG
    agent.

Specs

  • specs/progressive-disclosure.md — the bounded-root model this
    milestone extends to the convention kind (design commit + implementation)
  • specs/check-tools.md — the tooling-manifest checker the make site
    version gate builds on
  • specs/public-repo-hygiene.md — the public-tree rule the plan-file
    scrub restores

Closed tasks

  • [E1] Config + vocabulary: EntryPrefix(Kind), retire
    ConventionLinePrefix/HeadingRecent, ErrDuplicateStagedTitle,
    ThemeDir(convention)
  • [E2] Parser unification: convention ## -enumerator, prefix-parametrized
    parse path, parseConvention deleted, kind-aware inspect, SplitStaging
  • [E3] Validate: per-kind entry-below-themes, dup-title fail-loud,
    rule-3 via the enumerator
  • [E4] Mover: lift the convention refusal, Apply end-to-end,
    title-only identity through the plan
  • [E5] Add-path: section-targeted convention add + post-fold invariant
  • [E6] ctx-digest skill — convention path + Copilot sync
  • [E7] Measurement gate on a realistic fixture; human-gated real
    rollout; milestone gate
  • (also closes the trailing M3 [E3]: ctx-digest apply-path skill +
    Copilot sync + measurement gate)

All 22 tasks in specs/plans/pd-m4.md are [x].

Verification

  • Pre-commit hard gate: make lint 0 issues, go test ./... green,
    make audit pass.
  • Measurement gate (T20) on a realistic copy and the real rollout (T21):
    18 sections → 5 themes; byte-conservation (every section span present
    in exactly one theme file, none missing/duplicated/leaked), preamble
    byte-exact, bounded root, no broken theme links. Empty-plan re-apply is
    a byte-exact no-op.
  • Dumb-scanner false-boundary path exercised on an adversarial fenced
    fixture: mis-grouped as documented, bytes conserved.
  • Entry-kind (LEARNINGS/DECISIONS) path unchanged — M3 suite green.

… mover, prepend add-path

Design pass for progressive-disclosure milestone 4 (CONVENTIONS). The M3
mover refuses the convention kind; the spec had assumed conventions
accrete as `### ` entries under a `## Recent` staging zone, but the real
CONVENTIONS.md is 18 stable, curated `## ` sections. Resolved:

- Curated-taxonomy model: fold the `## ` sections into a handful of theme
  files; the root keeps `## Themes` gists. Conventions are not an
  accreting stream.
- Unify into the entry-kind path (Approach A): all three kinds share
  preamble | staging | `## Themes`, parametrized by a per-kind entry
  prefix (`## [` vs `## `) and identity (timestamp vs section title).
  Retire parseConvention, ConventionLinePrefix, HeadingRecent (## Recent).
- Dumb line-scanner, no fence detection (a rabbit hole in a destructive
  parser); byte-conservation + the human-gated plan review keep it safe.
  Fail loud on duplicate `## ` titles (ErrDuplicateStagedTitle).
- Convention add-path prepends above `## Themes` (was AppendAtEnd),
  correcting the original inconsistency — decisions/learnings already
  prepend. This deliberately relaxes the spec's "no add-path change"
  non-goal.

Revises specs/progressive-disclosure.md (layout, invariants, tests,
acceptance, non-goals, phasing) and records the decision in DECISIONS.md.
Implementation follows via /ctx-task-out --milestone pd-m4.

Spec: specs/progressive-disclosure.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
Progressive-disclosure milestone 4: teach the mover to digest
CONVENTIONS.md, whose entries are curated `## ` sections rather than
timestamped `## [` entries. Unifies the two parse paths into one,
prefix-parametrized on the per-kind entry marker.

Core (internal/disclosure):
- EntryPrefix(Kind): `## [` for learning/decision, `## ` for convention.
- One parse path (parseRegions); parseConvention deleted, Reconstruct
  de-branched. Convention staging enumerates `## ` sections by title
  identity (no timestamp), skipping the structural `## Themes` and
  HTML-comment examples with a deliberately dumb line scanner.
- Validate generalized to the per-kind prefix; new dup-title fail-loud
  (ErrDuplicateStagedTitle) since a convention's title is its whole
  identity. Retires ConventionLinePrefix / HeadingRecent (`## Recent`).
- Apply digests conventions end-to-end (append→verify→remove, one root
  rewrite); the refusal was derived from ThemeDir, so an explicit gate
  guarded it until the parse/validate paths landed.

Add-path (ctx convention add):
- `--section` is now REQUIRED for conventions and rejects placeholder
  values (TBD, n/a, …): a default section is a catch-all an undecided
  caller dumps everything into. A bullet lands at the top of its H2
  section, which keeps it enumerable and above `## Themes`.
- `--section Themes` declares a theme on all three canonical kinds:
  content is `<name> — <gist>`, and it writes both the gist bullet and
  the theme file, so the gist↔file pairing invariant holds at once.
- Shared build.RequiredBodyFlags exempts theme adds from the per-kind
  body-flag gate; ordinary adds still require their fields.

Skill + real rollout:
- ctx-digest skill gains the convention path, the dup-title guard, and a
  fix to the plan-JSON example (entries are objects, not strings — the
  documented string form failed json.Unmarshal since M3). Copilot synced.
- Real .context/CONVENTIONS.md folded: 18 sections → 5 themes
  (code-style, layout, workflow, docs, cli), root 390 → 22 lines.
  Conservation, invariants, and byte-exact preamble verified.

Bundled (jumbo commit, human-approved — spans specs, primary trailer
below; secondary specs cited inline for traceability):
- build(tooling): exact-pin zensical in the manifest; `make site` gates
  on it via `check-tools.sh --only zensical --strict`, catching drift in
  BOTH directions (behind = regression, ahead = unreviewed). Pin and
  installer read one source of truth. (Spec: specs/check-tools.md)
- build(site): rebuild docs with zensical 0.0.51 and fix a dead blog
  link fragment (#step-5-reindex-after-manual-edits →
  #step-5-project-a-table-of-contents-on-demand). `make site` had been
  silently regenerating every page with whatever generator was on PATH.
- docs: scrub a sibling-project design detail that leaked into the pd-m4
  plan; describe the design on ctx's own merits. (Spec:
  specs/public-repo-hygiene.md)
- test: temp-repo tests set local commit.gpgsign=false so `go test`
  never reaches for the GPG agent and hangs the terminal.

Spec: specs/progressive-disclosure.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
@josealekhine josealekhine self-assigned this Jul 25, 2026
@josealekhine
josealekhine requested a review from bilersan as a code owner July 25, 2026 19:29
@josealekhine
josealekhine merged commit 1a880bf into main Jul 25, 2026
17 checks passed
@josealekhine
josealekhine deleted the design/pd-m4-conventions branch July 25, 2026 19:35
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.

1 participant