Skip to content

Schedule data loop (#54): reusable base — renderer + packaged validator, distributed via remote_theme + pre-commit - #59

Open
WestonVoglesonger wants to merge 5 commits into
ICI3D:masterfrom
WestonVoglesonger:feat/schedule-data-loop-54
Open

Schedule data loop (#54): reusable base — renderer + packaged validator, distributed via remote_theme + pre-commit#59
WestonVoglesonger wants to merge 5 commits into
ICI3D:masterfrom
WestonVoglesonger:feat/schedule-data-loop-54

Conversation

@WestonVoglesonger

@WestonVoglesonger WestonVoglesonger commented Jul 13, 2026

Copy link
Copy Markdown

Implements the #54 flat-data schedule loop as the reusable base in the shared theme repo: a clinic edits one YAML file per cohort, a validator gates it, and a fixed Liquid include renders it. A bad data edit fails validation instead of silently rendering wrong, because no Liquid lives in the edited file.

Distribution: Path A (remote_theme + pre-commit)

Rendering and validation are two independent channels, both served from this repo. A Jekyll theme distributes _includes/_layouts/_sass/assets only, so it carries the renderer but not the Python validator, and not _data. That split is a feature, not a limitation: it forces schedule data and people records to be clinic-owned.

Concern Mechanism Clinic adds
Render schedule.html Jekyll remote_theme remote_theme: ICI3D/ICI3D.github.io + jekyll-remote-theme
Validate schedule data distributed pre-commit hook a .pre-commit-config.yaml entry

No submodule needed on either channel.

What's here (all clinic-agnostic)

  • _includes/schedule.html — shared renderer (Week to Day to Session). Resolves instructor keys against site.data.team, drops shadow: rows in the participant view.
  • ici3d_schedule/ — installable package: the validator (validate.py), the Tier-0 JSON Schema, and the role vocabulary, all as package data. Exposes a validate-schedule console script.
  • .pre-commit-hooks.yaml — the distributed hook clinics pin. Installs the package (schema + roles bundled) and validates the clinic's _data/schedule/*.yml against the shared, versioned schema without vendoring it.
  • .pre-commit-config.yaml + .github/workflows/schedule-validate.yml — this repo runs that same hook locally (pre-commit install) and in CI (pre-commit/action), so local and CI validation are one source of truth.
  • tools/import_schedule.py — wall .md to cohort YAML. tools/validate_schedule.py — thin backward-compat shim over the package.
  • _data/schedule/example/sample.yml — a synthetic example cohort (not a real schedule); documents the format and exercises the validator + renderer in CI.

Verified locally

  • In-repo hook: pre-commit run validate-schedule --all-files passes on the example; fails with clear errors on a broken schedule (bad kind, missing required fields, unresolvable instructor); correctly skips roles.yml.
  • Distributed hook path: built a wheel, installed into a clean venv, ran validate-schedule from a separate clinic-like directory with its own _data/team and no vendored schema/roles — passes on a valid schedule, fails on a broken instructor reference. Schema + roles resolve from bundled package data; instructors resolve from the clinic's own _data/team.
  • Earlier: a real Jekyll build renders the example (1 week / 2 days / 8 visible sessions of 9); a person key resolves to a linked name, role tokens render as labels, the one shadow: row is dropped (0 leaks).

Clinic-owned data (the #56 topology)

Both the renderer (site.data.team) and the validator (--people-dir) read _data/team from the consuming repo, so each clinic owns its schedule data and its faculty records. This settles the data-location question structurally: _data cannot travel via remote_theme, so clinic data lives in the clinic repo by construction.

The .github/actions/validate-schedule/ composite action is left in place transitionally, until clinic repos move to the distributed pre-commit hook.

Part of #54 / epic #58.

…rter, example

Implements the reusable flat-data schedule pipeline from ICI3D#54 in the shared theme
repo, where clinic builds read includes + data from (via the submodule):

- _includes/schedule.html: shared, fixed renderer (Week -> Day -> Session);
  resolves instructor keys against _data/team, drops shadow rows in the
  participant view. Never edited during a clinic.
- schemas/schedule-cohort.schema.json: Tier-0 JSON Schema.
- tools/validate_schedule.py: Tier 0 (schema) + Tier 1 (people resolution,
  non-overlap within track, end>=start). tools/import_schedule.py: wall -> YAML.
- .github/workflows/schedule-validate.yml: PR/push gate on _data/schedule/**.
- _data/schedule/roles.yml: shared role tokens.
- _data/schedule/example/sample.yml: a SYNTHETIC example cohort (not a real
  clinic) so the validator + renderer are exercised in CI and the format is
  documented.

Per-clinic schedule DATA stays OUT of the shared theme: each clinic keeps its own
schedule YAML in its own repo. Where a clinic's build reads that data from is the
ICI3D#56 topology decision.

Verified locally: validator 0 errors / 0 warnings; a real Jekyll build renders the
example (1 week / 2 days / 8 visible sessions of 9), resolves a person key to a
linked name and role tokens to their labels, and drops the shadow row (0 leaks).

Part of ICI3D#54 / epic ICI3D#58.
@WestonVoglesonger
WestonVoglesonger force-pushed the feat/schedule-data-loop-54 branch from a756911 to f0c11d6 Compare July 13, 2026 23:44
@WestonVoglesonger WestonVoglesonger changed the title Schedule data loop (#54): renderer, validator, importer, MMED 2025 data Schedule data loop (#54): reusable base — renderer, validator, importer, example Jul 13, 2026
Wrap tools/validate_schedule.py in a composite action
(.github/actions/validate-schedule) so each clinic repo can run the shared
validator by checking out this repo as a submodule and calling the action --
the validation logic (and schema/roles/people-dir defaults, resolved relative
to the validator's own location) stays maintained once here.

This repo's own schedule-validate.yml now uses the action too, so the theme and
every clinic run the identical check. Verified: the action's invocation matches
_data/schedule/example/sample.yml and validates 0 errors / 0 warnings.
@WestonVoglesonger

Copy link
Copy Markdown
Author

@pearsonca #54 base loop is up as #59: shared renderer + validator packaged as a composite action clinics pull in, plus a synthetic example. Verified locally (validator 0/0; real Jekyll render, instructors resolve, shadow rows dropped).

Two asks: it is a fork PR so the validate check needs an Approve-and-run, and master needs your review to merge.

Scope: base only, no clinic data in the theme (MMED's lives in MMED#26). The last mile (a clinic rendering its own data) waits on your #56 call.

Contributors can now run the schedule validator locally on every commit
(pip install pre-commit && pre-commit install), catching schema and
referential errors before pushing. CI runs the same hook via
pre-commit/action, so local and CI validation share one source of truth
(tools/validate_schedule.py). roles.yml is validator config, not a
schedule document, so it is excluded from the matched files.

The composite action is left in place for now: clinic repos still call it
until they move to the distributed pre-commit hook (follow-up).
Moves the validator, JSON Schema, and role vocabulary into an installable
ici3d_schedule package with a validate-schedule console script and a
.pre-commit-hooks.yaml. Clinic repos can now pin this repo as a pre-commit
hook and validate their schedule data against the shared, versioned schema
without vendoring it (no submodule needed):

  repos:
    - repo: https://github.com/ICI3D/ICI3D.github.io
      rev: <sha>
      hooks:
        - id: validate-schedule

Schema and roles ship as package data resolved relative to the module, so
the same code works pip-installed (distributed hook) and from a repo checkout
(this repo's own hook, CI, transitional composite action). --people-dir now
defaults to _data/team in the working repo, matching the renderer's
site.data.team lookup: instructor records are clinic-owned. tools/
validate_schedule.py is kept as a thin shim for backward compatibility.
Adds ici3d_schedule/README.md describing the two-channel split (Jekyll
remote_theme for rendering, this pre-commit hook for validation) and the
clinic-owned _data/team model, and fixes the workflow comment to point at it
instead of a DESIGN.md that does not exist.
@WestonVoglesonger WestonVoglesonger changed the title Schedule data loop (#54): reusable base — renderer, validator, importer, example Schedule data loop (#54): reusable base — renderer + packaged validator, distributed via remote_theme + pre-commit Jul 17, 2026
WestonVoglesonger added a commit to WestonVoglesonger/MMED that referenced this pull request Jul 17, 2026
Replaces the composite-action-via-submodule workflow with the distributed
pre-commit hook from ICI3D.github.io: MMED pins the hook in
.pre-commit-config.yaml and gets the same validation locally
(pre-commit install) and in CI (pre-commit/action), with the schema and role
vocabulary pulled in from the shared package (no vendoring). Instructor keys
resolve against the shared people records from the ICI3D.github.io submodule
via --people-dir, until MMED owns its own _data/team.

Interim: the hook points at the fork branch until ICI3D/ICI3D.github.io#59
merges; then it flips to the upstream repo at the merge sha.
@WestonVoglesonger

Copy link
Copy Markdown
Author

@pearsonca reshaped this to Path A: ICI3D.github.io is the shared source for both channels, no submodule needed.

  • Rendering: _includes/schedule.html via Jekyll remote_theme.
  • Validation: the validator + schema + roles are now a small installable package (ici3d_schedule) exposed as a pre-commit hook, run the same locally (pre-commit install) and in CI, schema bundled so nothing is vendored.

Since a theme carries _includes but not _data, schedule data and _data/team are clinic-owned by construction, which settles the #56 data-location question.

Tested: in-repo hook passes/fails correctly, and a wheel installed into a clean venv validates a separate clinic-style dir. MMED#26 is the consumer preview. An approve-and-run on CI here unblocks it.

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