coach

module
v0.12.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 8, 2026 License: BSD-2-Clause

README

coach

coach is an experimental AI coach for people (and agents) who write software. The thing you can use today is a local CLI: it reads a Git checkout, analyzes Go / TypeScript / TSX source, and prints advisory structural signals.

Coach stays on the 0.x line on purpose. It does not contact GitHub or call a model on this path. File-local analysis is Tree-sitter over committed Git objects. TypeScript --project-config additionally runs a host Node process and the TypeScript compiler; that is still local, not the platform preview.

Quick start (TypeScript)

Scan committed .ts / .tsx. No API key, no model, no merge gate. Uncommitted edits are invisible.

mise exec github:lousy-agents/coach -- coach codesignal --baseline

File-local mode is Tree-sitter over committed Git objects. It reports structural signals (structure.react_component_orchestration_density, coupling.deep_relative_import, security.toctou_check_then_act). It does not know your layers.

Project scanning is a different contract from ESLint boundary plugins, dependency-cruiser, or repo-chat. Those lint the worktree, infer a module graph, or guess architecture from retrieved files. Coach does not guess. You declare roots, layers, and forbidden_imports. Coach evaluates those edges with a host-resolved TypeScript compiler against the revision you named and emits versioned architecture.layer_violation signals — JSON schema_version: "2" that an agent can parse.

coach codesignal --baseline --check-project --project-language typescript
coach codesignal --baseline --suggest-project-config --project-language typescript
# commit the JSON at the analyzed revision, then:
coach codesignal --baseline --project-config .lousy-agents/coach.json --project-language typescript --format json

--check-project is readiness, not a scan (exit 0 even with gaps). The TypeScript form of --suggest-project-config is an interactive TTY and writes nothing until you confirm; the Go form writes the candidate without prompting. Project mode needs that committed policy plus a supported compiler and Node 24 or 26. An empty signals array is not compliance.

Full flags and schema: CLI contract.

Contract

  • Languages: Go, TypeScript, TSX. Other files get an unsupported_language diagnostic and are skipped.
  • Input: committed Git objects at the selected revision, not the dirty worktree. Uncommitted edits are invisible.
  • Git: git 2.42 or later must be on PATH: a scan needs 2.16 to start and --baseline needs 2.42 to read the files it analyzes; see git version. No Docker, no API key, no network for the default CLI path. In a partial clone Coach never fetches a missing object; a git older than 2.44 cannot be told that, so with it a read is made only when every object of the revisions the scan reads is already here, whatever the repository's configuration says; see what repository configuration can run.
  • Advisory: a completed analysis exits 0 even when it found signals. Coach does not gate merges.
  • Absence is not a clean bill of health. An empty signal set means no matched rule for the inputs that were analyzed. The forbidden_imports check reaches only imports between code inside declared layers; with --project-config, the report says how many project files under the configured roots sit outside every declared layer. It leaves that count out when no layers are declared, when the inputs are incomplete (for example, a project model cut short by its input budget), when a configured root holds no analyzed file, or when a TypeScript root's analyzed-file count does not match its path list.

Full flags, JSON schema, exit codes, rule IDs, and library quickstarts: CLI contract.

Run

From any Git worktree. Prefer a one-shot that does not mutate a global toolchain:

mise exec github:lousy-agents/coach -- coach codesignal --base main
coach codesignal --base main          # diff HEAD against main
coach codesignal --baseline           # every tracked Go/TS/TSX file at HEAD
coach codesignal --base main --format json

--base can be any ref Git can resolve (branch, tag, or SHA). Default output is text. --base and --baseline are mutually exclusive.

Signals are ranked, with severity and rule_id printed on each: lifecycle group first (with --base, introduced and changed findings come first), then severity, confidence, and path, with findings of the same metric rule (cognitive complexity, branch density, nesting depth) ordered by how far each exceeds its threshold. To read a long report, add --min-severity high|medium|advisory|low to hide lower severities (--min-severity medium also hides advisory layer-rule findings, and a --top cap can push them out because advisory ranks below every medium finding in the same lifecycle group; only complexity.cognitive_complexity and complexity.max_nesting_depth findings can be high, so --min-severity high shows only those two rules; security.toctou_check_then_act and state.hidden_input_mutation are always medium, so a high floor withholds them) or --top N to keep the first N in that order (with --base, that order puts resolved findings ahead of unknown ones, so a cap can spend slots on findings already fixed; see Report order). Both state how many signals they withheld (text also says how to show them all: the command, or a note to re-run without the narrowing flags you gave when an argument is unsafe to print; the printed command starts with coach, so if you launched through mise, run it as mise exec github:lousy-agents/coach -- coach codesignal ...), leave summary and coverage describing the full analysis, and never change the exit status. See the CLI contract.

Default --scope is production. --build-target <pattern> further limits Go production reachability; it is a no-op under --scope all.

