Latestinssan/Aartiq

AI-native agentic browser with OS automation capabilities

TypeScript

6

478 commits

updated Oct 4, 2026

See the code

See what people are saying

SourceMessageScoreDate

I'm 16 and built an open source AI browser that asks permission before every action. Works with Ollama (Qwen3 14B tested) (r/LocalLLM)

Hey everyone, This started because I was trying Perplexty's Comet browser and hit the rate limit in under 15 minutes. I got annoyed and thought "I could probably build this myself." That's honestly just irritation. I started in December on a school computer (i5, 8GB RAM). It couldn't even compile…

0

Oct 5, 2026

README

Aartiq™ — For The Questions That Matter

"The most important question isn't what you ask AI. It's what AI asks you before it acts."

Aartiq™ is an open-source AI browser that plans tasks, explains non-trivial actions, requests permission when required, and executes through controlled capabilities.

Plan → Explain → Ask → Execute

v0.3.7 — released 2026-09-13.

Latest release: v0.3.7 · full release notes

License: Apache 2.0 Version Downloads Windows macOS Linux Android Microsoft Store

Aartiq Browser


Why Aartiq?

Traditional browsers help you navigate the web.

AI assistants help you understand information.

Aartiq is built for the space between the two: helping AI carry out tasks while keeping the user in control.

Instead of manually opening tabs, searching websites, filling forms, creating documents, moving files, and repeating workflows, you describe the goal.

Aartiq can turn that goal into structured actions, evaluate those actions against its permission model, request approval when required, and execute through registered capabilities.

AI can act. You decide what it is allowed to do.


See Aartiq in Action

Prompt:

"Search for today's news, create a PDF summary, move it to my Desktop, and open it."

Aartiq task execution demo

The workflow:

Understand
    ↓
Plan
    ↓
Explain
    ↓
Ask
    ↓
Execute
    ↓
Result

Permission Workflow

PlanPermissionResults
imageimageimage

Aartiq searches the web, gathers information, creates the document, requests approval for actions that require it, moves the resulting file, and opens it.


Permission-First AI

Aartiq evaluates each command against its registered capability and permission policy.

Actions that require approval are presented before execution with information about what will happen and what resource or capability is involved.

Risk-Based Permissions

Risk tiers are assigned to the capability being invoked, not inferred from the wording of the prompt. They are advisory labels — the control that actually confines execution is OS sandboxing. Read the last column before relying on any row.

TierApproval behaviourAuto-approved?ExamplesWhat it does not guarantee
lowAsked every time, unless you turn on autoApproveLowRiskShell. With it off — the default — a low-risk command shows the same dialog as any other.Only behind the opt-in autoApproveLowRiskShell setting, which defaults to off. Nothing is granted at startup.ls, cat, pwd, find, grep, echo, NAVIGATEThe setting covers the whole low tier rather than named commands, so turning it on is a decision about a category. It is also independent of the MCP tool path: shell commands read autoApproveLowRiskShell from the permission store, MCP tool calls read a separate security_autoApproveLowRisk key, both default to off, and enabling one does not enable the other.
mediumAsked every time. autoApproveMidRisk does not reach shell commands — it still applies to MCP tool actions, which is a separate question.No. There is no setting that auto-approves a medium shell command.cp, mv, mkdir, touch, npm, git, node, python, curl, wget, osascriptAn unrecognised command lands here rather than in low, so this tier also means "we have never heard of it". "Allow Always" is withheld for network-capable and script-capable binaries, but a local write like cp or mkdir can still take an exact-match permanent grant.
highAsked every time, then offered as Allow Once / Always / Deny.Only if a grant exists for that exact command line, or a SHELL_HIGH / SHELL_ALL grant was made deliberately.chmod, find . -delete, kill, dd, mount, iptables, shutdownA permanent grant is never offered for a destructive command, so the Always button is absent here and Allow Once is the strongest answer available. chmod sits in this tier because it matches a destructive pattern, not because it is privileged in the usual sense — it was already high and moving it down would have weakened a default.
criticalDenied at the policy gate unconditionally, then offered to the user as an interactive Allow / Deny prompt.Never. Refused before the grant store and the auto-approve settings are consulted, and unreachable from every one of them.none assigned by any registryNo command in the tier table is assigned this tier. It is only synthesised at runtime for commands arriving from a remote device. Remote-origin shell execution strictly requires single-use, input-hash-bound QR+PIN ticket redemption.

For the complete command catalog, risk assignments, and implementation details:

AI Command Reference


How It Works

Aartiq converts natural-language goals into structured, permission-aware execution.

┌───────────────────────────┐
│           USER            │
│     Natural-language      │
│           goal            │
└─────────────┬─────────────┘
              │
              ▼
┌───────────────────────────┐
│      AI ORCHESTRATOR      │
│ GPT • Claude • Gemini ... │
└─────────────┬─────────────┘
              │
              ▼
┌───────────────────────────┐
│      TASK PLANNING        │
│   Structured Commands     │
└─────────────┬─────────────┘
              │
              ▼
┌───────────────────────────┐
│   PERMISSION & SECURITY   │
│ Risk • Capability • Scope │
└─────────────┬─────────────┘
              │
              ▼
        ┌──────────────┐
        │   APPROVAL   │
        │   REQUIRED?  │
        └──────┬───────┘
               │
               ▼
┌───────────────────────────┐
│     CONTROLLED EXECUTION  │
│ Browser • Files • OS • OCR│
└─────────────┬─────────────┘
              │
              ▼
┌───────────────────────────┐
│          RESULT           │
└───────────────────────────┘

Actions are exposed through registered capabilities rather than allowing the model unrestricted access to arbitrary system primitives.


Security

