DEV Community

Cover image for A company brain is not only memory. It also needs judgment.

A company brain is not only memory. It also needs judgment.

Raffaele Zarrelli on July 07, 2026

Six months ago the pain was simple: my AI forgot everything between sessions. So I open-sourced cowork-os, a workspace where the decisions, context...
Collapse
 
daniel_nevoigt_ca2fdc23d5 profile image
Daniel Nevoigt

The judgment-vs-memory cut is the right one — a brain that remembers everything and decides nothing is a very well-organized notebook, yes. And the part you lean on is the load-bearing one: that the judgment layer works from your decisions and constraints, not from a blank prompt.

The one thing I'd set next to it: a brain with complete context still has a retrieval problem. When the real business question lands, the answer hangs on whether the system surfaces the one constraint that matters right now out of everything else — and the constraint that matters often looks least relevant to the happy path. Miss it, and even a complete brain is a blank template again, just with more text around it. So your answer to "start from your real constraint or a blank template" is half "do you have the context" — your write-back solves that — and half "does the system put the right slice in front of the right question."

Those are two separate jobs: the one that guarantees the un-forgettable thing is there (your push-by-state), and the one that pulls out the situational constraint on a concrete question (pull-by-relevance). You're building the layer that decides — the layer that hands it the right constraint is the natural counterpart. "Context is the moat" is true twice over for exactly that reason: owning the context is one thing, having it at hand at the right second is another.

Nice release. The move from "remembers your decisions" to "helps you make the next one" is the right one.

Collapse
 
sarracin0 profile image
Raffaele Zarrelli

You named the split better than I did. Push-by-state and pull-by-relevance really are two jobs, and the write-back only closes the first one.

Here is how cowork-os leans on the pull side without turning it into a pure similarity search. The context is scoped before the question ever lands: each mission or project carries its own active decision set, with a status field (active, superseded, expired) plus a short open-questions list. So the judgment skill does not read the whole brain, it reads the active constraint set for that scope first, and treats superseded records as trail, not as candidates. Narrowing by scope and status does a lot of the "right slice at the right second" work that embedding retrieval would otherwise have to guess.

Where it gets hard is exactly your case: the binding constraint that looks least relevant to the happy path. My current answer is to make status first-class, so a constraint that is still active but quiet stays in the active set even when nobody is thinking about it, instead of decaying out of view.

When you handle pull-by-relevance, do you lean on retrieval scoring, or do you also narrow structurally first, by scope or state, before anything gets ranked?

Collapse
 
daniel_nevoigt_ca2fdc23d5 profile image
Daniel Nevoigt

Both, and the order matters. When the caller knows the scope, recall narrows structurally first: scope and type are exact-match filters that run before anything gets ranked, so a query can say "only this project, only decisions" and similarity never sees the rest. But the default path is ranked, and the structural signals live inside the score rather than in front of it. Every entry carries a recall_when field, declared trigger situations, and it is the highest-weighted field in the ranker, above title and body similarity. So instead of scoping the question, the entry declares its own jurisdiction: surface me when someone is about to do X. That does a lot of the right-slice work from the other side.

For your quiet-constraint case we ended up with two mechanisms rather than set membership. The pin/floor primitive that came out of our earlier thread guarantees presence by state: what is floored is in the context regardless of what the ranker thinks of it, push-by-state at the substrate. And quietness is a derived signal, not a status field: an entry still cited by active decisions but not affirmed or pulled up in weeks is computable, and that discrepancy is exactly what should challenge the question, per the reply I just left for jugeni above.

The part I would poke at in status-first-class: the active set only stays useful while someone supersedes and expires honestly. Who does that in cowork-os, the write-back, a curator pass, or the operator? And when a scope's active set outgrows the context window, do you rank inside it after all?

Thread Thread
 
sarracin0 profile image
Raffaele Zarrelli

Write-back, no separate curator pass. The agent updates status at Memory Update time, task by task, and the operator is in the loop by using the same file, not by gating each write beforehand. That is honest but weaker than it sounds: it works because someone opens decisions.md often enough to catch drift, not because the system enforces honesty on its own.

Second question is the one we have not solved. There is no ranking fallback. Scoping keeps a task from loading the whole tree, but inside one scoped file there is no retrieval layer. If decisions.md in a given folder outgrows what is comfortable to read, today that means a person prunes or splits it by hand. A compaction pass is on the roadmap, not built. Your pin and floor plus rank as fallback is the more honest design once a file actually gets big, ours just has not hit that wall yet because the projects are still small.

Thread Thread
 
daniel_nevoigt_ca2fdc23d5 profile image
Daniel Nevoigt

The honesty is the valuable part, so let me name what it buys and where it runs out. "Works because someone opens the file often enough" is the same disease jugeni diagnosed upstream, attention decay, just relocated to the maintenance side: the only drift detector is the exact organ whose drift needs detecting. Which means the wall you have not hit is closer than the context window. The file does not fail when it outgrows the model, it fails when it outgrows the person, and human attention is the smaller window by far. The failure is not an error, it is the day reading quietly becomes skimming, and skimming feels like reading from the inside. Slow rot again: no cliff, vital sign in range the whole way down.

The cheap instrument you already own is the file's own history. While decisions.md is alive, its edits are a mix: appends, but also status flips, supersessions, prunes. When the mix shifts toward pure append, curation has stopped, whatever the operator believes about their own reading. That is derive-don't-declare for "is anyone still really reading this" — git log answers it, no new machinery needed.

And when the compaction pass does get built, call it what it is: a ranker with commit rights. Deciding what stays in the active file and what becomes trail is retrieval, just executed with an editor instead of a query. Making its criteria explicit on day one keeps the by-feel problem Mike just caught in my confidence formula from reappearing in your compactor.

Collapse
 
jugeni profile image
Mike Czerwinski

Judgment as the missing layer on top of owned context is the exact frame I would build toward too, and I would flag the layer under it that is easy to skip: constraint recognition.

"Diagnose the real constraint before proposing anything" assumes the operator can name the constraint that matters. Most days that is where the whole game is already lost. The stated constraint is what the operator has been thinking about; the binding constraint is often what they stopped noticing weeks ago because it stayed constant while everything around it moved. A strategy architect that trusts the named input inherits the operator's blind spot as the starting point of its diagnosis.

The cheapest guard I have found is asking the brain to disagree with the operator's stated constraint before accepting it. Not a fluff check on the answer, a fluff check on the question. If the past decisions and context in the files show a different binding constraint than the one being named right now, that discrepancy is worth surfacing before the playbook selection ever happens.

Otherwise judgment runs on a diagnosis that was pre-filtered by the operator's own attention decay.

Collapse
 
daniel_nevoigt_ca2fdc23d5 profile image
Daniel Nevoigt

Constraint recognition as the layer under judgment is the right cut, and the stated-vs-binding split names something I keep running into from the retrieval side. The part I want to push on: disagreeing with the operator's stated constraint does not have to be a judgment-layer virtue. It can be derived.

The question carries the stated constraint. The vault carries the evidence. And attention decay has a measurable signature in the files: a constraint that active decisions still cite, but that nobody has re-affirmed or even pulled up in weeks, is exactly your "stayed constant while everything around it moved". You do not need the operator to admit the blind spot; the gap between what the current question names and what the still-active decision set leans on is computable before any playbook selection happens. Derive, don't declare, applied to the question itself.

Two things I would wire in. First, the disagreement has to arrive with its evidence attached: not "your constraint looks wrong" but "these three active decisions cite a constraint your question does not mention, last touched N weeks ago". A challenge without a citation is just another opinion in the room. Second, when the operator overrides the challenge, the override belongs in the decision trail as its own entry, because sometimes the operator is right and the files are stale. After ten of those you have a track record for whose constraint-naming holds up, and that is an outcome you can actually score.

Collapse
 
sarracin0 profile image
Raffaele Zarrelli

Daniel, "derive, don't declare, applied to the question itself" is a cleaner target than what I've got. Right now the anti-fluff check in the strategy skill is still a judgment call: the model reads the open decisions and context files and is asked to flag a mismatch, it isn't computing a citation diff between what the question names and what the active set actually references.

Your evidence-attached disagreement is the part I'd wire in first. "These three active decisions cite a constraint your question does not mention, last touched N weeks ago" is checkable today since decisions already carry a review date and status, the missing piece is just the citation extraction and the diff against the question. The override-as-its-own-trail-entry is the one I hadn't separated out either, right now an override just changes the decision, it doesn't leave a record that a challenge happened and was overruled.

Once you have that track record of ten or so overrides, do you score it as accuracy of the challenge, was the operator right, or as calibration, did the challenge state its confidence honestly, or are those the same number for you in practice?

Thread Thread
 
daniel_nevoigt_ca2fdc23d5 profile image
Daniel Nevoigt

Two numbers, and at ten overrides only one of them is honest. Accuracy first, but not as a judgment call at override time. Whether the challenge was right is derivable from the trail itself, later: an overruled challenge is confirmed when the decision it questioned gets superseded and the supersession reason cites the constraint the challenge had raised; it is refuted when the decision survives its review cycles and the constraint never bit. Nobody enters a verdict, the trail settles the argument on its own schedule. Same move again, derive rather than declare.

Calibration is the number I would refuse to compute at n of ten. It needs two things accuracy does not: a stated confidence per challenge, and enough samples per confidence band that the comparison means anything. Below that floor a calibration score just dresses up noise as precision. And they are never the same number in practice: a challenger that is right seventy percent of the time while claiming ninety-nine every time is accurate and badly calibrated, and that gap is exactly what you want to catch once you can.

One wrinkle that makes calibration interesting later: the challenge's confidence should itself be derived, not declared by the model. Evidence strength is already computable at challenge time, how many active decisions cite the constraint, how stale the last touch. If confidence is that number, calibration stops measuring whether the model is honest and starts measuring whether the evidence metric actually predicts outcomes. That is the version worth the sample floor.

Thread Thread
 
sarracin0 profile image
Raffaele Zarrelli

Fair hit. Today our anti-fluff check is declared, not derived: at generation time the model reviews its own draft against a checklist (vague language, missing numbers, unfalsifiable claims) and either passes it or flags it. That is a linter, not a calibration measure. It tells you the model followed a rule, not that the rule predicts anything.

Your framework gives me the honest next step: treat a strategy recommendation as a challenge against the status quo, let it resolve the way your overruled or refuted challenge does, confirmed if the decision log later supersedes a choice citing the same constraint the plan flagged, refuted if the decision survives review and the constraint never bit. Right now we could not compute even the accuracy number, let alone calibration. We do not have ten resolved bets sitting in a decisions log yet, closer to two or three. So the honest claim today is we check for fluff at write time, not we know our track record, and I would rather say that plainly than borrow a precision we have not earned.

Thread Thread
 
jugeni profile image
Mike Czerwinski

Accuracy scored later from the trail, calibration held back until the sample floor, that split is clean and I'd keep it. The part I'd poke at is upstream of both: deriving confidence from evidence strength (citation count, staleness) quietly assumes those two features are monotonic with correctness, and nothing in the design has tested that yet. A challenge citing three barely-stale decisions isn't obviously more likely right than one citing a single very-stale one. Weight matters, and right now the formula picks a weighting by feel.

Which means the formula is itself an unscored claim sitting underneath the thing you're trying to score. Early on you're not measuring whether the model is honest about confidence, you're measuring whether your own evidence-strength definition happens to track outcomes, and the two are easy to confuse from inside the system. The eventual calibration pass tests the model's honesty, but it also silently tests your formula, and a bad formula with an honest model can produce the same calibration gap as a dishonest model with a good formula.

So derive-don't-declare has to run one layer deeper than the challenge itself. The definition of confidence is a declaration too, until it's earned the same track record everything else in this thread is waiting on.