{"_id":"@archangel-tools/agent-worker","_rev":"4-5467e97fb6fe107de32b240662b54734","name":"@archangel-tools/agent-worker","dist-tags":{"latest":"0.2.2"},"versions":{"0.1.0":{"name":"@archangel-tools/agent-worker","version":"0.1.0","license":"MIT","_id":"@archangel-tools/agent-worker@0.1.0","maintainers":[{"name":"sdogik","email":"sergey.dogotar@gmail.com"}],"homepage":"https://github.com/archangel-tools/agent-worker#readme","bugs":{"url":"https://github.com/archangel-tools/agent-worker/issues"},"bin":{"agent-worker":"bin/agent-worker"},"dist":{"shasum":"1ec51066f4ef592507c21837c8486b4b4a138140","tarball":"https://registry.npmjs.org/@archangel-tools/agent-worker/-/agent-worker-0.1.0.tgz","fileCount":44,"integrity":"sha512-na4qPVprQeX+gP3lYQbRwLkE/RUZYM4sYOWbwu9HuMx2D8G1Dxxj2VpAAa3mNfG3NF8UFT7OrD8q4JnU9rWfwg==","signatures":[{"sig":"MEYCIQCy97b2S1pczEty56xVpQaz5LSXRVXsV0LN3NnFYNHY5AIhAJrArrP4JhpHN85YRqMFP1RcEsOVXy9FZ/BDlyBUgtH2","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":119804},"main":"dist/cli.js","type":"module","types":"./dist/cli.d.ts","engines":{"node":">=22.5.0"},"gitHead":"f4f182ff8f434370fe8c877008bc2e6632c8f877","scripts":{"dev":"tsx src/cli.ts","test":"vitest run","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"sdogik","email":"sergey.dogotar@gmail.com"},"repository":{"url":"git+https://github.com/archangel-tools/agent-worker.git","type":"git"},"_npmVersion":"11.16.0","description":"Unattended executor for agent-context organizations: scheduler + spawner + contract-verifier around headless Claude Code sessions. Org knowledge arrives at runtime from the layer and the backend.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"zod":"^3.23.8","yaml":"^2.5.1","commander":"^12.1.0","@archangel-tools/agent-ctx":"^0.4.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.16.0","vitest":"^3.2.7","typescript":"^5.5.0","@types/node":"^24.13.3"},"_npmOperationalInternal":{"tmp":"tmp/agent-worker_0.1.0_1786302404249_0.008928394695218111","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@archangel-tools/agent-worker","version":"0.2.0","license":"MIT","_id":"@archangel-tools/agent-worker@0.2.0","maintainers":[{"name":"sdogik","email":"sergey.dogotar@gmail.com"}],"homepage":"https://github.com/archangel-tools/agent-worker#readme","bugs":{"url":"https://github.com/archangel-tools/agent-worker/issues"},"bin":{"agent-worker":"bin/agent-worker"},"dist":{"shasum":"52de651361014fbd0af79514fd8c94828a2807f8","tarball":"https://registry.npmjs.org/@archangel-tools/agent-worker/-/agent-worker-0.2.0.tgz","fileCount":44,"integrity":"sha512-3LlyGohPiCGlTDgZWrXUZHkYZtjIHyyxoIjPtP5lITXVpGVXWrdi5MB7mlKSw28j7wftF+SZlb0S7bDykwrrqw==","signatures":[{"sig":"MEQCIEFWtXxSSlhYcRNgeiVjBM0r94Joeb9tYGXT7k91EsidAiAQ7ZuiOeP90Jcviu6eKmYDQg24PlszQrhoUUH1f2kTig==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":124197},"main":"dist/cli.js","type":"module","types":"./dist/cli.d.ts","engines":{"node":">=22.5.0"},"gitHead":"406c4020c03b2e2233c2f6d5d78d1e5201afe8c1","scripts":{"dev":"tsx src/cli.ts","test":"vitest run","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"sdogik","email":"sergey.dogotar@gmail.com"},"repository":{"url":"git+https://github.com/archangel-tools/agent-worker.git","type":"git"},"_npmVersion":"11.16.0","description":"Unattended executor for agent-context organizations: scheduler + spawner + contract-verifier around headless Claude Code sessions. Org knowledge arrives at runtime from the layer and the backend.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"zod":"^3.23.8","yaml":"^2.5.1","commander":"^12.1.0","@archangel-tools/agent-ctx":"^0.4.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.16.0","vitest":"^3.2.7","typescript":"^5.5.0","@types/node":"^24.13.3"},"_npmOperationalInternal":{"tmp":"tmp/agent-worker_0.2.0_1786315393620_0.21623683545911265","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@archangel-tools/agent-worker","version":"0.2.1","license":"MIT","_id":"@archangel-tools/agent-worker@0.2.1","maintainers":[{"name":"sdogik","email":"sergey.dogotar@gmail.com"}],"homepage":"https://github.com/archangel-tools/agent-worker#readme","bugs":{"url":"https://github.com/archangel-tools/agent-worker/issues"},"bin":{"agent-worker":"bin/agent-worker"},"dist":{"shasum":"69acdbfa94420c6994f2a4697bec2410b39f49b3","tarball":"https://registry.npmjs.org/@archangel-tools/agent-worker/-/agent-worker-0.2.1.tgz","fileCount":45,"integrity":"sha512-jWpbwjkzTsrrVJGj2xLMhy5CwXiKxH7WPwyuZFLWmopgU0dz4nH3IODJJX9He62G8a+86CA1HTpIccUVViiZkg==","signatures":[{"sig":"MEQCIEegeY01Zky4LsKWvGTo5tz286KS39mS7FBZPUg/C4OOAiAWf1VCK4/kTtE8dxq/CJCL/H8mYxK14VPTAgl7++wIQQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":133012},"main":"dist/cli.js","type":"module","types":"./dist/cli.d.ts","engines":{"node":">=22.5.0"},"gitHead":"d5ccf4fb5f1738e6a59f7fdb1c688e0ebfdfcba3","scripts":{"dev":"tsx src/cli.ts","test":"vitest run","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c8f1768e-f73c-4d7d-a6d3-b422e99c89db"}},"repository":{"url":"git+https://github.com/archangel-tools/agent-worker.git","type":"git"},"_npmVersion":"11.16.0","description":"Unattended executor for agent-context organizations: scheduler + spawner + contract-verifier around headless Claude Code sessions. Org knowledge arrives at runtime from the layer and the backend.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"zod":"^3.23.8","yaml":"^2.5.1","commander":"^12.1.0","@archangel-tools/agent-ctx":"^0.4.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.16.0","vitest":"^3.2.7","typescript":"^5.5.0","@types/node":"^24.13.3"},"_npmOperationalInternal":{"tmp":"tmp/agent-worker_0.2.1_1786374069225_0.26570789199299316","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@archangel-tools/agent-worker","version":"0.2.2","description":"Unattended executor for agent-context organizations: scheduler + spawner + contract-verifier around headless Claude Code sessions. Org knowledge arrives at runtime from the layer and the backend.","type":"module","license":"MIT","repository":{"type":"git","url":"git+https://github.com/archangel-tools/agent-worker.git"},"publishConfig":{"access":"public"},"engines":{"node":">=22.5.0"},"bin":{"agent-worker":"bin/agent-worker"},"main":"dist/cli.js","scripts":{"build":"tsc -p tsconfig.json","dev":"tsx src/cli.ts","test":"vitest run","test:watch":"vitest","typecheck":"tsc -p tsconfig.json --noEmit","prepublishOnly":"npm run build"},"dependencies":{"@archangel-tools/agent-ctx":"^0.5.3","commander":"^12.1.0","yaml":"^2.5.1","zod":"^3.23.8"},"devDependencies":{"@types/node":"^24.13.3","tsx":"^4.16.0","typescript":"^5.5.0","vitest":"^3.2.7"},"gitHead":"ca82e21deec5d593c5dfb24f07527a237556686e","types":"./dist/cli.d.ts","_id":"@archangel-tools/agent-worker@0.2.2","bugs":{"url":"https://github.com/archangel-tools/agent-worker/issues"},"homepage":"https://github.com/archangel-tools/agent-worker#readme","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-cVRlLvWGDOGWy3+g4PT/T0sXFH6RR/Zo2FDv+VCrz8avywZR0GS3h0/gM326Mi+vrW9od3gPn2FaGV5RduzEAQ==","shasum":"f461ddaacae6a01d70baa7f2523edea8d5337ad3","tarball":"https://registry.npmjs.org/@archangel-tools/agent-worker/-/agent-worker-0.2.2.tgz","fileCount":45,"unpackedSize":133012,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAL86KEIghnTBXdvEGTjaXaNL0KONY4h/WgUfBnziyNGAiEAiMvD2jqNl8FXP6n8mTE1S7ug6BVJ2XHDa8NhoqDNETo="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c8f1768e-f73c-4d7d-a6d3-b422e99c89db"}},"directories":{},"maintainers":[{"name":"sdogik","email":"sergey.dogotar@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/agent-worker_0.2.2_1786374827504_0.6414663508990757"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-09T19:06:44.067Z","modified":"2026-08-10T15:13:47.848Z","0.1.0":"2026-08-09T19:06:44.413Z","0.2.0":"2026-08-09T22:43:13.774Z","0.2.1":"2026-08-10T15:01:09.386Z","0.2.2":"2026-08-10T15:13:47.643Z"},"bugs":{"url":"https://github.com/archangel-tools/agent-worker/issues"},"license":"MIT","homepage":"https://github.com/archangel-tools/agent-worker#readme","repository":{"type":"git","url":"git+https://github.com/archangel-tools/agent-worker.git"},"description":"Unattended executor for agent-context organizations: scheduler + spawner + contract-verifier around headless Claude Code sessions. Org knowledge arrives at runtime from the layer and the backend.","maintainers":[{"name":"sdogik","email":"sergey.dogotar@gmail.com"}],"readme":"# agent-worker\n\nAn unattended executor: a THIN daemon — scheduler + spawner +\ncontract-verifier — around headless Claude Code sessions riding an operator's\nsubscription OAuth (`~/.claude`). All task intelligence lives in the\nworkplace's compiled layer (the `execute-task` skill); the worker only polls\nthe release gate, claims, spawns, and enforces the runtime contract\n(`CONTRACTS.md`). `ANTHROPIC_API_KEY` is deleted from every child environment.\n\n## Deployment model\n\nThe worker is thin on purpose: one instance per identity+host, serving exactly\nthe orgs that identity holds credentials for. The package knows nothing about\nany organization's content — org knowledge arrives at runtime from the org's\nlayer (`_schema.md` bindings) and the backend it points at. Jobs are deployment\nconfig, not package content: point `jobs_dir` at your own job files; the\npackaged `jobs.example/` is a template to copy from. Architecture decision:\nhttps://app.notion.com/p/3b7bfb5a7adc8165ace9e582b95a8454\n\nThree credentials never live in a repo; every deployment supplies its own:\n\n1. a Notion token, scoped to that org's teamspace, in the env var the config\n   names (`notion_token_env`, default `NOTION_TOKEN`);\n2. git access to that org's repos;\n3. a Claude login (`claude` CLI logged in, credentials in `~/.claude`).\n\n## Prerequisites\n\n- Node >= 22.5\n- `claude` CLI installed and logged in\n- a Notion integration whose token can read and write the org's tracker,\n  anchor, and activity-log collections\n\n## Runbook A — the vendor cockpit (this checkout)\n\nThe vendor runs one worker over every org, from the workspace root that holds\nall the repos side by side:\n\n```sh\n# clone the workspace root, then fill it\n./bootstrap.sh                             # every repo, from repos.txt\n\ncd archangel-tools/agent-worker\nnpm install && npm run build               # build from source\n\nmkdir -p ~/.config/agent-worker\ncp config.example.yaml ~/.config/agent-worker/config.yaml\n# then edit: constellation_root = the workspace root,\n#            agent_ctx_bin = <root>/archangel-tools/agent-ctx/bin/agent-ctx,\n#            jobs_dir = <root>/archangel-tools/agent-worker/jobs,\n#            one org entry per org (default NOTION_TOKEN env)\n\nexport NOTION_TOKEN=...                    # never config, never logged\nnpx -y @archangel-tools/agent-ctx@latest mirror <org>/agent-context   # mirror init\n\nnode bin/agent-worker doctor               # exit 1 on a hard failure\nnode bin/agent-worker once --dry-run       # what WOULD be claimed/fired; zero writes\nscripts/start.sh                           # nohup + pidfile in ~/.local/state/agent-worker\nscripts/stop.sh                            # SIGTERM; finishes the current run, then exits\n```\n\n## Runbook B — a single-org deployment\n\nA client org needs no vendor git access at all — the worker installs from\npublic npm, and the only repos on disk are the org's own:\n\n```sh\nnpm i -g @archangel-tools/agent-worker\n\n# ONLY your org, under one root:\nmkdir -p ~/agents && cd ~/agents\ngit clone <your-git-host>/<org>/agent-context\ngit clone <your-git-host>/<org>/<workplace>   # each workplace the tracker claims\n\nmkdir -p ~/.config/agent-worker\n# config: constellation_root: /home/you/agents, orgs: [yours] with your\n# notion_token_env — see the packaged config.example.yaml\nexport NOTION_TOKEN=...                    # or the var your config names\n\n# YOUR Claude subscription login: `claude` installed and logged in\n\nagent-worker doctor\nagent-worker once --dry-run\nagent-worker run                           # foreground; supervise however you like\n```\n\nOptional jobs: copy the packaged `jobs.example/` somewhere, replace `<org>`,\nand point `jobs_dir` at it.\n\n## Run\n\n`run` loops every `poll_seconds`: due jobs first (`jobs_dir/*.yaml` — daily\n`at:` or `every_minutes:`), then ONE task cycle per org — query the org\ntracker's `Ready` gate, resolve the workplace through task → project →\nsolution → `Repos`, claim to `In progress`, spawn `claude -p` with `agent-ctx\nrecall` output injected first and the output discipline appended last, and hand\nback to `Review`. One session at a time, sequential by design.\n\n## The prompt a run gets\n\nEvery prompt the daemon builds — task or job — is three parts in one fixed\norder: the recall block (or the marked `<!-- no memory available -->` line),\nthen the body (the task instruction, or a job's own `prompt` verbatim), then a\nclosing `<output-discipline>` block, the same bytes on every run.\n\nThat block tells an unattended session to skip preamble and postamble, never to\nrestate code, file contents, diffs or tool output already in the conversation,\nto continue without narrating a tool call that succeeded, and to spend the words\non the journal entry and the final report instead — those are the parts a human\nactually reads. Everything else is prose written into a log file nobody opens,\nand it is billed at output rates, several times input on these models.\n\nTwo properties of the block are load-bearing:\n\n- **It is at the tail.** The memory block and the task body ahead of it stay a\n  reusable prompt prefix; the discipline is appended after them, not woven in.\n- **It is byte-stable.** Editing a byte is a cache-busting change across every\n  job and every task, not a copy tweak. `OUTPUT_DISCIPLINE` in `src/runner.ts`\n  is the text; reword it deliberately or not at all.\n\nIt governs prose only, and it says so in its own last sentence — it never\nlicenses doing less of the work, skipping a check, or leaving the journal entry\nthin. A session told to be brief will otherwise hear \"be brief about the work\".\n\n## What a run costs\n\n`claude -p --output-format json` already prices every run it finishes. The\nrunner keeps what it reports — `total_cost_usd`, `num_turns` and the `usage`\ntoken breakdown, on `RunOutcome.cost` — and logs one line per run, to stdout\nand to the worker log in the state dir:\n\n```text\ncost: $0.4213 turns=12 in=900 out=300 cache_read=41000\n```\n\nThere is no ledger. Nothing aggregates those lines, nothing budgets against\nthem, and nothing declines a run for being expensive. This is only the part that\nwas free and that stopped being recoverable the moment the child process exited:\nthe number existed, the runner was discarding it, and the sole way back to it\nafterwards is re-reading megabytes of transcript. A CLI old enough to report\nnone of these fields leaves the run unpriced — no line, no `cost` on the\noutcome — rather than failing it.\n\n## Jobs\n\nA job is one YAML file in `jobs_dir`, loaded in filename order:\n\n- `name` — required; the key its last-run timestamp is stored under.\n- `at: \"HH:MM\"` (daily, local) or `every_minutes: <n>` — exactly one of them.\n- `kind: claude | command` — a `claude` job goes through the same runner as a\n  task; a `command` job is a plain spawn.\n- `cwd` — path under `constellation_root`; defaults to the root itself.\n- `prompt` — required for `kind: claude`; used as the prompt body, verbatim.\n- `argv` — required, non-empty, for `kind: command`.\n- `allowed_tools` — the `--allowedTools` list; empty by default.\n- `add_dirs` — `--add-dir` entries; a leading `~/` is expanded at run time.\n- `permission_mode` — `acceptEdits` by default.\n- `max_turns` — `100` by default.\n\nLast-run state lives in `jobs.json` in the state dir. A daily job fires once\n`at` has passed today and the last run predates it; the *attempt* is recorded\neven when it fails, so a broken job does not re-fire on every poll. A\n`claude`-kind job runs against the first configured org's bindings and token,\nand journals itself through its own skill — a missing entry is logged, never\nbackfilled (only task runs get a backfill).\n\n**Pin the spec in any job argv that runs the engine.** `mirror-refresh` shipped\nas `npx -y @archangel-tools/agent-ctx` with no version, so npx served whatever\nits cache already held — a build predating the `mirror` command. The job failed\nnightly with \"unknown command\", the mirror was never refreshed, and every job\nand task after it ran with `<!-- no memory available -->`: a silent no-op that\ncost the whole deployment its memory. The argv now says\n`@archangel-tools/agent-ctx@latest`, which is what `src/runner.ts` already did\nfor recall.\n\nThis checkout's own `jobs/` holds three, and their order is deliberate:\n\n- **`nightly-sweep`** (03:17, `claude`) — the `sweep-activity-log` skill over\n  the last 7 days: diff local session transcripts against the Activity Log by\n  `session:` token and backfill missing sessions as Draft entries.\n- **`mine-session-waste`** (03:27, `claude`) — after the sweep, so every session\n  in the window is already journalled. It reads this org's session transcripts,\n  canonicalizes each tool call so pagination and truncation differences collapse\n  into one signature, and reports loops of three or more occurrences (error\n  loops and re-fetch loops counted differently). Each distinct signature is\n  filed as a Task in the **un-released stage** (`Not started`, never `Ready`),\n  titled with the guardrail rather than the symptom; an existing open task for\n  the same signature is updated instead of twinned. At most 20 items per run,\n  and it journals itself only if something was filed. It may never write\n  Knowledge, author a decision, or move a task to `Ready` — that is invariant 11\n  of the event-sourcing pattern, and the reason its output is a proposal a human\n  releases. **Look for what it found in the Tasks database, un-released stage.**\n  It reads transcripts rather than the mirror, so its slot is about the sweep\n  having finished, not about memory.\n- **`mirror-refresh`** (03:47, `command`) — `agent-ctx mirror` for the org's\n  layer, so the next day's recall has current memory.\n\n`jobs/` is this deployment's config and is not packaged. Only `nightly-sweep`\nand `mirror-refresh` ship as templates, in `jobs.example/`: copy them, replace\n`<org>`, and point `jobs_dir` at the copies.\n\n## The contract it enforces\n\n- **Recall before the task** — fail-soft; a missing mirror degrades to a\n  marked \"no memory available\" line, never blocks the run.\n- **Journal after the task** — the runner verifies one activity-log entry\n  carrying the run's `session:<id>` token; a task session that did not journal\n  itself gets a Draft entry backfilled by the runner and the run exits\n  flagged. Jobs journal themselves per their own skills; a gap is logged, not\n  backfilled.\n\n## Boundaries (from CONTRACTS.md)\n\n- The worker never commits, tags, or pushes; it stops where `agent-ctx` stops.\n- One organization per run: a run binds to one org's layer, mirror, and\n  journal; nothing crosses orgs inside a run.\n","readmeFilename":"README.md"}