Skip to content

Project skills (open-science-project)

The open-science-project plugin is the project-structure component. It gives Claude Code and Codex seven skills, and hooks, that work on a project made from the template. It needs git and opsci.

claude plugin install open-science-project@open-science

For Codex: codex plugin add open-science-project@open-science, then restart and review the hooks with /hooks. See Claude Code and Codex.

Always name the skills in full, for example /open-science-project:new-task (in Codex, ask for open-science-project:new-task). If your own skills directory (~/.claude/skills/, or ~/.codex/skills/ for Codex) has a skill with the same short name, the model tends to pick that one instead; open-science:onboard offers to move such skills to an archive folder.

skill use it to
open-science-project:new-project create a new project from the template
open-science-project:new-task start a task, with or without a plan
open-science-project:context-files keep the context files current and under their line caps
open-science-project:migrate-project move an existing project into the layout without losing a file
open-science-project:update-from-template take framework improvements into a project made from an older template
open-science-project:private-investigation record a side question in a private context file
open-science-project:notion keep a project's Notion mirror in sync; see Notion

open-science-project:new-project

Creates an empty project to start working in. It does not invent research goals, methods or rules: a slot it was not given content for gets a one-line TODO:.

  1. It asks for the directory, a short slug, a one-line title and the user's name, and always asks what the project is about (the question, why it matters, the approach, what counts as success, the scope, the key sources). A short answer is fine; any part can be left for later.
  2. It runs opsci template instantiate (see Project template and layout), with --no-context-management unless you use session jumps.
  3. It makes the directory a git repository and commits everything.
  4. It writes your answer into PROJECT.md under the matching headings, a 3 to 8 line summary into AGENTS.md §1, and the opening paragraph of README.md. If you named a scratch directory, batch account or notification channel, it copies config/site.example.yaml to config/site.local.yaml and fills those fields only.
  5. It reports the directory, the framework commit recorded, and every TODO: left.

It does not create a public repository or add the project to your projects page unless you ask. It never copies the template over an existing project: use open-science-project:migrate-project or open-science-project:update-from-template.

open-science-project:new-task

A task is a directory, tasks/<id>/. The id is short, lower case, and starts with a sequence number (t07-mode-fit-v2).

  1. Design. The agent asks you only the decisions that are yours: the goal, what counts as done, constraints, budget, autonomy level. It proposes one approach and names the alternatives.
  2. Directory. It runs:
opsci task new <id> --title "<title>" --plan [--depends-on <id>...] [--related <id>...] \
    [--supersedes <id>...] [--autonomy autonomous|checkpoints|collaborative] [--hold-at S2 ...]

This writes context.md with a validated node header, log.md, subcontext/ and, with --plan, plan.md from the plan template. It refuses an id that is not lower case letters, digits and hyphens, an id that exists, an edge to a node that does not exist, and --hold-at without --autonomy checkpoints. Without --plan the task has no plan, which suits small work and explorations. 3. Plan. The agent writes plan.md: goal (a "done" that can be shown false), design with rejected alternatives, constraints, delegation, one section per subtask (output directory, what it delivers, steps, gate, what is fatal), and budget. There are no absolute paths and no job-submission lines in the plan. 4. Context. It fills the task's context.md, adds the task to the project context.md, runs opsci map build and opsci context check, and commits. 5. Stop. It reports the plan to you and stops. Execution starts when you approve it.

The plan header sets how much the agent does without asking:

autonomy the main agent
autonomous (default) runs the whole plan and escalates only fatal problems
checkpoints also stops at each point listed in hold_at
collaborative also asks whenever two readings of the plan would lead to materially different work

Fatal means: a plan assumption shown false, the budget ceiling would be exceeded, an irreversible action the plan does not cover, missing access, or a result that contradicts the goal.

A brainstorm task lives under brainstorm/tasks/ (opsci task new <id> --root brainstorm) and is soft-private by default. Its node is part of the project graph, and edges may join it to project tasks. When an idea is ready to become project work, the agent creates a new project task that restates it; it never links to the brainstorm task.

open-science-project:context-files

The rule behind it: a fresh session given only AGENTS.md, the project context.md and the task's tasks/<id>/context.md can take the correct next action without asking anything. Context files hold what is true now; history goes in the logs, detail in subcontext/.