Aartiq uses a defense-in-depth security model with risk-based permissions, capability controls, directory allowlists, platform-specific sandboxing, encrypted vault storage, and explicit approval workflows.

The security model, including which layers actually enforce and which only advise:

The model has 6 layers. Only 2 of them are enforcement boundaries in the strict sense — controls the OS applies that application code cannot bypass. The rest are policy and first-pass checks, and are labelled as such rather than presented as equally strong.

#LayerStrengthSource
1Visual Sandbox & SecureDOMheuristic/first-passsrc/lib/Security.ts
2Syntactic Firewallheuristic/first-passsrc/lib/SecurityValidator.js
3Human-in-the-Loop Approvalpolicy layersrc/core/capability-controller.js, src/core/shell-permission-bridge.js
4Directory Allowlistpolicy layersrc/core/directory-allowlist.js
5OS-Level Sandboxingenforcement boundarysrc/core/sandbox-executor.js
6Capability-Scoped Executionenforcement boundarysrc/core/capability-controller.js, src/core/approval-ticket-manager.js

The full model — risk levels, layer-by-layer detail, encryption & vault migration, and remote-device security — is documented on the Security Model page.

Continuous integration

.github/workflows/jest.yml — on-demand.

Manual dispatch only. There is no push or pull_request trigger, so a green run is not evidence about the latest commit.

Latest green run: #34769503518 (run #52, workflow_dispatch, 2026-09-13, acc703ae, success).

JobRunnerPassedSkippedFailedDeclared
Run Jest (aartiq-browser)ubuntu-latest537400577
Run Jest (Windows AppContainer sandbox runtime)windows-latest6130091
Run Jest (macOS Seatbelt sandbox runtime)macos-latest10400104
Run Jest (Linux bubblewrap sandbox runtime)ubuntu-latest5721078

4 jobs. All four jobs were green on the run above. Dispatch inputs can reduce this to 3 (skip-full-suite) or 1 (windows-test-pattern), so this is a default-dispatch count rather than an invariant. Node 24. 30 minutes on the full-suite job; the three sandbox jobs have no timeout configured.

Test counts are generated, not typed. On macOS (local) the full suite reports 1342 passed / 26 skipped / 0 failed of 1368 declared (generated 2026-10-04).

The per-job figures above belong to that run and commit, not to the current tree, which has grown since — for a current figure use the generated macOS line above. The same commit yields a different pass/skip split per platform, which is why every published count carries its environment.

Skip breakdown — macOS (local), 2026-10-04

ReasonSkippedEvidence
Platform-skipped12linux-bwrap-sandbox requires linux; generated on darwin; windows-job-sandbox requires win32; generated on darwin
Missing native OS-automation tooling11automation — tests registered via itWhenAvailable, skipped when the backend is absent (looks for xdotool, xte). Reason in file: "jest-circus has no this.skip() (Jasmine-only). Register the OS // automation tests as skipped unless the native backend exists on this // runner (xdotool / xt"
CRX3 signature-verifier bug3src/tests/extensions.crx-verifier.test.ts — describe.skip

The suite covers approval gating, params-hash verification, fail-closed sandboxing, directory allowlists, capability scoping, and agent token-binding.

Windows sandboxing (v0.3.7+)

v0.3.7 adds AppContainer + Job Object sandboxing on Windows. Before v0.3.7 the Job Object confined processes only; AppContainer adds OS-layer isolation — filesystem via package-SID ACL grants and network via zero capabilities — by starting the target with CreateProcessW in a suspended state inside the AppContainer and applying the Job Object at creation, so nothing runs even momentarily unsandboxed.

  • CI-verified on real Windows (windows-latest): the runtime matrix passes — suspended AppContainer start, OS-enforced ACL allowlist, verified job assignment, grandchild containment, secret isolation, and KILL_ON_JOB_CLOSE all return verified sandbox results.
  • Audited: design + source review in Audit Report/2026-09-13_Windows_AppContainer_Sandbox_Audit/SECURITY_AUDIT.md.
  • Fail-closed: any policy or setup failure returns a structured SANDBOX_* error; there is no fallback path that runs the command unsandboxed.

Network listeners

Every socket the application opens, and what actually protects it:

ServicePortDefault bind addressReachable from LAN whenAuthentication
MCP browser bridge3001127.0.0.1the security_mcpBridgeRemote setting is exactly true (defaults to false; no UI control sets it)A per-process token, required on every route including SSE. Host must be the loopback host and this listener's own port; any browser Origin must be on an allow-list of the app's own origins.
WiFi sync (desktop ↔ mobile)3004all interfaces (0.0.0.0 / ::)always — there is no switch to restrict itShort-lived 15-minute access tokens and 7-day refresh tokens bound to device ID. Every sync action requires an active, unexpired token, with brute-force lockout and explicit unpair revocation.
Native macOS / CLI bridge46203127.0.0.1never — the host is a literal in the source, not a switch anyone can flipA token required on every route, read from ~/.aartiq-token (mode 0600), plus the same Host and Origin checks.
Agent API tool server46204127.0.0.1config.remote === true (defaults to false; no UI, env var, or IPC path sets it)A token, required on every HTTP route, plus the same Host and Origin checks. An unknown x-agent-id is still auto-registered, but as a limited-trust agent — it no longer stands in for authentication.
Background task service (separate Electron app)3999127.0.0.1AARTIQ_SERVICE_HOST is set to a routable address (defaults to 127.0.0.1; no switch in the app)Authentication token required on all file endpoints (Bearer, X-Aartiq-Token, or ?token=) matching active sync session or AARTIQ_SYNC_TOKEN, plus Host header validation against DNS rebinding.

