Protocolbot 79774df456 fix: don't auto-fill source with @username when empty
Both frontend and backend were defaulting the source field to
@username when left empty. Now stores an empty string instead.

Frontend (app.js):
- saveProtocol: removed || '@' + currentUser.username fallback
- saveCollection: removed || '@' + currentUser.username fallback

Backend (api/index.php):
- Protocol create: ['source'] ?? '' instead of ?? ('@' . username)
- Collection create: ['source'] ?? '' instead of ?? ('@' . username)
2026-07-21 08:40:15 -06:00

Protocol Droid

A tool for authoring, sharing, and curating social protocols.

A project of the Media Economies Design Lab at the University of Colorado Boulder.

Overview

Protocol Droid is a web application where communities can document, share, and remix patterns of interaction — social protocols. It is self-hostable, whitelabel-able, and designed for organizations that want a trustful commons without external dependencies.

Features

  • Protocol library: browse protocols with structured fields (title, description, steps, outcome, practice, source)
  • Authoring: create protocols through a form-based editor
  • Forking: adapt an existing protocol to your context while linking back to the original
  • Collections: curate sets of protocols and share them
  • Identity: user accounts with optional SSO support
  • YAML import/export: protocols are fully structured YAML — portable, git-diffable, human-readable
  • Whitelabel: customize site name, tagline, and theme via config.yaml
  • Zero-dependency database: SQLite — no external database server required

Architecture

protocol-droid/
├── api/                  PHP backend (REST API)
│   ├── index.php         API router (all /api/* requests)
│   ├── db.php            Database connection + helpers (SQLite via PDO)
│   ├── auth.php          Session-based authentication
│   ├── config.php        Site configuration
│   └── yaml.php          YAML import/export helpers
├── frontend/             Single-page frontend
│   ├── index.html        HTML shell
│   ├── style.css         R2-Rebel blend stylesheet
│   └── app.js            Application logic (vanilla JS)
├── seeds/                Seed protocol YAML files
│   ├── round-robin-check-in.yaml
│   ├── consent-decision-making.yaml
│   ├── appreciative-apology.yaml
│   ├── temperature-reading.yaml
│   ├── dot-voting.yaml
│   └── fishbowl-discussion.yaml
├── cloudron/             Cloudron deployment files
│   └── CloudronManifest.json
├── data/                 SQLite database (auto-created)
├── schema.sql            SQLite database schema
├── config.yaml           Whitelabel configuration
├── .htaccess             Apache rewrite rules
└── README.md             This file

Stack

  • Backend: PHP 8.x with PDO (SQLite)
  • Database: SQLite — file-based, no server required
  • Frontend: Vanilla HTML/CSS/JS — no frameworks, no build step, no external dependencies
  • Data format: YAML for portability, SQLite for runtime
  • Auth: Session-based with optional SSO

Deployment

On Cloudron

  1. Create a LAMP app in Cloudron (no MySQL addon needed — uses SQLite)
  2. Clone the repo into the app's web root:
    cd /var/www/html  # or your Cloudron app's web root
    git clone https://git.medlab.host/ntnsndr/protocol-droid.git .
    
  3. Ensure the data/ directory is writable by the web server:
    mkdir -p data && chown www-data:www-data data && chmod 775 data
    
  4. The database schema auto-initializes on first API request (creates data/protocol_droid.db)
  5. Visit the site and register — the first user to register becomes admin
  6. Optionally load seed protocols: Go to the About page and click "Load seed protocols" (visible to admins only). This loads 6 example protocols into your library in one click. No curl needed.

No default admin credentials exist. A fresh deployment has an empty database. The first registration creates the admin account. Seed protocols are optional and must be explicitly loaded.

Updating

To update an existing deployment without losing data, simply pull the latest code:

cd /path/to/protocol-droid
git pull

The SQLite database (data/protocol_droid.db) is not tracked by git and will be preserved across updates. The schema uses CREATE TABLE IF NOT EXISTS so existing tables are never overwritten.

On any LAMP server

  1. Clone the repo to your web root (or a subdirectory like /protocol-droid/):
    cd /var/www/html/protocol-droid
    git clone https://git.medlab.host/ntnsndr/protocol-droid.git .
    
  2. Ensure the data/ directory is writable by the web server
  3. Visit the site and register — first user becomes admin

The SQLite database file is created automatically at data/protocol_droid.db. To use a custom path, set the DATABASE_PATH environment variable.

Subdirectory deployment: Protocol Droid works in a subdirectory (e.g. example.com/protocol-droid/). The root index.php auto-detects the base path from the server's script name. No configuration needed — just upload the files to the subdirectory and ensure index.php is served as the directory index (most LAMP setups do this by default with DirectoryIndex index.php or .htaccess).

With Docker

# Build and run a single container (no separate database container needed)
docker build -t protocol-droid .
docker run -d --name pd-web -p 8080:80 \
  -v pd_data:/var/www/html/data \
  protocol-droid

The SQLite database lives in the pd_data volume. The docker-compose.yml included in the repo runs the same setup.

Local development

# Start PHP built-in server
cd protocol-droid
php -S localhost:8000

The SQLite database is created automatically at data/protocol_droid.db. The first registration creates the admin account. To load the 6 sample protocols (Round Robin Check-In, Consent Decision-Making, etc.):

# After registering as admin:
curl -c cookies.txt -X POST http://localhost:8000/api/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"your-username","password":"your-password"}'

curl -b cookies.txt -X POST http://localhost:8000/api/seed

To remove all seed protocols (or any protocols), delete them individually:

curl -b cookies.txt -X DELETE http://localhost:8000/api/protocols/round-robin-check-in

API

Endpoint Method Description Auth
/api GET API info none
/api/config GET Site configuration none
/api/protocols GET List public protocols none
/api/protocols POST Create protocol member
/api/protocols/:slug GET Get protocol none
/api/protocols/:slug PUT Update protocol author/admin
/api/protocols/:slug DELETE Delete protocol author/admin
/api/protocols/:slug/yaml GET Export as YAML none
/api/protocols/:slug/votes GET Get votes for protocol none
/api/collections GET List collections none
/api/collections POST Create collection member
/api/collections/:slug GET Get collection none
/api/collections/:slug PUT Update collection author/admin
/api/collections/:slug DELETE Delete collection author/admin
/api/auth/register POST Register none
/api/auth/login POST Login none
/api/auth/logout POST Logout none
/api/auth/me GET Current user none
/api/users/:username GET Public profile none
/api/votes POST Vote on protocol member
/api/export GET Export all as YAML admin
/api/import POST Import YAML admin
/api/seed POST Load seed protocols admin

Whitelabeling

Protocol Droid is designed to be fully whitelabel-able. Here's how to customize it for your deployment:

The logo is an SVG file at frontend/logo.svg. It appears in the header next to the site name and as the browser/PWA icon.

To replace it:

  1. Create your own SVG logo (or PNG)
  2. Replace frontend/logo.svg (and frontend/favicon.ico, frontend/icon-192.png, frontend/icon-512.png for PWA icons)
  3. If using a different filename, update the <link> tags in frontend/index.html

For PWA icons, generate 192x192 and 512x512 PNG versions of your logo and save them as frontend/icon-192.png and frontend/icon-512.png. The web manifest is at manifest.json in the project root.

Site name and tagline

Edit config.yaml in the project root:

site_name: "Your Site Name"
site_tagline: "Your tagline here"
registration_enabled: true
require_approval: false

The site name appears in the browser title bar and the header breadcrumb. The tagline appears on the library page.

About page

The About page is plain HTML in frontend/index.html, inside the <!-- ABOUT VIEW --> section (look for <section id="view-about">). To customize it:

  1. Edit frontend/index.html
  2. Find the <!-- ABOUT VIEW --> comment
  3. Modify the text, links, and sections as needed
  4. Upload the file to your server (or git pull if editing in the repo)

No build step is needed — the HTML is served directly. The "Seed protocols" section at the bottom (id="seedSection") is automatically shown only to admin users, so you can leave it or remove it.

Terms of Service

The Terms of Service page is also plain HTML in frontend/index.html, inside the <!-- TERMS OF SERVICE VIEW --> section. Edit it to match your policies.

The footer is at the bottom of frontend/index.html, just before the closing <script> tag. It contains the CC-BY license link and Terms of Service link. Edit it to change the license or add your own links.

Colors and theme

Edit frontend/style.css. The CSS uses variables at the top of the file for the color scheme:

:root {
  --ink: #0a1929;          /* header background */
  --ink-dim: #8896a8;      /* dim text */
  --accent: #4a9eff;       /* primary blue */
  --accent-bright: #6db5ff; /* bright blue */
  --green-bright: #00ff88; /* $ prompt, accents */
  --surface: #f8f9fa;      /* card backgrounds */
  --border: #e0e4e8;       /* borders */
}

