Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / internal/modules/ai/safety.go |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 4b8e7ce594c068621867f9c9deed0ec64ae6c553 |
| Branch | ws3-clearance |
| Path or archive member | internal/modules/ai/safety.go |
| Original SHA-256 | 77dcef3e08a8833addb918566748f14a7e4db7bee56204bf7d062b72f6e67b5d |
| Git blob SHA | e277bfda8efaf07d467060402298b572bb00795b |
| Reading-copy SHA-256 | 77dcef3e08a8833addb918566748f14a7e4db7bee56204bf7d062b72f6e67b5d |
Every recorded occurrence
These 21 records contain identical original source bytes. Their paths and revisions remain part of the archive.
| Original record | Branch or archive | Revision / identifier | Original location |
|---|---|---|---|
| Janady13/missionmatch / internal/modules/ai/safety.go | ws3-clearance | 4b8e7ce594c068621867f9c9deed0ec64ae6c553 | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | ws7-federal-signal | 6a9f6ce9cfb13345ffb47770d4960e7c2d9c17c2 | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | ws6-retrieval | 6c56e29231ec05735927fa265c97d517499dfeaf | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | per-tenant-routing | 9bde0f9a74b89d01980fa658e5253acda7528d0c | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | ai-brain-live | aac32fc49c878cc5bca099459307611562d0bac1 | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | ws1-ontology-sync | b596f449a32a1016fbd403c36505cc00a1ac9ee6 | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | deploy-and-ops | bdacd9d0b4d5998d25fc74bf4007f4c3ec538c7a | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | ws8-teaching-loop | c823f0fb6bb2aba0f39001eb6de96f4000d9321f | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | phase2-eval-fairness | d361af254701975fe239927656ababb56374655e | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | ws2-alias-relationship | e4dada4601c6eb101830f9d223a9655dfa120616 | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | ws9-bench-ingestion | f585a9ef32fa554663ce1fba9a414a54b6e49cf0 | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | per-tenant-routing | 9bde0f9a74b89d01980fa658e5253acda7528d0c | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | ws6-retrieval | 6c56e29231ec05735927fa265c97d517499dfeaf | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | ws1-ontology-sync | b596f449a32a1016fbd403c36505cc00a1ac9ee6 | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | ws8-teaching-loop | c823f0fb6bb2aba0f39001eb6de96f4000d9321f | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | ws3-clearance | 4b8e7ce594c068621867f9c9deed0ec64ae6c553 | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | phase2-eval-fairness | d361af254701975fe239927656ababb56374655e | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | deploy-and-ops | bdacd9d0b4d5998d25fc74bf4007f4c3ec538c7a | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | ws2-alias-relationship | e4dada4601c6eb101830f9d223a9655dfa120616 | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | ws7-federal-signal | 6a9f6ce9cfb13345ffb47770d4960e7c2d9c17c2 | Open original |
| Janady13/missionmatch / internal/modules/ai/safety.go | ai-brain-live | aac32fc49c878cc5bca099459307611562d0bac1 | Open original |
Recovered source transcript
Download complete source text ↓136 lines · 6.7 KB
// Package ai is the augmented generation layer that sits ON TOP of the deterministic engine, never
// around it. It composes the augmented generation family (RAG over tenant documents, TAG over the tenant
// database of record, KAG over clearance and skills, GraphRAG over awards and opportunities, CAG over
// the stable public rules), routes each question to the cheapest sufficient strategy, and runs a
// faithfulness gate before any answer ships. It enforces, by construction, the platform's hard
// boundaries:
//
// - EEO isolation is absolute. NO AI path may read, index, reference, or name the eeo schema. The
// guards in this file refuse any SQL that mentions it, and a test walks every file in this package
// and fails if the word ever appears outside a prohibition comment.
// - The deterministic engine is the floor. The AI layer reads engine outputs and tenant data and
// narrates; it never recomputes a score or routes around engine.ScoreCandidate.
// - Reads are read only, parameterized, RLS scoped, and table allowlisted. The TAG layer chooses from
// a curated set of safe query intents, never free form SQL, the injection resistant pattern.
// - Every AI action emits an append only AEDT audit event.
package ai
import (
"errors"
"regexp"
"strings"
)
// ErrEEOForbidden is returned when any AI path references the segregated EEO schema. It is a hard,
// non recoverable refusal: demographics must never reach a model, an index, a graph, or a generated query.
var ErrEEOForbidden = errors.New("ai: the eeo schema is forbidden to every AI path")
// ErrNotReadOnly is returned when a TAG query is anything other than a single read.
var ErrNotReadOnly = errors.New("ai: only a single read only statement is allowed")
// eeoMarkerRe matches any reference to the EEO schema, its table, or its demographic columns, in any
// casing. This is the runtime backstop behind the structural separation (sqlc never models eeo).
var eeoMarkerRe = regexp.MustCompile(`(?i)\beeo\b|candidate_demographics|race_ethnicity|veteran_status|disability_status`)
// mutatingRe matches any statement that is not a pure read. The TAG layer is read only.
var mutatingRe = regexp.MustCompile(`(?i)\b(insert|update|delete|drop|alter|create|truncate|grant|revoke|copy|merge|call|do|vacuum|comment|reindex|set|reset|begin|commit|rollback)\b`)
// ForbidEEO refuses any text (a generated query, a prompt, a retrieved chunk, a memory record) that
// references the EEO schema. Every AI code path that touches SQL or model context calls this; the test
// suite proves no path can skip it.
func ForbidEEO(text string) error {
if eeoMarkerRe.MatchString(text) {
return ErrEEOForbidden
}
return nil
}
// protectedAttrRe matches a natural language reference to a protected attribute or a close proxy. It is the
// NL layer above the schema guard ForbidEEO: ForbidEEO blocks a query or prompt that NAMES the eeo schema,
// this catches a question that asks about demographics in plain words ("list candidates by race and
// gender") even though it names no schema object. An AEDT must never group, filter, or rank people by a
// protected attribute, so the brain refuses such a question rather than answering it.
var protectedAttrRe = regexp.MustCompile(`(?i)\b(race|racial|ethnicity|ethnic|gender|disabilit[a-z]+|religion|religious|pregnan[a-z]+|sexual orientation|national origin|marital status|veteran status)\b`)
// MentionsProtectedAttribute reports whether text asks about a protected attribute or a close proxy.
func MentionsProtectedAttribute(text string) bool { return protectedAttrRe.MatchString(text) }
// GuardReadOnlyQuery is the TAG safety gate. A query may execute only if it is a single SELECT (or a
// read only CTE leading to SELECT), references no EEO marker, and uses only allowlisted tables. It is the
// last line of defense behind the intent registry (which already constrains queries to a curated set);
// together they make a write or an EEO read impossible from the natural language path.
func GuardReadOnlyQuery(sql string, allowedTables map[string]bool) error {
trimmed := strings.TrimSpace(sql)
if trimmed == "" {
return ErrNotReadOnly
}
// Exactly one statement: a stray semicolon (stacked queries) is refused.
if strings.Count(strings.TrimRight(trimmed, "; \n\t"), ";") > 0 {
return errors.New("ai: stacked statements are not allowed")
}
if err := ForbidEEO(trimmed); err != nil {
return err
}
lower := strings.ToLower(trimmed)
if !strings.HasPrefix(lower, "select") && !strings.HasPrefix(lower, "with") {
return ErrNotReadOnly
}
// No mutating keyword may appear anywhere (a WITH ... that hides an INSERT, for example).
if mutatingRe.MatchString(lower) {
return ErrNotReadOnly
}
// Every referenced table (FROM/JOIN target) must be in the allowlist OR be a CTE defined in this same
// query (a name introduced by WITH ... AS, which is not a real table).
ctes := cteNames(lower)
for _, tbl := range referencedTables(lower) {
if !allowedTables[tbl] && !ctes[tbl] {
return errors.New("ai: table " + tbl + " is not in the read allowlist")
}
}
return nil
}
var tableRefRe = regexp.MustCompile(`(?i)\b(?:from|join)\s+([a-z_][a-z0-9_]*)`)
var cteNameRe = regexp.MustCompile(`(?i)(?:with|,)\s+([a-z_][a-z0-9_]*)\s+as\s*\(`)
// cteNames returns the names introduced by WITH ... AS in a read query, so the allowlist check does not
// reject a reference to a query local CTE.
func cteNames(lowerSQL string) map[string]bool {
out := map[string]bool{}
for _, m := range cteNameRe.FindAllStringSubmatch(lowerSQL, -1) {
out[m[1]] = true
}
return out
}
// referencedTables extracts the FROM/JOIN table identifiers from a read query (lowercased). It is a
// conservative helper for the allowlist check; the intent registry is the primary control.
func referencedTables(lowerSQL string) []string {
var out []string
for _, m := range tableRefRe.FindAllStringSubmatch(lowerSQL, -1) {
out = append(out, m[1])
}
return out
}
// ReadAllowlist is the set of tables the TAG layer may read. It is deliberately a curated subset of the
// public schema and contains NO eeo table, NO auth secret table, and NO demographic column source.
// Changing it is a security decision.
var ReadAllowlist = map[string]bool{
"candidates": true,
"candidate_skills": true,
"candidate_certifications": true,
"candidate_customer_experience": true,
"requirements": true,
"required_skills": true,
"opportunities": true,
"opportunity_records": true,
"slates": true,
"slate_members": true,
"candidate_evaluations": true,
"skills": true,
"sam_opportunities": true,
"usaspending_awards": true,
"bls_wages": true,
}