One of these binds all interfaces by default with no switch to restrict it. If you run Aartiq on a shared or untrusted network, that is the part to think about first.

Known limits

  • Runtime sandbox tests execute only on their own OS. There is no single job that exercises Seatbelt, bubblewrap, and AppContainer at once.
  • OS-automation tests skip wherever the native tooling is absent (xdotool/xte on Linux, cliclick on macOS).
  • The CRX3 signature-verifier suite is skipped because verifyCrx() hangs on a Node 24 / OpenSSL header parse. It is counted as skipped, never as passing, until the verifier is fixed.
  • SecurityValidator.js does not guarantee that non-blocked commands are safe — it is a fast first-pass reject layer.
  • Visual extraction reduces the DOM-based prompt-injection surface. It does not prevent prompt injection, and it cannot give semantic immunity against instructions rendered into the viewport.
  • Seatbelt profiles start from (allow default), so not every IPC class is denied by default; Mach IPC stays usable because node/python/shell require it.
  • Apple Events cannot be filtered by the current sandbox-exec — the operation is not exposed — so a sandboxed command could still ask another app to act on its behalf.
  • The WiFi sync server (3004) still binds every network interface by omission and has no token, Host or Origin check; it was changed by neither the listener-authentication work nor the bind-default change. The background task service (3999) and the PDF sync server bound 0.0.0.0 with a wildcard CORS header until the bind default became 127.0.0.1, with AARTIQ_SERVICE_HOST as the explicit opt-in and no CORS allow-origin header sent at all. See network.servers.
  • The session token is per-process, so it changes on every restart. A client configured once — a phone, another machine, a scheduled job — has to be reconfigured, and remote mode is not a finished design because of it.
  • The token has to travel in the mcp-remote URL, because mcp-remote accepts a bare URL and nothing else. It can therefore appear in a process argument list and in a client's own logs. See aartiq-browser/docs-audit/issues/pairing-token-in-url.md.
  • "Allow Always" is keyed on the full normalised command line, which is narrower than before but is still text matching, and a permanent grant has no lifetime. See aartiq-browser/docs-audit/issues/allow-always-granularity.md.
  • A permanent grant requires a binary that appears in the classifier's table. One that does not — including anything we have never seen — is offered Allow Once only, because a grant that repeats a command nobody can describe is a promise about behaviour rather than about the text. Local writes such as cp, mv, mkdir and touch are in the table and keep exact-match permanent grants.
  • The native bridge and the Agent API both defaulted to port 46203, so if both started one failed to bind and the error was logged and swallowed — not visible from outside. The Agent API now defaults to 46204 and the native bridge keeps 46203, so the two no longer collide.

Agent API & Tool Server

Aartiq exposes its browser capabilities to AI agents through a single, security-enforced tool registry served over two transports:

  • MCP (Model Context Protocol) for clients such as Claude Desktop, and
  • HTTP for local scripts, the in-product assistant, and remote access over Tailscale / LAN.

Every tool call — navigation, tab control, form filling, extension management, snapshots, theming, or OS actions — is routed through the SecurityPipeline before it runs. The pipeline performs risk classification, capability matching, and approval-gating.

Multiple agents, one browser

More than one agent can be connected to the same browser at once. Each connection is registered with a trust level that scopes its verbs and origins. A per-tab lock manager ensures two agents can't collide on form filling.

Accessibility snapshots with stable @ref ids

Instead of raw DOM dumps, agents receive an accessibility (AX) tree. Each interactive node carries an identity-bound @ref id derived from the page's backend node id, so a reference stays stable across navigation and DOM changes.

Form filling

Stored credentials and profiles are kept in an encrypted vault (AES-GCM, passphrase-derived key; the same E2EE2 scheme used elsewhere). A field matcher maps page inputs to stored values by autocompleting password fields and typed text.

Chrome extensions

Extensions can be loaded from an on-disk unpacked directory or installed from the Chrome Web Store. Web Store packages are checked as CRX3 before extraction: installFromWebStore calls the verifier and rejects an invalid signature (fail-closed) — src/lib/extensions/ChromeExtensionManager.js:256-266. The verifier's own test suite is currently skipped because verifyCrx hangs on Node 24's OpenSSL (src/tests/extensions.crx-verifier.test.ts:12-16), so signature verification is not covered by CI and is not claimed here to be runtime-verified.

UI themes and modes

The interface supports selectable themes and UI modes (normal, focus, reader, zen, presentation) that adjust what is shown and how the assistant presents itself, independent of the underlying authentication state.


Example Prompts

Try Aartiq with tasks such as:

PromptExample workflow
Search for React tutorials and open the top 3Searches the web and opens relevant results
Summarize this page and save it as a PDFReads the page and generates a structured PDF
Set brightness to 50% and open VS CodeUses supported system capabilities
Create a PowerPoint about climate changeGenerates a structured presentation
Schedule a daily backup at 9 AMCreates a recurring background task
Read the text in this screenshotUses OCR / visual intelligence
Fill this form with my detailsIdentifies and fills supported form fields
Search for electron performance and extract the resultsPerforms browser-based research

For every available command and its risk classification:

AI Command Reference →


AI Providers

Aartiq supports multiple AI backends, including:

  • Google Gemini
  • OpenAI GPT
  • Anthropic Claude
  • Groq
  • xAI
  • Azure OpenAI
  • Ollama (local)
  • LM Studio (local, OpenAI-compatible)
  • Apple Intelligence on macOS

Provider availability depends on the platform and configuration. Local models (Ollama, LM Studio) keep request content on the device; an OpenClaw-compatible local-agent bridge is also supported for remote inference.


Performance

Aartiq opens the Chromium window immediately and loads background services asynchronously, so the interface is usable before every subsystem has finished starting. Long-running automation runs as a background task, not a blocking modal.

