Skip to content

Latest commit

 

History

History
631 lines (452 loc) · 69.7 KB

plan-template.en.md

File metadata and controls

631 lines (452 loc) · 69.7 KB

mega2 Plan Template (English)

This is the English edition of docs/plan/plan-template.md for contributors. New dated plans must copy this structure (or the Chinese original), replace <...> placeholders, and delete unused explanatory prose. Do not delete mandatory sections. If a section does not apply, write N/A and the reason.

The Chinese file remains the in-repo operational original. If the two texts ever diverge on a gate or field, follow the Chinese file and open an Issue to sync this copy.

Template version: v2.5 (effective 2026-10-15). G-12 remains unchanged from v2.4. G-13 adds a narrowly predeclared aggregate of 2–3 independent code defects that actually blocked strict repository quality gates in one unpublished repair frontier; each child is accepted, reviewed, and committed locally, and the unique point runs full C/D on their final tree.

Product name is mega2. The Cargo package and binaries are mega2 / mega2_core. mega2 inherits from the same organization's Mega project. Mega is the transplant source and contract baseline, not a competitor.

Version and migration policy

  • Plans created after the effective date must match this version in full.
  • Plans already written before that date migrate incrementally: only cards you add or normatively edit must satisfy current G-* and new fields. Untouched cards stay as-is.
  • Migrating an entire legacy plan is its own piece of work. Do not sneak it into another task.
  • If a legacy plan temporarily keeps a conflicting field set, record one exception row in that plan's revision history with an expected migration time.

