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
6 changes: 3 additions & 3 deletions .github/workflows/authority.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ permissions:
jobs:
protected-surfaces:
name: Protected surfaces
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

steps:
- name: Checkout
Expand All @@ -28,7 +28,7 @@ jobs:

authority-patch-lock:
name: Authority patch lock
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

steps:
- name: Checkout
Expand All @@ -41,7 +41,7 @@ jobs:

doctrine-snapshot:
name: Doctrine snapshot
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

steps:
- name: Checkout
Expand Down
16 changes: 9 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ permissions:
jobs:
syntax:
name: Shell syntax
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

steps:
- name: Checkout
Expand All @@ -30,31 +30,33 @@ jobs:

shellcheck:
name: ShellCheck
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Install ShellCheck
run: |
sudo apt-get update
sudo apt-get install -y shellcheck
- name: Install pinned ShellCheck
run: scripts/install-shellcheck.sh

- name: Run ShellCheck
run: shellcheck bin/agently lib/*.sh tests/*.sh

smoke:
name: Smoke tests
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 15

steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Install pinned ShellCheck
run: scripts/install-shellcheck.sh

- name: Run smoke tests
run: ./tests/smoke.sh
2 changes: 1 addition & 1 deletion .github/workflows/promotion-source.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ permissions:
jobs:
source:
name: Require dev source for main
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

steps:
- name: Checkout
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ permissions:
jobs:
security-adversarial:
name: Security adversarial
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

steps:
- name: Checkout
Expand All @@ -28,7 +28,7 @@ jobs:

config-allowlist:
name: Config allowlist
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

steps:
- name: Checkout
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

# Local planning / scratch artifacts
docs/tmp/
77 changes: 41 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@

A local-first control plane for bounded agentic development loops.

Status: pre-release | v0.5.0 | CLI-only | Bash core | alpha - not production-ready

Agently runs today as a Bash CLI. It writes workflow state as files, compiles
bounded context packets, and runs guard/eval checks through detected local tools.

## Hook / Positioning
## What Agently Is

> Agently is a loop control plane, not a runaway loop runner.
>
Expand All @@ -20,42 +18,42 @@ not a model, IDE, cloud service, or CI system; it does not write code or operate
agents for you. Its state is local files under `.agently/`, so the loop stays
visible, diffable, and under developer authority.

| Agently is | Agently is not |
| --- | --- |
| A control plane for bounded agent-assisted loops. | An autonomous coding agent or model provider. |
| Local, file-backed workflow state under `.agently/`. | A SaaS, daemon, database, dashboard, or cloud orchestrator. |
| A compiler for copy-safe packets, prompts, evidence, and handoffs. | An IDE, CI/CD platform, or generic agent framework. |
| A guard/eval and reviewable patch surface for local checks. | A runaway retry engine or auto-promotion system. |
| A review gate around candidate work. | A replacement for maintainer approval. |
| Tool-agnostic around external agents/tools. | An integration with every named coding tool. |
| Agently is | Agently is not |
| ------------------------------------------------------------------ | ----------------------------------------------------------- |
| A control plane for bounded agent-assisted loops. | An autonomous coding agent or model provider. |
| Local, file-backed workflow state under `.agently/`. | A SaaS, daemon, database, dashboard, or cloud orchestrator. |
| A compiler for copy-safe packets, prompts, evidence, and handoffs. | An IDE, CI/CD platform, or generic agent framework. |
| A guard/eval and reviewable patch surface for local checks. | A runaway retry engine or auto-promotion system. |
| A review gate around candidate work. | A replacement for maintainer approval. |
| Tool-agnostic around external agents/tools. | An integration with every named coding tool. |

## Core Concepts

- **loop control plane** - the layer that names, sequences, and gates the steps
* **loop control plane** - the layer that names, sequences, and gates the steps
of an agent-assisted development loop; it coordinates the work around your
coding agents instead of doing the coding.
- **bounded loop** - a cycle with an explicit start, explicit scope, compiled
* **bounded loop** - a cycle with an explicit start, explicit scope, compiled
context instead of the whole repo, and an explicit review gate to close it.
- **packet** - a compiled, copy-safe Markdown context surface for a role/agent,
* **packet** - a compiled, copy-safe Markdown context surface for a role/agent,
built from file-backed state with size budgets.
- **handoff** - a recorded request/response exchange passed between roles or
* **handoff** - a recorded request/response exchange passed between roles or
agents so work transfers as durable files, not hidden chat state.
- **gate** - a required human decision point, such as accept, revise, reject, or
* **gate** - a required human decision point, such as accept, revise, reject, or
promote, before anything becomes canonical workflow state.
- **guard / eval** - local validation; guard runs bounded checks through
* **guard / eval** - local validation; guard runs bounded checks through
detected tools, and eval aggregates guard evidence or checks proposed patches
inside a throwaway git worktree.
- **local-first** - Agently runs on your machine from visible files; no daemon,
* **local-first** - Agently runs on your machine from visible files; no daemon,
database, dashboard, or hidden network calls.
- **human authority** - agent output is candidate context until reviewed; the
* **human authority** - agent output is candidate context until reviewed; the
developer or maintainer remains the final authority.
- **MCP** - Model Context Protocol. Agently currently has optional MCP config
* **MCP** - Model Context Protocol. Agently currently has optional MCP config
helper commands for Serena; a dedicated workflow adapter, `agently-mcp`, is
planned/deferred and not implemented in this Bash core.
- **doctrine / project rules** - versioned Markdown rules under
`docs/doctrine/` defining authority, scope, command contracts, and safety
boundaries; `init` copies a read-only snapshot into `.agently/doctrine/`, and
`agently guard doctrine` checks drift.
* **doctrine / project rules** - versioned Markdown rules whose canonical source
lives in Agently source-repo-only `docs/doctrine/`; `init` copies a read-only
runtime/reference snapshot into `.agently/doctrine/`, and `agently guard
doctrine` checks drift.

## How Agently Works: The Loop

Expand Down Expand Up @@ -149,27 +147,34 @@ agently decide accept --workstream main --task implementation-pass --note "Accep

## Current Scope & Roadmap

| Current in v0.5.0 pre-release | Directional or deferred |
| --- | --- |
| Bash CLI under `bin/` and `lib/`. | Packaged or remote install paths. |
| Managed user-local `self install`, `self status`, and `self uninstall`. | Self update and rollback. |
| Current in v0.5.0 pre-release | Directional or deferred |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| Bash CLI under `bin/` and `lib/`. | Packaged or remote install paths. |
| Managed user-local `self install`, `self status`, and `self uninstall`. | Self update and rollback. |
| `init`, `doctor`, `status`, workstreams, tasks, docs, packets, prompts, context, compact, inspect, evidence, report, decide, guard, eval, and patch commands. | Richer packet diagnostics, broader guard adapters, and project migration/template refresh. |
| File-backed `.agently/` state, handoffs, decisions, and doctrine snapshots. | A dedicated `agently-mcp` workflow adapter in a separate Python project. |
| Reviewable patch lane with `patch apply` gated by `--reviewed`; Git remains source-control authority. | A separate future TUI client over CLI contracts. |
| Optional Serena capability pack and explicit MCP config helper commands. | Full Serena setup automation or Agently-owned semantic code-intelligence reports. |
| File-backed `.agently/` state, handoffs, decisions, and doctrine snapshots. | A dedicated `agently-mcp` workflow adapter in a separate Python project. |
| Reviewable patch lane with `patch apply` gated by `--reviewed`; Git remains source-control authority. | A separate future TUI client over CLI contracts. |
| Optional Serena capability pack and explicit MCP config helper commands. | Full Serena setup automation or Agently-owned semantic code-intelligence reports. |

Out of scope for this Bash core today: production readiness, a daemon, database,
web UI, dashboard, embedded MCP server, autonomous source mutation, CI/CD
replacement, enterprise RBAC/SSO, hidden global config mutation, and hidden
network behavior.

Doctrine and project rules live in `docs/doctrine/`. For development on
Agently itself, those files define authority, architecture, command contracts,
## Doctrine

`docs/doctrine/` is Agently source-repo-only. It is the canonical doctrine source
for Agently development, defining authority, architecture, command contracts,
safety boundaries, testing, packet behavior, MCP boundaries, and roadmap
discipline. Initialized projects receive a read-only snapshot under
`.agently/doctrine/` so project-local loops can inspect the same rules.
discipline.

Initialized projects receive a read-only snapshot under `.agently/doctrine/` so
project-local loops can inspect the same rules. That snapshot is runtime
reference material only; it does not make `docs/doctrine/` target-project
authority, and Agently runtime commands do not get write authority over doctrine
source.

Development validation:
## Development Validation

```bash
bash -n bin/agently lib/*.sh tests/*.sh
Expand Down
1 change: 1 addition & 0 deletions bin/agently
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ set -euo pipefail

if [[ "${BASH_SOURCE[0]}" != "$0" ]]; then
echo "FAIL: agently must be executed, not sourced" >&2
# shellcheck disable=SC2317
return 1 2>/dev/null || exit 1
fi

Expand Down
8 changes: 8 additions & 0 deletions ci/toolchain.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Pinned CI/dev shell tooling. Sourced by scripts/install-shellcheck.sh.
SHELLCHECK_VERSION="0.11.0"

SHELLCHECK_LINUX_X86_64_SHA256="8c3be12b05d5c177a04c29e3c78ce89ac86f1595681cab149b65b97c4e227198"
SHELLCHECK_LINUX_AARCH64_SHA256="12b331c1d2db6b9eb13cfca64306b1b157a86eb69db83023e261eaa7e7c14588"

SHELLCHECK_DARWIN_X86_64_SHA256="3c89db4edcab7cf1c27bff178882e0f6f27f7afdf54e859fa041fca10febe4c6"
SHELLCHECK_DARWIN_AARCH64_SHA256="56affdd8de5527894dca6dc3d7e0a99a873b0f004d7aabc30ae407d3f48b0a79"
4 changes: 4 additions & 0 deletions docs/doctrine/12-testing-and-validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ If available:
shellcheck bin/agently lib/*.sh tests/*.sh
```

CI/dev shell tooling is pinned through `ci/toolchain.env`.
To upgrade ShellCheck, update the version and platform SHA256 values there,
then verify with `scripts/install-shellcheck.sh` and the normal validation suite.

## Smoke Test Doctrine

The smoke test SHOULD cover:
Expand Down
1 change: 1 addition & 0 deletions lib/agently.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set -euo pipefail

if [[ "${BASH_SOURCE[0]}" != "$0" ]]; then
echo "FAIL: agently lib must be executed, not sourced" >&2
# shellcheck disable=SC2317
return 1 2>/dev/null || exit 1
fi

Expand Down
6 changes: 5 additions & 1 deletion lib/cmd-inspect.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ inspect_emit_log_bounded() {
omitted=$((lines - max_lines))
printf '\n[TRUNCATED %s LINES - full log: %s]\n' "$omitted" "$logfile"
warn "full output logged at $logfile"
if (( status != 0 )); then
warn "command exited with status $status; log tail:"
tail -n 5 "$logfile" >&2
fi
else
cat "$logfile"
fi
Expand Down Expand Up @@ -156,7 +160,7 @@ inspect_grep_run() {
if has_cmd rg && [[ "$(agently_bool "$(agently_config_get "$root" inspect prefer_ripgrep)" 2>/dev/null || printf true)" == "true" ]]; then
rg --line-number --no-heading --color never -- "$pattern" "$target" > "$log" 2>&1
else
grep -R -n -- "$pattern" "$target" > "$log" 2>&1
grep -R -n --exclude-dir=.agently --exclude-dir=.git -- "$pattern" "$target" > "$log" 2>&1
fi
status=$?
set -e
Expand Down
3 changes: 2 additions & 1 deletion lib/cmd-packet.sh
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ packet_doctrine_manifest_section() {
}

packet_agent_rules_section() {
local root="$1" budget="$2" file="$root/AGENTS.md"
local root="$1" budget="$2" file
file="$root/AGENTS.md"
printf '<agent_rules>\n'
if [[ ! -f "$file" ]]; then
printf '_(AGENTS.md missing)_\n'
Expand Down
3 changes: 2 additions & 1 deletion lib/cmd-serena.sh
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,8 @@ serena_mcp_claude_state() {
}

serena_memory_snapshot_lines() {
local root="$1" dir="$root/.serena/memories" file rel size mtime
local root="$1" dir file rel size mtime
dir="$root/.serena/memories"
[[ -d "$dir" ]] || return 0
while IFS= read -r file; do
rel="$(rel_to_root "$root" "$file")"
Expand Down
3 changes: 2 additions & 1 deletion lib/cmd-tooling.sh
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ profile_value_from_file_or_default() {
}

profile_ensure_gitignore() {
local root="$1" file="$root/.agently/.gitignore" tmp
local root="$1" file tmp
file="$root/.agently/.gitignore"
mkdir -p "$root/.agently"
if [[ ! -f "$file" ]]; then
printf 'local.yml\ncache/\n' > "$file"
Expand Down
3 changes: 2 additions & 1 deletion lib/cmd-ws.sh
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,8 @@ workstream_branch_prepare() {
}

workstream_state_branch_get() {
local dir="$1" key="$2" file="$dir/state.yml"
local dir="$1" key="$2" file
file="$dir/state.yml"
[[ -f "$file" ]] || return 0
awk -v key="$key" '
/^[^[:space:]#][^:]*:/ {
Expand Down
3 changes: 2 additions & 1 deletion lib/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,8 @@ extract_skeleton_for_file() {
}

structural_digest_for_file() {
local file="$1" rel="${2:-$file}" lang lines bytes sha
local file="$1" rel lang lines bytes sha
rel="${2:-$file}"
lang="$(detect_language_for_file "$file")"
lines="$(line_count "$file")"
bytes="$(byte_count "$file")"
Expand Down
Loading
Loading