You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Implements the `specsync stale` command — a focused staleness detection tool that identifies specs whose source files have diverged via git commit history. Reports which specs need updating, how many commits they are behind, and which specific source files have drifted. Supports text, JSON, markdown, and GitHub output formats.
22
+
23
+
## Public API
24
+
25
+
### Exported Functions
26
+
27
+
| Function | Parameters | Returns | Description |
28
+
|----------|-----------|---------|-------------|
29
+
|`cmd_stale`|`root: &Path, format: OutputFormat, threshold: usize`|`()`| Detect and report stale specs based on git commit distance |
30
+
31
+
## Invariants
32
+
33
+
1. Staleness is determined by `git_commits_between`: a spec is stale when any source file has >= `threshold` commits since the spec was last modified (default: 5)
34
+
2. Specs with no `files` in frontmatter are counted as fresh (no source files to compare against)
35
+
3. Specs not yet tracked by git (no commit history) are skipped and counted as fresh
36
+
4. Results are sorted by most-stale-first (highest `max_commits_behind`)
37
+
5. Exit code is 1 when any stale specs are found, 0 when all are fresh
38
+
6. Requires a git repository — exits with error if `is_git_repo` returns false
39
+
40
+
## Behavioral Examples
41
+
42
+
### Scenario: All specs fresh
43
+
44
+
-**Given** all specs were updated after their source files
45
+
-**When**`specsync stale` is run
46
+
-**Then** prints "All specs are up to date" and exits 0
47
+
48
+
### Scenario: Spec behind source by 8 commits (threshold 5)
49
+
50
+
-**Given** module "auth" has source file `src/auth.rs` with 8 commits since spec was last updated
51
+
-**When**`specsync stale --threshold 5` is run
52
+
-**Then** reports auth as stale with "8 commits behind" and exits 1
53
+
54
+
### Scenario: JSON output
55
+
56
+
-**Given** 2 stale specs out of 10 total
57
+
-**When**`specsync stale --format json` is run
58
+
-**Then** outputs JSON with `total_specs: 10`, `stale_count: 2`, `stale_specs` array with per-file details
59
+
60
+
## Error Cases
61
+
62
+
| Condition | Behavior |
63
+
|-----------|----------|
64
+
| Not a git repository | Prints error, exits 1 |
65
+
| Spec file unreadable | Skipped silently |
66
+
| No frontmatter | Skipped silently |
67
+
| Source file doesn't exist on disk | Skipped in commit distance check |
68
+
69
+
## Dependencies
70
+
71
+
-`git_utils` — git commit history queries
72
+
-`parser` — frontmatter parsing for module name and files list
73
+
-`commands` — `load_and_discover` for config and spec file discovery
Shared git utility functions for querying repository history. Provides commit hash lookup, commit distance counting, and git repository detection. Used by the `stale`, `report`, and `scoring` modules to determine spec freshness relative to source file changes.
17
+
18
+
## Public API
19
+
20
+
### Exported Functions
21
+
22
+
| Function | Parameters | Returns | Description |
23
+
|----------|-----------|---------|-------------|
24
+
|`git_last_commit_hash`|`root: &Path, file: &str`|`Option<String>`| Get the SHA hash of the last commit that touched a file |
25
+
|`git_commits_between`|`root: &Path, spec_file: &str, source_file: &str`|`usize`| Count commits to source_file since spec_file was last modified |
26
+
|`is_git_repo`|`root: &Path`|`bool`| Check if a directory is inside a git work tree |
27
+
28
+
### Exported Types
29
+
30
+
| Type | Kind | Description |
31
+
|------|------|-------------|
32
+
|`StaleInfo`| struct | Staleness summary for a single spec: path, module name, max commits behind, per-file details |
33
+
34
+
## Invariants
35
+
36
+
1. All git commands execute with `current_dir(root)` to ensure correct repository context
37
+
2. Functions return safe defaults (None, 0, false) when git is unavailable or commands fail
0 commit comments