An update on Jules for Crystal and Shards

Hello 0/,

In my previous post, Collaboration in the age of AI, I discussed the challenge of AI-generated noise and proposed a three-tiered Deterministic Collaboration Protocol (DCP) designed to prevent maintainer burnout.

I’ve been working on putting this theory into practice. I want to share a concrete update on what we’ve done to clean up, verify, and operationalize this protocol on my forks of crystal-lang/crystal and crystal-lang/shards using Google’s Jules coding agent.

Here is the progress we’ve made so far to turn AI-assisted development into a clean, zero-friction workflow.

1. Hardening the VM Sandbox (Bootstrapping)

One of the biggest friction points for remote AI agents is environment setup. Brittle or missing dependencies lead to build failures and invalid assumptions.

  • Dynamic, Privileged Setup Scripts: We rewrote the VM bootstrap scripts (.jules/setup.sh) in both repositories. Instead of relying on hardcoded sudo (which crashes inside minimal container environments), the scripts now dynamically check the execution user ($EUID).

  • Official Repository Integrations: The scripts are configured to dynamically fetch the official Open Build Service (OBS) repository signing keys inline and install the official upstream Crystal package alongside development headers in a single, secure transaction. This ensures the agent is compiling code against a deterministic environment that mirrors upstream exactly.

  • Local CLI Tooling in Crystal (cjules): To manage the remote Jules sessions from the terminal, we integrated cjules; a CLI client for the Jules API written completely in Crystal. It fits our ecosystem perfectly and allowed us to watch execution logs, inspect remote activities, and cleanly apply or patch the agent’s changes to our local branches.

2. Auditing and Integrating the “Frozen” PRs

In my last post, I mentioned that the PRs on renich/crystal were frozen in time. We went back and performed a full audit and local integration check on all 7 open pull requests (which cover optimizations to Indexable#map, WebSocket DoS vulnerabilities in the Playground, and path traversal mitigations).

  • Strict Ecosystem Compliance (PR #30 Cleanup): In checking the commits of PR #30, we caught a classic case of agent workspace pollution: the agent had accidentally committed raw .diff patch files. Adhering to the protocol, I checked out the branch, deleted the stray files, amended the commit, and force-pushed a clean history back to GitHub.

  • Two-Stage Code Review Audit: We ran the open PR queue through our Two-Stage Code Review Pipeline (Adversarial Audit & Moderation Filtering). Through this pipeline, we caught a duplicate run conflict (PR #78 vs PR #76), approving #76 for its complete WebSocket fiber exception safety check while scheduling #78 to be closed (porting its Sentinel journal entry to master).

  • The Full Integration Pass: I ran a local dry-run merge of the approved branches onto master. The files merged with 100% success. The merged codebase compiled cleanly and passed the entire spec suite:

    Finished in 14.73 seconds
    331 examples, 0 failures, 0 errors, 1 pending
    

3. Codifying the Protocol for the Agents

A protocol is only useful if it is strictly followed. To ensure that future agent runs comply with the rules, we codified the guidelines directly into the project’s developer context:

  • Repository-Level Guidelines (AGENTS.md): The Deterministic Collaboration Protocol (DCP) is now formally documented as a core mandate under the ## 🛑 General Mandates & Workflow section of crystal/AGENTS.md and shards/AGENTS.md.

  • Custom AI Skill: We packaged these guidelines as a custom Antigravity skill (foss-collaboration). This forces any agent running in these workspaces to follow the Context → Invariants → Compliance sequence before proposing code.

  • First Compliance Verification: We launched and published the first formal compliance PR on Shards at renich/shards#1. This PR refactors the Git, Mercurial, and Fossil resolvers to spawn external commands using safe array-based arguments (mitigating shell injection risks) and removes unsafe .not_nil! assertions in the Molinillo solver.

4. Git-Versioned Prompts & Staggered Daily Runs

To avoid the tediousness of updating system prompts in the Jules Web UI, we implemented a Prompt Redirect Pattern and optimized our automated agent schedules:

  • The Prompt Redirect Pattern: We moved all role-specific instructions out of the Web UI and into Git under a dedicated directory: .jules/*_instructions.md. The Web UI now holds a single, static redirect line (e.g. “You are Bolt. Before starting your task, you MUST read .jules/bolt_instructions.md and follow its guidelines”). Future prompt modifications are made via standard Git commits.

  • Higgins (The QA/Spec Majordomo): We introduced a new, strict testing agent named Higgins (in charge of scanning modules with missing spec coverage and writing robust native Crystal unit specs).

  • Staggered Daily Cadence: To speed up our evaluation feedback loops without bottlenecking our GitHub Actions runner queue, we enabled Daily runs across all 6 schedules, staggered at 1-hour intervals in two blocks (overnight and early morning). This ensures each VM has time to complete its specs and push its PR before the next agent wakes up.

Closing Thoughts

By treating project conventions as rigid APIs and enforcing clean workspaces, we’ve shown that AI contributions can be integrated cleanly without taxing the cognitive load of human maintainers. The goal is to move away from “flooding the ether” with implementations and toward a workflow where the agent outputs verified, structured, and zero-pollution patches.

I’d love to hear your thoughts on these updates, the setup scripts, or how we might refine the protocol further as we continue our experiments!

1 Like