Usage rules

  • Name dated plans plan-YYYYMMDD.md. Use them for executable implementation, migration, refactor, or release work.
  • Long-lived capabilities belong only in plan-long.md (PT-* and SB-*). Dated plans may link those IDs. Do not copy the long-term roadmap into a second task table.
  • Every plan's fact baseline is the current checkout: source, tests, config, and docs. Older plans, screenshots, and meeting notes are clues only. Mega's pinned revision is the transplant baseline; Mega's historical prose is not proof of what mega2 already does.
  • Every task card must be executable by one Agent alone: clear scope, clear dependencies, concrete file landings, pass/fail acceptance, and copy-paste verification commands.
  • Every card must satisfy all G-* granularity rules: one independently recoverable behavior axis, item and size limits, one release slice per card by default. A named user's explicit plan-wide single-release instruction uses a registered G-12 group; eligible independent quality-gate defects may use the restricted G-13 repair aggregate. Ungranular cards must be split or merged before work starts.
  • Plans that touch public commands, config keys, DB schema, HTTP APIs, error types, storage formats, the Git protocol, migrations, authz, or security boundaries must include tests, docs, rollback, and compatibility handling.
  • If you cite Mega or another external repo (Libra, upstream orbit, …), pin a revision, file path, and check date. Do not treat a floating main as a spec.
  • New or changed entity / storage / migration work must update src/callisto/, src/jupiter/storage/, and src/jupiter/migration/ (including the migrations() list in src/jupiter/migration/mod.rs) and add matching integration tests.
  • Confirm every docs/*.md path exists before you cite it. New plans must not add dangling links: create the doc in the same card, or cite a file that already exists.
  • Production code must not add unexplained unwrap(), expect(), or panic!(). If the path is truly infallible, add an // INVARIANT: comment and say so in the card's acceptance.

Normative IDs and terms

Cite rules by ID (G-03, ER-04). Do not write "the previous section" or other references that break when clauses move. New clauses must be added to this table.

Prefix Meaning Defined in
ER-* Execution requirements (start, accept, release, evidence) Execution requirements
GC-* Global engineering constraints (every task) Global engineering constraints
G-* Task-card granularity Task-card granularity rules
ADR-* Accepted design decisions Accepted design decisions
GAP-* Fact-baseline gaps Current gaps
DEP-* Dependencies (cross-plan and external) Dependency register
REL-* Release groups (including family, plan-wide, and repair-aggregate windows) Release groups and concurrency windows
EX-* Allowlisted waivers (named approval) Field defaults and exceptions
FIX-* Out-of-scope fix cards found during execution (ER-10) End of the owning Phase
DEFER-* Deferred items (DEFER-<plan-prefix>-NN) Non-goals and deferred items
M<n> Milestones (M0, M1, …; no hyphen) Milestone acceptance and rollback

IDs this template must not reuse: plan-long.md PT-01..PT-13 (from PT-13, items may be mega2-native) and SB-01..SB-03; each dated plan's own task prefixes (for example IT-* in plan-20260727.md).

Terms (use these; do not invent synonyms):

  • Behavior axis: one independently recoverable change with self-contained external semantics. "LFS batch auth" is one axis; "LFS content addressing" is another.
  • Landing: one enumerable code or doc ownership domain: a concrete directory (src/jupiter/storage/, src/api/router/) or a same-topic doc set (docs/refactoring/config.md). Repo root, src/, tests/, and docs/ are not one landing.
  • Write set: files that will change, in three classes (G-10): implementation write set I (per card; decides concurrency), release write set R (per card; version face + Cargo.lock for an actual versioned release, or N/A for ER-08-eligible children, no-release cards, and terminal evidence-only close-out; today the version face is only Cargo.toml version; not used to group implementation concurrency, but serialized under I–R / R–R once a release window opens), coordination write set C (plan-level release order and windows; not a card field; "no concurrent multi-Agent release" is ER-12).
  • Release slice: normally one independent review + acceptance + version + commit + push; the ER-08 terminal evidence-only release card keeps review, applicable gates, commit, and push without a new version.
  • Family cards: a set of child cards that share one unique release point (G-08).
  • Plan-wide single-release group: after a named user's explicit instruction, a REL-* registration names every affected card, one final release point, and the no-push window. Members each pass local acceptance and review and make precise local commits; they inherit final-tree C/D coverage from that point (G-12).
  • Repair aggregate: 2–3 independent code defects that actually blocked strict repository quality gates in one unpublished repair frontier, each retaining its own implementation card, with a predeclared REL-* and one patch release point. It is neither a G-08 inseparable family nor a substitute for the G-12 user directive (G-13).
  • Rollback mode: exactly one of revert / forward-only / compensating / immutable-release (G-01). Irreversible work uses the last three; do not demand "one revert undoes it".

Title

# <topic> plan (<YYYY-MM-DD>)

Document duty

This document addresses <problem / capability>. The deliverable is <result>.

This file only plans work. It does not claim the work is done. At execution time, refresh source anchors first, then accept the card.

Scope

  • <commands / modules / services>
  • <DB schema, HTTP API, config keys, or storage formats>
  • <tests, docs, migrations, or release actions>

Non-goals

  • <capability we will not build>
  • <scope deferred to another plan / RFC / ADR>
  • <behavior that is easy to assume but is not promised>

Success

  • <user or system behavior change>
  • <machine-interface or data-state change>
  • <docs, tests, release evidence>
  • <when this plan may be marked complete>

Fact baseline

Refresh every line number and source anchor on the day work starts. Stale anchors are historical clues only.

Category Current fact Evidence
Code entry <src/...> <file:line>
Data / state <Postgres table / redis key / object namespace> <file:line>
CLI <mega2 ...> <src/commands/mod.rs:line (builtin / builtin_exec / load_mode)>
HTTP API <METHOD /api/v1/...> <src/api/router/...:line>
Config [section].key <config/config.toml:line + src/config model:line>
Errors <MegaError::...> <src/common/errors/mod.rs:line>
Migration <m<YYYYMMDD>_<HHMMSS>_<slug>> <migrations() registration line>
Docs <docs/...> <file:line>
Tests <-p mega2 --lib '<mod::tests>' or --test <target>> <file:line>
Workspace prelude <.env.test present / test stack up (Postgres 15432, Redis 16379, …)> <.env.test.example / docker/docker-compose.test.yml:line>
External reference <Mega repo@sha> <path + check date>

Current gaps

ID Gap Impact Evidence Plan action
GAP-01 <problem> <user / production impact> <file:line or external evidence> <task ID>

Relation to other plans

Plan / doc Relation This plan does
plan-long.md <PT / SB IDs> <link, consume, update status, or leave untouched>
plan-YYYYMMDD.md <blocked-by / parallel / supersede / conflict> <reuse, do not redo, migrate, close>
docs/refactoring/*.md <fact source or contract> <how we sync>
AGENTS.md / README.md <engineering baseline> <obey, propose a revision, or register drift>

Review conclusions and revision record

Self-review these dimensions before the plan is final. Fix blockers before any card starts.

Dimension Conclusion Revision
Worth doing <is the goal worth the cost> <adjust>
Feasibility <can tasks be split and delivered> <adjust>
Granularity <multi-axis, L/XL, fragment, unregistered merged release> <split / merge / register exception per G-*>
Dependencies and order <DAG acyclic, missing edges, executable release order> <adjust>
Completeness <tests / docs / migrations / rollback> <adjust>
Security <authz, secrets, paths, network, model input> <adjust>
Functional correctness <state machines, edges, error paths> <adjust>
Interface compatibility <CLI / HTTP / config / schema / errors> <adjust>
Data and control flow <transactions, idempotency, concurrency, distributed state> <adjust>
Performance and capacity <hot paths, complexity, storage growth> <adjust>
Reliability <crash recovery, retry, resource release> <adjust>
Maintainability <fact sources, boundaries, duplicated logic> <adjust>

Revision history

Every normative change after the plan is written (split/merge, dependency change, release-boundary change, decision reversal) gets one row. G-09 split sync closes here.

Date Trigger Change Old card → new cards Affected references
<YYYY-MM-DD> <self-review / review R<n> / baseline check> <what changed> <TASK-ID> → <TASK-ID>, <TASK-ID> <order, DEP, REL-*, traceability, test matrix, milestones, risks>

Accepted design decisions

If implementation must deviate, edit the plan first. Do not silently change semantics in code.

ADR--01: <title>

  • Status: Accepted
  • Context: <why this decision exists>
  • Decision: <chosen option>
  • Alternatives considered: <rejected options and why>
  • Consequences: <constraints, risks, follow-up>
  • Revisit when: <when to reopen>

Global engineering constraints

These apply to every task in the plan. Cards do not repeat them. Breaking any item means the task is not done.

  • GC-01 Verify before you build: On start, re-check the plan, related docs, current code, and tests. If the work is already done, add tests, add docs, update status, or close the card. Do not re-implement it.
  • GC-02 Single source of truth: Entity definitions, config parsing, API schemas, authz policy, error types, and shared helpers have one source. CLI handlers, HTTP handlers, migrations, and test fixtures must not each copy equivalent logic.
  • GC-03 Mega vs mega2 extension boundary: Code transplanted from Mega must mark source and diff. mega2-only surfaces must state the alternative, user impact, and machine interface.
  • GC-04 Output and error contract: User-visible errors use stable MegaError variants and stay in sync with docs/errors.md. HTTP status, JSON body, CLI exit code, and human-readable output are accepted separately. MegaError has no numeric error-code registry; variant → HTTP status lives only in src/common/errors/api.rs. Changing that map updates docs/errors.md or the card explains why not.
  • GC-05 Doc sync: Command, config, HTTP API, or public-behavior changes update the matching docs/ file, config/config.toml comments, and README.md. docs/ is Chinese-only; there is no EN/zh pair requirement. OpenAPI is aggregated at runtime by utoipa; there is no on-disk spec file. API schema evidence comes from a running /api/openapi.json.
  • GC-06 Test coverage: New entity / storage / migration work includes #[cfg(test)] mod tests using test_db_connection + apply_migrations. New CLI subcommands include parse tests and cover builtin() / builtin_exec() / load_mode(). New integration targets are files under tests/<name>.rs (cargo discovers them; no [[test]] stanza). Sync this plan's test matrix and docs/refactoring/integration.md.
  • GC-07 Secure defaults: Fail closed unless authn, Cedar authz, path ownership, schema version, object closure, or secret redaction is satisfied. Any fail-open needs an explicit user choice, a log, and a test. If a card's acceptance assumes "authz is on", verify that premise; do not assume a live Cedar EntityStore.
  • GC-08 Atomicity and recovery: Changes to DB transactions, redis, object storage, config, vault secrets, or release state must define transaction boundaries, idempotency keys, the crash window, and rollback / roll-forward.
  • GC-09 Concurrency and resource lifetime: DB pools, redis connections, file handles, async queues, and temp dirs must have release / recovery semantics. Tests must not depend on unisolated globals (env-mutating tests use src/config/testing.rs env_lock / EnvVarGuard).
  • GC-10 Performance budget: HTTP hot paths, DB queries, object I/O, Git protocol work, and background jobs must not introduce unbounded scans, unbounded memory, or N+1 DB/network calls. Write data size and assertions when it matters.
  • GC-11 No production panics: Production paths do not add bare unwrap() / expect() / panic!(). Return MegaResult, anyhow::Context, or a domain error with an actionable message.
  • GC-12 Precise commits: Stage only related paths. Do not commit -a. If you find unrelated dirty state, leave it and report it. Do not clean, reset, or fold it into the commit. Follow the Libra workflow in AGENTS.md "Task card release" and ER-07 below (this repo uses .libra, not git).

Execution requirements (mandatory)

A task is not complete if any applicable item fails. Cite IDs, not ordinals.

  1. ER-01 Pre-start safety check — all four, no exceptions:

    • Confirm branch, dirty state, and that target files have no unconfirmed user edits (libra status or the equivalent in AGENTS.md). If target files already have unconfirmed edits, report and do not overwrite.
    • Object storage is in-tree (src/orbit_api/ + src/orbit/). There is no sibling ../orbit and no crates/orbit* workspace members. A cargo resolve failure is not "missing orbit checkout".
    • Confirm .env.test exists (the repo ships .env.test.example only; .env.test is ignored). If it is missing, stop and ask per AGENTS.md. Do not silently run cargo test --all without sourcing it.
    • Confirm required test services are up: docker compose -f docker/docker-compose.test.yml up -d --wait (Postgres 15432, Redis 16379, Mailpit 11025/18025, RustFS 19000/19001; bucket init needs --profile init run --rm rustfs-init or the default rustfs-init health wait). Missing Postgres makes related tests panic, not skip.
  2. ER-02 Check, then implement: Refresh this card's source anchors, doc anchors, test targets, and external revisions. Then decide: implement, add tests, add docs, close, or downgrade.

  3. ER-03 Granularity gate: Before start, walk G-* and the card's Granularity summary. If scope has grown (new axis, AC/Verification over limit, scope rose to L, write set overlaps an in-flight card), edit the plan and split first. Do not silently expand during implementation.

  4. ER-04 Per-card acceptance gates: Gates are A focused surface gates (by what actually changed) + B type gates (by Task type) + C release close-out (required for every non-deferred card; who runs them is below) + D remote result gates (only when CI semantics cannot be reproduced locally). All applicable rows stack. All must pass.

    Authoritative submit contract is AGENTS.md "Required Checks Before Submitting Code Changes": cargo +nightly fmt --all --check, cargo clippy --all-targets --all-features -- -D warnings, source .env.test && cargo test --all. This template must not weaken those. AGENTS.md also requires cargo build and cargo build --tests with 0 errors and 0 warnings. Card-specific focused tests are additional, not a substitute.

    Gates do not count toward G-03. Verification lists only this card's own predicates.

    Two orthogonal status fields:

    • Lifecycle: pending | in-progress | blocked | done.
    • Acceptance: empty | locally-accepted | remote-pending | complete.
      • locally-accepted = applicable A + B passed; C coverage not yet obtained. Do not report done.
      • remote-pending = A/B passed and C coverage obtained (including one green three-gate run whose tree contains this card's final change), but applicable or inherited D is not green. Do not report done.
      • complete = A + B passed, C coverage obtained, and applicable or inherited D is green or deferred through the named EX-* rule below (or D is N/A). The G-12/G-13 unique version-tag Docker D is an exception to deferral: it must actually succeed.
      • Only path: A/B pass → locally-accepted → ER-05 review PASS → obtain C → (complete if no D; else remote-pending → D green or named EX-* deferral → complete). A deferral approved after C coverage may move a card from remote-pending to complete; do not rewrite its historical intermediate state as a green run. G-12/G-13 members remain at most locally-accepted until the final point supplies C, and cannot be done/complete until its required Docker D succeeds.
    • Lifecycle=done requires Acceptance=complete. blocked must return to in-progress before done. Plan completion requires every non-deferred card done.

    Who runs C:

    • Independent cards and G-08 / G-12 / G-13 versioned release points run the full C set.
    • family child, G-12 plan release child, and G-13 repair aggregate child cards each obtain A/B, fmt/clippy, ER-05 PASS, and a precise local commit. They do not bump, build release artifacts, push a branch or tag, or create a GitHub Release. They inherit C and applicable D from their named unique release point, whose final-tree three-gate run must contain all of each child's final changes. G-12/G-13 children cannot be done/complete before their unique point supplies C/D; before C they are at most locally-accepted.
    • no-release cards (docs / audit / spike / handoff) inherit C and D from the carrier release or close-out point named on the card. That ID must not be empty. Under G-12, pre-release no-release artifacts and local commits must be in the versioned point's tested tree; these cards remain locally accepted until it supplies C and the Docker D succeeds, and cannot provide an intermediate push. Strictly post-D evidence-only docs / audit cards remain no-release outside the pre-release REL-* group and name the ER-08 terminal evidence-only close-out as their C/D carrier. They cannot retroactively claim coverage by the pre-D tested tree or add product behavior. A named D deferral outside the G-12/G-13 unique version-tag Docker gate must explicitly cover both the card and its carrier.
    • There is no path that replaces the three gates with a zero-hit guard.

    A — focused surface gates (one row per production surface you actually changed):

    Surface changed Focused gate
    Pure lib unit logic in mega2_core (#[cfg(test)] under src/**) source .env.test && cargo test -p mega2 --lib '<mod::path::tests>'
    Lib logic that needs real Postgres Start the test stack, then the same --lib command; tests must use test_db_connection + apply_migrations
    Process / CLI black-box (tests/**) source .env.test && cargo test -p mega2 --test <target> -- --test-threads=1 [<filter>] (--test <target> is required)
    Bin composition root (src/main.rs, src/bin/migrate_local_to_s3.rs) Black-box --test <target> via CARGO_BIN_EXE_mega2 plus cargo clippy -p mega2 --all-targets -- -D warnings
    CLI parse and registration (src/cli.rs, src/commands/**) cargo test -p mega2 --lib 'cli::tests' + cargo test -p mega2 --lib 'commands::'; new/renamed subcommands assert builtin() / builtin_exec() / load_mode()
    HTTP / OpenAPI (src/api/**, src/server/http_server.rs) cargo test -p mega2 --lib 'api::' + sanitized /api/openapi.json from a running server
    src/callisto/**, src/jupiter/migration/** migrations() registration assert + apply_migrations(&db, true); empty down ⇒ Rollback mode = forward-only
    config/config.toml, src/config/** cargo run -p mega2 -- --config config/config.toml config validate, plus init / --deny-warnings / profile / bad-config / no-secret-leak as the change requires
    Git protocol / LFS Local equivalent of scripts/git_protocol_smoke.sh; check the current script, service config, and docker/docker-compose.test.yml for its prelude; read a workflow job only if it actually runs this matrix. Default config.toml points at 5432/6379, not the test stack — source .env.test or export MEGA_DATABASE__DB_URL / MEGA_REDIS__URL / MEGA_BASE_DIR. Push / tag / LFS need a seeded access token in the URL. LFS evidence requires MEGA2_GIT_SMOKE_PUSH=1 MEGA2_GIT_SMOKE_LFS=1 and the line PASS: HTTP LFS push and clone
    Cedar (src/contract/policy/**) Matching tests + an explicit assert of whether this card changed permit-all / empty EntityStore
    Repo config and CI (Cargo.toml non-version lines, rustfmt.toml, compose, scripts/**, .github/workflows/**) Local equivalent of the affected job, extracted from the workflow file; non-local bits go to D
    Docs / index only No A gate; B structure-and-link gate only

    For repo config and CI, read the affected workflow's complete jobs: entries, including on, permissions, if, env, run, uses, and with. Copy locally reproducible commands into A with their environment and prelude. A local checkout stands in for actions/checkout; GitHub runner credentials, remote builds, and registry publication require an actual triggered workflow result in D. Do not keep a fixed workflow-to-command snapshot.

    This repo is a single package mega2 (lib mega2_core, bins mega2 and migrate_local_to_s3). -p mega2 is equivalent to omitting it today; still write it so commands stay portable. Focused gates must use --lib or --test <target>.

    B — type gates:

    Task type Type gate
    implementation / migration / removal No extra type gate (A + C complete acceptance; family, G-12, and G-13 children run their applicable A/B, fmt/clippy, and inherit final-point C). Do not skip a focused test because full C will run later
    docs / audit / handoff Structure and links: product files exist, sections complete, internal links and file:line anchors resolve, new docs/*.md paths exist, status shows no out-of-scope edits. These types stay no-code / no-config. If code or config is required, reclassify per ER-03
    spike Artifact exists, go/no-go decided, follow-up cards registered; allowlist diff: every change is inside Deliverables; zero production-surface edits
    release Versioned release point: aggregate guards for the group's new tests + release note / compatibility evidence. Terminal evidence-only close-out: verify existing version's D evidence, plan status, doc links, and compatibility record; do not create a new version's release note

    C — release close-out (order is mandatory), run by cards that push: ① ER-08 version-face parity precheck → ② when Version increment is not N/A, bump Cargo.toml version accordingly and let the toolchain refresh Cargo.lock → ③ three AGENTS.md gates on the final tree (after bump when applicable) → ④ cargo build and cargo build --tests clean; add cargo build --release -p mega2 if you need a binary → ⑤ libra add <relevant paths> and libra commit -s -m → ⑥ libra push origin main and confirm the remote ref moved → ⑦ for every actual version bump, create an annotated matching tag on that commit with libra tag -m "v<version>: <summary>" v<version> and push it with libra push origin refs/tags/v<version> → ⑧ analyze the final diff, write a standard release note manually, and run gh release create v<version> -R gitmono-dev/mega2 --title "v<version>" --notes-file <release-notes-file>. The release note must include Highlights, user-visible changes, compatibility / configuration / migration guidance (N/A when none), verification results, and known limitations. Do not use --generate-notes or any other generated content. Cards with Version increment=N/A do not create tags or releases. For G-12 or G-13, the unique versioned point runs C after every pre-release member's A/B, review, and local commit is complete; step ③ covers their whole final tree, and steps ⑥–⑧ make the group's sole versioned branch-tip push, matching tag push, and manual GitHub Release.

    The G-13 repair aggregate point requires all children's established code causes/repairs, independent A/B, fmt/clippy, actual ER-05 PASS, and precise local commits, plus its own ER-05 PASS, before exclusively executing the actual patch release in order ①–⑧. Steps ③–④ test every member's final changes; child focused gates cannot substitute.

    A terminal evidence-only release close-out card that meets ER-08 sets Version increment=N/A and Release write set=N/A. C steps ② (version edit), ⑦ (tag), and ⑧ (human-written GitHub Release) do not apply; version-face check ①, the three gates on the final tree ③, builds ④, precise commit ⑤, and branch push ⑥ still apply, with ER-05 review PASS before C. Map D by the actual event/ref/path/job; this card's lack of a tag does not waive earlier independent code cards' or family, G-12, or G-13 release points' versioned releases and D gates. In G-12 it can run only after the sole versioned point's actual Docker D success. Its later docs/status branch push records post-D evidence; it creates no second version, tag, or GitHub Release and cannot substitute for the versioned point.

    C / D boundary: C includes the verified branch push, the matching tag push when applicable, and the human-written GitHub Release. Remote workflow results triggered by branch, tag, PR, or manual events belong to D, even if a run overlaps the last C steps. Each D item records the workflow file, job name, actual event and ref, the commit at that ref, applicability of paths: / paths-ignore: and job if (record "no filter" when both are absent), and the success predicate.

    D — remote result gate: Read each live workflow's on event, branch/tag/ref and paths: / paths-ignore: conditions, plus job if, then map them to the card's actual PR, manual dispatch, and branch/tag pushes. Neither paths: nor paths-ignore: means no path filter; file type alone cannot make D N/A. Record D=N/A only when the actual event/ref triggers no applicable job, with the reason.

    Actual event and ref (checked 2026-10-09; re-read at execution) Workflow / job Path scope and D predicate
    pull_request (record PR and run ref/commit) .github/workflows/repository-gates.yml / linux No path filter; require a successful run when the PR flow actually triggers the job
    Explicit workflow_dispatch (record selected ref/commit) .github/workflows/repository-gates.yml / linux No path filter; register only a run that was actually dispatched, not a merely available manual trigger
    push to main No matching workflow/job currently A branch push alone yields no D success; D=N/A if no other remote job was actually triggered
    push of a version tag matching v*.*.* or v* (record refs/tags/v<version> and its release commit) .github/workflows/docker.yml / docker No path filter; each version-tag push requires a successful remote job, including Docker registry build and push, even for a docs-only change

    This table records only the checked state; recompute from the live workflow event/ref/path/job conditions whenever they change. D evidence must identify the actual run for this card or its carrier release point. A PR run cannot stand in for the tag's Docker registry gate, and a branch push cannot stand in for an untriggered PR or tag run. D does not block locally-accepted or ER-05. D green or a named, allowlisted deferral is required for complete, except the G-12/G-13 unique version-tag Docker D must be green; a deferred result is never recorded as green. D failure is roll-forward only (new commit / new version), never revert of an already-pushed commit.

  5. ER-05 Review loop: After implementation and local acceptance, review. Fix findings and re-run acceptance until review says PASS. P0/P1 must close. "Residual risk accepted" cannot replace PASS except for P2 with a named owner in writing.

  6. ER-06 Docs and compatibility: Public-behavior cards sync user docs, developer docs, config/config.toml samples, the error contract, runtime OpenAPI evidence, and the test matrix.

  7. ER-07 Commit workflow: Follow AGENTS.md "Task card release" and ER-04/ER-08 in this template. Stage related paths only and commit with libra commit -s -m and a scoped message. Push the agreed branch at the card's release point; G-08, G-12, and G-13 children commit locally without pushing until their unique point. Do not --force. If local and remote have diverged, stop and report. After commit, verify the signature / sign-off convention this repo actually uses (do not invent a second convention in the card).

  8. ER-08 Version and release: The version source of truth is root Cargo.toml version. After the single-package inline there is one version face. On start day, re-count version-face files (rg -n '^version' Cargo.toml and rg -l '^\[package\]' --glob '**/Cargo.toml'). Version increment: patch (default) | minor | major | N/A. Breaking public-surface or schema/protocol changes must be minor or major. After every actual version bump, create and push the matching annotated v<version> tag and create a matching GitHub Release with a manually written standard release note. The note must be based on the final diff and include Highlights, user-visible changes, compatibility / configuration / migration guidance (N/A when none), verification results, and known limitations; --generate-notes is prohibited. Family children, G-12 plan release child, G-13 repair aggregate child cards, and docs / audit / spike / handoff cards use N/A and do not create tags or releases. A family, G-12, or G-13 code child inherits its named versioned point; the G-13 point must actually increment patch and cannot use N/A; no-release cards name their concrete versioned point or terminal evidence-only carrier. G-12 is allowed only when the whole plan's compatibility audit proves a patch release is sufficient. If a member needs minor or major, keep the plan blocked until the compatibility design is fixed or the user makes a new version decision; a single-patch instruction does not waive compatibility. A terminal evidence-only release card may also use Version increment=N/A and Release write set=N/A only after the existing versions' D results, with an implementation write set limited to evidence, plan status, and index docs and no new product behavior. It cannot be a family, G-12, or G-13 release point or replace the version bump, tag, GitHub Release, or D gate of an independently released implementation / migration / removal card or a versioned release point. Cargo commands use -p mega2.

  9. ER-09 Push failure: Non-fast-forward: pull/merge, re-accept, then push. Auth, permission, network, or server failures are not blind-retried; record the reason and wait for the next fix/release window.

  10. ER-10 Internal service errors (bounded retry): Redis, Postgres, object storage, SMTP, and AI-provider errors do not mark a task done. Deterministic 4xx / schema / compile / config defects are not retried. Fix in-card only if the fix stays on this card's axis and re-running ER-03 still passes; otherwise open FIX-*, add FIX-* -> current card, and set the current card blocked. Transient errors retry with exponential backoff (default ≤ 5 attempts, ≤ 30 minutes total). After budget, set blocked with sanitized evidence. Release pushes do not auto-retry (ER-09).

  11. ER-11 Evidence hygiene: Acceptance evidence must not store secrets, API keys, tokens, PII, unsanitized transcripts, private absolute paths, or raw tool payloads. Public test passwords (mega2_test_password, smtp-test-password, RustFS rustfs / rustfs_secret) are still redacted in records.

  12. ER-12 Concurrency vs serial release: Concurrent work is allowed only in implementation and review, and only when Implementation write sets are disjoint (G-10). Release is always serial and has one publisher: bump, build, release-point commit, push, and D tracking. Child cards can make their required precise local commits during implementation. Only one card may be in "bumped but not yet pushed" at a time. A G-12 group opens one versioned publication window after all pre-release members' local acceptance, reviews, and commits; no member may publish an intermediate branch tip, tag, or Release. An ER-08 terminal evidence-only branch push may follow the Docker D success without creating another versioned release. Do not invent an unverified document lease as a repo lock.

  13. ER-13 Tests must not leak shared state: When adding or changing tests, every shared side effect a case creates must be cleaned up before the case ends — above all table creation / seeding / migrations written directly into the shared test PostgreSQL public schema (i.e. anything not going through test_db_connection, which gives each case its own schema), as well as shared Redis, shared object-storage buckets, and fixed-path directories.

    • Background: test connections use a search_path that includes public (src/jupiter/tests.rs::database_url_with_search_path), so any table left in public is visible to other cases' unqualified lookups (e.g. to_regclass) and causes mass fixture failures on later runs (measured 2026-09-21: 84 stale tables in public broke 14 unrelated cases).
    • Requirements: on case exit (including panic paths — prefer guards / Drop / scoped cleanup) drop the tables, schemas, databases, buckets, and directories the case created; if a table must live in public, give it a case-unique name prefix and DROP TABLE IF EXISTS ... CASCADE at the end.
    • Review gate: when reviewing test diffs, "does every shared side effect have matching cleanup" is a mandatory check; when an existing case is found leaking shared state, fix it as its own card — do not copy the pattern into new cards.

