ORRERY
Health Uyari
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 6 GitHub stars
Code Basarisiz
- process.env — Environment variable access in plugins/orrery/mcp/server.test.ts
- Hardcoded secret — Potential hardcoded credential in plugins/orrery/mcp/server.test.ts
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Sol, Terra and Luna - in exact motion
ORRERY
Sol, Terra and Luna — in exact motion.
Architect-first orchestration for coding agents.
Exact model pinning. Consented writes. Fail-closed, always.
What this is
Orrery keeps you the architect.
Your main chat owns the requirements, the architecture, the decomposition, the diff review and the acceptance. It delegates implementation to three roles you pin yourself — a routine implementer, a high-complexity implementer, and a read-only advisor that returns exactly ship, fix-first, or rethink. Worker reports are treated as claims until you verify them.
The same rule applies to client adapters: rendered files express requested model, effort, and read-only behavior, but only a live host observation can prove that a client honored them. See the compatibility evidence matrix.
An orrery is a clockwork model of the solar system: every body driven in exact, inspectable relation, nothing drifting on its own. That is the contract.
The problem
Handing a whole feature to one agent and hoping is not engineering. But the fix — a lead agent that decomposes work and delegates to specialists — runs straight into two walls:
- Every client defines subagents differently. One wants
.codex/agents/*.toml, another.cursor/agents/*.md, another.claude/agents/*.md. They bind different things: some pin a model and reasoning effort and a sandbox, some pin only a model. - A plugin that writes into your agent config is privileged. If a prompt-injected model can talk it into writing an arbitrary file to an arbitrary path, you have handed an attacker your editor.
Orrery solves the first without ever conceding the second.
How it works
YOU
│
▼
┌─────────────────────────────────────────────┐
│ PARENT CHAT = ARCHITECT │
│ inherits YOUR model and reasoning effort │
│ │
│ owns: requirements · architecture · │
│ decomposition · the actual diff · │
│ re-running checks · acceptance │
└──────────────────┬──────────────────────────┘
│ delegates, then verifies
┌───────────────┼───────────────┐
▼ ▼ ▼
┌────────┐ ┌────────┐ ┌──────────┐
│ROUTINE │ │ HIGH │ │ ADVISOR │
│bounded │ │security│ │ read-only│
│ wiring │ │concurr.│ │ ship / │
│ specs │ │migrat. │ │fix-first/│
│ │ │refactor│ │ rethink │
└────────┘ └────────┘ └──────────┘
The parent never types implementation code when a delegated lane can do it. Workers receive a complete five-part specification — objective, file ownership, interfaces, constraints, verification — and return structured evidence. The parent then inspects the working tree, confirms only in-scope files changed, and re-runs the verification commands itself before a fresh advisor is asked for a verdict.
A ship verdict is not the end of a conversation. It is the end of an audit.
The one rule everything rests on
The model can never choose where a file is written.
Destinations are derived, never supplied. Only a workspace path crosses the tool boundary; the plugin computes the three legal destinations from (client, scope, workspace) and a fixed filename table. There is no code path in which a caller names a target.
Everything else is built on top of that.
Security model
| Control | How it is enforced |
|---|---|
| Derived destinations | Computed from client + scope + workspace. The write set is exactly three known paths, always. |
| Allowlisted writes | Every destination is re-checked against the workspace root (project scope) or the real home directory (user scope), and refused if any path component is a symlink. |
| Exact plans | A preview mints a single-use token bound to a digest of the planned content and the observed on-disk state. If anything changed since the preview, install refuses. Tokens expire in 10 minutes and do not survive a restart. |
| Second token for user scope | A separate INSTALL USER <nonce> carrying an independent nonce, so it cannot be derived from the install token. A generic "yes" is never accepted. |
| No silent clobbering | An unmanaged file at a destination is refused outright. A managed file must still hash to its recorded value, and is quarantined — not deleted — with a device/inode identity check before replacement. |
| Crash-safe transactions | A fsynced write-ahead journal records intent before publishing a link. Rollback is driven by that record, never by comparing content hashes, so an idempotent re-install cannot make it delete a file the transaction never wrote. |
| Serialized mutations | An exclusive lock over the plugin data directory. Acquisition is a plain exclusive create, so a live lock is never lifted; the only removal happens while holding a separate reclaim ticket, so at most one process is ever between removing a stale lock and creating its own. |
| Scoped recovery | Crash recovery deletes and renames files, so it runs only inside a tool that already declares destructive intent. Every other tool reports pendingRecovery instead. |
| No credentials, ever | Input is recursively scanned; any key matching secret, token, password, api key, credential, or private key is rejected. |
| No injection into role files | Carriage returns, newlines and NUL bytes are rejected in every string input, so no value can smuggle extra TOML keys or YAML frontmatter into a generated agent file. |
| No unenforceable claims | A client that cannot bind per-agent reasoning effort is refused when asked to store one, rather than persisting a comfortable lie. |
Tool-surface consent
The unsolved attack against MCP servers is the rug pull: a server is approved with benign tool descriptions, then mutates them afterwards to smuggle instructions into every agent that trusts it. The published mitigation is to pin tool descriptions at approval time and re-prompt if they ever change.
Orrery implements it.
TOOLS_DIGESTis the SHA-256 of the complete tool surface — every name, description, input schema, output schema and behaviour annotation.- CI asserts it matches a checked-in pin, so no description can change without a deliberate, reviewable commit.
- Setup records the digest you approved.
- Any later mismatch reports status
tools-changedand blocks every stateful operation until a human re-approves.
Call get_setup_status at any time and compare toolsDigest against approvedToolsDigest. If they differ, something moved.
Supported clients
Orrery states exactly what each host can and cannot enforce, and refuses to store a setting the host will not honour.
| Client | Project adapter | User adapter | Advisor read-only | Binds effort |
|---|---|---|---|---|
| Codex | .codex/agents/*.toml |
~/.codex/agents/*.toml |
os-sandbox |
yes |
| Cursor | .cursor/agents/*.md |
~/.cursor/agents/*.md |
frontmatter-flag |
yes |
| Claude Code | .claude/agents/*.md |
~/.claude/agents/*.md |
tool-allowlist |
no |
| VS Code | .github/agents/*.agent.md |
~/.copilot/agents/*.agent.md |
prompt-only |
no |
| GitHub Copilot | .github/agents/*.agent.md |
~/.copilot/agents/*.agent.md |
prompt-only |
no |
| Kiro | .kiro/agents/*.md |
~/.kiro/agents/*.md |
prompt-only |
no |
Read the read-only column carefully — this is the part most tools overstate.
os-sandbox— a read-only sandbox is requested. Only the observed sandbox policy proves isolation.tool-allowlist— the advisor is restricted to read tools. Real enforcement, but not an OS boundary.frontmatter-flag— a declared flag whose behaviour must be observed.prompt-only— a behavioural request with no enforcement at all.
render_client_adapter reports the mechanism as readOnlyMechanism and the exact native role identifiers as roleIds.
ChatGPT Work web, Kiro web/mobile, and skills-only surfaces are not native client profiles and cannot be saved through save_preferences. Use parent-chat prompt guidance only; role binding is not enforceable there.
What it will not do
A short list, because it matters more than the feature list:
- It will not guess a model ID, normalise one, or pick a fallback. If your pinned model is unavailable, that lane stops.
- It will not claim a guarantee it cannot observe. If your client silently substitutes a model, Orrery never chose that — and says so plainly rather than pretending the pin held.
- It will not treat manifest conformance as evidence of runtime behaviour.
- It will not pretend the orchestration prompt layer is enforced. The MCP server enforces the file-write contract. It cannot enforce that a model genuinely read a diff.
- It will not claim a consent token proves a human saw the preview. The token makes a write exact and stale-proof, but it is handed back to the caller, so an unsupervised agent can chain preview into install on its own. The install and uninstall tools are annotated
destructiveHint: trueso your host prompts for them, and that prompt is the human-in-the-loop control.
Quick start
Requirements: Bun on your client's PATH, a compatible Agent Plugins v1 client, and an absolute, existing, private ${PLUGIN_DATA} directory supplied by the host.
Setup is lazy — installing the plugin runs no interview, registers no hook, and writes no file. Nothing is written until you have seen an exact preview and repeated an exact token.
Codex
codex plugin marketplace add DivyamTalwar/ORRERY --ref main
codex plugin add orrery@orrery
Start a new chat, then request orchestration:
Use $orrery:orchestration to build this feature, verify it, and obtain the configured advisor review before reporting done.
Update an existing installation with codex plugin marketplace upgrade orrery.
Cursor
Cursor 3.15.6 rejects a symlinked local plugin and cannot resolve the portable bare bun command from its plugin MCP process. Both are host defects, so the canonical package is not bent around them. Use the guarded compatibility bridge instead — see docs/cursor-local-install.md.
Other clients
Install plugins/orrery as the plugin root through that client's documented Agent Plugins v1 UI or local package mechanism. Orrery does not claim a universal install command.
After any adapter install, update, or uninstall, start a new chat or reload the client so native role discovery observes the new state.
First-use interview
The interview stays in your main chat and asks one question at a time: client, scope, workspace, and three exact native model IDs copied from your client's picker or /model.
| Role | Purpose | Current Codex recommendation |
|---|---|---|
| Routine implementer | Bounded, mechanical, fully specified work | gpt-5.6-terra, high |
| High-complexity implementer | Security, concurrency, algorithms, hard debugging, migrations, wide refactors | gpt-5.6-terra, high |
| Advisor | Commitment review and final diff/evidence verdict; requested read-only | gpt-5.6-sol, high |
| Orchestrator | Parent ownership and verification | inherit |
These are editable recommendations, not a universal model catalogue. Orrery never guesses, normalises, silently falls back, or claims a model exists in another client.
MCP tools
Eight tools over newline-delimited JSON-RPC 2.0. Every one declares a JSON Schema outputSchema and complete behaviour annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint). Nothing reaches the network, so openWorldHint is false throughout.
| Tool | Read-only | Destructive |
|---|---|---|
get_setup_status |
● | |
get_preferences |
● | |
validate_configuration |
● | |
save_preferences |
||
render_client_adapter |
||
install_client_adapter |
● | |
uninstall_client_adapter |
● | |
reset_configuration |
● |
Protocol revisions 2026-07-28, 2025-06-18 and 2025-03-26 are negotiated. Under the 2026-07-28 stateless core a request needs no initialize handshake — it may carry its own protocol version in _meta, and list results carry ttlMs and cacheScope. An explicitly declared but unsupported revision is refused, never silently downgraded.
Configuration is schema-versioned and written atomically. Secret-like fields are rejected recursively; model IDs and effort values cannot contain control characters.
Preview, consent, reconfigure, and uninstall
render_client_adapter returns exact destinations, full contents, a SHA-256 plan digest, target-state hashes, host warnings, and a short-lived one-time confirmation token. It computes destinations from an existing workspace and the selected client and scope; the parent never hands the server an arbitrary destination path. User scope requires a second exact token.
Installation rejects traversal, symlink ancestors and targets, unmanaged conflicts, drifted managed files, expired or replayed consent, and target changes since preview. Managed files carry the exact orrery-managed:v1 marker and are recorded with hashes. Updates create private backups.
Reconfiguration repeats the interview and preview:
Use $orrery:setup to reconfigure my Orrery client, scope, workspace, and exact native role choices.
Adapter uninstall previews the current profile's managed files and its confirmation token, then removes only unchanged managed files. It does not uninstall the plugin package. reset_configuration requires its own exact token, is refused while managed files are installed, and is refused while the tool surface is unapproved so it cannot erase an unreviewed alarm.
Orchestration semantics
The parent owns the specification, architecture, decomposition, actual diff review, rerun verification, correction loops, and acceptance. Routine versus high routing is based on task complexity, never price alone. Worker reports are claims until the parent verifies the working tree and checks. The advisor remains behaviorally read-only unless the client exposes evidence of OS-enforced isolation; Orrery reports the observed guarantee rather than inventing one.
The historical exact Codex native lane remains compatible: separately installed Terra / High implementation and a fresh Sol / High reviewer. It does not use a Luna custom-agent TOML. The Luna lane instead uses app task tools and is outside native subagent V2.
| Mode | Worker | Parent ownership |
|---|---|---|
| Native lane | Saved routine/high role, then saved advisor role | Architecture, diff/check verification, corrections, acceptance |
| Luna task (explicit opt-in) | User-visible gpt-5.6-luna / Max task |
Monitoring, diff review, corrections, PR authorization, dependent ordering |
Use the Luna task lane only with current-request authorization such as: “Use the Luna task lane for this feature.” It requires list_projects, list_threads, create_thread, wait_threads, read_thread, and send_message_to_thread. A pending clientThreadId is a setup handle, not a ready task ID. Missing tools, Luna, or Max stop without fallback. The native lane remains the default for the exact retained Codex compatibility workflow and does not use a Luna companion file.
Requirements common to both modes
- Bun available for portable MCP runtime.
- A compatible plugin client and exact user-selected model access.
- Parent ownership of verification and acceptance.
Additional native-mode requirements
- Codex native custom-agent support and the separately installed exact roles.
- Observable runtime routing; no unverified model/effort claim.
jqfor the retained companion lookup/install script.
Additional Luna task-mode requirements
- Explicit authorization in the current request.
- Luna / Max availability and all six app task tools.
The native companion installation can be skipped for Luna-only use. Luna tasks do not require native subagents, Terra access, or companion TOML files. Luna-only users do not need to run scripts/install-agents.sh.
Retained Codex companion lane
For exact legacy-compatible native use:
plugin_dir="$(codex plugin list --json | jq -r '.installed[] | select(.pluginId == "orrery@orrery") | .source.path')"
sh "$plugin_dir/scripts/install-agents.sh"
sh "$plugin_dir/scripts/install-agents.sh" --check
Start a fresh task afterward. The installer refuses conflicting or symlinked files and retains the byte-exact v0.2.0 migration. Runtime routing may be inspected with:
sh "$plugin_dir/scripts/inspect-agent-runtime.sh" <native-subagent-thread-id>
Zero dependencies
The published plugin has no runtime dependencies. The MCP server is a single Bun file with nothing between it and the standard library. Releases ship a CycloneDX SBOM hashing every packaged file — if it lists a runtime dependency, the artifact is not ours.
Every release carries build provenance and a keyless signature verified in-workflow before publishing.
shasum -a 256 -c orrery-*.tar.gz.sha256
gh attestation verify orrery-*.tar.gz --repo DivyamTalwar/ORRERY
cosign verify-blob orrery-*.tar.gz \
--bundle orrery-*.tar.gz.cosign.bundle \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity-regexp '^https://github\.com/DivyamTalwar/ORRERY/\.github/workflows/release\.yml@refs/tags/'
Development
Running the full gate additionally needs jq and Python 3.11 or newer: the packaging
verification script parses the role templates with tomllib, which is 3.11+ only. The
plugin itself needs neither at runtime.
bun install --frozen-lockfile
bun run typecheck # strict TypeScript, checked index access
bun run test
bun run validate # manifests, skills, links, pinned schemas, pinned tool surface
bun run sbom
bun run ci # everything, plus the packaged-artifact end-to-end check
bun run ci builds a flattened archive, extracts it, starts the extracted MCP server with an isolated HOME and data directory, drives a full save → preview → install → uninstall cycle against it, and asserts the packaged artifact exposes exactly the pinned tool surface. The thing that ships is the thing that is tested.
Contributor workflow and trust-boundary rules are documented in CONTRIBUTING.md.
Run bun run doctor -- --workspace /absolute/project for a non-mutating, machine-readable compatibility report across all supported clients. The report inspects derived adapter paths and managed markers while explicitly separating those observations from live-host claims it cannot prove.
Renaming or forking
Several values are derived from the product name, including the pinned tool-surface digest and the byte-exact legacy migration fingerprints. A manual find-and-replace will silently break them, so use the guarded tool, which recomputes every derived digest and prints a dry run first:
bun run rebrand -- --name my-advisor --display "My Advisor" \
--author-name "Your Name" --repo https://github.com/you/my-advisor
bun run rebrand -- ... --apply
bun run ci
Uninstall any managed adapter files with the previous build before renaming: the managed marker changes with the name, so a renamed build will not recognise the old files.
Why "Orrery"
An orrery is a precision clockwork model of the solar system — every body driven in exact, knowable relation, nothing drifting on its own.
Two things make it the right name. The mechanism it models is transparent by construction: every gear is visible, every relation inspectable, nothing hidden inside the case. And the bodies it drives are the ones you are actually orchestrating.
Auditability is not a feature here. It is the whole machine.
Security
Found a vulnerability? See SECURITY.md for the threat model, the enforced-versus-unguaranteed split, and private reporting.
License
MIT © Divyam Talwar
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi