Inspiration
The CORTEX challenge is a stripped down version of a problem nobody has actually solved: keeping a knowledge graph correct as new evidence comes in. It has to update by the right amount, resist weak or fraudulent results, extend itself when something falls outside its model, and never let persuasive text overwrite what it knows. I picked it because it's a reasoning problem with a published rubric instead of a demo you win on polish.
What it does
I implemented ingest(item, view). It's a deterministic policy that reads one experimental result plus a read only belief graph and returns structured deltas. It decides how far to move a claim's confidence, whether the result is an ordinary contradiction or something the graph was never built to represent, whether to hold an extraordinary claim as pending, and when to just not act at all.
The main idea is that whether something is in-model or out-of-model is a geometry question, not a strength question.
Two transitions can show up with basically identical provenance, four independent groups, direct method, strong effect:
- Fibroblast to MesodermalProgenitor moves potency 3 to 2 inside the same lineage. The graph can express that, so it's an ordinary contradiction. Revise the claim and scope it.
- Fibroblast to Neuron stays at potency 3 but crosses lineage in one step. Not expressible on any modeled axis, so propose a new regime and leave the claim it looks like it contradicts alone.
No amount of extra replication turns one into the other. Any policy that decides OOD from evidence strength gets one of these wrong, which is exactly the near miss trap in the hidden set. Mine resolves both states against the graph and reads potency_level and lineage_identity off them.
How I built it
Five parts, all stdlib, no LLM calls, fully deterministic:
- Provenance normalization. One strength score built from independent groups, replication count, method directness, effect strength, and method class. The field types are mixed, replication_count shows up as 1 or as "many", so everything gets normalized through one place. Anything missing, malformed, negative, or unrecognized degrades toward weak, never strong. Retraction forces strength to zero.
- Firewall. item.body is untrusted. It only gets used to whitelist match tokens that already exist as graph entities or claim ids. Numbers, confidence values, and provenance inflated in prose never get read. Magnitude comes purely from structured provenance, so a body claiming "replicated across 50 labs" with thin structured evidence gets held pending instead of applied.
- Structural OOD. Potency change means in-model. Same potency, different lineage means regime. A property listed under axes_excluded means axis. All of that gets decided before strength is considered.
- Calibrated revision. Bounded log odds moves kept under the API cap. Every applied contradiction emits set_scope alongside revise_confidence, so a belief gets narrowed instead of deleted.
- Pending lifecycle. Extraordinary claims on thin provenance get held under a deterministic id rebuilt from the graph, so the module carries no state between items. A well powered non replication or a structured retraction retires only the note that's actually tied to it.
Challenges I ran into
The six practice items ship with a public answer key, which makes it really easy to pass them and learn nothing. So I wrote my own 19 case adversarial suite and went after my own policy with it: politely phrased injections, instructions split across sentences, retractions showing up several items later, near miss pairs with matched provenance, malformed provenance, contradictions arriving twice.
It found real bugs. The worst one was a well powered failure to reproduce falling through into the contradiction branch and driving the underlying claim down by half, when it should have just retired the pending note and left the claim alone. So the direction was inverted on a behaviour that's actually scored.
I also had a path that dropped pending notes when the body said stuff like "failed to replicate". It worked and it passed tests, and I deleted it anyway, because it let prose influence a drop_claim and that's the exact boundary this challenge exists to defend. That resolution is now driven by structured retraction status and supersession by a real result.
A hostile review pass after that found entity resolution completely fell apart under paraphrase. Five of six behaviours disappeared when I reworded the bodies but kept the provenance identical. Resolution is now case insensitive, tries multiple candidate spans, and falls back to the umbrella claim instead of silently no-oping.
Accomplishments that I'm proud of
Firewall gate passes, all six practice items pass, and the 19 case adversarial suite passes with OOD false positives at zero after I broadened recall. Getting recall up without quietly bleeding precision was the thing I was most worried about breaking.
More than the numbers though, deleting my own working shortcut because it violated the principle, instead of keeping it because it passed the tests.
What I learned
The firewall isn't a filter you bolt on, it's a property of where you let information flow. The framework already guarantees writes go through validated deltas. The half it can't enforce is whether my code decided to emit a delta because of something it read in untrusted prose. Passing the gate isn't about pattern matching injections, it's about never having a code path where body content reaches a mutation decision at all.
Also that a published rubric is a gift. I knew the four scored axes from minute one and could build straight at them.
What's next
DESIGN.md ships with an honest limitations section instead of pretending this is solved. Resolution is still lexical so heavy paraphrase can mis target. Regime vs axis for identity preserving change is a judgement call I'm not certain on. Pending ids are claim level rather than report level, so two thin reports on the same claim end up sharing a slot. CORTEX said nobody solves this in a weekend and I didn't. What I've got is the right structure and I think the right instincts.
Built With
- bayesian-inference
- knowledge-graphs
- probabilistic-reasoning
- prompt-injection-defense
- python
Log in or sign up for Devpost to join the conversation.