Skip to content

Claude Code

On macOS and Linux, start:

Terminal window
majlis daemon

For detected Claude installations, startup maintains managed hooks in ~/.claude/settings.json and an optional MCP entry in ~/.claude.json. It preserves foreign settings, records ownership and uses a stable helper under ~/.majlis/bin/majlis-hook.

Run Claude Code normally in your project. A native SessionStart callback supplies its session ID; the daemon physically verifies its checkout and enrolls a worker under the durable local-operator grant. When CLAUDE_ENV_FILE is available, SessionStart exports the exact private session-cache path for later CLI calls. Later callbacks use the persisted native-ID binding; changed cwd cannot move that session to another checkout.

After a daemon restart, the next callback can continue the verified binding into a fresh lifetime. The older unknown lifetime is fenced without claiming that its writer ended cleanly. Explicit session bindings retain precedence.

Auto-enrolled scopes use advisory warn policy. Prospective pre-write intents can show another agent’s overlapping scope; they do not grant a Claude permission. Observing an edit never creates ownership retrospectively. SessionEnd releases intents, while a missing end stays unknown.

Accepted block and ask scopes deny conservatively on outage instead of silently falling back to success. This fail-closed behavior does not establish a verified native strict-enforcement contract. Hooks cannot prevent writes by unrelated processes or agents bypassing them.

Native wake, item-specific acknowledgment, subagent identity and isolated expert execution remain unverified or unavailable. Use the durable inbox and context-refresh paths; transport or wake acceptance must not be described as read confirmation.

Claude hook Majlis event
SessionStart (startup, clear) start
SessionStart (resume) resume
SessionStart (compact), PreCompact compaction
SessionEnd end
PreToolUse on Edit, Write, MultiEdit, NotebookEdit pre_write
PreToolUse on other tools pre_tool (experimental)
PostToolUse / PostToolUseFailure post_tool / post_tool_error
Stop / SubagentStop stop / subagent_stop
UserPromptSubmit / Notification prompt / notification

Unknown events, missing identity, invalid types, payloads over 1 MiB and trailing data are rejected. Automatic enrollment verifies the callback checkout separately; cwd alone never authenticates identity.

These project-level or custom binding flows are optional; normal startup uses the automatic route above.

From an initialized checkout:

Terminal window
majlis install claude --preview-only
majlis install claude

This manages project-local .claude/settings.local.json, preserving unrelated hooks and recording ownership. To remove unchanged owned project entries:

Terminal window
majlis install uninstall claude --preview-only
majlis install uninstall claude

An explicit native binding uses the harness-assigned session ID:

Terminal window
majlis session register <native-id> --actor <handle> --checkout <root> --harness claude

Select the exact returned marker through MAJLIS_SESSION_FILE in the environment inherited by hooks, then continue that same native session. Registration neither accepts workspace policy nor supplies a harness approval. majlis init --harness claude only prepares workspace configuration and credentials; it does not install hooks.

majlis doctor reports binding and capability gaps. The helper enforces a 120 ms daemon deadline inside the 150 ms hook budget. When the daemon or helper is unavailable, the managed wrapper consults the private strict-scope projection: strict scopes deny conservatively and ordinary warn scopes remain advisory. A shell fallback alone cannot prove durable gap persistence.

majlis daemon --no-integrations disables user integration maintenance. majlis uninstall removes unchanged owned user integrations while preserving foreign or uncertain edits. A later normal daemon start installs them again.