Implementation order

Edge format: A -> B means A before B. The graph must be acyclic. Every edge points at a card, not a whole Phase (G-06). Update this section when cards split.

  • <TASK-01> -> <TASK-02>
  • <TASK-02> -> <TASK-03>

Dependency register

Every dependency outside this plan (other dated plans, external services, human approval, upstream revision) and every scope this plan hands off must be registered here before a card may cite it (G-06). In-plan edges use task IDs only.

direction: incoming = this plan waits; outgoing = this plan hands scope out (Owner is the receiver; timeout policy is what happens if they do not take it).

ID direction Type Object Owner Artifact and ready predicate Evidence Timeout / failure
DEP-01 <incoming / outgoing> <cross-plan / external service / approval / upstream revision> <plan-YYYYMMDD#TASK-ID, plan-long#PT-NN, or external> <person / system / receiving plan> <what is delivered and how we know it is usable> <file:line / commit / URL + check date> <wait cap, degrade or fallback>

Release groups and concurrency windows

Default: each card is its own release (G-07). Register an inseparable G-08 family, a user-directed G-12 plan-wide single release, or an eligible G-13 repair aggregate here before further member work or any publication; code children and the versioned point cite the REL-* ID in Release boundary, while no-release carriers name the point in C/D coverage from. A G-12 row quotes the named user's directive and date, enumerates the pre-release code and no-release carriers, identifies the unique final patch release point, and specifies the no-push window, recovery order, and final-tree C/D coverage. G-13 registration identifies its 2–3 implementation defects, actual blocking logs/source trees, unique point, and invalidation/exit rules. Any post-D ER-08 terminal evidence-only close-out is outside that release group.

