8000 A mission's gap list counts only as `mission evaluate` computed it (M9.27) by adeelahmad · Pull Request #101 · adeelahmad/aloop · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ tag in lockstep. Tag releases as `vMAJOR.MINOR.PATCH`.
- Core agent principles and the one-way / two-way door rule (ROADMAP §4.12, M9.30): seven core principles from Amazon's Leadership Principles, the door rule first, go to every aloop agent at session start (`aloop mission principles show --core`). A two-way door (a branch, a local edit, a test, a draft PR) is decided, not asked. A one-way door (`aloop mission doors list`: a push or merge to the default branch, a force-push, a release, a deploy, a message sent outside, a secret, dropped data, …) is stopped by a PreToolUse gate with `ASK[door] <id>` until the human records an authorization in their own terminal (`aloop mission doors authorize ID --by NAME --reason TEXT [--until DATE] [--once DIGEST]`, a hash-chained ledger row); a wall (switching a gate off, forging a human record) is never crossed. While a run is live, a question to the human must name a door the gate stopped and nobody authorized. Reason: Adeel's request that agents decide two-way doors themselves and ask only at a one-way door not already authorized. Test: `mission-doors.test.py`. Hardened by an adversarial review (15 findings, each a test): the gate reads Bash as the shell does (comments, line continuations, heredoc bodies, `xargs`, `find -exec`, `echo … | sh`), a branch condition reads the directory the command acts on (`git -C`, `cd`), settings are guarded wherever they live, dry runs and `command -v` are two-way, the newest decision by time counts and a revoke holds on every branch, a once-grant is crossed once under a lock, a broken ledger is named, and `doors authorize` refuses an agent's shell.
- DeepSeek Harness (dsh) host (ROADMAP §4.9): `aloop install dsh` (alias `deepseek`; `--project P` or `--global`) renders a `dsh --profile aloop` profile in `$DSH_HOME` and installs the skills. Its native plugin (`plugin/hosts/dsh/aloop.mjs`) runs the same gates as Claude Code on dsh's own events: a deny before a tool runs, a block after an invalid artifact write, and a stop gate that steers a role back up to 3 times before the supervisor is told it is BLOCKED (or STUCK, released unverified). Roles are agent presets on two subagent tools, one per model route (`deepseek-v4-pro` for planning, `deepseek-flash` for work by default; `MODEL_PLANNING_DSH` / `MODEL_WORKER_DSH` override). A writer's `aloop bind` moves its working directory into its worktree, and `host-adapter` confines its commands, edits and `working_directory` there. Usage is recorded Claude-shaped per role, so budgets, the ledger and `run-summary` work unchanged. `make e2e-live HOST=dsh` drives it live and exits 2 with the fix when no `DEEPSEEK_API_KEY` is set. Reason: DeepSeek's own harness is the cheapest route to a strong model. The profile records the project it serves (or `--global`), so another project's `aloop-init` never re-renders it, and gates get the worker shell's environment (no API key). The mission layer's six roles run on dsh too: presets on their route group's subagent tool, `gate-mission-scope` on every write and command, and `gate-mission-artifact` at each role's start and stop; the mission skill installs as `aloop-mission`. A second review (3 lenses; 11 confirmed findings, each fixed with a test) closed: a working directory that vanished (dsh's tools move it back to the main tree, so the plugin judges `ensure()`'s directory and `host-adapter` refuses to run from a missing one), gate switches from the project's `.env` (dsh loads it; `SKIP_HOOKS`, `GATE_RUN_TESTS`, `REPO_DIR`, `AGENTIC_*` from it never reach a gate), an interrupted Stop that dropped the sprint-close notice, and the shared profile: its owner is the main tree, an older unrecorded profile is claimed only by the project that installed it, and a project it does not serve is told so by `install status`, `aloop-init` and the session itself. Tests: `dsh-plugin.test.mjs` (40 checks, emulated), `dsh-runtime.test.mjs` (32 checks on the real pinned dsh 0.2.1-rc.2 with a scripted model; the CI hosts job installs it) and `dsh-install.test.py` (9).
- Brand kit and repo front page: `docs/brand/` holds the mark (an **a** whose bowl is a red-to-green loop passing a gold gate, with a 16 px cut), lockups, light and dark README banners, favicons, app icons, the site's OG card and the GitHub social preview, all generated by `docs/brand/gen_brand.py` from one palette with WCAG checks (rules in `docs/brand/README.md`). The README leads with the mission layer, the agent principles and the door rule, the supported hosts and the measured demo runs; the site carries the favicon and Open Graph/Twitter card metadata; `SECURITY.md` and bug/feature issue forms are new.
- A mission's gap lists count only as `mission evaluate` computed them (ROADMAP §4.12, M9.27): `evaluate` records `eval.completed` in the committed ledger, and `mission tick`, `evaluate check` and `goal` take the newest eval whose content that record covers, with a matching seal, in the ledger's order. An eval file written by hand, or edited (or re-stamped) after it was recorded, no longer sends the loop to `RESEARCH` as "goal met" or makes `goal derive` refuse what tick handed out, a clock that is behind no longer reorders them, and a fresh checkout derives and closes goals from the evals it committed. An eval or state named as journey or baseline evidence needs its record too. Tests: `mission-tick` check 32, `mission-journeys`.
- A mission's stop at a spend cap holds on a fresh checkout (ROADMAP §4.12, M9.24): the first `STOP_BUDGET` tick records a `mission.budget_exhausted` ledger row for the mission's content (once per content), and `mission tick` stops on it whatever the checkout's token ledger says, until a raised cap changes the content.
- Lifting a mission block is the human's own words (ROADMAP §4.12, M9.51): `aloop mission tick --force --by` now asks (exit 3) for the human's typed `lift <mission> <code>` line, the code bound to this occurrence of that block, and records a `mission.lifted` ledger row, so `--by` alone, a lift only the run log has (or a replayed one), an old line or a line typed for an earlier block lift nothing, a lift of 3 failed goals reaches only those goals whatever `--now` says, and a fresh checkout keeps a lifted block lifted. `/aloop:mission` counts a lift among the typed grants it relays. A lift recorded before this (run data only) no longer counts.
- The mission layer's six fixed roles (ROADMAP §4.12, M9.9): `market-researcher`, `product-tester`, `state-assessor`, `evaluator`, `mission-planner` and `ethics-reviewer`, each a persona with a four-case eval suite, a model route (the four that judge on the planning route, the two that measure on the worker route), hook matchers on Claude Code, Codex, OpenCode and dsh, and Codex/OpenCode agents and dsh presets from `aloop install` (which also renders the mission skill for OpenCode as `aloop-mission` once it ships). `plugin/mission/roles.json` names the paths each role writes. `gate-mission-scope` (PreToolUse) is the role path guard: a mission role never writes source, mission.json or another role's dir, never commits and never runs a human's approval; a builder never writes `docs/agents/mission/` or runs a writing `mission` command; the supervisor never hand-writes a role's artifact. No one hand-writes `docs/agents/mission/ledger.jsonl` or the captured prompts a grant reads (`<run data>/transcripts/`), runs a hook's `transcripts prompt|record|…`, or starts a host session (`claude -p`, `codex exec`, `opencode run`, `dsh <profile>`) from a tool call where a mission is set (its prompt would count as the human's words, M9.17), and no dispatched agent runs `mission baseline restore`, `events authority` or an `events emit` of a human event. `gate-mission-artifact` records what exists when a role starts and, at its stop, requires an artifact in its own paths that passes the core contract and its area's check, refuses a deleted artifact, a change to another role's or a ledger that no longer verifies, and records `artifact.created|updated` as provenance. A mission write never arms the sprint lock. The scope gate reads a Bash command as the shell would (`_shellread.py`: quotes, comments, line continuations, heredocs, wrappers such as `timeout` and `env`, `bash -c`, `eval`, a script run by an interpreter, variables and `$(mktemp)`). Each area's check runs once per artifact with its id or subject, an ethics hard line is the reviewer's finding, not a defect, and a derived goal whose only blocks are its pending ethics review waits on the Ethics Reviewer, not on the planner. Test: `mission-roles.test.py` (33 checks, with each role run through the real journeys, baseline, assess, evaluate and ethics, goal, research and judge areas), `mission-scope-bash.test.py` (225 commands), `opencode-plugin.test.mjs`.
Expand Down
Loading
Loading
0