Benchmark

Measured on a MacBook Pro M4 Pro, 12-core CPU, 24 GB RAM, macOS 26.5.

2026-07-20 — benchmarked on v0.3.4. Current release: v0.3.7.

MetricResult
First visible window0.32s
Warm start0.31s
Idle CPU after initialization<1%

Startup means time to first visible window, not complete service initialisation. Results vary by hardware, operating system, and configuration.

These figures predate the current release (v0.3.7) and were taken on v0.3.4. TODO(verify) — no benchmark script, raw output file, or instrumentation exists in either repository. These figures cannot currently be reproduced or checked. A published page also claimed the benchmark scripts were included in the repository; that claim was false and has been removed.

Detailed measurements and methodology:

Performance Benchmarks →


Installation

Pre-built Binaries

PlatformFormat
Windows.exe / .msix
WindowsMicrosoft Store
macOS — Apple Silicon.dmg
macOS — Intel.dmg
Linux.AppImage
Android.apk

Download the latest release from:

Aartiq Releases →

macOS

If macOS blocks the application:

xattr -cr /Applications/Aartiq.app

Build From Source

git clone https://github.com/Latestinssan/Aartiq.git
cd Aartiq/aartiq-browser

npm install

# Next.js development server
npm run dev

# Electron shell
npm run electron-start

Android

cd flutter_browser_app

flutter pub get
flutter run

Documentation

The GitHub README provides the product overview. Detailed architecture and implementation documentation lives on the Aartiq documentation site.

TopicDocumentation
Overview & ArchitectureOverview
Security ModelSecurity
AI CommandsCommand Reference
API ReferenceAPI Reference
ComponentsComponents
AutomationAutomation
Cloud SyncCloud Sync
TroubleshootingTroubleshooting
ChangelogChangelog
Release notes (source)release_notes/

Contributors

Built by Latestinssan with contributions from the community.

StarsForksContributorsVisibility
623public

Fetched from the GitHub API. Refresh with npm run docs:repo-facts.


[!IMPORTANT]

🚧 Project Status

Aartiq is a solo project maintained in an AI-assisted rhythm: AI agents handle day-to-day issue triage, analysis, and fix preparation, and a human reviews and approves every change to security, permissions, user data, or releases before it ships. Development currently runs at a limited pace around academic commitments — feature work pauses and resumes in bursts rather than on a fixed schedule. The repository stays public, existing releases stay available, and bug reports go to GitHub issues, triaged in the order things break. In short:

  • Every change to security, permissions, user data, releases, or project direction is reviewed and approved by a human before it ships.
  • CI must be green before any release goes out (see the Security section above for the current test numbers).
  • The maintainer remains responsible for the project's direction and correctness.

Why this setup: it lets a solo project keep shipping fixes and improvements without requiring full-time human bandwidth on every routine task, while keeping a human in the loop for anything consequential — which is the same philosophy Aartiq applies to its own permission model.

Bigger roadmap items (new features, larger refactors, community contribution workflows) are paused until there's more bandwidth or contributors to support them. Bug fixes, security patches, and documentation stay actively maintained.

Issues, PRs, and questions are welcome — response time may vary, but nothing ships without review.

— Latestinssan

Terminology

TermDefinition
CapabilityA registered action the model may invoke. Capabilities are the only way to affect the system — there is no unrestricted access to system primitives.
Approval ticketA single-use, time-limited token that authorises one capability execution and is consumed on use.
SkillA named, loadable instruction bundle that shapes how the assistant approaches a class of task. Distinct from a capability: a skill changes behaviour, a capability changes the system.
Risk tierAn advisory label (low / medium / high / critical) attached to a capability or derived for a command. It is not itself an enforcement boundary — see security.riskTiers.
Enforcement boundaryA control the OS applies, which application code cannot bypass. Only OS sandboxing and capability scoping qualify.
Fail-closedIf a control cannot be established or verified, the action does not run. There is no fallback path that runs it anyway.
Monitoring-onlyCode that observes and reports but does not block. It never gates an action, and should never be counted as if it did.
Agent APIThe HTTP and MCP transports that expose the capability registry to external agents. Both pass every call through the security pipeline.
Local-firstUser data stays on the device. Local models keep request content local; sync is end-to-end encrypted; credentials live in the OS keychain.

License

ComponentLicenceLicence fileStatus
Aartiq Browser — desktop, mobile, and core codeApache-2.0LICENSE + aartiq-browser/LICENSE.txtverified
Aartiq MCP Server — aartiq-mcp/MITaartiq-mcp/LICENSEverified
Landing page / documentation siteUnlicensed (private repository)noneverified

[!NOTE] Licence conflict resolved (2026-10-04). aartiq-browser/LICENSE.txt now carries the same Apache-2.0 text as the repository root, the package manifest declares Apache-2.0, and the Windows installer points at that same file — so installer, manifest and repository agree. The decision, including the EULA it replaced, is recorded in aartiq-browser/docs-audit/licence-decision.md. docs:check rule (j) fails if the copies ever disagree again.

The MCP server is MIT-licensed for compatibility with Claude Desktop and other MCP clients.

Trademark

Aartiq™ is a trademark of Latestinssan.

Aartiq™ is a trademark of Latestinssan. The open-source licence permits use, modification, and redistribution of the source code. It does not grant permission to use the Aartiq name, logo, trademarks, or visual identity. Modified distributions must be rebranded under a different name and must not present themselves as official Aartiq releases.


For The Questions That Matter.

The most important question isn't what you ask AI. It's what AI asks you before it acts.

Plan → Explain → Ask → Execute

Aartiq™

© 2026 Aartiq™. All rights reserved.