ID Members Unique release point Window rule Failure rollback order Why
REL-01 <G-08 members / G-12 pre-release scope / G-13 2–3 implementation children plus separately listed no-release carriers> <unique versioned release TASK-ID> <children commit locally; no version bump, branch/tag push, or GitHub Release; no interleaved release slice> <before push, reverse dependencies; after push, ER-10 forward fix> <G-08 inseparability / G-12 user directive and date / G-13 actual failures and source trees, admission and exit>

Concurrency statement: <groups whose I sets are disjoint / fully serial> (G-10)

Publisher: <the one Agent or person who runs C and tracks D> (ER-12)

Release window order: <order of REL-* / independent cards; only one card bumped-not-pushed at a time>

Phase 0:

Goal: <goal>

Entry:

  • <precondition>

Exit:

  • <done predicate>

Phase 1:

Goal: <goal>

Entry:

  • <precondition>

Exit:

  • <done predicate>

Task cards

Use a stable prefix (IT-01, A0-01, DR-01). Once cited, numbers are not reused. Split children append new numbers at the end of their Phase. Number order is not execution order. Execution follows the dependency edges. Retired numbers stay, with a replacement note.

Task-card granularity (mandatory)

Granularity is the first quality bar. A card that is too large cannot be reviewed, rolled back, or finished by one Agent. A card that is too small splits implementation from tests and docs and pays a release cost every time. New or edited cards must satisfy every G-*. Failure means "not ready to start": split or merge, then sync order, DEP, REL, traceability, test matrix, milestones, risks, and revision history.

  • G-01 One recoverable axis: One card owns one independently recoverable behavior axis. On failure or withdraw, one declared recovery action leaves the system in a coherent state. Recovery is not "one revert": irreversible work is fine if the path is single and written down. Do not pack "schema + storage + API", "delete A + B + C", or "new capability + drive-by refactor" into one card. If Description has two coordinating "and / also / while we're here" goals, split. Rollback mode is one of:

    • revert — local code/docs; one revert undoes it (default).
    • forward-only — irreversible data or migration (Postgres, object store, vault). Write invariants, recovery commands, and user impact. Many existing down methods are no-ops; the runner exposes up and destructive refresh only. Treat existing migrations as forward-only unless this card implements and proves a real down.
    • compensating — external side effects. Write the compensating command and idempotency key.
    • immutable-release — already pushed; only a new version. Write downgrade guidance and the compatibility window.
  • G-02 Complete deliverable: Implementation, tests, docs, and index sync for the same axis are one card. Split only when the extracted part is itself a recoverable axis (independent migration, deprecation close-out, performance gate, API facet, cross-plan handoff).

  • G-03 Item caps (independent predicates, not line count; ER-04 gates do not count):

    Task type AC cap Verification cap
    implementation / migration / removal 8 8
    spike 8 8
    docs / audit / handoff 20 20
    release 12 12 (aggregate guards, release note, compatibility evidence)

    AC counts independent pass/fail predicates (and / nested bullets / table rows). Verification counts independent gates (env prelude + following command = one gate; multiple --test targets = multiple; && of two judging commands = two). Over limit means multi-axis: split. Do not hide extras in long sentences or "etc."

  • G-04 Size cap: Start-state Estimated scope is S or M only. L/XL after the plan is written is a defect. Count behavior landings and production files only. Do not count this card's own tests, GC-05/ER-06 docs, or the ER-08 version face (still list them in the write sets).

    • S: ≤ 2 behavior landings, ≤ 3 production files, no schema / protocol / public-interface change.
    • M: ≤ 4 landings, ≤ 12 production files, at most one public behavior or interface change, still one axis.
    • Over M is L: split by default. Mechanical repo-wide rename/delete/format may take L-exception:EX-<n> with a named waiver. XL is never a start state. Counting src/ or repo root as "one landing" is inflation.
  • G-05 Agent-executable alone: Current evidence has checkable file:line anchors. Acceptance criteria are self-contained. Verification is copy-paste commands. Dependencies cite DEP-* or task IDs only. No "see above" or "same as the last card". Shared conventions become a GC or an ADR.

  • G-06 Closed acyclic deps: In-plan edges use task IDs. Cross-plan and external prelude must be DEP-* first. "Wait for Phase N" is a split error. Implementation-order edges and each card's Dependencies must match; if they differ, the order section wins and the card is fixed on the spot.

  • G-07 Release-slice alignment: Default one card = one release slice. implementation / migration / removal take a full slice unless they are predeclared G-08, G-12, or G-13 children. docs / audit / spike / handoff are no-release and say which commit lands them. A release card responsible for a version is the release point. The ER-08 terminal evidence-only release card submits existing D evidence and docs without serving as a versioned release point. Multi-card releases are allowed only under G-08 (inseparable family), G-12 (named user-directed whole-plan single release), or G-13 (restricted repair aggregate), with a REL-* row before further member work. Register and review the dated plan first; revise and bump this template first if normative rules change. A scratch note cannot merge slices.

  • G-08 Family cards: When a public-surface delete or a schema+reader pair cannot ship as independent slices, split into children that each review and each pass applicable ER-04 gates and each commit locally, sharing one release card as the unique release point. Children: family child. Point: family release point. Register the no-push window as REL-*.

  • G-09 Split protocol: The original number stays on the main axis. New children append new numbers. Old card says "split out <ID>". New card says "split from <ID>". Sync order, DEP, REL, traceability, test matrix, milestones, risks, and one revision-history row.

  • G-10 Write sets and concurrency:

    • I — code, tests, docs that carry this card's behavior.
    • R — Cargo.toml version + Cargo.lock for an actual versioned release. Use N/A for family child / G-12 plan release child / G-13 repair aggregate child / no-release cards and for an ER-08 terminal evidence-only release card, which still runs applicable C steps and pushes its evidence/docs without editing the version face.
    • C — plan-level release order (ER-12). Not a card field.
    • I–I overlap → no concurrent work (no waiver): add an order edge or merge into one integration card.
    • I–R overlap → the open release window write-locks R files.
    • R–R overlap → serialized by ER-12, not a concurrency ban.
    • Concurrency is judged on Implementation write set, not Files likely touched.
  • G-11 Task type: implementation (default) | migration (usually forward-only) | removal (usually a family) | spike (no production code; time-box S ≤ 0.5 person-day, M ≤ 2) | audit / docs (product-file or person-day caps) | release (normally a versioned point, including G-08, G-12, and G-13; only an ER-08 terminal evidence close-out may omit a new version, and it adds no product behavior) | handoff (no-release; incoming/outgoing in the DEP table).

  • G-12 User-directed whole-plan single patch release: Only a named user's explicit instruction for this plan may move its versioned publication to one final patch release. The G-07 per-card default and G-08 inseparable-family rule continue to govern other plans.

    • Before further member work or any publication under this boundary, register a REL-* row with the user's exact instruction and date, every pre-release code child and no-release carrier, the unique final versioned Task type=release point, the full no-push window, recovery order, and final-tree C/D coverage. The dependency DAG must place the point after all pre-release members. Record the normative change in revision history and obtain plan review PASS. If the directive arrives after some local work, record the boundary change and recheck those edits for A/B, review, precise local commits, and absence of publication; missing gates cannot be accepted retroactively. New or split cards require an updated row and G-09 synchronization before work resumes.
    • Every implementation / migration / removal child retains its own G-01–G-06 and G-09–G-11 checks, ER-04 A/B focused and type gates, ER-05 PASS, and a precise local libra commit -s. Set Release boundary=plan release child of REL-<n>, Version increment=N/A, Release write set=N/A, and C/D coverage from=<unique point ID>. Its reviewed, locally accepted output may feed dependent local cards; do not claim remote availability. No child may edit the version face, build release artifacts, push the plan's branch or version tag, create a GitHub Release, or trigger the versioned Docker publication. A temporary push to a real private test repository is allowed only when a focused test requires it and its cleanup contract applies; it is not a versioned publication.
    • Pre-release docs / audit / spike / handoff cards remain no-release, name the same point in C/D coverage from, and put their reviewed, locally accepted artifacts and precise local commits into that point's tested tree. Strictly post-D evidence-only docs / audit cards are outside the pre-release REL-* group; they remain no-release, name the post-D ER-08 terminal evidence-only release close-out as their C/D carrier, and cannot retroactively claim inclusion in the pre-D tested tree or introduce product behavior. That close-out may make a later docs/status branch push only after the sole versioned point's Docker D succeeds and never creates another version, tag, or GitHub Release.
    • Before the unique plan release point of REL-<n> executes, every pre-release member must have its A/B, review, and local commit evidence and a compatibility audit proving patch is sufficient. The point alone bumps patch once and executes full ER-04 C on the final tree containing every member's work, including the three gates after the bump, clean builds, precise commit, the group's sole versioned branch-tip push, matching annotated tag push, and one manually written GitHub Release. Its actual version-tag Docker D must succeed; the generic EX-* D deferral does not apply to this gate. Members inherit C/D from that point and cannot be done/complete before Docker succeeds.
    • No focused test, full three-gate check, build, review, ER-13 test cleanup, or compatibility gate is waived. If any member needs minor / major, must be remotely published before the final point, or the final tree's C/D fails, block the group and revise the plan or repair forward under ER-03/ER-10. Before publication, recover local commits in reverse dependency order; after publication, use ER-10 forward repair. No other release slice may be inserted into the no-push window.
  • G-13 Restricted aggregate of unpublished quality-gate repairs: Only 2–3 independent code defects that actually blocked strict repository quality gates in the same unpublished repair frontier qualify; each retains one single-axis implementation card. Preserve each actual sanitized failure log and traceable source cohort/commit. A later defect may emerge in an unpublished tree already containing an earlier repair; do not claim that every defect failed in the same byte-identical tree. Independent defects do not become a G-08 family. This rule neither replaces the G-12 named-user instruction nor admits new features, schema, or public-surface/compatibility changes; those retain G-07/G-08 or applicable G-12 boundaries.

    • Admission and registration: A defect may be registered pending for diagnosis, which proves neither cause, repair, nor release eligibility. Before further member implementation, register the 2–3 code children, common unpublished baseline, each actual failing source tree and proof of non-publication, one Task type=release point, sole publisher, complete no-push window, reverse-dependency recovery before push/forward-only recovery after push, final-tree C/D coverage, and invalidation/exit rules in REL-*. The DAG places the point after all pre-release carriers. Actual, mutually isolated Claude and Codex plan reviews must both explicitly PASS this group's G-13 applicability. Record any switch from existing local work and recheck each artifact; do not retroactively invent missing gates.
    • Child contract: Set Release boundary=repair aggregate child of REL-<n>, Version increment=N/A, Release write set=N/A, and C/D coverage from=<unique point ID>. Each cause and code repair must actually be established, and each child passes its own A/B, fmt/clippy, and actual ER-05 PASS before a precise local commit with ER-07 signature checks and sign-off. No child is done/complete before final C/D. G-01–G-06, G-09–G-11, and all other applicable rules remain. No-release docs/audit cards may name the point, but each retains acceptance, review, and a local commit in the final tested tree; they do not count toward the 2–3 code children.
    • Unique publication: The point sets Release boundary=repair aggregate release point of REL-<n>, Task type=release, Version increment=patch, and R to the actual version face plus Cargo.lock; it adds no product behavior. Only after every member's evidence above and the point's own ER-05 PASS may the sole publisher execute ER-04 C in order: ① parity → ② actual patch bump + toolchain lock refresh → ③ three gates on the final tree → ④ both builds → ⑤ precise commit with ER-07 signature checks/sign-off → ⑥ main push → ⑦ matching annotated tag → ⑧ manually written GitHub Release, then actual applicable D. The unique tag's Docker D must actually succeed and cannot be deferred. No earlier branch/tag push, Release, or interleaved release slice is allowed; an evidence-only close-out cannot replace this versioned point.
    • Invalidation and exit: An unknown cause, mere non-reproduction, or environment load without a code defect is not a completed repair and cannot enter aggregate publication. Reassess the group under ER-03 and obtain new plan review, or return to independent G-07 slices. Loss of admissible membership/source provenance, more than 3 defects, compatibility or dependency requirements outside this rule, or final-tree C/D failure also blocks the group; revise under ER-03/ER-10. Recover in the registered reverse order before push; after push, roll forward only. ER-09 push policy, independent ER-10 fault ownership and existing retry budgets, signature rules, no force/unknown flags, ignore/soft-skip limits, and evidence hygiene remain unchanged. G-13 is not a waiver and grants no retroactive authorization to an old publication window or an unexecuted check.

