A local-first control plane for coding agents. Run several AI sessions without losing track of what each one is allowed to do, what it decided, and what still needs you.
ASC gives an agent a contract — a goal, done-criteria, a write boundary — lets it proceed on what it owns, and stops it at the boundaries that are yours: ownership, shared contracts, secrets, irreversible actions. No ASC-managed external mutation is executed without the required authority/grant path. Everything is auditable afterwards.
The packages are on npm. Install them with the exact commands below. Cloning this repository is the contributor path — it is not how you use ASC.
If the version pinned here is not on the registry, this source is ahead of the release: report that the exact version is unpublished and stop. Do not fall back to another version —
@latestor an older pin is a runtime nobody tested these instructions against.
Coding agent? Read AGENTS.md — the ordered path from this URL to a ready control plane, with the decisions already made, and the rules for turning a work request into a session contract once there is real work.
Korean: README.ko.md. This file is canonical.
Running parallel agents, a person becomes the memory: carrying context between sessions, remembering which one was allowed to touch what, re-deriving why a decision was made. ASC moves that into a runtime that lives in your own space — not in the repository you are working on.
- Sessions with contracts — a goal, verifiable done-criteria, a write boundary.
- Proceed by default — an agent does not ask permission for what it owns.
- Escalation at real boundaries — and only there. Uncertainty is not a boundary.
- Audit — issuance and actual execution recorded separately, decisions with their reasons, independent verification kept apart from self-reports.
- Offline after install — local control-plane commands need no network.
- Not an agent, and not a model router. It does not do your work.
- Not a task tracker. It points at your canonical sources; it does not copy them.
- Not a sync service. Runtime state does not follow you between machines.
- Node 24 or newer — declared in
engines. Lower versions are not supported. - One runtime dependency:
zod.
ASC ships as two packages:
| Package | Role |
|---|---|
@asc-agent/runtime |
The runtime — core, CLI, adapters. Provides the asc command. |
@asc-agent/bootstrap |
Zero-install first run. Holds no setup logic of its own. |
npx --yes @asc-agent/bootstrap@0.10.2 setup apply --jsonFrom there the everyday path is three words:
asc setup # make this machine and this project ready
asc status # what is set up, what is running, what is blocked
asc work # start, publish and finish the workThe packaged profiles are examples — neither describes a real project. A profile that describes yours lives in your own directory and is picked up from there.
Make one from the repository you are in:
asc profile adopt # writes ~/.asc/profiles/<repo>/profile.json
asc setup apply --profile <repo>
asc status # profile: <repo> — your own profile directoryadopt writes only what a git remote proves: the project's identity. Canonical branches
and role boundaries stay empty, because this repository cannot tell you what your team
decided — add them as you agree on them. If someone already handed you a profile file, put
it in place instead:
mkdir -p ~/.asc/profiles/my-team
cp path/to/profile.json ~/.asc/profiles/my-team/profile.json
asc setup apply --profile my-teamFull rules — precedence, id collisions, what a profile may not do, and why moving one does not break an existing attachment — are in docs/profiles.md.
The command does not appear by magic, and this is the whole chain:
npx --yes @asc-agent/bootstrap@0.10.2 setup apply --json
↓ the bootstrap runs ASC's ordinary setup: detect → plan → apply → verify
↓ the plan lists "install the runtime on this machine" as a change
↓ apply runs: npm install -g @asc-agent/runtime@0.10.2
↓ npm owns the executable link (on Windows, npm's own asc.cmd)
↓ verify checks the installed version and that a NEW process can run it
bootstrap exits
↓
asc ... the stable local command, from here on
Installation is a change listed in the plan. The bootstrap never installs behind your
back, and it holds no setup policy of its own — it forwards to the same core the installed
asc uses.
ASC does not edit your shell profile or your PATH. If npm installs the package but asc
is not visible in the current process, ASC says exactly that instead of claiming success:
Runtime package was installed, but `asc` is not visible in this process.
Open a new terminal and run `asc status`.
Every command exists in all three tiers; only the entry differs.
| Tier | Entry | When |
|---|---|---|
| Zero-install | npx --yes @asc-agent/bootstrap@0.10.2 <command> --json |
nothing is installed yet |
| Persistent | asc setup installs it; asc update moves it |
the stable local command. npm install -g @asc-agent/runtime@0.10.2 is the manual fallback for when npx itself cannot start |
| Development | asc runtime use development <checkout> |
run a built checkout instead of the package |
If npx or npm exec dies before any ASC process starts — a package-runner or PATH
failure, not anything ASC printed — that is not an ASC failure, and there is no ASC error
code to branch on. Install the persistent tier and re-run the same subcommand as asc ….
This is different from HOST_EXECUTION_PERMISSION_REQUIRED, where the host refused a
command ASC asked to run: that one is ASC speaking, and its JSON says what to do next.
asc status # what works, what is blocked, and why
asc work start # pick up the runnable work you own
asc work publish # send an approved result outside
asc work finish # hand off, close and collect in one command
asc mode manual|auto # who executes an approved act
asc inbox # what is waiting on youAGENTS.md is the runbook — the ordered path, and the rules for what you decide yourself versus what you bring to a human. This section describes the data it works on.
Non-interactive and machine-readable. stdout is a single JSON document; diagnostics go
to stderr.
On a fresh machine, start from the bootstrap — there is no asc yet:
npx --yes @asc-agent/bootstrap@0.10.2 setup apply --jsonThe document carries a stable shape:
Run actions[].portable, never display. The two differ exactly while the runtime is
not yet installed: display is the short form a person types afterwards, portable is
what runs on this machine right now. Once executionMode is installed-runtime, they are
the same string.
Branch on code and requiresUserAction. Never parse the prose.
asc setup defaults to local scope, and in that mode nothing is created inside the
target repository.
--scope local (default) runtime = $ASC_HOME/workspaces/<W-id>/ repo footprint 0
--scope project runtime = <repo>/.asc/ only if the team decided so
ASC_HOMEdefaults to~/.asc. It holds one directory per workspace plus a reverse index,workspace-index.json.- There is no automatic promotion from local to project. Putting state inside a
repository is an explicit decision expressed only by
--scope project. .git/info/excludeis touched under project scope only. Local scope does not modify a single byte of the repository.
Measured, not asserted — recorded in the private evidence repository.
A workspace points at a project, not at a path.
| Concept | Meaning |
|---|---|
| Workspace Identity | W-… — the canonical, stable, logical identity |
| Alias | A normalized remote URL. Evidence of identity, never proof of it. |
| Locator | Where this checkout sits on this machine. It can change. |
So moving or re-cloning a checkout can still resolve to the same workspace.
asc workspace list
asc setup --profile <id> --workspace <W-id> # you declare the match; ASC never picks for youIf a repository already contains a repo/.asc from the older layout:
asc workspace migrateIt first judges whether that state is team-adopted or personal legacy, and refuses to move when it cannot tell. It copies, verifies, and never deletes the original — that is yours to do after you have checked.
asc runtime status
asc runtime use package
asc runtime use development /path/to/asc/packages/runtimepackage is the globally installed runtime — the one npm install -g put there.
development runs a built checkout instead.
The path is validated before it is stored: a checkout that is missing, is not ASC, or has not been built is rejected the moment you point at it, not later with a module-not-found. When it is simply unbuilt, the remedy names the checkout it applies to rather than assuming your current directory is it:
ASC_DEVELOPMENT_SOURCE_INVALID: /path/to/asc/packages/runtime has not been built yet
target: /path/to/asc/packages/runtime
Build that checkout and retry — do not run this in the current directory.
Run: npm run build
This selection is machine-local, kept under ASC_HOME. Changing it does not change any
project, and attaching or moving a workspace does not change it.
asc setup installs the host integration, and asc refresh brings it back to the build
you are running — those are the two commands a person needs. The rest is the advanced
surface, for diagnosis and recovery:
asc host claude install # writes the integration directly (skill bundle + SessionStart hook)
asc host claude uninstall # removes only what ASC installed
asc host claude bind # recovery: bind a session to a Run by hand — `asc work start` does it for you0.9.0 retired the 0.8.x PreToolUse guard. asc update and asc refresh remove its
registration and file from a 0.8.x host; a file you edited is left in place and reported.
Host artefacts are user-owned, not project-owned. install writes to your home
directory; uninstall removes only what ASC installed.
Install state is judged against the current source, not just against what was recorded at install time:
NOT_INSTALLED · INSTALLED_CURRENT · INSTALLED_STALE · INSTALLED_MODIFIED · BROKEN
STALE means the source moved on and you did not — reinstall converges it.
MODIFIED means you edited an ASC-owned file — it is preserved, and --force is the
only way to overwrite it.
An agent proceeds on what it owns. It escalates only when it hits a real boundary: ownership, a shared contract, an acceptance change, a secret or permission, an irreversible action, an explicit rule, or a conflict in the canonical source. Being uncertain, or having two options, is not a boundary.
An open escalation blocks the criteria it names — not the whole session:
blocked: N2 extend response schema
scope: server/**
running: N1 introduce runtime configuration
asc session audit <S-ID> shows issuance and actual execution separately, the decisions
an agent made without approval and why, the escalations it raised and the boundaries
they name, independent validation, and who currently holds the session.
Three different jobs, three commands:
asc update # move to the newest published release, then verify it
asc refresh # same version — bring this runtime's own integration back to it
asc uninstall # remove the product; your state staysupdate installs the new release and then lets that build refresh the host
integration, so a new runtime never leaves an older hook registration behind. refresh is the one to
reach for when the host shows INSTALLED_STALE at the version you already have: it
converges the host files and the machine registration and touches nothing else — not the
profile, not the workspace, not the identity, not sessions, not the execution mode.
uninstall removes the registration, the host integration and the installed runtime, in
that order, and keeps every byte of ASC_HOME. It refuses while a session or a physical
run is still live rather than abandoning it. There is no purge command.
npm install -g @asc-agent/runtime@<exact> still works and is the manual fallback when
the package runner itself cannot start.
| Symptom | Cause | What to do |
|---|---|---|
Cannot find package 'zod' across every test |
dependencies not installed | npm ci |
| Setup says a decision is required | a real human boundary | read code and nextActions |
ASC_DEVELOPMENT_SOURCE_INVALID |
the selected checkout is gone, is not ASC, or is unbuilt | follow the nextCommand it prints |
probe reports STOP |
claude is not on PATH |
a missing prerequisite, not an ASC failure |
Host shows INSTALLED_STALE |
the runtime moved on | asc refresh |
git clone https://github.com/colosair/asc.git
cd asc
npm ci
npm test
npm run typecheck
npm run buildRun the CLI straight from the checkout — Node executes the TypeScript sources directly:
node packages/runtime/cli/asc.ts --helpThat is the contributor path. It is not how a consumer installs ASC.
Distribution artefacts are compiled, because Node refuses to strip types under
node_modules:
npm run build # packages/runtime/dist
npm run pack:all # tarballs into private/packs
npm run smoke # install those tarballs into a throwaway HOME and drive the real bin
npm run release:check # version, namespace and documented-command driftnpm run smoke is the one that matters before a release: it never touches your real
~/.asc, ~/.claude, or npm cache. release:check does not publish anything — it only
detects drift. Publishing runs remotely through npm Trusted Publishing, dispatched by a
maintainer; the procedure is docs/release/README.md.
| What | Where | Nature |
|---|---|---|
| Current product model | docs/design/current-operating-model.md | what ASC does today |
| Historical design (v5.1, frozen) | docs/design/operating-model.md | the snapshot OM §x points at |
| Contracts — ports and boundaries | C-01 · C-02 · C-03 | Approval Port / Port boundary / Operator·Host Adapter |
| Contracts — responsibility and entry | C-04 · C-05 · C-06 | Responsibility / Skill Bundle / Zero-base Bootstrap |
| Contracts — observation and independence | C-07 · C-08 · C-09 | Monitoring / Presentation·Digest / External-System Independence |
| Contracts — audit, storage, always-on, autonomy | C-10 · C-11 · C-12 · C-13 | Orchestration Audit / Workspace·Local-first / Always-On / Autonomous Escalation |
| Contract — distribution | C-14 | how the executable exists on a machine |
| Architecture — distribution | docs/architecture/distribution-and-runtime.md | English |
| Profiles — bringing your own | docs/profiles.md | where a real project's profile lives |
| Team setup and upgrading | docs/team-setup.md | onboarding a teammate; moving to a newer runtime |
| Product status (SSOT) | docs/status.md | what exists, what is proven, what is not claimed |
| Block-level history | private evidence repository §2 | development record |
| Measured evidence | private evidence repository | runtime observations |
The canonical design (OM v5.1) and C-01~C-03 are frozen. They reopen only on evidence that a port, profile, or adapter boundary cannot solve the problem. Later contracts are follow-ons that do not modify them.
Reports here distinguish four claims, and do not blur them:
DOCUMENTED it is written down
TEST_VERIFIED an automated test covers it
RUNTIME_OBSERVED it was watched happening through the real CLI
DOGFOOD_VERIFIED it was watched happening during real work
No new block starts without measured evidence. A candidate has to be tied to something that actually happened, be likely to recur, and carry a clear gate. When the evidence is thin, the next block stays undecided.
- No credential is ever written into a project file.
- No machine-specific absolute path is ever written into a project file.
- No ASC-managed external mutation is executed without the required authority/grant path: a person's decision, a one-shot grant, a pre-execution review, exactly one mutation, a read-back, an audit record.
- ASC does not claim to sandbox the same-OS-user shell. A raw
git pushtyped at that shell is outside ASC's enforcement boundary; the Host and the OS own that boundary. Execution Mode answers who performs an approved act — a person (MANUAL) or ASC's managed executor (AUTO) — not what the shell may run. - Host installation touches only the ASC namespace. Your files and other tools' hooks are left alone.
ASC controls what an agent may do and reads credentials from your environment. Report issues through GitHub private vulnerability reporting — see SECURITY.md, including what not to put in a report.
ISC. See LICENSE.
{ "status": "ready_to_apply", // or already_configured / user_action_required / applied "code": "ASC_PROFILE_SELECTION_REQUIRED", // present only when a human must decide "executionMode": "bootstrap", // or installed-runtime "changes": [ { "target": "runtime-install", "package": "@asc-agent/runtime", "version": "0.10.2", "strategy": "npm-global", "from": "NOT_INSTALLED" }, { "target": "attach-workspace", "scope": "local", "profile": "..." } ], "requiresUserAction": false, "changesApplied": false, "actions": [ // ordered by what actually opens the way. `adopt_profile` appears when a profile // must exist before anything can be selected. { "type": "apply_setup", "display": "asc setup apply", "portable": "npx --yes @asc-agent/bootstrap@0.10.2 setup apply" } ], "nextActions": ["npx --yes @asc-agent/bootstrap@0.10.2 setup apply"], "evidence": ["project=/path", "git=yes", "attached=no", "runtime=NOT_INSTALLED"] }