Exit codes
Code Meaning
0 Analysis completed (signals or none). Not a quality gate.
1 Operational failure (not a git repo, missing git, unresolvable --base, empty repo, I/O; also --check-project when git cannot answer a question about an explicit --project-config: empty stdout, stderr names the question); and, in a partial clone, an object the clone lacks (Coach never fetches; this includes the merge base's version of a file a --base diff compares, and with a git older than 2.44 it is refused before anything runs).
2 Usage or invalid --project-config, or a TypeScript scan that cannot resolve a supported compiler or host Node (empty stdout except the policy-candidate document on the guided-authoring path; one or more stderr lines).
3 Required project coverage incomplete and --fail-on-incomplete-coverage was supplied (report still written to stdout); or --prepare-compiler operational failure resolving the revision or computing readiness.
What you should see

A short text report per signal (rule_id, severity, path, line, lifecycle, source_scope, changed, evidence, why it matters, recommendation), or a quiet report if nothing matched. lifecycle is introduced / existing / resolved / unknown (and baseline under --baseline).

Diff-mode limits (do not treat these as a clean PR):

  • Diff mode runs git diff --name-status with --find-renames (git's default 50% similarity) and --find-copies-harder (also considers unmodified files as copy sources — more aggressive than git's defaults). Rename (R) and copy (C) new paths are analyzed. A pure git rename or copy without old-path continuity yields lifecycle: unknown plus a continuity_not_determined path diagnostic — coach does not diff a rename against its old path, so a pure move is not classified existing or introduced. Adopters who only watch introduced_signals shall treat that path as incomplete, not green.
  • Statuses the CLI does not analyze (T, U, X, B) stay unsupported_change_type. Those paths increment summary.files_unanalyzed and summary.files_with_diagnostics, and the text headline qualifies the all-clear with the numeric unanalyzed count.

Text line is 1-based. JSON location.start_row is 0-based.

Lifecycle and counters

JSON summary counts every signals[] entry in exactly one of introduced_signals, existing_signals, resolved_signals, baseline_signals, unknown_signals. active_signals is len(signals) after the include-resolved filter, when no narrowing flag is set. That relationship holds for both --base and --baseline:

  • --base includes resolved in signals[] by default, so active_signals includes them. That total is not "problems present at HEAD".
  • --baseline does not include resolved. Signals there are baseline.

With --min-severity or --top, signals[] can be shorter than active_signals. When signals_withheld is present, active_signals == len(signals) + below_min_severity + beyond_top, reading an absent key as 0. In a schema_version: "2" report, project_changes[] is shortened to match, while project_summary.active_changes keeps the full count; each project change is also a signal, so the withheld ones are already counted in below_min_severity and beyond_top.

Problems present at HEAD are introduced_signals + existing_signals + unknown_signals (and baseline_signals under --baseline). Do not trust active_signals alone in diff mode.

Added (A) files in --base mode are lifecycle: introduced and count in introduced_signals. unknown is residual classification, not "new in this diff." An unanalyzable merge-base carries a base_read_failed, base_syntax_errors, or base_analysis_failed diagnostic. A rename or copy without old-path continuity is also unknown and carries continuity_not_determined; that is not a green introduced_signals miss.

Install

Install mise if you do not already have it, then pin the CLI from GitHub Releases:

curl https://mise.run | sh
~/.local/bin/mise use -g github:lousy-agents/coach

That mutates a global mise config. Hook mise into your shell so coach is on PATH (pick the one you use):

echo 'eval "$(~/.local/bin/mise activate bash)"' >> ~/.bashrc && eval "$(~/.local/bin/mise activate bash)"
# echo 'eval "$(~/.local/bin/mise activate zsh)"' >> ~/.zshrc && eval "$(~/.local/bin/mise activate zsh)"
# ~/.local/bin/mise activate fish | source

Pin a release if you want a fixed binary (latest published tag is v0.12.0):

mise use -g github:lousy-agents/coach@v0.12.0

Release archives exist for darwin_arm64, darwin_x86_64, linux_x86_64, and windows_x86_64. There is no linux_arm64 build yet.

From source instead of the release binary

This path uses the repo's mise.toml to pin the dev toolchain (Go 1.27.1, Node 24). That is not the same as installing the published coach binary.

git clone https://github.com/lousy-agents/coach.git
cd coach
mise install
mise exec -- go install ./cmd/coach
Signed archive without mise

Download the archive for your platform from Releases, verify checksums.txt with cosign, then put coach on your PATH. Commands: CLI contract.

Preview — experimental, try it now

These commands work on the current CLI. They may change without a 1.0 promise. Absence of findings is not compliance.

1. Project-level architecture policy

Opt into cross-file layer checks with a committed JSON config. Coach does not guess your architecture — you declare layers and forbidden import edges.

# Go: discover module/workspace roots (candidate only — review, add layers, commit)
coach codesignal --baseline --suggest-project-config

# after the file is committed at the analyzed revision
coach codesignal --base main --project-config .lousy-agents/coach.json
coach codesignal --baseline --project-config .lousy-agents/coach.json --project-language typescript

Move a root project.json to that path, from any directory of the repository:

top="$(git rev-parse --show-toplevel)" && mkdir -p "$top"/.lousy-agents && git -C "$top" mv -- project.json .lousy-agents/coach.json

An explicit --project-config still reads only that path. A schema-valid root project.json is still read with a deprecation diagnostic until the follow-up removal (issue #511). The lookup is .lousy-agents config.

--project-config content is read from the analyzed revision, not your dirty worktree. The path itself is checked on disk first, and what is there decides what Coach says. Every case below exits 2, and stdout stays empty except for the policy-candidate document on the guided-authoring path.

  • Nothing is there, the policy was never committed, and the index holds nothing for it: project_config_missing. A Go scan then prints --suggest-project-config; a TypeScript scan on a controlling terminal opens guided authoring, and --check-project names author_policy. An index entry that holds no content, made with git add --intent-to-add or by staging an empty file, counts as nothing, unless it is marked skip-worktree: git add refuses a new file at a path the mark hides, so Coach calls it an empty entry, names the mark (or the sparse checkout), and offers no new policy.
  • Nothing is there but the policy is committed at the analyzed revision: project_config_missing, with the one command that brings it back, git restore --source=<revision> --staged --worktree -- ':(top,literal)<path>', and no authoring. --check-project names it as the restore_policy next action, with executable: false. Coach offers that command only when it overwrites nothing and git can run it. If the index holds a staged edit to the policy, the restore from the revision would discard the edit, so Coach does not offer it as the default. It says why and offers no new policy, and it prints two choices: the restore from the index, which keeps the edit, and, labelled as the way to drop it, the restore from the revision, to drop it and bring back the committed copy. If the index holds an unmerged entry for the policy, if the policy is committed as a symbolic link, if a sparse checkout leaves it out of the working tree or its index entry is marked skip-worktree, or if git cannot say whether it is committed or what the index holds, Coach says why and offers neither a restore nor a new policy. An index entry that holds no content does not count as an edit: the restore replaces it, and the message says that it brings back the committed copy, unless the entry is marked skip-worktree, which stops a restore and is named instead.
  • Nothing is there and the policy was never committed, but the index holds an entry for it: project_config_missing, and no authoring, because a new policy would replace staged work. A staged regular file gets the one command that brings it back from the index, git restore -- ':(top,literal)<path>'. Coach prints no command, and says why, when the entry is unmerged, is a symbolic link or another entry that is not a regular file, or is marked skip-worktree or left out by a sparse checkout, because the command would fail or would recreate what the scan refuses. --check-project names neither next action.
  • A path under a regular file: project_config_missing. The message names the file in the way. When the analyzed revision commits that file, the message says it is a file the analyzed revision commits, so the path is probably wrong, and gives no advice to move or remove it, because the file is the repository's and the path is what is wrong. For a file nothing commits, the message says to move or remove it, then to restore the policy from git when it is committed, unless the index holds a staged edit to it, which the message names instead because a restore would discard it, or it is committed as a symbolic link, which the message says instead because a restore would recreate a link the scan refuses. When the policy is only staged, never committed, it says to move the file and then restore the staged copy from the index. When the index holds an unmerged entry for the policy, the step that brings the conflicted file back is described behind the step that moves the file, in words and with no command, because bringing it back would delete that file as well. It prints no git restore command and offers no authoring, because a restore would delete that file.
  • A symbolic link, a directory or other file that is not a regular file, a path that runs through a symbolic link, a file that cannot be read, or a parent that cannot be searched: project_config_invalid, naming the reason, with no restore and no authoring.
  • A policy path that the analyzed revision does not commit as written, while it commits the same path in another case (CFG/p.json named, cfg/p.json committed; or .Lousy-Agents/Coach.json committed where Coach reads .lousy-agents/coach.json): project_config_invalid, and --check-project names name_case_differs and offers no new policy. One message serves a policy you name and one Coach finds, on any file system and whatever core.ignorecase says: it names the committed spelling and the path Coach reads and says in words to make git record the policy at that path, then commit and run again. It prints no command, and it always warns that a file already at that path is to be moved aside first, because git can overwrite it with core.ignorecase set. A rename you have already staged is told the same as one you have not, because the revision still holds the old spelling until you commit. A policy you name is also told to pass the committed spelling, which is the way out for a slip of the case, and a directory renamed in case only is told to take two steps on a file system that folds case. A revision that commits exactly the path as written is read whatever spelling the disk shows. See the CLI contract.
  • A policy inside a submodule checkout, or at a path the analyzed revision commits as a submodule, naming the submodule: project_config_invalid while the checkout is there (the file in it, or the submodule itself), and project_config_missing once it is gone (git submodule deinit). --check-project names the cause in_submodule for all of them, and so for a name below the submodule that differs in case from the checkout's: the superproject holds no spelling of what is inside, so Coach does not report a difference in case there. A name that spells the submodule's own path in another case than the index records it, where git ignores case (core.ignorecase), is inside it all the same, and the message names the submodule as the index records it. The superproject records a submodule as one commit, so the file can be neither restored nor committed here; name a policy this repository commits. See the CLI contract.

A file that exists on disk but is not committed is rejected (project_config_invalid, with the instruction to commit it) until the disk-read slice of #168. Coach offers no new policy there, because a file already sits at the path. A valid config switches the report to schema_version: "2" and can emit architecture.layer_violation. required_layer can also emit architecture.layer_bypass (Go and TypeScript) on a narrow handler→SQL registry.

TypeScript --project-config uses Coach's embedded analyzer and a host-resolved compiler whose own package.json version is in the supported set (7.0.2 today). Version ranges (^, ~, latest) never count. If you previously vendored Coach's analyzer under the analyzed repository, you can delete that copy. --suggest-project-config never invents layers or forbidden_imports, and it never auto-applies a config.

Go --suggest-project-config prints a candidate. TypeScript --suggest-project-config --project-language typescript is an interactive TTY session and writes nothing until you confirm. Do not run it unattended.

2. TypeScript project readiness
coach codesignal --baseline --check-project --project-language typescript
coach codesignal --baseline --suggest-project-config --project-language typescript

Run --check-project first. It is read-only: it reports compiler, Node, and policy fit and exits 0 so you inspect the result instead of treating process status as a gate. It is not a scan. A scan that cannot resolve a supported compiler or host Node exits 2 with empty stdout except the policy-candidate document on the guided-authoring path, and one or more stderr lines. On a controlling terminal, a TypeScript scan whose --project-config names a policy that does not exist on disk and was never committed instead opens a guided-authoring session (a policy that is committed, or that the index holds, gets what the cases above describe instead); with --format json this session's exit-2 output is a JSON object carrying "schema_version": "1" and roots, not a CodeSignal report — the absent scope/signals/coverage keys distinguish it.

Coach's supported Node majors are exactly 24 and 26. Any other major is the node_unsupported readiness gap. @lousy-agents/coach-semantics declares this as engines.node: "^24 || ^26".

--prepare-compiler is a consented, interactive mise TypeScript compiler-setup session (requires a TTY; refuses otherwise). It prompts before installing. It also refuses, naming the gap without opening a menu, when the readiness gap is a runtime boundary (missing or unsupported host Node): Coach has no setup command for a Node version problem, and the flag shares that gate with the scan's own compiler-setup offer so the two paths cannot disagree on it. The flag remains mise-only, so it is narrower than the scan's offer in what it can install; Coach never names it as remediation for a gap only the project package manager could resolve.

A scan (--baseline/--base with --project-config, --project-language typescript, a committed policy, and an unresolved compiler) offers a superset of that setup interactively when it runs on a controlling terminal: it names the failing check and what happens after a successful install, then shows a menu of up to four choices — project_package (run the project's own package-manager install, e.g. npm ci --ignore-scripts), project_mise/global_mise (run mise install for a project- or globally-pinned supported TypeScript version), and cancel. A choice that would open only to report nothing to do is withheld from the menu, and a gap with nothing installable never opens a prompt at all. Picking project_package shows a preview (exact executable, arguments, working directory, expected on-disk changes, network use, and a bounded 5-minute timeout) before a separate, single-use confirm/install answer is required to actually run it — typing anything else, or a second leftover answer, cancels or is ignored rather than running twice. On cancel, nothing runs and the scan exits 2 with the original remediation. On failure, the scan exits 2, reports the failure, and never modifies the repository's tracked files. On success, Coach reruns the full readiness check and only continues the same scan through to a report if that rerun is clear; a rerun that still reports a gap still exits 2 with no report.

Pass --no-interactive, or set a non-empty CI environment variable, to make Coach treat the run as unattended even when a real controlling terminal is attached — for example, a pty-allocating CI runner (docker run -t, ssh -t) with nobody at the keyboard. A scan then falls straight through to the same message-only remediation a piped invocation gets, and --suggest-project-config / --prepare-compiler refuse with exit 2 rather than opening a prompt nobody will answer.

Still being built — do not expect these to work yet: unattended package-manager setup for the scanned project, Bun as a project runtime, and a packaged foreign-repository TypeScript journey.

Separate lab: local platform

The CLI above is the default product. A Docker API + worker stack can add agent judgments on a baseline scan. That path uses Docker, may call a model, and may read GitHub. It is not the default install.

Verified in CI: Path A (mise run platform-up / platform-smoke) with the stub model. Paths B (real local model) and C (live GitHub.com) are operator labs. Findings are tagged source=deterministic or source=agent; agent output cannot suppress a deterministic finding.

Local Coach quickstart.

Libraries

Analyzer as a library rather than the CLI — not required to run coach:

Directories

Path Synopsis
cmd
acceptance-guard-preflight command
Command acceptance-guard-preflight is the activation entry point for internal/acceptanceharness's ambient-credential guard: run it before any acceptance suite starts (see mise.toml's test-acceptance-fast task).
Command acceptance-guard-preflight is the activation entry point for internal/acceptanceharness's ambient-credential guard: run it before any acceptance suite starts (see mise.toml's test-acceptance-fast task).
acceptance-style-guard command
Command acceptance-style-guard fails if any acceptance_test.go or *_acceptance_test.go under the module root does not import github.com/onsi/ginkgo/v2 and reference a Ginkgo suite/spec API, except an explicit allowlist (see internal/acceptancestyle).
Command acceptance-style-guard fails if any acceptance_test.go or *_acceptance_test.go under the module root does not import github.com/onsi/ginkgo/v2 and reference a Ginkgo suite/spec API, except an explicit allowlist (see internal/acceptancestyle).
coach command
Command coach is the composition-root CLI for the coach project.
Command coach is the composition-root CLI for the coach project.
coach-api command
Command coach-api is the composition-root HTTP service for the coach platform: it wires internal/authn (Coach JWT auth, optional GitHub OAuth login, config-gated test mint) and internal/coachapi (POST /v1/jobs, GET /v1/jobs/{id}, GET /v1/jobs/{id}/report) behind a live authz.RepoAuthorizer and a Redis Streams queue.TaskQueue into one runnable server.
Command coach-api is the composition-root HTTP service for the coach platform: it wires internal/authn (Coach JWT auth, optional GitHub OAuth login, config-gated test mint) and internal/coachapi (POST /v1/jobs, GET /v1/jobs/{id}, GET /v1/jobs/{id}/report) behind a live authz.RepoAuthorizer and a Redis Streams queue.TaskQueue into one runnable server.
coach-worker command
Command coach-worker claims work through queue.TaskQueue, persists claim/heartbeat/fenced writes via coachapi.WorkerJobStore, and runs the repo_baseline_scan handler.
Command coach-worker claims work through queue.TaskQueue, persists claim/heartbeat/fenced writes via coachapi.WorkerJobStore, and runs the repo_baseline_scan handler.
codesignal-report command
Command codesignal-report reads a batch of NDJSON lines from stdin, accumulates a single codesignal.Input, and writes exactly one JSON codesignal.Report to stdout.
Command codesignal-report reads a batch of NDJSON lines from stdin, accumulates a single codesignal.Input, and writes exactly one JSON codesignal.Report to stdout.
fakegithub-server command
Command fakegithub-server runs internal/fakegithub as a standalone HTTP process, packaging the issue #79 Task 0.3 thin-offline-proof fixture (internal/acceptanceharness/thinproof) as an internal-network Compose service rather than an in-process httptest.Server.
Command fakegithub-server runs internal/fakegithub as a standalone HTTP process, packaging the issue #79 Task 0.3 thin-offline-proof fixture (internal/acceptanceharness/thinproof) as an internal-network Compose service rather than an in-process httptest.Server.
model-stub command
Command model-stub serves the compose OpenAI-compatible HTTP stub from internal/modelgateway so core smoke can exercise worker → Envoy AI Gateway → backend without model weights.
Command model-stub serves the compose OpenAI-compatible HTTP stub from internal/modelgateway so core smoke can exercise worker → Envoy AI Gateway → backend without model weights.
platform-smoke command
Command platform-smoke is the end-to-end credential-free smoke for the local platform compose stack (Baseline Scan Story 4 / Task 10): mint → submit repo_baseline_scan → poll → assert provenance-tagged report.
Command platform-smoke is the end-to-end credential-free smoke for the local platform compose stack (Baseline Scan Story 4 / Task 10): mint → submit repo_baseline_scan → poll → assert provenance-tagged report.
semantics-json command
Command semantics-json exposes internal/jsbridge as a long-running newline-delimited-JSON server on stdin/stdout, so non-Go hosts (the js/semantics package) can call pkg/semantics without linking CGO themselves.
Command semantics-json exposes internal/jsbridge as a long-running newline-delimited-JSON server on stdin/stdout, so non-Go hosts (the js/semantics package) can call pkg/semantics without linking CGO themselves.
semantics-wasm-smoke command
Stub entry point so `go build ./...` / `go vet ./...` on native platforms don't fail with "build constraints exclude all Go files".
Stub entry point so `go build ./...` / `go vet ./...` on native platforms don't fail with "build constraints exclude all Go files".
source-layout-guard command
Command source-layout-guard fails if any Go file under the module root is named, or declares identifiers named, by position or hash rather than by responsibility (see internal/sourcelayout and ADR-007).
Command source-layout-guard fails if any Go file under the module root is named, or declares identifiers named, by position or hash rather than by responsibility (see internal/sourcelayout and ADR-007).
thinproof-preflight command
Command thinproof-preflight is the no-pull/offline Compose preflight for issue #79's Task 0.3 thin offline proof (see docs/architecture/acceptance-harness.md section 2's binding contract): it checks, via `docker image inspect`, that the two local images deploy/compose/thinproof's docker-compose.yml expects already exist, before any `docker compose up` runs.
Command thinproof-preflight is the no-pull/offline Compose preflight for issue #79's Task 0.3 thin offline proof (see docs/architecture/acceptance-harness.md section 2's binding contract): it checks, via `docker image inspect`, that the two local images deploy/compose/thinproof's docker-compose.yml expects already exist, before any `docker compose up` runs.
thinproof-runner command
Command thinproof-runner is the external test-runner container for issue #79's Task 0.3 thin offline proof: it exercises the fake-GitHub -> pkg/githubingest -> pkg/semantics -> pkg/codesignal path against a fake GitHub service reachable only at FAKE_GITHUB_BASE_URL (e.g.
Command thinproof-runner is the external test-runner container for issue #79's Task 0.3 thin offline proof: it exercises the fake-GitHub -> pkg/githubingest -> pkg/semantics -> pkg/codesignal path against a fake GitHub service reachable only at FAKE_GITHUB_BASE_URL (e.g.
deploy
internal
acceptanceharness
Package acceptanceharness provides the offline acceptance-test guard rails for Feature Zero (GitHub issue #76, epic #73): an ambient-credential scanner that flags leaked-in, CI-style GitHub/AWS credentials before an acceptance suite runs, and a no-egress http.RoundTripper that makes an accidental public network call (e.g.
Package acceptanceharness provides the offline acceptance-test guard rails for Feature Zero (GitHub issue #76, epic #73): an ambient-credential scanner that flags leaked-in, CI-style GitHub/AWS credentials before an acceptance suite runs, and a no-egress http.RoundTripper that makes an accidental public network call (e.g.
acceptanceharness/agentloopharness
Package agentloopharness defines test/harness seams that a later epic's internal/agentloop package will import from its own tests: a scripted model-gateway stand-in (ScriptedGateway) and a recording tool-call broker (RecordingToolRegistry).
Package agentloopharness defines test/harness seams that a later epic's internal/agentloop package will import from its own tests: a scripted model-gateway stand-in (ScriptedGateway) and a recording tool-call broker (RecordingToolRegistry).
acceptanceharness/queueconformance
Package queueconformance defines a black-box behavioral contract for the eventual TaskQueue port described by ADR-006, and a reusable conformance suite (Run) that exercises any Queue implementation against it.
Package queueconformance defines a black-box behavioral contract for the eventual TaskQueue port described by ADR-006, and a reusable conformance suite (Run) that exercises any Queue implementation against it.
acceptanceharness/thinproof
Package thinproof is the shared, data-as-code fixture for GitHub issue #79's Task 0.3 thin offline proof: a single small file, at a fixed owner/repo/ref/path, served by internal/fakegithub and read back through pkg/githubingest's public GitHubFileReader API.
Package thinproof is the shared, data-as-code fixture for GitHub issue #79's Task 0.3 thin offline proof: a single small file, at a fixed owner/repo/ref/path, served by internal/fakegithub and read back through pkg/githubingest's public GitHubFileReader API.
acceptancestyle
Package acceptancestyle mechanically checks that every acceptance_test.go and *_acceptance_test.go imports github.com/onsi/ginkgo/v2 and references a Ginkgo suite/spec API (RunSpecs, Describe, It, …), except an explicit allowlist.
Package acceptancestyle mechanically checks that every acceptance_test.go and *_acceptance_test.go imports github.com/onsi/ginkgo/v2 and references a Ginkgo suite/spec API (RunSpecs, Describe, It, …), except an explicit allowlist.
agentloop
Package agentloop is a bounded tool-call broker over a typed registry (ADR-005).
Package agentloop is a bounded tool-call broker over a typed registry (ADR-005).
authn
Package authn implements Coach-signed JWT issue, validation, jti denylist revocation, HTTP auth middleware, optional GitHub OAuth App login (no scope), and a config-gated test-mint path for protected /v1 routes (ADR-001).
Package authn implements Coach-signed JWT issue, validation, jti denylist revocation, HTTP auth middleware, optional GitHub OAuth App login (no scope), and a config-gated test-mint path for protected /v1 routes (ADR-001).
authz
Package authz implements ADR-003's synchronous, submit-time repository authorization check: a principal may submit a scan of owner/repo only if the Coach GitHub App installation can read the repository and the principal has a GitHub-recognized role in it.
Package authz implements ADR-003's synchronous, submit-time repository authorization check: a principal may submit a scan of owner/repo only if the Coach GitHub App installation can read the repository and the principal has a GitHub-recognized role in it.
coachapi
Package coachapi is the coach platform's job domain: job, finding, and report types; the stable API contract (error codes and envelope); the authenticated Principal; and the JobStore and WorkerJobStore persistence ports.
Package coachapi is the coach platform's job domain: job, finding, and report types; the stable API contract (error codes and envelope); the authenticated Principal; and the JobStore and WorkerJobStore persistence ports.
coachapi/baseline
Package baseline runs one repo_baseline_scan job attempt: it resolves and reads the repository tree (GitHub Contents API, or the operator-configured smoke fixture), analyzes it through agentloop tools into deterministic findings, then judges hidden-mutation and change-cohesion findings with rubric tools, persisting rows through a fenced JobWriter as it goes.
Package baseline runs one repo_baseline_scan job attempt: it resolves and reads the repository tree (GitHub Contents API, or the operator-configured smoke fixture), analyzes it through agentloop tools into deterministic findings, then judges hidden-mutation and change-cohesion findings with rubric tools, persisting rows through a fenced JobWriter as it goes.
coachapi/clock
Package clock is the time source production code depends on, so a test can substitute a controlled one (acceptanceharness.FakeClock) and drive time forward with explicit calls instead of sleeping.
Package clock is the time source production code depends on, so a test can substitute a controlled one (acceptanceharness.FakeClock) and drive time forward with explicit calls instead of sleeping.
coachapi/httpapi
Package httpapi serves POST /v1/jobs, GET /v1/jobs/{id}, and GET /v1/jobs/{id}/report over a coachapi.JobStore, an authz.RepoAuthorizer, and a queue.TaskQueue.
Package httpapi serves POST /v1/jobs, GET /v1/jobs/{id}, and GET /v1/jobs/{id}/report over a coachapi.JobStore, an authz.RepoAuthorizer, and a queue.TaskQueue.
coachapi/queue
Package queue defines the application-owned TaskQueue and EventBus ports required by ADR-006 (docs/architecture/ADR-006-watermill-queue-abstraction.md): coach-api and coach-worker depend only on these interfaces, never on Watermill or a specific broker's types, so the backend (Redis Streams, SQS, ...) can be swapped without touching domain code.
Package queue defines the application-owned TaskQueue and EventBus ports required by ADR-006 (docs/architecture/ADR-006-watermill-queue-abstraction.md): coach-api and coach-worker depend only on these interfaces, never on Watermill or a specific broker's types, so the backend (Redis Streams, SQS, ...) can be swapped without touching domain code.
coachapi/queue/redisstream
Package redisstream implements the internal/coachapi/queue.TaskQueue port (ADR-006, docs/architecture/ADR-006-watermill-queue-abstraction.md) on top of Watermill's Redis Streams pub/sub (github.com/ThreeDotsLabs/watermill-redisstream), for coach's non-AWS / self-hosted deployment target.
Package redisstream implements the internal/coachapi/queue.TaskQueue port (ADR-006, docs/architecture/ADR-006-watermill-queue-abstraction.md) on top of Watermill's Redis Streams pub/sub (github.com/ThreeDotsLabs/watermill-redisstream), for coach's non-AWS / self-hosted deployment target.
coachapi/queue/sqs
Package sqs implements the internal/coachapi/queue.TaskQueue port (ADR-006, "Provider configuration" -> aws-sqs) on top of Amazon SQS.
Package sqs implements the internal/coachapi/queue.TaskQueue port (ADR-006, "Provider configuration" -> aws-sqs) on top of Amazon SQS.
coachapi/store/memory
Package memory is the in-process coachapi.WorkerJobStore used for local development and tests.
Package memory is the in-process coachapi.WorkerJobStore used for local development and tests.
coachapi/store/postgres
Package postgres is the durable coachapi.WorkerJobStore backed by Postgres; its schema is internal/coachapi/migrations.
Package postgres is the durable coachapi.WorkerJobStore backed by Postgres; its schema is internal/coachapi/migrations.
codesignalcli
Package codesignalcli is the scan use case behind `coach codesignal`: it analyzes the selected files of a diff or a repository baseline, hands a validated project policy to its language's project backend (Go or TypeScript), and discloses worktree state the committed report cannot see.
Package codesignalcli is the scan use case behind `coach codesignal`: it analyzes the selected files of a diff or a repository baseline, hands a validated project policy to its language's project backend (Go or TypeScript), and discloses worktree state the committed report cannot see.
codesignalcli/configauthoring
Package configauthoring helps a user produce a project-policy candidate: guided interactive authoring for TypeScript, and non-interactive root suggestion from a committed revision, written create-only.
Package configauthoring helps a user produce a project-policy candidate: guided interactive authoring for TypeScript, and non-interactive root suggestion from a committed revision, written create-only.
codesignalcli/gitrepo
Package gitrepo is the git process adapter behind coach codesignal: revision resolution, changed and tracked file selection, bounded and batched object reads, revision archives, and worktree status.
Package gitrepo is the git process adapter behind coach codesignal: revision resolution, changed and tracked file selection, bounded and batched object reads, revision archives, and worktree status.
codesignalcli/internal/gitfixture
Package gitfixture builds throwaway Git repositories for codesignalcli tests: one initialized repository per test, and one commit per file.
Package gitfixture builds throwaway Git repositories for codesignalcli tests: one initialized repository per test, and one commit per file.
codesignalcli/invocation
Package invocation writes the `coach codesignal` commands that a remediation line asks a user to run, so the check, the compiler setup, the scan and the authoring of a policy name a policy the same way.
Package invocation writes the `coach codesignal` commands that a remediation line asks a user to run, so the check, the compiler setup, the scan and the authoring of a policy name a policy the same way.
codesignalcli/pkgmanager
Package pkgmanager detects which package manager (npm, pnpm, Bun, or yarn) a TypeScript project declares, from the worktree or a committed revision, probes the version on PATH, and rejects configuration that would redirect package resolution.
Package pkgmanager detects which package manager (npm, pnpm, Bun, or yarn) a TypeScript project declares, from the worktree or a committed revision, probes the version on PATH, and rejects configuration that would redirect package resolution.
codesignalcli/policyref
Package policyref is the policy a run reads and who chose it.
Package policyref is the policy a run reads and who chose it.
codesignalcli/projectcheck
Package projectcheck runs `coach codesignal --check-project`: it evaluates the committed policy, project shape, host runtime, compiler, package manager, and dirty worktree, then aggregates them into one readiness result with ordered gaps and next actions.
Package projectcheck runs `coach codesignal --check-project`: it evaluates the committed policy, project shape, host runtime, compiler, package manager, and dirty worktree, then aggregates them into one readiness result with ordered gaps and next actions.
codesignalcli/projectconfig
Package projectconfig owns the project-policy document (project.json): its frozen schema-1 shape, strict decoding and validation, and the bounded read of the committed document at an analyzed revision.
Package projectconfig owns the project-policy document (project.json): its frozen schema-1 shape, strict decoding and validation, and the bounded read of the committed document at an analyzed revision.
codesignalcli/projectreadiness
Package projectreadiness is the --check-project result model: the checks, gaps, warnings, and next actions a readiness run reports, and the gap-code table that fixes each gap's status and remediation kind.
Package projectreadiness is the --check-project result model: the checks, gaps, warnings, and next actions a readiness run reports, and the gap-code table that fixes each gap's status and remediation kind.
codesignalcli/prompt
Package prompt reads answers from an interactive session one line at a time.
Package prompt reads answers from an interactive session one line at a time.
codesignalcli/render
Package render presents CodeSignal reports and project-readiness results as the CLI's text and JSON output.
Package render presents CodeSignal reports and project-readiness results as the CLI's text and JSON output.
codesignalcli/revisionfs
Package revisionfs serves one immutable Git revision as a read-only fs.FS, so project analysis never reads the live worktree.
Package revisionfs serves one immutable Git revision as a read-only fs.FS, so project analysis never reads the live worktree.
codesignalcli/shellword
Package shellword writes text into a command a user will paste into a POSIX shell, and decides whether it can be shown on a terminal at all.
Package shellword writes text into a command a user will paste into a POSIX shell, and decides whether it can be shown on a terminal at all.
codesignalcli/sourcescope
Package sourcescope labels each selected file as production, test-only, excluded, or unknown from the analyzed revision's own Go build graph and tsconfig.json, and filters or tallies files by that label.
Package sourcescope labels each selected file as production, test-only, excluded, or unknown from the analyzed revision's own Go build graph and tsconfig.json, and filters or tallies files by that label.
codesignalcli/subprocess
Package subprocess runs short, bounded probes of host executables (node, mise, package managers) with a wall-time limit and an output cap.
Package subprocess runs short, bounded probes of host executables (node, mise, package managers) with a wall-time limit and an output cap.
codesignalcli/terminal
Package terminal detects whether a file is an interactive controlling terminal, the precondition for every prompt the CLI shows.
Package terminal detects whether a file is an interactive controlling terminal, the precondition for every prompt the CLI shows.
codesignalcli/tssetup
Package tssetup runs the consented TypeScript compiler setup a failed readiness check offers: it builds the menu of verified installation choices, previews the exact frozen command, executes it only after a single explicit confirmation, and rechecks readiness afterwards.
Package tssetup runs the consented TypeScript compiler setup a failed readiness check offers: it builds the menu of verified installation choices, previews the exact frozen command, executes it only after a single explicit confirmation, and rechecks readiness afterwards.
codesignalcli/tstoolchain
Package tstoolchain resolves the host toolchain a TypeScript project scan runs on: the supported Node runtime and the one approved TypeScript compiler, found across the project manifest, project mise, and global mise origins, with mise's own trust gates applied before mise is ever asked.
Package tstoolchain resolves the host toolchain a TypeScript project scan runs on: the supported Node runtime and the one approved TypeScript compiler, found across the project manifest, project mise, and global mise origins, with mise's own trust gates applied before mise is ever asked.
codesignalcli/worktreeoverlay
Package worktreeoverlay serves a committed snapshot with the uncommitted state of chosen working-tree paths laid over it, so project analysis reads what is on disk for exactly those paths and committed bytes for the rest.
Package worktreeoverlay serves a committed snapshot with the uncommitted state of chosen working-tree paths laid over it, so project analysis reads what is on disk for exactly those paths and committed bytes for the rest.
fakegithub
Package fakegithub is a Coach-owned, fixture-driven fake GitHub HTTP service for offline acceptance testing.
Package fakegithub is a Coach-owned, fixture-driven fake GitHub HTTP service for offline acceptance testing.
gitpath
Package gitpath holds git's rules about which paths of a tree it will check out, for every place Coach writes a committed tree to disk.
Package gitpath holds git's rules about which paths of a tree it will check out, for every place Coach writes a committed tree to disk.
jsbridge
Package jsbridge defines the JSON protocol that exposes pkg/semantics to JavaScript/TypeScript consumers, plus the single handler both transport backends (WASM and stdio CLI) call.
Package jsbridge defines the JSON protocol that exposes pkg/semantics to JavaScript/TypeScript consumers, plus the single handler both transport backends (WASM and stdio CLI) call.
modelgateway
Package modelgateway is the sole inference seam for structured judgment: request in → schema-validated response out.
Package modelgateway is the sole inference seam for structured judgment: request in → schema-validated response out.
projectbridge
Package projectbridge defines the JSON protocol between pkg/projectmodel's TypeScript sidecar client (the pkg/projectmodel/internal/tssidecar process adapter) and a pinned local Node/TypeScript sidecar subprocess that produces raw TypeScript/TSX import facts from an immutable snapshot (issue #214).
Package projectbridge defines the JSON protocol between pkg/projectmodel's TypeScript sidecar client (the pkg/projectmodel/internal/tssidecar process adapter) and a pinned local Node/TypeScript sidecar subprocess that produces raw TypeScript/TSX import facts from an immutable snapshot (issue #214).
rubrics
Package rubrics holds versioned LLM-as-judge definitions, prompt assembly, and agent-loop tool adapters for seed rubrics (ADR-005).
Package rubrics holds versioned LLM-as-judge definitions, prompt assembly, and agent-loop tool adapters for seed rubrics (ADR-005).
sourcelayout
Package sourcelayout enforces ADR-007's naming rule: a Go file and the identifiers it declares are named for their responsibility, never for the position they were cut from (main_part2.go, body_mainPart2Test_44) or a generated hash (sigstartRecordingProxyListener39957725).
Package sourcelayout enforces ADR-007's naming rule: a Go file and the identifiers it declares are named for their responsibility, never for the position they were cut from (main_part2.go, body_mainPart2Test_44) or a generated hash (sigstartRecordingProxyListener39957725).
tstestutil
Package tstestutil holds helpers shared by Ginkgo acceptance tests that copy this repository's installed TypeScript compiler into a fixture worktree.
Package tstestutil holds helpers shared by Ginkgo acceptance tests that copy this repository's installed TypeScript compiler into a fixture worktree.
pkg
codesignal
Package codesignal turns pkg/semantics analysis results into prioritized, change-aware coaching signals.
Package codesignal turns pkg/semantics analysis results into prioritized, change-aware coaching signals.
domain
Package domain holds project facts that both the use-case layer (pkg/codesignal) and the adapter that builds them (pkg/projectmodel) are allowed to depend on.
Package domain holds project facts that both the use-case layer (pkg/codesignal) and the adapter that builds them (pkg/projectmodel) are allowed to depend on.
githubingest
Package githubingest reads individual file contents from a GitHub repository via the GitHub Contents API, authenticated as a GitHub App installation.
Package githubingest reads individual file contents from a GitHub repository via the GitHub Contents API, authenticated as a GitHub App installation.
projectmodel
Package projectmodel defines deterministic, offline, whole-repository structural facts about a codebase.
Package projectmodel defines deterministic, offline, whole-repository structural facts about a codebase.
projectmodel/internal/ssaload
Package ssaload is pkg/projectmodel's driven adapter for building Go SSA programs: it writes an fs.FS snapshot to a temporary directory and loads it through golang.org/x/tools/go/packages, which runs the local Go toolchain against those files.
Package ssaload is pkg/projectmodel's driven adapter for building Go SSA programs: it writes an fs.FS snapshot to a temporary directory and loads it through golang.org/x/tools/go/packages, which runs the local Go toolchain against those files.
projectmodel/internal/tssidecar
Package tssidecar runs the pinned Node/TypeScript project sidecar as a child process for one internal/projectbridge request.
Package tssidecar runs the pinned Node/TypeScript project sidecar as a child process for one internal/projectbridge request.
semantics
Package semantics extracts deterministic structural facts from raw source bytes (syntax validity, imports, branching metrics, constructor-like patterns, mutates_input) using Tree-sitter grammars.
Package semantics extracts deterministic structural facts from raw source bytes (syntax validity, imports, branching metrics, constructor-like patterns, mutates_input) using Tree-sitter grammars.
semantics/internal/engine
Package engine defines the narrow tree-sitter surface pkg/semantics relies on.
Package engine defines the narrow tree-sitter surface pkg/semantics relies on.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL