Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / cmd/tag-missions/main.go |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 1e9249840a4302ec82e123b9c9cb6f75badea3e4 |
| Branch | master |
| Path or archive member | cmd/tag-missions/main.go |
| Original SHA-256 | 6041d3a59de8970019f3484b589acf875bd89f5449fa3789dd9050192805f20e |
| Git blob SHA | 8e2fae7e8a58356ca468a115ef97bfb670600596 |
| Reading-copy SHA-256 | 6041d3a59de8970019f3484b589acf875bd89f5449fa3789dd9050192805f20e |
Every recorded occurrence
These 27 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 / cmd/tag-missions/main.go | master | 1e9249840a4302ec82e123b9c9cb6f75badea3e4 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | feature/aioe-upgrade | 2178e7298d0e5d9af83afa12402fd587f0ba6ed8 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | m5-price-to-win | 41000ad30fff4129fdaf5ec84e15ba14c27d4890 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | collision-deconfliction | 4ee5a09972608ed89f8377c6665542d5f450f0a6 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | ws7-federal-signal | 6a9f6ce9cfb13345ffb47770d4960e7c2d9c17c2 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | graphrag-foundation | b0ddeb9f633fd138d09309d1a17b7d13bc3a67f7 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | time-to-fill-survival | b66e1e505863d4f17741a4b9ede73509e45bd6c6 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | mag-substrate | b82c7100a492dec67dfd1eda6b3f53def859be35 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | capture-readiness | bae6af7cb2997e819174a9e9cfff5e16067a1975 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | ws8-teaching-loop | c823f0fb6bb2aba0f39001eb6de96f4000d9321f | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | phase2-connectors | e038d4c687aec16f8bd9bc4d907eea14d91f8704 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | presentation-readiness | eb574acaa29d71ce4d0f852572e87c275c79fdb7 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | ws9-bench-ingestion | f585a9ef32fa554663ce1fba9a414a54b6e49cf0 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | vendor-intelligence | fe9796a19c261951d3f2565206c0c1b5ac294465 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | collision-deconfliction | 4ee5a09972608ed89f8377c6665542d5f450f0a6 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | m5-price-to-win | 41000ad30fff4129fdaf5ec84e15ba14c27d4890 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | master | 1e9249840a4302ec82e123b9c9cb6f75badea3e4 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | ws8-teaching-loop | c823f0fb6bb2aba0f39001eb6de96f4000d9321f | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | mag-substrate | b82c7100a492dec67dfd1eda6b3f53def859be35 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | time-to-fill-survival | b66e1e505863d4f17741a4b9ede73509e45bd6c6 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | graphrag-foundation | b0ddeb9f633fd138d09309d1a17b7d13bc3a67f7 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | ws9-bench-ingestion | f585a9ef32fa554663ce1fba9a414a54b6e49cf0 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | presentation-readiness | eb574acaa29d71ce4d0f852572e87c275c79fdb7 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | ws7-federal-signal | 6a9f6ce9cfb13345ffb47770d4960e7c2d9c17c2 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | phase2-connectors | e038d4c687aec16f8bd9bc4d907eea14d91f8704 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | feature/aioe-upgrade | 2178e7298d0e5d9af83afa12402fd587f0ba6ed8 | Open original |
| Janady13/missionmatch / cmd/tag-missions/main.go | capture-readiness | bae6af7cb2997e819174a9e9cfff5e16067a1975 | Open original |
Recovered source transcript
Download complete source text ↓162 lines · 6.9 KB
// Command tag-missions runs the WS7 Phase 5a tenant mission tagging backfill. For each organization it
// classifies that tenant's candidates (headline plus skill names) and requirements (title plus labor
// category plus required skill names) with the pure deterministic missionclass classifier, and upserts
// structured mission tags into candidate_mission_tags and requirement_mission_tags. Those tags are the
// structured signal the Phase 5 retrieval upgrade and the Phase 6 Command Center read, replacing the WS6
// text only mission filter. It is a one shot job and a cron candidate like staffing-proactive-sync, and it
// is idempotent and safe to rerun: every upsert refreshes in place rather than duplicating.
//
// Mission tags are reference data, NEVER a scoring input, and the pass never reaches the eeo schema. The
// classifier is the SAME one the global federalsignal pass uses, so a tenant's SIGINT analyst gets a SIGINT
// tag from its headline and a COMSEC tag from a COMSEC skill; the curated WS2 alias layer adds synonyms
// beyond a literal keyword.
//
// It lists organization ids and reads the global alias pairs through the migrator role (the alias tables
// are global reference data). Every TAG WRITE, and the candidate and requirement reads it classifies, run
// through the NOBYPASSRLS application role inside each org's RunInTenantTx, so Postgres Row Level Security
// is exercised on every row and one tenant's tags can never read or write another's. Pass -org to limit the
// run to a single organization id.
//
// Env (server side only): MM_DATABASE_URL (the app DSN, NOBYPASSRLS, required), MM_MIGRATOR_DATABASE_URL
// (the migrator DSN, BYPASSRLS, used ONLY to enumerate org ids and read the global alias pairs; falls back
// to MM_DATABASE_URL).
//
// Build and run FIPS validated: CGO_ENABLED=0 GOFIPS140=v1.0.0 go build, run with GODEBUG=fips140=on.
package main
import (
"context"
"crypto/fips140"
"crypto/pbkdf2"
"crypto/sha256"
"flag"
"log"
"os"
"strings"
"time"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/missionworkforce/missionmatch/internal/modules/federalsignal"
"github.com/missionworkforce/missionmatch/internal/platform/database"
"github.com/missionworkforce/missionmatch/internal/platform/database/dbgen"
"github.com/missionworkforce/missionmatch/internal/platform/security"
"github.com/missionworkforce/missionmatch/internal/platform/tenant"
)
func main() {
orgFlag := flag.String("org", "", "limit the backfill to a single organization id (default: all orgs)")
flag.Parse()
// FIPS self test: derive one PBKDF2 key at the production cost under the active crypto module and fail
// closed if it errors, so a build that dropped the validated module is caught at boot, not mid run. This
// is the same in build FIPS gate the api and missionclass-sync binaries use.
if err := fipsSelfTest(); err != nil {
log.Fatalf("tag-missions: FIPS self test (PBKDF2 HMAC SHA 256) failed: %v", err)
}
log.Printf("tag-missions: fips_enabled=%v module=%s", fips140.Enabled(), fips140.Version())
appDSN := strings.TrimSpace(os.Getenv("MM_DATABASE_URL"))
if appDSN == "" {
log.Fatal("tag-missions: MM_DATABASE_URL (the app DSN) is required")
}
migDSN := firstNonEmpty(os.Getenv("MM_MIGRATOR_DATABASE_URL"), appDSN)
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Minute)
defer cancel()
// App pool: the tenant tag reads and writes run here, under RLS, never the migrator bypass.
appPool, err := database.NewPool(ctx, appDSN)
if err != nil {
log.Fatalf("tag-missions: app pool: %v", err)
}
defer appPool.Close()
// Fail closed unless this is the NOBYPASSRLS app role, so the backfill can never bypass tenant RLS.
if err := database.AssertRole(ctx, appPool, "missionmatch_app"); err != nil {
log.Fatalf("tag-missions: app pool role check: %v", err)
}
appDB := tenant.New(appPool)
// Migrator pool: enumerate org ids and read the global alias pairs ONLY. No tenant rows are written here.
migPool, err := pgxpool.New(ctx, migDSN)
if err != nil {
log.Fatalf("tag-missions: migrator pool: %v", err)
}
defer migPool.Close()
if err := database.AssertMigratorRole(ctx, migPool); err != nil {
log.Fatalf("tag-missions: %v", err)
}
// Build the AliasIndex ONCE from the global alias pairs (read via the migrator) and share it across every
// org, so the alias compile happens one time, not per org. The reader is the same MissionAliasPairs query
// the global pass uses, so both passes classify against an identical curated alias layer.
idx, err := federalsignal.BuildAliasIndex(ctx, federalsignal.NewRepo(migPool))
if err != nil {
log.Fatalf("tag-missions: build alias index: %v", err)
}
orgIDs, err := listOrgs(ctx, migPool, *orgFlag)
if err != nil {
log.Fatalf("tag-missions: list orgs: %v", err)
}
if len(orgIDs) == 0 {
log.Print("tag-missions: no organizations to process")
return
}
svc := federalsignal.NewTenantTagService(federalsignal.NewTenantTagRepo(appDB), idx)
var totalCandTags, totalReqTags int
for _, orgID := range orgIDs {
orgCtx := tenant.WithOrg(ctx, orgID.String())
cRes, cerr := svc.TagCandidatesForOrg(orgCtx)
if cerr != nil {
log.Fatalf("tag-missions: org %s tag candidates: %v", orgID, cerr)
}
rRes, rerr := svc.TagRequirementsForOrg(orgCtx)
if rerr != nil {
log.Fatalf("tag-missions: org %s tag requirements: %v", orgID, rerr)
}
log.Printf("tag-missions: org %s scanned %d candidates wrote %d candidate tags, scanned %d requirements wrote %d requirement tags",
orgID, cRes.CandidatesScanned, cRes.CandidateTags, rRes.RequirementsScanned, rRes.RequirementTags)
totalCandTags += cRes.CandidateTags
totalReqTags += rRes.RequirementTags
}
log.Printf("tag-missions: DONE, %d org(s), wrote %d candidate mission tags and %d requirement mission tags",
len(orgIDs), totalCandTags, totalReqTags)
}
// listOrgs returns the organization ids to process. It reads them through the migrator role (which sees
// every org) so one run covers the cluster; the per org tagging then runs under the app role and RLS. A
// -org value restricts the run to a single org for a targeted backfill.
func listOrgs(ctx context.Context, migPool *pgxpool.Pool, only string) ([]uuid.UUID, error) {
if only != "" {
id, err := uuid.Parse(strings.TrimSpace(only))
if err != nil {
return nil, err
}
return []uuid.UUID{id}, nil
}
return dbgen.New(migPool).ListAllOrganizationIDs(ctx)
}
// fipsSelfTest derives one PBKDF2 key at the production iteration count under the active crypto module. It
// is the in build FIPS gate, identical to the api and missionclass-sync binaries, so this backfill binary
// is held to the same validated crypto posture.
func fipsSelfTest() error {
_, err := pbkdf2.Key(sha256.New, "missionmatch fips self test", []byte("self test salt"), security.PBKDF2Iterations, 32)
return err
}
func firstNonEmpty(vals ...string) string {
for _, v := range vals {
if s := strings.TrimSpace(v); s != "" {
return s
}
}
return ""
}