Change these values to match your brand. The rest of the stylesheet inherits from them.

Navigation

The nav links (PROTOCOLS, COLLECTIONS, ABOUT) are in frontend/index.html in the <nav id="navBar"> section. You can rename, reorder, or remove links there.

Protocol YAML Format

id: round-robin-check-in
title: Round Robin Check-In
description: >-
  A structured way for each person in a group to share briefly.
source: Group Works Deck
source_url: https://groupworksdeck.org/deck
tags: [check-in, facilitation]
forked_from: null
image: null
steps:
  - headline: Frame the round
    description: >-
      The facilitator explains that each person will have up to one minute.
  - headline: Go around
    description: >-
      Each person speaks in turn. Passing is always an option.
outcome: >-
  Everyone has been heard; the group has a shared sense of where things stand.
practice: >-
  Use a talking object. Keep time gently. For large groups, break into smaller rounds.

License

Hippocratic License (HL3-CORE) — do no harm. See https://firstdonoharm.dev/

Roadmap

  • SSO / OIDC — The database schema and user table include sso_provider and sso_id fields, and the auth API has a placeholder SSO endpoint. Full OIDC provider support (university SSO, Google Workspace, etc.) is planned but not yet implemented.
  • Bicorder integration — Connecting Protocol Droid with the Protocol Bicorder diagnostic tool, so protocols can be evaluated along gradient dimensions.
  • Voting / evaluation — The votes table exists in the schema but the UI for voting on protocols is not yet built.
  • Image support — The protocol and collection schemas include an image field, but image upload and display are not yet implemented.
S
Description
No description provided
Readme
747 KiB
Languages
PHP 39.1%
JavaScript 32.5%
CSS 17%
HTML 10.8%
Dockerfile 0.6%