Latestinssan/Aartiq

AI-native agentic browser with OS automation capabilities

TypeScript

6

478 commits

updated Oct 4, 2026

See the code

See what people are saying

SourceMessageScoreDate

I'm 16 and built an open source AI browser that asks permission before every action. Works with Ollama (Qwen3 14B tested) (r/LocalLLM)

Hey everyone, This started because I was trying Perplexty's Comet browser and hit the rate limit in under 15 minutes. I got annoyed and thought "I could probably build this myself." That's honestly just irritation. I started in December on a school computer (i5, 8GB RAM). It couldn't even compile…

0

Oct 5, 2026

README

Aartiq™ — For The Questions That Matter

"The most important question isn't what you ask AI. It's what AI asks you before it acts."

Aartiq™ is an open-source AI browser that plans tasks, explains non-trivial actions, requests permission when required, and executes through controlled capabilities.

Plan → Explain → Ask → Execute

v0.3.7 — released 2026-09-13.

Latest release: v0.3.7 · full release notes

License: Apache 2.0 Version Downloads Windows macOS Linux Android Microsoft Store

Aartiq Browser


Why Aartiq?

Traditional browsers help you navigate the web.

AI assistants help you understand information.

Aartiq is built for the space between the two: helping AI carry out tasks while keeping the user in control.

Instead of manually opening tabs, searching websites, filling forms, creating documents, moving files, and repeating workflows, you describe the goal.

Aartiq can turn that goal into structured actions, evaluate those actions against its permission model, request approval when required, and execute through registered capabilities.

AI can act. You decide what it is allowed to do.


See Aartiq in Action

Prompt:

"Search for today's news, create a PDF summary, move it to my Desktop, and open it."

Aartiq task execution demo

The workflow:

Understand
    ↓
Plan
    ↓
Explain
    ↓
Ask
    ↓
Execute
    ↓
Result

Permission Workflow

PlanPermissionResults
imageimageimage

Aartiq searches the web, gathers information, creates the document, requests approval for actions that require it, moves the resulting file, and opens it.


Permission-First AI

Aartiq evaluates each command against its registered capability and permission policy.

Actions that require approval are presented before execution with information about what will happen and what resource or capability is involved.

Risk-Based Permissions

Risk tiers are assigned to the capability being invoked, not inferred from the wording of the prompt. They are advisory labels — the control that actually confines execution is OS sandboxing. Read the last column before relying on any row.

TierApproval behaviourAuto-approved?ExamplesWhat it does not guarantee
lowAsked every time, unless you turn on autoApproveLowRiskShell. With it off — the default — a low-risk command shows the same dialog as any other.Only behind the opt-in autoApproveLowRiskShell setting, which defaults to off. Nothing is granted at startup.ls, cat, pwd, find, grep, echo, NAVIGATEThe setting covers the whole low tier rather than named commands, so turning it on is a decision about a category. It is also independent of the MCP tool path: shell commands read autoApproveLowRiskShell from the permission store, MCP tool calls read a separate security_autoApproveLowRisk key, both default to off, and enabling one does not enable the other.
mediumAsked every time. autoApproveMidRisk does not reach shell commands — it still applies to MCP tool actions, which is a separate question.No. There is no setting that auto-approves a medium shell command.cp, mv, mkdir, touch, npm, git, node, python, curl, wget, osascriptAn unrecognised command lands here rather than in low, so this tier also means "we have never heard of it". "Allow Always" is withheld for network-capable and script-capable binaries, but a local write like cp or mkdir can still take an exact-match permanent grant.
highAsked every time, then offered as Allow Once / Always / Deny.Only if a grant exists for that exact command line, or a SHELL_HIGH / SHELL_ALL grant was made deliberately.chmod, find . -delete, kill, dd, mount, iptables, shutdownA permanent grant is never offered for a destructive command, so the Always button is absent here and Allow Once is the strongest answer available. chmod sits in this tier because it matches a destructive pattern, not because it is privileged in the usual sense — it was already high and moving it down would have weakened a default.
criticalDenied at the policy gate unconditionally, then offered to the user as an interactive Allow / Deny prompt.Never. Refused before the grant store and the auto-approve settings are consulted, and unreachable from every one of them.none assigned by any registryNo command in the tier table is assigned this tier. It is only synthesised at runtime for commands arriving from a remote device. Remote-origin shell execution strictly requires single-use, input-hash-bound QR+PIN ticket redemption.

For the complete command catalog, risk assignments, and implementation details:

AI Command Reference


How It Works

Aartiq converts natural-language goals into structured, permission-aware execution.

┌───────────────────────────┐
│           USER            │
│     Natural-language      │
│           goal            │
└─────────────┬─────────────┘
              │
              ▼
┌───────────────────────────┐
│      AI ORCHESTRATOR      │
│ GPT • Claude • Gemini ... │
└─────────────┬─────────────┘
              │
              ▼
┌───────────────────────────┐
│      TASK PLANNING        │
│   Structured Commands     │
└─────────────┬─────────────┘
              │
              ▼
┌───────────────────────────┐
│   PERMISSION & SECURITY   │
│ Risk • Capability • Scope │
└─────────────┬─────────────┘
              │
              ▼
        ┌──────────────┐
        │   APPROVAL   │
        │   REQUIRED?  │
        └──────┬───────┘
               │
               ▼
┌───────────────────────────┐
│     CONTROLLED EXECUTION  │
│ Browser • Files • OS • OCR│
└─────────────┬─────────────┘
              │
              ▼
┌───────────────────────────┐
│          RESULT           │
└───────────────────────────┘

Actions are exposed through registered capabilities rather than allowing the model unrestricted access to arbitrary system primitives.


Security

