# How the pack_board.bb Module Manages Tasks in SwarmForge

> Discover how the pack_board.bb module manages SwarmForge tasks using a single TSV file and file-based locking for reliable data persistence and exclusive access.

- Repository: [Robert C. Martin/swarm-forge](https://github.com/unclebob/swarm-forge)
- Tags: internals
- Published: 2026-08-31

---

**The `pack_board.bb` module manages SwarmForge tasks by persisting them as tab-separated rows in a single TSV file under `.swarmforge/board/tasks.tsv`, using file-based locking to guarantee exclusive access during all mutations.**

The `pack_board.bb` module serves as the core task-board implementation for the unclebob/swarm-forge repository. This Babashka-based script provides a lightweight command-line API that operates on a simple file-based storage system, prioritizing portability and concurrent safety without external database dependencies.

## Task Storage Architecture

### Board Directory and File Paths

The module defines the board location through the `board-dir` function at lines 82-84, which constructs the path `<project-root>/.swarmforge/board`. Within this directory, the `tasks-file` function (lines 85-87) points to `tasks.tsv`, the central datastore for all task records.

### TSV Data Format

Each task occupies one row with six tab-separated columns: `name`, `lane`, `created`, `updated`, `task-id`, and `audit-count`. This schema allows the module to track task progression through lanes (such as `dev`, `review`, or `done`) while maintaining temporal metadata and version control integration via the audit counter.

## Concurrency Safety with File-Based Locking

All mutating operations acquire an exclusive lock through the `with-board-lock` construct (lines 88-96). This macro creates a `tasks.lock` file in the board directory and establishes an exclusive lock before executing the body, ensuring that concurrent SwarmForge agents cannot corrupt the TSV during simultaneous write operations.

## Reading and Writing Task Data

The module provides two fundamental I/O helpers. The `read-rows` function (lines 38-44) returns a vector of non-blank lines from the TSV file, while `write-rows` (lines 45-52) handles atomic writes by first persisting to a temporary file before moving it into place, preventing data loss during write failures.

## Core Task Lifecycle Operations

### Creating Tasks

The `create!` function (lines 77-92) validates command-line arguments, checks for duplicate task names, and appends a new row to `tasks.tsv`. It optionally generates supplementary files: a body text file (`<name>.txt`) and a markdown document (`tasks/<name>.md`) for extended task descriptions.

### Moving and Completing Tasks

To change a task's status, the module uses `set-lane!` (lines 99-111), which locates the target row by name and updates the *lane* column while preserving the *created* and *updated* timestamps. The `done!` function (lines 115-117) simply invokes `set-lane!` with the literal `"done"` lane, signaling task completion.

### Listing and Deleting Tasks

The `list!` function (lines 119-124) outputs the raw TSV content to stdout, enabling downstream tools and UI components to parse the current board state. For removal, `delete!` (lines 126-133) eliminates the target row and cleans up the optional body file if it exists.

## Session Management and Auditing

Beyond basic CRUD operations, `pack_board.bb` supports SwarmForge's hand-off protocol through specialized functions. The `archive-session!` function (lines 65-71) captures a role's tmux pane content (or a stub) and stores it under `.swarmforge/sessions/<role>/pane.txt` for historical review. The `increment-audit!` function (lines 108-124) finds a row by its `task-id` and increments the final *audit-count* column, facilitating change tracking across agent transitions.

## Command Dispatch Interface

User-facing commands map to internal functions through the `commands` hashmap and `-main` entry point (lines 138-150). The CLI accepts the following operations:

```bash

# Create a new task in the dev lane

./pack_board.bb create --name "Implement auth" --lane "dev"

# Move to review lane

./pack_board.bb move --name "Implement auth" --lane "review"

# Mark as complete

./pack_board.bb done --name "Implement auth"

# List all tasks

./pack_board.bb list

# Archive tmux session for a role

./pack_board.bb archive --role "backend"

# Increment audit counter

./pack_board.bb increment-audit --task-id "20240901T123456789012Z-implement-auth"

# Delete task

./pack_board.bb delete --name "Implement auth"

```

## Summary

- The `pack_board.bb` module stores all task data in a single TSV file at `.swarmforge/board/tasks.tsv` with a six-column schema.
- File-based locking via `with-board-lock` prevents concurrent write corruption when multiple agents access the board simultaneously.
- Atomic write operations use temporary files to ensure data integrity during persistence failures.
- The module provides complete lifecycle management through `create!`, `set-lane!`, `done!`, `list!`, and `delete!` functions.
- Specialized functions like `archive-session!` and `increment-audit!` support SwarmForge's agent hand-off and auditing protocols.

## Frequently Asked Questions

### Where does pack_board.bb store task data?

According to the source code in `swarmforge/scripts/pack_board.bb`, task data persists in a tab-separated value file located at `<project-root>/.swarmforge/board/tasks.tsv`. The `board-dir` and `tasks-file` functions construct this path relative to the project root identified by Git traversal.

### How does the module handle concurrent access from multiple agents?

The `with-board-lock` mechanism (lines 88-96) creates a `tasks.lock` file and acquires an exclusive system-level lock before any mutation occurs. This ensures that only one SwarmForge agent can modify the TSV at a time, preventing race conditions and data corruption during parallel operations.

### What information is stored for each task in the TSV file?

Each row contains six tab-separated fields: the task `name`, current `lane` (status), `created` timestamp, `updated` timestamp, unique `task-id`, and `audit-count`. This schema supports workflow tracking while maintaining lightweight, parseable storage compatible with standard Unix tools.

### How do I programmatically move a task to a different lane?

Invoke the `move` command with the `--name` and `--lane` arguments, which triggers the `set-lane!` function (lines 99-111) to rewrite the lane column while preserving other metadata. For example: `./pack_board.bb move --name "Feature X" --lane "review"` transitions the task from its current state to the review lane.