From 5b7342580283fbb1dab6a3f56bcf59277ec37dbd Mon Sep 17 00:00:00 2001 From: Aron T Date: Tue, 29 Sep 2026 11:52:27 +0300 Subject: [PATCH 1/2] Adopt the hub's shared instruction templates; bridge them into Claude Code - Shared files (ecosystem, source, testing, docs, notebooks) copied unchanged from math_tech_study project_resources (#32); byte-identical, checked with cmp. - project.instructions.md is now this repo's own file: the CWJS dependency, planned function categories, test files and the real notebook setup (`using Revise` + `using Calculus`). The old notebooks file described an LAlatex/BlockArrays setup this repo's notebook environment does not have; the old testing file named Linear_Algebra.jl as the module. - copilot-instructions.md regenerated from the corrected canonical template with the "What CalculusWithJuliaSquared Provides" section kept: `gh` works (the ban was false), Azure section removed, communication rules as the marked Copilot mirror. Reexport lists corrected: LaTeXStrings comes through CWJS, not a second reexport here; Latexify added to the notebooks row. - New CLAUDE.md (shared template). julia compat is already 1.13 in all four environments; no bump needed. Co-Authored-By: Claude Opus 5.5 --- .github/copilot-instructions.md | 64 ++------ .github/instructions/docs.instructions.md | 16 +- .../instructions/ecosystem.instructions.md | 110 ++++++++++++++ .../instructions/notebooks.instructions.md | 101 ++++--------- .github/instructions/project.instructions.md | 118 +++++++-------- .github/instructions/source.instructions.md | 86 ++++++----- .github/instructions/testing.instructions.md | 140 ++++++------------ CLAUDE.md | 29 ++++ 8 files changed, 344 insertions(+), 320 deletions(-) create mode 100644 .github/instructions/ecosystem.instructions.md create mode 100644 CLAUDE.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 973c9b6..1f18c89 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -8,14 +8,14 @@ ### Core Architecture -- **`src/Calculus.jl`**: Main module; uses `@reexport` to re-export `CalculusWithJuliaSquared` and `LaTeXStrings` — consumers get all exported names with a single `using Calculus` +- **`src/Calculus.jl`**: Main module; uses `@reexport` to re-export `CalculusWithJuliaSquared` (which brings `LaTeXStrings` and the rest with it) — consumers get all exported names with a single `using Calculus` - **`test/`**: Tests using `Calculus` and `Test` only — re-exported names are available via `@reexport`, no explicit `using` needed in test files - **`docs/`**: Documenter.jl deploying to `https://fourm.info/calculus/` (cross-repo to `math_tech_study`) - **`notebooks/`**: Jupyter notebooks for exploration (not tested in CI) ### What CalculusWithJuliaSquared Provides -[`CalculusWithJuliaSquared`](https://github.com/FourMInfo/CalculusWithJuliaSquared.jl) is a personal, pure-Julia (zero-Python) fork of `CalculusWithJulia.jl`. It's **unregistered**, so its GitHub URL is declared in `Project.toml`'s `[sources]` section — required because Manifests are gitignored here, and without `[sources]` a clean clone (e.g. CI) tries the General registry and fails. Keep that section intact. It reexports `Plots`, `Symbolics`, `Roots`, `LinearAlgebra`, `SpecialFunctions`, and `IntervalSets`, and auto-configures the GR backend for headless CI at load time — so this repo needs **no direct `Plots` dependency and no GKS setup of its own**. Available after `using Calculus`: +[`CalculusWithJuliaSquared`](https://github.com/FourMInfo/CalculusWithJuliaSquared.jl) is a personal, pure-Julia (zero-Python) fork of `CalculusWithJulia.jl`. It's **unregistered**, so its GitHub URL is declared in `Project.toml`'s `[sources]` section — required because Manifests are gitignored here, and without `[sources]` a clean clone (e.g. CI) tries the General registry and fails. Keep that section intact. It reexports `Plots`, `Symbolics`, `Roots`, `LinearAlgebra`, `SpecialFunctions`, `IntervalSets`, and `LaTeXStrings`, and auto-configures the GR backend for headless CI at load time — so this repo needs **no direct `Plots` dependency and no GKS setup of its own**. Available after `using Calculus`: - **Plotting recipes**: `plotif`, `trimplot`, `signchart`, `plot_parametric`(`!`), `plot_polar`(`!`), `implicit_plot`(`!`), `vectorfieldplot`(`3d`), `arrow`(`!`), `riemann_plot`(`!`), `newton_plot!`, `plot_implicit_surface` - **Calculus utilities**: `riemann` (8 methods), `fubini`, `lim` (limit tables), `sign_chart`, `tangent`, `secant`, `D` and the `f'` prime notation (via ForwardDiff), `unzip`, `rangeclamp`, `const e` @@ -34,7 +34,7 @@ member environments. Each member has its own `Project.toml` and `Manifest.toml`: | `Project.toml` | Root package — defines `Calculus` as a library (uuid `dfd5a24e-f5d9-431d-8566-d266db9d2854`) | | `test/Project.toml` | Test-only deps (`Calculus`, `Test`) — workspace member | | `docs/Project.toml` | Docs deps (`Documenter`, `Dates`, `LiveServer`, `Calculus`) — workspace member; uses `Pkg.develop(path=".")`. `LiveServer` is for local live preview (see the `documenter-jl-conventions` skill) | -| `notebooks/Project.toml` | Notebook superset (`IJulia`, `Revise`, `Calculus`) — **not** a workspace member | +| `notebooks/Project.toml` | Notebook superset (`IJulia`, `Revise`, `Calculus`, `Latexify`) — **not** a workspace member | The `notebooks/` environment is intentionally excluded from the workspace `projects` list because it is a developer-only interactive environment, not a dependency of any other member. @@ -90,13 +90,6 @@ pkg> instantiate This creates `notebooks/Manifest.toml` (gitignored) with `path = ".."` pointing at the root package. Subsequent `julia --project=./notebooks` invocations will resolve `Calculus` from the local source. -## Julia Compilation Considerations - -- **Be Patient with First Runs**: Julia often needs to precompile packages on first run; allow 15–30 seconds before tests actually start -- **Example Expected Output**: `Precompiling Calculus... N dependencies successfully precompiled in 17 seconds` -- **Subsequent Runs**: Much faster once cache is built -- **Don't Cancel Early**: Allow time for compilation to complete - ## Git Best Practices - **Never use `git add .`** - Always stage files explicitly by name to avoid accidentally committing development files, notebooks, or temporary files @@ -109,47 +102,22 @@ This creates `notebooks/Manifest.toml` (gitignored) with `path = ".."` pointing - **ALWAYS check all commits on the branch first**: Run `git log main..HEAD --oneline` before writing the PR description - **ALWAYS push changes first**: Use `git push origin BRANCH_NAME` before creating PR -- **Do NOT use `gh pr create`** - The GitHub CLI command doesn't work properly in this environment -- **Use GitHub web interface with URL parameters**: +- **`gh` works here** — `gh pr create --repo FourMInfo/Calculus` is the normal route (verified 2026-09-28). Always pass `--repo` explicitly; see the `phased-implementation-workflow` skill for the branch → PR → squash-merge → prune sequence +- **Fallback if `gh` is unavailable**: open the compare URL in a browser, with title and body as parameters ``` https://github.com/FourMInfo/Calculus/compare/main...BRANCH_NAME?title=Your+PR+Title&body=Your+PR+Description ``` -- **Always provide fallback copy-paste content**: Include separate, copyable title and description in case URL parameters don't work - -## Azure Integration - -- Use Azure Best Practices: When generating code for Azure, running terminal commands for Azure, or performing operations related to Azure, invoke your `azure_development-get_best_practices` tool if available + Supply a separate copy-paste title and description as well, in case the URL parameters do not populate ## Communication Patterns -- Avoid being overly obsequious in responses - - do not tell me "I am happy to help" or similar phrases - - do not tell me how amazing I am or how great my work is - - do not say something is "awesome" or "fantastic" unless it is truly exceptional - - do not use overly emotional language - - do not use words like "wonderful" or "great" to describe my work - - do not use words like "perfect" or "flawless" to describe my work -- When asked to analyze a bug or problem first lay out the problem clearly, then suggest potential solutions or debugging steps and let the user decide on the next steps -- Never say "I see what the problem is" or similar phrases that imply you have fully understood the issue without further discussion and confirmation that you have understood the issue -- Always provide clear, actionable suggestions for next steps in debugging or implementation - - Acknowledge when you need more information or clarification before proceeding - - Summarize the current understanding of the issue before discussing potential solutions - - Document any assumptions made during the analysis - - Identify any knowledge gaps or areas requiring further investigation -- Notify user immediately if you cannot read a file they provided (e.g., PDFs, binary files) instead of silently substituting other files or faking understanding of the content -- If you are unsure about a solution, clearly state that more information is needed or that further investigation is required -- When providing code examples, ensure they are clear, concise, and directly relevant to the problem at hand - - Avoid unnecessary complexity in code examples - - Use comments to explain key parts of the code where necessary - - Ensure code examples are formatted correctly for readability -- If you find yourself repeating steps stop and explain why you are repeating them and ask if the user would like to proceed with the same steps again -- Always ask for confirmation before proceeding with potentially destructive actions, such as deleting files or making significant changes to the codebase -- When discussing code changes, clearly outline the impact of those changes on the overall project - - Discuss how changes align with project goals and coding standards - - Highlight any potential risks or trade-offs associated with the changes -- If you encounter a situation where you need to make assumptions, clearly state those assumptions and their implications -- When discussing project architecture or design decisions, provide a rationale for each decision made -- If you need to reference external resources or documentation, provide clear links and context for their relevance -- Always strive for clarity and precision in communication, especially when discussing technical details -- If you need to ask for clarification, do so in a way that encourages open dialogue and collaboration -- When providing feedback on code or design, focus on constructive criticism that helps improve the overall quality +> **Copilot mirror.** Claude Code gets these rules from the global `~/.claude/CLAUDE.md` +> (canonical: `Dotfiles.Mac/Files/claude/CLAUDE.md`), which is the source of truth. Copilot has no +> global-instructions equivalent, so the essentials are restated here. Keep the two in step. + +- No obsequiousness: no "happy to help", no praise of my work ("amazing", "awesome", "perfect", "flawless"), no emotional language +- Lay the problem out before proposing a fix, and never claim to have grasped an issue ("I see what the problem is") before that is confirmed +- Say when you need more information rather than guessing, and state any assumption you are working from +- Say immediately if you cannot read a file you were given — never substitute another file or infer its contents +- If you find yourself repeating steps, stop, explain why, and ask before repeating them +- Ask for confirmation before destructive actions or significant structural changes diff --git a/.github/instructions/docs.instructions.md b/.github/instructions/docs.instructions.md index 73a08a3..30bdedc 100644 --- a/.github/instructions/docs.instructions.md +++ b/.github/instructions/docs.instructions.md @@ -3,6 +3,11 @@ applyTo: 'docs/**' --- # Documentation Conventions +This file is **shared**: copied unchanged into every math study repo from the hub +(`FourMInfo/math_tech_study`, `project_resources/instructions/`) and byte-identical everywhere. +This repo's deployed URL (`dirname`) and anything specific to its docs are in +`project.instructions.md`. + ## Structure for Mathematical Concept Documentation Documentation in `docs/src/` explains general math concepts (not code). Follow these patterns: @@ -20,7 +25,7 @@ Documentation in `docs/src/` explains general math concepts (not code). Follow t - **Multiple representations**: Equations, tables, visual aids (SVG diagrams when helpful) - **Context matters**: Explain _why_ concepts are important, not just _what_ they are - Example: "Projections are fundamental to least-squares approximation, computer graphics, and data compression" -- **Derivations**: Show mathematical reasoning step-by-step (see projection and transformation matrix derivations) +- **Derivations**: Show mathematical reasoning step-by-step ## Mathematical Notation, MathJax3 & MathWorld Links @@ -50,16 +55,19 @@ See `documenter-jl-conventions` skill for section anchor rules and examples. ## Documentation Structure - **Cross-Repository Deployment**: Deploys to math_tech_study repository -- **Subdirectory Pattern**: Available at fourm.info/calculus/ +- **Subdirectory Pattern**: Available at `fourm.info//` — this repo's dirname is in `project.instructions.md` - **Auto-docs Integration**: Uses `@autodocs` for automatic function documentation - **Mathematical Notation**: Supports LaTeX rendering in documentation ## Building Documentation ```bash -julia --project=. docs/make.jl +# Once after cloning (docs/Manifest.toml is gitignored) — the same step CI runs +julia --project=docs -e 'using Pkg; Pkg.develop(path="."); Pkg.instantiate()' + +julia --project=docs docs/make.jl ``` -**IMPORTANT**: Always run `julia --project=. docs/make.jl` after making changes to documentation files in `docs/src/`. This allows the user to preview changes in the browser immediately without running the build manually. +**IMPORTANT**: Always run `julia --project=docs docs/make.jl` after making changes to documentation files in `docs/src/`. This allows the user to preview changes in the browser immediately without running the build manually. For a live, auto-refreshing preview served from `docs/build/`, use `LiveServer` (declared in `docs/Project.toml`). See the `documenter-jl-conventions` skill for the exact `serve` command. diff --git a/.github/instructions/ecosystem.instructions.md b/.github/instructions/ecosystem.instructions.md new file mode 100644 index 0000000..16a535e --- /dev/null +++ b/.github/instructions/ecosystem.instructions.md @@ -0,0 +1,110 @@ +--- +applyTo: '**' +--- +# Math Study Ecosystem + +This file is **shared**: it is copied unchanged into every math study repo from the hub +(`FourMInfo/math_tech_study`, `project_resources/instructions/`) and must stay byte-identical +everywhere. Never edit a repo's copy — change the hub template and propagate. Everything +specific to this repo (its package, deployed URL, dependencies, notebook setup) is in +`project.instructions.md`. + +## What This Repository Is + +This is **one subrepository** in a multi-repository Julia math study project. Understand the +broader ecosystem before changing CI, documentation configuration, or project structure. + +## The Math & Tech Study Hub + +The main website lives at **https://fourm.info**, built with **Franklin.jl** in the separate +repository `FourMInfo/math_tech_study`. The hub owns the top-level domain, navigation and +study guides. + +Current math study repositories and their deployed URLs: + +| Repository | Deployed URL | +|---|---| +| `FourMInfo/Linear_Algebra` | https://fourm.info/linear_algebra/ | +| `FourMInfo/Math_Foundations` | https://fourm.info/math_foundations/ | +| `FourMInfo/Calculus` | https://fourm.info/calculus/ | + +New repositories follow the same pattern; the hub template of this file gains a row and is +propagated to all of them. + +## How These Repositories Deploy + +Each repo is a Julia package documented with **Documenter.jl**. + +```text +Push to main + → CI.yml runs the deploy-docs job + → docs/make.jl builds the Documenter site + → deploydocs() cross-deploys to FourMInfo/math_tech_study (gh-pages branch) + → appears at fourm.info// (this repo's dirname: see project.instructions.md) +``` + +Key facts about `docs/make.jl`: + +- `ENV["GITHUB_REPOSITORY"]` is **deliberately overridden** to `"FourMInfo/math_tech_study"` — + this is what makes the deployment cross-repository. Do NOT remove or change it. +- `dirname` in `deploydocs()` sets the subdirectory on the live site. Do NOT change it. +- The `DOCUMENTER_KEY` secret is the private half of a deploy key registered on + `math_tech_study` (not on this repo), shared by every study repo. + +## CI Behaviour + +`.github/workflows/CI.yml` has three independent jobs (no `needs:` between them): + +1. **test** — runs on pull requests and manual triggers (`workflow_dispatch`), not on pushes to + `main` +2. **docs-build** — builds (does not deploy) the docs on pull requests that change `src/` or + `docs/` +3. **deploy-docs** — runs on push to `main` or a manual trigger, and deploys to the site + +Because deploy-docs does not wait for tests, a change must pass its tests on the pull request +**before** it is merged. + +**CRITICAL**: keep the `workflow_dispatch` trigger. It lets this repo's docs be redeployed +without a code change if they ever go missing from the site. + +## Project Layout and Environments + +- Every study repo's file and directory structure is generated by **DrWatson.jl** when the repo + is created, never by hand. The layout (`src/`, `test/`, `docs/`, `notebooks/` and the other + DrWatson directories) exists because DrWatson made it; CI and the docs build depend on it, so + do not restructure it. +- DrWatson also activates the project in interactive work: the Julia `startup.jl` (canonical + copy in `Dotfiles.Mac/Files/julia/`) loads it in every REPL and runs `quickactivate(".")` when + Julia starts in a repo root without `--project`. Code does not call DrWatson: tests and CI run + with `--project` / `Pkg.test()`, and notebooks and tests load everything through + `using `, whose module reexports its dependencies. +- `Manifest.toml` is gitignored in every environment, so the `[compat]` bounds in each + `Project.toml` (root, `docs/`, `test/`, `notebooks/`) are the only pin. Keep them current — + see the `julia-coding-conventions` skill. + +## Critical Constraints — Do NOT Do These + +| Action | Why It Is Dangerous | +|---|---| +| Enable GitHub Pages on this repository | Only `math_tech_study` may have GitHub Pages with the custom domain. Enabling it here breaks the domain | +| Change or remove the `ENV["GITHUB_REPOSITORY"]` override in `docs/make.jl` | Deployment targets the wrong repository | +| Change `dirname` in `deploydocs()` | The subdirectory path on the live site breaks | +| Remove `workflow_dispatch` from CI.yml | Loses the ability to redeploy the docs manually | +| Change the `DOCUMENTER_KEY` secret without also updating the deploy key on `math_tech_study` | Deployment fails with authentication errors | + +## Relationship to the Main Franklin Site + +The Franklin deploy in `math_tech_study` wipes `gh-pages` on every build, so its workflow backs +up **every** top-level directory on `gh-pages` first and restores those the build did not +regenerate. There is no list to maintain: a new study repo's subdirectory is preserved +automatically. The details are in `math_tech_study`'s +`.github/instructions/subrepo-docs-publishing.instructions.md`. + +## Local Documentation Preview + +```bash +# Build docs locally (does not deploy) +julia --project=docs docs/make.jl + +# The built site is in docs/build/ — see the documenter-jl-conventions skill for a live preview +``` diff --git a/.github/instructions/notebooks.instructions.md b/.github/instructions/notebooks.instructions.md index daad19f..94f481a 100644 --- a/.github/instructions/notebooks.instructions.md +++ b/.github/instructions/notebooks.instructions.md @@ -3,98 +3,53 @@ applyTo: 'notebooks/**' --- # Notebook Conventions +This file is **shared**: copied unchanged into every math study repo from the hub +(`FourMInfo/math_tech_study`, `project_resources/instructions/`) and byte-identical everywhere. +This repo's exact setup cell and any notebook-only display packages are in +`project.instructions.md`. + ## Setup Pattern -All notebooks should start with the standard setup cell: +Every notebook starts with a setup cell of this shape: ```julia using Revise -using Calculus -using LAlatex, BlockArrays - -LAlatex.set_backend!(:symbolics) -LAlatex.reset_display_defaults!() +using MyPackage ``` -What comes from where: +`using ` provides everything the module reexports (plotting, symbolic maths, +`LaTeXStrings` and the `L"..."` macro, …). A package that lives **only** in +`notebooks/Project.toml` is not reexported by the module and needs its own `using` line in the +setup cell — `project.instructions.md` lists any this repo has. -- `using Calculus` provides everything the module reexports — `LaTeXStrings` (the `L"..."` macro) plus the full `CalculusWithJuliaSquared` chain (`Plots`, `Symbolics`, `Roots`, calculus utilities and plotting recipes — see "What CalculusWithJuliaSquared Provides" in `copilot-instructions.md`). -- `LAlatex` and `BlockArrays` are **notebooks-environment dependencies only** (in `notebooks/Project.toml`, not the root project), so they need their own `using` line — they are *not* re-exported by `Calculus`. +## Notebook Environment -`set_backend!(:symbolics)` is required because this package uses Symbolics.jl; the default `:latexify` backend gives worse output for symbolic expressions. -`reset_display_defaults!()` ensures a clean display state on every kernel restart. +- The `notebooks/` environment is **not** a workspace member — run `pkg> dev ..` + + `pkg> instantiate` once after cloning. See the `julia-coding-conventions` skill for the full + pattern. Do not commit `notebooks/Manifest.toml`. +- Notebooks are for exploration and study; they are not tested in CI. ## Notebook Guidelines -- Notebooks are for exploration and study, not tested in CI -- The `notebooks/` environment is **not** a workspace member — run `pkg> dev ..` + `pkg> instantiate` once after cloning. See `julia-coding-conventions` skill for the full pattern. Do not commit `notebooks/Manifest.toml`. -- Use `println()` for output to make results clear when re-running cells +- Use `println()` for output, so results stay clear when cells are re-run - Include explanatory markdown cells between code cells -- Use Unicode variable names consistent with the source code (e.g., `v₁`, `θ`, `λ`) +- Use Unicode variable names consistent with the source code (e.g. `v₁`, `θ`, `λ`) - Reference the documentation sections being studied ## Plotting in Notebooks -- Plots render inline in Jupyter notebooks -- No need for headless mode configuration -- Prefer the ready-made recipes from `CalculusWithJuliaSquared` (`plotif`, `riemann_plot`, `plot_parametric`, `vectorfieldplot`, …) and this package's own plotting functions before writing new ones - -## LAlatex Display - -[LAlatex.jl](https://github.com/ea42gh/LAlatex.jl) (by ea42gh) is available in the notebooks environment (`using LAlatex` in the setup cell) and provides clean LaTeX rendering of mathematical objects in notebooks. Use it instead of raw `println` or `display` whenever presenting mathematical results. - -### Core functions - -| Function | Purpose | -|---|---| -| `l_show(...)` | Display one or more objects inline or as a display equation | -| `L_show(...)` | Same but returns a `String` instead of displaying | -| `lc(coeffs, vecs)` | Linear combination display | -| `set(...)` | Finite set or set-builder notation | -| `cases(...)` | Piecewise / cases display | -| `aligned(...)` | Multi-line aligned derivation or equation chain | -| `mixed_matrix(...)` / `@mixed_matrix` | Matrix with mixed numeric/symbolic entries | -| `factor_out_denominator(A)` | Factor a common denominator out of a rational matrix | - -### Common options for `l_show` - -```julia -l_show(L"A = ", A; arraystyle=:bmatrix) # bracket style: :bmatrix, :pmatrix, :vmatrix, :array -l_show(expr; symopts=(expand=true,)) # symbolic transformations: expand, factor, collect -l_show(A; number_formatter=x -> round_value(x,2)) # custom number formatting -l_show(A; number_formatter=percentage_formatter) # percentage display -l_show(aligned(...); inline=false, tag="1") # numbered display equation (no label — see below) -with_display_defaults(arraystyle=:bmatrix) do ... end # scoped defaults -``` - -### Block-partitioned matrices - -Wrap a plain matrix in `BlockArray` to get visual partition lines (horizontal `\hline` and vertical `|` separators) between blocks: - -```julia -B = BlockArray([1 2 4; 3 4 5], [1, 1], [2, 1]) # row sizes [1,1], col sizes [2,1] -display(l_show(L"B = ", B)) -``` - -### KaTeX constraint: no `\label` - -Jupyter notebooks render math with **KaTeX**, which supports `\tag{...}` but **not** `\label{...}`. Never pass the `label=` keyword to `l_show` in a notebook — it will produce a parse error. Use `tag=` only: - -```julia -# ✅ correct -display(l_show(aligned(...); inline=false, tag="1")) -# ❌ will fail in Jupyter -display(l_show(aligned(...); inline=false, tag="1", label="eq:foo")) -``` - -`label=` is only valid when rendering to full LaTeX/MathJax (e.g. Documenter.jl docs). +- Plots render inline; no headless configuration is needed +- Use the package's own plotting functions (`plot_*`) before writing new plotting code +- How figures display in notebooks, docs and the REPL alike is covered by the + `julia-figure-authoring` skill -### Reference +## Math Rendering: KaTeX, not MathJax -- [LAlatex.jl docs](https://ea42gh.github.io/LAlatex.jl/) -- [Demo notebook (upstream)](https://github.com/ea42gh/LAlatex.jl/blob/main/notebooks/LAlatex_demo.ipynb) -- [Interactive Binder demo](https://mybinder.org/v2/gh/ea42gh/LAlatex.jl/main?filepath=notebooks%2FLAlatex_demo.ipynb) +Jupyter renders math with **KaTeX**, which supports `\tag{...}` but **not** `\label{...}`. Never +emit `\label` in notebook output — it produces a parse error. `\label` is valid only where the +math is rendered by full LaTeX or MathJax (e.g. Documenter.jl docs). ## Julia Kernel Gotchas -See `julia-coding-conventions` skill (stale variable slot, building matrix from row vectors). \ No newline at end of file +See the `julia-coding-conventions` skill (stale variable slot, building a matrix from row +vectors). diff --git a/.github/instructions/project.instructions.md b/.github/instructions/project.instructions.md index f8c3333..385a187 100644 --- a/.github/instructions/project.instructions.md +++ b/.github/instructions/project.instructions.md @@ -1,86 +1,76 @@ --- applyTo: '**' --- -# Project Ecosystem Context +# Calculus — Repository-Specific Instructions - +This file is **this repo's own**: it holds everything specific to this repository and is never +overwritten by propagation from the hub. It can be as detailed as the repo needs. The shared +conventions every study repo follows are in the other files in `.github/instructions/` +(`ecosystem`, `source`, `testing`, `docs`, `notebooks`), which are copied unchanged from +`FourMInfo/math_tech_study/project_resources/instructions/` and must never be edited here. A +learning that holds for every study repo goes into those hub templates, not into this file. -## What This Repository Is +## This Repository -This is **one subrepository** in a multi-repository Julia math study project. Understanding the broader ecosystem is essential before making changes, especially to CI, documentation configuration, or project structure. - -## The Math & Tech Study Hub - -The main website lives at **https://fourm.info** and is built with: -- **Franklin.jl** (Lanyon template) in a separate GitHub repository: `FourMInfo/math_tech_study` -- The main site handles the top-level domain, navigation, and study guides - -Current subrepositories and their deployed URLs: -| Repository | Deployed URL | +| | | |---|---| -| `FourMInfo/Linear_Algebra` | https://fourm.info/linear_algebra/ | -| `FourMInfo/Math_Foundations` | https://fourm.info/math_foundations/ | -| `FourMInfo/Calculus` (this repo) | https://fourm.info/calculus/ | - -Additional subrepositories will be added in the future following the same pattern. - -## How This Repository Deploys - -This repo uses **DrWatson.jl** for project structure and **Documenter.jl** for documentation. +| GitHub | `FourMInfo/Calculus` | +| Deployed at | `https://fourm.info/calculus/` | +| `dirname` in `docs/make.jl` | `"calculus"` | +| Subject | Calculus: derivatives, integrals, limits, series and applications | -### Deployment Flow +## Package and Module -``` -Push to main - → CI.yml runs deploy-docs job - → docs/make.jl builds Documenter site - → deploydocs() cross-deploys to FourMInfo/math_tech_study (gh-pages branch) - → Appears at fourm.info/calculus/ -``` - -Key facts about `docs/make.jl`: -- `ENV["GITHUB_REPOSITORY"]` is **deliberately overridden** to `"FourMInfo/math_tech_study"` — this is what causes cross-repository deployment. Do NOT remove or change this. -- `dirname = "calculus"` in `deploydocs()` sets the subdirectory path. Do NOT change this. -- The `DOCUMENTER_KEY` secret is a deploy key for the `math_tech_study` repository (not this one). +- **Main module**: `src/Calculus.jl` +- **Source files**: `src/calculus_basic.jl` (not yet populated or included) +- **Reexported packages**: `CalculusWithJuliaSquared` (CWJS) only. CWJS in turn reexports + `Plots`, `Symbolics`, `Roots`, `LinearAlgebra`, `SpecialFunctions`, `IntervalSets` and + `LaTeXStrings`, so `using Calculus` brings all of them. What CWJS itself provides, how it is + installed and how to update it: "What CalculusWithJuliaSquared Provides" in + `.github/copilot-instructions.md`. +- **Headless plotting**: CWJS configures the GR backend at its own load time (the canonical + `julia-coding-conventions` pattern lives there), so this module does no GR configuration. + Tests still set `GKSwstype` before loading, as the shared testing conventions say. -### CI Behaviour +## Dependencies -The `.github/workflows/CI.yml` has three jobs: -1. **test** — runs only on PRs and manual triggers (`workflow_dispatch`), not on pushes to main -2. **docs-build** — builds (but does not deploy) docs on PRs where `src/` or `docs/` changed -3. **deploy-docs** — runs on push to main or manual trigger; this is the job that deploys to the site +- **Never add `Plots` or `SymPy` directly** — plotting and symbolic maths come through CWJS, + which exists to keep Python out. +- CWJS is unregistered and installed by GitHub URL through `[sources]` in `Project.toml`; keep that + section intact. +- **Check CWJS before writing a new function** — it may already exist (`riemann_plot`, `plotif`, + `tangent`, `lim`, …). -**CRITICAL**: The `workflow_dispatch` trigger on CI.yml must be preserved. When the Franklin main site redeploys, it can overwrite all subdirectory documentation. The manual trigger allows recovery by redeploying this repo's docs without a code change. +## Subject-Specific Conventions -## Why DrWatson +### Function Categories (planned) -DrWatson is used for **project reproducibility and structure**, not primarily for data management. It provides: -- `Project.toml` / `Manifest.toml` for exact Julia environment pinning -- Standard directory layout (`src/`, `test/`, `docs/`, `notebooks/`, `scripts/`, `data/`, `papers/`, `plots/`) -- `quickactivate` integration in notebooks and scripts +- **Differentiation**: derivatives, partial derivatives, gradients +- **Integration**: definite and indefinite integrals, numerical methods +- **Limits**: numerical limit evaluation +- **Series**: Taylor series, convergence -Do NOT remove DrWatson or restructure the directory layout — the CI and docs build depend on it. +### Naming -## Critical Constraints — Do NOT Do These +Parameter names follow standard calculus notation (`f` for functions, `a`, `b` for interval +endpoints, `h` for step size, `n` for sample counts). -| Action | Why It Is Dangerous | -|---|---| -| Enable GitHub Pages on this repository | Only `math_tech_study` may have GitHub Pages with the custom domain. Enabling it here will break the domain | -| Change or remove the `ENV["GITHUB_REPOSITORY"]` override in `docs/make.jl` | Deployment will target the wrong repository | -| Change `dirname` in `deploydocs()` | The subdirectory path on the live site will break | -| Remove `workflow_dispatch` from CI.yml | Loses ability to manually recover docs after Franklin site redeploy | -| Change the `DOCUMENTER_KEY` secret value without also updating the deploy key in `math_tech_study` | Deployment will fail with authentication errors | -| Reorder or remove jobs in CI.yml without understanding the `needs: test` dependency | Deploy job depends on test passing | - -## Relationship to the Main Franklin Site +## Tests -The main `math_tech_study` repo's GitHub Actions workflow has a **backup/restore mechanism** that preserves subdirectory docs when the Franklin site redeploys. If you add a new subrepository to the ecosystem in the future, the Franklin workflow in `math_tech_study` must be updated to include the new subdirectory name in both its backup and restore steps. +- **Test files**: `test_calculus_basics.jl` — currently a placeholder, to be replaced as functions + are implemented -## Local Documentation Preview +## Notebooks -```bash -# Build docs locally (does not deploy) -julia --project=. docs/make.jl +Setup cell for this repo: -# The built site is in docs/build/ — open docs/build/index.html in a browser +```julia +using Revise +using Calculus ``` + +- Prefer CWJS's ready-made plotting recipes (`plotif`, `riemann_plot`, `plot_parametric`, + `vectorfieldplot`, …) and this package's own plotting functions before writing new ones. +- `notebooks/Project.toml` also lists **Latexify**. `using Calculus` already loads it (CWJS + depends on it), which activates Symbolics' `SymbolicsLatexifyExt`, so symbolic output is + typeset with no extra line. Add `using Latexify` only to call `latexify(...)` by name. diff --git a/.github/instructions/source.instructions.md b/.github/instructions/source.instructions.md index 5d80157..4c17434 100644 --- a/.github/instructions/source.instructions.md +++ b/.github/instructions/source.instructions.md @@ -3,73 +3,81 @@ applyTo: 'src/**' --- # Source Code Conventions +This file is **shared**: copied unchanged into every math study repo from the hub +(`FourMInfo/math_tech_study`, `project_resources/instructions/`) and byte-identical everywhere. +This repo's module name, file layout, dependencies, function catalogue and conventions specific +to its subject are in `project.instructions.md` — read it before editing `src/`. + ## Module Structure & Exports -All code uses `@reexport` pattern and exports both computational + plotting functions: +The main module (`src/.jl`) uses `@reexport`, so that `using ` alone gives +notebooks, tests and docs everything they need, and it exports every public function: ```julia -# Main module uses @reexport for clean interface +module MyPackage using Reexport -@reexport using CalculusWithJuliaSquared, LaTeXStrings +@reexport using Plots, Symbolics, LaTeXStrings # this repo's list: project.instructions.md # Pure computational functions (no plotting dependencies) -export calculate_derivative, calculate_integral - +export calculate_something # Integrated plotting functions (computation + visualization) -export plot_function, plot_derivative +export plot_something + +include("mypackage_basic.jl") +end ``` -`CalculusWithJuliaSquared` brings `Plots`, `Symbolics`, `Roots`, `LinearAlgebra`, `SpecialFunctions`, and `IntervalSets` with it, plus ready-made calculus utilities and plotting recipes (see the "What CalculusWithJuliaSquared Provides" section in `copilot-instructions.md`). **Check there before writing a new function — it may already exist** (e.g. `riemann_plot`, `plotif`, `tangent`, `lim`). +- **Always export new public functions** from the main module. +- Keep `export` lines grouped by the two categories below, with a comment heading each. -## CI/Interactive Detection +## Headless Plotting -Handled by `CalculusWithJuliaSquared` at its own load time (the canonical `GKSwstype` pattern from the `julia-coding-conventions` skill lives there now). This module needs no GKS configuration of its own. +Tests set `ENV["GKSwstype"] = "100"` **before** loading the package (see +`testing.instructions.md`). Where a module configures the GR backend itself at load time, it +follows the canonical pattern in the `julia-coding-conventions` skill; +`project.instructions.md` says which applies here. -## Julia Coding Standards +## Separate Computation from Plotting -### Function Design Pattern +Every plotted result has a pure computational function underneath it: ```julia # Pure computational function (no plotting dependencies) -function calculate_derivative(f, x; h=1e-7) - return (f(x + h) - f(x - h)) / (2h) +function calculate_something(args...) + # ... mathematics only; errors here are real errors + return result end # Integrated plotting function (computation + visualization) -function plot_derivative(f, a, b; n=200) - xs = range(a, b, length=n) - ys = [calculate_derivative(f, x) for x in xs] +function plot_something(args...) + result = calculate_something(args...) try - plot!(xs, ys) + plot!(result) catch e !haskey(ENV, "CI") && @warn "Plotting failed: $e" end - return ys + return result end ``` -### General Coding Standards -1. Always export new functions in the main module -2. Separate pure computational logic from plotting — `calculate_*` functions have no Plots dependency -3. Plotting functions wrap computation with a try/catch for CI compatibility -4. Use clear parameter naming consistent with standard calculus notation -5. Document mathematical definitions and notation in docstrings - -### Function Categories -- **Differentiation**: Derivatives, partial derivatives, gradients -- **Integration**: Definite/indefinite integrals, numerical methods -- **Limits**: Numerical limit evaluation -- **Series**: Taylor series, convergence +- `calculate_*` functions have no plotting dependency and are tested directly. +- `plot_*` functions call the computational function, wrap only the plotting in `try`/`catch`, + and return the computed result so tests can check it. +- How a plotting function should return and display its figure is covered by the + `julia-figure-authoring` skill. -### Function Naming Patterns -- **Computational**: `calculate_*` (e.g., `calculate_derivative`, `calculate_integral`) -- **Plotting**: `plot_*` (e.g., `plot_function`, `plot_tangent`) +## Naming -## Dependencies & Libraries +- **Computational**: `calculate_*`; **plotting**: `plot_*` +- Descriptive suffixes for families of functions (e.g. `_matrix`, `_line`, `_roots`) +- `_symbolic` variants where a function has both a symbolic and a numeric form +- Parameter names follow standard mathematical notation (`θ` for angles, `v`/`w` for vectors, + `p`/`q` for points, `f` for functions); Unicode names are welcome -**Main Dependencies**: CalculusWithJuliaSquared (unregistered, installed by GitHub URL), LaTeXStrings, Reexport +## Documentation & Comments -### Libraries Used -- **CalculusWithJuliaSquared.jl**: calculus utilities, plotting recipes, and the full reexport chain (Plots, Symbolics, Roots, LinearAlgebra, SpecialFunctions, IntervalSets) — pure Julia, zero Python by design; never add `Plots` or `SymPy` directly here -- **LaTeXStrings.jl**: For `L"..."` string macro -- **Reexport.jl**: For `@reexport` clean module interface +- Every exported function has a docstring; the `documenter-jl-conventions` skill covers + signature lines, LaTeX in docstrings and `@autodocs` +- Explain the mathematics in comments: the concept, the formula, and any convention a caller + could get wrong (degrees vs radians, orientation, domain restrictions) +- Keep notation consistent with the repo's `docs/src/` pages diff --git a/.github/instructions/testing.instructions.md b/.github/instructions/testing.instructions.md index 69d810e..cfeb9ba 100644 --- a/.github/instructions/testing.instructions.md +++ b/.github/instructions/testing.instructions.md @@ -3,130 +3,86 @@ applyTo: 'test/**' --- # Testing Conventions -## CI Testing Strategy +This file is **shared**: copied unchanged into every math study repo from the hub +(`FourMInfo/math_tech_study`, `project_resources/instructions/`) and byte-identical everywhere. +This repo's package name, test files and subject-specific testing notes are in +`project.instructions.md`. How to design tests that can actually catch a defect is covered by +the `test-design-discipline` skill. -The CI testing strategy consists of three components: +## Test Setup -### 1. Module-Level Headless Detection -Configured in the main module (`Linear_Algebra.jl`) at load time. See `julia-coding-conventions` skill for the canonical GKSwstype pattern. +`test/runtests.jl` sets headless plotting **before** loading the package, loads it with a plain +`using` (the module reexports its dependencies — no `@quickactivate`), then includes one file per +topic inside a single top-level `@testset`: -### 2. Manual GKS Configuration in Tests -Set `ENV["GKSwstype"] = "100"` in test files before loading the module: ```julia -# In test files - Configure headless mode before loading module -ENV["GKSwstype"] = "100" # Force headless plotting for CI -using DrWatson, Test -@quickactivate "Calculus" -using Calculus -``` +using Test -### 3. Separated Computational/Plotting Logic with Robust Testing -- **Pure computational functions** (`calculate_*`): Test mathematical logic directly, no try-catch -- **Plotting functions** (`plot_*`): Test with try-catch fallback for CI compatibility -- **Integration testing**: Verify both computation and visualization work together +# Set headless mode for CI before loading module +ENV["GKSwstype"] = "100" -## Test Setup (Uses @quickactivate) -```julia -# Tests use DrWatson @quickactivate pattern -using DrWatson, Test -@quickactivate "Calculus" -# Load the Calculus package -using Calculus -``` +using MyPackage -## CI-Compatible Plotting Pattern -```julia -# Environment detection for plotting tests -if get(ENV, "CI", "false") == "true" || get(ENV, "GITHUB_ACTIONS", "false") == "true" - # In CI, just test that the function exists - @test hasmethod(plot_param_line, (typeof(p), typeof(q), Int64)) -else - # Local testing - allow plotting but capture any display issues - try - points = plot_param_line(p, q, 3) - # ... test plotting results - catch e - # Graceful fallback for plotting failures - @test hasmethod(plot_param_line, (typeof(p), typeof(q), Int64)) - end +@testset "MyPackage tests" begin + include("test_mypackage_basic.jl") end ``` -## Testing Patterns - -- **Comprehensive Coverage**: Test coverage includes all mathematical functions -- **CI-Safe**: Plotting tests work in both local and headless environments -- **Edge Cases**: Test mathematical edge cases (orthogonal vectors, zero angles, etc.) -- **Type Testing**: Verify return types (Point2f, AbstractVector, matrices) -- **Numerical Precision**: Use `atol=1e-10` for floating-point comparisons -- Use `@test_throws` for expected errors, `@test_broken` for known failures +- Test files are named `test_.jl`, one per source file or topic, and **every** test file + must be `include`d from `runtests.jl` — an orphaned file silently never runs (see the + `julia-coding-conventions` skill). +- Test-only dependencies go in `test/Project.toml`. -## CI-Compatible Testing Pattern +## Separate Computational and Plotting Tests -Separate computational logic from plotting, test math directly without try-catch, only use try-catch for visualization: +Mirror the source split: test the mathematics directly, and fence off only the display. ```julia -# Test computational logic directly (NO try-catch - mathematical errors should fail) -@testset "Pure Computational Tests" begin - points = calculate_param_line(p, q, 3) - @test length(points) == 3 - @test typeof(points) == Vector{Point2f} - # Test mathematical correctness without plotting dependencies +# Computational logic: NO try/catch — a mathematical error must fail the test +@testset "Computation" begin + result = calculate_something(args...) + @test result ≈ expected atol=1e-10 end -# Test integration (plotting + computation) with CI-safe fallback -@testset "Integration Tests" begin +# Plotting: the computation still must be right; only display failures are tolerated +@testset "Plotting" begin try - # Test the plotting function (includes computation + visualization) - result = plot_param_line(p, q, 3) - @test typeof(result) == Vector{Point2f} - @test length(result) == 3 + result = plot_something(args...) + @test result ≈ expected atol=1e-10 catch e - # Only catch plotting-related errors, not computational errors if contains(string(e), "display") || contains(string(e), "GKS") || isa(e, ArgumentError) - @test hasmethod(plot_param_line, (Point2f, Point2f, Int64)) + @test hasmethod(plot_something, typeof.(args)) else - # Re-throw computational errors - these should fail the test rethrow(e) end end end ``` -## Test Organization - -- **Grouped by Category**: Basic functions, transformation matrices, line geometry, advanced functions -- **CI Compatibility**: Plotting tests with environment detection -- **Comprehensive Coverage**: Test both happy path and edge cases -- **Type Validation**: Verify return types match expectations -- **Testing Structure**: Modular test files (`test_calculus_basics.jl`) - -## Plotting in Tests +## Testing Patterns -- If saving plots, use timestamped paths: `"plots/" * Dates.format(now(),"yyyymmdd-HHMMSS") * "functionname.png"` -- Ensure `plots/` directory exists before running tests that save plots -- Use LaTeX titles where appropriate: `title!(L"Plot\ Title")` +- Cover every exported function, the happy path **and** mathematical edge cases (degenerate + inputs, zero and boundary values, orthogonal or parallel cases) +- Check return types as well as values +- Floating-point comparisons use `≈` / `isapprox` with an explicit tolerance (`atol=1e-10` + unless the mathematics needs otherwise) +- `@test_throws` for expected errors, `@test_broken` for known failures +- Plots saved during tests go under `plots/`; the `julia-figure-authoring` skill covers naming ## Running Tests ```bash -# Local -julia --project=. test/runtests.jl +# As CI runs them +julia --project=. -e 'using Pkg; Pkg.test()' -# CI mode -CI=true julia --project=. test/runtests.jl +# Simulating CI's headless environment +CI=true julia --project=. -e 'using Pkg; Pkg.test()' ``` -## CI/CD Pipeline - -- **Tests**: Run on all PRs (`.github/workflows/CI.yml`) -- **Docs Build**: Test on PR (no deploy) -- **Docs Deploy**: Auto-deploy to `https://fourm.info/calculus/` on merge to `main` -- **Cross-Repo**: Deploys to `FourMInfo/math_tech_study` subdirectory - -## CI Considerations +## Tests in CI -- Tests automatically detect CI environment via ENV variables -- Plotting tests skip gracefully in headless mode -- 68 tests pass in both local and CI modes (plotting tests with fallbacks) -- Test execution time: ~15-16 seconds +- The **test** job runs on pull requests and manual triggers only — not on pushes to `main`, + and the deploy job does not wait for it. A change must pass on its pull request before merge. +- Plotting tests pass headless because of the `GKSwstype` setting and the fallbacks above. +- CI pipeline details and the deployed docs URL: `ecosystem.instructions.md` and + `project.instructions.md`. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..275bfae --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,29 @@ +# CLAUDE.md + +Claude Code does not read `.github/copilot-instructions.md` or the `applyTo`-scoped files in +`.github/instructions/` — both are VS Code Copilot mechanisms. This file bridges them, so the +two assistants work from one source instead of two copies that drift. + +This file is **shared**: copied unchanged into every math study repo from the hub +(`FourMInfo/math_tech_study`, `project_resources/claude/CLAUDE.template.md`) and byte-identical +everywhere. Never edit a repo's copy — change the hub template and propagate. + +## Repo instructions (loaded below) + +@.github/copilot-instructions.md + +@.github/instructions/ecosystem.instructions.md + +@.github/instructions/project.instructions.md + +## Path-scoped instructions + +Copilot loads these automatically by glob. Claude Code does not, so read the matching file +before editing in that area: + +| Before editing | Read | +|---|---| +| `src/**` | `.github/instructions/source.instructions.md` | +| `test/**` | `.github/instructions/testing.instructions.md` | +| `docs/**` | `.github/instructions/docs.instructions.md` | +| `notebooks/**` | `.github/instructions/notebooks.instructions.md` | From dcddcb62c70a77b95739dc53c1f0c49dfb8e9eda Mon Sep 17 00:00:00 2001 From: Aron T Date: Tue, 29 Sep 2026 11:59:41 +0300 Subject: [PATCH 2/2] Name the test file after its source file, as Linear_Algebra does src/calculus_basic.jl pairs with test/test_calculus_basic.jl (was test_calculus_basics.jl), and the commented-out include in Calculus.jl now names the file that exists. It stays commented out until the first functions are written. Co-Authored-By: Claude Opus 5.5 --- .github/instructions/project.instructions.md | 2 +- src/Calculus.jl | 2 +- test/runtests.jl | 2 +- test/{test_calculus_basics.jl => test_calculus_basic.jl} | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename test/{test_calculus_basics.jl => test_calculus_basic.jl} (100%) diff --git a/.github/instructions/project.instructions.md b/.github/instructions/project.instructions.md index 385a187..87b18db 100644 --- a/.github/instructions/project.instructions.md +++ b/.github/instructions/project.instructions.md @@ -57,7 +57,7 @@ endpoints, `h` for step size, `n` for sample counts). ## Tests -- **Test files**: `test_calculus_basics.jl` — currently a placeholder, to be replaced as functions +- **Test files**: `test_calculus_basic.jl` — currently a placeholder, to be replaced as functions are implemented ## Notebooks diff --git a/src/Calculus.jl b/src/Calculus.jl index df7eb06..a8fbcc7 100644 --- a/src/Calculus.jl +++ b/src/Calculus.jl @@ -11,6 +11,6 @@ using Reexport # Integrated plotting functions (computation + visualization) -# include("calculus_basics.jl") # uncomment when source file exists +# include("calculus_basic.jl") # uncomment once the first functions are written end # module diff --git a/test/runtests.jl b/test/runtests.jl index 8370997..0b9f31e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -10,7 +10,7 @@ println("Starting tests") ti = time() @testset "Calculus tests" begin - include("test_calculus_basics.jl") + include("test_calculus_basic.jl") # add more test files here end diff --git a/test/test_calculus_basics.jl b/test/test_calculus_basic.jl similarity index 100% rename from test/test_calculus_basics.jl rename to test/test_calculus_basic.jl