312 lines
19 KiB
Markdown
312 lines
19 KiB
Markdown
# Repo Memory Test Documentation Roadmap
|
|
|
|
## Purpose
|
|
|
|
This roadmap tracks the human-readable Markdown test plan for `repo-memory`.
|
|
|
|
It exists so a new agent can immediately answer four questions without
|
|
re-reading the whole codebase:
|
|
|
|
- which test-plan documents already exist
|
|
- which cases have already been written down
|
|
- which cases are still missing
|
|
- what file should be updated next
|
|
|
|
This roadmap is for the Markdown test-plan set under `docs/tests/repo-memory/`.
|
|
It is not a replacement for automated Go tests.
|
|
|
|
## Current Snapshot
|
|
|
|
Snapshot date:
|
|
|
|
- `2026-03-20`
|
|
|
|
Current state:
|
|
|
|
- `repo-memory` CLI is implemented for `init`, `add`, `ingest`, `search`, `list`, `events`, `link`, `verify`, and `repos`
|
|
- package-local automated Go tests now cover every currently documented `repo-memory` command case and workflow case through dedicated CLI integration tests, plus the existing markdown parser and store-level tests
|
|
- this roadmap now exists under `docs/tests/repo-memory/ROADMAP.md`
|
|
- all planned global, shared, workflow, command-index, and command-case Markdown documents in the current `repo-memory` test-plan set have been authored
|
|
- each implemented `repo-memory` command folder now uses `README.md` as an index plus one Markdown file per planned case
|
|
- `docs/tests/repo-memory-skill/` can now stay focused on skill-forward behavior while `docs/tests/repo-memory/` owns direct CLI contract coverage
|
|
- a follow-up edge audit on `2026-03-20` identified seven additional boundary cases, and those cases are now authored in the Markdown plan
|
|
- `verify` automation also exposed and fixed a store-level deadlock in `ListVerifyCandidates`, so the documented verify workflows now execute end-to-end in tests
|
|
|
|
Progress summary for planned test-plan documents, excluding `ROADMAP.md`:
|
|
|
|
- planned document files: `39`
|
|
- authored document files: `39`
|
|
- planned case slugs in this roadmap: `31`
|
|
- authored case slugs in this roadmap: `31`
|
|
|
|
## Scope
|
|
|
|
In scope:
|
|
|
|
- `repo-memory init`
|
|
- `repo-memory add`
|
|
- `repo-memory ingest`
|
|
- `repo-memory search`
|
|
- `repo-memory list`
|
|
- `repo-memory events`
|
|
- `repo-memory link`
|
|
- `repo-memory verify`
|
|
- `repo-memory repos`
|
|
- cross-command workflows
|
|
- shared test conventions for text output, exit codes, temp repos, repo fixtures, and read-only DB inspection where the CLI has no inspection surface
|
|
|
|
Out of scope:
|
|
|
|
- `skills/repo-memory/` forward execution behavior except as a related reference
|
|
- implementation details that are not visible through the `repo-memory` CLI contract
|
|
- future commands that are not currently implemented
|
|
|
|
## Tracking Rules
|
|
|
|
Directory model:
|
|
|
|
- one folder per command or shared area
|
|
- each folder keeps a `README.md` entrypoint
|
|
- command folders use `README.md` as an index only
|
|
- each command case lives in its own Markdown file named after the case slug
|
|
- cross-command workflow cases remain grouped in `docs/tests/repo-memory/workflows/README.md`
|
|
|
|
Case identity:
|
|
|
|
- do not use numeric IDs
|
|
- identify each command case by its concrete file path
|
|
- identify each workflow case by `path + case slug`
|
|
- command case file naming pattern:
|
|
|
|
```text
|
|
<case-slug>.md
|
|
```
|
|
|
|
- workflow case heading pattern:
|
|
|
|
```md
|
|
## case: add-search-events-roundtrip
|
|
```
|
|
|
|
Per-case structure inside the case document:
|
|
|
|
- `用例意义`
|
|
- `前置条件`
|
|
- `输入`
|
|
- `预期输出`
|
|
- `断言结论`
|
|
|
|
How to update this roadmap when a new case is written:
|
|
|
|
1. if it is a command case, create or update the target `<case-slug>.md` file under the relevant command folder
|
|
2. if it is a command case, add or update the entry in that folder `README.md` index
|
|
3. if it is a workflow case, add or update the case inside `docs/tests/repo-memory/workflows/README.md`
|
|
4. move the case slug from `Pending Case Backlog` to `Authored Case Register`
|
|
5. update the authored counts in `Current Snapshot`
|
|
6. if a new Markdown file is created, update `Document Progress`
|
|
|
|
Allowed status values in this roadmap:
|
|
|
|
- `pending`
|
|
- `in_progress`
|
|
- `done`
|
|
- `deferred`
|
|
|
|
## Existing Automated Coverage Reference
|
|
|
|
The Markdown test-plan set starts from explicit CLI contract docs, but these
|
|
automated tests already exist and should be used as source material when
|
|
writing the docs:
|
|
|
|
- [init_integration_test.go](../../../packages/repo-memory-runtime/cmd/repo-memory/init_integration_test.go) for `init`
|
|
- [add_integration_test.go](../../../packages/repo-memory-runtime/cmd/repo-memory/add_integration_test.go) for `add`
|
|
- [ingest_integration_test.go](../../../packages/repo-memory-runtime/cmd/repo-memory/ingest_integration_test.go) for `ingest`
|
|
- [search_integration_test.go](../../../packages/repo-memory-runtime/cmd/repo-memory/search_integration_test.go) for `search`
|
|
- [list_integration_test.go](../../../packages/repo-memory-runtime/cmd/repo-memory/list_integration_test.go) for `list`
|
|
- [events_integration_test.go](../../../packages/repo-memory-runtime/cmd/repo-memory/events_integration_test.go) for `events`
|
|
- [link_integration_test.go](../../../packages/repo-memory-runtime/cmd/repo-memory/link_integration_test.go) for `link`
|
|
- [verify_integration_test.go](../../../packages/repo-memory-runtime/cmd/repo-memory/verify_integration_test.go) for `verify`
|
|
- [repos_integration_test.go](../../../packages/repo-memory-runtime/cmd/repo-memory/repos_integration_test.go) for `repos`
|
|
- [workflow_integration_test.go](../../../packages/repo-memory-runtime/cmd/repo-memory/workflow_integration_test.go) for the documented workflow cases
|
|
- [store_test.go](../../../packages/repo-memory-runtime/internal/store/store_test.go#L11) `TestImportDocumentAndSearch`
|
|
- [store_test.go](../../../packages/repo-memory-runtime/internal/store/store_test.go#L67) `TestUpsertEntryWithAliasesAndDependencies`
|
|
- [store_test.go](../../../packages/repo-memory-runtime/internal/store/store_test.go#L178) `TestApplyVerificationResult`
|
|
- [load_test.go](../../../packages/repo-memory-runtime/internal/documents/load_test.go#L10) `TestParseFile`
|
|
- [main_test.go](../../../packages/repo-memory-runtime/cmd/repo-memory/main_test.go#L12) `TestVerifyCandidateDetectsFileChange`
|
|
- [main_test.go](../../../packages/repo-memory-runtime/cmd/repo-memory/main_test.go#L50) `TestVerifyCandidateMarksMissingDependencyStale`
|
|
|
|
These tests do not remove the need for the Markdown plan. They only reduce
|
|
discovery work.
|
|
|
|
## Planned Directory Tree
|
|
|
|
```text
|
|
docs/tests/repo-memory/
|
|
ROADMAP.md
|
|
README.md
|
|
_shared/
|
|
README.md
|
|
workflows/
|
|
README.md
|
|
init/
|
|
README.md
|
|
<case-slug>.md
|
|
add/
|
|
README.md
|
|
<case-slug>.md
|
|
ingest/
|
|
README.md
|
|
<case-slug>.md
|
|
search/
|
|
README.md
|
|
<case-slug>.md
|
|
list/
|
|
README.md
|
|
<case-slug>.md
|
|
events/
|
|
README.md
|
|
<case-slug>.md
|
|
link/
|
|
README.md
|
|
<case-slug>.md
|
|
verify/
|
|
README.md
|
|
<case-slug>.md
|
|
repos/
|
|
README.md
|
|
<case-slug>.md
|
|
```
|
|
|
|
## Document Progress
|
|
|
|
| Path | Purpose | Planned Cases | Authored Cases | Status |
|
|
| --- | --- | ---: | ---: | --- |
|
|
| `docs/tests/repo-memory/README.md` | Global testing conventions and glossary | 0 | 0 | done |
|
|
| `docs/tests/repo-memory/_shared/README.md` | Shared fixtures, output assertions, exit codes, and repo rules | 0 | 0 | done |
|
|
| `docs/tests/repo-memory/workflows/README.md` | Cross-command scenarios | 4 | 4 | done |
|
|
| `docs/tests/repo-memory/init/README.md` | `init` command case index | 0 | 0 | done |
|
|
| `docs/tests/repo-memory/init/init-creates-schema-on-empty-db.md` | `init` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/init/init-is-idempotent-on-existing-db.md` | `init` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/add/README.md` | `add` command case index | 0 | 0 | done |
|
|
| `docs/tests/repo-memory/add/add-registers-repo-and-entry.md` | `add` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/add/add-updates-existing-entry-on-same-kind-and-key.md` | `add` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/add/add-failed-validation-still-registers-repo.md` | `add` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/ingest/README.md` | `ingest` command case index | 0 | 0 | done |
|
|
| `docs/tests/repo-memory/ingest/ingest-imports-docs-ai-markdown.md` | `ingest` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/ingest/ingest-rejects-when-no-markdown-found.md` | `ingest` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/ingest/ingest-imports-headingless-markdown-as-single-entry.md` | `ingest` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/search/README.md` | `search` command case index | 0 | 0 | done |
|
|
| `docs/tests/repo-memory/search/search-returns-matching-entry-snippet.md` | `search` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/search/search-matches-alias-with-repo-filter.md` | `search` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/search/search-returns-no-results-when-empty.md` | `search` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/search/search-rejects-missing-query.md` | `search` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/list/README.md` | `list` command case index | 0 | 0 | done |
|
|
| `docs/tests/repo-memory/list/list-filters-by-kind-and-status.md` | `list` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/list/list-returns-no-entries-when-empty.md` | `list` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/events/README.md` | `events` command case index | 0 | 0 | done |
|
|
| `docs/tests/repo-memory/events/events-reads-history-by-id.md` | `events` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/events/events-resolves-entry-by-repo-kind-key.md` | `events` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/events/events-rejects-missing-entry-selector.md` | `events` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/link/README.md` | `link` command case index | 0 | 0 | done |
|
|
| `docs/tests/repo-memory/link/link-creates-relation-between-entries.md` | `link` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/link/link-rejects-missing-relation.md` | `link` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/link/link-rejects-when-entry-id-missing.md` | `link` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/verify/README.md` | `verify` command case index | 0 | 0 | done |
|
|
| `docs/tests/repo-memory/verify/verify-downgrades-changed-file-dependency.md` | `verify` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/verify/verify-marks-missing-hard-dependency-stale.md` | `verify` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/verify/verify-prints-no-repos-when-empty.md` | `verify` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/verify/verify-skips-explicit-repo-without-git-head.md` | `verify` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/verify/verify-downgrades-entry-missing-verified-on-commit.md` | `verify` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/repos/README.md` | `repos` command case index | 0 | 0 | done |
|
|
| `docs/tests/repo-memory/repos/repos-lists-tracked-repositories.md` | `repos` command case | 1 | 1 | done |
|
|
| `docs/tests/repo-memory/repos/repos-prints-no-repos-when-empty.md` | `repos` command case | 1 | 1 | done |
|
|
|
|
## Authoring Order
|
|
|
|
Recommended order:
|
|
|
|
1. `docs/tests/repo-memory/README.md`
|
|
2. `docs/tests/repo-memory/_shared/README.md`
|
|
3. `docs/tests/repo-memory/workflows/README.md`
|
|
4. `docs/tests/repo-memory/add/README.md` plus its linked case files
|
|
5. `docs/tests/repo-memory/ingest/README.md` plus its linked case files
|
|
6. `docs/tests/repo-memory/search/README.md` plus its linked case files
|
|
7. `docs/tests/repo-memory/verify/README.md` plus its linked case files
|
|
8. the remaining command indexes and case files
|
|
|
|
Reason:
|
|
|
|
- the workflow file captures the highest-value repo-memory lifecycle behavior first
|
|
- command documents can then reuse shared conventions and already-fixed terminology
|
|
|
|
## Edge Audit Notes
|
|
|
|
Per-command review status after auditing the current CLI source and authored docs:
|
|
|
|
- `init`: current coverage is sufficient for now; no additional high-value boundary was found beyond ordinary filesystem failure paths
|
|
- `add`: now covers both normal upsert flow and the surprising zero-entry repo side effect on failed validation
|
|
- `ingest`: now covers both ordinary section import and the headingless fallback-entry parser path
|
|
- `search`: now covers both positive lookup behavior and the required `--query` failure contract
|
|
- `list`: current coverage is acceptable for now; remaining gaps are mostly lower-priority default-limit behavior and shared uninitialized-schema behavior
|
|
- `events`: now covers both selector styles and the missing-selector failure contract
|
|
- `link`: now covers both successful relation writes and missing-input rejection for ids and relation
|
|
- `verify`: now covers changed-file downgrade, missing-hard-dependency stale, empty-repo set, explicit skip without Git HEAD, and missing `verified_on_commit`
|
|
- `repos`: current coverage is acceptable for now; the zero-entry repo side effect is intentionally documented from the `add` boundary case
|
|
|
|
## Authored Case Register
|
|
|
|
| Path | Case Slug | Coverage Note | Status |
|
|
| --- | --- | --- | --- |
|
|
| `docs/tests/repo-memory/workflows/README.md` | `add-search-events-roundtrip` | end-to-end write, search, and history roundtrip for one durable entry | done |
|
|
| `docs/tests/repo-memory/workflows/README.md` | `ingest-search-list-across-sections` | markdown ingest surfaces multiple imported entries through search and list | done |
|
|
| `docs/tests/repo-memory/workflows/README.md` | `add-link-and-resolve-related-entry` | two entries are linked and the relation is persisted | done |
|
|
| `docs/tests/repo-memory/workflows/README.md` | `verify-downgrades-after-repo-change` | repo changes propagate into downgraded or stale durable knowledge | done |
|
|
| `docs/tests/repo-memory/init/init-creates-schema-on-empty-db.md` | `init-creates-schema-on-empty-db` | initializes an empty database path and prints the initialized path | done |
|
|
| `docs/tests/repo-memory/init/init-is-idempotent-on-existing-db.md` | `init-is-idempotent-on-existing-db` | repeated init succeeds on the same database path | done |
|
|
| `docs/tests/repo-memory/add/add-registers-repo-and-entry.md` | `add-registers-repo-and-entry` | auto-bootstraps schema, registers the repo, and creates one durable entry | done |
|
|
| `docs/tests/repo-memory/add/add-updates-existing-entry-on-same-kind-and-key.md` | `add-updates-existing-entry-on-same-kind-and-key` | repeated upsert reuses the same entry id and records an update event | done |
|
|
| `docs/tests/repo-memory/add/add-failed-validation-still-registers-repo.md` | `add-failed-validation-still-registers-repo` | failed validation still leaves a zero-entry repo row visible through `repos` | done |
|
|
| `docs/tests/repo-memory/ingest/ingest-imports-docs-ai-markdown.md` | `ingest-imports-docs-ai-markdown` | imports markdown sections under `docs/ai` as confirmed knowledge entries | done |
|
|
| `docs/tests/repo-memory/ingest/ingest-rejects-when-no-markdown-found.md` | `ingest-rejects-when-no-markdown-found` | rejects an empty scan tree with a stable error message | done |
|
|
| `docs/tests/repo-memory/ingest/ingest-imports-headingless-markdown-as-single-entry.md` | `ingest-imports-headingless-markdown-as-single-entry` | headingless markdown falls back to one imported entry instead of being skipped | done |
|
|
| `docs/tests/repo-memory/search/search-returns-matching-entry-snippet.md` | `search-returns-matching-entry-snippet` | returns a ranked text result with status and snippet lines | done |
|
|
| `docs/tests/repo-memory/search/search-matches-alias-with-repo-filter.md` | `search-matches-alias-with-repo-filter` | matches alias terms while narrowing by repo substring | done |
|
|
| `docs/tests/repo-memory/search/search-returns-no-results-when-empty.md` | `search-returns-no-results-when-empty` | prints `no results` for an empty search result set | done |
|
|
| `docs/tests/repo-memory/search/search-rejects-missing-query.md` | `search-rejects-missing-query` | rejects empty search invocation without `--query` | done |
|
|
| `docs/tests/repo-memory/list/list-filters-by-kind-and-status.md` | `list-filters-by-kind-and-status` | narrows entries by repo substring, kind, and status | done |
|
|
| `docs/tests/repo-memory/list/list-returns-no-entries-when-empty.md` | `list-returns-no-entries-when-empty` | prints `no entries` when the filtered result set is empty | done |
|
|
| `docs/tests/repo-memory/events/events-reads-history-by-id.md` | `events-reads-history-by-id` | prints newest-first history for one entry id | done |
|
|
| `docs/tests/repo-memory/events/events-resolves-entry-by-repo-kind-key.md` | `events-resolves-entry-by-repo-kind-key` | resolves an entry without `--id` when repo, kind, and key are provided | done |
|
|
| `docs/tests/repo-memory/events/events-rejects-missing-entry-selector.md` | `events-rejects-missing-entry-selector` | rejects calls that omit both `--id` and `--repo+--kind+--key` | done |
|
|
| `docs/tests/repo-memory/link/link-creates-relation-between-entries.md` | `link-creates-relation-between-entries` | persists one directed relation between two existing entries | done |
|
|
| `docs/tests/repo-memory/link/link-rejects-missing-relation.md` | `link-rejects-missing-relation` | rejects empty relation input before write | done |
|
|
| `docs/tests/repo-memory/link/link-rejects-when-entry-id-missing.md` | `link-rejects-when-entry-id-missing` | rejects link requests without both entry ids | done |
|
|
| `docs/tests/repo-memory/verify/verify-downgrades-changed-file-dependency.md` | `verify-downgrades-changed-file-dependency` | downgrades a confirmed entry to `needs_review` when a tracked file changed | done |
|
|
| `docs/tests/repo-memory/verify/verify-marks-missing-hard-dependency-stale.md` | `verify-marks-missing-hard-dependency-stale` | marks a confirmed entry `stale` when a hard dependency disappears | done |
|
|
| `docs/tests/repo-memory/verify/verify-prints-no-repos-when-empty.md` | `verify-prints-no-repos-when-empty` | prints `no repos` when the initialized DB has no tracked repositories | done |
|
|
| `docs/tests/repo-memory/verify/verify-skips-explicit-repo-without-git-head.md` | `verify-skips-explicit-repo-without-git-head` | explicit repo verification reports a skip when the repo is not a Git repo or has no HEAD | done |
|
|
| `docs/tests/repo-memory/verify/verify-downgrades-entry-missing-verified-on-commit.md` | `verify-downgrades-entry-missing-verified-on-commit` | entries created without `verified_on_commit` downgrade to `needs_review` once the repo becomes verifiable | done |
|
|
| `docs/tests/repo-memory/repos/repos-lists-tracked-repositories.md` | `repos-lists-tracked-repositories` | lists every tracked repository with entry counts and update timestamps | done |
|
|
| `docs/tests/repo-memory/repos/repos-prints-no-repos-when-empty.md` | `repos-prints-no-repos-when-empty` | prints `no repos` for an initialized but unused database | done |
|
|
|
|
## Pending Case Backlog
|
|
|
|
No pending case slugs remain in the current plan.
|
|
|
|
When a new CLI contract or workflow needs coverage:
|
|
|
|
1. if it is a command case, create a new `<case-slug>.md` file under the relevant command folder and add it to that folder `README.md` index
|
|
2. if it is a workflow case, add it to `docs/tests/repo-memory/workflows/README.md`
|
|
3. add the new slug to `Authored Case Register`
|
|
4. update `Current Snapshot` and `Document Progress`
|
|
|
|
## Definition Of Done
|
|
|
|
This roadmap is complete only when all of the following are true:
|
|
|
|
- every implemented `repo-memory` command has a corresponding document folder
|
|
- each planned command index and case document exists
|
|
- each pending case slug has been either authored or explicitly deferred
|
|
- the authored-case register matches the actual Markdown files on disk
|
|
- a new agent can pick any pending case and know exactly where it should be written
|