Index mapping design
The index mapping preserves continuity between specification slugs and GitHub issue numbers.
Purpose
Section titled “Purpose”Maintain a durable mapping from external_id
(spec slug) to GitHub issue numbers so title changes or re-ordering never break updates.
Mapping lifecycle
Section titled “Mapping lifecycle”stateDiagram-v2 [*] --> LoadIndex: Sync starts LoadIndex --> EmptyIndex: File missing/corrupt LoadIndex --> ExistingIndex: Valid index found
EmptyIndex --> ComputePlan: Fresh mappings ExistingIndex --> ComputePlan: Merge with specs
ComputePlan --> DryRun: dry_run=true ComputePlan --> ExecutePlan: dry_run=false
DryRun --> [*]: No persistence
ExecutePlan --> CreateIssues: New slugs ExecutePlan --> UpdateIssues: Changed specs ExecutePlan --> CloseIssues: Missing specs
CreateIssues --> UpdateIndex: Record new mappings UpdateIssues --> UpdateIndex: Update hashes CloseIssues --> PruneIndex: Remove stale entries
UpdateIndex --> PersistIndex PruneIndex --> PersistIndex
PersistIndex --> [*]: Write atomically
This state diagram shows how the index is loaded, updated during sync operations, and persisted atomically.
File path
Section titled “File path”.issuesuite/index.json
Format (version 1)
Section titled “Format (version 1)”{ "version": 1, "generated_at": "2025-09-26T12:00:00Z", "repo": "<owner>/<repo>", "entries": { "api-timeouts": { "issue": 123, "hash": "abc123def4567890" } }}
Fields
Section titled “Fields”version
: Schema revision (start at 1).generated_at
: UTC ISO-8601 timestamp of last full write.repo
: Target repository identifier (optional locally).entries
: Map slug IDs to entry objects containingissue
(int) andhash
(truncated SHA-256).
Lifecycle
Section titled “Lifecycle”- Load existing index if present; start fresh on corruption.
- After a successful non-dry-run sync update entries for created/updated specs and prune stale entries on subsequent runs.
- Persist atomically by writing to a temp file then renaming.
Snapshot threshold
Section titled “Snapshot threshold”The orchestrator emits a mapping_snapshot
in summaries when the mapping size is below the configurable threshold (default 500). Larger mappings include size metadata only.
Error handling
Section titled “Error handling”- On JSON decode errors, log a warning and treat the index as empty.
- On write failure, surface the error but do not abort the sync once results are printed.
Future extensions
Section titled “Future extensions”- Add
closed
boolean for retired IDs. - Cache GitHub Project item IDs to reduce API calls.
- Merge with the hash-state file to reduce file count.
Refer to the ADR index for the authoritative decision record.