Docs cover 75 commands; tests cover 53; usage covers 72. Tests is the bottleneck — every Completed command needs all three. Closing the largest group would move 96% of the debt — the biggest single shift available.
Coverage counts the docs that exist; depth weighs what they actually say — from full behavioral prose down to a bare signature stub.
How far the non-reference docs have fallen behind the code — measured in days, from git commit timestamps.
command: sheaf short: Sheaf — contract-coverage analysis. long: | Sheaf finds the gaps between your contracts (APIs, CLIs), tests, docs,
N/A
N/A
N/A
N/A
command: sheaf coverage
short: Print the CoverageProfile for one element.
long: |
Focused inverse of `sheaf report`. Runs the full pipeline, then
emits the CoverageProfile for the single element named by --element
as either pretty-printed text or JSON.
usage: sheaf coverage --element id [--config path] [--repo path] [--format fmt]
pname: sheaf
plink: sheaf.yaml
options:
- option: config
value_type: string
`sheaf scan`, `sheaf gaps`, `sheaf coverage`, `sheaf report`, `sheaf snapshot`, `sheaf serve`, and `sheaf review` all run the full pipeline (config load → adapter dispatch → indexer → analyzers) before producing their output. `sheaf render` and `sheaf review-html` are pipeline-free — they render from a Snapshot JSON / `delta.json` that an earlier pipeline run already produced — as are `sheaf doctor`, `sheaf version`, and `sheaf init`.
- [`sheaf coverage`](sheaf_coverage.md) — the production version of single-element drill-in. - [`sheaf report`](sheaf_report.md) — bulk dump of every profile.
func TestRunCoverage_UnknownElement(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runCoverage(&out, &errOut, "", dir, "definitely-not-a-real-element", "text")
if rc != 2 {
t.Errorf("expected rc=2 for unknown element; got %d; stderr=%s", rc, errOut.String())
}
}
func TestRunCoverage_FormatRepoFlags(t *testing.T) {
// --format json with a bogus --element still resolves the
// pipeline and prints the no-profile error. Path coverage check
// for the --repo + --format flag attribution.
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runCoverage(&out, &errOut, "", dir, "nope-not-real", "json")
if rc != 2 {
t.Errorf("expected rc=2; got %d", rc)
}
}
func TestRunCoverage_MissingConfig(t *testing.T) {
dir := t.TempDir()
var out, errOut bytes.Buffer
rc := runCoverage(&out, &errOut, "", dir, "anything", "text")
if rc == 0 {
t.Errorf("expected non-zero exit on missing config; out=%s err=%s", out.String(), errOut.String())
}
}
N/A
command: sheaf coverage
short: Print the CoverageProfile for one element.
long: |
Focused inverse of `sheaf report`. Runs the full pipeline, then
emits the CoverageProfile for the single element named by --element
as either pretty-printed text or JSON.
usage: sheaf coverage --element id [--config path] [--repo path] [--format fmt]
pname: sheaf
plink: sheaf.yaml
options:
- option: config
value_type: string
**Coverage.** `sheaf coverage --element` is required — it names the contract element whose profile you want. `sheaf coverage --format` switches between the human-readable text dump and `json`, while `sheaf coverage --config` and `sheaf coverage --repo` locate the project the same way scan does.
func TestCoverage_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so --config / --repo / --element /
// --format are parsed from the command line. The runCoverage tests
// above pass those values positionally, which never exercises the
// flag wiring (nor attributes the flags in the self-scan); this
// closes both gaps in one real end-to-end parse.
dir := setupFixture(t)
rc := Coverage([]string{
"--config", dir + "/sheaf.textproto",
"--repo", dir,
"--element", "nope-not-real",
"--format", "json",
})
if rc != 2 {
t.Errorf("expected rc=2 for unknown --element via argv; got %d", rc)
}
}
N/A
command: sheaf coverage
short: Print the CoverageProfile for one element.
long: |
Focused inverse of `sheaf report`. Runs the full pipeline, then
emits the CoverageProfile for the single element named by --element
as either pretty-printed text or JSON.
usage: sheaf coverage --element id [--config path] [--repo path] [--format fmt]
pname: sheaf
plink: sheaf.yaml
options:
- option: config
value_type: string
**Coverage.** `sheaf coverage --element` is required — it names the contract element whose profile you want. `sheaf coverage --format` switches between the human-readable text dump and `json`, while `sheaf coverage --config` and `sheaf coverage --repo` locate the project the same way scan does.
func TestCoverage_RequiresElement(t *testing.T) {
// Empty --element exits 2 from the public argv entry with the
// required-flag message, before runCoverage is ever reached.
if rc := Coverage([]string{"--repo", t.TempDir()}); rc != 2 {
t.Errorf("expected rc=2 when --element is omitted; got %d", rc)
}
}
func TestCoverage_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so --config / --repo / --element /
// --format are parsed from the command line. The runCoverage tests
// above pass those values positionally, which never exercises the
// flag wiring (nor attributes the flags in the self-scan); this
// closes both gaps in one real end-to-end parse.
dir := setupFixture(t)
rc := Coverage([]string{
"--config", dir + "/sheaf.textproto",
"--repo", dir,
"--element", "nope-not-real",
"--format", "json",
})
if rc != 2 {
t.Errorf("expected rc=2 for unknown --element via argv; got %d", rc)
}
}
N/A
command: sheaf coverage
short: Print the CoverageProfile for one element.
long: |
Focused inverse of `sheaf report`. Runs the full pipeline, then
emits the CoverageProfile for the single element named by --element
as either pretty-printed text or JSON.
usage: sheaf coverage --element id [--config path] [--repo path] [--format fmt]
pname: sheaf
plink: sheaf.yaml
options:
- option: config
value_type: string
**Coverage.** `sheaf coverage --element` is required — it names the contract element whose profile you want. `sheaf coverage --format` switches between the human-readable text dump and `json`, while `sheaf coverage --config` and `sheaf coverage --repo` locate the project the same way scan does.
func TestCoverage_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so --config / --repo / --element /
// --format are parsed from the command line. The runCoverage tests
// above pass those values positionally, which never exercises the
// flag wiring (nor attributes the flags in the self-scan); this
// closes both gaps in one real end-to-end parse.
dir := setupFixture(t)
rc := Coverage([]string{
"--config", dir + "/sheaf.textproto",
"--repo", dir,
"--element", "nope-not-real",
"--format", "json",
})
if rc != 2 {
t.Errorf("expected rc=2 for unknown --element via argv; got %d", rc)
}
}
N/A
command: sheaf coverage
short: Print the CoverageProfile for one element.
long: |
Focused inverse of `sheaf report`. Runs the full pipeline, then
emits the CoverageProfile for the single element named by --element
as either pretty-printed text or JSON.
usage: sheaf coverage --element id [--config path] [--repo path] [--format fmt]
pname: sheaf
plink: sheaf.yaml
options:
- option: config
value_type: string
**Coverage.** `sheaf coverage --element` is required — it names the contract element whose profile you want. `sheaf coverage --format` switches between the human-readable text dump and `json`, while `sheaf coverage --config` and `sheaf coverage --repo` locate the project the same way scan does.
func TestCoverage_RequiresElement(t *testing.T) {
// Empty --element exits 2 from the public argv entry with the
// required-flag message, before runCoverage is ever reached.
if rc := Coverage([]string{"--repo", t.TempDir()}); rc != 2 {
t.Errorf("expected rc=2 when --element is omitted; got %d", rc)
}
}
func TestCoverage_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so --config / --repo / --element /
// --format are parsed from the command line. The runCoverage tests
// above pass those values positionally, which never exercises the
// flag wiring (nor attributes the flags in the self-scan); this
// closes both gaps in one real end-to-end parse.
dir := setupFixture(t)
rc := Coverage([]string{
"--config", dir + "/sheaf.textproto",
"--repo", dir,
"--element", "nope-not-real",
"--format", "json",
})
if rc != 2 {
t.Errorf("expected rc=2 for unknown --element via argv; got %d", rc)
}
}
N/A
command: sheaf doctor short: Diagnose configuration and adapter health. long: | Validates sheaf.textproto and categorization-rules.textproto, walks every configured adapter, and probes the LLM embedder. Use before the first scan on a new project, or whenever a scan starts producing surprising output. usage: sheaf doctor [--config path] [--repo path] pname: sheaf plink: sheaf.yaml options: - option: config
`sheaf scan`, `sheaf gaps`, `sheaf coverage`, `sheaf report`, `sheaf snapshot`, `sheaf serve`, and `sheaf review` all run the full pipeline (config load → adapter dispatch → indexer → analyzers) before producing their output. `sheaf render` and `sheaf review-html` are pipeline-free — they render from a Snapshot JSON / `delta.json` that an earlier pipeline run already produced — as are `sheaf doctor`, `sheaf version`, and `sheaf init`.
Parse-time and resolve-time errors abort startup with a path-prefixed message (`contract_anchor[1].argh.crate_roots: missing required field`). Probe-time warnings appear in `sheaf doctor` output and at the top of `sheaf scan` runs but do not abort.
func TestRunDoctor_FixtureProject(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runDoctor(&out, &errOut, "", dir)
if rc != 0 {
t.Fatalf("runDoctor returned %d; stderr=%s", rc, errOut.String())
}
got := out.String()
for _, want := range []string{"[OK]", "gtest", "markdown", "Project: demo"} {
if !strings.Contains(got, want) {
t.Errorf("output missing %q\n%s", want, got)
}
}
}
func TestRunDoctor_RulesMissingIsTolerated(t *testing.T) {
dir := t.TempDir()
if err := os.WriteFile(filepath.Join(dir, "sheaf.textproto"), []byte(fixtureConfig), 0o644); err != nil {
t.Fatalf("write: %v", err)
}
var out, errOut bytes.Buffer
rc := runDoctor(&out, &errOut, "", dir)
if rc != 0 {
t.Fatalf("runDoctor returned %d; stderr=%s", rc, errOut.String())
}
if !strings.Contains(out.String(), "[MISSING]") {
t.Errorf("expected [MISSING] marker; got %s", out.String())
}
}
func TestRunDoctor_RepoFlag(t *testing.T) {
// Doctor's --repo flag drives the config + rules path resolution.
// Confirm a non-default --repo still finds the fixture's
// sheaf.textproto.
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runDoctor(&out, &errOut, "", dir)
if rc != 0 {
t.Fatalf("runDoctor(--repo) returned %d; stderr=%s", rc, errOut.String())
}
}
N/A
command: sheaf doctor short: Diagnose configuration and adapter health. long: | Validates sheaf.textproto and categorization-rules.textproto, walks every configured adapter, and probes the LLM embedder. Use before the first scan on a new project, or whenever a scan starts producing surprising output. usage: sheaf doctor [--config path] [--repo path] pname: sheaf plink: sheaf.yaml options: - option: config
**Doctor.** `sheaf doctor` validates the config and walks every adapter. `sheaf doctor --config` checks a config outside the repo root, and `sheaf doctor --repo` resolves the source map relative to a different tree.
func TestDoctor_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so --config and --repo are parsed
// from the command line (the runDoctor tests pass them positionally,
// which neither exercises flag wiring nor attributes --config).
dir := setupFixture(t)
if rc := Doctor([]string{"--config", dir + "/sheaf.textproto", "--repo", dir}); rc != 0 {
t.Errorf("Doctor(--config,--repo) returned %d; want 0", rc)
}
}
N/A
command: sheaf doctor short: Diagnose configuration and adapter health. long: | Validates sheaf.textproto and categorization-rules.textproto, walks every configured adapter, and probes the LLM embedder. Use before the first scan on a new project, or whenever a scan starts producing surprising output. usage: sheaf doctor [--config path] [--repo path] pname: sheaf plink: sheaf.yaml options: - option: config
**Doctor.** `sheaf doctor` validates the config and walks every adapter. `sheaf doctor --config` checks a config outside the repo root, and `sheaf doctor --repo` resolves the source map relative to a different tree.
func TestRunDoctor_RepoFlag(t *testing.T) {
// Doctor's --repo flag drives the config + rules path resolution.
// Confirm a non-default --repo still finds the fixture's
// sheaf.textproto.
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runDoctor(&out, &errOut, "", dir)
if rc != 0 {
t.Fatalf("runDoctor(--repo) returned %d; stderr=%s", rc, errOut.String())
}
}
func TestDoctor_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so --config and --repo are parsed
// from the command line (the runDoctor tests pass them positionally,
// which neither exercises flag wiring nor attributes --config).
dir := setupFixture(t)
if rc := Doctor([]string{"--config", dir + "/sheaf.textproto", "--repo", dir}); rc != 0 {
t.Errorf("Doctor(--config,--repo) returned %d; want 0", rc)
}
}
N/A
command: sheaf gaps
short: List findings filterable by kind, library, and severity.
long: |
Runs the same pipeline as `sheaf scan` and prints the resulting
Finding list, filtered client-side. Output as text, json, or csv.
usage: sheaf gaps [--config path] [--repo path] [--kind k] [--library prefix] [--severity sev] [--format fmt]
pname: sheaf
plink: sheaf.yaml
options:
- option: config
value_type: string
default_value: ""
**Gaps.** `sheaf gaps` lists findings. Narrow them with `sheaf gaps --severity` (minimum `INFO`/`WARNING`/`ERROR`), `sheaf gaps --kind` (a specific finding kind), and `sheaf gaps --library` (one library or element-ID prefix). `sheaf gaps --format` emits `text`, `json`, or `csv`, and `sheaf gaps --config` selects a non-default config.
`sheaf scan`, `sheaf gaps`, `sheaf coverage`, `sheaf report`, `sheaf snapshot`, `sheaf serve`, and `sheaf review` all run the full pipeline (config load → adapter dispatch → indexer → analyzers) before producing their output. `sheaf render` and `sheaf review-html` are pipeline-free — they render from a Snapshot JSON / `delta.json` that an earlier pipeline run already produced — as are `sheaf doctor`, `sheaf version`, and `sheaf init`.
func TestRunGaps_TextFormat(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runGaps(&out, &errOut, "", dir, "", "", "INFO", "text")
if rc != 0 {
t.Fatalf("runGaps returned %d; stderr=%s", rc, errOut.String())
}
// The fixture project has no contract surface configured, so the
// finding list is empty. The text formatter emits the "No findings."
// sentinel in that case — confirm the success path stays runnable.
if got := out.String(); !strings.Contains(got, "No findings.") && !strings.Contains(got, "findings:") {
t.Errorf("expected gaps output; got %q", got)
}
}
func TestRunGaps_CSVFormat(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runGaps(&out, &errOut, "", dir, "", "", "INFO", "csv")
if rc != 0 {
t.Fatalf("runGaps returned %d; stderr=%s", rc, errOut.String())
}
if !strings.Contains(out.String(), "id,kind,subject,severity,analyzer,message") {
t.Errorf("expected CSV header; got %q", out.String())
}
}
func TestRunGaps_LibraryRepoKindFlags(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runGaps(&out, &errOut, "", dir, "THIN_REFERENCE", "demo", "WARNING", "text")
if rc != 0 {
t.Fatalf("runGaps with --library/--repo/--kind returned %d; stderr=%s", rc, errOut.String())
}
}
N/A
command: sheaf gaps
short: List findings filterable by kind, library, and severity.
long: |
Runs the same pipeline as `sheaf scan` and prints the resulting
Finding list, filtered client-side. Output as text, json, or csv.
usage: sheaf gaps [--config path] [--repo path] [--kind k] [--library prefix] [--severity sev] [--format fmt]
pname: sheaf
plink: sheaf.yaml
options:
- option: config
value_type: string
default_value: ""
**Gaps.** `sheaf gaps` lists findings. Narrow them with `sheaf gaps --severity` (minimum `INFO`/`WARNING`/`ERROR`), `sheaf gaps --kind` (a specific finding kind), and `sheaf gaps --library` (one library or element-ID prefix). `sheaf gaps --format` emits `text`, `json`, or `csv`, and `sheaf gaps --config` selects a non-default config.
func TestGaps_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so every gaps flag is parsed from the
// command line. The runGaps tests pass these positionally, which
// leaves --config / --format / --severity unattributed in the
// self-scan even though they're exercised here end to end.
dir := setupFixture(t)
rc := Gaps([]string{
"--config", dir + "/sheaf.textproto",
"--repo", dir,
"--severity", "WARNING",
"--format", "csv",
"--kind", "THIN_REFERENCE",
"--library", "demo",
})
if rc != 0 {
t.Errorf("Gaps(--config/--repo/--severity/--format/--kind/--library) returned %d; want 0", rc)
}
}
N/A
command: sheaf gaps
short: List findings filterable by kind, library, and severity.
long: |
Runs the same pipeline as `sheaf scan` and prints the resulting
Finding list, filtered client-side. Output as text, json, or csv.
usage: sheaf gaps [--config path] [--repo path] [--kind k] [--library prefix] [--severity sev] [--format fmt]
pname: sheaf
plink: sheaf.yaml
options:
- option: config
value_type: string
default_value: ""
**Gaps.** `sheaf gaps` lists findings. Narrow them with `sheaf gaps --severity` (minimum `INFO`/`WARNING`/`ERROR`), `sheaf gaps --kind` (a specific finding kind), and `sheaf gaps --library` (one library or element-ID prefix). `sheaf gaps --format` emits `text`, `json`, or `csv`, and `sheaf gaps --config` selects a non-default config.
func TestGaps_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so every gaps flag is parsed from the
// command line. The runGaps tests pass these positionally, which
// leaves --config / --format / --severity unattributed in the
// self-scan even though they're exercised here end to end.
dir := setupFixture(t)
rc := Gaps([]string{
"--config", dir + "/sheaf.textproto",
"--repo", dir,
"--severity", "WARNING",
"--format", "csv",
"--kind", "THIN_REFERENCE",
"--library", "demo",
})
if rc != 0 {
t.Errorf("Gaps(--config/--repo/--severity/--format/--kind/--library) returned %d; want 0", rc)
}
}
N/A
command: sheaf gaps
short: List findings filterable by kind, library, and severity.
long: |
Runs the same pipeline as `sheaf scan` and prints the resulting
Finding list, filtered client-side. Output as text, json, or csv.
usage: sheaf gaps [--config path] [--repo path] [--kind k] [--library prefix] [--severity sev] [--format fmt]
pname: sheaf
plink: sheaf.yaml
options:
- option: config
value_type: string
default_value: ""
**Gaps.** `sheaf gaps` lists findings. Narrow them with `sheaf gaps --severity` (minimum `INFO`/`WARNING`/`ERROR`), `sheaf gaps --kind` (a specific finding kind), and `sheaf gaps --library` (one library or element-ID prefix). `sheaf gaps --format` emits `text`, `json`, or `csv`, and `sheaf gaps --config` selects a non-default config.
func TestRunGaps_LibraryRepoKindFlags(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runGaps(&out, &errOut, "", dir, "THIN_REFERENCE", "demo", "WARNING", "text")
if rc != 0 {
t.Fatalf("runGaps with --library/--repo/--kind returned %d; stderr=%s", rc, errOut.String())
}
}
func TestGaps_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so every gaps flag is parsed from the
// command line. The runGaps tests pass these positionally, which
// leaves --config / --format / --severity unattributed in the
// self-scan even though they're exercised here end to end.
dir := setupFixture(t)
rc := Gaps([]string{
"--config", dir + "/sheaf.textproto",
"--repo", dir,
"--severity", "WARNING",
"--format", "csv",
"--kind", "THIN_REFERENCE",
"--library", "demo",
})
if rc != 0 {
t.Errorf("Gaps(--config/--repo/--severity/--format/--kind/--library) returned %d; want 0", rc)
}
}
N/A
command: sheaf gaps
short: List findings filterable by kind, library, and severity.
long: |
Runs the same pipeline as `sheaf scan` and prints the resulting
Finding list, filtered client-side. Output as text, json, or csv.
usage: sheaf gaps [--config path] [--repo path] [--kind k] [--library prefix] [--severity sev] [--format fmt]
pname: sheaf
plink: sheaf.yaml
options:
- option: config
value_type: string
default_value: ""
**Gaps.** `sheaf gaps` lists findings. Narrow them with `sheaf gaps --severity` (minimum `INFO`/`WARNING`/`ERROR`), `sheaf gaps --kind` (a specific finding kind), and `sheaf gaps --library` (one library or element-ID prefix). `sheaf gaps --format` emits `text`, `json`, or `csv`, and `sheaf gaps --config` selects a non-default config.
func TestRunGaps_LibraryRepoKindFlags(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runGaps(&out, &errOut, "", dir, "THIN_REFERENCE", "demo", "WARNING", "text")
if rc != 0 {
t.Fatalf("runGaps with --library/--repo/--kind returned %d; stderr=%s", rc, errOut.String())
}
}
func TestGaps_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so every gaps flag is parsed from the
// command line. The runGaps tests pass these positionally, which
// leaves --config / --format / --severity unattributed in the
// self-scan even though they're exercised here end to end.
dir := setupFixture(t)
rc := Gaps([]string{
"--config", dir + "/sheaf.textproto",
"--repo", dir,
"--severity", "WARNING",
"--format", "csv",
"--kind", "THIN_REFERENCE",
"--library", "demo",
})
if rc != 0 {
t.Errorf("Gaps(--config/--repo/--severity/--format/--kind/--library) returned %d; want 0", rc)
}
}
N/A
command: sheaf gaps
short: List findings filterable by kind, library, and severity.
long: |
Runs the same pipeline as `sheaf scan` and prints the resulting
Finding list, filtered client-side. Output as text, json, or csv.
usage: sheaf gaps [--config path] [--repo path] [--kind k] [--library prefix] [--severity sev] [--format fmt]
pname: sheaf
plink: sheaf.yaml
options:
- option: config
value_type: string
default_value: ""
func TestRunGaps_LibraryRepoKindFlags(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runGaps(&out, &errOut, "", dir, "THIN_REFERENCE", "demo", "WARNING", "text")
if rc != 0 {
t.Fatalf("runGaps with --library/--repo/--kind returned %d; stderr=%s", rc, errOut.String())
}
}
func TestGaps_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so every gaps flag is parsed from the
// command line. The runGaps tests pass these positionally, which
// leaves --config / --format / --severity unattributed in the
// self-scan even though they're exercised here end to end.
dir := setupFixture(t)
rc := Gaps([]string{
"--config", dir + "/sheaf.textproto",
"--repo", dir,
"--severity", "WARNING",
"--format", "csv",
"--kind", "THIN_REFERENCE",
"--library", "demo",
})
if rc != 0 {
t.Errorf("Gaps(--config/--repo/--severity/--format/--kind/--library) returned %d; want 0", rc)
}
}
N/A
command: sheaf gaps
short: List findings filterable by kind, library, and severity.
long: |
Runs the same pipeline as `sheaf scan` and prints the resulting
Finding list, filtered client-side. Output as text, json, or csv.
usage: sheaf gaps [--config path] [--repo path] [--kind k] [--library prefix] [--severity sev] [--format fmt]
pname: sheaf
plink: sheaf.yaml
options:
- option: config
value_type: string
default_value: ""
**Gaps.** `sheaf gaps` lists findings. Narrow them with `sheaf gaps --severity` (minimum `INFO`/`WARNING`/`ERROR`), `sheaf gaps --kind` (a specific finding kind), and `sheaf gaps --library` (one library or element-ID prefix). `sheaf gaps --format` emits `text`, `json`, or `csv`, and `sheaf gaps --config` selects a non-default config.
func TestGaps_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so every gaps flag is parsed from the
// command line. The runGaps tests pass these positionally, which
// leaves --config / --format / --severity unattributed in the
// self-scan even though they're exercised here end to end.
dir := setupFixture(t)
rc := Gaps([]string{
"--config", dir + "/sheaf.textproto",
"--repo", dir,
"--severity", "WARNING",
"--format", "csv",
"--kind", "THIN_REFERENCE",
"--library", "demo",
})
if rc != 0 {
t.Errorf("Gaps(--config/--repo/--severity/--format/--kind/--library) returned %d; want 0", rc)
}
}
N/A
command: sheaf init short: Scaffold a starter sheaf.textproto + categorization rules. long: | Writes a starter pair of config files (sheaf.textproto and categorization-rules.textproto) into --repo. Refuses to overwrite
**Do not edit a single file in this stage. Do not run `sheaf init`. The point is to understand the repo shape before letting a template push you toward the wrong adapter.**
`sheaf scan`, `sheaf gaps`, `sheaf coverage`, `sheaf report`, `sheaf snapshot`, `sheaf serve`, and `sheaf review` all run the full pipeline (config load → adapter dispatch → indexer → analyzers) before producing their output. `sheaf render` and `sheaf review-html` are pipeline-free — they render from a Snapshot JSON / `delta.json` that an earlier pipeline run already produced — as are `sheaf doctor`, `sheaf version`, and `sheaf init`.
func TestRunInit_MinimalTemplate(t *testing.T) {
dir := t.TempDir()
var out, errOut bytes.Buffer
rc := runInit(&out, &errOut, dir, "minimal")
if rc != 0 {
t.Fatalf("runInit returned %d; stderr=%s", rc, errOut.String())
}
for _, name := range []string{"sheaf.textproto", "categorization-rules.textproto"} {
full := filepath.Join(dir, name)
if _, err := os.Stat(full); err != nil {
t.Errorf("init didn't write %s: %v", full, err)
}
}
if !strings.Contains(out.String(), "Bootstrapped Sheaf config") {
t.Errorf("expected bootstrap line; got %s", out.String())
}
}
func TestRunInit_RefusesOverwrite(t *testing.T) {
dir := t.TempDir()
if err := os.WriteFile(filepath.Join(dir, "sheaf.textproto"), []byte("preexisting"), 0o644); err != nil {
t.Fatalf("seed: %v", err)
}
var out, errOut bytes.Buffer
rc := runInit(&out, &errOut, dir, "minimal")
if rc == 0 {
t.Errorf("expected non-zero exit when sheaf.textproto exists; got 0, stderr=%s", errOut.String())
}
}
func TestRunInit_UnknownTemplate(t *testing.T) {
dir := t.TempDir()
var out, errOut bytes.Buffer
rc := runInit(&out, &errOut, dir, "definitely-not-a-template")
if rc == 0 {
t.Errorf("expected non-zero exit on unknown template; got 0")
}
if !strings.Contains(errOut.String(), "unknown template") {
t.Errorf("expected unknown-template error; got %s", errOut.String())
}
}
N/A
command: sheaf init short: Scaffold a starter sheaf.textproto + categorization rules. long: | Writes a starter pair of config files (sheaf.textproto and categorization-rules.textproto) into --repo. Refuses to overwrite
**Init.** `sheaf init` scaffolds a starter config. `sheaf init --repo` chooses where the files are written.
func TestRunInit_RepoFlag(t *testing.T) {
dir := t.TempDir()
var out, errOut bytes.Buffer
rc := runInit(&out, &errOut, dir, "minimal")
if rc != 0 {
t.Fatalf("init --repo returned %d", rc)
}
for _, name := range []string{"sheaf.textproto", "categorization-rules.textproto"} {
if _, err := os.Stat(filepath.Join(dir, name)); err != nil {
t.Errorf("init didn't write %s", name)
}
}
}
func TestInit_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so --repo and --template are parsed
// from the command line. The runInit tests pass the template
// positionally, which never attributes the --template flag.
dir := t.TempDir()
if rc := Init([]string{"--repo", dir, "--template", "minimal"}); rc != 0 {
t.Fatalf("Init(--repo,--template) returned %d; want 0", rc)
}
if _, err := os.Stat(filepath.Join(dir, "sheaf.textproto")); err != nil {
t.Errorf("init via argv didn't write sheaf.textproto: %v", err)
}
}
N/A
command: sheaf init short: Scaffold a starter sheaf.textproto + categorization rules. long: | Writes a starter pair of config files (sheaf.textproto and categorization-rules.textproto) into --repo. Refuses to overwrite
func TestInit_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so --repo and --template are parsed
// from the command line. The runInit tests pass the template
// positionally, which never attributes the --template flag.
dir := t.TempDir()
if rc := Init([]string{"--repo", dir, "--template", "minimal"}); rc != 0 {
t.Fatalf("Init(--repo,--template) returned %d; want 0", rc)
}
if _, err := os.Stat(filepath.Join(dir, "sheaf.textproto")); err != nil {
t.Errorf("init via argv didn't write sheaf.textproto: %v", err)
}
}
N/A
command: sheaf render short: Render an HTML report from a saved Snapshot JSON (in-process; no server).
- **Wrong ecosystem view at render time.** Doctor doesn't know which `--ecosystem` flag you'll pass to `sheaf render`. Picking the wrong one is silent — the report renders, just with the wrong nouns and tiers (see Stage 6 below).
This is the in-process path — `sheaf snapshot` emits the library's Snapshot JSON and `sheaf render` turns it into a self-contained HTML file, no server. (The older `sheaf serve --port 7700 &` + `scanner --server http://127.0.0.1:7700 …` two-process flow still works and produces the same report, but the snapshot→render path is the lead recommendation.)
func TestRunRender_DerivesCommitFromRepoRoot(t *testing.T) {
snap := snapshotForRender(t)
// The sheaf repo itself is a git working tree; use it as the
// --repo-root so gitShortCommit resolves a real short HEAD.
repoRoot, err := filepath.Abs("../..")
if err != nil {
t.Fatalf("abs repo root: %v", err)
}
want := strings.TrimSpace(gitShortCommit(repoRoot))
if want == "" {
t.Skip("repo root is not a git tree (no HEAD); commit-derivation cannot be exercised")
}
out := filepath.Join(t.TempDir(), "report.html")
html := renderToFile(t, out, []string{
snap, "--library", "fuchsia.io", "--ecosystem", "fidl",
"--repo-root", repoRoot, "-o", out,
})
wantSpan := "sha:" + want
if !strings.Contains(html, wantSpan) {
t.Errorf("rendered report does not carry the derived sha %q; "+
"the regen render_one coverage reports would show no sha", wantSpan)
}
}
func TestRunRender_ExplicitCommitOverridesDerivation(t *testing.T) {
snap := snapshotForRender(t)
repoRoot, err := filepath.Abs("../..")
if err != nil {
t.Fatalf("abs repo root: %v", err)
}
out := filepath.Join(t.TempDir(), "report.html")
const pinned = "zzz9999"
html := renderToFile(t, out, []string{
snap, "--library", "fuchsia.io", "--ecosystem", "fidl",
"--repo-root", repoRoot, "--commit", pinned, "-o", out,
})
if !strings.Contains(html, "sha:"+pinned) {
t.Errorf("explicit --commit %q was not honored in the rendered report", pinned)
}
// The real HEAD must NOT leak in when an explicit commit is given.
if real := strings.TrimSpace(gitShortCommit(repoRoot)); real != "" && real != pinned &&
strings.Contains(html, "sha:"+real) {
t.Errorf("derived sha %q leaked despite explicit --commit %q", real, pinned)
}
}
func TestRunRender_NonGitRepoRootLeavesCommitEmpty(t *testing.T) {
snap := snapshotForRender(t)
// A plain temp dir is not a git tree, so gitShortCommit returns ""
// and the report must render with no sha (deterministic).
nonGit := t.TempDir()
out := filepath.Join(t.TempDir(), "report.html")
html := renderToFile(t, out, []string{
snap, "--library", "fuchsia.io", "--ecosystem", "fidl",
"--repo-root", nonGit, "-o", out,
})
if strings.Contains(html, "sha:") {
t.Errorf("non-git --repo-root produced a sha; render must stay empty/deterministic")
}
}
N/A
command: sheaf render short: Render an HTML report from a saved Snapshot JSON (in-process; no server).
**Render.** `sheaf render` turns a saved snapshot into the HTML report in-process — no server. `sheaf render --from-snapshot` names the snapshot and `sheaf render --library` overrides its label; `sheaf render --ecosystem` picks the rendering shape and `sheaf render --api-level` the target level for removed-element detection. `sheaf render --output` (alias `-o`) is the destination and `sheaf render --quiet` drops progress chatter. `sheaf render --repo-root` points at the git working tree — it enables the Lag section and the `{abs_path}` links that `sheaf render --source-url-template` can em…
N/A
N/A
command: sheaf render short: Render an HTML report from a saved Snapshot JSON (in-process; no server).
**Render.** `sheaf render` turns a saved snapshot into the HTML report in-process — no server. `sheaf render --from-snapshot` names the snapshot and `sheaf render --library` overrides its label; `sheaf render --ecosystem` picks the rendering shape and `sheaf render --api-level` the target level for removed-element detection. `sheaf render --output` (alias `-o`) is the destination and `sheaf render --quiet` drops progress chatter. `sheaf render --repo-root` points at the git working tree — it enables the Lag section and the `{abs_path}` links that `sheaf render --source-url-template` can em…
func TestRunRender_ExplicitCommitOverridesDerivation(t *testing.T) {
snap := snapshotForRender(t)
repoRoot, err := filepath.Abs("../..")
if err != nil {
t.Fatalf("abs repo root: %v", err)
}
out := filepath.Join(t.TempDir(), "report.html")
const pinned = "zzz9999"
html := renderToFile(t, out, []string{
snap, "--library", "fuchsia.io", "--ecosystem", "fidl",
"--repo-root", repoRoot, "--commit", pinned, "-o", out,
})
if !strings.Contains(html, "sha:"+pinned) {
t.Errorf("explicit --commit %q was not honored in the rendered report", pinned)
}
// The real HEAD must NOT leak in when an explicit commit is given.
if real := strings.TrimSpace(gitShortCommit(repoRoot)); real != "" && real != pinned &&
strings.Contains(html, "sha:"+real) {
t.Errorf("derived sha %q leaked despite explicit --commit %q", real, pinned)
}
}
N/A
command: sheaf render short: Render an HTML report from a saved Snapshot JSON (in-process; no server).
**Render.** `sheaf render` turns a saved snapshot into the HTML report in-process — no server. `sheaf render --from-snapshot` names the snapshot and `sheaf render --library` overrides its label; `sheaf render --ecosystem` picks the rendering shape and `sheaf render --api-level` the target level for removed-element detection. `sheaf render --output` (alias `-o`) is the destination and `sheaf render --quiet` drops progress chatter. `sheaf render --repo-root` points at the git working tree — it enables the Lag section and the `{abs_path}` links that `sheaf render --source-url-template` can em…
N/A
N/A
command: sheaf render short: Render an HTML report from a saved Snapshot JSON (in-process; no server).
**Render.** `sheaf render` turns a saved snapshot into the HTML report in-process — no server. `sheaf render --from-snapshot` names the snapshot and `sheaf render --library` overrides its label; `sheaf render --ecosystem` picks the rendering shape and `sheaf render --api-level` the target level for removed-element detection. `sheaf render --output` (alias `-o`) is the destination and `sheaf render --quiet` drops progress chatter. `sheaf render --repo-root` points at the git working tree — it enables the Lag section and the `{abs_path}` links that `sheaf render --source-url-template` can em…
func TestRunRender_DerivesCommitFromRepoRoot(t *testing.T) {
snap := snapshotForRender(t)
// The sheaf repo itself is a git working tree; use it as the
// --repo-root so gitShortCommit resolves a real short HEAD.
repoRoot, err := filepath.Abs("../..")
if err != nil {
t.Fatalf("abs repo root: %v", err)
}
want := strings.TrimSpace(gitShortCommit(repoRoot))
if want == "" {
t.Skip("repo root is not a git tree (no HEAD); commit-derivation cannot be exercised")
}
out := filepath.Join(t.TempDir(), "report.html")
html := renderToFile(t, out, []string{
snap, "--library", "fuchsia.io", "--ecosystem", "fidl",
"--repo-root", repoRoot, "-o", out,
})
wantSpan := "sha:" + want
if !strings.Contains(html, wantSpan) {
t.Errorf("rendered report does not carry the derived sha %q; "+
"the regen render_one coverage reports would show no sha", wantSpan)
}
}
func TestRunRender_ExplicitCommitOverridesDerivation(t *testing.T) {
snap := snapshotForRender(t)
repoRoot, err := filepath.Abs("../..")
if err != nil {
t.Fatalf("abs repo root: %v", err)
}
out := filepath.Join(t.TempDir(), "report.html")
const pinned = "zzz9999"
html := renderToFile(t, out, []string{
snap, "--library", "fuchsia.io", "--ecosystem", "fidl",
"--repo-root", repoRoot, "--commit", pinned, "-o", out,
})
if !strings.Contains(html, "sha:"+pinned) {
t.Errorf("explicit --commit %q was not honored in the rendered report", pinned)
}
// The real HEAD must NOT leak in when an explicit commit is given.
if real := strings.TrimSpace(gitShortCommit(repoRoot)); real != "" && real != pinned &&
strings.Contains(html, "sha:"+real) {
t.Errorf("derived sha %q leaked despite explicit --commit %q", real, pinned)
}
}
func TestRunRender_NonGitRepoRootLeavesCommitEmpty(t *testing.T) {
snap := snapshotForRender(t)
// A plain temp dir is not a git tree, so gitShortCommit returns ""
// and the report must render with no sha (deterministic).
nonGit := t.TempDir()
out := filepath.Join(t.TempDir(), "report.html")
html := renderToFile(t, out, []string{
snap, "--library", "fuchsia.io", "--ecosystem", "fidl",
"--repo-root", nonGit, "-o", out,
})
if strings.Contains(html, "sha:") {
t.Errorf("non-git --repo-root produced a sha; render must stay empty/deterministic")
}
}
N/A
command: sheaf render short: Render an HTML report from a saved Snapshot JSON (in-process; no server).
**Render.** `sheaf render` turns a saved snapshot into the HTML report in-process — no server. `sheaf render --from-snapshot` names the snapshot and `sheaf render --library` overrides its label; `sheaf render --ecosystem` picks the rendering shape and `sheaf render --api-level` the target level for removed-element detection. `sheaf render --output` (alias `-o`) is the destination and `sheaf render --quiet` drops progress chatter. `sheaf render --repo-root` points at the git working tree — it enables the Lag section and the `{abs_path}` links that `sheaf render --source-url-template` can em…
Saved snapshots let you re-render without restanding the server. The preferred path is fully in-process — no `sheaf serve`, no `scanner` — using `sheaf snapshot` to persist the Snapshot JSON and `sheaf render --from-snapshot` to render it:
N/A
N/A
command: sheaf render short: Render an HTML report from a saved Snapshot JSON (in-process; no server).
**Render.** `sheaf render` turns a saved snapshot into the HTML report in-process — no server. `sheaf render --from-snapshot` names the snapshot and `sheaf render --library` overrides its label; `sheaf render --ecosystem` picks the rendering shape and `sheaf render --api-level` the target level for removed-element detection. `sheaf render --output` (alias `-o`) is the destination and `sheaf render --quiet` drops progress chatter. `sheaf render --repo-root` points at the git working tree — it enables the Lag section and the `{abs_path}` links that `sheaf render --source-url-template` can em…
N/A
N/A
command: sheaf render short: Render an HTML report from a saved Snapshot JSON (in-process; no server).
**Render.** `sheaf render` turns a saved snapshot into the HTML report in-process — no server. `sheaf render --from-snapshot` names the snapshot and `sheaf render --library` overrides its label; `sheaf render --ecosystem` picks the rendering shape and `sheaf render --api-level` the target level for removed-element detection. `sheaf render --output` (alias `-o`) is the destination and `sheaf render --quiet` drops progress chatter. `sheaf render --repo-root` points at the git working tree — it enables the Lag section and the `{abs_path}` links that `sheaf render --source-url-template` can em…
func TestRunRender_DerivesCommitFromRepoRoot(t *testing.T) {
snap := snapshotForRender(t)
// The sheaf repo itself is a git working tree; use it as the
// --repo-root so gitShortCommit resolves a real short HEAD.
repoRoot, err := filepath.Abs("../..")
if err != nil {
t.Fatalf("abs repo root: %v", err)
}
want := strings.TrimSpace(gitShortCommit(repoRoot))
if want == "" {
t.Skip("repo root is not a git tree (no HEAD); commit-derivation cannot be exercised")
}
out := filepath.Join(t.TempDir(), "report.html")
html := renderToFile(t, out, []string{
snap, "--library", "fuchsia.io", "--ecosystem", "fidl",
"--repo-root", repoRoot, "-o", out,
})
wantSpan := "sha:" + want
if !strings.Contains(html, wantSpan) {
t.Errorf("rendered report does not carry the derived sha %q; "+
"the regen render_one coverage reports would show no sha", wantSpan)
}
}
func TestRunRender_ExplicitCommitOverridesDerivation(t *testing.T) {
snap := snapshotForRender(t)
repoRoot, err := filepath.Abs("../..")
if err != nil {
t.Fatalf("abs repo root: %v", err)
}
out := filepath.Join(t.TempDir(), "report.html")
const pinned = "zzz9999"
html := renderToFile(t, out, []string{
snap, "--library", "fuchsia.io", "--ecosystem", "fidl",
"--repo-root", repoRoot, "--commit", pinned, "-o", out,
})
if !strings.Contains(html, "sha:"+pinned) {
t.Errorf("explicit --commit %q was not honored in the rendered report", pinned)
}
// The real HEAD must NOT leak in when an explicit commit is given.
if real := strings.TrimSpace(gitShortCommit(repoRoot)); real != "" && real != pinned &&
strings.Contains(html, "sha:"+real) {
t.Errorf("derived sha %q leaked despite explicit --commit %q", real, pinned)
}
}
func TestRunRender_NonGitRepoRootLeavesCommitEmpty(t *testing.T) {
snap := snapshotForRender(t)
// A plain temp dir is not a git tree, so gitShortCommit returns ""
// and the report must render with no sha (deterministic).
nonGit := t.TempDir()
out := filepath.Join(t.TempDir(), "report.html")
html := renderToFile(t, out, []string{
snap, "--library", "fuchsia.io", "--ecosystem", "fidl",
"--repo-root", nonGit, "-o", out,
})
if strings.Contains(html, "sha:") {
t.Errorf("non-git --repo-root produced a sha; render must stay empty/deterministic")
}
}
N/A
command: sheaf render short: Render an HTML report from a saved Snapshot JSON (in-process; no server).
**Render.** `sheaf render` turns a saved snapshot into the HTML report in-process — no server. `sheaf render --from-snapshot` names the snapshot and `sheaf render --library` overrides its label; `sheaf render --ecosystem` picks the rendering shape and `sheaf render --api-level` the target level for removed-element detection. `sheaf render --output` (alias `-o`) is the destination and `sheaf render --quiet` drops progress chatter. `sheaf render --repo-root` points at the git working tree — it enables the Lag section and the `{abs_path}` links that `sheaf render --source-url-template` can em…
N/A
N/A
N/A
command: sheaf render short: Render an HTML report from a saved Snapshot JSON (in-process; no server).
**Render.** `sheaf render` turns a saved snapshot into the HTML report in-process — no server. `sheaf render --from-snapshot` names the snapshot and `sheaf render --library` overrides its label; `sheaf render --ecosystem` picks the rendering shape and `sheaf render --api-level` the target level for removed-element detection. `sheaf render --output` (alias `-o`) is the destination and `sheaf render --quiet` drops progress chatter. `sheaf render --repo-root` points at the git working tree — it enables the Lag section and the `{abs_path}` links that `sheaf render --source-url-template` can em…
N/A
N/A
N/A
command: sheaf render short: Render an HTML report from a saved Snapshot JSON (in-process; no server).
**Render.** `sheaf render` turns a saved snapshot into the HTML report in-process — no server. `sheaf render --from-snapshot` names the snapshot and `sheaf render --library` overrides its label; `sheaf render --ecosystem` picks the rendering shape and `sheaf render --api-level` the target level for removed-element detection. `sheaf render --output` (alias `-o`) is the destination and `sheaf render --quiet` drops progress chatter. `sheaf render --repo-root` points at the git working tree — it enables the Lag section and the `{abs_path}` links that `sheaf render --source-url-template` can em…
N/A
N/A
command: sheaf render short: Render an HTML report from a saved Snapshot JSON (in-process; no server).
**Render.** `sheaf render` turns a saved snapshot into the HTML report in-process — no server. `sheaf render --from-snapshot` names the snapshot and `sheaf render --library` overrides its label; `sheaf render --ecosystem` picks the rendering shape and `sheaf render --api-level` the target level for removed-element detection. `sheaf render --output` (alias `-o`) is the destination and `sheaf render --quiet` drops progress chatter. `sheaf render --repo-root` points at the git working tree — it enables the Lag section and the `{abs_path}` links that `sheaf render --source-url-template` can em…
func TestRunRender_DerivesCommitFromRepoRoot(t *testing.T) {
snap := snapshotForRender(t)
// The sheaf repo itself is a git working tree; use it as the
// --repo-root so gitShortCommit resolves a real short HEAD.
repoRoot, err := filepath.Abs("../..")
if err != nil {
t.Fatalf("abs repo root: %v", err)
}
want := strings.TrimSpace(gitShortCommit(repoRoot))
if want == "" {
t.Skip("repo root is not a git tree (no HEAD); commit-derivation cannot be exercised")
}
out := filepath.Join(t.TempDir(), "report.html")
html := renderToFile(t, out, []string{
snap, "--library", "fuchsia.io", "--ecosystem", "fidl",
"--repo-root", repoRoot, "-o", out,
})
wantSpan := "sha:" + want
if !strings.Contains(html, wantSpan) {
t.Errorf("rendered report does not carry the derived sha %q; "+
"the regen render_one coverage reports would show no sha", wantSpan)
}
}
func TestRunRender_ExplicitCommitOverridesDerivation(t *testing.T) {
snap := snapshotForRender(t)
repoRoot, err := filepath.Abs("../..")
if err != nil {
t.Fatalf("abs repo root: %v", err)
}
out := filepath.Join(t.TempDir(), "report.html")
const pinned = "zzz9999"
html := renderToFile(t, out, []string{
snap, "--library", "fuchsia.io", "--ecosystem", "fidl",
"--repo-root", repoRoot, "--commit", pinned, "-o", out,
})
if !strings.Contains(html, "sha:"+pinned) {
t.Errorf("explicit --commit %q was not honored in the rendered report", pinned)
}
// The real HEAD must NOT leak in when an explicit commit is given.
if real := strings.TrimSpace(gitShortCommit(repoRoot)); real != "" && real != pinned &&
strings.Contains(html, "sha:"+real) {
t.Errorf("derived sha %q leaked despite explicit --commit %q", real, pinned)
}
}
func TestRunRender_NonGitRepoRootLeavesCommitEmpty(t *testing.T) {
snap := snapshotForRender(t)
// A plain temp dir is not a git tree, so gitShortCommit returns ""
// and the report must render with no sha (deterministic).
nonGit := t.TempDir()
out := filepath.Join(t.TempDir(), "report.html")
html := renderToFile(t, out, []string{
snap, "--library", "fuchsia.io", "--ecosystem", "fidl",
"--repo-root", nonGit, "-o", out,
})
if strings.Contains(html, "sha:") {
t.Errorf("non-git --repo-root produced a sha; render must stay empty/deterministic")
}
}
N/A
command: sheaf render short: Render an HTML report from a saved Snapshot JSON (in-process; no server).
**Render.** `sheaf render` turns a saved snapshot into the HTML report in-process — no server. `sheaf render --from-snapshot` names the snapshot and `sheaf render --library` overrides its label; `sheaf render --ecosystem` picks the rendering shape and `sheaf render --api-level` the target level for removed-element detection. `sheaf render --output` (alias `-o`) is the destination and `sheaf render --quiet` drops progress chatter. `sheaf render --repo-root` points at the git working tree — it enables the Lag section and the `{abs_path}` links that `sheaf render --source-url-template` can em…
N/A
N/A
command: sheaf report
short: Bulk dump all coverage profiles as CSV, JSON, or HTML.
long: |
Runs the full pipeline and emits every CoverageProfile in the corpus.
CSV and JSON go to stdout; HTML is written as a multi-page browser
into --output.
usage: sheaf report [--config path] [--repo path] [--format csv|json|html] [--output dir]
pname: sheaf
plink: sheaf.yaml
options:
- option: config
value_type: string
`sheaf scan`, `sheaf gaps`, `sheaf coverage`, `sheaf report`, `sheaf snapshot`, `sheaf serve`, and `sheaf review` all run the full pipeline (config load → adapter dispatch → indexer → analyzers) before producing their output. `sheaf render` and `sheaf review-html` are pipeline-free — they render from a Snapshot JSON / `delta.json` that an earlier pipeline run already produced — as are `sheaf doctor`, `sheaf version`, and `sheaf init`.
**Report.** `sheaf report` bulk-dumps every coverage profile. `sheaf report --format` chooses `csv`, `json`, or `html`; when it is `html`, `sheaf report --output` names the directory the multi-page report is written to. `sheaf report --config` and `sheaf report --repo` locate the project.
func TestRunReport_CSVFormat(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runReport(&out, &errOut, "", dir, "csv", "")
if rc != 0 {
t.Fatalf("runReport returned %d; stderr=%s", rc, errOut.String())
}
if !strings.HasPrefix(out.String(), "element_id,tests,docs,examples,missing") {
t.Errorf("expected CSV header at start; got %q", firstLine(out.String()))
}
}
func TestRunReport_HTMLRequiresOutput(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runReport(&out, &errOut, "", dir, "html", "")
if rc != 2 {
t.Errorf("expected rc=2 when --format html lacks --output; got %d", rc)
}
}
func TestRunReport_HTMLWritesIndex(t *testing.T) {
dir := setupFixture(t)
outDir := filepath.Join(t.TempDir(), "report")
var out, errOut bytes.Buffer
rc := runReport(&out, &errOut, "", dir, "html", outDir)
if rc != 0 {
t.Fatalf("runReport(html) returned %d; stderr=%s", rc, errOut.String())
}
if !strings.Contains(out.String(), "HTML report written") {
t.Errorf("expected success line; got %q", out.String())
}
}
N/A
command: sheaf report
short: Bulk dump all coverage profiles as CSV, JSON, or HTML.
long: |
Runs the full pipeline and emits every CoverageProfile in the corpus.
CSV and JSON go to stdout; HTML is written as a multi-page browser
into --output.
usage: sheaf report [--config path] [--repo path] [--format csv|json|html] [--output dir]
pname: sheaf
plink: sheaf.yaml
options:
- option: config
value_type: string
**Report.** `sheaf report` bulk-dumps every coverage profile. `sheaf report --format` chooses `csv`, `json`, or `html`; when it is `html`, `sheaf report --output` names the directory the multi-page report is written to. `sheaf report --config` and `sheaf report --repo` locate the project.
func TestRunReport_RepoConfigFlags(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runReport(&out, &errOut, dir+"/sheaf.textproto", dir, "csv", "")
if rc != 0 {
t.Fatalf("runReport(--config,--repo) returned %d", rc)
}
}
N/A
command: sheaf report
short: Bulk dump all coverage profiles as CSV, JSON, or HTML.
long: |
Runs the full pipeline and emits every CoverageProfile in the corpus.
CSV and JSON go to stdout; HTML is written as a multi-page browser
into --output.
usage: sheaf report [--config path] [--repo path] [--format csv|json|html] [--output dir]
pname: sheaf
plink: sheaf.yaml
options:
- option: config
value_type: string
**Report.** `sheaf report` bulk-dumps every coverage profile. `sheaf report --format` chooses `csv`, `json`, or `html`; when it is `html`, `sheaf report --output` names the directory the multi-page report is written to. `sheaf report --config` and `sheaf report --repo` locate the project.
func TestRunReport_HTMLRequiresOutput(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runReport(&out, &errOut, "", dir, "html", "")
if rc != 2 {
t.Errorf("expected rc=2 when --format html lacks --output; got %d", rc)
}
}
N/A
command: sheaf report
short: Bulk dump all coverage profiles as CSV, JSON, or HTML.
long: |
Runs the full pipeline and emits every CoverageProfile in the corpus.
CSV and JSON go to stdout; HTML is written as a multi-page browser
into --output.
usage: sheaf report [--config path] [--repo path] [--format csv|json|html] [--output dir]
pname: sheaf
plink: sheaf.yaml
options:
- option: config
value_type: string
**Report.** `sheaf report` bulk-dumps every coverage profile. `sheaf report --format` chooses `csv`, `json`, or `html`; when it is `html`, `sheaf report --output` names the directory the multi-page report is written to. `sheaf report --config` and `sheaf report --repo` locate the project.
func TestRunReport_HTMLRequiresOutput(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runReport(&out, &errOut, "", dir, "html", "")
if rc != 2 {
t.Errorf("expected rc=2 when --format html lacks --output; got %d", rc)
}
}
N/A
command: sheaf report
short: Bulk dump all coverage profiles as CSV, JSON, or HTML.
long: |
Runs the full pipeline and emits every CoverageProfile in the corpus.
CSV and JSON go to stdout; HTML is written as a multi-page browser
into --output.
usage: sheaf report [--config path] [--repo path] [--format csv|json|html] [--output dir]
pname: sheaf
plink: sheaf.yaml
options:
- option: config
value_type: string
**Report.** `sheaf report` bulk-dumps every coverage profile. `sheaf report --format` chooses `csv`, `json`, or `html`; when it is `html`, `sheaf report --output` names the directory the multi-page report is written to. `sheaf report --config` and `sheaf report --repo` locate the project.
func TestRunReport_RepoConfigFlags(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runReport(&out, &errOut, dir+"/sheaf.textproto", dir, "csv", "")
if rc != 0 {
t.Fatalf("runReport(--config,--repo) returned %d", rc)
}
}
N/A
command: sheaf review short: Render a PR review comment from base + head corpora. long: | Scans two checkouts of the same project (--base = PR target, --repo = PR head) using the same sheaf.textproto, builds a delta, and
`sheaf scan`, `sheaf gaps`, `sheaf coverage`, `sheaf report`, `sheaf snapshot`, `sheaf serve`, and `sheaf review` all run the full pipeline (config load → adapter dispatch → indexer → analyzers) before producing their output. `sheaf render` and `sheaf review-html` are pipeline-free — they render from a Snapshot JSON / `delta.json` that an earlier pipeline run already produced — as are `sheaf doctor`, `sheaf version`, and `sheaf init`.
**Review.** `sheaf review` renders a PR-coverage-delta comment. It needs a base tree via `sheaf review --base`; `sheaf review --repo` is the PR head and `sheaf review --pr` is the reference printed in the comment header. `sheaf review --review` overrides the configured review adapter (`noop`/`file`/`gerrit`/`github`), `sheaf review --file-out` is where the `file` adapter writes, and `sheaf review --post` actually posts the comment instead of printing it. `sheaf review --config` selects the config used for both base and head.
func TestReview_RequiresBase(t *testing.T) {
// The public entry refuses to run without --base; we exercise it
// through Review() so the flag-required branch is covered.
if rc := Review([]string{"--repo", "."}); rc != 2 {
t.Errorf("expected rc=2 when --base missing; got %d", rc)
}
}
func TestRunReview_MissingConfig(t *testing.T) {
headDir := t.TempDir()
baseDir := t.TempDir()
var out, errOut bytes.Buffer
rc := runReview(&out, &errOut, "", headDir, baseDir, "PR#1", false, "", "", "", "", "", "", "")
if rc == 0 {
t.Errorf("expected non-zero exit on missing config; out=%s err=%s", out.String(), errOut.String())
}
}
func TestBuildReviewAdapter_NoopOverride(t *testing.T) {
cfg := &configpb.Config{}
a, err := buildReviewAdapter(cfg, "noop", "")
if err != nil {
t.Fatalf("buildReviewAdapter: %v", err)
}
if a == nil || a.Name() != "noop" {
t.Errorf("expected noop adapter; got %#v", a)
}
}
N/A
command: sheaf review short: Render a PR review comment from base + head corpora. long: | Scans two checkouts of the same project (--base = PR target, --repo = PR head) using the same sheaf.textproto, builds a delta, and
**Review.** `sheaf review` renders a PR-coverage-delta comment. It needs a base tree via `sheaf review --base`; `sheaf review --repo` is the PR head and `sheaf review --pr` is the reference printed in the comment header. `sheaf review --review` overrides the configured review adapter (`noop`/`file`/`gerrit`/`github`), `sheaf review --file-out` is where the `file` adapter writes, and `sheaf review --post` actually posts the comment instead of printing it. `sheaf review --config` selects the config used for both base and head.
func TestReview_RequiresBase(t *testing.T) {
// The public entry refuses to run without --base; we exercise it
// through Review() so the flag-required branch is covered.
if rc := Review([]string{"--repo", "."}); rc != 2 {
t.Errorf("expected rc=2 when --base missing; got %d", rc)
}
}
func TestReview_FileOutRepoBaseFlags(t *testing.T) {
// --base + --repo + --review file + --file-out: confirm the flag
// wiring parses, even though the pipeline fails on missing config.
headDir := t.TempDir()
baseDir := t.TempDir()
fileOut := filepath.Join(t.TempDir(), "out.md")
rc := Review([]string{
"--base", baseDir,
"--repo", headDir,
"--review", "file",
"--file-out", fileOut,
"--pr", "PR#unit",
})
// rc != 2 (would be parse error); 3 expected because config
// loading fails on the empty repo. We just need flag parsing
// to land.
if rc == 2 {
t.Errorf("flag parse failed for review --base/--repo/--review/--file-out; rc=2")
}
}
func TestReview_ConfigPostFlags(t *testing.T) {
// Drive --config + --post through the public argv entry alongside a
// noop review adapter. Config loading fails on the empty repo (rc=3),
// so the run never reaches the post step — but the flags parse, which
// attributes --config and --post without any external side effect.
headDir := t.TempDir()
baseDir := t.TempDir()
rc := Review([]string{
"--base", baseDir,
"--repo", headDir,
"--config", headDir + "/sheaf.textproto",
"--review", "noop",
"--post",
})
// rc == 2 would be a flag-parse error; we expect the later config-load
// failure (rc=3) instead, proving the flags landed.
if rc == 2 {
t.Errorf("flag parse failed for review --config/--post; rc=2")
}
}
N/A
command: sheaf review short: Render a PR review comment from base + head corpora. long: | Scans two checkouts of the same project (--base = PR target, --repo = PR head) using the same sheaf.textproto, builds a delta, and
**Review.** `sheaf review` renders a PR-coverage-delta comment. It needs a base tree via `sheaf review --base`; `sheaf review --repo` is the PR head and `sheaf review --pr` is the reference printed in the comment header. `sheaf review --review` overrides the configured review adapter (`noop`/`file`/`gerrit`/`github`), `sheaf review --file-out` is where the `file` adapter writes, and `sheaf review --post` actually posts the comment instead of printing it. `sheaf review --config` selects the config used for both base and head.
func TestReview_ConfigPostFlags(t *testing.T) {
// Drive --config + --post through the public argv entry alongside a
// noop review adapter. Config loading fails on the empty repo (rc=3),
// so the run never reaches the post step — but the flags parse, which
// attributes --config and --post without any external side effect.
headDir := t.TempDir()
baseDir := t.TempDir()
rc := Review([]string{
"--base", baseDir,
"--repo", headDir,
"--config", headDir + "/sheaf.textproto",
"--review", "noop",
"--post",
})
// rc == 2 would be a flag-parse error; we expect the later config-load
// failure (rc=3) instead, proving the flags landed.
if rc == 2 {
t.Errorf("flag parse failed for review --config/--post; rc=2")
}
}
N/A
command: sheaf review short: Render a PR review comment from base + head corpora. long: | Scans two checkouts of the same project (--base = PR target, --repo = PR head) using the same sheaf.textproto, builds a delta, and
**Review.** `sheaf review` renders a PR-coverage-delta comment. It needs a base tree via `sheaf review --base`; `sheaf review --repo` is the PR head and `sheaf review --pr` is the reference printed in the comment header. `sheaf review --review` overrides the configured review adapter (`noop`/`file`/`gerrit`/`github`), `sheaf review --file-out` is where the `file` adapter writes, and `sheaf review --post` actually posts the comment instead of printing it. `sheaf review --config` selects the config used for both base and head.
func TestReview_FileOutRepoBaseFlags(t *testing.T) {
// --base + --repo + --review file + --file-out: confirm the flag
// wiring parses, even though the pipeline fails on missing config.
headDir := t.TempDir()
baseDir := t.TempDir()
fileOut := filepath.Join(t.TempDir(), "out.md")
rc := Review([]string{
"--base", baseDir,
"--repo", headDir,
"--review", "file",
"--file-out", fileOut,
"--pr", "PR#unit",
})
// rc != 2 (would be parse error); 3 expected because config
// loading fails on the empty repo. We just need flag parsing
// to land.
if rc == 2 {
t.Errorf("flag parse failed for review --base/--repo/--review/--file-out; rc=2")
}
}
N/A
command: sheaf review short: Render a PR review comment from base + head corpora. long: | Scans two checkouts of the same project (--base = PR target, --repo = PR head) using the same sheaf.textproto, builds a delta, and
**Review.** `sheaf review` renders a PR-coverage-delta comment. It needs a base tree via `sheaf review --base`; `sheaf review --repo` is the PR head and `sheaf review --pr` is the reference printed in the comment header. `sheaf review --review` overrides the configured review adapter (`noop`/`file`/`gerrit`/`github`), `sheaf review --file-out` is where the `file` adapter writes, and `sheaf review --post` actually posts the comment instead of printing it. `sheaf review --config` selects the config used for both base and head.
func TestReview_ConfigPostFlags(t *testing.T) {
// Drive --config + --post through the public argv entry alongside a
// noop review adapter. Config loading fails on the empty repo (rc=3),
// so the run never reaches the post step — but the flags parse, which
// attributes --config and --post without any external side effect.
headDir := t.TempDir()
baseDir := t.TempDir()
rc := Review([]string{
"--base", baseDir,
"--repo", headDir,
"--config", headDir + "/sheaf.textproto",
"--review", "noop",
"--post",
})
// rc == 2 would be a flag-parse error; we expect the later config-load
// failure (rc=3) instead, proving the flags landed.
if rc == 2 {
t.Errorf("flag parse failed for review --config/--post; rc=2")
}
}
N/A
command: sheaf review short: Render a PR review comment from base + head corpora. long: | Scans two checkouts of the same project (--base = PR target, --repo = PR head) using the same sheaf.textproto, builds a delta, and
**Review.** `sheaf review` renders a PR-coverage-delta comment. It needs a base tree via `sheaf review --base`; `sheaf review --repo` is the PR head and `sheaf review --pr` is the reference printed in the comment header. `sheaf review --review` overrides the configured review adapter (`noop`/`file`/`gerrit`/`github`), `sheaf review --file-out` is where the `file` adapter writes, and `sheaf review --post` actually posts the comment instead of printing it. `sheaf review --config` selects the config used for both base and head.
func TestReview_FileOutRepoBaseFlags(t *testing.T) {
// --base + --repo + --review file + --file-out: confirm the flag
// wiring parses, even though the pipeline fails on missing config.
headDir := t.TempDir()
baseDir := t.TempDir()
fileOut := filepath.Join(t.TempDir(), "out.md")
rc := Review([]string{
"--base", baseDir,
"--repo", headDir,
"--review", "file",
"--file-out", fileOut,
"--pr", "PR#unit",
})
// rc != 2 (would be parse error); 3 expected because config
// loading fails on the empty repo. We just need flag parsing
// to land.
if rc == 2 {
t.Errorf("flag parse failed for review --base/--repo/--review/--file-out; rc=2")
}
}
N/A
command: sheaf review short: Render a PR review comment from base + head corpora. long: | Scans two checkouts of the same project (--base = PR target, --repo = PR head) using the same sheaf.textproto, builds a delta, and
**Review.** `sheaf review` renders a PR-coverage-delta comment. It needs a base tree via `sheaf review --base`; `sheaf review --repo` is the PR head and `sheaf review --pr` is the reference printed in the comment header. `sheaf review --review` overrides the configured review adapter (`noop`/`file`/`gerrit`/`github`), `sheaf review --file-out` is where the `file` adapter writes, and `sheaf review --post` actually posts the comment instead of printing it. `sheaf review --config` selects the config used for both base and head.
func TestReview_RequiresBase(t *testing.T) {
// The public entry refuses to run without --base; we exercise it
// through Review() so the flag-required branch is covered.
if rc := Review([]string{"--repo", "."}); rc != 2 {
t.Errorf("expected rc=2 when --base missing; got %d", rc)
}
}
func TestReview_FileOutRepoBaseFlags(t *testing.T) {
// --base + --repo + --review file + --file-out: confirm the flag
// wiring parses, even though the pipeline fails on missing config.
headDir := t.TempDir()
baseDir := t.TempDir()
fileOut := filepath.Join(t.TempDir(), "out.md")
rc := Review([]string{
"--base", baseDir,
"--repo", headDir,
"--review", "file",
"--file-out", fileOut,
"--pr", "PR#unit",
})
// rc != 2 (would be parse error); 3 expected because config
// loading fails on the empty repo. We just need flag parsing
// to land.
if rc == 2 {
t.Errorf("flag parse failed for review --base/--repo/--review/--file-out; rc=2")
}
}
func TestReview_ConfigPostFlags(t *testing.T) {
// Drive --config + --post through the public argv entry alongside a
// noop review adapter. Config loading fails on the empty repo (rc=3),
// so the run never reaches the post step — but the flags parse, which
// attributes --config and --post without any external side effect.
headDir := t.TempDir()
baseDir := t.TempDir()
rc := Review([]string{
"--base", baseDir,
"--repo", headDir,
"--config", headDir + "/sheaf.textproto",
"--review", "noop",
"--post",
})
// rc == 2 would be a flag-parse error; we expect the later config-load
// failure (rc=3) instead, proving the flags landed.
if rc == 2 {
t.Errorf("flag parse failed for review --config/--post; rc=2")
}
}
N/A
command: sheaf review short: Render a PR review comment from base + head corpora. long: | Scans two checkouts of the same project (--base = PR target, --repo = PR head) using the same sheaf.textproto, builds a delta, and
**Review.** `sheaf review` renders a PR-coverage-delta comment. It needs a base tree via `sheaf review --base`; `sheaf review --repo` is the PR head and `sheaf review --pr` is the reference printed in the comment header. `sheaf review --review` overrides the configured review adapter (`noop`/`file`/`gerrit`/`github`), `sheaf review --file-out` is where the `file` adapter writes, and `sheaf review --post` actually posts the comment instead of printing it. `sheaf review --config` selects the config used for both base and head.
func TestReview_FileOutRepoBaseFlags(t *testing.T) {
// --base + --repo + --review file + --file-out: confirm the flag
// wiring parses, even though the pipeline fails on missing config.
headDir := t.TempDir()
baseDir := t.TempDir()
fileOut := filepath.Join(t.TempDir(), "out.md")
rc := Review([]string{
"--base", baseDir,
"--repo", headDir,
"--review", "file",
"--file-out", fileOut,
"--pr", "PR#unit",
})
// rc != 2 (would be parse error); 3 expected because config
// loading fails on the empty repo. We just need flag parsing
// to land.
if rc == 2 {
t.Errorf("flag parse failed for review --base/--repo/--review/--file-out; rc=2")
}
}
func TestBuildReviewAdapter_UnknownOverride(t *testing.T) {
cfg := &configpb.Config{}
if _, err := buildReviewAdapter(cfg, "definitely-not-an-adapter", ""); err == nil {
t.Errorf("expected error for unknown --review value")
}
}
func TestReview_ConfigPostFlags(t *testing.T) {
// Drive --config + --post through the public argv entry alongside a
// noop review adapter. Config loading fails on the empty repo (rc=3),
// so the run never reaches the post step — but the flags parse, which
// attributes --config and --post without any external side effect.
headDir := t.TempDir()
baseDir := t.TempDir()
rc := Review([]string{
"--base", baseDir,
"--repo", headDir,
"--config", headDir + "/sheaf.textproto",
"--review", "noop",
"--post",
})
// rc == 2 would be a flag-parse error; we expect the later config-load
// failure (rc=3) instead, proving the flags landed.
if rc == 2 {
t.Errorf("flag parse failed for review --config/--post; rc=2")
}
}
N/A
command: sheaf scan short: Run the scan pipeline against a project and print a summary. long: | Loads sheaf.textproto, dispatches every configured contract-anchor, test-parser, doc-parser, rendered-reference, and implements-map adapter, builds the cross-reference index, runs every enabled analyzer, and prints a per-stage timing summary plus a per-finding-kind histogram. The workhorse subcommand. usage: sheaf scan [--config path] [--repo path] [--quiet] pname: sheaf plink: sheaf.yaml options:
Parse-time and resolve-time errors abort startup with a path-prefixed message (`contract_anchor[1].argh.crate_roots: missing required field`). Probe-time warnings appear in `sheaf doctor` output and at the top of `sheaf scan` runs but do not abort.
**Severity meanings.** `INFO` is reported but never blocks; `WARNING` increments the warning count (`sheaf scan` exit code 1 if any); `ERROR` increments the error count (exit code 2). The PR-bot routes severity into comment-section ordering (errors first).
func TestRunScan_FixtureProject(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runScan(&out, &errOut, "", dir, false)
if rc != 0 {
t.Fatalf("runScan returned %d; stderr=%s", rc, errOut.String())
}
got := out.String()
for _, want := range []string{
"Contract elements: 0",
"Test cases: 1",
"Doc claims:",
"FooTest.BarReturnsTrue",
} {
if !strings.Contains(got, want) {
t.Errorf("output missing %q\n--- got ---\n%s", want, got)
}
}
}
func TestRunScan_MissingConfig(t *testing.T) {
dir := t.TempDir()
var out, errOut bytes.Buffer
rc := runScan(&out, &errOut, "", dir, false)
if rc == 0 {
t.Errorf("expected non-zero exit on missing config; out=%s err=%s", out.String(), errOut.String())
}
}
func TestRunScan_RepoConfigFlags(t *testing.T) {
// Exercise the --repo + --config wiring: a config path provided
// explicitly should be honored even when --repo names a directory
// that itself contains no sheaf.textproto.
dir := setupFixture(t)
otherRepo := t.TempDir()
var out, errOut bytes.Buffer
rc := runScan(&out, &errOut, dir+"/sheaf.textproto", otherRepo, true)
if rc != 0 {
t.Fatalf("runScan(--config) returned %d; stderr=%s", rc, errOut.String())
}
}
N/A
command: sheaf scan short: Run the scan pipeline against a project and print a summary. long: | Loads sheaf.textproto, dispatches every configured contract-anchor, test-parser, doc-parser, rendered-reference, and implements-map adapter, builds the cross-reference index, runs every enabled analyzer, and prints a per-stage timing summary plus a per-finding-kind histogram. The workhorse subcommand. usage: sheaf scan [--config path] [--repo path] [--quiet] pname: sheaf plink: sheaf.yaml options:
**Scan.** A bare `sheaf scan` runs against `<repo>/sheaf.textproto`. Point `sheaf scan --config` at a config that lives elsewhere, set the project root with `sheaf scan --repo`, and pass `sheaf scan --quiet` to drop the per-adapter sample blocks when you only want the corpus summary.
func TestRunScan_RepoConfigFlags(t *testing.T) {
// Exercise the --repo + --config wiring: a config path provided
// explicitly should be honored even when --repo names a directory
// that itself contains no sheaf.textproto.
dir := setupFixture(t)
otherRepo := t.TempDir()
var out, errOut bytes.Buffer
rc := runScan(&out, &errOut, dir+"/sheaf.textproto", otherRepo, true)
if rc != 0 {
t.Fatalf("runScan(--config) returned %d; stderr=%s", rc, errOut.String())
}
}
func TestScan_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so --repo and --config are parsed from
// the command line. The runScan tests name --config in a string only
// incidentally and --repo only in a comment, so --repo never gets
// attributed; this exercises the real flag wiring end to end.
dir := setupFixture(t)
if rc := Scan([]string{"--config", dir + "/sheaf.textproto", "--repo", dir, "--quiet"}); rc != 0 {
t.Errorf("Scan(--config,--repo,--quiet) returned %d; want 0", rc)
}
}
N/A
command: sheaf scan short: Run the scan pipeline against a project and print a summary. long: | Loads sheaf.textproto, dispatches every configured contract-anchor, test-parser, doc-parser, rendered-reference, and implements-map adapter, builds the cross-reference index, runs every enabled analyzer, and prints a per-stage timing summary plus a per-finding-kind histogram. The workhorse subcommand. usage: sheaf scan [--config path] [--repo path] [--quiet] pname: sheaf plink: sheaf.yaml options:
**Scan.** A bare `sheaf scan` runs against `<repo>/sheaf.textproto`. Point `sheaf scan --config` at a config that lives elsewhere, set the project root with `sheaf scan --repo`, and pass `sheaf scan --quiet` to drop the per-adapter sample blocks when you only want the corpus summary.
func TestRunScan_QuietSuppressesSamples(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runScan(&out, &errOut, "", dir, true /* quiet */)
if rc != 0 {
t.Fatalf("runScan returned %d; stderr=%s", rc, errOut.String())
}
if strings.Contains(out.String(), "Sample tests:") || strings.Contains(out.String(), "Sample doc mentions:") {
t.Errorf("--quiet did not suppress sample blocks; got %s", out.String())
}
}
func TestScan_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so --repo and --config are parsed from
// the command line. The runScan tests name --config in a string only
// incidentally and --repo only in a comment, so --repo never gets
// attributed; this exercises the real flag wiring end to end.
dir := setupFixture(t)
if rc := Scan([]string{"--config", dir + "/sheaf.textproto", "--repo", dir, "--quiet"}); rc != 0 {
t.Errorf("Scan(--config,--repo,--quiet) returned %d; want 0", rc)
}
}
N/A
command: sheaf scan short: Run the scan pipeline against a project and print a summary. long: | Loads sheaf.textproto, dispatches every configured contract-anchor, test-parser, doc-parser, rendered-reference, and implements-map adapter, builds the cross-reference index, runs every enabled analyzer, and prints a per-stage timing summary plus a per-finding-kind histogram. The workhorse subcommand. usage: sheaf scan [--config path] [--repo path] [--quiet] pname: sheaf plink: sheaf.yaml options:
**Scan.** A bare `sheaf scan` runs against `<repo>/sheaf.textproto`. Point `sheaf scan --config` at a config that lives elsewhere, set the project root with `sheaf scan --repo`, and pass `sheaf scan --quiet` to drop the per-adapter sample blocks when you only want the corpus summary.
func TestScan_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so --repo and --config are parsed from
// the command line. The runScan tests name --config in a string only
// incidentally and --repo only in a comment, so --repo never gets
// attributed; this exercises the real flag wiring end to end.
dir := setupFixture(t)
if rc := Scan([]string{"--config", dir + "/sheaf.textproto", "--repo", dir, "--quiet"}); rc != 0 {
t.Errorf("Scan(--config,--repo,--quiet) returned %d; want 0", rc)
}
}
N/A
command: sheaf serve short: Start the MCP server. long: | Run the ingest → index pipeline once and then keep the corpus live behind an MCP server. Coding agents and the scanner binary consume the server's contract-element lookup, coverage-profile lookup, worked-example retrieval, library_snapshot, and review_pr ops. usage: sheaf serve [--config path] [--repo path] [--bind host] [--port n] pname: sheaf plink: sheaf.yaml options: - option: config
- [`sheaf serve`](sheaf_serve.md) — the MCP server the scanner connects to. - [`sheaf snapshot`](sheaf_snapshot.md) — the preferred, in-process way to persist a Snapshot JSON (replaces `scanner --snapshot-out`). - [`sheaf render`](sheaf_render.md) — the preferred, in-process way to render a saved Snapshot JSON.
- **C5.** Hot reload on config change during `sheaf serve`: nice to have, v2. - **C6.** mTLS support for the MCP server (currently `BEARER` is the only non-NONE auth). Defer until pulled. - **C7.** `analyzer.config { key, *_value }` free-form fallback: should sustained use of free-form keys for the same analyzer auto-promote into a typed oneof case at code-gen time? Probably overengineering; just promote manually when patterns emerge.
func TestServe_FlagParseFailure(t *testing.T) {
// Bad flag: ContinueOnError + flag.Parse returns 2 from the
// public entry point. Use a value the flag set rejects.
if rc := Serve([]string{"--unknown-flag"}); rc != 2 {
t.Errorf("expected rc=2 on bad flag; got %d", rc)
}
}
func TestServe_BindPortRepoConfigFlags(t *testing.T) {
// Drive the public Serve entry with --bind/--port/--config/--repo
// against a directory that has no sheaf.textproto. The pipeline
// fails early on config load (rc=3); the assertion here is that
// the binding flags parse without error.
dir := t.TempDir()
rc := Serve([]string{"--bind", "127.0.0.1", "--port", "0", "--repo", dir, "--config", dir + "/missing.textproto"})
if rc == 0 {
t.Errorf("expected non-zero exit with missing config; got 0")
}
}
func TestServe_MissingConfig(t *testing.T) {
dir := t.TempDir()
if rc := Serve([]string{"--repo", dir}); rc == 0 {
t.Errorf("expected non-zero exit on missing config")
}
}
N/A
command: sheaf serve short: Start the MCP server. long: | Run the ingest → index pipeline once and then keep the corpus live behind an MCP server. Coding agents and the scanner binary consume the server's contract-element lookup, coverage-profile lookup, worked-example retrieval, library_snapshot, and review_pr ops. usage: sheaf serve [--config path] [--repo path] [--bind host] [--port n] pname: sheaf plink: sheaf.yaml options: - option: config
**Serve.** `sheaf serve` starts the MCP server. `sheaf serve --bind` sets the listen address (default `127.0.0.1`) and `sheaf serve --config` selects the config whose corpus is served.
value, the flag wins. Example: `sheaf serve --bind` / `--port` override `mcp_server.bind` / `mcp_server.port` (`internal/cli/extra.go:491`). - **Credentials are environment-only.** API keys and tokens are never read from the config file. `ANTHROPIC_API_KEY` has no config field at all; the `*_token_env` fields hold the *name* of an env var, not the secret. See §3.6. - **One config-beats-env exception — the LLM model.** The model tag resolves config before env: an explicit `--model` / `llm.model` wins, and `ANTHROPIC_MODEL` is consulted only when neither is set, ahead of the per-backend defau…
func TestServe_BindPortRepoConfigFlags(t *testing.T) {
// Drive the public Serve entry with --bind/--port/--config/--repo
// against a directory that has no sheaf.textproto. The pipeline
// fails early on config load (rc=3); the assertion here is that
// the binding flags parse without error.
dir := t.TempDir()
rc := Serve([]string{"--bind", "127.0.0.1", "--port", "0", "--repo", dir, "--config", dir + "/missing.textproto"})
if rc == 0 {
t.Errorf("expected non-zero exit with missing config; got 0")
}
}
N/A
command: sheaf serve short: Start the MCP server. long: | Run the ingest → index pipeline once and then keep the corpus live behind an MCP server. Coding agents and the scanner binary consume the server's contract-element lookup, coverage-profile lookup, worked-example retrieval, library_snapshot, and review_pr ops. usage: sheaf serve [--config path] [--repo path] [--bind host] [--port n] pname: sheaf plink: sheaf.yaml options: - option: config
**Serve.** `sheaf serve` starts the MCP server. `sheaf serve --bind` sets the listen address (default `127.0.0.1`) and `sheaf serve --config` selects the config whose corpus is served.
func TestServe_BindPortRepoConfigFlags(t *testing.T) {
// Drive the public Serve entry with --bind/--port/--config/--repo
// against a directory that has no sheaf.textproto. The pipeline
// fails early on config load (rc=3); the assertion here is that
// the binding flags parse without error.
dir := t.TempDir()
rc := Serve([]string{"--bind", "127.0.0.1", "--port", "0", "--repo", dir, "--config", dir + "/missing.textproto"})
if rc == 0 {
t.Errorf("expected non-zero exit with missing config; got 0")
}
}
N/A
command: sheaf serve short: Start the MCP server. long: | Run the ingest → index pipeline once and then keep the corpus live behind an MCP server. Coding agents and the scanner binary consume the server's contract-element lookup, coverage-profile lookup, worked-example retrieval, library_snapshot, and review_pr ops. usage: sheaf serve [--config path] [--repo path] [--bind host] [--port n] pname: sheaf plink: sheaf.yaml options: - option: config
func TestServe_BindPortRepoConfigFlags(t *testing.T) {
// Drive the public Serve entry with --bind/--port/--config/--repo
// against a directory that has no sheaf.textproto. The pipeline
// fails early on config load (rc=3); the assertion here is that
// the binding flags parse without error.
dir := t.TempDir()
rc := Serve([]string{"--bind", "127.0.0.1", "--port", "0", "--repo", dir, "--config", dir + "/missing.textproto"})
if rc == 0 {
t.Errorf("expected non-zero exit with missing config; got 0")
}
}
N/A
command: sheaf serve short: Start the MCP server. long: | Run the ingest → index pipeline once and then keep the corpus live behind an MCP server. Coding agents and the scanner binary consume the server's contract-element lookup, coverage-profile lookup, worked-example retrieval, library_snapshot, and review_pr ops. usage: sheaf serve [--config path] [--repo path] [--bind host] [--port n] pname: sheaf plink: sheaf.yaml options: - option: config
func TestServe_BindPortRepoConfigFlags(t *testing.T) {
// Drive the public Serve entry with --bind/--port/--config/--repo
// against a directory that has no sheaf.textproto. The pipeline
// fails early on config load (rc=3); the assertion here is that
// the binding flags parse without error.
dir := t.TempDir()
rc := Serve([]string{"--bind", "127.0.0.1", "--port", "0", "--repo", dir, "--config", dir + "/missing.textproto"})
if rc == 0 {
t.Errorf("expected non-zero exit with missing config; got 0")
}
}
func TestServe_MissingConfig(t *testing.T) {
dir := t.TempDir()
if rc := Serve([]string{"--repo", dir}); rc == 0 {
t.Errorf("expected non-zero exit on missing config")
}
}
N/A
command: sheaf snapshot short: Emit a library's Snapshot JSON (in-process; pipe to scanner --from-snapshot).
`sheaf scan`, `sheaf gaps`, `sheaf coverage`, `sheaf report`, `sheaf snapshot`, `sheaf serve`, and `sheaf review` all run the full pipeline (config load → adapter dispatch → indexer → analyzers) before producing their output. `sheaf render` and `sheaf review-html` are pipeline-free — they render from a Snapshot JSON / `delta.json` that an earlier pipeline run already produced — as are `sheaf doctor`, `sheaf version`, and `sheaf init`.
Saved snapshots let you re-render without restanding the server. The preferred path is fully in-process — no `sheaf serve`, no `scanner` — using `sheaf snapshot` to persist the Snapshot JSON and `sheaf render --from-snapshot` to render it:
func TestRunSnapshot_RequiresLibrary(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runSnapshot(&out, &errOut, "", dir, "", "", "")
if rc != 2 {
t.Errorf("expected rc=2 when --library is empty; got %d", rc)
}
}
func TestRunSnapshot_StdoutEmitsVersionedJSON(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runSnapshot(&out, &errOut, "", dir, "fuchsia.io", "", "")
if rc != 0 {
t.Fatalf("runSnapshot returned %d; stderr=%s", rc, errOut.String())
}
var snap struct {
SchemaVersion int `json:"schema_version"`
Library string `json:"library"`
Elements []map[string]any `json:"elements"`
}
if err := json.Unmarshal(out.Bytes(), &snap); err != nil {
t.Fatalf("snapshot stdout is not valid JSON: %v", err)
}
if snap.SchemaVersion != librarysnapshot.SchemaVersion {
t.Errorf("schema_version = %d; want %d", snap.SchemaVersion, librarysnapshot.SchemaVersion)
}
if snap.Library != "fuchsia.io" {
t.Errorf("library = %q; want %q", snap.Library, "fuchsia.io")
}
}
func TestRunSnapshot_OutWritesFile(t *testing.T) {
dir := setupFixture(t)
outPath := filepath.Join(t.TempDir(), "nested", "snap.json")
var out, errOut bytes.Buffer
rc := runSnapshot(&out, &errOut, "", dir, "fuchsia.io", "", outPath)
if rc != 0 {
t.Fatalf("runSnapshot(--out) returned %d; stderr=%s", rc, errOut.String())
}
data, err := os.ReadFile(outPath)
if err != nil {
t.Fatalf("snapshot file not written: %v", err)
}
var snap struct {
SchemaVersion int `json:"schema_version"`
}
if err := json.Unmarshal(data, &snap); err != nil {
t.Fatalf("snapshot file is not valid JSON: %v", err)
}
if snap.SchemaVersion != librarysnapshot.SchemaVersion {
t.Errorf("schema_version = %d; want %d", snap.SchemaVersion, librarysnapshot.SchemaVersion)
}
}
N/A
command: sheaf snapshot short: Emit a library's Snapshot JSON (in-process; pipe to scanner --from-snapshot).
**Snapshot.** `sheaf snapshot` emits a library's Snapshot JSON for the server-free render path. `sheaf snapshot --library` names the library (a comma-separated list rolls several into one snapshot, labelled by `sheaf snapshot --library-label`), `sheaf snapshot --out` is the destination file, and `sheaf snapshot --config` / `sheaf snapshot --repo` locate the project.
func TestSnapshot_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so --config / --repo / --library-label
// are parsed from the command line. The runSnapshot tests pass these
// positionally, leaving those three flags unattributed in the
// self-scan even though they're exercised here.
dir := setupFixture(t)
outPath := filepath.Join(t.TempDir(), "snap.json")
rc := Snapshot([]string{
"--config", dir + "/sheaf.textproto",
"--repo", dir,
"--library", "fuchsia.io",
"--library-label", "demo",
"--out", outPath,
})
if rc != 0 {
t.Fatalf("Snapshot(--config/--repo/--library/--library-label/--out) returned %d; want 0", rc)
}
if _, err := os.Stat(outPath); err != nil {
t.Errorf("snapshot via argv didn't write --out file: %v", err)
}
}
N/A
command: sheaf snapshot short: Emit a library's Snapshot JSON (in-process; pipe to scanner --from-snapshot).
**Snapshot.** `sheaf snapshot` emits a library's Snapshot JSON for the server-free render path. `sheaf snapshot --library` names the library (a comma-separated list rolls several into one snapshot, labelled by `sheaf snapshot --library-label`), `sheaf snapshot --out` is the destination file, and `sheaf snapshot --config` / `sheaf snapshot --repo` locate the project.
func TestRunSnapshot_RequiresLibrary(t *testing.T) {
dir := setupFixture(t)
var out, errOut bytes.Buffer
rc := runSnapshot(&out, &errOut, "", dir, "", "", "")
if rc != 2 {
t.Errorf("expected rc=2 when --library is empty; got %d", rc)
}
}
func TestSnapshot_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so --config / --repo / --library-label
// are parsed from the command line. The runSnapshot tests pass these
// positionally, leaving those three flags unattributed in the
// self-scan even though they're exercised here.
dir := setupFixture(t)
outPath := filepath.Join(t.TempDir(), "snap.json")
rc := Snapshot([]string{
"--config", dir + "/sheaf.textproto",
"--repo", dir,
"--library", "fuchsia.io",
"--library-label", "demo",
"--out", outPath,
})
if rc != 0 {
t.Fatalf("Snapshot(--config/--repo/--library/--library-label/--out) returned %d; want 0", rc)
}
if _, err := os.Stat(outPath); err != nil {
t.Errorf("snapshot via argv didn't write --out file: %v", err)
}
}
N/A
command: sheaf snapshot short: Emit a library's Snapshot JSON (in-process; pipe to scanner --from-snapshot).
**Snapshot.** `sheaf snapshot` emits a library's Snapshot JSON for the server-free render path. `sheaf snapshot --library` names the library (a comma-separated list rolls several into one snapshot, labelled by `sheaf snapshot --library-label`), `sheaf snapshot --out` is the destination file, and `sheaf snapshot --config` / `sheaf snapshot --repo` locate the project.
func TestSnapshot_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so --config / --repo / --library-label
// are parsed from the command line. The runSnapshot tests pass these
// positionally, leaving those three flags unattributed in the
// self-scan even though they're exercised here.
dir := setupFixture(t)
outPath := filepath.Join(t.TempDir(), "snap.json")
rc := Snapshot([]string{
"--config", dir + "/sheaf.textproto",
"--repo", dir,
"--library", "fuchsia.io",
"--library-label", "demo",
"--out", outPath,
})
if rc != 0 {
t.Fatalf("Snapshot(--config/--repo/--library/--library-label/--out) returned %d; want 0", rc)
}
if _, err := os.Stat(outPath); err != nil {
t.Errorf("snapshot via argv didn't write --out file: %v", err)
}
}
N/A
command: sheaf snapshot short: Emit a library's Snapshot JSON (in-process; pipe to scanner --from-snapshot).
1. **Server-backed (default).** Connect to `--server`, list libraries, prompt for a selection (skipped when `--library` is set), pull a `library_snapshot`, and render. `--snapshot-out <path>` persists the snapshot for offline replay, but is **deprecated** — prefer `sheaf snapshot --out`, which produces the same JSON in-process without a server. 2. **Offline (`--from-snapshot <path>`).** Skip the server entirely and render directly from a previously-saved snapshot JSON. Use when iterating on the report template, when the source server is no longer running, or when you need a hermetic build.
**Snapshot.** `sheaf snapshot` emits a library's Snapshot JSON for the server-free render path. `sheaf snapshot --library` names the library (a comma-separated list rolls several into one snapshot, labelled by `sheaf snapshot --library-label`), `sheaf snapshot --out` is the destination file, and `sheaf snapshot --config` / `sheaf snapshot --repo` locate the project.
| `--snapshot-out <path>` | `""` | **DEPRECATED** — persist the fetched snapshot to disk for later replay. Prefer `sheaf snapshot --out` (in-process, no server). | | `--from-snapshot <path>` | `""` | Render from a saved snapshot; skips the server connect entirely. |
func TestRunSnapshot_OutWritesFile(t *testing.T) {
dir := setupFixture(t)
outPath := filepath.Join(t.TempDir(), "nested", "snap.json")
var out, errOut bytes.Buffer
rc := runSnapshot(&out, &errOut, "", dir, "fuchsia.io", "", outPath)
if rc != 0 {
t.Fatalf("runSnapshot(--out) returned %d; stderr=%s", rc, errOut.String())
}
data, err := os.ReadFile(outPath)
if err != nil {
t.Fatalf("snapshot file not written: %v", err)
}
var snap struct {
SchemaVersion int `json:"schema_version"`
}
if err := json.Unmarshal(data, &snap); err != nil {
t.Fatalf("snapshot file is not valid JSON: %v", err)
}
if snap.SchemaVersion != librarysnapshot.SchemaVersion {
t.Errorf("schema_version = %d; want %d", snap.SchemaVersion, librarysnapshot.SchemaVersion)
}
}
func TestSnapshot_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so --config / --repo / --library-label
// are parsed from the command line. The runSnapshot tests pass these
// positionally, leaving those three flags unattributed in the
// self-scan even though they're exercised here.
dir := setupFixture(t)
outPath := filepath.Join(t.TempDir(), "snap.json")
rc := Snapshot([]string{
"--config", dir + "/sheaf.textproto",
"--repo", dir,
"--library", "fuchsia.io",
"--library-label", "demo",
"--out", outPath,
})
if rc != 0 {
t.Fatalf("Snapshot(--config/--repo/--library/--library-label/--out) returned %d; want 0", rc)
}
if _, err := os.Stat(outPath); err != nil {
t.Errorf("snapshot via argv didn't write --out file: %v", err)
}
}
N/A
command: sheaf snapshot short: Emit a library's Snapshot JSON (in-process; pipe to scanner --from-snapshot).
**Snapshot.** `sheaf snapshot` emits a library's Snapshot JSON for the server-free render path. `sheaf snapshot --library` names the library (a comma-separated list rolls several into one snapshot, labelled by `sheaf snapshot --library-label`), `sheaf snapshot --out` is the destination file, and `sheaf snapshot --config` / `sheaf snapshot --repo` locate the project.
func TestSnapshot_ArgvFlagParsing(t *testing.T) {
// Drive the public argv entry so --config / --repo / --library-label
// are parsed from the command line. The runSnapshot tests pass these
// positionally, leaving those three flags unattributed in the
// self-scan even though they're exercised here.
dir := setupFixture(t)
outPath := filepath.Join(t.TempDir(), "snap.json")
rc := Snapshot([]string{
"--config", dir + "/sheaf.textproto",
"--repo", dir,
"--library", "fuchsia.io",
"--library-label", "demo",
"--out", outPath,
})
if rc != 0 {
t.Fatalf("Snapshot(--config/--repo/--library/--library-label/--out) returned %d; want 0", rc)
}
if _, err := os.Stat(outPath); err != nil {
t.Errorf("snapshot via argv didn't write --out file: %v", err)
}
}
N/A
command: sheaf verify short: Adversarially check a snapshot's top-line numbers (vs the join + disk) before a report is shown.
> **Onboard your repo with the `sheaf-onboard` skill (recommended).** Your agent does the reconnaissance and config, runs the scan, then runs `sheaf verify` to check every headline number against disk *before* it shows you the report, so your spot-check is a confirmation, not a discovery. If config alone can't reach a surface, it offers a `sheaf-build-adapter` handoff instead of quietly under-counting. > > ```sh > docs/examples/sheaf-onboard/install.sh # then, in Claude / Cursor / Cline: /sheaf-onboard > ``` > > Any agentic CLI (Gemini, Codex) drives it via [`AGENTS.md`](docs/examples/sheaf-on…
**Verify.** `sheaf verify` adversarially re-checks a scan's headline numbers before the report is shown. It reads a snapshot via `sheaf verify --from-snapshot` and reconciles it — or, as a one-shot, `sheaf verify --config` builds the snapshot in-process (with `sheaf verify --library`) and verifies it in a single step. `sheaf verify --repo` points at the source tree, `sheaf verify --ecosystem` selects the view shape, and `sheaf verify --low-coverage-threshold` sets the suspicion line. `sheaf verify --disk` runs the on-disk oracle — `sheaf verify --check-urls` adds dead-link resolution, `she…
func TestReconcileTests_MismatchIsError(t *testing.T) {
rd := &scanner.ReportData{
Total: 2,
TestCount: 1,
Methods: []scanner.MethodRow{{Name: "a", Test: 1}, {Name: "b", Test: 0}},
}
profByID := map[string]map[string]any{
"a": testProfile(0),
"b": testProfile(0),
}
rep := &Report{}
reconcileTests(rep, rd, profByID)
if !hasCategory(rep, CatReconcile) {
t.Fatalf("expected a reconcile finding, got %+v", rep.Findings)
}
}
func TestReconcileTests_ConsistentIsClean(t *testing.T) {
rd := &scanner.ReportData{
Total: 2,
TestCount: 1,
Methods: []scanner.MethodRow{{Name: "a", Test: 3}, {Name: "b", Test: 0}},
}
profByID := map[string]map[string]any{
"a": testProfile(3, "a_test.go", "a2_test.go"),
"b": testProfile(0),
}
rep := &Report{}
reconcileTests(rep, rd, profByID)
if hasCategory(rep, CatReconcile) {
t.Fatalf("expected no reconcile finding, got %+v", rep.Findings)
}
}
func TestDecompose_ZeroSurfaceWarnsNotErrors(t *testing.T) {
rd := &scanner.ReportData{
Total: 48, ShowTestTile: true,
TestCount: 10, TestPct: 21,
PrimaryTotal: 11, PrimaryNoun: "Commands", PrimaryTestN: 10, PrimaryTestPct: 91,
ModifierTotal: 37, ModifierNoun: "Flags", ModifierTestN: 0, ModifierTestPct: 0,
}
rep := &Report{}
decomposeTiers(rep, rd, 0.15)
if !hasCategoryTier(rep, CatZeroSurface, "modifier") {
t.Fatalf("expected zero_surface on the modifier tier, got %+v", rep.Findings)
}
for _, f := range rep.Findings {
if f.Category == CatZeroSurface && f.Severity != SeverityWarn {
t.Fatalf("a 0%% surface must be a WARNING pre-disk, got severity %q", f.Severity)
}
}
}
N/A
command: sheaf verify short: Adversarially check a snapshot's top-line numbers (vs the join + disk) before a report is shown.
**Verify.** `sheaf verify` adversarially re-checks a scan's headline numbers before the report is shown. It reads a snapshot via `sheaf verify --from-snapshot` and reconciles it — or, as a one-shot, `sheaf verify --config` builds the snapshot in-process (with `sheaf verify --library`) and verifies it in a single step. `sheaf verify --repo` points at the source tree, `sheaf verify --ecosystem` selects the view shape, and `sheaf verify --low-coverage-threshold` sets the suspicion line. `sheaf verify --disk` runs the on-disk oracle — `sheaf verify --check-urls` adds dead-link resolution, `she…
N/A
N/A
command: sheaf verify short: Adversarially check a snapshot's top-line numbers (vs the join + disk) before a report is shown.
**Verify.** `sheaf verify` adversarially re-checks a scan's headline numbers before the report is shown. It reads a snapshot via `sheaf verify --from-snapshot` and reconciles it — or, as a one-shot, `sheaf verify --config` builds the snapshot in-process (with `sheaf verify --library`) and verifies it in a single step. `sheaf verify --repo` points at the source tree, `sheaf verify --ecosystem` selects the view shape, and `sheaf verify --low-coverage-threshold` sets the suspicion line. `sheaf verify --disk` runs the on-disk oracle — `sheaf verify --check-urls` adds dead-link resolution, `she…
N/A
N/A
command: sheaf verify short: Adversarially check a snapshot's top-line numbers (vs the join + disk) before a report is shown.
**Verify.** `sheaf verify` adversarially re-checks a scan's headline numbers before the report is shown. It reads a snapshot via `sheaf verify --from-snapshot` and reconciles it — or, as a one-shot, `sheaf verify --config` builds the snapshot in-process (with `sheaf verify --library`) and verifies it in a single step. `sheaf verify --repo` points at the source tree, `sheaf verify --ecosystem` selects the view shape, and `sheaf verify --low-coverage-threshold` sets the suspicion line. `sheaf verify --disk` runs the on-disk oracle — `sheaf verify --check-urls` adds dead-link resolution, `she…
N/A
N/A
command: sheaf verify short: Adversarially check a snapshot's top-line numbers (vs the join + disk) before a report is shown.
**Verify.** `sheaf verify` adversarially re-checks a scan's headline numbers before the report is shown. It reads a snapshot via `sheaf verify --from-snapshot` and reconciles it — or, as a one-shot, `sheaf verify --config` builds the snapshot in-process (with `sheaf verify --library`) and verifies it in a single step. `sheaf verify --repo` points at the source tree, `sheaf verify --ecosystem` selects the view shape, and `sheaf verify --low-coverage-threshold` sets the suspicion line. `sheaf verify --disk` runs the on-disk oracle — `sheaf verify --check-urls` adds dead-link resolution, `she…
N/A
N/A
command: sheaf verify short: Adversarially check a snapshot's top-line numbers (vs the join + disk) before a report is shown.
**Verify.** `sheaf verify` adversarially re-checks a scan's headline numbers before the report is shown. It reads a snapshot via `sheaf verify --from-snapshot` and reconciles it — or, as a one-shot, `sheaf verify --config` builds the snapshot in-process (with `sheaf verify --library`) and verifies it in a single step. `sheaf verify --repo` points at the source tree, `sheaf verify --ecosystem` selects the view shape, and `sheaf verify --low-coverage-threshold` sets the suspicion line. `sheaf verify --disk` runs the on-disk oracle — `sheaf verify --check-urls` adds dead-link resolution, `she…
N/A
N/A
N/A
command: sheaf verify short: Adversarially check a snapshot's top-line numbers (vs the join + disk) before a report is shown.
**Verify.** `sheaf verify` adversarially re-checks a scan's headline numbers before the report is shown. It reads a snapshot via `sheaf verify --from-snapshot` and reconciles it — or, as a one-shot, `sheaf verify --config` builds the snapshot in-process (with `sheaf verify --library`) and verifies it in a single step. `sheaf verify --repo` points at the source tree, `sheaf verify --ecosystem` selects the view shape, and `sheaf verify --low-coverage-threshold` sets the suspicion line. `sheaf verify --disk` runs the on-disk oracle — `sheaf verify --check-urls` adds dead-link resolution, `she…
N/A
N/A
command: sheaf verify short: Adversarially check a snapshot's top-line numbers (vs the join + disk) before a report is shown.
**Verify.** `sheaf verify` adversarially re-checks a scan's headline numbers before the report is shown. It reads a snapshot via `sheaf verify --from-snapshot` and reconciles it — or, as a one-shot, `sheaf verify --config` builds the snapshot in-process (with `sheaf verify --library`) and verifies it in a single step. `sheaf verify --repo` points at the source tree, `sheaf verify --ecosystem` selects the view shape, and `sheaf verify --low-coverage-threshold` sets the suspicion line. `sheaf verify --disk` runs the on-disk oracle — `sheaf verify --check-urls` adds dead-link resolution, `she…
N/A
N/A
command: sheaf verify short: Adversarially check a snapshot's top-line numbers (vs the join + disk) before a report is shown.
**Verify.** `sheaf verify` adversarially re-checks a scan's headline numbers before the report is shown. It reads a snapshot via `sheaf verify --from-snapshot` and reconciles it — or, as a one-shot, `sheaf verify --config` builds the snapshot in-process (with `sheaf verify --library`) and verifies it in a single step. `sheaf verify --repo` points at the source tree, `sheaf verify --ecosystem` selects the view shape, and `sheaf verify --low-coverage-threshold` sets the suspicion line. `sheaf verify --disk` runs the on-disk oracle — `sheaf verify --check-urls` adds dead-link resolution, `she…
N/A
N/A
command: sheaf verify short: Adversarially check a snapshot's top-line numbers (vs the join + disk) before a report is shown.
**Verify.** `sheaf verify` adversarially re-checks a scan's headline numbers before the report is shown. It reads a snapshot via `sheaf verify --from-snapshot` and reconciles it — or, as a one-shot, `sheaf verify --config` builds the snapshot in-process (with `sheaf verify --library`) and verifies it in a single step. `sheaf verify --repo` points at the source tree, `sheaf verify --ecosystem` selects the view shape, and `sheaf verify --low-coverage-threshold` sets the suspicion line. `sheaf verify --disk` runs the on-disk oracle — `sheaf verify --check-urls` adds dead-link resolution, `she…
N/A
N/A
command: sheaf verify short: Adversarially check a snapshot's top-line numbers (vs the join + disk) before a report is shown.
**Verify.** `sheaf verify` adversarially re-checks a scan's headline numbers before the report is shown. It reads a snapshot via `sheaf verify --from-snapshot` and reconciles it — or, as a one-shot, `sheaf verify --config` builds the snapshot in-process (with `sheaf verify --library`) and verifies it in a single step. `sheaf verify --repo` points at the source tree, `sheaf verify --ecosystem` selects the view shape, and `sheaf verify --low-coverage-threshold` sets the suspicion line. `sheaf verify --disk` runs the on-disk oracle — `sheaf verify --check-urls` adds dead-link resolution, `she…
N/A
N/A
command: sheaf verify short: Adversarially check a snapshot's top-line numbers (vs the join + disk) before a report is shown.
**Verify.** `sheaf verify` adversarially re-checks a scan's headline numbers before the report is shown. It reads a snapshot via `sheaf verify --from-snapshot` and reconciles it — or, as a one-shot, `sheaf verify --config` builds the snapshot in-process (with `sheaf verify --library`) and verifies it in a single step. `sheaf verify --repo` points at the source tree, `sheaf verify --ecosystem` selects the view shape, and `sheaf verify --low-coverage-threshold` sets the suspicion line. `sheaf verify --disk` runs the on-disk oracle — `sheaf verify --check-urls` adds dead-link resolution, `she…
N/A
N/A
command: sheaf verify short: Adversarially check a snapshot's top-line numbers (vs the join + disk) before a report is shown.
**Verify.** `sheaf verify` adversarially re-checks a scan's headline numbers before the report is shown. It reads a snapshot via `sheaf verify --from-snapshot` and reconciles it — or, as a one-shot, `sheaf verify --config` builds the snapshot in-process (with `sheaf verify --library`) and verifies it in a single step. `sheaf verify --repo` points at the source tree, `sheaf verify --ecosystem` selects the view shape, and `sheaf verify --low-coverage-threshold` sets the suspicion line. `sheaf verify --disk` runs the on-disk oracle — `sheaf verify --check-urls` adds dead-link resolution, `she…
N/A
N/A
command: sheaf verify short: Adversarially check a snapshot's top-line numbers (vs the join + disk) before a report is shown.
**Verify.** `sheaf verify` adversarially re-checks a scan's headline numbers before the report is shown. It reads a snapshot via `sheaf verify --from-snapshot` and reconciles it — or, as a one-shot, `sheaf verify --config` builds the snapshot in-process (with `sheaf verify --library`) and verifies it in a single step. `sheaf verify --repo` points at the source tree, `sheaf verify --ecosystem` selects the view shape, and `sheaf verify --low-coverage-threshold` sets the suspicion line. `sheaf verify --disk` runs the on-disk oracle — `sheaf verify --check-urls` adds dead-link resolution, `she…
N/A
N/A
command: sheaf verify short: Adversarially check a snapshot's top-line numbers (vs the join + disk) before a report is shown.
**Verify.** `sheaf verify` adversarially re-checks a scan's headline numbers before the report is shown. It reads a snapshot via `sheaf verify --from-snapshot` and reconciles it — or, as a one-shot, `sheaf verify --config` builds the snapshot in-process (with `sheaf verify --library`) and verifies it in a single step. `sheaf verify --repo` points at the source tree, `sheaf verify --ecosystem` selects the view shape, and `sheaf verify --low-coverage-threshold` sets the suspicion line. `sheaf verify --disk` runs the on-disk oracle — `sheaf verify --check-urls` adds dead-link resolution, `she…
N/A
N/A
command: sheaf version short: Print version information. long: | Print the linked build version (set via -ldflags at link time, defaulting to 0.1.0-dev) and exit. Takes no flags and runs no
`sheaf scan`, `sheaf gaps`, `sheaf coverage`, `sheaf report`, `sheaf snapshot`, `sheaf serve`, and `sheaf review` all run the full pipeline (config load → adapter dispatch → indexer → analyzers) before producing their output. `sheaf render` and `sheaf review-html` are pipeline-free — they render from a Snapshot JSON / `delta.json` that an earlier pipeline run already produced — as are `sheaf doctor`, `sheaf version`, and `sheaf init`.
func TestVersion(t *testing.T) {
if rc := Version(nil); rc != 0 {
t.Errorf("Version rc = %d", rc)
}
}
N/A
Recipes name the command, not the flag — 85% of commands appear in at least one workflow, only 44% of flags do.