Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ jobs:
- name: JSON wire-casing gate — camelCase ratchet
run: ./scripts/check-json-casing.sh

- name: Filename-policy gate — no monolith naming outside internal/api
run: ./scripts/check-filename-policy.sh

- name: File-size gate (STRICT — W5.5 bookend, fleet-wide Go + TS red flags)
run: STRICT=1 ./scripts/check-file-size.sh

Expand Down
6 changes: 3 additions & 3 deletions internal/auth/password.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ const (
argon2Version = argon2.Version

// argon2TestMemoryKiB is the reduced Argon2id memory cost used when
// STEM_TEST_MODE is set (8 MiB instead of 64 MiB) so the test suite
// finishes in milliseconds. Production binaries never see this.
argon2TestMemoryKiB = 8 * 1024
// STEM_TEST_MODE is set so the test suite can instantiate many auth
// managers under the race detector. Production binaries never see this.
argon2TestMemoryKiB = 64
)

// Password validation constants.
Expand Down
55 changes: 55 additions & 0 deletions scripts/check-filename-policy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
# check-filename-policy.sh — capability-package file-naming gate.
#
# The flat internal/api package uses filename prefixes (handlers_, jobs_) to
# separate concerns within one large package. Those prefixes are meaningful
# *only* there. Once code is decomposed into a dedicated capability package
# (internal/<cap>/), the package declaration already supplies that context, so
# the prefix becomes stutter: internal/health/handlers_health_api.go re-states
# "health" twice and re-asserts a layer fact the package name already makes.
#
# Best practice in a decomposed package is to name files for their role *within*
# the package (health.go, checks.go, handler.go) — never by re-stating the layer
# (handlers_/jobs_) or the capability the package itself already represents.
# This is not a Go *language* rule (the toolchain accepts these names); it is an
# architecture-consistency rule that keeps the internal/api strangle honest:
# monolith vocabulary stays in the monolith and is dropped on the way out.
#
# This gate fails if any handlers_*.go / jobs_*.go file exists outside
# internal/api, UNLESS the file's own package directory is named for that token
# (e.g. internal/platform/jobs/jobs.go is the eponymous file of package `jobs`,
# and jobs_test.go is its standard test — both idiomatic, not monolith baggage).
# The gate is green on the current tree and only fires when a decomposition
# carries the monolith's grouping prefix forward instead of dropping it.
#
# Run locally: scripts/check-filename-policy.sh
set -euo pipefail

violations=""
while IFS= read -r f; do
[[ -z "$f" ]] && continue
dir=$(basename "$(dirname "$f")") # parent package directory
prefix="${f##*/}"; prefix="${prefix%%_*}" # handlers | jobs
# Allow the eponymous package file/test (dir named for the prefix token).
[[ "$dir" == "$prefix" ]] && continue
violations+="$f"$'\n'
# Scan git-tracked files only — never a raw worktree walk. CI sets GOMODCACHE
# inside the repo (./.cache/go/pkg/mod), so a find(1) sweep would trip on
# third-party handlers_*.go in the module cache (a false positive). git ls-files
# inherently ignores the cache, build artifacts, and anything gitignored.
done < <(git ls-files -- \
':(glob)**/handlers_*.go' ':(glob)**/jobs_*.go' \
':(exclude)internal/api/**' ':(exclude)vendor/**')
violations=$(printf '%s' "$violations" | sed '/^[[:space:]]*$/d' | sort)

if [[ -n "$violations" ]]; then
echo "❌ Filename-policy gate: monolith file-naming prefixes (handlers_/jobs_)"
echo " must not appear outside internal/api. A decomposed capability package"
echo " names files for their role within the package — drop the prefix:"
echo " internal/health/handlers_health_api.go → internal/health/health.go"
echo ""
echo "$violations"
exit 1
fi

echo "✓ Filename-policy gate: no monolith naming prefixes outside internal/api."
Loading