72Saat is an offline-first earthquake-response copilot for Istanbul households. It targets the first 72 hours after a major earthquake, when neighbors and families make the decisions that determine whether people stay reachable, conserve energy, avoid secondary hazards, and coordinate help.
The core design choice is simple: the Gemma 4 model is not the safety oracle. The fine-tuned model helps interpret messy Turkish panic text; a deterministic Python safety kernel writes the user-visible action plan from cited AFAD, Kızılay, INSARAG, IFRC, WHO, KOERI, IBB, JICA, and TBMM guidance.
The repo is built around one proof case: T021, a real İzmir/Bayraklı survivor testimony where an earlier model produced harmful trapped-under-rubble advice. The shipped path now detects the trapped state before model inference, bypasses the model, routes to four cited survival cards, and blocks forbidden actions. For T021,
model_calls_made=0,kernel_only_path=true, and the harmful raw advice is no longer reachable.Start here: read the Kaggle writeup, inspect the T021 before/after artifacts, run the kernel notebook, then run the 119-test orchestrator suite. The companion site turns the same evidence into a bilingual household decision panel for Istanbul residents, with district priors and 80 primary-source citations. Every core claim has a file, test, or source trail.
Why this exists at all: the thing that keeps people alive in an earthquake is the building they are standing in. 72Saat is the harm-reduction layer beneath that — not a substitute for it. Full framing in
docs/KAGGLE_WRITEUP.mdunder Why this product should not need to exist.
This is the load-bearing proof in the repo. Same trapped-survivor input. Two architectures.
| BEFORE — raw model | AFTER — kernel-wrapped | |
|---|---|---|
model_calls_made |
1 | 0 |
kernel_only_path |
false | true |
| Output | 4 harmful action_card items judged HARMFUL by Nemotron-3 Super 120B |
4 cited cards synthesized verbatim from authority sources |
| Forbidden-action gate | not run (kernel bypassed for the demo) | clean — no violations |
| Artifact | evals/live_smoke/t021_BEFORE_raw_model_d50v8a.json |
evals/live_smoke/t021_AFTER_kernel_wrapped.json |
Reproduce without model weights:
make t021This runs scripts/reproduce_t021_kernel.py,
which walks the T021 input through the kernel and prints a JSON
payload matching the AFTER artifact's shape. No model weights needed.
The architectural claim — and its enforcement — lives in these files:
services/orchestrator/src/orchestrator/kernel/situation_state_extractor.pyservices/orchestrator/src/orchestrator/kernel/card_router.pyservices/orchestrator/src/orchestrator/kernel/forbidden_action_gate.pyservices/orchestrator/src/orchestrator/agent/safety_wrapped.pyservices/orchestrator/src/orchestrator/routes/agent.pydata/knowledge/situation_state.yamlservices/orchestrator/tests/test_t021_kernel.pyservices/orchestrator/tests/test_safety_wrapped_t021.pyservices/orchestrator/tests/test_agent_api_safety.py
| Layer | Path | What it is |
|---|---|---|
| PWA (the product) | apps/web/ |
React PWA, offline-capable, Turkish-first; uses @72saat/domain deterministic flows; orchestrator API is a separate local demo/integration path |
| Orchestrator + kernel | services/orchestrator/ |
FastAPI + the 3-module deterministic safety kernel + 119 passing tests |
| Training pipeline | training/ |
Unsloth QLoRA pipeline, 4 d50v8 HPO configs, sweep scripts |
| Data — knowledge | data/knowledge/ |
Taxonomy (5 phases × 6 concerns × 14 events) + matrix + runtime ontology |
| Data — cards | data/guidance/ |
136 cited safety cards (13 hand + 46 authoritative + 74 realistic + 3 universal fallback) |
| Data — testimonies | data/scenarios/real_testimony/ |
191 first-person published-journalism survivor accounts (50 hand + 141 crawled) |
| Data — SFT corpus | data/datasets/sft/ |
942-row shipped d50v8a-safe corpus; supplementary d50v9-1 adds cards.v9.1.jsonl |
| Data — district priors | data/priors/districts/ |
Istanbul 39-district risk priors (IBB / JICA sourced) |
| Evaluation | evals/ |
Live-smoke proof artifacts + HPO sweep results + per-eval logs |
| Notebook | notebooks/ |
Kaggle reproducing notebook + metadata + generator |
| Docs | docs/ |
Writeup, model card, architecture, safety-kernel deep dive, audits |
| Artifact | Link | Purpose |
|---|---|---|
| Kaggle writeup | submitted via Kaggle | official submission narrative |
| Kaggle model | umutkeltek/72saat-d50v8a-safe |
shipped model artifact for the notebook + kernel path |
| Supplementary model | umutkeltek/72saat-d50v9-1 |
public d50v9-1 checkpoint for reproducibility; not the shipped demo model |
| Kaggle notebook | umutkeltek/72saat-kernel-demo |
reproduces the T021 kernel path |
| Demo video | docs/DEMO.md |
product walkthrough (YouTube; see Kaggle writeup) |
| Companion site | https://72saat.pages.dev | public evidence panel + 80-source citation registry |
| This repo | the page you're on | source, data, tests, evaluation, reproducibility |
Model weights are published on Kaggle Models, not vendored in this
GitHub repository. The public datasets and evaluation transcripts live
in this repo under data/datasets/ and evals/results/.
Gemma is a trademark of Google LLC. 72Saat is not endorsed by or affiliated with Google.
The deployed companion site, 72saat.pages.dev, is not a second implementation of the app. It is the public evidence panel for the project.
This GitHub repo contains the implementation: the React PWA, FastAPI orchestrator, Gemma 4 fine-tuning pipeline, deterministic safety kernel, testimony archive, cited safety cards, evaluation artifacts, and reproducibility notebook.
The website explains the same system for a public Istanbul audience: seismic risk frame, building-era risk bands, 39-district priors, first-72-hours timeline, T021 before/after model-card proof, authority- source tiers, and the 80-source citation registry.
Use the repo to verify how 72Saat works. Use the companion site to understand the Istanbul-specific evidence and why the product is designed around the first 72 hours.
See docs/WEBSITE.md for the site map and the
repo↔site source-trail table.
docs/KAGGLE_WRITEUP.md — ~2,700-word
authoritative technical writeup.
docs/ARCHITECTURE.md — five-layer overview.
docs/SAFETY_KERNEL.md — load-bearing module
deep dive.
make t021Expected:
model_calls_made=0kernel_only_path=true- four trapped-survival cards matched
(
group_trapped_coordination,voice_conservation_under_rubble,no_unstructured_movement_under_rubble,trapped_self_rescue) - no forbidden-action violations
make test-kernel20 kernel-specific tests across 3 files (9 + 6 + 5).
make testExpected: 119 passed.
make dataThis validates the 191 testimony records, 39 district priors, cited cards,
and the SFT provenance inventory. See
docs/DATA_REPRODUCIBILITY.md.
notebooks/72saat-kernel-demo.ipynb
— self-contained T021 kernel reproduction on Kaggle's infrastructure.
The default run uses the preserved public raw-model failure artifact for
the BEFORE shot and executes the deterministic kernel for the AFTER shot;
live raw-model inference is optional via SAAT72_RUN_MODEL=1 on a
compatible GPU.
data/scenarios/real_testimony/README.md
and docs/TESTIMONY_ARCHIVE.md.
- Card-level:
data/guidance/**/*.json(each card'ssource_refs) - Taxonomy authority tiers:
data/knowledge/taxonomy.yaml - Companion citation registry:
docs/SOURCES.md
Full reproducibility recipes (including the live MLX path on Mac and
the portable CUDA training path) live in
docs/REPRODUCIBILITY.md.
| Field | Value |
|---|---|
| Model | umutkeltek/72saat-d50v8a-safe (QLoRA adapter on Gemma-4 E4B) |
| Method | QLoRA via Unsloth |
| LoRA | r=32, α=32, dropout 0.05 |
| Training | 3 epochs, LR 2e-4, warmup 15, bf16, seed 42 |
| Hardware | Single RTX 4090, ~14 minutes |
| SFT corpus | 942 rows: 350 state + 216 testimony + 350 tools + 26 boundaries |
cards.jsonl |
excluded by design — the architectural fix the T021 audit pointed to |
See docs/MODEL_CARD.md for the full model card
including the variant inventory and
docs/TRAINING.md for the full training pipeline.
Three methods, all disclosed. The full breakdown is in
docs/EVALUATION.md.
| Method | Result |
|---|---|
| 1. Self-scored testimony alignment | d50v8a-safe: 0.514 aggregate / 0.514 blind / 0.958 urgency match |
| 2. Independent LLM-as-judge (Nemotron-3 Super 120B Pass B) | d50v8a-safe: mean Likert 2.83/5, 6 raw harm flags of 24 (worse than d50v7) — zero reach the user post-kernel |
| Submission-day d50v9-1 supplement | 3 independent Pass B runs, 0/24 harmful each; published for comparison, not swapped into the shipped path |
| 3. Forbidden-action gate integration tests | 20 / 20 passing; verbatim-rejection fixture against d50v7's actual T021 output |
| Full orchestrator suite | 119 / 119 passing |
72Saat is a research hackathon submission, not a certified emergency- response system.
- The raw fine-tuned model can still produce harmful advice in some disaster cases; the shipped product path relies on the deterministic safety kernel to prevent those outputs from reaching users.
- The d50v8a-safe raw model scored worse than d50v7 in Nemotron Pass B harmful flags; it ships because the architecture moved action authorship out of the model. Zero of those raw harm flags reach the user post-kernel.
- The evaluation measures alignment with a testimony-derived safety specification, not real-world survival benefit.
- There has been no professional emergency-response validation, AFAD / Kızılay endorsement, or live field test.
- A known training-loop refinement (token-level loss masking via
completion_only_loss=true) was disclosed but not enabled because of a TRL library conflict with the formatting function. Post-hackathon work would revisit this. - Hyperparameters were inherited and lightly swept under deadline constraints, not exhaustively optimized.
- Testimony data is based on published journalism, not direct survivor recruitment.
- District priors and safety cards are decision support, not building-specific or person-specific risk certification.
The full limitations list lives in docs/LIMITATIONS.md.
| Doc | Purpose |
|---|---|
docs/KAGGLE_WRITEUP.md |
Authoritative ~2,700-word technical writeup |
docs/QUICKSTART.md |
Judge navigation — every writeup claim mapped to a file path |
docs/ARCHITECTURE.md |
Five-layer system overview + request lifecycle |
docs/SAFETY_KERNEL.md |
Deep dive on the three kernel modules + wrapper |
docs/MODEL_CARD.md |
Model card + variant inventory + raw-vs-wrapped honesty |
docs/TRAINING.md |
Unsloth QLoRA pipeline + HPO sweep |
docs/EVALUATION.md |
Three eval methods, including the Nemotron Pass B numbers |
docs/DATA_AND_KNOWLEDGE.md |
Taxonomy + cards + district priors |
docs/TESTIMONY_ARCHIVE.md |
191-testimony archive + schema + T021 deep dive |
docs/WEBSITE.md |
Companion site tour + repo↔site source map |
docs/PRODUCT.md |
The PWA's four modes |
docs/DEMO.md |
Demo video + demo artifacts |
docs/REPRODUCIBILITY.md |
Six paths to verify, from zero-setup to full local boot |
docs/LIMITATIONS.md |
Full honest-limitations breakdown |
docs/BUILD_TIMELINE.md |
April→May 2026 iteration arc |
docs/SOURCES.md |
Citation registry (80 primary sources) |
docs/audits/D50V7_DATASET_AUDIT.md |
SFT corpus + loss-mask audit |
docs/audits/HPO_SWEEP_RESULTS.md |
Overnight 4-config HPO sweep findings |
docs/archive/T021_PIVOT_HANDOFF_20260516.md |
Engineering handoff documenting the T021 pivot |
- Code, fine-tuned LoRA adapter, schemas, taxonomy, and curated testimony schema — CC-BY 4.0.
- Citation:
CITATION.cfffor academic citation. - Third-party:
THIRD_PARTY_NOTICES.mdfor Gemma model terms, Unsloth, transformers, MLX, testimony source publishers, and cited authority organizations. - Authors:
AUTHORS.md.
Citation of an organization or source document does not imply endorsement, certification, or review of 72Saat by that organization.