How `swarm_handoff.sh` Validates Hand‑off Draft Files: A Deep Dive into SwarmForge's 7-Step Pipeline
The validation logic in swarm_handoff.sh is actually implemented in the accompanying swarm_handoff.bb Clojure/Babashka script, which runs a deterministic 7-step pipeline checking syntax, semantics, type compatibility, and Git integrity before queuing any hand‑off.
swarm_handoff.sh in the unclebob/swarm-forge repository serves as a thin Bash wrapper that delegates all work to swarm_handoff.bb. Understanding this validation logic is essential for developers creating hand‑off drafts that pass inspection and reach the outbox. Each validation step in swarm_handoff.bb is designed to catch specific categories of errors before malformed files propagate through the SwarmForge system.
Where the Validation Actually Lives
The Bash wrapper at swarmforge/scripts/swarm_handoff.sh contains no validation logic itself—it simply passes arguments to swarm_handoff.bb. All draft validation happens in the Babashka script at swarmforge/scripts/swarm_handoff.bb, specifically within functions parse-draft, validate-recipients, validate, and their helper functions.
Step 1: Parse the Draft File for Syntax Errors
The parse-draft function (lines 93–136) reads the hand‑off draft line‑by‑line and extracts field/value pairs. It collects multiple syntax errors rather than failing on the first:
- Missing separator: Fields must use
": "(colon space) - Empty fields: Neither field names nor values can be blank
- Duplicate headers: Each header may appear only once
- Reserved fields: Fields like
from,timestamp, andsequenceare reserved for system use - Unknown fields: Any field not in the allowed set is rejected
This greedy error collection lets users fix multiple issues in one pass.
# Example syntax error caught by parse-draft
$ ./swarm_handoff.sh malformed.handoff
HANDOFF INVALID: malformed.handoff
Errors:
- Line 3: Missing ': ' separator.
- Duplicate header 'priority'.
- Unknown field 'urgency'.
Step 2: Validate Recipients in the to Header
The validate-recipients function (lines 138–156) processes the comma‑separated to field with four specific checks per recipient:
- Empty recipient – no blank entries between commas
- Underscores – illegal in recipient names
- Duplication – no repeated recipients allowed
- Unknown role – each recipient must exist in
roles.tsv(checked viarole-known?)
The roles.tsv file at .swarmforge/roles.tsv provides the canonical list of valid roles.
Step 3: Check Required Fields and Base Constraints
In the validate function (lines 195–202), the base-errors construction ensures:
type,to, andpriorityare all presenttypematches allowed values:git_handoffornotepriorityconforms to the two‑digit pattern (e.g.,01,12)
Step 4: Apply Type‑Specific Header Validation
Depending on the type value, additional validation runs via git-errors (lines 211–222) or note-errors (lines 224–229):
git_handoff requirements:
commitheader must be present and resolvable to a valid Git objecttaskheader required, with length restrictions- Commit SHA canonicalized to short‑hash via
canonical-commit
note requirements:
messageheader required, with length validation
Step 5: Enforce Field‑Type Compatibility
The field-errors comprehension (lines 181–194) ensures headers only appear when appropriate to their type. For example, task and commit are illegal in a note hand‑off, while message cannot appear in a git_handoff.
This prevents semantic confusion where fields meant for one hand‑off type leak into another.
Step 6: Canonicalize Git Commits
The canonical-commit function (lines 157–172) provides Git integrity validation:
- Runs
git rev-parse --disambiguateto locate a unique object for the given SHA fragment - Verifies the object is actually a commit (not a tree or blob)
- Returns the canonical short‑hash for consistent identification
This ensures hand‑offs reference real, reachable commits in the repository.
Step 7: Aggregate and Report All Errors
The final return of validate (lines 235–236) combines parsing errors, recipient errors, field‑type errors, and type‑specific errors into a single vector. The -main function at the bottom of swarm_handoff.bb orchestrates the flow:
- Parse →
parse-draft - Validate →
validate(with all helper functions) - If errors exist → print
error-reportand exit with status 2 - If clean → write hand‑off to
.swarmforge/handoffs/outbox/
Valid vs. Invalid Hand‑off Examples
Valid git_handoff draft:
type: git_handoff
to: reviewer,qa
priority: 05
task: improve-login-flow
commit: a1b2c3d4e5
$ ./swarm_handoff.sh example.handoff
HANDOFF QUEUED: /path/to/.swarmforge/handoffs/outbox/05_20241012T083045Z_000123_from_alice_to_reviewer_qa.handoff
Invalid draft (missing commit, duplicate recipient):
type: git_handoff
to: reviewer,reviewer
priority: 09
task: refactor-auth
$ ./swarm_handoff.sh bad.handoff
HANDOFF INVALID: bad.handoff
Errors:
- Missing required header 'commit' for git_handoff.
- Duplicate recipient 'reviewer'.
Exit status 2 prevents queuing malformed hand‑offs.
Key Source Files for Hand‑off Validation
| File | Purpose |
|---|---|
swarmforge/scripts/swarm_handoff.sh |
Bash wrapper forwarding to Babashka script |
swarmforge/scripts/swarm_handoff.bb |
Core validation pipeline with all functions above |
.swarmforge/roles.tsv |
Canonical role list for recipient validation |
swarmforge/handoff-protocol.md |
Protocol specification for hand‑off format |
Summary
The swarm_handoff.sh validation logic—implemented in swarm_handoff.bb—provides comprehensive draft checking through seven distinct steps:
- Syntax validation via
parse-draftcatches formatting errors - Recipient validation via
validate-recipientsenforces role existence and naming rules - Base field requirements ensure mandatory headers are present and well‑formed
- Type‑specific rules apply appropriate constraints for
git_handoffvs.note - Field‑type compatibility prevents inappropriate header mixing
- Git integrity checks via
canonical-commitvalidate commit references - Aggregated error reporting gives complete feedback before any exit
This pipeline guarantees that only syntactically correct, semantically valid, and type‑appropriate hand‑offs reach the SwarmForge outbox.
Frequently Asked Questions
What exit status does swarm_handoff.sh return for invalid drafts?
Exit status 2. The script explicitly exits with code 2 when validation errors are found, after printing the error-report. Successful validation results in normal exit status 0 and the hand‑off being queued to the outbox.
Can I use underscores in recipient names according to swarm_handoff.sh validation?
No. The validate-recipients function explicitly rejects any recipient containing underscores. This is one of the four checks applied to each comma‑separated entry in the to header, alongside emptiness, duplication, and role existence in roles.tsv.
Why does swarm_handoff.sh delegate to a Babashka script rather than pure Bash?
The validation requirements—structured parsing, error aggregation, Git integration, and type‑dependent logic—are complex enough to benefit from Clojure's data structures and libraries. swarm_handoff.bb handles this elegantly while swarm_handoff.sh provides a familiar CLI entry point and handles environment setup.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →