#Best practices for AGENTS.md, HEARTBEAT.md

27 messages Ā· Page 1 of 1 (latest)

cerulean pond
#

Hi!

I’ve been spending quite some time trying to understand the best way to put instructions and what to put where, and while every time I learn something new, I’m also getting some issues on the way. Mainly related to skill adherence and how agents follow instructions.
In the template AGENTS.md it often says ā€œdo this and thisā€, but my agents don’t really do those actions, they treat AGENTS file as a protocol on what to do in certain situations, but they are missing some trigger or call to action. Let’s say I put exact steps and rules on how to move cards through statuses/lists in Trello, and one rule says ā€œif you need more info or get stuck - move to Blockedā€. In my HEARTBEAT I want them to periodically check boards for tasks tagged with their roles and work on those tasks.
The problem: they often mess up the rules on how to move tasks, they leave them in TODO if lacking info, or moving to Done etc.
When I put more rules on how to move tasks right in the HEARTBEAT checklist, they seem to follow it, but then I’m duplicating same thing twice which is weird. So, what is the best way to make sure agents strictly follow the rules and at the same time actually know when to take action and perform automatic tasks? I’m using Minimax M2.7 which claims to have 97% skill adherence šŸ˜…

sour narwhalBOT
mental quarryBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> āœ… Mark Solution

sour narwhalBOT
supple currentBOT
#

Short version: treat them as different layers.

  • AGENTS.md = standing orders / rulebook, what the agent is allowed to do, exact state transitions, escalation rules
  • HEARTBEAT.md or cron = trigger, when to actually run that work

So yes, if AGENTS says ā€œmanage Trello like thisā€ but nothing explicitly says ā€œrun Trello triage nowā€, the model may treat it as background policy, not an action request.

What usually works best:

  1. Put the full workflow in AGENTS.md
    • explicit state machine, not prose
    • example:
      • missing info → Blocked + leave comment with what is missing
      • started work → In Progress
      • verified complete → Done
      • never move TODO -> Done directly
#
  1. Put only the trigger in HEARTBEAT.md

    • not the whole policy again
    • e.g. ā€œRun Trello triage for cards tagged with this role, following standing orders in AGENTS.md.ā€
  2. Add a verification rule in AGENTS.md

    • ā€œBefore ending a Trello run, verify every touched card is in the correct list.ā€
    • This helps a lot. Docs call this the Execute → Verify → Report pattern.
  3. Use tasks: in HEARTBEAT.md for periodic checks

    • good for ā€œevery 15m scan Trelloā€
    • keeps the heartbeat small and avoids duplicating the full rules

Very important gotcha: if you enabled heartbeat.lightContext: true, heartbeat runs only keep HEARTBEAT.md, not AGENTS.md. In that setup, what you’re seeing is expected, the heartbeat sees the checklist but not the standing orders.

So for your case, I’d structure it like this:

AGENTS.md

#
  • Trello program
  • allowed states
  • exact transition rules
  • forbidden transitions
  • escalation rules
  • execute/verify/report

HEARTBEAT.md

tasks:
- name: trello-role-scan
  interval: 15m
  prompt: "Execute Trello triage for cards tagged with this role, following the standing orders in AGENTS.md."

- If nothing needs attention, reply HEARTBEAT_OK.
cerulean pond
#

Is it correct to put intervals in heartbeat file though? If my config hearbeat is 30m, how would agent run a task every 15m?

supple currentBOT
#

Yep, that’s the key limitation: tasks: intervals inside HEARTBEAT.md are evaluated only when a heartbeat tick happens.

So if your heartbeat is every 30m:

  • a task with interval: 15m will not run every 15m
  • it can only run at the next heartbeat, so in practice it runs every 30m max

Think of it as:

  • heartbeat cadence = polling frequency
  • tasks: interval = ā€œis this task due on this poll?ā€

So for your case:

  • if you want rough periodic checks, HEARTBEAT.md is fine
  • if you want real 15m execution, either:
    1. set heartbeat to 15m, or
cerulean pond
#

Yes please, would be awesome. Ideally I also want to have all the shared protocols (Trello is used by all agents, but default trello skill does not specify state transitions) to be extracted somewhere so I don’t repeat the rules for all agents in their AGENTS.md.
Then as I understood HEARTBEAT.md should be clean and only contain short ā€œdo this, do thatā€ tasks.

supple currentBOT
#

Yep, that’s the right mental model.

Also, the skill not defining state transitions is normal. Skills usually handle the mechanics of doing Trello actions. Your workflow policy belongs in standing orders / shared protocol docs.

The clean setup I’d use is:

1. Put the shared Trello rules in one shared file

Example: protocols/trello.md

# Trello Protocol

## Allowed lists
- TODO
- IN_PROGRESS
- BLOCKED
#
- DONE

## Transition rules
- If work has not started, keep in TODO.
- If work started, move to IN_PROGRESS.
- If missing information, dependency, or permission, move to BLOCKED and add a comment saying exactly what is missing.
- Move to DONE only when acceptance criteria are met and verified.

## Forbidden transitions
- Never leave a card in TODO after discovering it is blocked.
- Never move a card to DONE without verification.
- Never guess missing information.

## Required verification
- After changing any card, re-read the card and verify the list matches the evidence.
#
- In the final report, list every touched card and why it was moved.

