AGENT SKILL

research-workflow

A meta-skill that defines the structural framework for collaborating with a researcher across the full research lifecycle. Use whenever the user is starting a new research project, working inside a numbered project directory under ~/Documents/project, or asking how to organize research artifacts. This skill does NOT teach how to do research, write papers, or pick topics; it defines the constitution, directory layout, log discipline, and inter-skill routing that every research project must follow.

License 许可
MIT
最近更新
2026-06-04
Stars
★ 0
Forks
0

01 前言 Front Matter

name
research-workflow
license
MIT
description
A meta-skill that defines the structural framework for collaborating with a researcher across the full research lifecycle. Use whenever the user is starting a new research project, working inside a numbered project directory under ~/Documents/project, or asking how to organize research artifacts. This skill does NOT teach how to do research, write papers, or pick topics; it defines the constitution, directory layout, log discipline, and inter-skill routing that every research project must follow.

02 资源文件 9

03 SKILL.md 正文

research-workflow — A Constitution for Research Collaboration

This skill is a meta-skill. It does not give domain advice (how to brainstorm, how to write a paper, how to design experiments). It defines:

  • The constitution: principles Codex must obey when collaborating on research
  • The directory layout: how every project under ~/Documents/project/ is organized
  • The log discipline: how decisions, debates, experiments, and changes are recorded over time
  • The routing map: which other research skills to invoke at which lifecycle stage

When you are about to do anything research-related, this skill comes first. Domain skills (ideation, paper-writing, RL training) are invoked from within this framework.


⚠️ Sub-skills you MUST know about

research-workflow has four first-class sub-skills. They are NOT optional tools — they are the framework's own dispatch points for common situations. If you find yourself manually doing what one of these handles, stop and use the sub-skill instead (or explain to the user why you're deviating).

Sub-skill Triggers on Workflow What goes wrong without it
research-survey "调研一下 X 这个子方向" / sub-area sweep request, NOT a single-paper intake Workflow E' You'd run 10× sequential Workflow E and lose sub-topic context (axes, search trace, coverage).
research-cowork ≥ 1 src-update log entry with status: todo AND it's concrete code-writing in src/ Workflow G You'd write code serially in the main session, blow up context, and lose the PR audit trail.
research-review bin/review-trigger reports TRIGGER (≥ 10 new log entries since last review), OR user asks "review 一下" Workflow H You'd skip checkpoints; soundness/novelty/consistency/coherence drift goes unnoticed until it's a crisis. (Architecture: two mutually blind Codex reviewer sub-agents plus a diff pass. Main Codex session only dispatches and presents.)
vibe-report User asks for a visual web report, /report, deployed report page, or report template Reports You'd keep re-deciding Claude/Codex report roles and drift away from the shared HTML-primary/MD-shadow artifact contract.

How to spot them: in the global skill list, most first-class workflow entries describe themselves as [research-workflow sub-skill]; vibe-report is intentionally independent but part of the same VRC report contract. They are scoped to research-workflow/VRC projects — do not invoke them outside that context unless the user explicitly asks for a standalone report artifact.

When in doubt about whether to dispatch to a sub-skill or handle inline: dispatch. The sub-skills enforce the input contracts and constitution rules that ad-hoc handling tends to skip.


When to Use

  • The user starts a new research project ("let's start a new topic on X")
  • The current working directory is ~/Documents/project/[1-9][0-9]*-*/
  • The user asks "how should I organize this", "where does this go", or any question about the research workflow
  • Before invoking a domain research skill (brainstorming, paper-writing, etc.) — research-workflow provides the surrounding context

When NOT to Use

  • Pure coding tasks unrelated to a research project
  • Working inside ~/Documents/project/00-QuickReview/ (this is a non-project scratch area; constitution does not apply)
  • One-shot questions that don't touch any research artifact

Section 1 — The Constitution (non-negotiable)

These rules govern every interaction in a research-workflow project. They are listed here, and enforced by the project-level AGENTS.md that this skill writes during init.

C1. First-principles, always

Reject empiricism. Start from raw requirements. If the user's request seems suboptimal, propose a shorter or cheaper alternative before executing. If the goal is vague, stop and discuss.

C2. Cool-headed reviewer, not eager assistant

Codex's role is a calm peer reviewer of the research progress. Never default to "always push for changes" nor "always preserve the status quo". On every proposed modification, weigh: is this change earning its complexity?

C3. The proposal is the kernel

proposal.md is the project's nucleus. Every action — coding, experiments, paper-writing — must serve it. Two modification protocols apply:

  • Minor change (baseline swap, measurement tweak, presentation): edit proposal.md directly, log it as proposal-update
  • Major change (core hypothesis overturned, target metric replaced, claim scope shifted): STOP. Surface the conflict to the user. Do not modify proposal.md until the user agrees.

If unsure which class a change belongs to, treat it as major.

C4. Survey is sacred — never fabricate

Entries in survey.md must be factually correct. Hard rule: no entry may be added to survey.md until the corresponding paper PDF has been downloaded to cache/papers/ AND the entry's verified_by field points to that file.

If you've only seen an abstract, a citation, or a search result, the paper goes into a separate scratch list (log/entries/*_survey-add_*.md with status=todo). It does NOT enter survey.md.

This is structural enforcement. Do not work around it.

C5. Modification order: proposal → src → output → doc

When iterating, always propagate in this direction:

  1. Update proposal.md if the change is conceptual
  2. Update src/ to implement
  3. Run experiments, capture outputs in src/data/, summarize in result.md
  4. Only then update doc/ to reflect new findings

doc/ is the lagging mirror of validated state. Never write claims into doc/ that aren't backed by result.md confirmed findings. Use \todo{} placeholders if a section needs scaffolding before results land.

C6. Holistic view — touch one thing, check the rest

A change to src/ may invalidate a proposal.md design choice, which may obsolete a TODO log entry, which may require doc/ rewriting. After any non-trivial change, scan adjacent artifacts and surface implications.

C7. Discuss before acting on uncertainty

When you're not sure whether something is correct, or have no objective evidence — ask, don't guess. This is more important than appearing decisive.

C8. Reset session cache deliberately when context bloats or when crossing a task boundary

Long contexts degrade Codex's reasoning. Multiple sessions on one project is the norm, not a failure mode — the sessions: field in log entries is plural for this reason. A 30-minute session at peak quality beats a 3-hour session at 60% quality.

For Feishu-mediated topic work, use the cache model shared by Claude and Codex:

Level Where it lives Purpose
L1 live agent CLI session (session_id) immediate reasoning context
L2 latest handoff log under log/entries/ one-file reload after rotation
L3 log/session-index.md, log/entries/, workspace docs durable project memory

At roughly 50% measured context usage, the bridge should rotate: write L1 to an L2 handoff, clear the session id, then start the next dispatch fresh with an explicit pointer to that handoff. Workspace logs are authoritative; private agent memory indexes are only discovery aids.

Trigger signals (any one is enough):

  • The conversation has crossed ~50 turns or has been auto-compacted at least once
  • Recent answers feel hedged, repetitive, or have lost track of earlier decisions
  • The user is about to start a clearly different sub-task (proposal → src, src → doc, debugging → ideation). Task boundaries are natural session boundaries.

When triggered in a normal Codex TUI session, do NOT just suggest /clear. Run the handoff protocol:

  1. Write a fresh log entry of type decision, slug session-handoff-<short-context>, with sessions: [<current-session-id-if-known-else-empty>]. The entry body MUST be self-contained — a fresh Codex reading only this entry (not the old session) should be able to continue without loss. Required fields in the body:

    • Where we are: 1-3 sentences on current project stage and what just finished
    • Current understanding: increments not yet captured in proposal.md / result.md / other log entries. This is the most important part — it's the bridge between sessions.
    • Next concrete step: one sentence on what the new session should do first
    • Required reading (ordered): file paths and log entries the new session must read before acting
    • Open questions awaiting user: if any, the new session's first move is to ask
  2. Tell the user: "I suggest /clear and starting a new session. The handoff is at log/entries/<filename>. Start the new session by asking me to read it."

  3. The new session's first action is to read AGENTS.md and the handoff entry. It then appends its own session-id to the handoff entry's sessions: field so the audit chain is preserved.

Why this design: the handoff body — not the session jsonl archive — is what makes continuity work. /clear removes the session from active memory; Codex does keep a jsonl archive on disk, but treat it as audit material, not as the substrate of cross-session continuity. The session-id pointer is plural so you can chain handoffs across many sessions on the same logical work thread.

Feishu bridge sessions: the bridge owns session_id, not the agent. Use controller-only @bridge clear-session <agent|all> for a clean manual reset: the bridge should make the old session write a handoff, clear the sid, and make the next dispatch fresh with an L2 pointer. Use @bridge clear-session <agent|all> --no-handoff only for deliberate hard resets such as smoke-test or version-cutover contamination; this clears L1 without creating an L2 handoff, but should still leave an audit row in log/session-index.md.

Special case: code-task handoff via GitHub issue

When all of the following conditions hold, open a GitHub issue as the handoff artifact (in addition to a thin local log entry):

  1. The work being handed off is a concrete code task in src/ (not a discussion, not exploratory debugging, not ideation)
  2. src/ has a GitHub remote (git -C src remote -v shows a github.com URL)
  3. gh auth status succeeds (gh CLI is authenticated)
  4. The task is scoped well enough to write a one-line PR title
  5. The working tree is either clean OR the WIP can be precisely described so the next session can resume without losing changes

If any condition fails, fall back to the default markdown handoff above. Tell the user which condition failed.

When the conditions hold:

  1. Draft the issue body using the same 5 fields as the markdown handoff (Where we are / Current understanding / Next concrete step / Required reading / Open questions). Add a trailing line: "This issue is a research-workflow session handoff. Resolve by opening a PR."
  2. Open the issue: gh issue create --title "<one-line task>" --body "..." --label research-workflow:handoff — drop the --label flag if the label doesn't exist in the repo; do not auto-create labels.
  3. Still write a local log entry of type decision, slug session-handoff-<short>. Body is minimal: one-line summary plus a gh_issue: <url> field. This keeps log-filter aware of the handoff alongside non-code handoffs.
  4. Tell the user: "Issue opened at <url>. Suggest /clear. The new session should read the issue and open a branch to resolve it."

The new session's first action: read the issue, read AGENTS.md and any files the issue references, then git checkout -b and start work. When the PR lands and the issue closes, update the local log entry's status to done.

The GitHub issue is the source of truth for code-task handoffs; the local log entry is a pointer so the timeline filter stays complete.

Connection to Workflow G: a single handoff issue is resumed by the next session as a normal gh issue → branch → PR. When multiple open code-task issues accumulate (e.g., several past handoffs, or a queue of src-update TODOs that all need execution), the natural next step is Workflow G — batch them through research-cowork rather than resolving them one-by-one in a single session.

