agsync

ESLint for your agents’ memory

01 / 09

AGENTS.md — my-service

01 / 09

That’s it. It’s all just markdown.

my-service/

.github/

docker/

migrations/

src/

api/

db/

workers/

tests/

package.json

tsconfig.json

README.md

memory/

tasks/

# my-service

## Boot protocol

Before changing anything:

1. `agsync check --no-baseline` — if it fails, repair what is

unambiguous and report the rest. Do not start on memory you

cannot trust.

2. `memory/goal.md` — what this service is for

3. `memory/decisions.md` — why it is built the way it is

4. `memory/state.md` — what is done, and what is only claimed

5. `tasks/README.md` — what is open

## Rules

- Decisions are append-only. Supersede one, never edit it.

- A task is `done` only once its Acceptance line has been run.

A my-service repository. agsync reads only the markdown files listed below; the rest of the project is shown dimmed and is not selectable.
my-service/
  .github/
  docker/
  migrations/
  src/
    api/
    db/
    workers/
  tests/
  package.json
  tsconfig.json
  README.md
  AGENTS.md (selectable)
  memory/
    goal.md (selectable)
    decisions.md (selectable)
    state.md (selectable)
  tasks/
    README.md (selectable)
    01-idempotent-retries.md (selectable)

02 / 09

Everything here reads fine to a human

$ pip install agsync

Collecting agsync

Downloading agsync-0.1.1-py3-none-any.whl.metadata (13 kB)

Downloading agsync-0.1.1-py3-none-any.whl (37 kB)

Installing collected packages: agsync

Successfully installed agsync-0.1.1

 

[notice] A new release of pip is available: 24.2 -> 26.2.1

[notice] To update, run: python3.12 -m pip install --upgrade pip

$ claude

agsync check # your agent, mid-workflow

AGENTS.md

6 error protocol-files-exist boot protocol requires 'memory/goal.md', which does not exist — this step is unsatisfiable and every session skips it

9 error protocol-files-exist boot protocol requires 'goal.md', which does not exist — this step is unsatisfiable and every session skips it

memory/decisions.md

11 error unique-decision-ids D-021 is redefined here (first defined at line 7); 1 reference(s) to D-021 are now ambiguous

27 error decision-has-date D-027 has no **Date:** field

27 error relations-resolve D-027 supersedes D-019, which is not defined

tasks/09-verify-staging-deploy.md

1 error no-dependency-cycles dependency cycle: 09 -> 25 -> 09

9 error links-resolve link target '../memory/state.md' does not exist

tasks/25-cache-invalidation.md

3 warn status-not-qualified status is qualified with free text ('(all tiers incl. the edge cache)'); move the caveat into the body and keep the status machine-readable

tasks/26-rate-limit-headers.md

3 warn status-not-qualified status is qualified with free text ('(proxy path smoke-tested; client typecheck clea...'); move the caveat into the body and keep the status machine-readable

tasks/README.md

- error index-matches-files task 26 exists (tasks/26-rate-limit-headers.md) but is absent from the index — invisible to anyone reading it

4 error links-resolve link target '../memory/goal.md' does not exist

14 error index-matches-files task 25: index says 'todo', file says 'done'

 

5 decisions, 3 tasks, 2 index rows

10 error(s), 2 warning(s)

exit 1

                      $ pip install agsync
Collecting agsync
  Downloading agsync-0.1.1-py3-none-any.whl.metadata (13 kB)
Downloading agsync-0.1.1-py3-none-any.whl (37 kB)
Installing collected packages: agsync
Successfully installed agsync-0.1.1

[notice] A new release of pip is available: 24.2 -> 26.2.1
[notice] To update, run: python3.12 -m pip install --upgrade pip

$ claude

$ agsync check
AGENTS.md
     6  error protocol-files-exist  boot protocol requires 'memory/goal.md', which does not exist — this step is unsatisfiable and every session skips it
     9  error protocol-files-exist  boot protocol requires 'goal.md', which does not exist — this step is unsatisfiable and every session skips it
memory/decisions.md
    11  error unique-decision-ids  D-021 is redefined here (first defined at line 7); 1 reference(s) to D-021 are now ambiguous
    27  error decision-has-date  D-027 has no **Date:** field
    27  error relations-resolve  D-027 supersedes D-019, which is not defined