Recommended split dimensions

Dimension Cut Typical result
Data / state entity + migration → storage write / idempotency → read projection / recovery 3 cards
Protocol version / negotiate → capacity / backpressure → consumer attach 3 cards
Surface service/storage → machine interface → CLI or client 2–3 cards
Lifecycle new impl → default flip → deprecation shim → physical delete cards per release window
Security identity / request boundary → path / object ownership → redaction one card per axis
Cleanup public-surface delete (family) → internal module exit → dependency drop family + ordinary cards

Granularity anti-patterns

Anti-pattern Symptom Fix
Giant card scope = L; AC > 8; several goals in Description Split on the table above
Fragment card "add tests" / "add docs" / "rename a field" alone Merge back onto the axis (G-02)
Multi-axis disguise long sentence or "etc." to stay under 8 Recount predicates (G-03)
Landing inflation src/ or repo root counted as one landing Recount at directory grain (G-04)
Implicit dependency "per card X's convention" that X never delivered Write it here or promote to GC / ADR (G-05)
Ghost acceptance only cargo test --all, or rg that cannot tell miss from error Name package/target/fn; use the exit-code template
Dangling dependency "Phase N done" or free-text external prelude Converge to task IDs / DEP-* (G-06)
Fake rollback already pushed or migrated, still "one revert" Choose forward-only / compensating / immutable-release
Concurrent collision two independent cards share I Order edge or merge (G-10, no waiver)
Drive-by merge several cards released as one from a scratch note Register an eligible G-08, G-12, or G-13 REL-* before start, or split back into independent releases
Early plan-wide publication a G-12 member bumps, pushes, tags, creates a Release, or marks done before final Docker D Block the group and record the actual remote state; use ER-10 forward recovery for any push and re-review the release boundary. A false done returns to the factual acceptance state