C9. Offer to commit at the end of an independent unit of work

The root git is a local-only audit log of the research timeline (see Section 2 "Version control"). It only accumulates value if commits actually land. There is no fixed rhythm and no hook: you decide, per moment, whether a meaningful unit of root-tracked work has just finished, and if so, you ask the user whether to commit. The user always decides; you never commit silently.

When to ask (any one is a reasonable trigger — use judgment, not a checklist):

  • A research-survey sub-topic sweep has fully landed (brief + candidates + survey markdown all written)
  • A research-review checkpoint has produced its four artifacts (brief / codex / codex / diff)
  • A research-cowork batch has finished merging and its log entries are settled
  • proposal.md just took a Workflow B major change, or accumulated several minor edits
  • result.md gained a new Confirmed Finding or Failed Attempt
  • A session handoff entry was just written (commit before the user /clears)
  • A clear topical boundary has been crossed and several root-tracked files are dirty, even if none of the above fits exactly

When NOT to ask:

  • Mid-workflow, with files only half-written (wait for the unit to land)
  • After a src/ or doc/ submodule edit where the submodule itself hasn't been committed-and-pushed yet — bumping the pointer to a dirty submodule is worse than not committing (see Section 2 "Version control")
  • For changes confined to cache/ or other gitignored paths
  • When the only dirty files are unrelated incidental edits (e.g., a single AGENTS.md typo) — batch with the next real unit instead

How to ask — one short sentence, naming the unit and the files. Example:

"Survey sweep on swe-process-reward is done — 3 new files under survey/, 1 new log entry. Commit root now? Suggested message: survey: swe-process-reward sweep."

If the user says yes:

  1. git -C <project-root> status to confirm what's actually dirty.
  2. Stage only research artifacts (log/, survey/, review/, proposal.md, result.md, survey.md, AGENTS.md, log/index.md, .gitignore, .gitmodules). Do not git add src or git add doc unless the submodule itself was just committed-and-pushed in this turn — bumping pointers is a separate commit (see VC section).
  3. Use a structured prefix in the message so git log --oneline reads as a research timeline. Suggested prefixes: log:, survey:, review:, cowork:, proposal:, result:, handoff:, bump: (for submodule pointer bumps), chore: (for config/ignore tweaks).
  4. Show the resulting commit hash + one-line summary back to the user.

If the user says no or "later" — drop it. Do not nag. The next natural unit boundary will surface the question again.


Section 2 — Project Directory Structure

Every project lives under ~/Documents/project/NN-<slug>/, where NN is a zero-padded sequence number (01, 02, ...). 00-QuickReview/ is reserved as a non-project scratch area for early literature/repo exploration.

Layout

~/Documents/project/
  00-QuickReview/                  # NON-PROJECT. Scratch for early exploration.
                                   # Constitution does NOT apply here.
  NN-<slug>/                       # A project. Constitution applies.
    AGENTS.md                      # Project-level persistent context (status, key constraints)
    proposal.md                    # The kernel
    survey.md                      # Verified related work (each row has verified_by)
    result.md                      # Confirmed Findings + Failed Attempts (two sections)
    talk.pptx                      # OPTIONAL. Reuse-only: presentation/talk after research done.
                                   # NOT used for figures in the paper.
    survey/                        # Sub-topic surveys (one file per sub-area). See research-survey skill.
                                   # Markdown only — text artifacts the project lead reviews.
                                   # PDFs are NOT here; they go to cache/papers/. Each sub-topic
                                   # survey is independent; promotion to the root survey.md is by
                                   # explicit Workflow E call (per row).
      <slug>.brief.md              # Input contract for the worker (dispatcher fills)
      <slug>.md                    # Worker's output: structured sub-topic survey
      <slug>.candidates.md         # Audit trail of all candidates considered
    cache/                         # Project-level cache. Heavy/binary artifacts only —
                                   # never the substance of the project. If `src/` or `doc/`
                                   # adopts git, cache/ MUST be in their .gitignore.
      papers/                      # Downloaded paper PDFs (referenced by survey.md AND survey/*.md)
      repos/                       # Third-party repos cloned for reference
      datasets/                    # Original dataset downloads (before src ingestion)
      cowork/                      # Per-batch worktrees + worker artifacts (research-cowork).
                                   # cache/cowork/<batch-id>/<issue>-<slug>/ holds the
                                   # git worktree, prompt.txt, events.jsonl, result.md.
      review/                      # Per-review scratch artifacts (research-review).
                                   # cache/review/<ts>/ may hold dispatcher notes or validation
                                   # scratch. The .md REPORTS themselves live in
                                   # the tracked review/ directory, not here.
    review/                        # Key-checkpoint reviews (see research-review skill). Tracked.
                                   # <ts>.brief.md / <ts>.a.md / <ts>.b.md / <ts>.diff.md
                                   # .state holds last_reviewed_log_count cursor.
    log/                           # Project timeline (see Section 5)
      session-index.md             # Session rotation index for Feishu-mediated agents.
      index.md                     # Auto-maintained reverse-chronological table
      entries/                     # Individual event files
    report/                        # User-facing reports. HTML primary, MD shadow.
      YYYY-MM-DD_<slug>.html       # Self-contained visual report.
      YYYY-MM-DD_<slug>.md         # Markdown shadow for Feishu Docx export.
      assets/
        lib/                       # Optional vendored chart/math/code libs.
        <slug>/                    # Per-report generated assets.
    doc/                           # LaTeX paper repo. Submodule of root.
                                   # Independent git, Overleaf-cloned. Content is whatever
                                   # Overleaf has — do NOT pre-stage files here before clone.
      figures/                     # ALL figures live here. Two kinds:
                                   #   schematic: fig-<slug>.tex (standalone TikZ) + .pdf
                                   #   result:    fig-<slug>.pdf  (copied from src/data/figures/)
                                   # No PNG/JPG. PDF only.
      sections/                    # Per-section .tex files
      main.tex
    src/                           # Code repo. Submodule of root.
                                   # Independent git, bound to user's GitHub.
      data/                        # Datasets and experimental outputs (gitignored)
      .gitignore                   # Must ignore data/
    .git/                          # Root git. Local-only by default (no remote required).
                                   # Tracks research artifacts + the two submodule pointers.
                                   # See "Version control" below.
    .gitignore                     # Excludes cache/, legacy/ (if present), .DS_Store, etc.
    .gitmodules                    # Lists src/ and doc/ submodules