tasks/09-verify-staging-deploy.md
     1  error no-dependency-cycles  dependency cycle: 09 -> 25 -> 09
     9  error links-resolve  link target '../memory/state.md' does not exist
tasks/25-cache-invalidation.md
     3  warn status-not-qualified  status is qualified with free text ('(all tiers incl. the edge cache)'); move the caveat into the body and keep the status machine-readable
tasks/26-rate-limit-headers.md
     3  warn status-not-qualified  status is qualified with free text ('(proxy path smoke-tested; client typecheck clea...'); move the caveat into the body and keep the status machine-readable
tasks/README.md
     -  error index-matches-files  task 26 exists (tasks/26-rate-limit-headers.md) but is absent from the index — invisible to anyone reading it
     4  error links-resolve  link target '../memory/goal.md' does not exist
    14  error index-matches-files  task 25: index says 'todo', file says 'done'

5 decisions, 3 tasks, 2 index rows
10 error(s), 2 warning(s)
                      
exit 1
                    

03 / 09

Rarer than you’d think

agsync check # after someone fixed it

1 decisions, 1 tasks, 1 index rows

0 error(s), 0 warning(s)

exit 0

                      $ agsync check
1 decisions, 1 tasks, 1 index rows
0 error(s), 0 warning(s)
                      
exit 0
                    

04 / 09

Two agents, one task

agent-a

git commit -am "claim task 00"

1 decisions, 2 tasks, 2 index rows

0 error(s), 0 warning(s)

[main 0343383] claim task 00

2 files changed, 4 insertions(+), 4 deletions(-)

git push

To /var/folders/tp/frsg8twj4s55qxrdmh_f7kg40000gn/T/tmp.1j3RLgAvQF/memory.git

6134770..0343383 main -> main

agent-b

git commit -am "claim task 00"

1 decisions, 2 tasks, 2 index rows

0 error(s), 0 warning(s)

[main 718c394] claim task 00

2 files changed, 4 insertions(+), 4 deletions(-)

git push

To /var/folders/tp/frsg8twj4s55qxrdmh_f7kg40000gn/T/tmp.1j3RLgAvQF/memory.git

! [rejected] main -> main (fetch first)

error: failed to push some refs to '/var/folders/tp/frsg8twj4s55qxrdmh_f7kg40000gn/T/tmp.1j3RLgAvQF/memory.git'

hint: Updates were rejected because the remote contains work that you do not

hint: have locally. This is usually caused by another repository pushing to

hint: the same ref. If you want to integrate the remote changes, use

hint: 'git pull' before pushing again.

hint: See the 'Note about fast-forwards' in 'git push --help' for details.

git commit -am "start task 02"

tasks/02-rate-limit.md

3 error in-progress-needs-owner in progress with no **Owner:** — another agent cannot tell whether this is being worked on or was abandoned

 

1 decisions, 2 tasks, 2 index rows

1 error(s), 0 warning(s)

agent-a: $ git commit -am "claim task 00"
1 decisions, 2 tasks, 2 index rows
0 error(s), 0 warning(s)
[main 0343383] claim task 00
 2 files changed, 4 insertions(+), 4 deletions(-)

agent-a: $ git push
To /var/folders/tp/frsg8twj4s55qxrdmh_f7kg40000gn/T/tmp.1j3RLgAvQF/memory.git
   6134770..0343383  main -> main

agent-b: $ git commit -am "claim task 00"
1 decisions, 2 tasks, 2 index rows
0 error(s), 0 warning(s)
[main 718c394] claim task 00
 2 files changed, 4 insertions(+), 4 deletions(-)

agent-b: $ git push
To /var/folders/tp/frsg8twj4s55qxrdmh_f7kg40000gn/T/tmp.1j3RLgAvQF/memory.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to '/var/folders/tp/frsg8twj4s55qxrdmh_f7kg40000gn/T/tmp.1j3RLgAvQF/memory.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally. This is usually caused by another repository pushing to
hint: the same ref. If you want to integrate the remote changes, use
hint: 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

$ git commit -am "start task 02"
tasks/02-rate-limit.md
     3  error in-progress-needs-owner  in progress with no **Owner:** — another agent cannot tell whether this is being worked on or was abandoned

1 decisions, 2 tasks, 2 index rows
1 error(s), 0 warning(s)

05 / 09

Every commit you’ve ever pushed, judged

agsync replay . # the part that hurts

sha date errors rules

c88a4a0 2026-08-01 0 —

39f40b0 2026-08-01 1 protocol-files-exist

314ed2e 2026-08-02 2 protocol-files-exist, unique-decision-ids

afdc70c 2026-08-03 2 protocol-files-exist, unique-decision-ids

a467863 2026-08-04 1 unique-decision-ids

b869229 2026-08-05 1 unique-decision-ids

 

5 of 6 pushes would have been rejected

exit 0

                      $ agsync replay .
sha      date        errors  rules
c88a4a0  2026-08-01       0  —
39f40b0  2026-08-01       1  protocol-files-exist
314ed2e  2026-08-02       2  protocol-files-exist, unique-decision-ids
afdc70c  2026-08-03       2  protocol-files-exist, unique-decision-ids
a467863  2026-08-04       1  unique-decision-ids
b869229  2026-08-05       1  unique-decision-ids

5 of 6 pushes would have been rejected
                      
exit 0
                    

06 / 09

How long nobody noticed

agsync replay . --first-seen

sha date errors rules

c88a4a0 2026-08-01 0 —

39f40b0 2026-08-01 1 protocol-files-exist

314ed2e 2026-08-02 2 protocol-files-exist, unique-decision-ids

afdc70c 2026-08-03 2 protocol-files-exist, unique-decision-ids

a467863 2026-08-04 1 unique-decision-ids

b869229 2026-08-05 1 unique-decision-ids

 

5 of 6 pushes would have been rejected

 

rule first failed survived

unique-decision-ids 314ed2e 2026-08-02 4 commits, 3 days (still failing at HEAD)

protocol-files-exist 39f40b0 2026-08-01 3 commits, 1 day

 

longest-lived violation: unique-decision-ids in memory/decisions.md — 4 commits — D-001 is redefined here (first defined at line 6); 2 reference(s) to …

exit 0

                      $ agsync replay . --first-seen
sha      date        errors  rules
c88a4a0  2026-08-01       0  —
39f40b0  2026-08-01       1  protocol-files-exist
314ed2e  2026-08-02       2  protocol-files-exist, unique-decision-ids
afdc70c  2026-08-03       2  protocol-files-exist, unique-decision-ids
a467863  2026-08-04       1  unique-decision-ids
b869229  2026-08-05       1  unique-decision-ids

5 of 6 pushes would have been rejected

rule                  first failed         survived
unique-decision-ids   314ed2e 2026-08-02   4 commits, 3 days (still failing at HEAD)
protocol-files-exist  39f40b0 2026-08-01   3 commits, 1 day

longest-lived violation: unique-decision-ids in memory/decisions.md — 4 commits — D-001 is redefined here (first defined at line 6); 2 reference(s) to …
                      
exit 0
                    

07 / 09

The part people uninstall

git commit -m "wip" # good luck

memory/decisions.md

16 error unique-decision-ids D-001 is redefined here (first defined at line 6); 1 reference(s) to D-001 are now ambiguous

tasks/README.md

9 error index-matches-files task 00: index says 'todo', file says 'done'

 

1 decisions, 1 tasks, 1 index rows

2 error(s), 0 warning(s)

exit 1

                      $ git commit -m "wip"
memory/decisions.md
    16  error unique-decision-ids  D-001 is redefined here (first defined at line 6); 1 reference(s) to D-001 are now ambiguous
tasks/README.md
     9  error index-matches-files  task 00: index says 'todo', file says 'done'

1 decisions, 1 tasks, 1 index rows
2 error(s), 0 warning(s)
                      
exit 1
                    

08 / 09

Start from nothing

agsync init

created AGENTS.md

created memory/goal.md

created memory/decisions.md

created memory/state.md

created tasks/README.md

created tasks/00-example.md

created .agsync.toml

 

Next: describe your project's objective in memory/goal.md, then run `agsync check`.

exit 0

                      $ agsync init
created  AGENTS.md
created  memory/goal.md
created  memory/decisions.md
created  memory/state.md
created  tasks/README.md
created  tasks/00-example.md
created  .agsync.toml

Next: describe your project's objective in memory/goal.md, then run `agsync check`.
                      
exit 0