Field defaults and exceptions

After this section declares defaults, cards may omit fields that take the default, or write Inherited. Only deviations are expanded and listed below. Required on every card: Task type, Lifecycle / Acceptance, Rollback mode, Implementation write set, Version increment, C/D coverage from, Granularity. Release write set may be Inherited or N/A. Deliverables is required on docs / audit / spike / handoff.

  • Release boundary default: <independent / other>
  • Task type default: <implementation / other>
  • Rollback mode default: <revert / other>
  • Migration and rollback default: <N/A: no schema migration / other>
  • Security and privacy default: <inherit GC-07, GC-11 / other>
  • Performance budget default: <inherit GC-10 / other>
  • Docs and compatibility default: <sync related docs/ and config samples per GC-05 / other>

Default overrides (not waivers):

Task Field Value and why
<ID> <Rollback mode> <forward-only: existing down is empty>
<ID> <Docs and compatibility impact> <dev docs only>

Rule waivers (EX-*, named approval). Only these four rules may be waived. G-01, G-02, G-05–G-13 are never waivable; G-12 and G-13 are restricted release-boundary rules, not EX-* waivers of other granularity rules.

Waivable Allowed reasons
G-03 item cap Checklist products (docs / audit / index) truly need more items, with a file list
G-04 size cap (L-exception) Mechanical: repo-wide rename, bulk delete, format
ER-07 signing Named repo-policy exception (sign-off-only)
ER-04 D completion evidence Remote CI minutes exhausted or external runner unavailable; require named approval by the user or a maintainer, never self-approval by the publisher, workflow/job/ref scope per card, and a DEFER-* debt item with restart condition. Only D may be deferred: A/B/C, local three gates, ER-05 review (plus independent review where required), commit, tag, and human-written GitHub Release remain mandatory. The unique G-12/G-13 version-tag Docker success cannot be deferred. Later remote failure requires an ER-10 forward fix
Exception ID Task (or ALL/<scope>) Waived rule Reason and compensation Approver Review round Evidence Expires
EX-01 <ID> <G-03> <docs-only; product files = …> <name> <R-n> <file:line / review> <this plan / YYYY-MM-DD>

