diff --git a/CLAUDE.md b/CLAUDE.md index 7567e93..7e87b8f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,7 +7,7 @@ The private Go module every Vantage service imports. Extracted from the vantage-shared/ ├── grpc/pb/ # the agent↔control-plane wire types, hand-written ├── grpc/codec/ # the JSON codec they travel over -├── proto/vantage/v1/ # vantage.proto — documentation for the above +├── proto/vantage/v1/ # vantage.proto - documentation for the above ├── mail/ # the one email system: transport + templates ├── license/ # payload, sign, verify, trusted keys, plans ├── models/ # Instance, User, Settings @@ -18,7 +18,7 @@ vantage-shared/ └── cmd/lkctl/ # issue and inspect licences by hand ``` -Module path is `gitea.hostxtra.co.uk/vantage/vantage-shared` — **lowercase +Module path is `gitea.hostxtra.co.uk/vantage/vantage-shared` - **lowercase `vantage`**, though the Gitea org is canonically `Vantage`. Gitea serves both spellings; Go module paths are case-sensitive strings, and two spellings would cache as two modules. Keep the lowercase one. @@ -46,7 +46,7 @@ v0.2.0`. Consumers pin exact versions. `grpc/codec`. Nothing generates them, and `vantage.proto` is not compiled by any build. It is the readable statement of the wire contract, and it lives in the same repository as the Go types precisely so that a message added to one can be -added to the other **in the same commit** — that co-location is the only thing +added to the other **in the same commit** - that co-location is the only thing enforcing the match, so do not split them again. There used to be two copies of `pb`, in the agent and the server, and they had @@ -57,7 +57,7 @@ sides. The agent links the server half as dead code, which the linker drops. **A wire change lands in three steps, in this order**: release this module, bump the pin in `vantage/server` (live at the next push to main), bump the pin in `vantage/agent` (live only at the next `agent/v*` tag). The control plane will -be ahead of the fleet in between, which was true before too — it is just written +be ahead of the fleet in between, which was true before too - it is just written down in two `go.mod` files now instead of implied by a shared directory. ## Things that mirror something outside this repository @@ -71,7 +71,7 @@ with a file in another repository: probe finds no ciphertext and reports "this database stores no ciphertext yet", so the one gate that catches what a key fingerprint cannot becomes a no-op. `settings` is deliberately in neither that map nor - `CiphertextCollections()` — its ESO read token is a SHA-256 hash, not + `CiphertextCollections()` - its ESO read token is a SHA-256 hash, not ciphertext. - **`mail/templates/layout.html.tmpl`** carries the control plane's dark theme values as **literal hex**. Email clients support neither `var()` nor a @@ -81,8 +81,12 @@ with a file in another repository: - **`provision`** is the single implementation of the slug rules that both the control plane and Vantage HQ depend on. It is the one place those two repositories must agree on behaviour, which is why it is here rather than - copied — but it now also means a change to it is a release and two pin bumps. + copied - but it now also means a change to it is a release and two pin bumps. `mail/render_test.go` renders every template and fails if one exists that no case covers. The templates are parsed in `init()`, so without that test a mistyped field is a boot-time panic in three services. + +## Writing style + +Never use em dashes (the long dash character) anywhere: code, comments, UI copy, docs, commit messages. Use a plain hyphen ` - `, a comma, a colon, or split the sentence instead. diff --git a/backup/archive.go b/backup/archive.go index 752111b..5a668e7 100644 --- a/backup/archive.go +++ b/backup/archive.go @@ -98,8 +98,8 @@ func indexMember(name string) string { return "indexes/" + name + ".json" } // Reader is an opened archive. // // Open extracts to a temporary directory rather than streaming, because gzip -// offers no random access and the manifest — which carries the checksums every -// other member is judged against — is written last. Verifying before writing a +// offers no random access and the manifest - which carries the checksums every +// other member is judged against - is written last. Verifying before writing a // single document to the target is worth one pass over local disk. This is why // the container image needs a /tmp. type Reader struct { diff --git a/backup/dump.go b/backup/dump.go index 1374d6c..12dd223 100644 --- a/backup/dump.go +++ b/backup/dump.go @@ -148,8 +148,8 @@ func dumpIndexes(ctx context.Context, w *Writer, db *mongo.Database, name string defer cur.Close(ctx) // The specs are read as raw BSON and re-encoded as extended JSON, one - // element per index, so key order and every option the server reported — - // partialFilterExpression, collation, weights and the rest — survive + // element per index, so key order and every option the server reported - + // partialFilterExpression, collation, weights and the rest - survive // verbatim. Decoding into bson.M would lose compound key order, and // reconstructing an index from a hand-picked set of options would drop // whatever was not picked. diff --git a/backup/restore.go b/backup/restore.go index 31ed217..507f077 100644 --- a/backup/restore.go +++ b/backup/restore.go @@ -72,7 +72,7 @@ func (o RestoreOptions) warn(format string, args ...any) { // The order is fixed and every check that can refuse does so before the first // write: format, checksums (done by Open), key policy, then target inspection. // A restore that has begun writing and then fails leaves a partial database -// which the next run refuses to touch, which is correct — the alternative is a +// which the next run refuses to touch, which is correct - the alternative is a // silent merge, and merging two control planes reconciles nothing. func Restore(ctx context.Context, opt RestoreOptions) (RestoreResult, error) { m := opt.Archive.Manifest() @@ -302,14 +302,14 @@ func splitBSON(raw []byte) (bson.Raw, []byte, error) { // The specs are handed to the createIndexes command exactly as the source // server reported them, rather than reconstructed into a mongo.IndexModel from // a hand-picked set of options. Reconstruction dropped every option nobody had -// thought to pick — partialFilterExpression above all, which this codebase +// thought to pick - partialFilterExpression above all, which this codebase // relies on for partial unique indexes, and which replayed as a full unique // index fails on any real database. It also lost compound key order, which is // significant. // // A unique index that will not build means the restored data violates it, and -// the unique indexes here — (instance_id, email), instance slug, settings -// instance, the ESO token hash — are tenant-isolation properties rather than +// the unique indexes here - (instance_id, email), instance slug, settings +// instance, the ESO token hash - are tenant-isolation properties rather than // optimisations. That aborts. A non-unique index failing is a performance // problem and warns. func replayIndexes(ctx context.Context, opt RestoreOptions, coll *mongo.Collection, name string) (int, error) { diff --git a/backup/restore_test.go b/backup/restore_test.go index 0272d26..82ff60c 100644 --- a/backup/restore_test.go +++ b/backup/restore_test.go @@ -243,7 +243,7 @@ func TestRestoreAbortsWhenAUniqueIndexCannotBuild(t *testing.T) { // Built by hand rather than dumped: two documents that collide on email // alongside an index specification declaring email unique. No live database - // would let those coexist, which is exactly the point — this is the shape + // would let those coexist, which is exactly the point - this is the shape // of a corrupted or hand-edited archive, and restore must refuse rather // than load the rows and leave the index missing. a, err := bson.Marshal(bson.M{"email": "a@example.com"}) @@ -371,8 +371,8 @@ func TestIdIndexIsSkipped(t *testing.T) { } // TestRestoreReplaysPartialUniqueIndex is the regression guard for the defect -// that made a restore abort on any real database: a partial unique index — -// this codebase has them on workflow_steps and settings — replayed as a full +// that made a restore abort on any real database: a partial unique index - +// this codebase has them on workflow_steps and settings - replayed as a full // unique index hits duplicate keys, and a failing unique index is fatal. func TestRestoreReplaysPartialUniqueIndex(t *testing.T) { client, _ := testDB(t) diff --git a/backup/verify.go b/backup/verify.go index 043f603..9c92681 100644 --- a/backup/verify.go +++ b/backup/verify.go @@ -109,8 +109,8 @@ func probe(ctx context.Context, opt VerifyOptions, rep *VerifyReport) error { rep.ProbeDecrypted = true return nil } - // No ciphertext anywhere is an ordinary state — a deployment that has - // stored no secrets, keys or SSO configuration yet — and is not a failure. + // No ciphertext anywhere is an ordinary state - a deployment that has + // stored no secrets, keys or SSO configuration yet - and is not a failure. return nil } @@ -121,13 +121,13 @@ func probe(ctx context.Context, opt VerifyOptions, rep *VerifyReport) error { // This map MIRRORS BY HAND the bson tags in server/internal/models, which this // package cannot import: shared/ is a separate module and models is under // server/internal. It must change in the same commit as any rename of the -// fields below — the same mirrored-constant hazard as web/lib/targets.ts and +// fields below - the same mirrored-constant hazard as web/lib/targets.ts and // services.MaxWorkloadLogLines. The sources are: // -// keys — models/key.go: private_key_enc, passphrase_enc -// secrets — models/secret.go: encrypted_value -// auth_providers — models/auth_provider.go: client_secret_enc -// console_sessions — models/console_session.go: rdp_user_enc, rdp_pass_enc +// keys - models/key.go: private_key_enc, passphrase_enc +// secrets - models/secret.go: encrypted_value +// auth_providers - models/auth_provider.go: client_secret_enc +// console_sessions - models/console_session.go: rdp_user_enc, rdp_pass_enc // // settings is deliberately absent: it holds no ciphertext at all. The ESO read // token is stored as a SHA-256 hash, which no key opens. diff --git a/license/license.go b/license/license.go index 752f24b..8737e1f 100644 --- a/license/license.go +++ b/license/license.go @@ -45,7 +45,7 @@ const ( FeatureMCP = "mcp" ) -// Support levels. Carried for display and enforced by nothing — there is no code +// Support levels. Carried for display and enforced by nothing - there is no code // path anywhere that branches on these, and there must not be one. They are here // so an air-gapped install can tell its operator who to call without reaching // Vantage HQ. @@ -74,7 +74,7 @@ type Limits struct { // FillUnset replaces any zero field with the same field from base. // // This exists for one reason: a licence signed before a field existed decodes it -// as 0, and 0 would read as the most restrictive possible value — no monitors, +// as 0, and 0 would read as the most restrictive possible value - no monitors, // and an audit log trimmed to nothing. A blob we cannot re-sign must not be // allowed to mean that. // diff --git a/license/plans.go b/license/plans.go index 0da8490..a5bcb02 100644 --- a/license/plans.go +++ b/license/plans.go @@ -4,7 +4,7 @@ package license // // This table is the seed. The admin service owns the authoritative copy in its // `plans` collection, and every issued licence snapshots the plan it was cut -// from — so editing a plan never rewrites an existing licence, the same rule as +// from - so editing a plan never rewrites an existing licence, the same rule as // workflow_runs.steps_snapshot. // // Limits here are the BASE allowance: what the tier grants before anything is diff --git a/license/verify.go b/license/verify.go index 5d0c348..16d0127 100644 --- a/license/verify.go +++ b/license/verify.go @@ -97,7 +97,7 @@ func Verify(blob string, opts VerifyOpts) Result { // Parse verifies the signature only, ignoring binding and expiry. // // Used to display a licence and to inspect a blob a customer has emailed in. -// Never use it for enforcement — it does not check who the licence is for. +// Never use it for enforcement - it does not check who the licence is for. func Parse(blob string) (License, error) { parsed, err := lk.LicenseFromB32String(blob) if err != nil { diff --git a/mail/licence.go b/mail/licence.go index cd9da19..b27fa89 100644 --- a/mail/licence.go +++ b/mail/licence.go @@ -5,7 +5,7 @@ import ( "time" ) -// SendLicense delivers the blob inline. It is signed public data, not a secret — +// SendLicense delivers the blob inline. It is signed public data, not a secret - // it is useless on any instance other than the one it names. func (s Sender) SendLicense(to, instanceName, blob string) error { return s.sendTemplate(to, "", "license", struct { diff --git a/mail/render.go b/mail/render.go index 00ccd29..67629f6 100644 --- a/mail/render.go +++ b/mail/render.go @@ -90,7 +90,7 @@ func normaliseText(s string) string { } // funcs are shared by both template flavours. They exist so that a message -// template never formats a date or builds a structure itself — two templates +// template never formats a date or builds a structure itself - two templates // formatting the same date two ways is exactly the drift this package removes. var funcs = map[string]any{ // dict builds a map for the layout's helper templates, which take more diff --git a/mail/sender.go b/mail/sender.go index 5c7e991..1701bc8 100644 --- a/mail/sender.go +++ b/mail/sender.go @@ -3,7 +3,7 @@ // It owns three things that used to exist in three copies: the SMTP // conversation (including the 465-implicit-TLS case that net/smtp gets wrong), // the RFC 5322 envelope, and the rendered look of a Vantage email. Callers see -// only typed Send* methods — nobody outside this package builds a subject line, +// only typed Send* methods - nobody outside this package builds a subject line, // a MIME part or a colour. package mail @@ -24,7 +24,7 @@ import ( // timeout bounds the whole SMTP conversation. Without it a mail server that // accepts the connection and then stalls holds an HTTP request open until the -// client gives up — and admin's signup rollback runs on that request's context. +// client gives up - and admin's signup rollback runs on that request's context. const timeout = 15 * time.Second // Sender is a configured SMTP destination. It is a value, not a singleton: @@ -92,7 +92,7 @@ func (s Sender) sendTemplate(to, replyTo, name string, data any) error { // Port 465 is implicit TLS: the server expects a TLS handshake immediately, so // the connection is wrapped BEFORE any SMTP is spoken. Every other port gets // plaintext then STARTTLS if offered. net/smtp.SendMail only does the latter, -// which is why it fails against a 465 mail server — that bug silently stopped +// which is why it fails against a 465 mail server - that bug silently stopped // every admin email from being delivered once already. func (s Sender) send(m message) error { if !s.Enabled() { diff --git a/mail/templates/invite.html.tmpl b/mail/templates/invite.html.tmpl index 5f292da..bcb4472 100644 --- a/mail/templates/invite.html.tmpl +++ b/mail/templates/invite.html.tmpl @@ -3,5 +3,5 @@ {{template "lead" (printf "You have been invited to join %s on Vantage." .AccountName)}} {{template "p" "Set your own password and finish joining:"}} {{template "button" (dict "label" "Set password and join" "url" .Link)}} -{{template "p" "This link expires in 24 hours. If you were not expecting this, ignore it — nothing happens until you open the link."}} +{{template "p" "This link expires in 24 hours. If you were not expecting this, ignore it - nothing happens until you open the link."}} {{end}} diff --git a/mail/templates/invite.txt.tmpl b/mail/templates/invite.txt.tmpl index fa5a7a9..81559e2 100644 --- a/mail/templates/invite.txt.tmpl +++ b/mail/templates/invite.txt.tmpl @@ -4,5 +4,5 @@ {{template "lead" (printf "You have been invited to join %s on Vantage." .AccountName)}} {{template "p" "Set your own password and finish joining:"}} {{template "button" (dict "label" "Set password and join" "url" .Link)}} -{{template "p" "This link expires in 24 hours. If you were not expecting this, ignore it — nothing happens until you open the link."}} +{{template "p" "This link expires in 24 hours. If you were not expecting this, ignore it - nothing happens until you open the link."}} {{end}} diff --git a/mail/templates/layout.html.tmpl b/mail/templates/layout.html.tmpl index 84d1f83..dc4d7e5 100644 --- a/mail/templates/layout.html.tmpl +++ b/mail/templates/layout.html.tmpl @@ -3,7 +3,7 @@ Every colour in the email system lives in this file and nowhere else, in the same way no component in web/, site/ or adminsite/ carries a hex. The values - are web/app/globals.css's tokens — an email is read before the recipient + are web/app/globals.css's tokens - an email is read before the recipient clicks through to the control plane, so the two should not look like different products. They are written as literal hex here because email clients support neither var() nor a reliable prefers-color-scheme, so the @@ -18,7 +18,7 @@ --ink-3 #71879f --well #04101f Layout is tables and inline styles throughout, which is not a stylistic - choice — it is the only thing Outlook renders predictably. + choice - it is the only thing Outlook renders predictably. A message file overrides "title", "pill" and "body"; the empty defaults below exist so that a message needing no pill does not have to define one. @@ -57,7 +57,7 @@

