93a8a3b311
---ci--- project: oy phase: 1 milestone: v0.2 status: complete phase_role: execution requirements: covered: [REQ-015, REQ-016, REQ-017, REQ-012] partial: [] ---/ci--- Phase 1 (Orgs+Window foundation) complete. 3 new modules (x/window, x/stand, x/guild) + lexicon meta-test scaffolding (G-004). 143 tests total (53 v0.1 baseline + 90 new), 100% coverage on new packages. Window = fullest primitive (lifecycle Open->Active->Revoked-> Expired, rate-limit, append-only audit log). 9-type Stand enum. Guild Hand-Pass @ 0% fee. G-003 by-ID-string import invariant test green. G-004/G-009 lexicon meta-test + self-test table green. Tagged v0.1.1.
88 lines
3.1 KiB
Go
88 lines
3.1 KiB
Go
// Package lexicon holds the project-wide lexicon firewall (REQ-012).
|
|
//
|
|
// The 9 banned financial terms must never appear in any production or test
|
|
// .go file under x/. This package exposes the banned-terms list and detection
|
|
// helpers; the terms themselves are assembled at runtime from two-character
|
|
// fragments so that the SOURCE of this package does not contain any banned
|
|
// term as a literal substring. This is the standard lexicon-test bootstrapping
|
|
// pattern: the firewall's own code must not trip the firewall.
|
|
//
|
|
// The lexicon firewall is NEW in v0.2 (G-002): v0.1 is lexicon-clean in
|
|
// practice but has zero lexicon tests. The project-wide meta-test in
|
|
// P1-04-02 (lexicon_meta_test.go) is the durable firewall; per-package
|
|
// lexicon assertions in each new module's types_test.go scan the module's
|
|
// production files.
|
|
package lexicon
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
// term is a banned term assembled from two halves so the source file does
|
|
// not contain the literal banned word.
|
|
type term struct {
|
|
a, b string
|
|
}
|
|
|
|
// fragments holds the 9 banned terms as (a, b) halves. Neither half alone
|
|
// is a banned term, and concatenation produces the banned term at runtime.
|
|
var fragments = []term{
|
|
{"ba", "nk"}, // bank
|
|
{"depo", "sit"}, // deposit
|
|
{"intere", "st"}, // interest
|
|
{"yie", "ld"}, // yield
|
|
{"curre", "ncy"}, // currency
|
|
{"dol", "lar"}, // dollar
|
|
{"eu", "ro"}, // euro
|
|
{"acco", "unt"}, // account
|
|
{"savin", "gs"}, // savings
|
|
{"deposito", "r"}, // depositor
|
|
}
|
|
|
|
// BannedTerms returns the banned financial terms (REQ-012). The spec lists
|
|
// 10 terms (often described as "9" in plan docs, counting dollar/euro as a
|
|
// pair): bank, deposit, interest, yield, currency, dollar, euro, account,
|
|
// savings, depositor. The terms are assembled at runtime from fragments so
|
|
// this package's source does not contain any banned term as a literal
|
|
// substring.
|
|
func BannedTerms() []string {
|
|
out := make([]string, len(fragments))
|
|
for i, t := range fragments {
|
|
out[i] = t.a + t.b
|
|
}
|
|
return out
|
|
}
|
|
|
|
// bannedTermRegexes are the compiled word-boundary regexes for the 9 banned
|
|
// terms. Word boundaries prevent false positives like "openyield" matching
|
|
// "yield" or "european" matching "euro" — the firewall bans the words as
|
|
// concepts, not as arbitrary substrings. The regexes are case-insensitive.
|
|
var bannedTermRegexes = func() []*regexp.Regexp {
|
|
terms := BannedTerms()
|
|
out := make([]*regexp.Regexp, len(terms))
|
|
for i, t := range terms {
|
|
out[i] = regexp.MustCompile(`\b` + regexp.QuoteMeta(t) + `\b`)
|
|
}
|
|
return out
|
|
}()
|
|
|
|
// FindBannedTerm returns the first banned term found in s (case-insensitive,
|
|
// word-boundary match) and true, or "" and false if none. Used by the
|
|
// project-wide meta-test (P1-04-02) and the per-package lexicon assertions.
|
|
func FindBannedTerm(s string) (string, bool) {
|
|
lower := strings.ToLower(s)
|
|
terms := BannedTerms()
|
|
for i, re := range bannedTermRegexes {
|
|
if re.MatchString(lower) {
|
|
return terms[i], true
|
|
}
|
|
}
|
|
return "", false
|
|
}
|
|
|
|
// ContainsBannedTerm is an alias for FindBannedTerm kept for compatibility.
|
|
func ContainsBannedTerm(s string) (string, bool) {
|
|
return FindBannedTerm(s)
|
|
}
|