What does it do?

Till turns a one-register night close into a constrained Strands workflow for small-shop owners.

The cashier counts the drawer and classifies tenders. The auditor applies one visible policy table to variance, refunds, voids, and no-sales. Safe items continue automatically; only exceptions that policy cannot safely close reach the owner's Decision Inbox. A real Strands BeforeNodeCallEvent interrupts the graph before the clerk. After the owner stamps every open decision, the same graph resumes and files a locked deposit packet.

The board is deliberately transparent: role contracts live in skills/role/SKILL.md, policy is centralized in till/policy.py, the register tape exposes the tool calls, and the final packet can be exported as local JSON after the night is locked.

Why does it matter?

Small-shop owners repeatedly close the same register while making judgment-heavy decisions about shortages, refunds, and voids. Till keeps repetitive work in the background and surfaces only the decisions that require human judgment. It prevents a deposit from being filed while an exception is unresolved.

What is demonstrated?

  1. A seeded register starts with no open asks.
  2. Run night close executes the Strands graph.
  3. The owner sees a drawer variance and refund exception while the clerk is blocked.
  4. The owner accepts or approves each open decision.
  5. The same graph resumes and files a locked deposit packet.
  6. The board shows the role/tool tape, empty inbox, locked packet, and local JSON audit export.

The board also accepts a different POS-neutral close packet with shop metadata, expected/count cash, tenders, and refund/void/no-sale exceptions. The same graph and policy table process it, while malformed packets are rejected before the graph starts.

How is Strands used?

  • GraphBuilder connects cashier → auditor → clerk.
  • Each role is a MultiAgentBase graph node and loads a role contract from skills/role/SKILL.md.
  • BeforeNodeCallEvent provides the owner-gate interrupt before the clerk.
  • interruptResponse resumes the same graph after the complete decision set is validated.
  • The deterministic local executor is deliberate: no model is allowed to invent or decide cash policy. Optional model review is bounded to owner-facing explanation.

Boundary

The current build uses a synthetic, process-local register. It does not claim a real POS connection, real-money movement, multi-user persistence, hosted deployment, measured customer savings, or AWS AgentCore deployment. The local audit export is a JSON download and is not uploaded or persisted by Till.

See the public README for setup instructions, architecture, tests, and limitations.

Built With

Share this project:

Updates

Submission history