file holds cap
context.md (project) goal, task table, in flight, next step, waiting on the user, open questions 200 lines
tasks/<id>/context.md node header and the task's goal, current state, in flight, next step, pointers 200 lines
tasks/<id>/subcontext/*.md one subtask or subagent each none
tasks/<id>/log.md, log/YYYY-MM.md append-only history none
map/README.md the project's logic, hand-written 150 lines

The same caps apply to brainstorm/context.md and brainstorm/tasks/<id>/context.md.

After every finished subtask the agent answers four questions (contracts/main.md §3):

  1. Did a task's status or edges change, or did a subtask start, finish, fail or branch? Update its node header and its map.md. Did a result land, change or fail? Write or update its file in tasks/<id>/results/. A result is something later work will rely on, or something that answers part of the task's goal; a debugging finding goes only in the task's map.md, unless it matters conceptually. The agent sets milestone: true when the result obviously answers part of the project's question, and asks you when unsure. Run opsci map build, and settle every result it reports as resting on failed or superseded work.
  2. Does the next agent need to know? Update context.md.
  3. Was a source or package used or consulted? Update citations/. If a result relies on it, its key goes in that result's uses:; an assumption taken from it is a result of its own (kind: assumption).
  4. Append one line to the task log and one to log/YYYY-MM.md.

open-science-project:private-investigation

For a question you ask on the side that needs real work to answer (reading code or papers, a computation, a test run) but does not advance the project. The agent uses it when you invoke it, and on its own when such a question comes up; a question it can answer quickly it just answers.

The investigation gets its own directory, private-docs/investigations/<YYYY-MM-DD>-<slug>/, with a context.md holding the question, the state of the work and the answer, and the scripts and plots it needed. private-docs/ is never exported. The investigation is soft-private by default: the task's public context.md names the file in backticks and says when to read it, without stating the question or the findings. A hard-private investigation is listed under hard_private: in publish/manifest.yaml and is named in no exported file; private-docs/investigations/README.md indexes all of them. If the answer changes the project, the agent restates what the task needs in the task's own files.

open-science-project:migrate-project

Moves an existing project, ongoing or finished, into the layout without losing a file.

  1. It works in a git worktree on a new branch, so the original is untouched until you merge, and records every file with its hash first: opsci migrate inventory <worktree> -o <scratch>/inventory.json. It lists the files git ignores (data, outputs) with their size and asks whether, after the merge, you want them copied to their new paths or moved.
  2. It instantiates the template into a scratch directory and copies over only the files the project does not have. It then creates the migration task, tasks/t00-migration/ (soft-private), and registers the session for its context.md. That file records the worktree, the inventory, your answers and the next step, and its plan.md holds the approved mapping, so a large migration can stop and be taken over by another session with open-science-context:continue-context.
  3. It proposes a mapping (which directories become tasks; what goes to src/, data/, paper/, citations/, rules/, archive/; where each ignored file goes; the results each task will record) and waits for your approval before moving anything. Files move with git mv, so history follows them, and references to old paths are fixed.
  4. It writes a node header per task, a result file for each approved result (with what it rests on, its figures and code, and the external works it uses), each task's map.md, map/README.md, the project context.md, PROJECT.md from the project's own descriptions, and one log line, then builds the map and the claims graph.
  5. It runs opsci migrate compare <scratch>/inventory.json <worktree>, which fails if any file's content is found nowhere (a moved file counts as kept), reports, and asks you to approve the merge.
  6. After the merge it offers to copy or move the ignored files, and to mirror the project to Notion (opsci notion enable, then opsci notion init).

open-science-project:update-from-template

Takes framework improvements into a project. It is a diff against the framework commit the project was copied from, applied by hand, never a re-copy. See Updating a project.

Hooks

The Claude Code plugin installs three hooks. All act only inside a project made from the template (a directory holding both AGENTS.md and config/framework.yaml). Without jq, the line-cap hook does nothing; without python3, the human-verified guard falls back to a stricter text search of the whole request and the push guard does nothing.

hook when what it does
line cap after an agent's Edit or Write when a context.md is over 200 lines or map/README.md over 150, reports it to the agent as an error with the instruction to prune it now; after a task context edit it reminds the agent of the four questions. Needs jq
human-verified guard before an agent's Edit, Write or NotebookEdit refuses an edit after which the file sets verification: human-verified more often than before, in any YAML spelling (quotes, escapes, tags, block scalars, anchors); paths are resolved through symlinks. Needs python3; PyYAML, if installed, adds a parse of the front matter
public push guard before an agent's Bash command refuses a direct push to the public repository (see Publishing). Needs python3

Both guard against mistakes; they are not security boundaries. Bash commands are not checked by the human-verified guard. The publish check is the second line: it refuses a human-verified node whose verification: line was last changed in an agent's commit.

Codex uses separate adapters for apply_patch, including patches touching several files. They enforce the same human-verification and line-cap rules, and the same public push guard. Trust the definitions using /hooks. Shell/custom-tool edits can bypass file checks; run opsci context check and publication checks as well. Every agent commit includes Agent: claude or Agent: codex.