Maru is a local-first desktop workspace for Korean knowledge and document operations. It combines a React 19 and TypeScript interface with a Tauri 2 Rust core, and treats the filesystem as the source of truth.
The current product release is v1.1.4, Off the Main Thread. Releases before v0.3.0 shipped under the name Anchor; v0.3.0 completed the application identifier and on-disk migration to Maru.
| Area | State | Evidence |
|---|---|---|
| Product release | v1.1.4 | Signed desktop bundles and standalone CLI for macOS, Windows, and Linux |
| Planning milestone | v1.1 Felt Quality and Native Proof | Phases 6-11; phases 6-8 complete (39 plans) |
| Application shell | Complete | 18 lazy modes; MainApp held to 15 useState and 24 useEffect calls |
| Verification | Passing | Typecheck, ESLint, unit tests, Rust fmt/clippy, E2E, build, and bundle budgets |
| Typed IPC | ERR-06 closed | Every conflict-emitting command preserves { code, message }; recursive source guard active |
| Main-thread isolation | PERF-01/02 closed | All 365 production commands off the UI thread (356 ISOLATED + 9 UI); native load proof keeps loaded p95 at 2ms with the negative control at 4789ms |
| Active milestone | v1.1, phase 08 complete | Phase 09 (Durability and Session Lifecycle) is next; releases ship as 1.1.x while v1.1 is open |
The milestone archive, audit, retrospective, and summary live under
.planning/milestones/, .planning/RETROSPECTIVE.md, and
.planning/reports/.
- Filesystem authoritative: notes, tasks, drafts, evidence, and diagrams remain usable without Maru. Caches are disposable.
- Local-first writes: ordinary editing happens inside user-owned workspace folders. Cloud or Hub writes require an explicit supported path and approval.
- Byte-stable documents: a frontmatter field edit preserves unrelated keys, comments, order, quoting, and document body bytes.
- Fail-closed mutation: revision checks, workspace ownership, write policy, path containment, and managed-write validation run again in Rust.
- Inspectable automation: AI work is suggestion-first. Protected writes use approval staging and durable audit events.
- Korean document fidelity: HWPX, DOCX, PDF, Korean filenames, Korean IME, and public-document writing workflows are first-class concerns.
Rule SSOTs for the working environment live at:
~/workspace/work/_meta/rules/
frontmatter-schema.md
document-lifecycle.md
hub-contract.md
evidence-policy.md
Settings opens as an overlay and is not counted as an app mode. Diagram and Graph are enabled by default; E2E Flow is flag-gated.
| Mode | Korean label | Purpose |
|---|---|---|
dashboard |
대시보드 | Today, tasks, schedule, inbox, agents, drafts, git, recent documents, and sync status |
pkm |
문서 | Markdown and HTML document tree, multi-tab editor, outline, references, and utility rail |
scratchpad |
스크래치패드 | Durable memos and disposable result files with Rich, Source, and Preview editing |
files |
파일 | Finder-style folders, direct children, previews, editing, and safe file operations |
inbox |
인박스 | Drop, pending, processed, provider, classification, approval, and processing flows |
comms |
메시지 | Telegram, Outlook/Microsoft 365, and provider readiness configuration |
meetings |
회의록 | Transcript intake, summaries, meeting review, and follow-through |
today |
오늘 | Prepare, execute, review, capacity, calendar selection, and explicit sync |
tasks |
태스크 | File-backed task list, calendar, detail editing, status changes, and AI runs |
drafts |
아이디어 | Idea lifecycle, implementation drafts, promotion, and recurring automation |
gap |
갭 분석 | Compare promoted drafts with frozen baselines and record human revision patterns |
agents |
에이전트 | Runtime status, chat, runs, permissions, schedules, and user-created agents |
catalog |
카탈로그 | Operations catalog for deadlines, approvals, evidence, and inbox signals |
studio |
스튜디오 | Seven-step document authoring, template, guideline, HWP field, export, and package flow |
diagram |
다이어그램 | Concept maps, report patterns, templates, history, and managed report assets |
graph |
그래프 | WebGL vault/workspace graph, neighborhoods, saved views, and reviewed relationship writes |
sites |
사이트 | Site switcher and embedded native browser surface |
e2e |
E2E 플로우 | Hidden end-to-end flow console for development and verification |
The desktop application and standalone CLI are separate artifacts.
brew tap STAIxBWLB/homebrew-cask
# Desktop application only
brew install --cask maru-workspace
# Standalone CLI only; installs the executable as `maru`
brew install maru-cli
maru --versionThe cask installs Maru.app and does not create a CLI symlink. The desktop app
uses signed Tauri updater metadata from GitHub Releases. Homebrew installations
can also be upgraded explicitly:
brew upgrade --cask maru-workspace
brew upgrade maru-cli+---------------------------------------------------------------+
| Tauri WebView: React 19 + TypeScript |
| |
| 18 typed lazy mode adapters |
| BlockNote / CodeMirror / DOMPurify / Radix UI |
| Sigma WebGL / Graphology / diagram canvas / terminal canvas |
+-------------------------------+-------------------------------+
| Tauri IPC
+-------------------------------v-------------------------------+
| Rust core |
| |
| workspace scan + cache document + frontmatter |
| inbox + provider bridges today + tasks + scheduler |
| terminal PTY + screen model graph + diagram + Studio |
| skill host + agent host Hub client + export pipeline |
| write policy + approval atomic files + revision guards |
| worker-isolated commands path-transaction admission |
+---------------+-------------------------------+---------------+
| stdio | fixed argv
+---------------v--------------+ +-------------v---------------+
| Local MCP sidecar (Node) | | External CLIs and skills |
| Read-first workspace tools | | Claude/Codex/Kimi/Kiro/hwp |
+------------------------------+ +-----------------------------+
- Rust owns workspace filesystem access, cache, git operations, frontmatter, provider bridges, terminal sessions, skill ownership, agent execution, catalog, Studio, export, Diagram, Graph storage, and write enforcement.
src/lib/owns frontend domain logic and module stores.- React components own rendering, editors, user interaction, graph layout, and diagram canvas behavior. They do not bypass Rust write guards.
src/lib/does not import components, except for documented type-only legacy boundaries. Nothing importssrc/App.tsx.- Shared UI state follows keyed module-store plus
useSyncExternalStorepatterns. No additional global state library or provider tree is used. - Production commands never block the UI/shared async worker thread: 356
ISOLATED commands run on awaited
spawn_blockingworkers and 9 native-window commands stay UI-bound, and every filesystem mutation passes shared path-transaction admission before taking domain locks. The 365-command inventory, worker-boundary, and admission evidence are gated bycheck-command-isolationinmake verify.
- Markdown uses Rich, Source, and sanitized Preview modes.
- HTML uses Visual, Source, and sandboxed Preview modes. Scripts, event handlers, forms, frames, meta refresh, network resources, and paths outside the owning workspace are blocked in the runtime clone and never written back.
- Documents support read, save, create, version, rename, move, duplicate, and system-Trash operations with optimistic concurrency.
- Files presents folders, direct children, search, binary previews, shared document drafts, multi-selection, keyboard control, and collision-safe file operations.
- Rename and move use
.maru-rename-txn/staging with recovery on the next scan. Operations never overwrite an existing target.
- Document Studio guides source selection, template and guideline choice, section editing, HWP fields, export, and package freeze.
- Native template publication requires released
hwp0.12.1 or newer and fails closed on malformed fill reports, unmatched fields, or validation failure. - The lower-level
hwped_*engine bridge supports read, render, edit, compose, validate, and capabilities withhwp0.8.7 or newer. - Export manifests bind source hashes to DOCX, HWPX, and PDF outputs and record partial failures instead of reporting silent success.
- The gaejosik linter supports Korean public-document style during authoring.
- Evidence Binder stores schema-v2 state under
<workspace>/.maru/binder/<doc-id>.json, uses full binary SHA-256 identity, revision-checked atomic mutations, explicit targets, local verification, and submission selection. - Drafts use
$MARU_DRAFTSplus.maru/drafts/index.json; promotion is approval-gated and freezes a baseline for Gap analysis. - Diagram documents live at
diagrams/*.cmd.json; report assets live underattachments/diagrams/<docId>/; pattern presets live in.maru/diagram-patterns/. - Graph uses a multi-directed Graphology model, Sigma WebGL, an off-thread ForceAtlas2 worker, visibility reducers, saved views, and schema-gated writes.
- The terminal uses
portable-ptyandalacritty_terminal, streams ordered generation-tagged frames, limits frames in flight, and requires a current generation-bearing handle for every session command. - Terminal and Graph share a persistent bottom/right panel with independent themes and remembered layout.
- Claude Code, Codex, Kimi, and Kiro are first-class runtimes. Each named agent binds a skill, runtime, permission mode, and optional schedule.
- Provider probes and real integrations have bounded output, timeout,
cancellation, and stale-request handling. The real-binary integration smoke
remains separate from hermetic
make verify.
- The skill host owns five tiers: core, public, private, imported, and managed. One name maps to one tier; doctor, dirty, reconcile, import, and tool-sync operations are available through the CLI.
- Codex installs target
$CODEX_HOME/skillswhenCODEX_HOMEis set, otherwise~/.codex/skills. - Settings > Jobs manages the external
dotworkspace sync service through its versioned JSON API. Maru uses fixed arguments, serializes mutations, and confirms destructive or secret-expanding actions.
Global user state:
~/.maru/
settings.json
workspaces.json
skills/registry.json
skills/_cache/
Workspace-local state:
<workspace>/
.maruignore
.maru/
cache/ # disposable workspace index and Hub cache
workspace-state.json # collapsed folders and workspace UI state
versions/ # explicit document snapshots
studio/ # per-document Studio state
binder/ # per-document Evidence Binder state
diagrams/ # diagram history and backups
drafts/ # draft index and frozen promotion baselines
queue/ # recoverable provider/Hub work queues
<workspace>/.maru/settings.json is a legacy migration input only. New
workspaces use global settings plus workspace-state.json.
Scratchpad structure:
<work>/scratchpad/
ideation/{seeds,developing,proposals,_archive}/
memos/
drafts/
temp/{claude,codex,kimi,kiro,runtime}/
Only temp/ is disposable. Ideation, memos, and drafts are durable and may be
Git-tracked. Cleanup is explicit and moves selected files to system Trash.
Public workspace configuration is registry-only in v1.1.0. Provider metadata is non-secret, manually entered roles map to coarse capabilities, and filesystem writability is probed again before granting direct writes. OAuth and live cloud role checks are not implied by this metadata.
src-tauri/src/frontmatter/ops.rsis the only allowed frontmatter write path.resolve_inside_vaultand shared containment helpers stay lexical. Deliberate symlinks inside a workspace remain supported.- Managed writes pass
vault_guard::validate_managed_write, create a snapshot, and use revision-checked atomic replacement. Note deletion remains MCP-only. - Every conflict code the frontend can consume crosses as structured
IpcError. New Rust modules are covered automatically by the ERR-06 guard. - Error normalization accepts only known contract codes. Unknown or forged
codes degrade to a plain
Errorand never satisfy recovery branches. - Provider and subprocess commands use fixed argv rather than a shell whenever input can cross a trust boundary.
- The application has no default telemetry, Maru account, cloud-sync engine, multi-user CRDT, or autonomous-write default.
- Signed update metadata is mandatory. Unsigned or ad-hoc updater feeds are not accepted.
Requirements:
- Node.js 22 or newer
- pnpm 9.15 or newer
- Rust MSRV 1.77.2;
rust-toolchain.tomlpins the repository verification toolchain - Platform libraries required by Tauri 2
Common commands:
pnpm install
# Browser development with mocked Tauri IPC
pnpm dev
# Native development
pnpm tauri:dev
# Focused frontend gates
pnpm typecheck
pnpm lint
pnpm lint:i18n
pnpm test
pnpm test:e2e
pnpm build
# Rust gates
make test-rust
make fmt-check
make clippy
# Complete hermetic verification
make verify
# Phase 08 evidence closure gate alone (365 production commands, PERF-01/PERF-02)
node scripts/check-command-isolation.mjs --all --expected-count 365
# Full verify plus release-only CLI and debug Tauri checks
make release-checks
# Complete local release gate
make release-preflight
# Real installed runtime smoke; not hermetic
make verify-integration
MARU_CLI_SMOKE_ROUNDTRIP=1 make verify-integration
# Local MCP sidecar smoke
MARU_MCP_WORKSPACE="$PWD" node sidecars/maru-mcp/index.mjsSkill registry checks:
cargo run --manifest-path src-tauri/Cargo.toml -p maru-cli --bin maru-cli -- --version
cargo run --manifest-path src-tauri/Cargo.toml -p maru-cli --bin maru-cli -- doctor --json
cargo run --manifest-path src-tauri/Cargo.toml -p maru-cli --bin maru-cli -- skills dirty --json
cargo run --manifest-path src-tauri/Cargo.toml -p maru-cli --bin maru-cli -- skills sync --check --tools claude,codex --jsonmake verify covers:
- four TypeScript projects: application, Node config, E2E, and scripts
- ESLint correctness rules with zero warnings
- release-version synchronization and static architecture guards
- frontend tests and Rust library tests
- rustfmt and clippy with warnings denied
- production frontend build and gzip bundle budgets, including the native-e2e ship-isolation scan of the produced bundle (D-10)
- the Phase 08 evidence closure gate (
check-command-isolation): every registered production command carries final justified worker-boundary, mutation-admission and processing-caller evidence against the 365-command inventory (node scripts/check-command-isolation.mjs --all --expected-count 365)
Pull requests run a lightweight decision job first. Source changes fan out to
make verify and Playwright E2E. Version-changing PRs run make release-checks
instead of the ordinary verify target, adding release-mode CLI and debug Tauri
checks. Documentation-only and .planning/** changes skip expensive CI.
A push to main may reuse the exact PR tree only when the successful PR run is
for the identical head SHA. Direct pushes, merge-tree differences, missing
checks, and API failures run the full suite.
CI E2E runs Chromium against Vite with mocked IPC. It does not prove WKWebView, the native PTY, Korean IME behavior, macOS menus, signing, or notarization. macOS-affecting changes require a real-app or release-artifact check.
The release version's major and minor come from the active GSD milestone in
.planning/STATE.md; releases only increment the patch. Milestone v1.1 ships as
1.1.x, and opening milestone v1.2 moves releases to 1.2.0. There is one tag
namespace and it belongs to releases: milestone completion no longer creates a
git tag.
Version sources must remain synchronized:
package.json
src-tauri/tauri.conf.json
src-tauri/Cargo.toml
src-tauri/maru-cli/Cargo.toml
src-tauri/Cargo.lock (maru and maru-cli package entries)
Release sequence:
- Merge a version PR after release checks and Playwright E2E pass.
- Verify exact-tree
mainCI. - Dispatch and pass Release Preflight.
- Publish a GitHub Release whose tag is exactly
v<package version>and whose target is the verifiedmaincommit.Validate release inputsenforces the prefix and fails before release lookup or bundle creation. - Wait for Release Bundles to finish across macOS ARM, macOS Intel, Linux, and Windows.
- Verify the public artifacts, updater manifest, signatures, and Homebrew tap.
The release workflow produces 20 platform assets, then a single finalizer
publishes latest.json for 11 updater platforms and updates Homebrew. A complete
release therefore has 21 non-empty assets. Platform jobs never race to write
the manifest.
Useful local checks:
make release-version-check
node scripts/check-release-version.mjs --tag v$(node -p "require('./package.json').version")
make macos-distribution-check
make macos-distribution-local-checkPublic macOS releases fail closed unless all signing secrets are configured:
APPLE_CERTIFICATE
APPLE_CERTIFICATE_PASSWORD
KEYCHAIN_PASSWORD
APPLE_ID
APPLE_PASSWORD
APPLE_TEAM_ID
TAURI_SIGNING_PRIVATE_KEY
TAURI_SIGNING_PRIVATE_KEY_PASSWORD
Developer ID signing and Tauri updater signing are separate. The normal release does not enable the browser-passkey provisioning overlay.
Local Apple material belongs outside the repository:
~/workspace/work/.maru/secrets/apple/
DeveloperIDApplication.p12
AuthKey_<APPLE_API_KEY_ID>.p8
certificate-password
api-issuer-id
api-key-id # optional
keychain-password # optional
After downloading release artifacts:
xcrun stapler validate Maru_*.dmg
spctl -a -vv -t open --context context:primary-signature Maru_*.dmg
codesign --verify --deep --strict --verbose=4 Maru.app
spctl -a -vv -t exec Maru.appHomebrew verification:
make homebrew-audit HOMEBREW_TAP_DIR=../homebrew-cask
make homebrew-fetch HOMEBREW_TAP_DIR=../homebrew-caskThe explicit make homebrew-update* targets are recovery tools. The release
finalizer normally updates STAIxBWLB/homebrew-cask automatically after the
manifest succeeds.
Skills deploy independently from the desktop application through
STAIxBWLB/skills. Bundle changes are verified, packaged, minisign-signed, and
published to the skills-channel prerelease. Maru checks after launch and every
six hours, auto-applies only when local skills are clean and runtime-compatible,
and exposes manual check/apply commands in the CLI and Skills UI.
src-tauri/skills-bootstrap/ is a frozen first-run fallback, not the live OTA
source. Refresh it deliberately with make skills-bootstrap-refresh only when
an application release must carry a newer offline bootstrap.
The GSD v1.0 Structural Debt Paydown milestone is complete and archived. The active milestone is v1.1 Felt Quality and Native Proof, spanning phases 6-11. The long-range product plan remains in ROADMAP.md, but planned items there are not active commitments until a GSD milestone promotes them into requirements.
Milestone v1.1 promoted part of the carried-over backlog into requirements. The remaining candidates are:
- ERR-05 closed-enum IPC construction
- Hub evidence index, approval/finalize, certification, and Deck Studio tracks
Maru v1.1.0 intentionally does not include:
- semantic or embedding search
- a Maru account or default telemetry
- a built-in cloud-sync engine
- mobile distribution
- iMessage or Slack ingestion
- multi-user collaboration, CRDT, or realtime editing
- PDF annotation or OCR
- a public skill marketplace server
- agent-autonomous edits as the default behavior
- unsigned updater feeds
- CHANGELOG.md: release-by-release shipped changes
- ROADMAP.md: long-range product tracks
- docs/agents.md: agents and runtime model
- docs/diagram.md: Diagram and report-pattern contracts
- docs/graph.md: Graph storage, interaction, and write safety
- docs/studio.md: Document Studio and native template flow
- docs/hwp-editor.md: lower-level HWP engine bridge
- docs/SSOT-TIERS.md: skill ownership tiers
- docs/BOUNDARIES.md: cross-repository ownership boundaries
- docs/macos-passkeys.md: opt-in passkey distribution runbook
- .planning/reports/MILESTONE_SUMMARY-v1.0.md: completed structural milestone summary
No license file is currently published. All rights reserved unless a license is added.