Document Classification: Internal — CHLOM Confidential Owner: CrownThrive, LLC Last Updated: 2025-08-08
This document extends the Algorithm Catalog with pre‑filled algorithm documentation for key codenames and starter code stubs (Rust + Python gRPC) so engineering can begin implementation immediately. Link each implementation back to the relevant Model Card and Proprietary Algorithm Doc entries.
Part I — Pre‑Filled Proprietary Algorithm Docs (by Codename)
A. AegisScore‑LR (Logistic Regression, Calibrated)
Section 1 — Codename: AegisScore‑LR Section 2 — Purpose & Scope: Linear baseline risk scorer for Phase 0; wraps into CE decisioning. Section 3 — Inputs & Outputs
- Inputs: feature_vector(identity, risk_signals, graph_features), sanctions_flag, zk_valid
- Outputs: score[0..1000], band{L/M/H/C}, explanations[top‑k weights] Section 4 — Core Logic (Pseudocode)
p = sigmoid(b0 + Σ wi*xi + w_sanctions*I[sanctions_flag] + w_zk*I[zk_valid])
score = round(1000 * calibrate(p))
band = bucket(score)
Section 5 — KPIs & Performance Targets: ROC‑AUC ≥ 0.74; ECE ≤ 0.04; P95 ≤ 50ms.
Section 6 — Interfaces & API: gRPC RiskModel.Predict
; CE /v1/score/compliance
.
Section 7 — Testing & Validation: unit(params fixed), golden vectors, calibration curves.
Section 8 — Security: redact explanations; rate‑limit per tenant.
Section 9 — Maintenance: semver; deprecate on drift PSI > 0.2.
B. AegisScore‑GBT (Gradient‑Boosted Trees)
Codename: AegisScore‑GBT Purpose: Nonlinear risk model for Phase 1; interpretable via TreeSHAP. Inputs/Outputs: Same as LR; plus TreeSHAP attributions. Pseudocode:
score_raw = Σ_t γ_t * tree_t(x)
score = round(1000 * calibrate(sigmoid(score_raw)))
KPIs: ROC‑AUC ≥ 0.82; P95 ≤ 100ms; SHAP top‑k latency ≤ 20ms. Security: Clip SHAP to whitelist features.
C. GBA‑Prop (Graph Risk Propagation)
Codename: GBA‑Prop Purpose: Spread risk from seed nodes through typed edges. Inputs: Subgraph induced around target nodes; type weights per edge. Outputs: risk[v] ∈ [0,1], path explanations. Pseudocode:
risk = base
for t in 1..T:
for v in V:
agg = Σ_{u∈N(v)} risk[u]*w(edge(u,v))*decay
risk[v] = (1-α)*base[v] + α*agg
KPIs: Convergence ≤ 10 iters; Lift@Top1% ≥ 2×. Security: Cap α, decay; bound neighborhood size.
D. SanctionsMatcher‑Hybrid
Codename: SanctionsMatcher‑Hybrid Purpose: High‑recall fuzzy match for sanctions/PEP. Inputs: name(s), DOB, country, alt spellings. Outputs: match_score ∈ [0,1], candidate list, decision flag. Pseudocode:
score = 0.5*JW(name1,name2) + 0.2*metaphone(name1,name2) + 0.2*I[|dobΔ|≤2y] + 0.1*I[country match]
flag = score ≥ θ
KPIs: Recall ≥ 0.98 @ P≥0.90. Security: Keep provider datasets version‑pinned; no raw PII in logs.
E. IsoForest‑AD (Isolation Forest Anomaly Detection)
Codename: IsoForest‑AD Purpose: Unsupervised anomaly detection for triage streams. Inputs: tabular features; per‑tenant model variants optional. Outputs: anomaly_score ∈ [0,1], top path features. Pseudocode:
forest = fit_isolation_forest(X)
score = 1 - mean(path_length(x))/c(n)
KPIs: Precision@K +15% vs random; P95 ≤ 50ms. Security: Train on sanitized features only.
F. PR‑Fraud (Personalized PageRank Fraud Ranking)
Codename: PR‑Fraud Purpose: Rank proximity to known‑bad seeds. Inputs: graph G(V,E), seeds S, teleport prob β. Outputs: pr[v] ∈ [0,1]. Pseudocode:
r = init
for t in 1..T:
r = (1-β)*A_norm^T * r + β * teleport(S)
KPIs: Top‑K stability; P95 ≤ 150ms (10k nodes). Security: Normalize by edge type; limit degree explosion.
Part II — Starter Code Stubs (Rust + Python gRPC)
These are scaffolds. Do not paste secrets. Wire into CI/CD with signing and SBOM. All code references the OpenAPI and gRPC interfaces defined below.
1. gRPC Proto (Shared)
syntax = "proto3";
package chlom.risk;
message PredictRequest { string entity_id = 1; map<string,double> features = 2; bool sanctions_flag = 3; bool zk_valid = 4; }
message PredictResponse { int32 score = 1; string band = 2; repeated string explanations = 3; }
service RiskModel {
rpc Predict (PredictRequest) returns (PredictResponse);
}
2. Python — Model Server (AegisScore‑LR & IsoForest‑AD)
# app.py
import grpc
from concurrent import futures
from typing import Dict
import numpy as np
from model_pb2 import PredictResponse
import model_pb2_grpc
class RiskModelServicer(model_pb2_grpc.RiskModelServicer):
def __init__(self, lr_params: Dict[str, float]):
self.w = lr_params["weights"]
self.b0 = lr_params["b0"]
def Predict(self, request, context):
x = np.array([request.features.get(k, 0.0) for k in self.w.keys()])
z = self.b0 + float(np.dot(list(self.w.values()), x))
if request.sanctions_flag:
z += -5.0
if request.zk_valid:
z += 0.5
p = 1.0 / (1.0 + np.exp(-z))
score = int(round(1000 * p))
band = "Low" if score < 400 else ("Medium" if score < 700 else ("High" if score < 900 else "Critical"))
return PredictResponse(score=score, band=band, explanations=[])
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=8))
model_pb2_grpc.add_RiskModelServicer_to_server(RiskModelServicer({"weights": {"age": -0.1, "degree": 0.3}, "b0": 0.0}), server)
server.add_insecure_port("[::]:50051")
server.start(); server.wait_for_termination()
if __name__ == "__main__":
serve()
3. Rust — CE Service (Axum) calling gRPC Model Server
// src/main.rs
use axum::{routing::post, Json, Router};
use serde::{Deserialize, Serialize};
use tonic::transport::Channel;
#[derive(Deserialize)]
struct ComplianceReq { entity: Entity, context: serde_json::Value }
#[derive(Deserialize)]
struct Entity { r#type: String, identifiers: serde_json::Value }
#[derive(Serialize)]
struct ComplianceResp { operation_id: String, score: i32, band: String }
mod risk_client { tonic::include_proto!("chlom.risk"); }
use risk_client::{risk_model_client::RiskModelClient, PredictRequest};
#[tokio::main]
async fn main() {
let app = Router::new().route("/v1/score/compliance", post(score_handler));
axum::Server::bind(&"0.0.0.0:8080".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
}
async fn score_handler(Json(_req): Json<ComplianceReq>) -> Json<ComplianceResp> {
let mut client = RiskModelClient::connect("http://model:50051").await.unwrap();
let predict = PredictRequest { entity_id: "e".into(), features: Default::default(), sanctions_flag: false, zk_valid: false };
let res = client.predict(predict).await.unwrap().into_inner();
Json(ComplianceResp { operation_id: uuid::Uuid::new_v4().to_string(), score: res.score, band: res.band })
}
4. Rust — ZKV Client Stub (call verifier service)
pub async fn verify_proof(proof: String, public_inputs: Vec<String>) -> anyhow::Result<bool> {
// TODO: call ZKV service; handle circuit IDs and version pinning
Ok(true)
}
5. Kafka Producer/Consumer (Rust rdkafka) — Skeleton
use rdkafka::{config::ClientConfig, producer::{FutureProducer, FutureRecord}};
pub async fn publish_score(topic: &str, key: &str, payload: &str) {
let producer: FutureProducer = ClientConfig::new()
.set("bootstrap.servers", "kafka:9092")
.create().unwrap();
let _ = producer.send(FutureRecord::to(topic).key(key).payload(payload), std::time::Duration::from_secs(0)).await;
}
6. Dockerfiles (minimal)
Python model server
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 50051
CMD ["python", "app.py"]
Rust CE service
FROM rust:1.79 as builder
WORKDIR /src
COPY . .
RUN cargo build --release
FROM gcr.io/distroless/cc
COPY --from=builder /src/target/release/ce /bin/ce
EXPOSE 8080
CMD ["/bin/ce"]
7. CI/CD Notes (SLSA + Sigstore)
- Build → test → scan → sign; store provenance attestation.
- Block merge on critical SAST/DAST/SCA findings.
- Two‑person promotion to
8. Integration Checklist
- Wire CE
- Add ZKV verification call when
- Emit
- Register model in Model Registry; attach Model Card.
- Add dashboards (latency, error rate, drift alerts).
Part III — How to Extend (Phase 1)
- Drop‑in swap AegisScore‑GBT for LR in the Python model server (or serve both and select via header).
- Add PR‑Fraud and GBA‑Prop features into Feature Store nightly batch; expose as inputs to AegisScore models.
- Optional: move LR to Rust for fully native path; retain Python for heavier models.
End. Align all implementations with Trade‑Secret SOP. Before deploying, complete the Model Card and register versions in the Model Registry.