Fix stale/misattributed facts introduced by the README.md and CHANGELOG.md refresh: correct the CI ADR attribution (ADR-KV-014 for lib's first pipeline, not solely ADR-KV-013), mark the go-swagger untagged-operation bug as already resolved (sf-gate #3, PR #5) instead of still-live, and correct the legacy-branch count (~70, not ~150) and the changelog's overclaimed 'every tag is annotated' statement (only v0.7.5 is). Part of the go-mesh docs refresh: every governed member repo gets a README on the shared mesh template (constellation context, API surface, build/run/test, configuration, release & deploy) and a Keep-a-Changelog CHANGELOG derived from real git tags and history. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|---|---|---|
| .github/workflows | ||
| .vscode | ||
| api | ||
| app | ||
| build | ||
| scripts | ||
| swagger | ||
| .gitignore | ||
| .gitleaks.toml | ||
| CHANGELOG.md | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
| go.mod | ||
| go.sum | ||
README.md
go/lib — Shared Go library for the Keenan Vision service mesh
go/lib (module code.tnxs.net/vernonkeenan/lib) is the shared toolchain
every Go microservice in the Keenan Vision mesh pins in its go.mod. It is
not a service — it ships no server, no Dockerfile, no compose entry — it is
a library app package (InitConfig/InitDB/InitForce, config
accessors, zap logging, Prometheus/CORS middleware, generic marshal
helpers) plus a set of go-swagger–generated typed HTTP clients (api/)
against the sibling services' own swagger specs. Because every mesh service
pins the same module, a lib bump is a constellation-wide rebuild (KV-C6a).
Constellation context
- Toolchain member of the Keenan Vision Go mesh governed by
../../kv-meta/(see../../kv-meta/CONSTELLATION.md§1.3, contract KV-C6). Not a deployed service: no swagger server, no port, no entry in thedocker/kvwebcompose on pluto. - KV-C6a: every mesh service (
auth,cache,crm,members,pdf,plex,render,research,sf-gate,stash) pins an explicitcode.tnxs.net/vernonkeenan/libtag in its owngo.mod; consumption is a per-consumergo.modbump, never automatic. - Distribution is via a world-readable Gitea pull-mirror at
code.tnxs.net/vernonkeenan/lib(andwork/lib), enabling credential-freego get code.tnxs.net/vernonkeenan/lib@vX.Y.Zfrom Docker/CI/dev boxes even though the GitHub repo itself is private (ADR-KV-014). Everything committed here is treated as published, permanently — a gitleaks CI gate makes leaking a secret a build failure, not a review nit. - CI (self-hosted runner,
go build/vet/test ./...+ gitleaks on every push/PR) landed 2026-07-12 aslib's first-ever pipeline (ADR-KV-014) —libwas the only one of the 12 Go-roster repos with no CI at all going into the 2026-07-12 test-harness audit, so this closes out that gap. Thetestjob islib's instance of the mesh-wide unit-test-gate program (ADR-KV-009, amended by ADR-KV-013, which scopeslibas one of its 12 governed repos); thegitleaksjob is ADR-KV-014's public-mirror secret-scan gate, specific tolibbecause it's the one repo mirrored world-readable. api/also acts aslib's own internal client of the mesh:app/auth.go'sCheckAPIUsercallsauth's generated client to validate an API key, solibis simultaneously a library and a consumer of one sibling service.
Package surface
| Path | What it is |
|---|---|
app/root.go |
InitConfig(systemName, level) — loads /etc/vernonkeenan/<systemName>.yaml via viper, one-time init guard |
app/config.go |
Configuration struct + Get*/Is* accessors (DBMS, DSN, log level, metrics, service accounts, workers, email, chunk/cache sizing) |
app/mysql.go |
InitDB() — opens MyDB *sql.DB against the configured MySQL DSN |
app/force.go |
InitForce(serviceAccountName) — opens a Salesforce go-force API connection from a configured service account |
app/auth.go |
CheckAPIUser(token) — validates an API key against auth's generated client |
app/prometheus.go |
SetupPrometheusHandler — CORS + request-count/duration middleware |
app/service-helpers.go |
Pointer helpers (String/Bool/Int64/…), GetFieldsAndValues reflection helper (unit-tested) |
app/user.go, user-helpers.go, tenantuser.go, userrole.go, address.go |
First-class domain structs + swagger marshal/unmarshal helpers shared by consumers |
app/logger/logger.go |
Thin zap.SugaredLogger wrapper (New(level), level constants) |
api/{auth,crm,members,plex,research,sfgate,stash}/ |
go-swagger–generated typed clients + models, one directory per sibling service, regenerated from that service's own spec |
swagger/*.yaml, swagger/defs/, swagger/external/ |
Copies of each sibling service's spec (the KV-C6b spec-copy problem — no sync mechanism besides make regen), shared component defs, and host/path-rewritten copies for external doc publishing; also carries legacy vendored Kazoo/Clerk specs from lib's pre-mesh history |
Build, run, test
go build ./...
go vet ./...
go test ./... # table-driven unit tests today: app/service-helpers.go pure helpers
make install-swagger # install the pinned go-swagger CLI (SWAGGER_VERSION in Makefile)
make regen # aka `make swagger` — regenerate api/ from sibling specs
make release VERSION=vX.Y.Z
make release-dry-run VERSION=vX.Y.Z
go test ./... is CI-gating on every push and PR (ADR-KV-009/013), same as
the rest of the mesh; lib is a library so there is nothing to "run."
make regen requires the sibling repos auth, crm, stash, sf-gate,
research, members, plex cloned adjacently — it reads each one's
swagger/<service>-vernonkeenan.yaml, copies it into ./swagger and
./swagger/external, and regenerates every client under api/, rewriting
the external specs' scheme/host/path the same way the old make swagger
ritual did. It fails fast, before touching anything, if any sibling spec is
missing. Review git status/git diff, commit, open a PR, and merge it to
main like any other change — client regen is never bundled into the
release step; make regen runs a non-fatal go build ./... at the end as
an early warning, but the real gate is CI on that PR.
Known gap (resolved for the current spec set, but can recur): if any
sibling spec has an operation with no top-level tags:, go-swagger routes
it into a fallback operations package whose import path in
<name>_client/<name>_client.go doesn't respect --client-package —
reproduced across go-swagger v0.33.2 through v0.35.0 while building this
tooling. The one instance found, sf-gate-vernonkeenan.yaml's PUT /researchprojectservices (no tags:), was fixed at the source (sf-gate
#3 added the missing tags: entry) and regenerated clean in the v0.7.5
feat/regen-clients-processor-token PR — api/sfgate has no fallback
operations package today. If a future sibling spec change reintroduces an
untagged operation, make regen's non-fatal go build ./... step will
fail with this same signature; fix it at the source (add a tags: entry in
that service's spec) rather than hand-patching generated code, since the
next regen would just reintroduce it.
Configuration
lib reads no config file of its own. app.InitConfig(systemName, level)
loads config on behalf of the calling service: viper reads
/etc/vernonkeenan/<systemName>.yaml (YAML), with environment-variable
overrides via prefix VERNONKEENAN_ (. replaced by _ in key names),
unmarshalled into app.Configuration — AppName, BackendID,
DBMS/DBMSHost/DBMSName/DBMSUsername/DBMSPassword, DSN,
Environment, LogLevel, GelfURI, Metrics (address/enabled),
ServiceAccounts (a map of external-system credentials, e.g. the auth
service account CheckAPIUser reads its own API key from), Workers,
Email, CacheSizes/Chunks. The concrete /etc/vernonkeenan/<name>.yaml
file lives on each deploy host, not in this repo — see the calling
service's own README for its file name and required keys.
Versioning & pinning contract (KV-C6a)
-
Module:
code.tnxs.net/vernonkeenan/lib, fetched via the Gitea anonymous mirror (not GitHub directly — the GitHub repo is private). -
Pin, don't float: every consumer pins an explicit
vX.Y.Ztag in itsgo.mod. Bumping the pin is a normal PR in the consumer repo; there is no auto-bump mechanism. -
Release is one command:
make release VERSION=vX.Y.Z(scripts/release.sh) from a cleanmaincheckout that matchesorigin/main:- Validates
VERSIONisvMAJOR.MINOR.PATCHand strictly greater than the latest existing tag. - Requires you're on
main, the tree is clean, and localmainmatchesorigin/main(no local-only commits). - Runs
go build ./...andgo vet ./...as a last sanity check. - Creates an annotated tag at HEAD, pushes it, and runs
gh release createwith generated notes. - POSTs to the Gitea mirror-sync API for
vernonkeenan/libandwork/lib(skipped with a warning ifGITEA_TOKENis unset — there is no existing Gitea/tnxs token variable defined anywhere on this workstation today;GITEA_TOKENis a new name, not a rename of something already in use).
make release-dry-run VERSION=vX.Y.Zruns steps 1-3 and prints what steps 4-5 would do, without tagging, pushing, publishing, or syncing anything. - Validates
-
A
libbump is constellation-wide: any breaking change toapp.Configuration,InitConfig/InitDB/InitForce, or a generated client's shape ripples to every pinned service on its nextgo.modbump. -
Branch-per-version is retired (ADR-KV-014, 2026-07-12):
libmoved to main +v*tags, replacing the old three-web-UI-plus-CLI manual release ritual. ~70 legacyvX.Y.Zbranches (one per pre-migration release;git branch --list 'v*') remain in the repo as historical artifacts of the old convention, not the active release mechanism. -
Prerequisites for a release: the sibling repos (for
make regen) cloned adjacently;ghauthenticated with push access tovernonkeenan/lib;GITEA_TOKENexported for the mirror-sync step (optional — see above).
Release & deploy
main + PR flow: land changes on main via PR (CI runs build/vet/test +
gitleaks on the PR and on push to main), then cut a release with make release VERSION=vX.Y.Z, which tags main, publishes a GitHub release, and
triggers the Gitea mirror-sync. Unlike the deployed mesh services, lib has
no Dockerfile, no container image, and no deploy step — it is never
built into hub.tnxs.net and never rolled out via the docker/kvweb
compose on pluto. "Release" means "a new tag other repos can pin," full
stop; downstream rollout happens when each consumer bumps its own go.mod
line for code.tnxs.net/vernonkeenan/lib to the new tag and goes through
its own release/deploy path.