Imported from JuliaNonconvex/NonconvexUtils.jl (
AGENTS.md). Install upstream withnpx skills add JuliaNonconvex/NonconvexUtils.jl. Copyright stays with the author.
AGENTS.md
This file provides general meta instructions for agents working with code in
this repository. Detailed project description (architecture, module structure,
build/test commands, dependencies, usage examples) lives in the Memory Bank
(memory-bank/, git-ignored) — read those files for project specifics and keep
them up to date as the project evolves.
Topic-specific guidance
opencode loads the topic-specific guidance files listed in opencode.jsonc
under instructions. They extend the guidance here with rules tailored to
specific kinds of work:
.opencode/instructions/code.md— code comments discipline, Julia generic indexing,@inboundspolicy, and NonconvexUtils.jl-specific coding notes..opencode/instructions/debug.md— fail-fast guards, Revise/MCP usage, systematic debugging approach, and AD correctness checking..opencode/instructions/architect.md— project scope, key architectural decisions, and design principles..opencode/instructions/ask.md— explanation stance, how to answer, and key NonconvexUtils.jl concepts.
Stance
- Favor fail-fast over silently trying to continue. Surface unexpected conditions so they can be inspected and understood.
- Use American spellings. Avoid jargon and metaphors not widely accepted by experts in the field. Do not make technical prose sound like a pitch deck.
Memory Bank
This project uses a Memory Bank to preserve context across agent sessions, because an agent's memory resets completely between sessions. After each reset, the agent relies ENTIRELY on the Memory Bank to understand the project and continue work effectively. The agent MUST read ALL memory bank files at the start of EVERY task — this is not optional.
Memory Bank Structure
The Memory Bank lives in memory-bank/ (git-ignored) and consists of core files
in Markdown, building on each other in a clear hierarchy:
projectbrief.md— Foundation document; core requirements and goals; source of truth for project scope.productContext.md— Why this project exists; problems it solves; how it should work; user experience goals.activeContext.md— Current work focus; recent changes; next steps; active decisions and considerations; important patterns and preferences; learnings.systemPatterns.md— System architecture; key technical decisions; design patterns in use; component relationships; critical implementation paths.techContext.md— Technologies used; development setup; technical constraints; dependencies; tool usage patterns.progress.md— What works; what's left to build; current status; known issues; evolution of project decisions.
Create additional files/folders within memory-bank/ when they help organize
complex feature documentation, integration specs, API docs, testing strategies,
or deployment procedures.
Memory Bank Updates
Memory Bank updates occur when:
- Discovering new project patterns.
- After implementing significant changes.
- When the user requests with update memory bank (MUST review ALL files).
- When context needs clarification.
After every memory reset, the agent begins completely fresh. The Memory Bank is the only link to previous work. It must be maintained with precision and clarity, because the agent's effectiveness depends entirely on its accuracy.
Julia development
- Use the local
Project.tomlenvironment (--project=.). Revise, TestEnv, Cthulhu, and other developer-oriented tools live in the global (fallback) environment. - Do not bias decisions about packages based on what is already installed.
- When adding new packages to the local project, also update the
[compat]section ofProject.tomlto bound the version of the new dependency. After editingProject.toml, runPkg.resolve(). Resolver errors sometimes indicate package conflict;Pkg.update()can fix such errors. - Find the source for session-loaded packages with
Pkg.pkgdir(M::Module). For packages not loaded into the session, check the active project'sManifest.tomlfor the path before searching the hard drive.
Debugging Julia code
- Use
Reviseto amortize compilation cost. The MCP server runsRevise.revise()automatically before every eval, so edits to loaded packages are already applied when code runs; callingRevise.revise()yourself is redundant. Exceptions: non-Revisable packages (Revise itself and its dependencies), and one-shot measurement/benchmarking runs — in those cases run julia directly from the shell. - Use
Pkg.test()for a final run only when ready to submit a pull request.
Julia style guide
- Avoid being unnecessarily restrictive about method arguments.
f(A::Matrix{Float64})silently excludes sparse matrices, GPU arrays,Float32, dual numbers, and anything else that would work fine — the caller gets a confusingMethodErrorinstead. Annotate only as specifically as the implementation requires: useMatrix{Float64}only when accallor similar demands a specific memory layout and element type; useAbstractMatrixwhen 2-D structure matters; useAbstractArraywhen it does not; leave unannotated when the method works for any input. Annotate to control dispatch and resolve ambiguities, not to document intent. - The same caution applies to parametric
structconstructors. Write the inner constructor with unconstrained value arguments —MyStruct{A,B}(a, b) where {A,B}, not(a::A, b::B)— and let the field declarations andnewdo the coercion; constraining the arguments breaks calls likeMyStruct{Float64}(1, 0). Outer constructors should only compute type parameters and delegate inward, forming a cascadeMyStruct(args...)→MyStruct{A}(args...)→MyStruct{A,B}(args...)so every call form coerces identically. Somestructs have trailing type-parameters that are primarily internal, conferring inferrability but not usually manipulated by users; the cascade should leap over these by calling the inner constructor directly,MyStruct{A,B}(args...)→MyStruct{A,B,typeof(c),typeof(d)}(args...), wherecanddhave already beenconverted to types consistent withAandB. - Avoid redundant keyword syntax: when a variable name matches the keyword
argument name, use the short form
f(; max_iter)instead off(; max_iter=max_iter). This applies at function call sites,NamedTupleconstruction, and similar contexts. @test_throws SomeExceptionType exprmay be worth testing whenSomeExceptionTypeprovides meaning, but@test_throws "message that clearly explains the problem to users" expris typically the more relevant target for testing. There are cases where it may be reasonable to test both.
Devops
- Do not post comments on GitHub without getting explicit approval for the exact text. GitHub is also a social media environment; do not represent the maintainer without consent.
- Any post made on the maintainer's behalf (GitHub issue, PR, comment, review, or other public message) must disclose that it was prepared with assistance from AI and name the model and the harness/tool that produced it (e.g. "Prepared with assistance from GLM-5.2 via opencode"). Do not present AI-assisted text as the maintainer's own unaided writing.
- Comments, docstrings, and commit messages must stand on their own for a
reader who has only the repository: state what is true about the code now,
not its history, its motivation, or the plan it came from. Re-read the diff's
comments before proposing a commit. Full guidance and examples:
.opencode/instructions/code.md(Code comments). - Commit subject lines should ideally be shorter than lines in the body (aim for ≤ 50, up to 72 OK) due to formatting on GitHub.
- Changes motivated by GitHub issues or PRs should include a comment with the corresponding issue number. Do not put the issue number in the subject line, as that can be confusing in conjunction with a merge-squash that inserts the PR# in the subject. If the commit fixes an issue, put "Fixes #xyz" or similar in the body of the commit message; that will trigger GitHub to auto-close the issue. If a commit closes multiple issues, you cannot provide ranges or comma-separated lists of numbers; use "Fixes #abc; fixes #def; ...".
- For commits written by agents, use "Assisted-by" rather than "Co-authored-by", and fill in the appropriate model/version/email details.