From 120c90eb004a922c41b78a70b02973799d355d35 Mon Sep 17 00:00:00 2001 From: Daniel Ari Friedman Date: Tue, 3 Nov 2026 10:01:11 -0800 Subject: [PATCH] docs: add folder-level README and AGENTS guides Cover 22 undocumented authoring directories: CI configuration, the pinned GNN specification, and the src layers (kernels, provenance, artifacts, curriculum plus catalog_data and materials, scholarship, manuscript, figures plus plots, dashboard plus assets, skilltree, pipeline, integration, validation, pilot, publication, screenshots). Add 44 files: 22 README guides and 22 AGENTS guides. Generated output/, .omo evidence, generated docs/todo roadmap pages, captured manuscript screenshots and the vendored SkillTree client are skip-listed with reasons. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> --- .github/AGENTS.md | 10 ++++++++++ .github/README.md | 13 +++++++++++++ .github/workflows/AGENTS.md | 11 +++++++++++ .github/workflows/README.md | 14 ++++++++++++++ gnn/AGENTS.md | 13 +++++++++++++ gnn/README.md | 12 ++++++++++++ src/artifacts/AGENTS.md | 10 ++++++++++ src/artifacts/README.md | 11 +++++++++++ src/curriculum/AGENTS.md | 13 +++++++++++++ src/curriculum/README.md | 18 ++++++++++++++++++ src/curriculum/catalog_data/AGENTS.md | 13 +++++++++++++ src/curriculum/catalog_data/README.md | 13 +++++++++++++ src/curriculum/materials/AGENTS.md | 10 ++++++++++ src/curriculum/materials/README.md | 13 +++++++++++++ src/dashboard/AGENTS.md | 12 ++++++++++++ src/dashboard/README.md | 14 ++++++++++++++ src/dashboard/assets/AGENTS.md | 11 +++++++++++ src/dashboard/assets/README.md | 11 +++++++++++ src/figures/AGENTS.md | 11 +++++++++++ src/figures/README.md | 13 +++++++++++++ src/figures/plots/AGENTS.md | 11 +++++++++++ src/figures/plots/README.md | 11 +++++++++++ src/integration/AGENTS.md | 12 ++++++++++++ src/integration/README.md | 13 +++++++++++++ src/kernels/AGENTS.md | 12 ++++++++++++ src/kernels/README.md | 14 ++++++++++++++ src/manuscript/AGENTS.md | 10 ++++++++++ src/manuscript/README.md | 17 +++++++++++++++++ src/pilot/AGENTS.md | 10 ++++++++++ src/pilot/README.md | 12 ++++++++++++ src/pipeline/AGENTS.md | 11 +++++++++++ src/pipeline/README.md | 13 +++++++++++++ src/provenance/AGENTS.md | 11 +++++++++++ src/provenance/README.md | 13 +++++++++++++ src/publication/AGENTS.md | 10 ++++++++++ src/publication/README.md | 13 +++++++++++++ src/scholarship/AGENTS.md | 10 ++++++++++ src/scholarship/README.md | 13 +++++++++++++ src/screenshots/AGENTS.md | 11 +++++++++++ src/screenshots/README.md | 13 +++++++++++++ src/skilltree/AGENTS.md | 12 ++++++++++++ src/skilltree/README.md | 13 +++++++++++++ src/validation/AGENTS.md | 9 +++++++++ src/validation/README.md | 8 ++++++++ 44 files changed, 528 insertions(+) create mode 100644 .github/AGENTS.md create mode 100644 .github/README.md create mode 100644 .github/workflows/AGENTS.md create mode 100644 .github/workflows/README.md create mode 100644 gnn/AGENTS.md create mode 100644 gnn/README.md create mode 100644 src/artifacts/AGENTS.md create mode 100644 src/artifacts/README.md create mode 100644 src/curriculum/AGENTS.md create mode 100644 src/curriculum/README.md create mode 100644 src/curriculum/catalog_data/AGENTS.md create mode 100644 src/curriculum/catalog_data/README.md create mode 100644 src/curriculum/materials/AGENTS.md create mode 100644 src/curriculum/materials/README.md create mode 100644 src/dashboard/AGENTS.md create mode 100644 src/dashboard/README.md create mode 100644 src/dashboard/assets/AGENTS.md create mode 100644 src/dashboard/assets/README.md create mode 100644 src/figures/AGENTS.md create mode 100644 src/figures/README.md create mode 100644 src/figures/plots/AGENTS.md create mode 100644 src/figures/plots/README.md create mode 100644 src/integration/AGENTS.md create mode 100644 src/integration/README.md create mode 100644 src/kernels/AGENTS.md create mode 100644 src/kernels/README.md create mode 100644 src/manuscript/AGENTS.md create mode 100644 src/manuscript/README.md create mode 100644 src/pilot/AGENTS.md create mode 100644 src/pilot/README.md create mode 100644 src/pipeline/AGENTS.md create mode 100644 src/pipeline/README.md create mode 100644 src/provenance/AGENTS.md create mode 100644 src/provenance/README.md create mode 100644 src/publication/AGENTS.md create mode 100644 src/publication/README.md create mode 100644 src/scholarship/AGENTS.md create mode 100644 src/scholarship/README.md create mode 100644 src/screenshots/AGENTS.md create mode 100644 src/screenshots/README.md create mode 100644 src/skilltree/AGENTS.md create mode 100644 src/skilltree/README.md create mode 100644 src/validation/AGENTS.md create mode 100644 src/validation/README.md diff --git a/.github/AGENTS.md b/.github/AGENTS.md new file mode 100644 index 0000000..a16bdee --- /dev/null +++ b/.github/AGENTS.md @@ -0,0 +1,10 @@ +# AGENTS.md — `.github/` + +- Keep action references pinned to full commit SHAs with the release in a + trailing comment. `dependabot.yml` owns upgrades. +- Keep the offline/live split. Do not add a job that pretends to run the Docker + or browser proofs; those stay local and explicit. +- The `gnn-conformance` job reads its tag and commit from + [`../gnn/upstream.json`](../gnn/upstream.json); do not duplicate the pin here. +- Keep `permissions` least-privilege and `timeout-minutes` bounded. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/.github/README.md b/.github/README.md new file mode 100644 index 0000000..d82e30c --- /dev/null +++ b/.github/README.md @@ -0,0 +1,13 @@ +# `.github/` — repository automation + +`dependabot.yml` declares the dependency-update policy. `workflows/gates.yml` +is the only workflow: it runs the offline gate set and the pinned-GNN +conformance job on pushes to `main`, pull requests and manual dispatch. + +The live Docker + SkillTree + browser proofs are deliberately not simulated +here; see [`workflows/README.md`](workflows/README.md) and the project +[`../AGENTS.md`](../AGENTS.md) gate list. + +Local check before editing a workflow: `uvx ruff check src scripts tests` and +`uv run pytest --cov=src --cov-fail-under=90` cover the same code paths the +offline job runs. diff --git a/.github/workflows/AGENTS.md b/.github/workflows/AGENTS.md new file mode 100644 index 0000000..ff9c3f4 --- /dev/null +++ b/.github/workflows/AGENTS.md @@ -0,0 +1,11 @@ +# AGENTS.md — `.github/workflows/` + +- `gates.yml` is the only workflow. Add a job only when it can run on a hosted + runner; live Docker and browser proofs stay local. +- Keep the `gnn conformance (pinned v5.0.3)` job name. It is the required-check + identity, and the pin must come from `gnn/upstream.json`. +- The conformance lane must fail, never skip, when the pinned fetch or parser + provisioning fails. +- Mirror local commands; the offline job should not invent a stricter command + that `AGENTS.md` does not document. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 0000000..f2fea07 --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,14 @@ +# `.github/workflows/` — CI jobs + +`gates.yml` defines two jobs: + +- `gates` — locked sync, Ruff check/format, mypy, curriculum and artifact + builds, the provenance/scholarship/manuscript validators, and the test suite + with the 90% coverage floor. +- `gnn conformance (pinned v5.0.3)` — fetches the commit in + [`../../gnn/upstream.json`](../../gnn/upstream.json), provisions its own + Python 3.12 environment, validates the specification, and runs + `tests/test_gnn_conformance.py`. + +Live Docker, SkillTree and browser proofs are not run here. The job names are +the required checks; keep them stable when editing. diff --git a/gnn/AGENTS.md b/gnn/AGENTS.md new file mode 100644 index 0000000..b2d4b8c --- /dev/null +++ b/gnn/AGENTS.md @@ -0,0 +1,13 @@ +# AGENTS.md — `gnn/` + +- `discrete_active_inference_agent.gnn.md` and + [`../src/kernels/active_inference.py`](../src/kernels/active_inference.py) are + one contract. Change them together, with + [`../src/gnn_conformance.py`](../src/gnn_conformance.py) and + [`../tests/test_gnn_conformance.py`](../tests/test_gnn_conformance.py). +- Read the pin from `upstream.json`; never read a GNN checkout's working tree. + The validator extracts the recorded commit with `git archive`. +- A pin change needs a fresh conformance run: + `uv run python scripts/validate_gnn_spec.py` and + `uv run pytest tests/test_gnn_conformance.py -q`. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/gnn/README.md b/gnn/README.md new file mode 100644 index 0000000..ff36917 --- /dev/null +++ b/gnn/README.md @@ -0,0 +1,12 @@ +# `gnn/` — pinned GNN specification + +`discrete_active_inference_agent.gnn.md` is the Generalized Notation Notation +specification of the discrete-agent kernel's generative model. +`upstream.json` records the parser pin: repository +`ActiveInferenceInstitute/Generalized_Notation_Notation`, tag `v5.0.3`, commit +`8f293d9ba810e6eda5c09842d9c7ed9ffa5f92c1`. + +`scripts/validate_gnn_spec.py` extracts that pinned commit with `git archive` +and validates the specification. `tests/test_gnn_conformance.py` checks the +specification against [`../src/kernels/active_inference.py`](../src/kernels/active_inference.py). +CI runs both in `gnn conformance (pinned v5.0.3)`. diff --git a/src/artifacts/AGENTS.md b/src/artifacts/AGENTS.md new file mode 100644 index 0000000..1da01ae --- /dev/null +++ b/src/artifacts/AGENTS.md @@ -0,0 +1,10 @@ +# AGENTS.md — `src/artifacts/` + +- Write atomically, through `json_io.write_json_artifact`; do not scatter + `json.dump` calls through producers. +- Keep output deterministic: sorted keys, stable separators, no wall-clock + timestamps or machine paths unless the payload schema explicitly owns them. +- Add or change a stable payload in `contracts.py` first, then update every + reader. Consumers type their inputs with these `TypedDict` shapes. +- A malformed payload fails at the write boundary, not when a figure renders. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/artifacts/README.md b/src/artifacts/README.md new file mode 100644 index 0000000..ea75156 --- /dev/null +++ b/src/artifacts/README.md @@ -0,0 +1,11 @@ +# `src/artifacts/` — deterministic JSON artifacts + +`json_io.py` provides read/write helpers for JSON objects and arrays, including +`write_json_artifact`. `contracts.py` declares the `TypedDict` payload shapes +shared by figure and dashboard consumers. + +Artifacts are the boundary between producers (validators, figure renderers) and +readers (figures, dashboard, manuscript variables). Writers sort keys and omit +timestamps by default so rebuilds are byte-identical. + +Parent guide: [`../AGENTS.md`](../AGENTS.md). diff --git a/src/curriculum/AGENTS.md b/src/curriculum/AGENTS.md new file mode 100644 index 0000000..48934ed --- /dev/null +++ b/src/curriculum/AGENTS.md @@ -0,0 +1,13 @@ +# AGENTS.md — `src/curriculum/` + +- Keep the graph acyclic and fully connected foundations→applications. Roots + stay in `MATH_FOUNDATIONS` and `PROBABILITY`; ids stay unique and + prerequisites must resolve. +- Add skills as data in `catalog_data/` or an `_ext_*.py` module, not in + `graph.py`. Use the `_s`/`_q` shorthands from `authoring.py`. +- Any learner-facing number is a `{{claim:NAME}}` token. Author input values + inside `$...$` math; the bare-number linter must stay green. +- Imports are `src.*` only. A bare `curriculum.` import creates a second module + identity and breaks the DAG types. +- Run `uv run python scripts/build_curriculum.py` after edits, plus the + curriculum tests. Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/curriculum/README.md b/src/curriculum/README.md new file mode 100644 index 0000000..40b10de --- /dev/null +++ b/src/curriculum/README.md @@ -0,0 +1,18 @@ +# `src/curriculum/` — the validated prerequisite DAG + +`model.py` defines the frozen `Stratum`, `Subject`, `Skill` and +`AssessmentQuestion` types. `graph.py` owns `CurriculumGraph` validation, +topological order, levels and the foundations→applications connectivity check. +`catalog.py` is the entry point: `build_curriculum()` assembles the subjects and +runs `quality.py`. + +Subject content lives in [`catalog_data/`](catalog_data/); the many `_ext_*.py` +modules are curriculum extensions aggregated by +`catalog_data/subjects_extensions_*.py`. `normalize.py` and +`assessment_normalize.py` harden authored data; `diagnostics.py`, +`recommendations.py`, `alignment.py` and `vfe_efe_bridge.py` derive read-only +views. + +Build: `uv run python scripts/build_curriculum.py`. +Parent guide: [`../AGENTS.md`](../AGENTS.md). Architecture: +[`../../docs/architecture.md`](../../docs/architecture.md). diff --git a/src/curriculum/catalog_data/AGENTS.md b/src/curriculum/catalog_data/AGENTS.md new file mode 100644 index 0000000..a2687b8 --- /dev/null +++ b/src/curriculum/catalog_data/AGENTS.md @@ -0,0 +1,13 @@ +# AGENTS.md — `src/curriculum/catalog_data/` + +- Append skills with `_s(...)`/`_q(...)`. Give each a unique `skill_id`, a + stratum, an objective, and prerequisites that already exist. +- Every description number is a claim token. No literal result values. +- Keep `assembly.py` thin; subject construction belongs in the `subjects_*` + modules and their aggregated `_ext_*` sources. +- Do not add graph rules here. Validation belongs in `../graph.py` and + `../quality.py`. +- Rebuild and test after edits: + `uv run python scripts/build_curriculum.py` then + `uv run pytest tests/test_curriculum_catalog.py -q`. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/curriculum/catalog_data/README.md b/src/curriculum/catalog_data/README.md new file mode 100644 index 0000000..dce0a0d --- /dev/null +++ b/src/curriculum/catalog_data/README.md @@ -0,0 +1,13 @@ +# `src/curriculum/catalog_data/` — authored curriculum data + +`assembly.py` exposes the thin `build_subject_list()`. `core_strata.py` holds +the inline stratum tuples; `subjects_canopy.py` shapes the subject tree. The +`subjects_extensions_*.py` modules aggregate the `_ext_*.py` extension modules +that sit one level up in [`..`](..). + +This is the directory to edit when adding or changing a skill. `_s` and `_q` +come from [`../authoring.py`](../authoring.py); graph validation stays in +[`../graph.py`](../graph.py). + +Build: `uv run python scripts/build_curriculum.py`. +Parent guide: [`../AGENTS.md`](../AGENTS.md). diff --git a/src/curriculum/materials/AGENTS.md b/src/curriculum/materials/AGENTS.md new file mode 100644 index 0000000..9d6fe3b --- /dev/null +++ b/src/curriculum/materials/AGENTS.md @@ -0,0 +1,10 @@ +# AGENTS.md — `src/curriculum/materials/` + +- Every material row needs a resolvable source in + `data/course_material_sources.yaml`; do not invent a URL or a commit. +- Keep records read-only projections of the graph and source catalog. No learner + progress, ranking or completion state belongs here. +- Validation is fail-closed: an unaligned skill, quiz or material must fail + `scripts/validate_course_material_alignment.py`. +- Keep the JSON shape stable; the dashboard and manuscript variables read it. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/curriculum/materials/README.md b/src/curriculum/materials/README.md new file mode 100644 index 0000000..20750c7 --- /dev/null +++ b/src/curriculum/materials/README.md @@ -0,0 +1,13 @@ +# `src/curriculum/materials/` — local Learn records + +Builds the modular dashboard "Learn" records from the curriculum graph and +`data/course_material_sources.yaml`. `builders.py` assembles records, +`validation.py` checks them, `github_sources.py` resolves pinned GitHub +citations, and `models.py`/`helpers.py` hold the shared types. + +The contract keeps material sources traceable to a real URL or commit while +leaving learner state to SkillTree. The validation entry point is +`write_course_material_artifacts`. + +Check: `uv run python scripts/validate_course_material_alignment.py`. +Parent guide: [`../AGENTS.md`](../AGENTS.md). diff --git a/src/dashboard/AGENTS.md b/src/dashboard/AGENTS.md new file mode 100644 index 0000000..c39e18f --- /dev/null +++ b/src/dashboard/AGENTS.md @@ -0,0 +1,12 @@ +# AGENTS.md — `src/dashboard/` + +- Keep payload shapes stable. `/api/status`, `/api/course-materials`, graph, + artifact and SkillTree-link responses have contract tests; change both sides + together. +- The CSP starts at `default-src 'none'` and must keep the SkillTree origin in + `frame-src` and its `ws://`/`wss://` origin in `connect-src`. +- `?defer_live=1` skips only the live parity round trip. Never let a deferred + block read as a passed check; validators use the default path. +- Bind loopback only. Do not add a remote host default or an app-owned login. +- Parent rules: [../AGENTS.md](../AGENTS.md). Design tokens: + [`../../DESIGN.md`](../../DESIGN.md). diff --git a/src/dashboard/README.md b/src/dashboard/README.md new file mode 100644 index 0000000..de1f195 --- /dev/null +++ b/src/dashboard/README.md @@ -0,0 +1,14 @@ +# `src/dashboard/` — local learner dashboard + +A read-only shell over generated artifacts and official SkillTree views. +`server.py` is the small HTTP server; `payload.py`, `status.py` and +`artifacts.py` build its JSON; `artifact_catalog.py` and `figure_metadata.py` +register the evidence surfaces; `graph_analysis.py` serves the additive graph +recommendation; `live_validation.py` runs the live parity check. + +SkillTree owns progress, ranking, quizzes and learner records. The dashboard +must not become a second implementation or an app-owned authentication layer. +The static frontend lives in [`assets/`](assets/). + +Run: `uv run python scripts/serve_learner_dashboard.py`. +Parent guide: [`../AGENTS.md`](../AGENTS.md). diff --git a/src/dashboard/assets/AGENTS.md b/src/dashboard/assets/AGENTS.md new file mode 100644 index 0000000..01b94c1 --- /dev/null +++ b/src/dashboard/assets/AGENTS.md @@ -0,0 +1,11 @@ +# AGENTS.md — `src/dashboard/assets/` + +- No frontend framework, bundler or npm dependency. Keep this surface vanilla and + directly servable. +- Read [`../../../DESIGN.md`](../../../DESIGN.md) before styling; use declared CSS + tokens, not raw colors. +- Do not rename payload keys or reshape a response from the browser side alone. + Update `src/dashboard/` and its tests in the same change. +- Treat `vendor/skills-client-js.esm.min.js` as third-party. Do not edit it by + hand; replace it only with a reviewed upstream build. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/dashboard/assets/README.md b/src/dashboard/assets/README.md new file mode 100644 index 0000000..97b6587 --- /dev/null +++ b/src/dashboard/assets/README.md @@ -0,0 +1,11 @@ +# `src/dashboard/assets/` — dashboard frontend + +`index.html`, `app.js` and `styles.css` are the vanilla HTML/CSS/JS learner +dashboard. `vendor/skills-client-js.esm.min.js` is the pinned official +SkillTree client; it is vendored, not built. + +The frontend renders the payloads from [`..`](..) and embeds the official +SkillTree display. It follows the root [`../../../DESIGN.md`](../../../DESIGN.md) +token contract and has no npm build step. + +Parent guide: [`../AGENTS.md`](../AGENTS.md). diff --git a/src/figures/AGENTS.md b/src/figures/AGENTS.md new file mode 100644 index 0000000..72f1b92 --- /dev/null +++ b/src/figures/AGENTS.md @@ -0,0 +1,11 @@ +# AGENTS.md — `src/figures/` + +- Keep rendering deterministic and headless. Set `MPLBACKEND=Agg`; do not open a + window or read the clock for a label. +- Numeric inputs come from the graph or a validated audit payload. No hardcoded + results in a renderer. +- A new figure needs a registry row, filename, caption, alt text and semantic + metadata; the manuscript audit cross-checks them. +- Keep `figure_registry.json` and the dashboard artifact catalog in step; both + name the same files. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/figures/README.md b/src/figures/README.md new file mode 100644 index 0000000..651e5c6 --- /dev/null +++ b/src/figures/README.md @@ -0,0 +1,13 @@ +# `src/figures/` — figure registry and renderers + +`registry.py` loads the typed figure registry and its chart contract; +`registry_manifest.py` holds the canonical rows and semantic overrides; +`table_companions.py` emits the table companions. The renderers live in +[`plots/`](plots/). + +`plots.render_all()` writes the PNGs and `figure_registry.json`. Numeric inputs +come from the curriculum graph and the validated audit payloads, never from +literals in a renderer. Rendering is headless (`Agg`). + +Check: `uv run pytest tests/test_figures.py -q`. +Parent guide: [`../AGENTS.md`](../AGENTS.md). diff --git a/src/figures/plots/AGENTS.md b/src/figures/plots/AGENTS.md new file mode 100644 index 0000000..f88478f --- /dev/null +++ b/src/figures/plots/AGENTS.md @@ -0,0 +1,11 @@ +# AGENTS.md — `src/figures/plots/` + +- One renderer per registered figure. Register it in `registry.py`; do not add a + second filename or caption rule here. +- Use `style.py` tokens and the headless backend. No random, date or + environment-dependent labels. +- Read inputs through `FigureRenderContext`; do not reach into another package's + private state. +- A renderer change that moves a label, filename or caption must update the + manuscript declaration and dashboard artifact in the same change. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/figures/plots/README.md b/src/figures/plots/README.md new file mode 100644 index 0000000..a61ac44 --- /dev/null +++ b/src/figures/plots/README.md @@ -0,0 +1,11 @@ +# `src/figures/plots/` — figure renderers + +One module per figure family: `curriculum.py`, `kernels.py`, +`scholarship_coverage.py`, `scholarship_source_map.py`, +`scholarship_source_health.py`, `front_matter_cover.py`, +`front_matter_atlas.py`, `graph_diagnostics.py`, `roadmap.py` and +`validation.py`. `registry_io.py` owns `FigureRenderContext` and `render_all()`; +`style.py` holds the shared palette; `registry_helpers.py` and +`validation_data.py`/`validation_intent.py` support the registry and its checks. + +Parent guide: [`../AGENTS.md`](../AGENTS.md). diff --git a/src/integration/AGENTS.md b/src/integration/AGENTS.md new file mode 100644 index 0000000..497b9e1 --- /dev/null +++ b/src/integration/AGENTS.md @@ -0,0 +1,12 @@ +# AGENTS.md — `src/integration/` + +- This is a live proof, not a unit test. Do not make a green offline run imply + that Docker or the browser proof ran. +- Bind local services to loopback. Never add a public host default, a remote + URL or a deployment helper here. +- Restart a stale browser session at most once, as + `ensure_browser_session_responsive` does; then fail with the named harness + cause. +- Do not duplicate dashboard, SkillTree or curriculum logic. Call the owning + package and assert on its real output. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/integration/README.md b/src/integration/README.md new file mode 100644 index 0000000..e46d11c --- /dev/null +++ b/src/integration/README.md @@ -0,0 +1,13 @@ +# `src/integration/` — live-stack orchestration + +`full_app_stack.py` brings up and checks the live proof: Docker services, +SkillTree and the local learner dashboard. It owns orchestration only; the +dashboard payload, SkillTree client and curriculum logic stay in their packages. + +`ensure_browser_session_responsive` probes the browser automation daemon and +restarts it once before a browser proof, so a stale session is reported as a +harness problem rather than an application failure. + +Driver: `scripts/validate_full_app_stack.py`. Parent guide: +[`../AGENTS.md`](../AGENTS.md). This proof needs a Docker daemon and a browser; +CI does not run it. diff --git a/src/kernels/AGENTS.md b/src/kernels/AGENTS.md new file mode 100644 index 0000000..c5ca7f4 --- /dev/null +++ b/src/kernels/AGENTS.md @@ -0,0 +1,12 @@ +# AGENTS.md — `src/kernels/` + +- Keep every function pure: inputs in, values out, no file, network or global + state. Rendering and writes belong in `figures/` and `scripts/`. +- Units are nats. Keep the existing guards against negative, unnormalized and + non-finite inputs; a new guard needs a test that rejects the bad input. +- No bare `kernels.` imports. Use `from src.kernels. import ...`. +- Every learner-facing number comes from `examples.build_claim_registry()`, + referenced as `{{claim:NAME}}`; never hardcode a result in a skill. +- Kernel changes land with a real-value test asserting an analytic identity, + not a smoke call. Seed any RNG with `numpy.random.default_rng`. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/kernels/README.md b/src/kernels/README.md new file mode 100644 index 0000000..5b000ef --- /dev/null +++ b/src/kernels/README.md @@ -0,0 +1,14 @@ +# `src/kernels/` — pure Active Inference math + +Deterministic NumPy/SciPy functions in nats. This package is the only source of +quantitative values used in learner-facing content. + +- `information.py` — entropy, KL divergence, cross-entropy, mutual information, surprise. +- `distributions.py` — softmax, normalize, stable logs, Dirichlet expectations. +- `inference.py` — Bayes posterior, variational free energy, log evidence, ELBO. +- `active_inference.py` — expected free energy, policy posterior, `DiscreteActiveInferenceAgent`. +- `predictive_coding.py` — precision-weighted descent to the analytic minimum. +- `examples.py` — fixed-input worked examples and `build_claim_registry()`. + +Check: `uv run pytest tests/test_kernels_*.py -q`. +Parent guide: [`../AGENTS.md`](../AGENTS.md). GNN specification: [`../../gnn/README.md`](../../gnn/README.md). diff --git a/src/manuscript/AGENTS.md b/src/manuscript/AGENTS.md new file mode 100644 index 0000000..63d0241 --- /dev/null +++ b/src/manuscript/AGENTS.md @@ -0,0 +1,10 @@ +# AGENTS.md — `src/manuscript/` + +- Keep every audit fail-closed. Do not add an allowlist or a warning-only path to + turn a real manuscript defect green. +- Numbers in prose are tokens, never literals. A changed count is regenerated, + not hand-edited. +- A new figure needs its registry row, caption, alt text, semantic metadata and + manuscript declaration; the audit checks all of them. +- Keep the prose American English; the validator is intentional. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/manuscript/README.md b/src/manuscript/README.md new file mode 100644 index 0000000..2d5db29 --- /dev/null +++ b/src/manuscript/README.md @@ -0,0 +1,17 @@ +# `src/manuscript/` — manuscript surface validation + +- `audit.py` — validates `figure_registry.json` against manuscript figure + declarations, `[@fig:...]` references, readable PNGs, caption/alt text, + semantic metadata and dashboard artifacts; writes `manuscript_artifacts.json`. +- `claim_support.py` — validates `claim-support` anchors against evidence + classes, citations, variables, claim tokens, figures and limitations. +- `variables.py` — keeps generated counts bound to tokens, not prose literals. +- `american_english.py` — rejects British spelling variants in authored prose. +- `web_math.py` — checks rendered HTML that carries math loads MathJax. + +Drivers: `scripts/validate_manuscript_artifacts.py`, +`scripts/validate_claim_support.py`, `scripts/validate_manuscript_variables.py`, +`scripts/validate_american_english.py`. + +Parent guide: [`../AGENTS.md`](../AGENTS.md). Writing rules: +[`../../docs/agent_instructions.md`](../../docs/agent_instructions.md). diff --git a/src/pilot/AGENTS.md b/src/pilot/AGENTS.md new file mode 100644 index 0000000..d575a75 --- /dev/null +++ b/src/pilot/AGENTS.md @@ -0,0 +1,10 @@ +# AGENTS.md — `src/pilot/` + +- Keep the contract protocol-only. Do not add learner records, identifiers, + storage or an outcome claim. +- Validation stays fail-closed: missing privacy, feasibility or missing-data + fields raise `PilotContractError`. +- Read-only SkillTree exports only. No writes, no live calls from validation. +- Change the schema and [`../../docs/pilot/`](../../docs/pilot/) together, with + a test for both the accepted and rejected shape. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/pilot/README.md b/src/pilot/README.md new file mode 100644 index 0000000..1e2cd8c --- /dev/null +++ b/src/pilot/README.md @@ -0,0 +1,12 @@ +# `src/pilot/` — learner-pilot protocol contract + +`contract.py` validates the protocol-only learner-pilot contract: +`load_pilot_contract()` reads a JSON object and `validate_pilot_contract()` +checks that the protocol is measurable, privacy-bounded and non-causal. Failures +raise `PilotContractError`. + +The package stores no learner state and makes no efficacy claim. The schema and +privacy boundary are documented in [`../../docs/pilot/`](../../docs/pilot/). + +Check: `uv run python scripts/validate_learner_pilot_contract.py`. +Parent guide: [`../AGENTS.md`](../AGENTS.md). diff --git a/src/pipeline/AGENTS.md b/src/pipeline/AGENTS.md new file mode 100644 index 0000000..af87e6f --- /dev/null +++ b/src/pipeline/AGENTS.md @@ -0,0 +1,11 @@ +# AGENTS.md — `src/pipeline/` + +- Keep this package importable and argument-free. CLI parsing, stdout and exit + codes belong in `scripts/`. +- Call the owning package for each artifact; do not duplicate kernel, figure, + curriculum or scholarship logic here. +- Writes go through `src.artifacts.json_io` and stay deterministic. Do not add + timestamps or machine paths to a payload. +- Rebuilding the full artifact set must remain safe to run repeatedly and must + not require the live SkillTree stack. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/pipeline/README.md b/src/pipeline/README.md new file mode 100644 index 0000000..6d6f684 --- /dev/null +++ b/src/pipeline/README.md @@ -0,0 +1,13 @@ +# `src/pipeline/` — importable artifact builders + +`generated_outputs.py` builds the project's derived artifacts in one place: +the claim ledger, deterministic figures and table companions, dashboard +artifact payloads, course-material records, and the audit JSON that figures and +the dashboard consume. It calls the owning packages rather than reimplementing +their logic. + +`scripts/run_kernels.py` is the thin CLI wrapper: it parses arguments, calls +this package, and maps the result to a process status. + +Parent guide: [`../AGENTS.md`](../AGENTS.md). Output layout: +[`../../docs/output_conventions.md`](../../docs/output_conventions.md). diff --git a/src/provenance/AGENTS.md b/src/provenance/AGENTS.md new file mode 100644 index 0000000..dc03326 --- /dev/null +++ b/src/provenance/AGENTS.md @@ -0,0 +1,11 @@ +# AGENTS.md — `src/provenance/` + +- Fail closed. An unbacked, empty or malformed `{{claim:NAME}}` token is an + error, never a blank substitution. +- Re-registering a claim with a different value or provenance must keep raising. + String claims must not contain digits. +- Scan every learner-facing field, not only the description. Add the new field + to `Skill.claim_tokens()` and to the render tests. +- Never hand-type a computed result into content; add the worked example in + `kernels/examples.py` and reference the claim. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/provenance/README.md b/src/provenance/README.md new file mode 100644 index 0000000..2829939 --- /dev/null +++ b/src/provenance/README.md @@ -0,0 +1,13 @@ +# `src/provenance/` — claim registry and token binding + +`claims.py` holds `ClaimRegistry`, which records named numeric claims with +units, source and description. `binding.py` substitutes `{{claim:NAME}}` tokens, +fails closed on unbacked or malformed tokens, and lints bare decimal result +numbers in learner-facing prose. + +The chain is: kernel example registers a claim, skill content references the +token, and export fails if the token cannot resolve. `output/data/claims.json` +is the emitted ledger. + +Check: `uv run pytest tests/test_provenance.py -q`. +Parent guide: [`../AGENTS.md`](../AGENTS.md). diff --git a/src/publication/AGENTS.md b/src/publication/AGENTS.md new file mode 100644 index 0000000..d60f94c --- /dev/null +++ b/src/publication/AGENTS.md @@ -0,0 +1,10 @@ +# AGENTS.md — `src/publication/` + +- Never publish implicitly. Do not add a publish call, a background request or a + side effect on import. +- Read the token from `ZENODO_PROD_TOKEN`; never commit, log or echo it. +- Network calls need an explicit operation, a bounded timeout and a typed error. + Tests use a local server or a stub, never the real Zenodo API. +- A new release action needs a test proving the no-op path writes and sends + nothing. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/publication/README.md b/src/publication/README.md new file mode 100644 index 0000000..cdde32d --- /dev/null +++ b/src/publication/README.md @@ -0,0 +1,13 @@ +# `src/publication/` — release boundary + +`zenodo.py` reserves a Zenodo concept DOI for an unpublished draft and reads the +token from `ZENODO_PROD_TOKEN`. It deliberately has no publish call: minting a +live DOI is an outward-facing action for a human running release tooling, not a +build step. + +The module talks to `https://zenodo.org/api` with a 60-second timeout and raises +`ZenodoError` on an unusable response. Nothing here runs during tests, imports or +artifact builds. + +Parent guide: [`../AGENTS.md`](../AGENTS.md). Release status: +[`../../docs/publication_readiness.md`](../../docs/publication_readiness.md). diff --git a/src/scholarship/AGENTS.md b/src/scholarship/AGENTS.md new file mode 100644 index 0000000..24a69e1 --- /dev/null +++ b/src/scholarship/AGENTS.md @@ -0,0 +1,10 @@ +# AGENTS.md — `src/scholarship/` + +- Every authored citation resolves to a BibTeX entry and a source-role row. A + missing row is a failure, not an "unclassified" pass. +- Keep network health separate from coverage. A dead link is reported in its own + bucket; it does not silently satisfy or fail the role matrix. +- Never downgrade a specific source role to a generic one to make a gate green. +- The audit JSON is deterministic. Sort rows and omit timestamps. +- Run `uv run python scripts/analyze_scholarship.py` after citation edits. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/scholarship/README.md b/src/scholarship/README.md new file mode 100644 index 0000000..2e75927 --- /dev/null +++ b/src/scholarship/README.md @@ -0,0 +1,13 @@ +# `src/scholarship/` — citation source-role coverage + +`coverage.py` parses the authored manuscript citations, resolves them against +`manuscript/references.bib`, checks each one against a source-role row in +`data/scholarship_sources.yaml`, and writes `scholarship_coverage.json`. +`source_health.py`, `source_health_network.py` and `source_health_report.py` +separate locator and role problems from dead-link and bot-block results. +`frontier_sources.py` and `gap_report.py` keep frontier and boundary support out +of the genuine source-health bucket. + +Build: `uv run python scripts/analyze_scholarship.py`. +Parent guide: [`../AGENTS.md`](../AGENTS.md). Method: +[`../../docs/scholarship_coverage.md`](../../docs/scholarship_coverage.md). diff --git a/src/screenshots/AGENTS.md b/src/screenshots/AGENTS.md new file mode 100644 index 0000000..75cf2cb --- /dev/null +++ b/src/screenshots/AGENTS.md @@ -0,0 +1,11 @@ +# AGENTS.md — `src/screenshots/` + +- These pixels are live-browser evidence. Never hand-edit a PNG or + `screenshot_provenance.json`; rerun the capture instead. +- Keep the viewport and view list in `manifest.py` stable. A new view needs its + registry row, dashboard artifact entry and manuscript consumer. +- Capture only a local, explicitly started stack. Do not point it at a remote + host or store credentials in the provenance record. +- Keep the capture deterministic where it can be: fixed viewport, fixed route, + explicit readiness wait. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/screenshots/README.md b/src/screenshots/README.md new file mode 100644 index 0000000..99f903c --- /dev/null +++ b/src/screenshots/README.md @@ -0,0 +1,13 @@ +# `src/screenshots/` — captured dashboard evidence + +`manifest.py` defines the fixed capture views and their chart-contract metadata. +`capture.py` drives a live local dashboard through the browser automation and +writes PNGs plus `screenshot_provenance.json`. `staging.py` prepares the capture +inputs. + +Captures land in `manuscript/assets/screenshots/` at a pinned 1440×900 viewport; +the figure registry and dashboard artifact catalog register those exact paths. +The rows are evidence from a running stack, not deterministic renders. + +Driver: `scripts/capture_dashboard_screenshots.py`. +Parent guide: [`../AGENTS.md`](../AGENTS.md). diff --git a/src/skilltree/AGENTS.md b/src/skilltree/AGENTS.md new file mode 100644 index 0000000..9162b63 --- /dev/null +++ b/src/skilltree/AGENTS.md @@ -0,0 +1,12 @@ +# AGENTS.md — `src/skilltree/` + +- No mocks. Test the REST client and seeder against a real local server + (`pytest-httpserver`), asserting path, method, headers and body. +- Seed in dependency-safe order: quizzes before quiz-gated skills, dependencies + after skills. Do not reorder for convenience. +- Judge a reconciliation by `missingAfter`/`extraAfter`, not by retry counters. + A late write confirmed by a re-read is `confirmedAfterTimeout`, not a failure. +- Read tokens from the caller or environment; never write a credential, cookie + or session token into an artifact or test fixture. +- Keep browser automation out of the pure FORM helpers. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/skilltree/README.md b/src/skilltree/README.md new file mode 100644 index 0000000..1af475a --- /dev/null +++ b/src/skilltree/README.md @@ -0,0 +1,13 @@ +# `src/skilltree/` — SkillTree export and live client + +`model.py` holds the SkillTree project/subject/skill/quiz dataclasses. +`exporter.py` projects the curriculum graph to that model; `seeder.py` creates +project → subjects → quizzes → skills → dependencies in order. +`client.py`, `transport.py` and `admin_ops.py` are the REST boundary; +`dependency_reconciler.py` checks live prerequisite edges. +`form_login_core.py`/`form_login_validation.py` and +`local_auth.py`/`local_auth_state.py` own the local FORM bootstrap. +`deployment_matrix.py` describes the browser-safe deployment modes. + +Export: `uv run python scripts/export_skilltree.py`. Seed and reconcile need a +live instance. Parent guide: [`../AGENTS.md`](../AGENTS.md). diff --git a/src/validation/AGENTS.md b/src/validation/AGENTS.md new file mode 100644 index 0000000..24a7b78 --- /dev/null +++ b/src/validation/AGENTS.md @@ -0,0 +1,9 @@ +# AGENTS.md — `src/validation/` + +- Keep `Finding` frozen and its fields stable; reports depend on + `code at location: message`. +- Add gate-specific issue types as `IssueLike` objects and adapt them with + `finding_from_issue()` rather than changing `Finding`. +- No printing or exiting here. Return findings; the calling script owns the + process status. +- Parent rules: [../AGENTS.md](../AGENTS.md). diff --git a/src/validation/README.md b/src/validation/README.md new file mode 100644 index 0000000..2ccd211 --- /dev/null +++ b/src/validation/README.md @@ -0,0 +1,8 @@ +# `src/validation/` — shared finding type + +`finding.py` defines the frozen `Finding` dataclass (`code`, `location`, +`message`), the structural `IssueLike` protocol, and `finding_from_issue()`. +Gate dataclasses across the project adapt their issues to this shape so one +report renderer can print them. + +Parent guide: [`../AGENTS.md`](../AGENTS.md).