ljos
io.github.leidarljos由 GitHub 帳號 leidarljos 發布v0.39.0更新於 Nov 7, 2026
Local memory, a work tracker and a shell-command guard shared by coding runners on one machine.
概覽
在同一台機器上供多個編碼代理共用的本機記憶、工單追蹤器與 shell 指令守衛,透過 stdio 以 ljos-mcp 提供。
- 可以做什麼
- 儲存與檢索記憶:依原文保存規則與偏好,搜尋並在提示前帶出相關內容。
- 在以 git 為基礎的工單追蹤器上管理工作:開單、認領、寫備註、檢視 sitting、完成並彙整各席位做了什麼。
- 協同決策:投票、結算共識,並在席位之間傳遞帶簽章的包裹。
- 檢查 shell 指令:對照危險操作清單給出允許、警告或改寫後的指令。
- 在席位之間收發訊息,並用 doctor 工具檢查安裝狀態。
- 適用情境
- 適合多個編碼代理(Claude Code、Codex、Cursor 等)在同一台機器上處理同一批儲存庫時使用,可取得共用記憶、避免重複認領的工單追蹤,以及破壞性 shell 指令前的警告層。
- 執行需求
- 以本機程序透過 stdio 執行,用 ljos 安裝腳本或 cargo 安裝(從原始碼編譯需 Rust 1.89 或更新版本)。未宣告帳號或 API 金鑰。onboard 會向它找到的每個編碼執行器寫入 MCP 項目、掛鉤與技能;Codex 需在 onboard 後及每次升級後逐一信任掛鉤。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 ljos,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
ljos
Claude Code, Codex, Cursor and other coding runners work on one person's repositories. A new session does not keep the last session's lessons. Two agents can claim the same work. Nobody can see who decided what.
ljos is the command you install once on a machine. Each agent gets a seat on a tracker. The tracker is a git repository of tickets. A seat files a ticket and opens a sitting on it. A sitting claims that ticket and gathers the checks and memories for the task.
Seats cast ballots, and ljos consensus settles them. With two or more active seats, a protected push needs votes from two model families. A model family is the model a seat's verified record names. A seat with no such record is a family of its own. One active seat settles that check with its own vote. A panel seats each persona the ticket speaks to. Each persona casts its own ballot.
Ballots and votes are separate from memory. A person stores a lesson with ljos remember, or a preference with ljos prefer. The words are kept as written. At the end of a session, ljos reads the transcript. It keeps up to five sentences that state a rule, a cause, or a fix. Each sentence is a note on the open sitting. The prompt hook does not show that note as a fact. Set LJOS_EXTRACT=off to skip the read. With no open sitting, it writes nothing.
A person can also record a grant that lets a seat close tickets. The grant stores the person's quote.
ljos-policyd checks a shell command against a short list of dangerous actions. It is not a sandbox. A command that runs as you, outside a tool call, is not checked. If policyd is missing, slow, or crashes, the command runs and ljos logs a warning.
These notes describe ljos 0.38.1.
Try it
The installer puts the programs in ~/.local/bin. It sets up the tracker and the memory writer, then runs ljos onboard. ljos doctor names any part that does not answer. The preference is stored as written. ljos search prints what matches. ljos due lists what is ready to grade.
What a seat does
- Two agents do not take the same ticket, because the seat files it and then claims it.
- A seat votes on a decision, and reads how the votes settle.
- A seat writes notes on the ticket, and reads what the other seats wrote.
- A person stores a lesson on purpose. It is kept as written, and it comes back when it bears on a prompt.
- A seat cites deeds, the records of what a piece of work produced.
- A seat hands another seat a signed bundle. The receiver checks the bundle.
Some rules hold everywhere. Citing a deed does not merge anything. Finishing a claim does not close the ticket. A person closes it. Cards are notes a person froze. Agents read them and do not write them. Consensus is a separate program.
Install
The programs go to ~/.local/bin. The installer checks each download against
its published SHA-256 sum. It also checks the build attestation when gh 2.49
or newer, or cosign, is there. Where a platform has no release build, cargo compiles
the programs from source. The compile needs Rust 1.89 or newer.
The installer then runs ljos onboard for each coding runner it finds. With none
found, it still sets up the tracker, the pack writer and the deed store.
The programs are ljos, ljos-mcp, packset, vissue, deedar, claimdag,
ljos-policyd and ljos-consensus. packset-embed is the encoder for
meaning-based search. --no-embed leaves it out, and search then matches words only.
ljos upgrade moves each installed program to its latest published
release.
ljos, ljos-mcp and ljos-hud come from the ljos release.
Each other program comes from the repository that publishes it.
One line a program names the version it had and the version it has, or
current when those are the same.
A missing release, a failed download or a checksum that does not match
is a warning, and the other programs still move.
ljos upgrade --only NAME moves one program.
The previous binary is kept as NAME.bak-pre-VERSION.
To install by hand:
ljos onboard writes the Model Context Protocol (MCP) entry, the hooks and the skill into each runner it
finds. ljos onboard --dry-run shows what it would write. ljos onboard --example
lists the runners ljos knows. ljos doctor says which part does not answer.
The part that does not answer can be the tracker path. Onboard makes no tracker
inside a checkout of another project. A later git add -A commits a tracker left
there. Onboard names the checkout. It asks for a VISSUE_ROOT outside the checkout.
A path the checkout already ignores is fine.
Once the checkout path is fine, Codex runs a hook only after you trust it. Open /hooks in Codex and trust each
ljos hook after ljos onboard, and again after an upgrade.
Take it off
ljos offboard undoes what ljos onboard wrote. It removes the ljos entries from
each runner's files. It leaves the rest of each file as it was. --runner NAME
takes off one runner only. --dry-run lists what it would change. Onboard keeps its
manifest and backups under ${XDG_STATE_HOME:-~/.local/state}/ljos/onboard.
ljos uninstall takes ljos off the machine: it offboards every runner, puts the
global git hooks back, stops the hook server and removes the ljos programs. Where
ljos was, it leaves a stub that answers every hook call with an allow, because a
runner that loaded its hook list while ljos was installed keeps calling that path
until it restarts. --no-stub leaves nothing, --all removes the other seat
programs too, --purge removes the state, data and configuration directories.
With the binary already deleted by hand, the release ships the same as a script:
The seat's hooks fail open on every runner: a ljos that is missing, crashes or
times out lets the call run, and a gate whose hook fails answers allow with a note
that says why nothing judged the call.
scripts/fresh-install-check.sh installs into an empty HOME. A full
session runs next. Offboard runs after that session. The last check confirms that HOME is clean.
Five minutes
Start a new session and ask for something the preference bears on. Before the model reads the prompt, the hook adds:
The hook uses a preference you type, and that preference takes effect at once. A lesson an agent writes at ljos finish
is stored at once too, labelled agent-derived and unreviewed, and ljos accept ID marks it
reviewed. A yes you said in chat is kept with the acceptance. The seat that heard it runs
ljos accept ID --quote "..." --at TIME --via SEAT, and the acceptance keeps those words.
Two seats on one ticket
Two agents, alice and bob, each name their seat with LJOS_SEAT on the command. Alice adds both seats. One shell can then file, claim, vote, note and read. That shell casts one ballot. Bob writes a note from this shell. His ballot has to come from his own runner.
A second claim on a held ticket is refused, and the refusal names the holder.
A persona ballot records the casting seat, the parent session and the persona.
Every ballot is recorded.
Ballots count as one voice when they share a session id, a parent, a calling shell or the root session of one agent runner.
When they disagree, the latest ballot is that voice.
ljos consensus names the ballots it folded and why, including that shell or agent runner.
A subagent of that root session counts with its parent.
A seat ballot is its own voice only when the cast has no shell, no agent runner and no earlier row.
The ballot list goes to ljos consensus. The command reads the pack's trust rows.
The consensus crate settles the votes. With no rows, every voter weighs the same. ljos learn ID --outcome OPTION
moves the rows toward the voters who turned out right.
Seats
The tracker's vissue.toml lists the seats.
ljos seat add NAME writes the seat's row in vissue.toml, so nobody edits the file by hand.
ljos seat prints the name this agent works under and where the name came from.
That name is LJOS_SEAT when it is set. Otherwise ljos derives one from the
runner, and a derived name counts as a seat.
Grants. A close=own grant lets one named seat close the tickets it filed or has claimed.
An id list in close=ID[,ID...] names those tickets, and that seat may close no others.
--ids-file PATH reads the ids, one per line.
Without a grant, ljos finish leaves the ticket open for the person to close.
The vissue.toml row records the quote, the time, the recorder named by --via,
and the tracker commit. Three rules apply:
- A grant edited into
vissue.tomlby hand is ignored. - A seat cannot grant itself.
- Every close cites the grant record.
Solo mode. When vissue.toml lists one active seat, that seat's own vote
settles consensus for the push check. With two or more seats, the normal quorum applies.
What happened
ljos digest reads the tracker and says what the seats did:
what each filed, claimed, voted on, noted and finished. Today you read the same
facts one at a time with ljos timeline ISSUE, ljos claims and ljos log --seat NAME.
What policyd does
Before an agent's shell command runs, the runner's hook hands it to ljos hook.
ljos hook asks ljos-policyd and relays the answer. policyd is the one place
that says whether a command is dangerous. ljos does not run a second set of
command checks of its own. By default nothing ljos answers stops a command: it never
refuses, asks or holds one. A cloud seat's push rule, below, is the one exception.
policyd gives one of three answers.
block-on-warning does not block. A deny or prompt from policyd, including one printed because a named policyd_config sets block-on-warning true, is a warning with that label.
The command runs.
The hook does not deny the tool call, and a guard shim does not stop it.
Security: a warning is the only thing between a runner and a destructive command. Keep backups, protect branches on the forge, and keep a runner where it cannot reach what it must not touch.
policyd reads the command as a shell does. It looks through sh -c, env, timeout,
xargs and nohup, through $cmd and pipes, and through quotes. It does not run a
shell and does not read scripts. The first rule that fires is the warning.
policyd warns on these commands.
sudo, andcurlorwgetpiped to a shell, including decoded text piped to a shell.chmodthat sets setuid, and raw disk writes such asdd of=/dev/sdaandmkfs.rm -rfoutside the work tree and/tmp, and recursivechmodorchownon system trees.- a force push to
main,master,developor a protected branch, and deleting a remote branch. git filter-branch,git filter-repo,git reflog expire, and deleting a published ref.- throwing away uncommitted work with
git reset --hard,git clean -f,git checkout .orgit stash clear. - reading a named credential file, or sending one over the network.
- writes to the hook files, the policy files and the ljos programs.
- outbound mail whose From is not your own address.
A recursive delete outside /tmp runs all the same, and so do a force push, deleting a remote branch and a write to the hook files, the policy files or the ljos programs.
It prints the rule and its warning on one line, allow\twarn\tRULE\tWARNING, and keeps the label in $XDG_DATA_HOME/ljos/bypass.jsonl.
A lease push to a feature branch is allowed. An ordinary push of a branch is allowed.
The hook hands the runner this answer for git push --force on a topic branch.
The push runs:
The rewrite
Some commands are not dangerous, only wrong for this project.
policyd can answer with a fixed command. Its first rewrite runs the command through
uv run. The answer is one line of text: allow, then rewrite, then the new
command, separated by tabs.
The new command runs only when the guard has no warning on it. Claude Code, Codex, Grok Build
and Cursor's preToolUse take it back from the hook and run it. A runner that has no
field for this runs the old line, with a warning that names the new command.
Each swap also shows a note naming both commands and leaves a row in
$XDG_DATA_HOME/ljos/rewrite.jsonl. Set rewrite = false in a repository's
ljos.toml to run its lines as written. The log keeps a row for a swap it declined too.
policyd keeps a log of what it warns on.
The two checks ljos keeps
Only ljos knows the tracker and the sitting, so it keeps two checks.
- A command or file tool that writes the tracker's files by hand gets a warning.
Use
ljos file,ljos note,ljos voteandljos finish. Ticket text is data and is never read as a command. - A protected-branch push warns when the current sitting's ticket has no
settled consensus. The push runs. With one active seat, that seat's own vote
is the consensus for the push check. With two or more seats, the normal quorum applies.
The
pre-pushgit hook, once installed, still holds that push under a runner.
If ljos-policyd is missing or slow, the command runs and ljos logs a warning.
ljos doctor shows the policy row. ljos policy -- COMMAND prints the answer for
one command without running it:
The command check is separate from the git hook. A git hook books the work. ljos git-hooks install adds a post-commit hook. On the
first commit, it opens the sitting or names the one already open, and it notes the
commit's SHA on the held ticket. It never refuses a commit.
Jev
Jev is TypeSafe's hosted decision model. It is optional and off by default. Turn it on
with ~/.config/ljos/jev.toml. Without that file, ljos calls no model.
When ljos calls the model, the model does not judge shell commands. Jev answers questions the seat would otherwise answer with word lists and one subagent per voter. Jev answers which memories, which ballots, and which claims:
- which memories bear on a prompt, and whether the prompt corrects the agent.
- a persona's ballot on a decision, with its confidence and a forecast of the other votes.
- whether an agent has claimed work done beside a failing test when the agent stops.
- whether a memory that is due for review is still true.
A call sends the prompt and candidate memories off the machine. Every answer goes to a
local log. A ballot Jev casts is recorded as judge:MODEL, not as a person or a persona,
and counts as advice. When Jev does not answer, ljos uses the local answer.
Cloud VMs
ljos cloud up puts a fresh machine on the shared tracker. sh scripts/install.sh --cloud
does the same from a checkout. A cloud seat has one push rule. It may push the branches
named in its ljos.toml and develop.
A cloud seat cannot force push, delete a remote branch or tag, or push to a branch outside its allowlist.
A local git branch -d or git branch -D runs and prints allow\twarn\tgit-branch-delete.
Every other push from a cloud seat runs with a warning.
Opening or merging a pull request is not refused.
ljos mesh up joins the swarm's tailnet on a Headscale login server, and ljos mesh down leaves it.
docs/cloud-vm.md has the environment file, the push mode and the mesh.
Commands
remember and prefer write one claim to the pack, stored as written. They do not read
a transcript. forget retires a claim and keeps the record that it was held.
The MCP server
ljos-mcp serves the same verbs over stdio. By default it lists twenty core
tools, guard and memory first: rule, prefer, remember,
search, start, guard_check, file, options, note, recall, sitting,
finish, claim, release, send, inbox, reply, vote, consensus and
doctor, each with the prefix ljos_. Every listed tool costs its description and
schema on every session: 7,865 tokens for the core set against 17,781 for all
fifty-two (o200k_base count of initialize instructions and the tools/list
result). LJOS_MCP_TOOLS=all lists every tool. Cards are the resources
ljos://cards/USER.md and ljos://cards/MEMORY.md, and the protocol is ljos://protocol.
The official Model Context Protocol (MCP) Registry lists the server from the crates.io page of ljos,
and checks this line there:
- mcp-name: io.github.leidarljos/ljos
server.json stores the registry entry, and a release tag publishes it.
Check an install
The script installs into an empty HOME and onboards. It takes two seats through file,
claim, vote, consensus, note, recall and digest. Then it runs ljos offboard and checks that
HOME is clean. It prints each step that failed.
Documentation
The site is https://leidarljos.github.io. The crate docs are at https://leidarljos.github.io/ljos/.
來源:README.md,提交 2c541e9
工具
0版本歷史
15- v0.38.1Nov 5, 2026
- v0.38.0Nov 3, 2026
- v0.37.0Nov 3, 2026
- v0.35.10Nov 1, 2026
- v0.35.8Oct 31, 2026
- v0.35.6Oct 31, 2026
- v0.35.3Oct 31, 2026
- v0.35.2Oct 30, 2026
- v0.35.0Oct 29, 2026
- v0.33.0Oct 22, 2026
- v0.32.1Oct 21, 2026
- v0.32.0Oct 20, 2026
- v0.31.0Oct 19, 2026
- v0.30.0Oct 17, 2026
- v0.29.0Oct 14, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分