RightNow-AI/openfang
Open-source Agent Operating System
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 6d ago
- ✓15 active contributors
- ✓Apache-2.0 licensed
Show all 6 evidence items →Show less
- ✓CI configured
- ✓Tests present
- ⚠Concentrated ownership — top contributor handles 67% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/rightnow-ai/openfang)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/rightnow-ai/openfang on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: RightNow-AI/openfang
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/RightNow-AI/openfang shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 6d ago
- 15 active contributors
- Apache-2.0 licensed
- CI configured
- Tests present
- ⚠ Concentrated ownership — top contributor handles 67% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live RightNow-AI/openfang
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/RightNow-AI/openfang.
What it runs against: a local clone of RightNow-AI/openfang — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in RightNow-AI/openfang | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 36 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of RightNow-AI/openfang. If you don't
# have one yet, run these first:
#
# git clone https://github.com/RightNow-AI/openfang.git
# cd openfang
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of RightNow-AI/openfang and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "RightNow-AI/openfang(\\.git)?\\b" \\
&& ok "origin remote is RightNow-AI/openfang" \\
|| miss "origin remote is not RightNow-AI/openfang (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "Cargo.toml" \\
&& ok "Cargo.toml" \\
|| miss "missing critical file: Cargo.toml"
test -f "crates/openfang-kernel/src/lib.rs" \\
&& ok "crates/openfang-kernel/src/lib.rs" \\
|| miss "missing critical file: crates/openfang-kernel/src/lib.rs"
test -f "crates/openfang-runtime/src/lib.rs" \\
&& ok "crates/openfang-runtime/src/lib.rs" \\
|| miss "missing critical file: crates/openfang-runtime/src/lib.rs"
test -f "crates/openfang-api/src/server.rs" \\
&& ok "crates/openfang-api/src/server.rs" \\
|| miss "missing critical file: crates/openfang-api/src/server.rs"
test -f "crates/openfang-api/src/openai_compat.rs" \\
&& ok "crates/openfang-api/src/openai_compat.rs" \\
|| miss "missing critical file: crates/openfang-api/src/openai_compat.rs"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 36 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~6d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/RightNow-AI/openfang"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
OpenFang is an open-source Agent Operating System written in Rust that runs autonomous agents 24/7 on schedules without user prompts. Unlike chatbot frameworks, it compiles to a single ~32MB binary and features "Hands"—pre-built capability packages that perform tasks like research, monitoring, lead generation, and social media management independently. The system includes 14 crates (137K LOC), a SQLite-backed memory layer, WASM sandbox execution, WebSocket gateways for Discord/Slack, and a dashboard UI served on localhost:4200. Workspace monorepo: 14 crates under crates/ (openfang-types, openfang-memory, openfang-runtime, openfang-kernel, openfang-cli, openfang-hands, openfang-skills, openfang-extensions, openfang-api, openfang-channels, openfang-wire, openfang-migrate, openfang-desktop). Pre-built agent definitions in agents/ (hello-world, coder, debugger, analyst, etc. with agent.toml configs). CI/CD via GitHub Actions (.github/workflows/ci.yml, release.yml). Desktop UI likely in openfang-desktop crate, CLI entry point via openfang-cli.
👥Who it's for
Developers and DevOps engineers building autonomous agent systems who need a production-ready, self-contained runtime without external orchestration dependencies. Teams managing AI agents at scale who require deterministic scheduling, knowledge graphs, multi-agent coordination, and a single binary deployment model.
🌱Maturity & risk
Actively developed and battle-tested (2,543+ tests passing, zero clippy warnings, v0.6.4 released). Pre-1.0 status means breaking changes between minor versions are expected, and the project recommends pinning to specific commits for production use until v1.0. The extensive test suite, multiple crates, CI/CD workflows, and structured agent ecosystem indicate serious engineering, but the pre-1.0 warning should be taken seriously for production deployments.
Primary risk is pre-1.0 API stability—minor version upgrades may break agent definitions or crate APIs. The project is maintained by RightNow-AI (potential single-maintainer risk, though GitHub Actions CI suggests team processes). Large dependency surface (tokio full features, wasmtime, axum, rusqlite, reqwest with all TLS variants) increases supply chain exposure. Rust MSRV is 1.75 (reasonable but not bleeding-edge), and WASM sandbox (wasmtime v43) requires careful security review if running untrusted agent code.
Active areas of work
v0.6.4 is current (April 2026 timeframe per README). Project is feature-complete but actively refined. Crates are well-organized with clear separation of concerns (memory, runtime, kernel, API layers). Agent ecosystem includes 15+ pre-built agents (analyst, architect, coder, debugger, devops-lead, etc.). Migration documentation present (MIGRATION.md), suggesting version transition tooling. Security guidelines documented (SECURITY.md), contributing guidelines established (CONTRIBUTING.md).
🚀Get running
# Unix/macOS/Linux
curl -fsSL https://openfang.sh/install | sh
openfang init
openfang start
# Dashboard: http://localhost:4200
# Or build from source (Rust 1.75+)
git clone https://github.com/RightNow-AI/openfang.git
cd openfang
cargo build --release
./target/release/openfang init
./target/release/openfang start
# Windows
irm https://openfang.sh/install.ps1 | iex
openfang init
openfang start
Daily commands:
# Development build and test
cargo build
cargo test --all
# Run daemon (listens on 4200 for dashboard, API, and agent scheduling)
cargo run --bin openfang-cli -- start
# Run specific agent
cargo run --bin openfang-cli -- agent run agents/hello-world/agent.toml
# Format and lint
cargo fmt --all
cargo clippy --all -- -D warnings
Dashboard accessible at http://localhost:4200 after openfang start.
🗺️Map of the codebase
Cargo.toml— Workspace root defining all 14 crates, shared dependencies (tokio, serde, sqlx), and version 0.6.4—essential for understanding build structure and dependency graphcrates/openfang-kernel/src/lib.rs— Core kernel crate providing agent lifecycle, task scheduling, and execution model—foundational to all agent behavior in OpenFangcrates/openfang-runtime/src/lib.rs— Runtime execution engine for agent tasks and skill invocation—load-bearing for how agents actually execute workcrates/openfang-api/src/server.rs— HTTP/WebSocket server entry point and request routing—critical for all external communication with OpenFangcrates/openfang-api/src/openai_compat.rs— OpenAI-compatible API layer enabling third-party client integration—key integration point for agent chat interfacescrates/openfang-cli/src/main.rs— CLI entry point and command-line agent orchestration—primary user-facing interface for local agent deploymentcrates/openfang-skills/src/lib.rs— Skill framework and built-in skill implementations—defines how agents extend capabilities and interact with external systems
🛠️How to make changes
Add a New Built-in Skill
- Define the skill struct in
crates/openfang-skills/src/lib.rsimplementing theSkilltrait (with execute, describe, validate methods) (crates/openfang-skills/src/lib.rs) - Register the skill in the skill registry by adding a variant to the skill enum and implementing factory logic (
crates/openfang-skills/src/lib.rs) - Add input/output types to
crates/openfang-types/src/lib.rsif introducing new message or parameter shapes (crates/openfang-types/src/lib.rs) - Test the skill in
crates/openfang-skills/tests/and ensure it integrates with the runtime executor (crates/openfang-skills/tests) - Reference the skill in an agent's
agent.tomlunder theskillssection to expose it in agent capabilities (agents/hello-world/agent.toml)
Create a New Agent from Template
- Copy the hello-world agent directory to
agents/your-agent-name/and renameagent.toml(agents/hello-world/agent.toml) - Edit the
agent.tomlwith agent name, description, skills list, system prompt, and memory config (agents/hello-world/agent.toml) - If using Python, create
agent.py,server.py, andrequirements.txtfollowing the langchain-code-reviewer pattern (agents/langchain-code-reviewer/agent.py) - Deploy via CLI:
openfang agent load agents/your-agent-name/or via API POST to/api/agents(crates/openfang-cli/src/main.rs)
Add a New REST API Endpoint
- Define the request/response types in
crates/openfang-api/src/types.rsusing serde derive macros (crates/openfang-api/src/types.rs) - Implement the handler function in
crates/openfang-api/src/routes.rs(e.g., async fn handler(State(state), Json(req)) -> Json<Resp>) (crates/openfang-api/src/routes.rs) - Register the route in the router builder in
crates/openfang-api/src/server.rs(e.g., .route('/api/myendpoint', post(handler))) (crates/openfang-api/src/server.rs) - If returning streaming data, wrap response with
StreamChunkerfromcrates/openfang-api/src/stream_chunker.rs(crates/openfang-api/src/stream_chunker.rs)
Integrate an External LLM Provider
- Add the provider client dependency to
crates/openfang-runtime/Cargo.toml(e.g., reqwest, anthropic-rs) (crates/openfang-runtime/Cargo.toml) - Create a new LLM adapter struct in
crates/openfang-runtime/src/implementing async inference with streaming support (crates/openfang-runtime/src/lib.rs) - Register the adapter in the kernel's LLM router, using environment variables for API keys (e.g.,
OPENFANG_LLM_PROVIDER) (crates/openfang-kernel/src/lib.rs) - Test via the OpenAI-compatible endpoint at
POST /v1/chat/completionsto ensure drop-in compatibility (crates/openfang-api/src/openai_compat.rs)
🔧Why these technologies
- Rust (tokio async runtime) — High-performance, memory-safe async execution for concurrent agent tasks; zero-cost abstractions enable efficient multi-agent orchestration without GC pauses
- Axum web framework —
🪤Traps & gotchas
Rust MSRV 1.75: Ensure your toolchain is at least 1.75 (check rustc --version). SQLite bundled: rusqlite uses bundled SQLite, so no system dependency needed but linking may be slow on first build. Full tokio features: Workspace enables tokio full, which includes all runtime features—this is intentional but increases binary size. wasmtime v43 sandbox: Untrusted agent code runs in WASM sandbox via wasmtime; ensure you understand WASM security model if agents execute external code. No .env auto-loading: .env.example exists but environment variable handling is explicit—check openfang-cli for exact env var expectations (likely API keys, LLM provider keys). agent.toml format is versioned: MIGRATION.md suggests breaking changes in config format between minor versions; always pin version. Dashboard on localhost:4200 only: No built-in auth layer visible in file list; assume not exposed to untrusted networks without reverse proxy. Cross.toml present: Cross-compilation configured; verify target triple if building for non-native architectures.
🏗️Architecture
💡Concepts to learn
- Autonomous Scheduling & Hand-Based Execution — Unlike request-response chatbot models, OpenFang's 'Hands' are self-waking tasks on cron-like schedules; understanding this event-driven autonomy is core to building agents that work without prompts.
- Knowledge Graph (Long-Term Memory in SQLite) — Agents persist learnings and context in a graph stored in SQLite (crates/openfang-memory); this is how agents build reasoning over time, unlike stateless LLM calls.
- WASM Sandbox (wasmtime) for Untrusted Code Execution — Agents can execute skills compiled to WebAssembly in isolation; critical for multi-tenant or adversarial agent scenarios where code isolation prevents breakouts.
- Monorepo Workspace Architecture (Cargo Workspaces) — The 14-crate structure (kernel, runtime, memory, hands, skills, api, cli, etc.) demonstrates how to decompose a complex system into independently testable, reusable units; useful pattern for any large Rust project.
🔗Related repos
openai/swarm— Python multi-agent framework with agent routing and hand-offs; similar goal of autonomous coordination but lighter-weight than OpenFang, not a full OS.microsoft/autogen— Multi-agent conversation framework with code execution sandboxing; OpenFang's Rust+WASM approach is more self-contained and production-oriented.langchain-ai/langchain— Agent abstraction layer and tool composition; OpenFang competes at a higher level (full scheduler + memory + isolation) rather than just agent primitives.huggingface/agents— Tool-use and agent reasoning library; complementary to OpenFang's execution runtime (OpenFang could integrate HF agent reasoning models).crewai/crewai— Python multi-agent framework with role-based agents and async tasks; OpenFang's Rust foundation and standalone binary are key differentiators.
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add integration tests for multi-agent orchestration in openfang-kernel
The repo contains 14+ pre-built agents (coder, debugger, analyst, etc.) in the agents/ directory, but there's no evidence of integration tests validating inter-agent communication through the orchestrator agent. With 1,767+ existing tests, adding orchestration test coverage would catch regressions in agent-to-agent message passing, state synchronization via openfang-memory, and concurrent agent lifecycle management—critical for an 'Agent Operating System'.
- [ ] Create tests/integration/multi_agent_orchestration.rs testing openfang-kernel with 3+ agents from agents/ spawned concurrently
- [ ] Validate message routing between agents via openfang-wire and openfang-channels
- [ ] Test state consistency via openfang-memory across multiple agent contexts
- [ ] Add test case for orchestrator agent delegating tasks to coder + analyst agents
- [ ] Reference existing Cargo.toml test setup and workspace members
Add GitHub Actions workflow for cross-platform WASM compilation verification
The Cargo.toml includes wasmtime v43 and Cross.toml exists, indicating WASM sandbox support is core to openfang's agent isolation. However, the .github/workflows/ only shows ci.yml and release.yml without explicit WASM compilation tests. New contributors should add a dedicated workflow validating that agents can be compiled to WASM and executed in wasmtime across Linux/macOS/Windows.
- [ ] Create .github/workflows/wasm-build.yml with cross-platform matrix (ubuntu, macos, windows)
- [ ] Test compilation of openfang-kernel and openfang-extensions with wasm32-unknown-unknown target
- [ ] Add step validating a sample agent (e.g., agents/hello-world) compiles to WASM
- [ ] Cache Rust target directory to optimize CI runtime
- [ ] Reference Cross.toml for any target-specific configuration needs
Document skill/capability system for Python agents in agents/langchain-code-reviewer
The langchain-code-reviewer agent is the only Python-based agent in the repo (with agent.py, requirements.txt, config.example.toml, workflow.json), yet it lacks documented examples of how to extend its skills or integrate it with Rust-based agents. Adding a comprehensive how-to guide would lower the barrier for contributors wanting to build polyglot agents and demonstrate openfang's language flexibility.
- [ ] Create agents/langchain-code-reviewer/SKILLS.md documenting the workflow.json structure and available LLM tools
- [ ] Add step-by-step guide for adding a new skill to langchain-code-reviewer (e.g., 'suggest tests' capability)
- [ ] Document how to invoke the Python agent from Rust agents via openfang-wire/IPC
- [ ] Include example of bridging config.example.toml parameters to agent.py runtime
- [ ] Reference AGENTS.md and CONTRIBUTING.md for consistency with existing documentation patterns
🌿Good first issues
- Add structured logging output to crates/openfang-cli/src/ to show which Hands are executing and their results—trace subscriber is configured but agent execution logs are likely sparse. Write integration tests in tests/ validating log output for agent lifecycle events.: Easy-Medium
- Implement a simple example agent in agents/ (e.g., weather-tracker) that schedules a Hand to fetch weather data hourly and stores results in the knowledge graph via crates/openfang-memory. Add documentation to AGENTS.md explaining the agent.toml schema and hand definitions.: Medium
- Add WebSocket event broadcasting to crates/openfang-api/src/ so the dashboard (crates/openfang-desktop) receives real-time agent execution updates (Hand started, skill completed, error occurred). Current API likely polls; push-based updates improve UX.: Medium-Hard
- Create comprehensive doctests in crates/openfang-hands/src/ and crates/openfang-skills/src/ demonstrating how to compose skills into hands and hands into agents. Current tests likely exist but hand/skill composition patterns aren't documented inline.: Easy
- Extend crates/openfang-migrate/ with a schema migration for v0.6.x → v0.7.x (hypothetical) to formalize the migration story. Add integration tests running old agents through migrations. Makes upgrade path clearer for production users.: Hard
⭐Top contributors
Click to expand
Top contributors
- @jaberjaber23 — 67 commits
- @dependabot[bot] — 8 commits
- @benhoverter — 5 commits
- @Hypn0sis — 3 commits
- @Streamweaver — 3 commits
📝Recent commits
Click to expand
Recent commits
3cce1eb— bump v0.6.4 (jaberjaber23)c89958b— firefox sidebar (jaberjaber23)b0a9245— openrouter free (jaberjaber23)67bbcc6— cachyos build (jaberjaber23)a91bfc0— dashboard bind (jaberjaber23)948117d— bump v0.6.3 (jaberjaber23)2dedab2— think persist (jaberjaber23)8642c4d— timeout reload (jaberjaber23)46a6eb3— slack dedup (jaberjaber23)99b4ce2— telegram cache (jaberjaber23)
🔒Security observations
- High · Insecure Deserialization with MessagePack —
Cargo.toml: rmp-serde = 1. The codebase usesrmp-serde(MessagePack) for serialization without apparent validation. MessagePack deserialization can be vulnerable to arbitrary code execution if untrusted data is deserialized, especially when combined with Rust's dynamic trait objects. Fix: Validate and sanitize all incoming MessagePack data. Consider using a schema validation library. Implement strict type checking for deserialized objects. Review all locations wherermp-serdeis used with untrusted input. - High · WASM Sandbox Potential RCE Vector —
Cargo.toml: wasmtime = 43. The project includeswasmtime(WASM runtime) which executes untrusted code. If agents can load arbitrary WASM modules without validation, this could enable remote code execution within the agent sandbox. Fix: Implement strict WASM module validation and signing. Only allow whitelisted WASM modules. Implement resource limits (memory, CPU time) for WASM execution. Use WASM capability restrictions to limit system access. - High · SQL Injection Risk in SQLite Implementation —
Cargo.toml: rusqlite = { version = "0.31", features = ["bundled", "serde_json"] }. The codebase usesrusqlitewith JSON support. If agent code or user input is dynamically constructed into SQL queries without proper parameterization, SQL injection is possible. Fix: Enforce parameterized queries throughout the codebase. Audit all SQL query construction code. Use rusqlite's prepared statements exclusively. Never concatenate user input into SQL strings. Implement a query builder or ORM layer. - High · API Key Exposure in Environment Variables —
.env.example (entire file). The .env.example file contains multiple LLM provider API keys (Anthropic, OpenAI, Google, etc.) as plaintext examples. If .env files are not properly gitignored or if example values are used in production, this poses credential exposure risk. Fix: Ensure .env is in .gitignore (verify in .gitignore). Never commit actual API keys. Use a secrets management system (HashiCorp Vault, AWS Secrets Manager). Implement credential rotation. Add pre-commit hooks to prevent .env commits. Consider using environment-based configuration with no defaults. - High · Insecure TLS Configuration for WebSocket —
Cargo.toml: tokio-tungstenite = { version = "0.24", default-features = false, features = ["connect", "rustls-tls-native-roots"] }. The WebSocket client usestokio-tungstenitewithrustls-tls-native-roots. Native roots can be compromised. Additionally, there's no indication of certificate pinning or hostname verification enforcement. Fix: Consider usingrustls-tlswith explicit root store. Implement certificate pinning for critical connections. Enforce TLS 1.3 minimum. Validate hostnames strictly. Add certificate transparency checks if connecting to external services. - Medium · Incomplete Docker Security Hardening —
Dockerfile. The Dockerfile runs as root user by default, doesn't include USER directive, and exposes port 4200. The runtime image includes python3 and nodejs which increase attack surface if agent code can execute arbitrary commands. Fix: Add USER directive with non-root user. Remove unnecessary runtime dependencies (python3, nodejs) or use multi-stage build to exclude them. Implement read-only filesystem where possible. Use--cap-drop=ALLand add only necessary capabilities. Implement network policies. Consider using distroless images. - Medium · Overly Permissive Cargo Dependencies —
Cargo.toml (workspace.dependencies section). Dependencies use loose version constraints (e.g.,tokio = { version = "1", ... }) which allows for any 1.x version including potentially vulnerable ones. The workspace uses resolver = "2" which has different dependency resolution behavior. Fix: Pin exact or tighter minor versions for critical dependencies (tokio, reqwest, rusqlite, wasmtime). Usecargo auditin CI/CD (already in .cargo/audit.toml - verify it
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.