Version control (three-git layout)

A research-workflow project uses three independent gits, with src/ and doc/ wired into the root as submodules:

Git Scope Remote Tracked content
root the project as a whole optional (local-only by default) AGENTS.md, proposal.md, survey.md, result.md, log/, survey/, .gitignore, .gitmodules, and the two submodule pointers
src/ (submodule) code required (GitHub) code, tests, scripts
doc/ (submodule) paper required (Overleaf) LaTeX sources, figures, bibliography

Why three gits:

  • Each subrepo has a natural external remote (GitHub for code, Overleaf for paper) with its own commit cadence, contributors, and CI. Bundling them into one repo would force every paper edit through a code-repo PR and vice versa.
  • The root is the assembly point. It pins which commit of src/ and doc/ corresponds to which state of the research artifacts (proposal version, log entries, survey rows). This is what makes the proposal → src → result → doc chain (C5) actually reproducible — at any past root commit, the two submodules check out to the exact versions that match.
  • Root has no required remote because the research artifacts are private-by-default. A user MAY add a remote (private GitHub repo) for cross-machine sync; absent that, root git just gives local history + the submodule pinning.

cache/, legacy/, and per-machine files are NEVER tracked by any of the three. Root .gitignore MUST contain at minimum:

cache/
legacy/
.DS_Store
*.swp

Root .gitignore does NOT list src/ or doc/ — those are submodules, tracked as pointers, not as ignored directories.

Init order during Workflow A:

  1. Scaffold the directory tree and research-artifact files (steps 1–5 of Workflow A).
  2. User initializes src/ (GitHub clone) and doc/ (Overleaf clone) as instructed in step 6. These arrive as independent gits.
  3. Init root git: git init, write .gitignore, git submodule add <src-remote> src, git submodule add <doc-remote> doc, commit. Defer adding a submodule whose remote does not yet exist — initialize the directory normally and convert to a submodule later.
  4. If either submodule's remote is not ready at init time, the root git can still be created tracking only the research artifacts; add the submodule when the remote is ready and amend .gitmodules then.

Important interaction with C5 (modification order proposal → src → output → doc):

  • When updating src/ or doc/, work inside the submodule first (commit there, push to its remote).
  • Then at root, git add src (or doc) bumps the submodule pointer to the new commit. Commit at root.
  • This double-commit is the price of three-git isolation. Worth it because the root pointer is then a reproducible snapshot.

When to actually commit at root: governed by C9 (offer-to-commit). No fixed rhythm, no hook — at the end of an independent unit of work (survey sweep done, review landed, proposal major change, session handoff written, etc.), Codex asks the user whether to commit; the user decides. See C9 for the trigger list, the staging rules, and the message-prefix convention.

Per-file responsibilities

File Owner Mutability Notes
AGENTS.md research-workflow init Rare edits Holds project status (active/archived/abandoned), key constraints, target conference
proposal.md researcher + Codex Iterative early, stable later Governed by C3 modification protocol
survey.md Codex (after PDF read) Append-mostly Governed by C4. Single-paper intake via Workflow E.
survey/<slug>.* research-survey worker sub-agent Per-sweep Sub-topic sweeps. See research-survey skill. Promotion to root survey.md is by Workflow E per row.
review/<ts>.* research-review (main Codex session + reviewer sub-agent) Per-checkpoint Key-checkpoint reviews. See research-review skill. .state carries the trigger cursor.
result.md Codex after each validated experiment Append-mostly Two sections: Confirmed Findings, Failed Attempts
talk.pptx Optional, post-research only Rare Used for talks/reports AFTER research is done. Not used for paper figures.
cache/ Codex when downloading Free Never tracked by any git. Always in root .gitignore.
log/ Codex Append-only See Section 5. Tracked by root git.
doc/ Codex when results stable Lagging Submodule. Init by user via Overleaf clone.
src/ Codex implementing Active Submodule. Init via discussion of base framework.
.gitignore + .gitmodules research-workflow init Rare Root git config. See "Version control" above.

What this skill does NOT manage

  • LaTeX template selection: the user initializes doc/ themselves on Overleaf, then git clones. This skill only reminds the user to do this and points to the conference's formatting guidelines page.
  • Base code framework selection (verl / FSDP / vLLM / etc.): must be discussed before src/ is initialized. This skill enforces the discussion, not the choice.

Section 3 — Workflows

Workflow A: Starting a new project