Aartiq uses a defense-in-depth security model with risk-based permissions, capability controls, directory allowlists, platform-specific sandboxing, encrypted vault storage, and explicit approval workflows.

The security model, including which layers actually enforce and which only advise:

The model has 6 layers. Only 2 of them are enforcement boundaries in the strict sense — controls the OS applies that application code cannot bypass. The rest are policy and first-pass checks, and are labelled as such rather than presented as equally strong.

#LayerStrengthSource
1Visual Sandbox & SecureDOMheuristic/first-passsrc/lib/Security.ts
2Syntactic Firewallheuristic/first-passsrc/lib/SecurityValidator.js
3Human-in-the-Loop Approvalpolicy layersrc/core/capability-controller.js, src/core/shell-permission-bridge.js
4Directory Allowlistpolicy layersrc/core/directory-allowlist.js
5OS-Level Sandboxingenforcement boundarysrc/core/sandbox-executor.js
6Capability-Scoped Executionenforcement boundarysrc/core/capability-controller.js, src/core/approval-ticket-manager.js

The full model — risk levels, layer-by-layer detail, encryption & vault migration, and remote-device security — is documented on the Security Model page.

Continuous integration

.github/workflows/jest.yml — on-demand.

Manual dispatch only. There is no push or pull_request trigger, so a green run is not evidence about the latest commit.

Latest green run: #34769503518 (run #52, workflow_dispatch, 2026-09-13, acc703ae, success).

JobRunnerPassedSkippedFailedDeclared
Run Jest (aartiq-browser)ubuntu-latest537400577
Run Jest (Windows AppContainer sandbox runtime)windows-latest6130091
Run Jest (macOS Seatbelt sandbox runtime)macos-latest10400104
Run Jest (Linux bubblewrap sandbox runtime)ubuntu-latest5721078

4 jobs. All four jobs were green on the run above. Dispatch inputs can reduce this to 3 (skip-full-suite) or 1 (windows-test-pattern), so this is a default-dispatch count rather than an invariant. Node 24. 30 minutes on the full-suite job; the three sandbox jobs have no timeout configured.

Test counts are generated, not typed. On macOS (local) the full suite reports 1342 passed / 26 skipped / 0 failed of 1368 declared (generated 2026-10-04).

The per-job figures above belong to that run and commit, not to the current tree, which has grown since — for a current figure use the generated macOS line above. The same commit yields a different pass/skip split per platform, which is why every published count carries its environment.

Skip breakdown — macOS (local), 2026-10-04

ReasonSkippedEvidence
Platform-skipped12linux-bwrap-sandbox requires linux; generated on darwin; windows-job-sandbox requires win32; generated on darwin
Missing native OS-automation tooling11automation — tests registered via itWhenAvailable, skipped when the backend is absent (looks for xdotool, xte). Reason in file: "jest-circus has no this.skip() (Jasmine-only). Register the OS // automation tests as skipped unless the native backend exists on this // runner (xdotool / xt"
CRX3 signature-verifier bug3src/tests/extensions.crx-verifier.test.ts — describe.skip

The suite covers approval gating, params-hash verification, fail-closed sandboxing, directory allowlists, capability scoping, and agent token-binding.

Windows sandboxing (v0.3.7+)

v0.3.7 adds AppContainer + Job Object sandboxing on Windows. Before v0.3.7 the Job Object confined processes only; AppContainer adds OS-layer isolation — filesystem via package-SID ACL grants and network via zero capabilities — by starting the target with CreateProcessW in a suspended state inside the AppContainer and applying the Job Object at creation, so nothing runs even momentarily unsandboxed.

  • CI-verified on real Windows (windows-latest): the runtime matrix passes — suspended AppContainer start, OS-enforced ACL allowlist, verified job assignment, grandchild containment, secret isolation, and KILL_ON_JOB_CLOSE all return verified sandbox results.
  • Audited: design + source review in Audit Report/2026-09-13_Windows_AppContainer_Sandbox_Audit/SECURITY_AUDIT.md.
  • Fail-closed: any policy or setup failure returns a structured SANDBOX_* error; there is no fallback path that runs the command unsandboxed.

Network listeners

Every socket the application opens, and what actually protects it:

ServicePortDefault bind addressReachable from LAN whenAuthentication
MCP browser bridge3001127.0.0.1the security_mcpBridgeRemote setting is exactly true (defaults to false; no UI control sets it)A per-process token, required on every route including SSE. Host must be the loopback host and this listener's own port; any browser Origin must be on an allow-list of the app's own origins.
WiFi sync (desktop ↔ mobile)3004all interfaces (0.0.0.0 / ::)always — there is no switch to restrict itShort-lived 15-minute access tokens and 7-day refresh tokens bound to device ID. Every sync action requires an active, unexpired token, with brute-force lockout and explicit unpair revocation.
Native macOS / CLI bridge46203127.0.0.1never — the host is a literal in the source, not a switch anyone can flipA token required on every route, read from ~/.aartiq-token (mode 0600), plus the same Host and Origin checks.
Agent API tool server46204127.0.0.1config.remote === true (defaults to false; no UI, env var, or IPC path sets it)A token, required on every HTTP route, plus the same Host and Origin checks. An unknown x-agent-id is still auto-registered, but as a limited-trust agent — it no longer stands in for authentication.
Background task service (separate Electron app)3999127.0.0.1AARTIQ_SERVICE_HOST is set to a routable address (defaults to 127.0.0.1; no switch in the app)Authentication token required on all file endpoints (Bearer, X-Aartiq-Token, or ?token=) matching active sync session or AARTIQ_SYNC_TOKEN, plus Host header validation against DNS rebinding.

One of these binds all interfaces by default with no switch to restrict it. If you run Aartiq on a shared or untrusted network, that is the part to think about first.

Known limits

  • Runtime sandbox tests execute only on their own OS. There is no single job that exercises Seatbelt, bubblewrap, and AppContainer at once.
  • OS-automation tests skip wherever the native tooling is absent (xdotool/xte on Linux, cliclick on macOS).
  • The CRX3 signature-verifier suite is skipped because verifyCrx() hangs on a Node 24 / OpenSSL header parse. It is counted as skipped, never as passing, until the verifier is fixed.
  • SecurityValidator.js does not guarantee that non-blocked commands are safe — it is a fast first-pass reject layer.
  • Visual extraction reduces the DOM-based prompt-injection surface. It does not prevent prompt injection, and it cannot give semantic immunity against instructions rendered into the viewport.
  • Seatbelt profiles start from (allow default), so not every IPC class is denied by default; Mach IPC stays usable because node/python/shell require it.
  • Apple Events cannot be filtered by the current sandbox-exec — the operation is not exposed — so a sandboxed command could still ask another app to act on its behalf.
  • The WiFi sync server (3004) still binds every network interface by omission and has no token, Host or Origin check; it was changed by neither the listener-authentication work nor the bind-default change. The background task service (3999) and the PDF sync server bound 0.0.0.0 with a wildcard CORS header until the bind default became 127.0.0.1, with AARTIQ_SERVICE_HOST as the explicit opt-in and no CORS allow-origin header sent at all. See network.servers.
  • The session token is per-process, so it changes on every restart. A client configured once — a phone, another machine, a scheduled job — has to be reconfigured, and remote mode is not a finished design because of it.
  • The token has to travel in the mcp-remote URL, because mcp-remote accepts a bare URL and nothing else. It can therefore appear in a process argument list and in a client's own logs. See aartiq-browser/docs-audit/issues/pairing-token-in-url.md.
  • "Allow Always" is keyed on the full normalised command line, which is narrower than before but is still text matching, and a permanent grant has no lifetime. See aartiq-browser/docs-audit/issues/allow-always-granularity.md.
  • A permanent grant requires a binary that appears in the classifier's table. One that does not — including anything we have never seen — is offered Allow Once only, because a grant that repeats a command nobody can describe is a promise about behaviour rather than about the text. Local writes such as cp, mv, mkdir and touch are in the table and keep exact-match permanent grants.
  • The native bridge and the Agent API both defaulted to port 46203, so if both started one failed to bind and the error was logged and swallowed — not visible from outside. The Agent API now defaults to 46204 and the native bridge keeps 46203, so the two no longer collide.

Agent API & Tool Server

Aartiq exposes its browser capabilities to AI agents through a single, security-enforced tool registry served over two transports:

  • MCP (Model Context Protocol) for clients such as Claude Desktop, and
  • HTTP for local scripts, the in-product assistant, and remote access over Tailscale / LAN.

Every tool call — navigation, tab control, form filling, extension management, snapshots, theming, or OS actions — is routed through the SecurityPipeline before it runs. The pipeline performs risk classification, capability matching, and approval-gating.

Multiple agents, one browser

More than one agent can be connected to the same browser at once. Each connection is registered with a trust level that scopes its verbs and origins. A per-tab lock manager ensures two agents can't collide on form filling.

Accessibility snapshots with stable @ref ids

Instead of raw DOM dumps, agents receive an accessibility (AX) tree. Each interactive node carries an identity-bound @ref id derived from the page's backend node id, so a reference stays stable across navigation and DOM changes.

Form filling

Stored credentials and profiles are kept in an encrypted vault (AES-GCM, passphrase-derived key; the same E2EE2 scheme used elsewhere). A field matcher maps page inputs to stored values by autocompleting password fields and typed text.

Chrome extensions

Extensions can be loaded from an on-disk unpacked directory or installed from the Chrome Web Store. Web Store packages are checked as CRX3 before extraction: installFromWebStore calls the verifier and rejects an invalid signature (fail-closed) — src/lib/extensions/ChromeExtensionManager.js:256-266. The verifier's own test suite is currently skipped because verifyCrx hangs on Node 24's OpenSSL (src/tests/extensions.crx-verifier.test.ts:12-16), so signature verification is not covered by CI and is not claimed here to be runtime-verified.

UI themes and modes

The interface supports selectable themes and UI modes (normal, focus, reader, zen, presentation) that adjust what is shown and how the assistant presents itself, independent of the underlying authentication state.


Example Prompts

Try Aartiq with tasks such as:

PromptExample workflow
Search for React tutorials and open the top 3Searches the web and opens relevant results
Summarize this page and save it as a PDFReads the page and generates a structured PDF
Set brightness to 50% and open VS CodeUses supported system capabilities
Create a PowerPoint about climate changeGenerates a structured presentation
Schedule a daily backup at 9 AMCreates a recurring background task
Read the text in this screenshotUses OCR / visual intelligence
Fill this form with my detailsIdentifies and fills supported form fields
Search for electron performance and extract the resultsPerforms browser-based research

For every available command and its risk classification:

AI Command Reference →


AI Providers

Aartiq supports multiple AI backends, including:

  • Google Gemini
  • OpenAI GPT
  • Anthropic Claude
  • Groq
  • xAI
  • Azure OpenAI
  • Ollama (local)
  • LM Studio (local, OpenAI-compatible)
  • Apple Intelligence on macOS

Provider availability depends on the platform and configuration. Local models (Ollama, LM Studio) keep request content on the device; an OpenClaw-compatible local-agent bridge is also supported for remote inference.


Performance

Aartiq opens the Chromium window immediately and loads background services asynchronously, so the interface is usable before every subsystem has finished starting. Long-running automation runs as a background task, not a blocking modal.