Granularity audit table

Fill after the plan is written and after every normative edit. Any failing column blocks start. Over-limit AC / VER / scope must carry @EX-ID or L-exception:EX-n that exists in the waiver table, names this card (or ALL/<scope>), matches the exceeded rule, uses an allowlisted reason, and is still in date. D deferrals must also cover each card in the waiver table and be recorded in its C/D coverage from; they do not count as G-03/G-04 granularity exceptions.

Task type axis recovery complete self-contained AC VER landing / prod-files scope deps writeset release split-from exception
<ID> <Task type> <axis> <recovery> <yes> <yes> <n/cap[@EX-ID]> <n/cap[@EX-ID]> <n>/<n> <S/M/L-exception:EX-n> <TASK-ID/DEP-ID/none> <no-overlap/serialized-on ID> <independent/REL-n family child/REL-n family point/REL-n plan child/REL-n plan point/REL-n repair child/REL-n repair point/no-release> <ID/N/A> <EX-ID/N/A>

Verification judgment

Zero-hit guards must distinguish "no match" from "command failed". rg exits 0 = hit, 1 = zero hits, >1 = error. Do not use ! rg or if rg; then exit 1; fi alone. Use:

if rg -n "<pattern>" <paths>; then
  echo "FAIL: forbidden pattern found"; exit 1
else
  rc=$?
  if [ "$rc" -ne 1 ]; then echo "ERROR: rg failed with exit $rc"; exit "$rc"; fi
  echo "OK: zero hits"
fi
  • Allowlist guards compare each hit to a fixed list and attach the hit diff.
  • rg used only to find a symbol must say "anchor location, not a predicate".
  • New test fns / filters are marked (new) with a clear home: --lib '<mod::path::tests::fn>' or --test <target>.
  • cargo test --all does not replace the card's focused tests (ER-04). Focused tests do not replace the plan-completion three gates.
  • Tests that need real services must state the prelude. Missing Postgres panics. Treating skip as pass is ghost acceptance.

Task : <title>

Task type: <implementation | migration | removal | spike | audit | docs | release | handoff> (G-11)

Lifecycle / Acceptance: <pending | in-progress | blocked | done> / <empty | locally-accepted | remote-pending | complete> (ER-04; done requires complete)

Description: <what, why, user impact. One sentence names the single axis.>

Out of scope: <each item: "owned by <ID>" / "not scheduled; restart when …" / "permanent non-goal because …">

Current evidence:

Fact Evidence
<current impl or gap> <file:line / test / external repo@sha>

Acceptance criteria:

  • <user-visible or system predicate>
  • <API / config / schema / error predicate>
  • <failure-path / edge predicate>
  • <docs / compatibility / migration predicate>

Verification:

  • <exact command>
  • <exact command>
  • <manual / sanitized evidence, if required>

Dependencies: <none / this-plan Task IDs + the concrete artifact consumed / DEP-ID> (G-06)

Deliverables: <required for docs / audit / spike / handoff: product file list. Code cards: N/A or Inherited.>

Implementation write set: <files or dirs that carry this card. Concurrency is judged only here.> (G-10)

Release write set: <Inherited (= Cargo.toml version + Cargo.lock) / N/A (family child / plan release child / repair aggregate child / no-release / ER-08 terminal evidence-only release)>

Files likely touched: <src/...>, <tests/...>, <config/...>, <docs/...> (estimate)