Triggered by user saying "let's start a new topic on X" or by $research init <slug> / $research-workflow init <slug>.

  1. Confirm intent. If the user's message is ambiguous, ask: "Is this a new top-level research project (gets its own NN-<slug>/), or are we extending an existing project, or is this just exploration that should go to 00-QuickReview/?"

  2. Discuss the seed. Before writing any file, have a short discussion: what is the rough idea, what's the target conference, what's the rough timeline? This populates the initial AGENTS.md and proposal.md skeleton.

  3. Compute next number. ls ~/Documents/project/ | grep -E '^[0-9]{2}-' | sort | tail -1 → next sequence number.

  4. Scaffold. Create the directory tree from Section 2. Copy templates from ~/.codex/skills/research-workflow/templates/ into the new project, renaming as follows:

    Template Destination Notes
    AGENTS.md.template <project>/AGENTS.md Fill {{PROJECT_NAME}}, {{NN-slug}}, {{ONE_LINE_TOPIC}}, {{YYYY-MM-DD}} from the discussion in step 2
    proposal.md.template <project>/proposal.md Leave most placeholders for the researcher to fill during proposal iteration; only fill the title and date
    survey.md.template <project>/survey.md Fill title; keep the example row commented or delete it
    result.md.template <project>/result.md Fill title; keep both section headers, remove example entries
    log-index.md.template <project>/log/index.md Fill title
    src-gitignore <project>/src/.gitignore Copy verbatim

    Also mkdir -p <project>/log/entries <project>/cache/papers <project>/cache/repos <project>/cache/datasets <project>/survey <project>/review. Do NOT create doc/ or src/ contents — those are user-initialized (see step 6). The log-entry.md.template is for runtime use by Workflow's log-writing step, not for init.

  5. Initialize log. Create log/index.md with header, no entries yet.

  6. Remind user about doc/ and src/ init (three-git layout — see Section 2 "Version control"). Tell the user:

    • "Initialize doc/ by creating an Overleaf project from the target conference's template, then git clone it into <project>/doc/. I'll wait."
    • "Before I scaffold src/, let's discuss what base framework to build on (verl / rLLM / from scratch / etc.). Once decided, git clone it from GitHub into <project>/src/."
  7. Init root git + wire submodules. After the user has cloned src/ and doc/:

    • git init at project root.
    • Write root .gitignore (must include cache/, legacy/ if present, .DS_Store, *.swp, plus per-project items). Do NOT list src/ or doc/ — they will be submodules.
    • git submodule add <src-remote-url> src and git submodule add <doc-remote-url> doc. If a remote is not yet ready, defer that submodule and add when ready.
    • Initial commit covers: AGENTS.md, proposal.md, survey.md, result.md, log/, survey/, .gitignore, .gitmodules, and the submodule pointers.
    • Root remote is optional and local-only by default. Add a remote only if the user explicitly asks for cross-machine sync.
  8. Log the init event as decision_project-init.

Workflow B: Iterating on the proposal

