How to Build a Company OS using Kimi K3 (Builder's Guide)

This is a complete A–Z breakdown of Kimi K3 what it is and how to run your entire business using only AI Agents
This will change everything about how you work with Kimi
TLDR; If you don't want to read a 4480-word article, here is the GitHub repo which you can give to your agent. https://github.com/codejunkie99/meridian-company-os
Bookmark these builds before you forget.
Preface
The elements every company OS needs, derived from scratch, with the prompts that build each one. Learn the principle, take the prompt, build yours.
I built one (meridian-company-os, MIT licensed) and it is the reference for this guide, not the point of it. The point is the nine elements underneath it, because those are the elements underneath any company OS you will ever build.
Bookmark these 9 builds before you forget.
The Command cockpit: the operator surface from BUILD 5, and what the nine elements add up to.
Introduction
You are orchestrating agents with a chat window and a prayer. An agent that can spend money, ship code, and hire other agents is a company, and you are running that company with the tooling of a search box. This guide fixes that.
Here is the situation as of July 2026. A coding agent on the worker tier will generate any file you can describe in one paragraph, in under a minute, for cents.
It will also happily spend your budget, resolve its own approvals, and forget everything on refresh, because nobody built the walls. The model got cheap. The operating structure around it did not get built.
A company OS is not a nicer chat UI. It is the answer to six questions, at all times:
Answer all six and you have a company OS. Answer fewer and you have a demo.
This is not a philosophy of one, and it is not a walkthrough of my repo. It is the required elements, each with a generalized prompt you hand your coding agent, the reference implementation it produced for me, and a check that proves the element exists.
My stack was React 19 + TypeScript + Vite. Yours can be anything. The elements do not change.
How the whole thing was actually built, so you can copy the method and not just the output:
That is the entire toolchain. You will see it working inside every build below.
What you will have at the end, element by element:
Who this is for: anyone with a terminal, a coding agent, and the intent to run more than one agent at a time. You do not copy my files. You take the principle and the prompt, and your agent writes your files.
How to read it: in order, doing the checks. Each element assumes the ones before it. The check is the proof the element exists; skip it and you are stacking on rumor.
The principles underneath everything. Three, and every design decision in the next nine builds is an instance of one of them:
No essays from here on.
Prerequisites
node --version # v20+; any modern runtime works, this is what the reference used
npm --version # ships with node
# the coding agent that generates every file:
ls ~/.kimi-code/bin/kimi # kimi code cli installed
kimi login # once; stores oauth creds locally
# skills installed in kimi code before the first prompt:
# superpowers (github.com/obra/superpowers) planning + review discipline
# context7 (github.com/upstash/context7) fresh, version-accurate docsPin the runtime once: Kimi K3 is the worker tier that generated the reference files. Run a different model and you get different files, which is fine, because you are building yours, not mine. What you hold constant is the prompt and the check.
Why Kimi K3
Kimi K3 at a glance: launch specs and public benchmark standings, styled to match the console.
The runtime choice, fast. Not hype, just the tradeoffs.
What it is
Where it loses (be honest)
Where it wins (this exact workload)
Why it's the pick
The map
The nine elements, and the files they became in the reference implementation. Your file names will differ. Your elements will not.
any-company-os/
scaffold BUILD (this section): runtime + strict types, minimal deps
domain model BUILD 0: the nouns -> src/lib/types.ts
seeded world BUILD 1: never boot empty -> src/lib/seed.ts, skills.ts
source of truth BUILD 2: one store -> src/lib/store.tsx
heartbeat BUILD 3: the 2.6s tick -> src/lib/sim.ts
memory BUILD 4: survive reload -> persistence in store.tsx
operator surface BUILD 5: the cockpit -> src/App.tsx, views/Command.tsx
the gate BUILD 6: approvals inbox -> views/Approvals.tsx
command line BUILD 7: talk to it -> views/KimiSpace.tsx
real runtime BUILD 8: fenced agent -> server/kimiBridge.ts, vite.config.tsAll ten prompts in this guide also ship as runnable files in prompts/, one per element, so kimi -p "$(cat prompts/00-scaffold.md)" works out of the box.
First, the scaffold. Principle: fewer dependencies, fewer lies. A company OS's one job is trustworthy state, and every dependency is someone else's state you now have to trust.
Prompt, through kimi -p:
im building a company os. one console to run a whole company of humans
and ai agents from. pick me a lean setup: typed language, fast dev
loop, and as close to zero runtime deps as you can get away with. set
up the scaffold and tell me what you put in and why. anything you cant
justify in one line, rip out.What K3 produced for the reference: React 19 + TypeScript 5.8 strict + Vite 6, and exactly one runtime dependency beyond React (lucide-react for icons). Scripts: dev, build (tsc -b && vite build), preview.
Context7 mattered here already: without it, K3 scaffolded React 18 patterns; with it, the config came out Vite 6 native on the first try.
CHECK: install and typecheck, exit code 0. Count your runtime dependencies; if you cannot justify each one in one line, this build is not done.
npm install && npx tsc --noEmit; echo "exit: $?"BUILD 0: The vocabulary
Why, in one line: a company is state, so before any behavior exists, every noun the company runs on must have exactly one typed definition.
First principles. Ask what irreducibly exists in any company of humans and agents, and you get seven nouns:
Every company OS is these seven nouns plus opinions. Type the nouns first and the opinions stay honest.
The generalized prompt. Notice it names the nouns and the two questions to ask of each, and nothing about my stack:
ok before any logic i want the nouns. if im running a company of humans
and agents, what are the things that have to exist? actor, goal, task,
approval, money spent, a line in the log, the company holding it all.
model all of it in types, no behavior. for each noun ask two questions:
what does the operator need to see, and what does the system need to
enforce? statuses are closed unions not strings. money and tokens are
numbers not vibes. and if two of my nouns are secretly the same thing,
call it out, dont let me ship a mess.Reference implementation. K3 emitted src/lib/types.ts, 416 lines, zero logic. The shapes that carry the whole system, and the enforcement question visible inside each one:
export type AgentStatus = "working" | "idle" | "paused" | "blocked" | "offline";
export interface Agent {
id: ID; companyId: ID; name: string; title: string; department: string;
kind: "ai" | "human"; runtime?: string; model?: string; managerId?: ID;
status: AgentStatus; heartbeat: string;
monthlyBudget: number; spent: number; // enforce: spend has a ceiling
successRate: number; tasksCompleted: number;
skills: string[]; color: string; lastHeartbeat?: number;
}
export type ApprovalType = "hire" | "spend" | "override" | "publish" | "terminate";
export interface Approval {
id: ID; companyId: ID; type: ApprovalType; title: string; rationale: string;
requestedBy: ID; amount?: number;
status: "pending" | "approved" | "rejected"; // enforce: three states, no fourth
checks: PolicyCheck[]; // the machine argues its case
decidedAt?: number; decidedBy?: string;
}
export interface ActivityEvent {
id: ID; companyId: ID; ts: number; actorId: ID;
kind: "heartbeat" | "task" | "delegation" | "spend"
| "approval" | "governance" | "goal" | "system";
message: string; amount?: number; // what is not written down did not happen
}How the Kimi pass went: one kimi -p call, whole file in one shot.
The Superpowers skill earned its slot here. Its review discipline made K3 append a "two of your nouns overlap" note: a delegation and a task assignment were nearly the same noun, resolved as a delegatedBy field on Task instead of a new interface. That is the prompt's last sentence doing real work.
CHECK: typecheck passes with zero any. Then the noun audit: grep your interfaces and confirm each of the seven nouns has exactly one home.
npx tsc --noEmit && grep -c "^export interface" src/lib/types.tsBUILD 1: The world
Why, in one line: you cannot learn to operate an empty company, so the OS must boot into a world already mid-operation.
First principles. An operator surface teaches through recognition: you see an over-budget agent, a blocked task, a pending hire, and you learn what the controls do. An empty state teaches nothing, and it hides rendering bugs besides (an empty column and a broken column look identical).
So any company OS needs a deterministic seeded world: same world every boot, every status represented, every gate already holding a decision.
The generalized prompt:
take the types we just wrote and fake me a whole company thats already
running, so the app has stuff on screen the second it boots. who works
here? give em real titles, who reports to who, budgets theyve half
burned through, hit rates. whats being worked on rn, whats stuck? what
decisions are sitting in my inbox waiting on a yes? every status in the
model shows up at least once. make it feel like i walked into a live
company at 2pm on a tuesday, not an empty template. no random(), same
world every boot.Reference implementation. K3 produced two files.
seed.ts (~600 lines of fixtures):
And skills.ts, a registry of installable capability packs credited to their real sources:
export const SKILLS: Skill[] = [
s("superpowers", "Superpowers", "obra/superpowers",
"https://github.com/obra/superpowers", "developer",
"Battle-tested workflow superpowers: TDD, debugging, planning, and review discipline."),
s("context7", "Context7", "upstash/context7",
"https://github.com/upstash/context7", "developer",
"Pulls fresh, version-accurate library docs into the agent's context window."),
// ...design, marketing, social, finance, operations, legal packs
];There is a loop worth noticing. The two skills running inside my Kimi Code CLI while it generated this file are the first two entries in the registry the file defines.
The OS you are building installs skills on its agents the same way you just installed skills on the agent building it. The method is the product.
One regeneration was needed here. K3's first pass put every task in in_progress, which fails the "every status at least once" line. The fix was not editing the seed; it was that line getting added to the prompt, then kimi -p again. Fix the prompt, never the file.
CHECK: boot twice, diff the world. Deterministic means identical.
node -e "const {seedState}=await import('./src/lib/seed.ts'); \
console.log(Object.keys(seedState().tasks).length)" # same count, every runBUILD 2: The source of truth
Why, in one line: a company is state, so state may only change in one place, and everything else is a window.
First principles. The failure mode of every multi-agent dashboard is the same: five components each holding a copy of the truth, drifting. The cure is structural, not disciplinary.
One store. One reducer, a pure function from state plus action to state. Views read; views dispatch; views never mutate.
Do this and every later element (the log, the gate, the heartbeat) becomes a reducer case instead of an architecture decision.
The generalized prompt:
every screen should just be a window onto one source of truth, not its
own little pile of state everywhere. build me that source. if the store
is the ONLY place state can change, what shape is it, and how does a
button ask it to change something without reaching in and mutating junk?
one pure reducer, one action union, selectors for the common reads.
keep it so i can bolt on new actions later without rewriting the world.
build it. then tell me the one case youd bet money i break first.Reference implementation. src/lib/store.tsx, about 1,400 lines: StoreProvider, useStore() returning { state, dispatch }, a reducer covering every member of the Action union, and selectors (companyAgents, companyTasks, companyApprovals, agentName). The case that carries principle two and three at once:
case "decideApproval": {
const a = s.approvals[action.id];
if (!a || a.status !== "pending") return s; // no double-deciding
const decided = { ...a, status: action.approve ? "approved" : "rejected",
decidedAt: Date.now(), decidedBy: "you" } as const;
return {
...s,
approvals: { ...s.approvals, [a.id]: decided },
activity: [{ id: crypto.randomUUID(), companyId: a.companyId,
ts: Date.now(), actorId: "you", kind: "governance",
message: `${action.approve ? "Approved" : "Rejected"}: ${a.title}` },
...s.activity], // the decision is written down
};
}How the Kimi pass went: this is the one build K3 stalled on. Two worker-tier attempts produced reducers that mutated nested objects in three cases, both caught by the check, not by reading the diff. The build got escalated to a frontier model, same prompt verbatim, clean on the first pass.
That is the tiering rule in practice: K3 is the default worker, the frontier model is reserved for the one build where purity is the whole point. Asked for the case it would bet money I break first, it named deciding an already-decided approval, hence the status !== "pending" guard.
CHECK: exhaustiveness by grep. Every action in the union has a case, or it is a dead button waiting to be pressed.
grep -c 'case "' src/lib/store.tsx # >= the number of members in your Action union
npx tsc --noEmitBUILD 3: The heartbeat
Why, in one line: real companies move while you are not looking, so the OS must tick on its own clock or it is training you on a lie.
First principles. Agents spend and progress continuously; your attention is discrete. A console that only changes when you click teaches you that nothing happens between clicks, which is exactly wrong and exactly expensive.
So any company OS needs a heartbeat: a small, bounded, pure state transition fired on a timer. Bounded is the load-bearing word. An unbounded tick is a runaway; a bounded one costs pennies of simulated spend and proves the pipes.
The generalized prompt:
i want this thing alive even with zero real agents plugged in, so when
i open it the numbers are already moving. picture one heartbeat of a
running company, like 2 seconds of it. what changes? a bit of money
burns, some work creeps forward, a log line drops. make that one step a
pure state -> state function so i can fire it on a timer and trust it
never corrupts anything. cap everything: spend per tick, progress per
tick, log length. whats the smallest believable amount of movement, and
how do i stop it running away? build the tick and defend the numbers
you picked.Reference implementation. src/lib/sim.ts: runTick(state): State, fired every 2,600 ms by a single interval in the provider. Per tick: one working agent accrues $0.40 to $3.04, one open task gains 3 to 10 percent progress, a heartbeat line lands, and the log is capped at 500 entries newest-first.
Asked to defend the numbers, K3's answer survives as the design: a tick just visible to a human eye (2.6s), spend small enough that an hour of simulation costs pocket change, a log cap so memory cannot creep.
export const TICK_MS = 2600;
export function runTick(s: State): State {
const tickN = Math.floor(Date.now() / 1000);
const agents = Object.values(s.agents).filter((a) => a.status === "working");
if (agents.length === 0) return s;
const actor = pick(agents, tickN);
const spend = +(0.4 + (tickN % 13) * 0.22).toFixed(2); // $0.40..$3.04, bounded
// ...advance one task, append events...
return { ...s, activity: [...events, ...s.activity].slice(0, 500) }; // capped
}And exactly one interval, wired by a follow-up kimi -p edit scoped to a single hook: while simRunning, dispatch {type:"tick"} every TICK_MS, clear on cleanup, intervals nowhere else.
CHECK: watch the feed for 30 seconds; lines land roughly every 2.6s. Pause; it freezes. Resume; it moves. Lines arriving faster than 2.6s means two intervals, and two intervals means some component is doing the provider's job.
BUILD 4: The memory
Why, in one line: a company that forgets itself on refresh is a demo, and the line between demo and system is a reload.
First principles. Split all state into two kinds and the design writes itself. Domain state (who works here, what was spent, what was decided) is the company; it must survive. Session state (which screen you were on, an open modal, a toast) is your visit; persisting it is a bug.
So: an allowlist snapshot of domain slices, written on a debounce after real edits, restored on boot. And one ordering law: never write before the restore completes, or you overwrite the company with a blank.
The generalized prompt:
rn a refresh nukes the whole company back to seed. thats a demo not a
system. i want state to survive reload. think about what actually
deserves to be saved vs what doesnt: whats real company data vs whats
just where i happened to be clicking? allowlist the real stuff,
explicitly exclude the session junk. whats the fail case if i save at
the wrong second, and how do i make sure i never overwrite good data
with a half-loaded blank? build the save + restore path and warn me
about the ordering trap before i step in it.Reference implementation. A hydrate action, a persistable() allowlist (companies, agents, goals, tasks, approvals, runs, activity, customSkills, activeCompanyId), a 400 ms debounced write, and the trap named in the prompt guarded by one line:
useEffect(() => {
if (!state.hydrated) return; // the ordering law: never write before restore
const id = window.setTimeout(() => {
window.localStorage.setItem(SNAPSHOT_KEY, JSON.stringify(persistable(state)));
}, 400);
return () => window.clearTimeout(id);
}, [state]);How the Kimi pass went: a kimi -p edit against the existing store, not a fresh file. The prompt's warning clause is why the hydrated gate exists.
Asked to name the trap before stepping in it, K3 named this exact race: first render fires the persist effect before the snapshot loads, writing seed over saved data. Cheap models find real bugs when the prompt makes finding bugs the deliverable.
CHECK: two states, both reachable. Let the sim burn for 20 seconds, refresh, numbers continue. Clear the key, refresh, clean seed returns.
# in the browser console:
localStorage.removeItem("meridian.snapshot") # yours will differ; then reloadBUILD 5: The operator surface
Why, in one line: the operator asks three questions in a fixed order (what is happening, does it need me, what do I do), and the main screen must answer them top to bottom.
First principles. Derive the cockpit from the questions, not from what looks good in a screenshot:
And because a company is state, every widget is a pure read of the store. A cockpit that caches its own numbers is an instrument that lies.
The generalized prompt:
i need the one screen i actually stare at all day. im the operator.
when i open it it answers, in this order: whats happening, does it need
me, what do i do about it. so: the one number that says are we winning,
whos on fire or over budget, whats waiting on my yes, how fast money is
burning per team, and a live feed of what just happened. every widget
just reads the store, nothing owns its own state, everything that needs
me is one click from here. build the shell + this cockpit, top to
bottom in that order.Reference implementation. A sidebar shell (nav, company switcher, sim toggle) and CommandView: north-star with delta, risk radar, pending-approvals count that deep-links to the gate, department burn bars from company.budgets, newest-20 activity feed. All selectors, no local intervals, machine values in mono.
Context7 earned its keep again: React 19 memoization guidance came in current, so per-tick re-renders stay cheap without stale-API workarounds.
The cockpit is one operator surface; the Work board is another, built from the same store and the same tokens. Once BUILD 2 exists, every surface is a pure window onto it.
CHECK: open the cockpit cold and answer the three questions aloud in under ten seconds without clicking. Switch companies; every widget swaps with no stale number bleeding through. Click the approvals count; you land on the gate.
BUILD 6: The gate
Why, in one line: power flows through gates, so nothing that spends, hires, ships, or fires resolves without an explicit recorded yes.
First principles. Autonomy is a budget, not a right. The five verbs that can hurt you (spend, hire, override, publish, terminate) each need the same four things at decision time:
One more, easy to miss: when a policy check fails, approving must feel like overriding. Defaults are where governance goes to die.
The generalized prompt:
heres the rule for the whole thing: an agent never spends money, hires,
ships something public, or fires anyone without me saying yes. build me
the one inbox where that yes lives. every item shows the ask, whos
asking, why, how much, and the systems own policy checks (in budget? is
there a manager? under the cap?) so i see its reasoning before i decide.
approve and reject both leave a permanent trace in the log with my name
on it, not just a ui toggle. and if a check failed, dont make approve
the easy default, make me override on purpose. build the inbox.The gate. Every card shows the ask, the requester, the rationale, the amount, and the system's own policy checks. Approve and reject are the only exits, and both write to the log.
Reference implementation. ApprovalsView: pending first, each card with type badge, requester, rationale, amount in mono, and pass/fail policy checks with detail text. The default-flipping line, exactly as the prompt demanded:
const failed = a.checks.some((c) => !c.passed);
// ...
<button className={failed ? "danger" : "primary"}
onClick={() => dispatch({ type: "decideApproval", id: a.id, approve: true })}>
{failed ? "Override and approve" : "Approve"}
</button>The decision itself is BUILD 2's decideApproval case, which is the point: the gate is a screen, but the law lives in the reducer. A gate enforced in the UI is a suggestion.
CHECK: approve one seeded item; it moves to decided, stamped "approved by you," and a governance line lands in the feed. Find an item with a failing check; the button reads "Override and approve."
Then watch the sim for a minute: if any approval resolves without your click, the gate is broken and nothing else matters until it is fixed.
BUILD 7: The command line
Why, in one line: operators issue orders, and an order that costs a model call to parse is slower, pricier, and less deterministic than a regex.
First principles. There are two kinds of operator utterances. Commands ("create task x, assign to bea, p1", "move MER-1042 to review", "budget report") have fixed grammar and a known action: parse them locally, dispatch the real store action, print exactly what changed. Total cost zero, latency zero.
Everything else is conversation, and that is what the model is for. The routing rule is deterministic first, model as fallback, and always show the trace. An OS that does things silently is indistinguishable from one that does nothing.
The generalized prompt:
fastest way to run this company is a command line, not clicking around.
i want a chat where i type "create task: fix onboarding, assign to bea,
p1" or "move MER-1042 to review" or "budget report" and it just DOES
it, hits the store, shows me exactly what changed. no model call, no
cost, no waiting, when its a known command. only when nothing matches
does it fall through to an actual model later. parse first, dispatch
the real action, print the trace. and dont route to a model for
anything you can just execute.Typed commands hit the store directly and print the trace, no model call. Only a non-command sentence falls through to the local K3 runtime, shown here answering with its `kimi -p (local, k3)` trace.
Reference implementation.
KimiSpaceView: regex parse against the command grammar, name-to-id resolution through the store's selectors, dispatch, trace line back into the chat. The fallback branch prints a placeholder this build, because the model is BUILD 8's problem:
if ((m = input.match(/^create task:\s*(.+?),\s*assign to\s+(\w+),\s*(p[0-3])$/i))) {
dispatch({ type: "createTask", title: m[1],
assigneeId: agentIdByName(m[2]), priority: m[3] as never, by: "you" });
next.push({ role: "system", body: `Created task "${m[1]}" (${m[3]}) -> ${m[2]}` });
} else {
next.push({ role: "assistant", body: "(would route to local kimi runtime)" });
}CHECK: create task: refresh onboarding emails, assign to Bea, p1 creates a real task with a generated code and prints the trace. budget report prints spend against limit per department, instantly, no spinner, because no model was called. A nonsense sentence hits the placeholder.
Command handling that shows a loading state is a model call you are paying for and should not be.
BUILD 8: The real runtime
Why, in three lines: everything so far runs on a simulation, and a company OS that never touches a real agent is a diorama. The last element is the bridge to an actual runtime, and it is the most dangerous file in the system, because it spawns a process that can think and spend.
So the fence is the feature: concurrency of one, an input cap, a kill timer, an isolated workdir, and credentials that never cross back over the wire.
First principles. Whatever your runtime (a CLI, an API, a queue), the bridge needs the same five walls, each answering one attack:
And one grace rule: if the runtime is absent, degrade to simulation, never crash. The console must outlive its agents.
The generalized prompt:
ok everything so far is fake, a nice sim. now wire in my real agent. i
have a real cli installed and logged in on this machine. when i type
something that is NOT a known command, spawn the real agent and answer
with the actual model, my own creds. but this is the scariest path in
the app, its spawning a process that can spend, so fence it hard and
tell me the fence before you build it: how many run at once, how big an
input, how long before you kill it, where it runs, what must never leak
back out. and if the cli isnt there, dont crash, stay in sim mode.Reference implementation. Kimi is both the builder and the built here: the runtime the bridge spawns is the same ~/.kimi-code/bin/kimi that generated every file above, invoked as kimi -p with the operator's message on stdin, reusing the kimi login credentials.
The fence, as shipped:
Two endpoints: GET /local-runtime/status and POST /local-runtime/kimi/chat. And because the bridge spawns a local process, the dev server binds to 127.0.0.1 only:
export default defineConfig({
plugins: [react(), kimiOAuthProxy(), localKimiBridge()],
// local-first: the bridge spawns your cli, never expose beyond this machine
server: { port: 4173, host: "127.0.0.1" },
preview: { port: 4173, host: "127.0.0.1" },
});A final kimi -p edit swapped BUILD 7's placeholder branch for the real POST, with the offline fallback intact.
CHECK: prove the fence, not the feature. Status endpoint reports the CLI; a non-command sentence gets answered by the real model. Then attack it: two chats at once, the second returns 409; paste 9,000 characters, rejected before spawn; rename the CLI binary, the app stays up in sim mode.
curl -s http://127.0.0.1:4173/local-runtime/statusThe rollout
An OS you built in a weekend still gets adopted in weeks. Graduate.
Week 4 is where the numbers stop being simulated. Department burn, projections, and a model/token ledger, every real dollar traceable to an agent and a task.
Each row unlocks the next. Week 4 on day 1 is how you fund a educational invoice.
The runbook
Every alarm the system raises, and the move. The signal is generic to any company OS; the action is where the reference points you.
The Rules (print this)
Closing
The repo was never the point. Meridian is one implementation, in one stack, of nine elements that do not care about your stack: vocabulary, world, truth, heartbeat, memory, surface, gate, command line, runtime.
Build those nine in Rails or Rust or a spreadsheet with macros and you have a company OS. Skip the gate or the log and you have a leak with a UI, in any language.
And notice what actually built it: a worker-tier model, two skills, nine prompts, and a check after each. The method you just read is the machine it produces. You write the spec, a cheap agent writes the files, the walls keep everyone honest, including you.
Tonight: write BUILD 0. Open your agent, hand it the vocabulary prompt, and make it name the seven nouns of your company. Do not let it write a single behavior. The nouns are the whole first night, and everything else is a window onto them.
So here is the question worth arguing about: what are the seven nouns of your company, and which two did you almost merge? Build BUILD 0 tonight and reply with your types.
Built from my own notes while constructing the reference repo; every file was generated by Kimi K3 through the Kimi Code CLI, and a frontier model edited this prose and handled one escalated build (the reducer). The claims are checkable against (https://github.com/codejunkie99/meridian-company-os).
This is written by the authors' notes while building with Kimi K3 and Kimi Code CLI and it has been edited by Kimi K3 Code and Opus 4.7.
TLDR; If you don't want to read a 4480-word article, here is the GitHub repo which you can give to your agent. github.com/codejunkie99/m…