Docs and compatibility impact: <Inherited / concrete files>

Rollback mode: <revert | forward-only | compensating | immutable-release> (G-01)

Migration and rollback: <N/A or up/down, roll-forward, invariants, recovery commands, user impact; say so if down is empty>

Security and privacy: <N/A or Cedar, secrets, paths, redaction, input checks>

Performance budget: <N/A or data size, complexity, wall-clock / benchmark>

Estimated scope: <S / M / L-exception:EX-<n>> (G-04)

Version increment: <patch | minor | major | N/A (only for ER-08-eligible cards, including G-12 plan release child, G-13 repair aggregate child, and terminal evidence-only release)> (ER-08; G-12/G-13 final point is patch)

Release boundary: <independent (also for terminal evidence-only release) | family child of REL-<n> (k/n) | family release point of REL-<n> | plan release child of REL-<n> | plan release point of REL-<n> | repair aggregate child of REL-<n> | repair aggregate release point of REL-<n> | no-release> (G-07/G-08/G-12/G-13; merged releases require a predeclared REL-* row)

C/D coverage from: <self | <TASK-ID>> (ER-04; family child, G-12 plan release child, and G-13 repair aggregate child name their concrete versioned point; pre-release no-release names that point, while strictly post-D evidence-only docs / audit names its ER-08 terminal close-out carrier)

Granularity: type=<Task type>; axis=<single axis>; recovery=<one recovery action and coherent post-state>; complete=<yes>; self-contained=<yes>; AC=<n>/<cap>[@EX-ID]; VER=<n>/<cap>[@EX-ID]; landing=<n>; prod-files=<n>; scope=<S|M|L-exception:EX-n>; deps=<none|TASK-ID,…|DEP-ID,…>; writeset=<no-overlap|serialized-on TASK-ID>; release=<independent|REL-n family child|REL-n family point|REL-n plan child|REL-n plan point|REL-n repair child|REL-n repair point|no-release>; split-from=<TASK-ID|N/A>; exception=<EX-ID[,…]|N/A>

Mapping: type→G-11, axis/recovery→G-01, complete→G-02, AC/VER→G-03 (caps 8 / 12 / 20 by type; ER-04 does not count), landing/prod-files/scope→G-04, self-contained→G-05, deps→G-06, release→G-07/G-08/G-12/G-13, split-from→G-09, writeset→G-10, exception→registered EX-*. If you cannot fill this line, the card is not split cleanly.

Test matrix

Class Must cover Target / command
Unit <pure logic, config parser, error map> <cargo test -p mega2 --lib '<mod::tests>'>
Integration (DB) <real Postgres + storage/migration> <--lib with test_db_connection + apply_migrations>
Integration (process) <real binary, service start, config parse> <cargo test -p mega2 --test <target> -- --test-threads=1>
CLI <parse, three registrations, exit codes, output> <cargo test -p mega2 --lib 'cli::tests'>
HTTP API <routes, status, JSON schema, auth> <cargo test -p mega2 --lib 'api::...'>
Migration <up/down, old/new schema, data move> <migration tests>
Config <validate / init / profile / secret leak> <cargo run -p mega2 -- ... config validate ...>
Git protocol <clone/fetch/push/shallow/v2/LFS> <scripts/git_protocol_smoke.sh local equivalent>
Security <authn, Cedar, secrets, path traversal, redaction> <cargo test ...>
Performance <size and budget> <criterion / wall-clock>
live/gated <RustFS / Mailpit / SMTP> <compose profile or env-gated command>

Traceability

Task Source / evidence mega2 landing Docs / compatibility Named tests
<ID> <file:line / issue / repo@sha> <src/callisto / src/jupiter / src/api / …> <docs/..., config/config.toml, runtime OpenAPI> <-p mega2 --lib or --test>

Milestone acceptance and rollback

Milestone Done when Release / evidence Rollback or roll-forward
M0 <baseline frozen> <commit/test/doc> <N/A>
M1 <first releasable slice> <version/test/review> <rollback/forward fix>

Failure-recovery matrix

Failure point Acceptable residue Recovery Forbidden outcome
<mid-transaction, pre-commit> <temp table / partial write> <retry/abandon/rollback> <data loss / partial commit / silent success>

Risk register

Risk Impact Mitigation Task
<risk> <high/med/low + impact> <test/design/gate> <ID>

Performance and capacity summary

Operation Per-call cost Cumulative cost Budget / cap Proof
<op> <O(...)> <O(...)> <threshold> <test/benchmark>

Compatibility and docs close-out

  • docs/errors.md synced, or N/A.
  • Related docs/refactoring/*.md synced, or N/A.
  • config/config.toml samples and comments synced, or N/A.
  • Runtime OpenAPI (/api/openapi.json) evidence captured, or N/A (no on-disk spec).
  • README.md / AGENTS.md constraints synced or drift registered, or N/A.
  • src/callisto/, src/jupiter/storage/, src/jupiter/migration/ (including migrations()) synced, or N/A.
  • New docs/*.md citations all exist, or N/A.
  • plan-long.md dated-plan index or PT/SB status synced, or N/A.

Review log

Result is only PASS or FAIL. FAIL must list P0/P1 and close them next round. P2 may be accepted in writing by a named owner; that does not change this round's FAIL (ER-05).

Round Scope Result P0/P1 P2 disposition Evidence
R1 <files/tasks> <PASS / FAIL> <items and close state> <fix / named accepter> <commands / re-review>

Non-goals and deferred items

ID Deferred Why Restart when Owner
DEFER--01 <what> <why> <when> <plan/PT/ADR>

Completion criteria

The plan is complete only when all of the following hold:

  • Every card satisfies G-*: no unregistered L exception, no XL card, no fragment cards, no unregistered merged release, I-set conflicts resolved; granularity audit table filled. A G-12 plan has a dated named-user directive, complete REL-* membership, and one final patch release point.
  • Every G-13 group has actual failures/source trees, established code causes/repairs, per-child A/B, ER-05, and precise local commits; its unique actual patch, complete final-tree C, matching tag/manual Release, and actual Docker D are complete. Unknown causes and mere non-reproduction are not completed repairs; invalid groups have followed G-13 exit rules.
  • Every non-deferred card has met acceptance and Lifecycle=done and Acceptance=complete (ER-04). remote-pending cards must first get green D or a named, allowlisted EX-* deferral with registered DEFER-* debt. blocked cards must unblock or become DEFER-*.
  • Every card's Verification commands have been run and recorded.
  • Plan completion gates: cargo +nightly fmt --all --check, cargo clippy --all-targets --all-features -- -D warnings, source .env.test && cargo test --all all green; cargo build and cargo build --tests 0 errors / 0 warnings; no new crate-level #[allow(...)].
  • Required docs / config / error contract / test-matrix updates are done.
  • Required migration, rollback, and failure-recovery checks are done; each card's Rollback mode was actually proven or recorded as unprovable.
  • Final review is PASS; all P0/P1 closed; only named P2 residual risk remains.
  • Every actual version bump has a consistent version face, build / commit / push evidence, a pushed matching v<version> tag, and a matching GitHub Release created through gh with a manually written standard release note; no generated notes were used. For G-12, exactly one patch bump and one versioned branch-tip/tag/Release publication cover all pre-release locally committed members, and the actual version-tag Docker D run succeeded before any member became done/complete. A later ER-08 evidence-only docs/status branch push has no version increment, tag, or GitHub Release.
  • Revision history records every post-draft normative change (G-09).
  • Related plan-long.md PT/SB status or dated-plan index is synced, or N/A.