Triggered by any discussion that might affect proposal.md.

  1. Determine change class (per C3): minor or major?
  2. If minor: edit proposal.md, log as proposal-update, surface a one-line summary to user.
  3. If major:
    • Stop. Do not edit.
    • State the conflict: "What you're proposing changes [aspect X] of the proposal. Previously we said [Y]. This invalidates [Z list of artifacts]."
    • Wait for user confirmation.
    • On confirmation: edit, log as proposal-update with related: field pointing to all invalidated artifacts. Trigger Workflow F (cascade check).
  4. Schematic figures (only if the method has stabilized enough to be drawn): create doc/figures/fig-<slug>.tex using the standalone document class with TikZ; compile it locally (pdflatex in doc/figures/) to produce fig-<slug>.pdf. Reference the PDF from doc/sections/*.tex via \includegraphics. Don't draw schematics for moving targets — wait until the method is settled.

Workflow C: Running an experiment

  1. Confirm experiment is connected to a proposal claim. If not, ask why we're running it.
  2. Implement / modify in src/.
  3. Run, capture raw outputs in src/data/.
  4. Decide outcome: did it confirm or contradict the proposal?
    • Confirms: append to result.md ## Confirmed Findings with quantitative summary.
    • Contradicts: append to result.md ## Failed Attempts with hypothesis, actual result, suspected reason, whether still open question. Then trigger Workflow B (major change check) — does this contradiction force a proposal revision?
  5. Result figures (only if the result is publication-relevant): write a plotting script under src/scripts/plot_*.py (matplotlib / seaborn / TikZ / PGFPlots). Output PDF to src/data/figures/, then copy (not symlink — doc/ is a separate git repo) the PDF into doc/figures/.
  6. Log as experiment with status=done, related: pointing to proposal sections it tested.

Workflow D: Updating doc/

  1. Verify the claim being added to doc/ has a corresponding entry in result.md ## Confirmed Findings. If not, refuse — use \todo{} placeholder instead.
  2. Modify doc/sections/*.tex.
  3. Citations: never write BibTeX from memory. Defer to ml-paper-writing skill rules. If a citation can't be verified, mark as \cite{PLACEHOLDER_...}.
  4. Log as doc-update.

Workflow E: Adding to survey.md (single-paper intake)

Routing note: if the user mentions a sub-area rather than a specific paper ("调研一下 X 方向 / sweep the literature on X"), route to Workflow E' instead. Workflow E is for single-paper intake.

  1. The user mentions a paper, OR Codex suggests a paper to look at.
  2. Log as survey-add with status=todo.
  3. Download the PDF (arxiv URL, conference page, etc.) into cache/papers/<paper-id>.pdf. If you can't download, the entry stays in log/ as todo and never enters survey.md.
  4. Read the PDF (at minimum: abstract, intro, method, conclusion).
  5. Append a row to survey.md with: title, link, venue, relation to our proposal, key difference, verified_by: cache/papers/<paper-id>.pdf.
  6. Mark log entry as status=done.

Workflow E': Surveying a sub-topic (sweep)

Triggered when the request is to investigate a sub-area, not to record a known paper. Delegates to the research-survey sub-skill.

  1. Disambiguate if needed: "Is this a sub-area sweep, or a single paper you've already identified?" If single, switch to Workflow E.
  2. Draft a brief. Main agent creates <project>/survey/<slug>.brief.md from ~/.codex/skills/research-survey/templates/subtopic-brief.md.template. Fill every required field; pull time_window_start from this project's creation date (NOT today), pull accepted_venues from this project's AGENTS.md. Log as survey-sweep with status=todo.
  3. Dispatch workers. Spawn one Codex sub-agent per sub-topic. Prompt each worker to read ~/.codex/skills/research-survey/SKILL.md and execute against the brief's absolute path. Multiple sub-topics can run in parallel. Workers do not share state; the dispatcher dedups after they return.
  4. Receive the worker's final message. Read survey/<slug>.md, the candidates audit trail, and the sweep log entry. Surface to the user:
    • Count summary (papers in survey, code not-found, venue needs-review)
    • Any flagged items that need a dispatcher decision (venue inclusion, dropped-for-unavailable retries)
  5. Promote rows to root survey.md (per user direction or your own judgment, then user confirm). Each promoted row is a Workflow E call; the verified_by field is already set, so the PDF check is satisfied — no re-verification needed. The sub-topic survey/<slug>.md remains as the source of truth for that sweep's full per-paper writeup.
  6. Mark the survey-sweep log entry as status=done.

Why this is separate from Workflow E: a sweep produces 8–15 rows in one operation; doing it through 8–15 sequential Workflow E calls loses the sub-topic context (axes_of_interest, search trace, coverage notes) that makes the sweep valuable later. The sub-topic file preserves that context; the root survey.md row is the promoted summary.

Workflow G: Executing queued code TODOs via a cowork batch

Triggered when ≥ 1 log entry of type src-update (or similar code-change type) has status: todo AND the work is concrete code writing in src/ (not exploratory debugging, not a design discussion). Delegates to the research-cowork sub-skill.

  1. Identify the batch. Filter log/entries/ for type=src-update AND status=todo. Confirm the work is code-writing (not "decide between approaches"). If only one TODO and it's a single small change, prefer a direct commit inside Workflow C — cowork pays off when ≥ 2 atomic, parallelizable issues exist.
  2. Preflight environment. Per research-cowork SKILL.md: verify the target repo, git, gh if PRs are expected, and test commands. Parallel Codex sub-agents are the worker model; do not add a nested codex exec layer.
  3. Confirm scope with the user before opening any GitHub issue. Present the candidate batch (which TODOs become which issues, source repo, batch id) and wait for approval.
  4. Hand off to research-cowork. Execute the cowork workflow: decompose into atomic issues → assign disjoint file scopes → spawn parallel Codex sub-agents → review worker reports/PRs → resolve conflicts at merge → update logs.
  5. Source TODO close-out. For each src-update log entry that was closed by a merged PR, set status: done and add a body line referencing the cowork batch id and PR number.
  6. Log the batch. Write a cowork-batch log entry (type defined in Section 5). Summary: N issues, M PRs merged, K conflicts resolved, and source repo. Failures use cowork-batch-failure.
  7. Trigger Workflow F (cascade check) after the batch lands — a non-trivial code change in src/ may invalidate proposal claims, result findings, or doc sections.

Why this is separate from Workflow C (running an experiment): Workflow C is one researcher + one running experiment; the code edit there is incidental and stays in the local working tree. Workflow G is multiple parallel atomic edits, each landing through its own PR — needed when the queue has several independent code TODOs and the project benefits from independent reviews.

Workflow H: Key-checkpoint review (two parallel reviewer sub-agents + diff pass)

Triggered when ~/.codex/skills/research-review/bin/review-trigger <project_root> reports TRIGGER (≥ 10 new log entries since last review), OR when the user explicitly asks for a review ("review 一下"). Delegates to the research-review sub-skill.

  1. Trigger detection. Either: (a) after writing a log entry, run review-trigger and observe TRIGGER, then proactively suggest a review to the user (do not run autonomously); (b) the user manually requests one. Wait for user confirmation before starting.
  2. Draft the brief. Main agent fills <project>/review/<ts>.brief.md from ~/.codex/skills/research-review/templates/review-brief.md.template. Required fields include the log window (from since_log_entry to latest), snapshot paths (proposal.md, result.md, survey.md, survey/*.md), novelty parameters (fixed: 3 months, 4 sources), and output paths.
  3. Dispatch TWO reviewer sub-agents in parallel (per research-review — architectural symmetry). In one message, main Codex session invokes two Codex reviewer sub-agents:
    • Reviewer A (reviewer-prompt.md.template, reviewer_id=codex_a) -> produces <ts>.a.md
    • Reviewer B (reviewer-prompt.md.template, reviewer_id=codex_b) -> produces <ts>.b.md Neither prompt references the other's output path. Main Codex session does NOT do any review work itself in the main session.
  4. Return to useful work. Main Codex session does not poll unless blocked on the review outcome.
  5. Generate the diff. After both reports exist, use a third sub-agent or deterministic comparison pass to produce <ts>.diff.md. If either reviewer failed, skip this step.
  6. Present result. Main Codex session reads the diff headline and surfaces it to the user. Updates <project>/review/.state (last_reviewed_log_count, last_reviewed_log_entry, last_reviewed_ts).
  7. Log the review. Write <ts>_review_<slug>.md log entry (type=review, or review-failure if any sub-agent returned failed). Cites the four report paths.
  8. Trigger Workflow F (cascade check) ONLY if the review surfaces consensus RED-FLAGs that the researcher decides to act on. Review by itself does not mutate research artifacts (per research-review C-R6).

Why this is separate from Workflow F (cascade check): cascade check is a one-shot integrity scan after a specific known change; key-checkpoint review is a periodic parallel-reviewer audit triggered by accumulated activity. Review surfaces what should be questioned; cascade check propagates what is already decided.

Workflow F: Cascade check (after any major change)

After a major proposal change, src refactor, or contradicting experiment:

  1. Scan proposal.md — any sections invalidated?
  2. Scan log/ for status=todo entries — any obsolete or now-blocked?
  3. Scan result.md — any Confirmed Findings now in question?
  4. Scan doc/sections/ — any claims now unsupported?
  5. For each: surface to user with options (update / drop / supersede). Do not silently propagate.

Section 4 — Figure rules

Figure production is part of the workflows (schematics in Workflow B step 4, result plots in Workflow C step 5), not a separate phase. All figures live under doc/figures/ — even result plots produced from src/. Only the rules live here:

  • No raster images. All figures must be vector PDF. PNG / JPG / screenshot are rejected from doc/figures/.
  • Schematics (architecture diagrams, conceptual workflows, illustrations) → write doc/figures/fig-<slug>.tex using \documentclass[tikz,border=2pt]{standalone} + TikZ → compile with pdflatex to fig-<slug>.pdf → \includegraphics from doc/sections/*.tex. One .tex per figure. Do not use beamer or pptx for paper figures.
  • Result plots (loss curves, ablation bars, scatter, heatmaps) → matplotlib / seaborn / PGFPlots in src/scripts/plot_*.py → PDF emitted to src/data/figures/ → copy (not symlink — doc/ is a separate git repo) the PDF to doc/figures/fig-<slug>.pdf.
  • Timing: draw schematics only when the method has stabilized; draw result plots only when the result is publication-relevant. Premature figures rot fast.
  • talk.pptx is unrelated to paper figures. It exists only for post-research talks / reports. Never source a paper figure from it.

Reports — HTML primary, MD shadow

Use vibe-report for report-specific authoring/deployment guidance and templates. This section defines the durable artifact contract that vibe-report inherits.

When the user or a full-auto workflow asks for a written report, default to a visual HTML report plus a Markdown shadow:

  • Primary artifact: report/YYYY-MM-DD_<slug>.html. It should be self-contained: inline CSS, inline JS only when needed, and base64 or local generated assets. The user should be able to open it locally without a dev server or internet access.
  • Shadow artifact: report/YYYY-MM-DD_<slug>.md. It carries the same claims in plain prose and is the source for later Feishu Docx export.
  • Generated assets live under report/assets/<slug>/. Reusable optional libraries live under report/assets/lib/.
  • Use vendored Chart.js, KaTeX, or highlight.js only when they are already available. Do not make report generation depend on network downloads. Plain CSS, inline SVG, and static tables are acceptable defaults.
  • Do not use React, Vue, or a build step for reports unless the user explicitly asks for an app rather than a report.
  • Author with the existing single-writer discipline. A reviewer can add inline <aside class="reviewer-note">...</aside> blocks or a separate review log; the primary author resolves them before final delivery.
  • Match visualization complexity to signal. Use charts, timelines, matrices, and callouts when they clarify the result; do not decorate sparse evidence.
  • The report must present findings and the data behind them together: key findings, visual evidence, method/scope, caveats, and links to source artifacts should all be visible in the HTML.
  • In Feishu bridge mode, prefer Bridge /report: Claude defaults to the HTML/front-end artifact via vibe-report; Codex defaults to deployment with vrc report serve.
  • vrc report serve <workspace> <report.html> serves the report from the topic workspace with backend Basic Auth, binds 0.0.0.0, chooses an available port, generates a controller-reachable http://<host>:<port>/... URL using report_public_host or host-IP detection, and sends credentials to the controller by Feishu DM. Do not post report passwords in the group.
  • Commit the HTML, MD, and required assets as normal workspace artifacts after the report unit is complete and the user approves the commit.

Section 5 — The log/ system

The log replaces TODO.md, decisions.md, and any other timeline document. Everything that happens with a timestamp goes here.

File layout

log/
  index.md                                # Auto-maintained, reverse-chronological table
  entries/
    YYYY-MM-DD_HHMM_<type>_<slug>.md      # Individual events

Event file schema

---
timestamp: 2026-04-29T11:00:00+08:00
type: <one of: debate | decision | experiment | proposal-update | src-update | doc-update | survey-add | survey-sweep | survey-sweep-failure | cowork-batch | cowork-batch-failure | review | review-failure>
slug: short-kebab-case
status: todo | done           # OPTIONAL. Only used for actionable events.
sessions: [<cc-session-id>, ...]   # OPTIONAL. Cross-references to Codex sessions.
related: [<other-entry-filename>]   # OPTIONAL. Links to related events.
---

# One-line title

**Summary**: One sentence. This is what shows up in `index.md`.

**Details**: Free-form markdown body. As long as needed.

When entries are created

Codex proactively offers to create a log entry after:

  • A round of proposal/architecture discussion concludes
  • An experiment finishes (success or failure)
  • The user states a clear decision ("let's go with X", "drop Y")
  • A non-trivial change to proposal.md / src/ / doc/ lands
  • A debate ends without resolution (log as debate, status=open if you add status)

Manual creation via $research log <type> <slug> [--status todo] or $research-workflow log <type> <slug> [--status todo].

In both cases, the actual file may be written directly by the main Codex session or by a lightweight Codex sub-agent when isolation is useful.

index.md

Auto-maintained. Reverse-chronological. Full list, no truncation. Format:

# Project NN-<slug> Timeline

| Date | Type | Slug | Summary | Status |
|---|---|---|---|---|
| 2026-04-29 11:00 | proposal-update | drop-multi-task | Removed multi-task variant after 4 ablations showed no gain | done |
| 2026-04-29 09:30 | debate | aux-loss-question | Discussed adding aux loss; no decision | — |
| ... |

Regenerated by ~/.codex/skills/research-workflow/bin/log-filter --regenerate-index after any new entry.

Filter program

bin/log-filter (bash, uses ripgrep + awk). Output mimics git log --oneline.

log-filter                              # All events, reverse-chronological
log-filter --type experiment            # Only experiments
log-filter --status todo                # Only open todos
log-filter --slug multi-task            # Slug substring match
log-filter --recent 10                  # Last 10
log-filter --type src-update --recent 5 # Combine filters
log-filter --regenerate-index           # Rewrite index.md from entries/

The script is idempotent and stateless — it only reads entries/ and prints / overwrites index.md.


Section 6 — Inter-skill routing

research-workflow does not duplicate domain skills. It routes to them at the right moment.

The full list of relevant skills installed locally is in available-skills.md. Consult that file when picking a skill. High-frequency routings:

Lifecycle stage Default skill
Brainstorming early ideas / pivoting brainstorming-research-ideas
Stuck, need creative leap creative-thinking-for-research
Surveying a sub-topic (sub-area sweep, not single-paper intake) research-survey
Executing queued code TODOs (≥ 2 atomic issues in parallel via Codex sub-agents) research-cowork
Key-checkpoint review of the research (parallel codex + Codex, four dimensions) research-review
Drafting / refining the paper ml-paper-writing (a.k.a. 20-ml-paper-writing)
Drawing schematic figures Direct LaTeX/TikZ in doc/figures/ (standalone, no skill required)
Post-research talk / report slides pptx (document-skills) — only for talk.pptx, never for paper figures
RL post-training verl, openrlhf, trl-fine-tuning, grpo-rl-training
Distributed training scaffolding accelerate, pytorch-fsdp2, megatron-core
Inference for eval / agent harness vllm, sglang
Evaluation lm-evaluation-harness, bigcode-evaluation-harness
Experiment tracking weights-and-biases

When you spot that a different skill in ~/.codex/skills/ would help and isn't in available-skills.md, suggest adding it rather than silently using it. The user maintains the whitelist.


Section 7 — Common Anti-patterns

Anti-pattern Symptom Correction
Eager proposal rewrite Modifying proposal.md every time an experiment surprises us Apply C3 — minor vs major distinction. Most surprises are minor adjustments to claims, not core revisions.
Survey by hearsay Adding entries to survey.md based on titles/abstracts only Apply C4 hard. PDF must exist locally; verified_by must point to it.
Doc gets ahead of results Writing claims in doc/ before result.md confirms them Apply C5. Use \todo{} placeholders. doc is a lagging mirror.
Silent cascades Changing src/ without checking proposal/doc/log impact Apply C6. After any non-trivial change, run cascade check (Workflow F).
Decision without log "We decided X" but no log entry Offer to log immediately. Log entries are cheap, retrieval is priceless.
Raster figures sneaking in PNG screenshots in doc/figures/ Reject. Apply Section 4. Either redo as a standalone TikZ schematic or as a matplotlib/PGFPlots PDF.
Citations from memory BibTeX entries Codex wrote without API verification Reject per ml-paper-writing rules. Use \cite{PLACEHOLDER_...} until verified.
Constitutional drift Mid-session, Codex forgets the constitution Re-read project-level AGENTS.md. The user can also remind by saying "constitution check".
Long-session quality decay Conversation past ~50 turns, hedged/repetitive answers, or about to start a new sub-task — but Codex keeps going Apply C8. Stop, write a handoff log entry, suggest /clear. Multi-session work is normal.

Section 8 — Skill Entry Aliases

Codex CLI does not load user-defined slash commands from ~/.codex/commands. Use /skills, $skill-name mentions, or natural language. Common argument shapes:

  • $research init <slug> — Workflow A. Creates the project scaffold.
  • $research log <type> <slug> [--status todo|done] — Manually create a log entry.
  • $research filter [args] — Wraps bin/log-filter. Same args.
  • $research check — Run cascade check (Workflow F) on the current project.
  • $research status — Show current project's AGENTS.md status, recent log activity, open todos.

Notes for the agent

  • This skill is meta. Do not put domain advice here. If you find yourself wanting to write "how to brainstorm" or "how to pick baselines", that belongs in another skill.
  • The constitution is maintained primarily by the project-level AGENTS.md that init writes. SKILL.md (this file) is the source of truth, but the user-facing daily enforcer is the per-project AGENTS.md.
  • When in doubt, follow C7: ask the user. This is a meta skill about disciplined collaboration, not autonomous execution.

04 同仓库更多 Skills