2. In each agent’s AGENTS.md, keep only a tiny pointer + role rules

Because arbitrary files are not auto-injected by default, each agent still needs a small instruction telling it to read the shared protocol.

## Shared protocols
- Before any Trello action, read `protocols/trello.md` and follow it exactly.

## My Trello role
- Only work on cards tagged `design` and assigned to this agent.
- If a card needs another role, leave a comment and move it per the Trello protocol.

That’s the minimal repetition I’d accept. Just the pointer, not the full rules copied everywhere.

#

3. Keep HEARTBEAT.md short and trigger-oriented

tasks:
- name: trello-scan
  interval: 30m
  prompt: "Scan Trello for cards matching this agent's role. Execute triage per AGENTS.md and the shared Trello protocol."

- If nothing needs attention, reply HEARTBEAT_OK.

4. If you need exact timing, use cron

If you want true every 15m, use cron. Heartbeat is better for ā€œperiodic background checksā€, not precise scheduling.


Best-practice split

#
  • Shared protocol file = global rules all agents use
  • AGENTS.md = agent-specific authority + ā€œread the shared protocol before Xā€
  • HEARTBEAT.md = small recurring triggers
  • cron = exact schedule

One important gotcha

If you use heartbeat.lightContext: true, the heartbeat run keeps only HEARTBEAT.md, not the usual bootstrap files. For agents that depend on AGENTS.md + shared protocol references, I would keep that off.

Docs:

If you want, I can also write you a copy-paste Trello template for:

  • protocols/trello.md
  • one agent AGENTS.md
  • one minimal HEARTBEAT.md
cerulean pond
#

Yes please, would be great.
I'm using lightContext: false, so it should be fine on that part.

supple currentBOT
#

Nice, lightContext: false is perfect for this pattern.

Here’s a copy-paste starter I’d use.

protocols/trello.md

# Shared Trello Protocol

Use this protocol for every Trello action. These rules apply to all agents.

## Scope

- Only act on cards that match your role, assignment, or explicitly requested tag.
- If a card is outside your scope, do not move it unless this protocol explicitly allows it.

## Required review before changing a card
#

Before moving any card, inspect:
- title
- description
- checklist / subtasks
- latest comments
- labels / tags
- assignees
- due date, if present

Do not move a card based on title alone.

## State transition rules

| Condition | Required action |
#
| --- | --- |
| No work started, no blocker | Keep in `TODO` |
| Work has started and can continue | Move to `IN_PROGRESS` |
| Missing info, dependency, approval, access, or asset | Move to `BLOCKED` |
| All acceptance criteria completed and verified | Move to `DONE` |

## Mandatory blocker rule

If you need more information, are waiting on someone, or cannot continue safely:
- move the card to `BLOCKED`
- add a comment that says exactly what is missing
- mention the dependency or person/team if known
- stop work on that card

Never leave a blocked card in `TODO`.
#

## Done rule

Move a card to `DONE` only if:
- the requested work is actually complete
- acceptance criteria are met
- the result was verified

Never move a card to `DONE` just because it looks close or has no recent activity.

## Forbidden actions

- Do not move `TODO` directly to `DONE` without verification.
- Do not guess missing information.
- Do not silently leave ambiguous cards unchanged if they are clearly blocked.
#
- Do not invent new workflow states unless explicitly configured.

## Execute, verify, report

For every Trello run:
1. Execute the needed card changes
2. Verify each touched card ended in the correct state
3. Report what changed and why

## Final report format

For each touched card, report:
- card name
- previous state
- new state
#
- short reason

Agent AGENTS.md snippet

## Shared protocols

- Before any Trello action, read `protocols/trello.md` and follow it exactly.
- The shared Trello protocol is mandatory, not optional guidance.

## My Trello scope

- I only work on cards labeled `design`, `ux`, and cards assigned to this agent.
#
- If a card needs another role, I may move it to `BLOCKED` per the Trello protocol and explain what is needed.
- I do not manage unrelated cards.

## Automation rules

- When asked to perform Trello triage, do the work immediately, not just describe what should happen.
- Follow Execute, Verify, Report on every Trello run.
- If any card state is ambiguous, use the Trello protocol decision rules, not intuition.

HEARTBEAT.md

tasks:
#
- name: trello-role-triage
  interval: 30m
  prompt: |
    Run Trello triage for cards in your scope.
    Before changing anything, read AGENTS.md and protocols/trello.md.
    Process all matching cards once.
    Apply the shared Trello protocol exactly.
    If a card is blocked, move it to BLOCKED and explain what is missing.
    Verify every touched card after changing it.

- If nothing needs attention, reply HEARTBEAT_OK.

My recommendation

#

Keep it split like this:

  • protocols/trello.md = shared workflow brain
  • AGENTS.md = per-agent scope + ā€œread the shared protocolā€
  • HEARTBEAT.md = short trigger only

That gives you a little duplication, but only the useful kind. One small pointer in each AGENTS.md, not the whole Trello policy copied everywhere.

If you need true 15m execution, use cron. If 30m polling is fine, heartbeat is enough.

Docs:

If you want, I can do one more pass and make this even stricter, like a more deterministic ā€œif X then Yā€ version for better model compliance.