Migration: Document Index Restructure (v1.51.0)
Affects releases: 1.51.0 and later
Breaking change: No (auto-migration on first run)
Backed-up: Yes (legacy _index.md preserved as _index.md.bak)
What changed
The single-file docs/_index.md has been replaced with a per-suite layout
under docs/_index/:
docs/_index/
├── _manifest.yaml # always loaded into AI prompts (~2-5K tokens)
├── _checksums.json # never sent to AI; used for incremental detection
└── groups/
├── checkout.index.md # lazy-loaded; one per suite
├── payments.index.md
└── ...
Why
On large projects (500+ docs), the legacy single-file index grew to ~46K
tokens, over a third of the model’s 128K context window. Combined with the
analyzer’s per-doc previews, the prompt routinely exceeded 200K tokens and
hit a hard 400 prompt token count exceeds the limit of 128000 error from
the model. The new layout is per-suite, so generating tests scoped to suite X
loads only suite X’s entries.
A new pre-flight token-budget check fails fast with an actionable error listing the available suites and their token costs, rather than letting the model overflow.
What you need to do
Existing users
Nothing. Run spectra docs index once after upgrading and you’ll see:
Migrated 541 docs across 12 suites. Largest suite: SM_GSG_Topics
(145 docs, ~10,877 tokens). Legacy index preserved as
docs/_index.md.bak — safe to delete after verification.
The original docs/_index.md is renamed to docs/_index.md.bak. The new
layout is written under docs/_index/. Subsequent runs do an incremental
update.
Optional cleanup
After verifying the new layout works (spectra docs list-suites), you can
delete docs/_index.md.bak. Add docs/_index/ to source control as you
would any generated artifact.
Reviewing default exclusion patterns
This migration introduces coverage.analysis_exclude_patterns (defaults below).
Documents matching these globs are still indexed and counted in coverage,
but their suites are flagged skip_analysis: true and the AI analyzer
excludes them from prompt input by default.
{
"coverage": {
"analysis_exclude_patterns": [
"**/Old/**",
"**/old/**",
"**/legacy/**",
"**/archive/**",
"**/release-notes/**",
"**/CHANGELOG*",
"**/SUMMARY.md"
]
}
}
Override per-document via frontmatter:
---
suite: my-custom-suite
analyze: true
---
Or globally by editing coverage.analysis_exclude_patterns in
spectra.config.json. Setting it to [] disables all default exclusions.
New CLI flags
| Flag | Affects | Behavior |
|---|---|---|
--include-archived |
spectra docs index, spectra ai compile-analysis-prompt, spectra ai analyze |
Includes skip-analysis suites in the AI input |
--no-migrate |
spectra docs index |
Errors out instead of auto-migrating a legacy file |
--suites <ids> |
spectra docs index |
Re-indexes only the named suites |
New introspection commands
# List every suite with document count + token estimate + skip status
spectra docs list-suites
spectra docs list-suites --output-format json
# Print one suite's index file
spectra docs show-suite SM_GSG_Topics
New configuration keys
{
"ai": {
"analysis": {
"max_prompt_tokens": 96000 // pre-flight budget; 0 to disable
}
},
"coverage": {
"analysis_exclude_patterns": [...],
"max_suite_tokens": 80000 // spillover threshold
},
"source": {
"doc_index_dir": "docs/_index", // v2 layout root
"group_overrides": {} // per-path suite override
}
}
New exit code
| Code | Meaning |
|---|---|
4 |
Pre-flight budget exceeded; narrow with --suite or raise ai.analysis.max_prompt_tokens |
Troubleshooting
“Analyzer prompt would be ~187K tokens, exceeding…”
That’s the new pre-flight check. Pick a suite from
spectra docs list-suites and re-run with --suite <id>. If you genuinely
need to load the entire corpus, raise
ai.analysis.max_prompt_tokens in spectra.config.json (within the
model’s actual capacity).
“No doc-suite ‘' in manifest"
The CLI passes --suite as both a test-suite name and a doc-suite filter.
If they don’t match, you’ll see a warning and the analyzer falls back to
loading all non-archived suites (still subject to the budget check). To
reconcile, either rename the test suite to match the doc-suite, or add
a config override:
{
"source": {
"group_overrides": {
"docs/some/path.md": "my-suite"
}
}
}
Migration didn’t run on a project I expected
The migrator only runs when (a) docs/_index.md exists AND (b)
docs/_index/_manifest.yaml does not. If both are present, migration is
skipped. To force a re-migration, delete docs/_index/ and re-run.