Benchmark

Measured on a MacBook Pro M4 Pro, 12-core CPU, 24 GB RAM, macOS 26.5.

2026-07-20 — benchmarked on v0.3.4. Current release: v0.3.7.

MetricResult
First visible window0.32s
Warm start0.31s
Idle CPU after initialization<1%

Startup means time to first visible window, not complete service initialisation. Results vary by hardware, operating system, and configuration.

These figures predate the current release (v0.3.7) and were taken on v0.3.4. TODO(verify) — no benchmark script, raw output file, or instrumentation exists in either repository. These figures cannot currently be reproduced or checked. A published page also claimed the benchmark scripts were included in the repository; that claim was false and has been removed.

Detailed measurements and methodology:

Performance Benchmarks →


Installation

Pre-built Binaries

PlatformFormat
Windows.exe / .msix
WindowsMicrosoft Store
macOS — Apple Silicon.dmg
macOS — Intel.dmg
Linux.AppImage
Android.apk

Download the latest release from:

Aartiq Releases →

macOS

If macOS blocks the application:

xattr -cr /Applications/Aartiq.app

Build From Source

git clone https://github.com/Latestinssan/Aartiq.git
cd Aartiq/aartiq-browser

npm install

# Next.js development server
npm run dev

# Electron shell
npm run electron-start

Android

cd flutter_browser_app

flutter pub get
flutter run

Documentation

The GitHub README provides the product overview. Detailed architecture and implementation documentation lives on the Aartiq documentation site.

TopicDocumentation
Overview & ArchitectureOverview
Security ModelSecurity
AI CommandsCommand Reference
API ReferenceAPI Reference
ComponentsComponents
AutomationAutomation
Cloud SyncCloud Sync
TroubleshootingTroubleshooting
ChangelogChangelog
Release notes (source)release_notes/

Contributors

Built by Latestinssan with contributions from the community.

StarsForksContributorsVisibility
623public

Fetched from the GitHub API. Refresh with npm run docs:repo-facts.


[!IMPORTANT]

🚧 Project Status

Aartiq is a solo project maintained in an AI-assisted rhythm: AI agents handle day-to-day issue triage, analysis, and fix preparation, and a human reviews and approves every change to security, permissions, user data, or releases before it ships. Development currently runs at a limited pace around academic commitments — feature work pauses and resumes in bursts rather than on a fixed schedule. The repository stays public, existing releases stay available, and bug reports go to GitHub issues, triaged in the order things break. In short:

  • Every change to security, permissions, user data, releases, or project direction is reviewed and approved by a human before it ships.
  • CI must be green before any release goes out (see the Security section above for the current test numbers).
  • The maintainer remains responsible for the project's direction and correctness.

Why this setup: it lets a solo project keep shipping fixes and improvements without requiring full-time human bandwidth on every routine task, while keeping a human in the loop for anything consequential — which is the same philosophy Aartiq applies to its own permission model.

Bigger roadmap items (new features, larger refactors, community contribution workflows) are paused until there's more bandwidth or contributors to support them. Bug fixes, security patches, and documentation stay actively maintained.

Issues, PRs, and questions are welcome — response time may vary, but nothing ships without review.

— Latestinssan

Terminology

TermDefinition
CapabilityA registered action the model may invoke. Capabilities are the only way to affect the system — there is no unrestricted access to system primitives.
Approval ticketA single-use, time-limited token that authorises one capability execution and is consumed on use.
SkillA named, loadable instruction bundle that shapes how the assistant approaches a class of task. Distinct from a capability: a skill changes behaviour, a capability changes the system.
Risk tierAn advisory label (low / medium / high / critical) attached to a capability or derived for a command. It is not itself an enforcement boundary — see security.riskTiers.
Enforcement boundaryA control the OS applies, which application code cannot bypass. Only OS sandboxing and capability scoping qualify.
Fail-closedIf a control cannot be established or verified, the action does not run. There is no fallback path that runs it anyway.
Monitoring-onlyCode that observes and reports but does not block. It never gates an action, and should never be counted as if it did.
Agent APIThe HTTP and MCP transports that expose the capability registry to external agents. Both pass every call through the security pipeline.
Local-firstUser data stays on the device. Local models keep request content local; sync is end-to-end encrypted; credentials live in the OS keychain.

License

ComponentLicenceLicence fileStatus
Aartiq Browser — desktop, mobile, and core codeApache-2.0LICENSE + aartiq-browser/LICENSE.txtverified
Aartiq MCP Server — aartiq-mcp/MITaartiq-mcp/LICENSEverified
Landing page / documentation siteUnlicensed (private repository)noneverified

[!NOTE] Licence conflict resolved (2026-10-04). aartiq-browser/LICENSE.txt now carries the same Apache-2.0 text as the repository root, the package manifest declares Apache-2.0, and the Windows installer points at that same file — so installer, manifest and repository agree. The decision, including the EULA it replaced, is recorded in aartiq-browser/docs-audit/licence-decision.md. docs:check rule (j) fails if the copies ever disagree again.

The MCP server is MIT-licensed for compatibility with Claude Desktop and other MCP clients.

Trademark

Aartiq™ is a trademark of Latestinssan.

Aartiq™ is a trademark of Latestinssan. The open-source licence permits use, modification, and redistribution of the source code. It does not grant permission to use the Aartiq name, logo, trademarks, or visual identity. Modified distributions must be rebranded under a different name and must not present themselves as official Aartiq releases.


For The Questions That Matter.

The most important question isn't what you ask AI. It's what AI asks you before it acts.

Plan → Explain → Ask → Execute

Aartiq™

© 2026 Aartiq™. All rights reserved.