{{- end -}} -{{- /* well shows machine output — a licence blob, an install ID. Mirrors +{{- /* well shows machine output - a licence blob, an install ID. Mirrors web/'s --well surface, the floor beneath the ground. */ -}} {{- define "well" -}}
{{.}}
diff --git a/mail/templates/layout.txt.tmpl b/mail/templates/layout.txt.tmpl index 2d28593..279e16d 100644 --- a/mail/templates/layout.txt.tmpl +++ b/mail/templates/layout.txt.tmpl @@ -1,7 +1,7 @@ {{- /* The plain-text counterpart of layout.html.tmpl. - It defines the same helper names — p, lead, button, well, note, rows, chip — + It defines the same helper names - p, lead, button, well, note, rows, chip - so a message's txt file reads as the same document as its html one, and a helper added on one side is obvious by its absence on the other. diff --git a/mail/templates/license.html.tmpl b/mail/templates/license.html.tmpl index 4af696a..c2e8b25 100644 --- a/mail/templates/license.html.tmpl +++ b/mail/templates/license.html.tmpl @@ -3,5 +3,5 @@ {{template "lead" (printf "Your licence for %s is below." .InstanceName)}} {{template "p" "Paste it into Settings → Licence on your Vantage install:"}} {{template "well" .Blob}} -{{template "p" "The licence is signed public data, not a secret — it is useless on any instance other than the one it names."}} +{{template "p" "The licence is signed public data, not a secret - it is useless on any instance other than the one it names."}} {{end}} diff --git a/mail/templates/license.txt.tmpl b/mail/templates/license.txt.tmpl index c52b5e6..0c0156f 100644 --- a/mail/templates/license.txt.tmpl +++ b/mail/templates/license.txt.tmpl @@ -4,5 +4,5 @@ {{template "lead" (printf "Your licence for %s is below." .InstanceName)}} {{template "p" "Paste it into Settings > Licence on your Vantage install:"}} {{template "well" .Blob}} -{{template "p" "The licence is signed public data, not a secret — it is useless on any instance other than the one it names."}} +{{template "p" "The licence is signed public data, not a secret - it is useless on any instance other than the one it names."}} {{end}} diff --git a/mail/templates/renewed.html.tmpl b/mail/templates/renewed.html.tmpl index 3f2e0a5..94056a6 100644 --- a/mail/templates/renewed.html.tmpl +++ b/mail/templates/renewed.html.tmpl @@ -2,5 +2,5 @@ {{define "title"}}{{.InstanceName}} is renewed{{end}} {{define "body"}} {{template "lead" (printf "Your Free licence for %s now runs until %s." .InstanceName (date .Expires))}} -{{template "p" "Nothing else changes — your servers, agents and monitors carry on as they were."}} +{{template "p" "Nothing else changes - your servers, agents and monitors carry on as they were."}} {{end}} diff --git a/mail/templates/renewed.txt.tmpl b/mail/templates/renewed.txt.tmpl index bddaad1..7c2d233 100644 --- a/mail/templates/renewed.txt.tmpl +++ b/mail/templates/renewed.txt.tmpl @@ -3,5 +3,5 @@ {{define "title"}}{{.InstanceName}} is renewed{{end}} {{define "body"}} {{template "lead" (printf "Your Free licence for %s now runs until %s." .InstanceName (date .Expires))}} -{{template "p" "Nothing else changes — your servers, agents and monitors carry on as they were."}} +{{template "p" "Nothing else changes - your servers, agents and monitors carry on as they were."}} {{end}} diff --git a/mail/templates/verification.html.tmpl b/mail/templates/verification.html.tmpl index d22c4f2..48b9668 100644 --- a/mail/templates/verification.html.tmpl +++ b/mail/templates/verification.html.tmpl @@ -3,5 +3,5 @@ {{template "lead" "Confirm this address to finish setting up your Vantage account."}} {{template "button" (dict "label" "Confirm email address" "url" .Link)}} {{template "p" (printf "The link works once and expires in %d hours." .TTLHours)}} -{{template "p" "If you did not request this, ignore this email — nothing happens until the link is opened."}} +{{template "p" "If you did not request this, ignore this email - nothing happens until the link is opened."}} {{end}} diff --git a/mail/templates/verification.txt.tmpl b/mail/templates/verification.txt.tmpl index b71edf9..9be7061 100644 --- a/mail/templates/verification.txt.tmpl +++ b/mail/templates/verification.txt.tmpl @@ -4,5 +4,5 @@ {{template "lead" "Confirm this address to finish setting up your Vantage account."}} {{template "button" (dict "label" "Confirm email address" "url" .Link)}} {{template "p" (printf "The link works once and expires in %d hours." .TTLHours)}} -{{template "p" "If you did not request this, ignore this email — nothing happens until the link is opened."}} +{{template "p" "If you did not request this, ignore this email - nothing happens until the link is opened."}} {{end}} diff --git a/mail/templates/vuln_digest.html.tmpl b/mail/templates/vuln_digest.html.tmpl index 9d2679e..d492fe0 100644 --- a/mail/templates/vuln_digest.html.tmpl +++ b/mail/templates/vuln_digest.html.tmpl @@ -6,7 +6,7 @@ (dict "k" "Instance" "v" .InstanceName) (dict "k" "New findings" "v" .Count))}} {{range .Rows}} -{{if .FixedIn}}{{template "well" (printf "%s (%s) — %s on %s, fixed in %s" .CVEID .Severity .PackageName .ServerName .FixedIn)}}{{else}}{{template "well" (printf "%s (%s) — %s on %s, no fix published" .CVEID .Severity .PackageName .ServerName)}}{{end}} +{{if .FixedIn}}{{template "well" (printf "%s (%s) - %s on %s, fixed in %s" .CVEID .Severity .PackageName .ServerName .FixedIn)}}{{else}}{{template "well" (printf "%s (%s) - %s on %s, no fix published" .CVEID .Severity .PackageName .ServerName)}}{{end}} {{end}} {{if .More}}{{template "p" (printf "…and %d more." .More)}}{{end}} {{template "note" (printf "Scanned against a vulnerability database pulled %s ago." .DBAge)}} diff --git a/mail/templates/vuln_digest.txt.tmpl b/mail/templates/vuln_digest.txt.tmpl index 086c803..1c00c08 100644 --- a/mail/templates/vuln_digest.txt.tmpl +++ b/mail/templates/vuln_digest.txt.tmpl @@ -4,7 +4,7 @@ {{define "body"}} {{template "lead" .Summary}} -{{range .Rows}}- {{.CVEID}} ({{.Severity}}) — {{.PackageName}} on {{.ServerName}}{{if .FixedIn}}, fixed in {{.FixedIn}}{{else}}, no fix published{{end}} +{{range .Rows}}- {{.CVEID}} ({{.Severity}}) - {{.PackageName}} on {{.ServerName}}{{if .FixedIn}}, fixed in {{.FixedIn}}{{else}}, no fix published{{end}} {{end}} {{if .More}}...and {{.More}} more.{{end}} diff --git a/mail/vuln.go b/mail/vuln.go index a82215d..318be2b 100644 --- a/mail/vuln.go +++ b/mail/vuln.go @@ -10,7 +10,7 @@ type VulnDigestRow struct { PackageName string ServerName string // FixedIn empty means no vendor fix has been published, which the template - // says explicitly rather than leaving blank — it is a real state, not + // says explicitly rather than leaving blank - it is a real state, not // missing data. FixedIn string } @@ -23,7 +23,7 @@ type VulnDigestRow struct { type VulnDigest struct { InstanceName string // Count is every newly opened finding in the batch, which may exceed - // len(Rows) — Rows is capped and More carries the remainder. + // len(Rows) - Rows is capped and More carries the remainder. Count int TopSeverity string Summary string diff --git a/models/instance.go b/models/instance.go index 9f4c244..73435fe 100644 --- a/models/instance.go +++ b/models/instance.go @@ -13,7 +13,7 @@ import ( // keys, workflows, monitors and secrets. It is the unit a licence attaches to. // // A paying customer may hold several. That grouping is called an Account and -// lives only in the admin control plane — this service never sees it. +// lives only in the admin control plane - this service never sees it. type Instance struct { ID bson.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"` InstanceID string `bson:"instance_id" json:"instance_id"` diff --git a/models/settings.go b/models/settings.go index e9b6dad..438eb96 100644 --- a/models/settings.go +++ b/models/settings.go @@ -31,7 +31,7 @@ type Settings struct { // LocalLoginEnabled is a pointer because it is absent on every settings // document written before this feature existed, and a plain bool would read - // absent as disabled — turning off password login for the entire fleet at + // absent as disabled - turning off password login for the entire fleet at // upgrade. Nil means enabled. LocalLoginEnabled *bool `bson:"local_login_enabled,omitempty" json:"local_login_enabled,omitempty"` @@ -43,7 +43,7 @@ type Settings struct { // APITokenMaxDays caps how long a newly created API token may live. // // A pointer for the same reason the retention fields are: absent must mean - // the default, and the default here is no cap at all — never-expire tokens + // the default, and the default here is no cap at all - never-expire tokens // are allowed until an instance decides otherwise, so an upgrade changes // nothing. Nil or 0 is no cap. A positive value refuses both a longer // expiry and a token with no expiry. diff --git a/models/user.go b/models/user.go index 56aecba..1c6b8b5 100644 --- a/models/user.go +++ b/models/user.go @@ -26,7 +26,7 @@ const ( AuthOIDC = "oidc" // AuthHQ marks a user projected from a Vantage HQ account. Its role, // password and existence are owned by HQ, and the instance API refuses to - // change any of them locally — a role editable in two places is a role with + // change any of them locally - a role editable in two places is a role with // two answers. AuthHQ = "hq" ) diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index c0a2822..4ae108b 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -42,7 +42,7 @@ message SyncResponse { // collect_packages tells the agent whether this instance's licence grants // vulnerability scanning. False means do not collect at all: no gRPC body, - // no document, no storage. The server re-checks on ReportPackages — this + // no document, no storage. The server re-checks on ReportPackages - this // flag is the optimisation, the server check is the boundary. // // Absent reads as false, which is the safe direction: an old server that @@ -246,7 +246,7 @@ message ServerCommand { // Behind an L7 proxy the agent's HTTP/2 connection terminates at the proxy, so // keepalive pings are answered by the proxy whether or not the server behind it // is still there. A pod that dies leaves the agent blocked in Recv on a stream -// that will never produce another message and never error — commands are +// that will never produce another message and never error - commands are // dispatched into it and silently lost. Only traffic that originates at the // server itself distinguishes a live stream from an orphaned one. message PingCmd { diff --git a/provision/instance.go b/provision/instance.go index 96be785..cddb3d4 100644 --- a/provision/instance.go +++ b/provision/instance.go @@ -30,8 +30,8 @@ func CreateInstance(ctx context.Context, db *mongo.Database, name string) (*mode // created before payment and provisioning happens on the confirmed-payment // webhook. Provisioning with the placeholder's own ID keeps the id stable, so // the subscription's custom_data never points at a rewritten row and later -// webhooks still resolve it. If an instance with this ID already exists — a -// webhook retried after a partial provision — it is returned as-is rather than +// webhooks still resolve it. If an instance with this ID already exists - a +// webhook retried after a partial provision - it is returned as-is rather than // duplicated. // // The count-then-insert loop is racy on its own. It is safe only because @@ -92,7 +92,7 @@ var ErrSlugTaken = errors.New("slug taken") // the slug it holds now. // // It returns the current slug unchanged when the name still derives to it, so a -// cosmetic edit — capitalisation, punctuation, a trailing "Ltd." — is not a move +// cosmetic edit - capitalisation, punctuation, a trailing "Ltd." - is not a move // and cannot collide with the instance's own slug. func RenameSlug(name, currentSlug string) (string, error) { base, err := BaseSlug(name) @@ -110,13 +110,13 @@ func RenameSlug(name, currentSlug string) (string, error) { // It returns the name and slug the control plane held BEFORE the write, and // those are the only correct values to unwind with. The caller's own copy of the // instance may be stale, and admin's copy stores slug with `omitempty`, so an -// unwind driven from there can write an empty slug — which either mis-restores +// unwind driven from there can write an empty slug - which either mis-restores // the tenant host or trips the unique index against every other slugless row. // // The count-then-update is racy on its own, and is safe for the same reason // CreateInstanceWithID's loop is: instances.slug carries a unique index, so a // lost race surfaces as a duplicate-key error. Unlike creation there is nothing -// to retry with — the caller asked for one specific name — so it becomes +// to retry with - the caller asked for one specific name - so it becomes // ErrSlugTaken. Do not remove the duplicate-key branch, and do not remove the // index. func RenameInstance(ctx context.Context, db *mongo.Database, instanceID, name string) (inst *models.Instance, prevName, prevSlug string, err error) { diff --git a/provision/slug.go b/provision/slug.go index 9656448..27d2405 100644 --- a/provision/slug.go +++ b/provision/slug.go @@ -2,7 +2,7 @@ // plane and sitesvc. // // These rules used to be duplicated: the control plane owned one copy and -// sitesvc mirrored it by hand. The copies had already drifted — sitesvc retried +// sitesvc mirrored it by hand. The copies had already drifted - sitesvc retried // on a lost slug race while the control plane returned an error. This package // is the single definition; neither service may reimplement any of it. package provision