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.
- 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.
- 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-*andSB-*). 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
mainas a spec. - New or changed entity / storage / migration work must update
src/callisto/,src/jupiter/storage/, andsrc/jupiter/migration/(including themigrations()list insrc/jupiter/migration/mod.rs) and add matching integration tests. - Confirm every
docs/*.mdpath 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(), orpanic!(). If the path is truly infallible, add an// INVARIANT:comment and say so in the card's acceptance.
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/, anddocs/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.lockfor an actual versioned release, orN/Afor ER-08-eligible children, no-release cards, and terminal evidence-only close-out; today the version face is onlyCargo.tomlversion; 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
releasecard 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 finalreleasepoint, 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".
# <topic> plan (<YYYY-MM-DD>)
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.
<commands / modules / services><DB schema, HTTP API, config keys, or storage formats><tests, docs, migrations, or release actions>
<capability we will not build><scope deferred to another plan / RFC / ADR><behavior that is easy to assume but is not promised>
<user or system behavior change><machine-interface or data-state change><docs, tests, release evidence><when this plan may be marked complete>
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> |
| ID | Gap | Impact | Evidence | Plan action |
|---|---|---|---|---|
| GAP-01 | <problem> |
<user / production impact> |
<file:line or external evidence> |
<task ID> |
| 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> |
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> |
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> |
If implementation must deviate, edit the plan first. Do not silently change semantics in code.
- 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>
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
MegaErrorvariants and stay in sync withdocs/errors.md. HTTP status, JSON body, CLI exit code, and human-readable output are accepted separately.MegaErrorhas no numeric error-code registry; variant → HTTP status lives only insrc/common/errors/api.rs. Changing that map updatesdocs/errors.mdor the card explains why not. - GC-05 Doc sync: Command, config, HTTP API, or public-behavior changes update the matching
docs/file,config/config.tomlcomments, andREADME.md.docs/is Chinese-only; there is no EN/zh pair requirement. OpenAPI is aggregated at runtime byutoipa; 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 testsusingtest_db_connection+apply_migrations. New CLI subcommands include parse tests and coverbuiltin()/builtin_exec()/load_mode(). New integration targets are files undertests/<name>.rs(cargo discovers them; no[[test]]stanza). Sync this plan's test matrix anddocs/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.rsenv_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!(). ReturnMegaResult,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 inAGENTS.md"Task card release" and ER-07 below (this repo uses.libra, notgit).
A task is not complete if any applicable item fails. Cite IDs, not ordinals.
-
ER-01 Pre-start safety check — all four, no exceptions:
- Confirm branch, dirty state, and that target files have no unconfirmed user edits (
libra statusor the equivalent inAGENTS.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../orbitand nocrates/orbit*workspace members. A cargo resolve failure is not "missing orbit checkout". - Confirm
.env.testexists (the repo ships.env.test.exampleonly;.env.testis ignored). If it is missing, stop and ask perAGENTS.md. Do not silently runcargo test --allwithout sourcing it. - Confirm required test services are up:
docker compose -f docker/docker-compose.test.yml up -d --wait(Postgres15432, Redis16379, Mailpit11025/18025, RustFS19000/19001; bucket init needs--profile init run --rm rustfs-initor the defaultrustfs-inithealth wait). Missing Postgres makes related tests panic, not skip.
- Confirm branch, dirty state, and that target files have no unconfirmed user edits (
-
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.
-
ER-03 Granularity gate: Before start, walk
G-*and the card'sGranularitysummary. 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. -
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.mdalso requirescargo buildandcargo build --testswith 0 errors and 0 warnings. Card-specific focused tests are additional, not a substitute.Gates do not count toward G-03.
Verificationlists 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 namedEX-*rule below (or D isN/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 → (completeif no D; elseremote-pending→ D green or namedEX-*deferral →complete). A deferral approved after C coverage may move a card fromremote-pendingtocomplete; do not rewrite its historical intermediate state as a green run. G-12/G-13 members remain at mostlocally-accepteduntil the final point supplies C, and cannot bedone/completeuntil its required Docker D succeeds.
Lifecycle=donerequiresAcceptance=complete.blockedmust return toin-progressbeforedone. Plan completion requires every non-deferred carddone.
Who runs C:
- Independent cards and G-08 / G-12 / G-13 versioned
releasepoints run the full C set. family child, G-12plan release child, and G-13repair aggregate childcards each obtain A/B, fmt/clippy, ER-05PASS, 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 bedone/completebefore their unique point supplies C/D; before C they are at mostlocally-accepted.no-releasecards (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-onlydocs/auditcards remainno-releaseoutside the pre-releaseREL-*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)]undersrc/**)source .env.test && cargo test -p mega2 --lib '<mod::path::tests>'Lib logic that needs real Postgres Start the test stack, then the same --libcommand; tests must usetest_db_connection+apply_migrationsProcess / 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>viaCARGO_BIN_EXE_mega2pluscargo clippy -p mega2 --all-targets -- -D warningsCLI parse and registration ( src/cli.rs,src/commands/**)cargo test -p mega2 --lib 'cli::tests'+cargo test -p mega2 --lib 'commands::'; new/renamed subcommands assertbuiltin()/builtin_exec()/load_mode()HTTP / OpenAPI ( src/api/**,src/server/http_server.rs)cargo test -p mega2 --lib 'api::'+ sanitized/api/openapi.jsonfrom a running serversrc/callisto/**,src/jupiter/migration/**migrations()registration assert +apply_migrations(&db, true); emptydown⇒Rollback mode = forward-onlyconfig/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 requiresGit protocol / LFS Local equivalent of scripts/git_protocol_smoke.sh; check the current script, service config, anddocker/docker-compose.test.ymlfor its prelude; read a workflow job only if it actually runs this matrix. Defaultconfig.tomlpoints at 5432/6379, not the test stack —source .env.testor exportMEGA_DATABASE__DB_URL/MEGA_REDIS__URL/MEGA_BASE_DIR. Push / tag / LFS need a seeded access token in the URL. LFS evidence requiresMEGA2_GIT_SMOKE_PUSH=1 MEGA2_GIT_SMOKE_LFS=1and the linePASS: HTTP LFS push and cloneCedar ( src/contract/policy/**)Matching tests + an explicit assert of whether this card changed permit-all / empty EntityStoreRepo config and CI ( Cargo.tomlnon-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, includingon,permissions,if,env,run,uses, andwith. Copy locally reproducible commands into A with their environment and prelude. A local checkout stands in foractions/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(libmega2_core, binsmega2andmigrate_local_to_s3).-p mega2is equivalent to omitting it today; still write it so commands stay portable. Focused gates must use--libor--test <target>.B — type gates:
Task type Type gate implementation/migration/removalNo 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/handoffStructure and links: product files exist, sections complete, internal links and file:lineanchors resolve, newdocs/*.mdpaths exist, status shows no out-of-scope edits. These types stay no-code / no-config. If code or config is required, reclassify per ER-03spikeArtifact exists, go/no-go decided, follow-up cards registered; allowlist diff: every change is inside Deliverables; zero production-surface editsreleaseVersioned 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 incrementis notN/A, bumpCargo.tomlversionaccordingly and let the toolchain refreshCargo.lock→ ③ threeAGENTS.mdgates on the final tree (after bump when applicable) → ④cargo buildandcargo build --testsclean; addcargo build --release -p mega2if you need a binary → ⑤libra add <relevant paths>andlibra commit -s -m→ ⑥libra push origin mainand confirm the remote ref moved → ⑦ for every actual version bump, create an annotated matching tag on that commit withlibra tag -m "v<version>: <summary>" v<version>and push it withlibra push origin refs/tags/v<version>→ ⑧ analyze the final diff, write a standard release note manually, and rungh 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/Awhen none), verification results, and known limitations. Do not use--generate-notesor any other generated content. Cards withVersion increment=N/Ado 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-05PASS, 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
releaseclose-out card that meets ER-08 setsVersion increment=N/AandRelease 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 reviewPASSbefore 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 jobif(record "no filter" when both are absent), and the success predicate.D — remote result gate: Read each live workflow's
onevent, branch/tag/ref andpaths:/paths-ignore:conditions, plus jobif, then map them to the card's actual PR, manual dispatch, and branch/tag pushes. Neitherpaths:norpaths-ignore:means no path filter; file type alone cannot make DN/A. Record D=N/Aonly 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/linuxNo 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/linuxNo path filter; register only a run that was actually dispatched, not a merely available manual trigger pushtomainNo matching workflow/job currently A branch push alone yields no D success; D= N/Aif no other remote job was actually triggeredpushof a version tag matchingv*.*.*orv*(recordrefs/tags/v<version>and its release commit).github/workflows/docker.yml/dockerNo 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-acceptedor ER-05. D green or a named, allowlisted deferral is required forcomplete, 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. -
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 replacePASSexcept for P2 with a named owner in writing. -
ER-06 Docs and compatibility: Public-behavior cards sync user docs, developer docs,
config/config.tomlsamples, the error contract, runtime OpenAPI evidence, and the test matrix. -
ER-07 Commit workflow: Follow
AGENTS.md"Task card release" and ER-04/ER-08 in this template. Stage related paths only and commit withlibra commit -s -mand 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). -
ER-08 Version and release: The version source of truth is root
Cargo.tomlversion. After the single-package inline there is one version face. On start day, re-count version-face files (rg -n '^version' Cargo.tomlandrg -l '^\[package\]' --glob '**/Cargo.toml').Version increment:patch(default) |minor|major|N/A. Breaking public-surface or schema/protocol changes must beminorormajor. After every actual version bump, create and push the matching annotatedv<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/Awhen none), verification results, and known limitations;--generate-notesis prohibited. Family children, G-12plan release child, G-13repair aggregate childcards, anddocs/audit/spike/handoffcards useN/Aand 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 useN/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 needsminorormajor, 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-onlyreleasecard may also useVersion increment=N/AandRelease write set=N/Aonly 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 releasedimplementation/migration/removalcard or a versioned release point. Cargo commands use-p mega2. -
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.
-
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-*, addFIX-* -> current card, and set the current cardblocked. Transient errors retry with exponential backoff (default ≤ 5 attempts, ≤ 30 minutes total). After budget, setblockedwith sanitized evidence. Release pushes do not auto-retry (ER-09). -
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, RustFSrustfs/rustfs_secret) are still redacted in records. -
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. -
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
publicschema (i.e. anything not going throughtest_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_paththat includespublic(src/jupiter/tests.rs::database_url_with_search_path), so any table left inpublicis 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 inpublicbroke 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 andDROP TABLE IF EXISTS ... CASCADEat 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.
- Background: test connections use a
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>
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> |
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>
Goal: <goal>
Entry:
<precondition>
Exit:
<done predicate>
Goal: <goal>
Entry:
<precondition>
Exit:
<done predicate>
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.
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
Descriptionhas two coordinating "and / also / while we're here" goals, split.Rollback modeis 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 existingdownmethods are no-ops; the runner exposesupand destructiverefreshonly. Treat existing migrations asforward-onlyunless this card implements and proves a realdown.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/removal8 8 spike8 8 docs/audit/handoff20 20 release12 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--testtargets = 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 scopeisSorMonly.L/XLafter 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
Mis L: split by default. Mechanical repo-wide rename/delete/format may takeL-exception:EX-<n>with a named waiver.XLis never a start state. Countingsrc/or repo root as "one landing" is inflation.
-
G-05 Agent-executable alone:
Current evidencehas checkablefile:lineanchors.Acceptance criteriaare self-contained.Verificationis copy-paste commands.DependenciesciteDEP-*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'sDependenciesmust 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/removaltake a full slice unless they are predeclared G-08, G-12, or G-13 children.docs/audit/spike/handoffareno-releaseand say which commit lands them. Areleasecard responsible for a version is the release point. The ER-08 terminal evidence-onlyreleasecard 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 aREL-*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
releasecard as the unique release point. Children:family child. Point:family release point. Register the no-push window asREL-*. -
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.tomlversion+Cargo.lockfor an actual versioned release. UseN/Afor family child / G-12 plan release child / G-13 repair aggregate child / no-release cards and for an ER-08 terminal evidence-onlyreleasecard, 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, notFiles likely touched.
-
G-11 Task type:
implementation(default) |migration(usuallyforward-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 versionedTask type=releasepoint, 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 reviewPASS. 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/removalchild retains its own G-01–G-06 and G-09–G-11 checks, ER-04 A/B focused and type gates, ER-05PASS, and a precise locallibra commit -s. SetRelease boundary=plan release child of REL-<n>,Version increment=N/A,Release write set=N/A, andC/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/handoffcards remainno-release, name the same point inC/D coverage from, and put their reviewed, locally accepted artifacts and precise local commits into that point's tested tree. Strictly post-D evidence-onlydocs/auditcards are outside the pre-releaseREL-*group; they remainno-release, name the post-D ER-08 terminal evidence-onlyreleaseclose-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 genericEX-*D deferral does not apply to this gate. Members inherit C/D from that point and cannot bedone/completebefore 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.
- Before further member work or any publication under this boundary, register a
-
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
implementationcard. 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
pendingfor 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, oneTask type=releasepoint, 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 inREL-*. The DAG places the point after all pre-release carriers. Actual, mutually isolated Claude and Codex plan reviews must both explicitlyPASSthis 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, andC/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-05PASSbefore a precise local commit with ER-07 signature checks and sign-off. No child isdone/completebefore 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 plusCargo.lock; it adds no product behavior. Only after every member's evidence above and the point's own ER-05PASSmay 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.
- Admission and registration: A defect may be registered
| 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 |
| 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 |
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> |
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> |
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.
rgused 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 --alldoes 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 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.
| 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> |
| 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 | 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 point | Acceptable residue | Recovery | Forbidden outcome |
|---|---|---|---|
<mid-transaction, pre-commit> |
<temp table / partial write> |
<retry/abandon/rollback> |
<data loss / partial commit / silent success> |
| Risk | Impact | Mitigation | Task |
|---|---|---|---|
<risk> |
<high/med/low + impact> |
<test/design/gate> |
<ID> |
| Operation | Per-call cost | Cumulative cost | Budget / cap | Proof |
|---|---|---|---|---|
<op> |
<O(...)> |
<O(...)> |
<threshold> |
<test/benchmark> |
-
docs/errors.mdsynced, orN/A. - Related
docs/refactoring/*.mdsynced, orN/A. -
config/config.tomlsamples and comments synced, orN/A. - Runtime OpenAPI (
/api/openapi.json) evidence captured, orN/A(no on-disk spec). -
README.md/AGENTS.mdconstraints synced or drift registered, orN/A. -
src/callisto/,src/jupiter/storage/,src/jupiter/migration/(includingmigrations()) synced, orN/A. - New
docs/*.mdcitations all exist, orN/A. -
plan-long.mddated-plan index or PT/SB status synced, orN/A.
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> |
| ID | Deferred | Why | Restart when | Owner |
|---|---|---|---|---|
| DEFER--01 | <what> |
<why> |
<when> |
<plan/PT/ADR> |
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, completeREL-*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=doneandAcceptance=complete(ER-04).remote-pendingcards must first get green D or a named, allowlistedEX-*deferral with registeredDEFER-*debt.blockedcards must unblock or becomeDEFER-*. - 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 --allall green;cargo buildandcargo build --tests0 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 modewas 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 throughghwith 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 becamedone/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.mdPT/SB status or dated-plan index is synced, orN/A.