Turn ten principles into controls, and measure consistency from the log

short · 45 min · Objective 4.2

Task

Convert each responsible-AI principle from the lesson into a control on your own lab app, with a metric, a threshold and an owner. Then measure the ones you can measure today: run a small regression set through the gateway several times and compute, from logs/gateway.jsonl, how often each answer is right and whether repeated runs agree. Finish with a model card, because transparency needs a document and explainability needs something else.

Steps

  1. Create lab/rai-controls.csv with header principle,claim,metric,threshold,owner,evidence,action_on_breach and one row each for fairness, inclusiveness, reliability, safety, consistency, transparency, explainability, privacy, security and accountability. Every threshold contains a number; every owner is a role from your RACI.
  2. Be honest about fairness: this app decides nothing about people, so write the claim and metric you would need if it did, and set inclusiveness as something you can test now, such as the pass rate on questions rephrased informally or in a second language.
  3. Give the app a defined failure behaviour: edit the system prompt so that a question its documents cannot answer gets a fixed phrase, such as NOT IN MY DOCUMENTS.
  4. Create lab/regression.csv with header id,question,expected and at least six rows: four questions answered in your FAQ or policy documents, with expected a short string a correct answer must contain; one informal rephrasing of one of them; and one question outside the documents, whose expected string is the fallback phrase.
  5. Send each question to the gateway three times, exactly as written in the CSV, as a test user of its own, rai-eval: POST $GW/ask (HTTPS on 127.0.0.1:8088 since lesson 13) with a JSON body holding user and question. First add rai-eval to app/users.json with public and internal, so it can read the documents the answers come from, and give it a rate_limits entry such as 30 in gateway/rules.json: eighteen requests is past lesson 10's five in ten minutes, and a refused run would count as a wrong answer. The Verify finds each run in logs/gateway.jsonl by the question inside the record's prompt field, and marks it correct when the record's response field contains the row's expected string.
  6. Run the verify block and copy the measured correct-run counts into the evidence column of the reliability, consistency and safety rows.
  7. Write lab/model-card.md with six level-two headings: ## Intended use, ## Out of scope, ## Data, ## Evaluation results, ## Known limitations, ## Owner. Cite it as the transparency evidence. Explainability needs different evidence: per-answer retrieved_ids in the log, showing which documents an answer drew on.

Verify

cd ~/secai-lab
python - <<'EOF'
import csv, json
rows = list(csv.DictReader(open("lab/rai-controls.csv", encoding="utf-8")))
want = {"fairness", "inclusiveness", "reliability", "safety", "consistency",
        "transparency", "explainability", "privacy", "security", "accountability"}
print("principles missing:", sorted(want - {r["principle"] for r in rows}))
print("no number in threshold:", [r["principle"] for r in rows if not any(c.isdigit() for c in r["threshold"])])
print("no owner:", [r["principle"] for r in rows if not r["owner"]])
ev = {r["principle"]: r["evidence"] for r in rows}
print("transparency and explainability share evidence:", ev.get("transparency") == ev.get("explainability"))
log = [json.loads(l) for l in open("logs/gateway.jsonl", encoding="utf-8") if l.strip()]
for q in csv.DictReader(open("lab/regression.csv", encoding="utf-8")):
    hits = [r for r in log if q["question"] in r["prompt"]]
    ok = sum(q["expected"].lower() in r["response"].lower() for r in hits)
    print(q["id"], len(hits), "runs,", ok, "correct,",
          "consistent" if ok in (0, len(hits)) else "INCONSISTENT")
EOF
grep -c '^## ' lab/model-card.md

No principles missing, empty threshold and owner lists, share evidence: False, every regression id with three or more runs, and six model-card headings. The correct counts are a measurement, not a pass mark: an inconsistent question is a finding to record, not a reason to rerun until it agrees. A question with zero runs means the logged prompt does not contain it verbatim; check how your template inserts the question.

Notes

Matching the question inside the logged prompt works because the gateway logs the prompt as sent, after the template and retrieved chunks were added. If a question passed on two runs and failed on the third, try lowering the runner's randomness setting and rerunning; the lesson's point is that for a policy answer, variation is a defect.

This is an independent study companion for CompTIA SecAI+ CY0-001 and is not produced by or endorsed by CompTIA.