Files
sherlock/docs/conventions.md
T
amacocian 53b0d025f5
Release / release (push) Successful in 24s
Shared infra for installer
2026-06-13 14:25:40 +02:00

4.2 KiB

Conventions

Rules that govern this repo. Anything that becomes load-bearing belongs here, in conventions.md, never in a section appended to another doc.

Repository layout

cmd/                    one subdir per shippable binary; package main only
setup/                  bootstrap installer entry (go run ./setup); not shipped
internal/               every other package; never imported outside this module
internal/installer/     the one install/update implementation (shared by setup + `sherlock update`)
docs/                   one topic per file (see "Docs" below)
VERSION                 release version source of truth (see versioning.md)
README.md               TOC only

No top-level pkg/ until we have an external consumer.

Go

  • Module path: gitea.alexandru.macocian.me/amacocian/sherlock.
  • Target Go toolchain: go 1.25 (pinned via go.mod's go directive; CI installs the matching minor).
  • One package main per cmd/<binary>/. No multiple-main-files trickery.
  • Every other package has a top-of-file Package <name> ... doc comment (in the leading .go source file; we drop standalone doc.go files once a real source file exists).
  • Third-party deps are added with a one-line justification. The current set:
    • github.com/zalando/go-keyring — OS keyring for token persistence.
    • github.com/BurntSushi/toml — parse the operator config (config.toml).
    • github.com/coreos/go-oidc/v3 — OIDC discovery + ID-token verification against Authentik.
    • golang.org/x/oauth2 — auth-code + PKCE + refresh against Authentik's token endpoint.
    • golang.org/x/modsemver for version comparison in self-update.
    • github.com/grafana/mcp-grafana + github.com/mark3labs/mcp-go — upstream Grafana MCP tool set, served in-process by cmd/grafana-mcp.
    • github.com/modelcontextprotocol/go-sdk — MCP server SDK for the gitea/gssh MCPs.
    • github.com/coder/websocket — gssh exec WebSocket client.

Docs

  • README.md is TOC only. One-line description + a bulleted index of docs/*.md.
  • One topic per file under docs/. Never append a new section to an existing doc to cover a new concern; create docs/<new-topic>.md and link it from README.md.
  • Cross-link aggressively: every doc should link to the other docs whose concerns it touches.
  • Mermaid diagrams over images or ASCII art. Diagrams live next to the prose that explains them.

Naming

  • Binaries are kebab-case (gitea-mcp, gssh-mcp).
  • Built-in agent profiles match the agent's canonical CLI name (copilot, claude, aider).
  • Service registry files match the service's canonical name (gitea.toml, grafana.toml).
  • Env vars are <SERVICE>_TOKEN (e.g. GITEA_TOKEN, GSSH_TOKEN).

Extensibility invariants

  • Agent extensibility: adding a new agent CLI is a Go file under internal/agent/ registering itself via init(). See agents.md. The TOML-overlay design was tried and dropped — per-CLI quirks (auth subcommands, flag schemas, MCP config shapes) deserve a real code home.
  • Service extensibility: adding a new downstream service is a TOML drop-in under ~/.config/sherlock/services.d/ + (optionally) a new cmd/<service>-mcp/ binary. Sherlock's own code does not learn about individual services.

Commits

  • Conventional-ish: area: short imperative (e.g. authn: persist client_id in TokenSet, docs: add gssh-integration).
  • One logical change per commit. CI must pass on every commit on main.

CI

  • .gitea/workflows/release.yaml is the single pipeline. On every push + PR it runs gofmt, go vet, errcheck, staticcheck, go test -race, and go build.
  • On push to main only, and only after every gate above passes, a final step reads the root VERSION file and pushes the tag vVERSION if it doesn't already exist. A tag is never created on a red build. Cutting a release is a one-line edit to VERSION. See versioning.md.
  • Sherlock is operator-installed via install.sh (which clones + go installs) and self-updates via sherlock update. No host-deploy pipeline.

Security

  • No secrets in this repo, ever. Not in tests, not in fixtures, not in comments.
  • The operator's Authentik tokens and (Phase 2+) per-service tokens live in the OS keyring. See storage.md.