AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
Checks that a TypeScript codebase still has the shape you meant it to have, and blocks an edit that would change it
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
trueup keeps a TypeScript codebase in the shape you meant it to have, and stops a coding agent from quietly changing that shape.
It reads your source files without running them, works out which file depends on which, and compares that against rules you wrote down. When something breaks a rule, it names the file, says what happened, and says what to do about it.
Read the guides.
It reads between files, not inside them
A linter reads one file at a time and tells you about that file. A variable nobody uses. A keyword you forgot.README 전문 보기 ↗trueup keeps a TypeScript codebase in the shape you meant it to have, and stops a coding agent from quietly changing that shape.
It reads your source files without running them, works out which file depends on which, and compares that against rules you wrote down. When something breaks a rule, it names the file, says what happened, and says what to do about it.
A linter reads one file at a time and tells you about that file. A variable nobody uses. A keyword you forgot.
trueup looks at the lines between files instead. Which parts of your project are allowed to know about which other parts. Where a file should live. Whether a folder has quietly turned into a junk drawer. None of that can be seen from inside any single file, which is why the shape of a project drifts for months and nobody notices.
You describe the shape once. Every run after that answers a single question: is this still true?
You need Node 24 or newer.
npm install --save-dev @vismek-solutions/trueup
Let it write a first draft of the rules by reading your folders:
npx trueup init
That draft gives you zones, which are names for groups of files. What it will not guess is which zones may reach which, because a folder layout cannot say which direction the dependencies are meant to run. That part is yours:
// trueup.config.ts
import { defineConfig } from "@vismek-solutions/trueup";
export default defineConfig({
zones: [
{ name: "spec", patterns: ["**/*.test.ts"] },
{ name: "components", patterns: ["src/components/**"] },
{ name: "hooks", patterns: ["src/hooks/**"] },
{ name: "api", patterns: ["src/api/**"] },
{ name: "domain", patterns: ["src/domain/**"] },
{ name: "app", patterns: ["src/**"] },
{ name: "server", patterns: ["server/**"] },
],
boundaries: [
{ from: "components", allow: ["hooks", "api"] },
{ from: "hooks", allow: ["api"] },
{ from: "api", allow: [] },
],
});
Then run it:
npx trueup
Every finding arrives with an explanation of what it means and how to resolve it:
every-import-respects-its-zone-boundary 1 error
src/hooks/useCart.ts:1:10 is hooks and may not reach components: CartRow from src/components/CartRow.tsx
────────
Code in one zone reached a symbol declared in a zone it may not reach. The edge is named by its
declaring file, so a barrel in between does not excuse it.
Do this:
- Move the code to a zone that may reach the target.
- Or have the target expose what the caller needs through a zone the caller may reach.
- Run `trueup explain <file>` to see what a file may reach.
Not the fix: widening the rule so the edge becomes legal.
It exits with a failure code whenever there is something to fix, so a CI step needs no extra flags.
Rules you write, in one config file:
Checks that need nothing from you but zones:
A check that reports success while enforcing nothing is worse than no check at all, so an empty or degraded input is an error here rather than a pass.
Claude Code can run a command before it writes a file and cancel the write if that command objects. Put this in .claude/settings.json and the agent gets the refusal as its tool result, with the reason it needs to correct course in the same turn:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [{ "type": "command", "command": "npx trueup guard" }]
}
]
}
}
Nothing lands on disk, and no trip through you is needed. The rules themselves are protected too, because an agent told to make the build pass will widen a rule as readily as fix the code.
Record what is already there, then hold the line from that point:
npx trueup --update-baseline
A new violation fails the build after that. A recorded one prints as a warning, so nobody forgets the debt is there.
The report comes out in the format your forge reads, so a finding lands on the line that caused it rather than in a job log nobody opens.
npx trueup --gitlab
npx trueup --github
The first is GitLab Code Quality, the second is SARIF for GitHub code scanning. Both carry the remedy with the finding, and a violation the baseline already accepted arrives ranked below a new one. Wiring either into a pipeline.
The guides ship with the package, so you can read them without leaving the terminal and without a browser:
npx trueup docs
That lists every page with a line about each. Name one and it prints in full, and a claim name from a failing run works in the same place:
npx trueup docs seams
The same guides are published at vismek-solutions.github.io/trueup, and cover the parts this page only mentions.
The suite is checked with Stryker, which changes one thing in the source at a time and runs the tests again. A test that executes a branch without asserting anything about it lets the change through, so it counts as a gap here rather than as coverage.
That is the same failure this tool exists to catch between files, turned back on the tests themselves.
A full check on a 900-file monorepo takes about a tenth of a second. The guard takes about the same, including the time to start the process.
packages/trueup the checker, the CLI, and the write-time guard
apps/docs the documentation site
trueup.config.ts what this repo asserts about itself
trueup checks its own shape, so the first thing to run on a clone is the tool:
pnpm install
pnpm run check
The guides are readable from the repo the same way they are from the package:
pnpm run docs
pnpm run docs concepts/zones