This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/docs/DEMO-WORKFLOWS.md
Jeffrey Smith 680ec3b897
All checks were successful
CI/CD / detect-changes (push) Successful in 3s
CI/CD / test-frontend (push) Successful in 5s
CI/CD / test-go-pg (push) Successful in 2m34s
CI/CD / test-sqlite (push) Successful in 2m46s
CI/CD / build-and-deploy (push) Successful in 1m55s
Feat rebrand armature (#43)
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com>
Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
2026-03-31 23:25:37 +00:00

331 lines
9.6 KiB
Markdown

# Demo Workflows — v0.3.6
Four example workflow packages that prove the engine works end-to-end.
Each is a self-contained `.pkg` archive installable via Admin > Packages.
## Feature Capability Matrix
| Feature | Bug Report | Onboarding | Content Approval | Webhook |
|---------|:----------:|:----------:|:----------------:|:-------:|
| Public entry (anonymous) | ✅ | | | |
| Progressive fieldsets | ✅ | ✅ | | |
| Branch rules (conditional routing) | ✅ | | | |
| Team assignment + claim | ✅ | | | |
| SLA timer | ✅ | | | |
| Starlark automated stage | | ✅ | | ✅ |
| db.insert (ext_data tables) | | ✅ | | ✅ |
| notifications.send | | ✅ | | |
| http.post (outbound webhook) | | | | ✅ |
| connections.get (credentials) | | | | ✅ |
| Signoff gate (required_role) | | ✅ | | |
| Multi-party signoff (quorum) | | | ✅ | |
| Rejection reroute | | ✅ | ✅ | |
| Review cycle (loop) | | | ✅ | |
---
## Package 1: Bug Report Triage
**Slug:** `bug-report-triage`
**Entry mode:** `public_link` — anyone with the link can submit
**Tier:** browser (no Starlark needed)
### Stage Flow
```
[submit] → [classify] → [fix-critical] → [verify]
public team ↘ [fix-normal] ↗ team
team
```
### Stages
| # | Name | Mode | Audience | Key Feature |
|---|------|------|----------|-------------|
| 0 | submit | form | public | 2 fieldsets: "Report Details" (email, summary, component, severity) + "Reproduction" (steps, expected, actual) |
| 1 | classify | form | team | Team reviews. Branch rules: severity=critical → fix-critical, else → fix-normal |
| 2 | fix-critical | form | team | Senior team queue. SLA: 3600s |
| 3 | fix-normal | form | team | Standard fix queue |
| 4 | verify | review | team | Verify fix, close out |
### Branch Rules (stage 1)
```json
[
{"field": "severity", "op": "eq", "value": "critical", "target_stage": "fix-critical"},
{"field": "severity", "op": "neq", "value": "critical", "target_stage": "fix-normal"}
]
```
### API Walkthrough
```bash
# 1. Start public instance (no auth required)
curl -X POST $BASE/api/v1/public/workflows/$WF_ID/start \
-H 'Content-Type: application/json' \
-d '{"data": {"reporter_email": "user@example.com", "summary": "Login broken", "component": "ui", "severity": "critical", "steps": "1. Click login", "expected": "Login page", "actual": "500 error"}}'
# Response includes entry_token for anonymous continuation
# {"id": "inst-xxx", "entry_token": "tok-yyy", ...}
# 2. Resume (check status)
curl $BASE/api/v1/public/workflows/resume/tok-yyy
# 3. Team member claims the classify assignment
curl -X POST $BASE/api/v1/teams/$TEAM/assignments/$ASSIGN_ID/claim \
-H "Authorization: Bearer $TOKEN"
# 4. Advance classify stage (triggers branch rule)
curl -X POST $BASE/api/v1/teams/$TEAM/instances/$INST/advance \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"data": {"severity": "critical", "notes": "Confirmed production issue"}}'
# → Routes to fix-critical (not fix-normal)
```
---
## Package 2: Employee Onboarding
**Slug:** `employee-onboarding`
**Entry mode:** `team_only`
**Tier:** starlark
**Permissions:** `db.write`, `notifications.send`
### Stage Flow
```
[new-hire-info] → [provision-accounts] → [manager-signoff] → [it-setup] → [welcome]
team automated (Starlark) review + signoff team automated
auto-advances reject → stage 0 auto-advances
```
### Stages
| # | Name | Mode | Audience | Key Feature |
|---|------|------|----------|-------------|
| 0 | new-hire-info | form | team | 2 fieldsets: "Personal Info" + "Access Requirements" |
| 1 | provision-accounts | automated | system | Starlark: db.insert provisioning records, notify HR |
| 2 | manager-signoff | review | team | 1 approval required, required_role: "manager", reject → new-hire-info |
| 3 | it-setup | form | team | IT confirms hardware + access |
| 4 | welcome | automated | system | Starlark: log completion, send welcome notification |
### Starlark Hooks
**`on_provision(ctx)`** — Automated provisioning:
```python
def on_provision(ctx):
data = ctx["stage_data"]
name = data.get("full_name", "unknown")
dept = data.get("department", "general")
# Record provision in ext_data table
db.insert("provisions", {
"employee_name": name,
"department": dept,
"needs_vpn": str(data.get("needs_vpn", False)),
"needs_admin": str(data.get("needs_admin", False)),
"equipment": data.get("equipment", "standard laptop"),
"status": "provisioned"
})
# Notify the HR user who started this workflow
notifications.send(
ctx["started_by"],
"Accounts provisioned for " + name,
"Department: " + dept + ". Ready for manager review."
)
return {"advance": True, "data": {
"provision_status": "complete",
"accounts": ["email", "vpn" if data.get("needs_vpn") else None, "admin" if data.get("needs_admin") else None]
}}
```
**`on_welcome(ctx)`** — Completion logging:
```python
def on_welcome(ctx):
data = ctx["stage_data"]
db.insert("onboarding_log", {
"employee_name": data.get("full_name", ""),
"department": data.get("department", ""),
"completed_by": ctx["started_by"],
"status": "complete"
})
notifications.send(
ctx["started_by"],
"Onboarding complete: " + data.get("full_name", ""),
"All stages finished. Welcome aboard!"
)
return {"advance": True, "data": {"onboarding_complete": True}}
```
### Signoff Gate (stage 2)
```json
{
"validation": {
"required_approvals": 1,
"required_role": "manager",
"reject_action": "new-hire-info"
}
}
```
### Prerequisites
- Team must have a custom "manager" role (via Team Admin > Members > Team Roles)
- At least one team member with the "manager" role assigned
---
## Package 3: Content Approval
**Slug:** `content-approval`
**Entry mode:** `team_only`
**Tier:** browser
### Stage Flow
```
[draft] → [review] → [publish]
team team ↕ team
[revision]
team
```
### Stages
| # | Name | Mode | Audience | Key Feature |
|---|------|------|----------|-------------|
| 0 | draft | form | team | Author submits title, body, category |
| 1 | review | review | team | 2 approvals required. Reject → revision |
| 2 | revision | form | team | Author revises. Branch rule always routes back to review |
| 3 | publish | form | team | Final confirmation |
### Review Cycle
The rejection reroute creates a loop:
1. Author submits draft → enters review
2. Reviewer A approves, Reviewer B rejects → `reject_action: "revision"` routes to stage 2
3. Author revises → branch rule routes back to review (stage 1)
4. Both reviewers approve → advances to publish (stage 3)
### Signoff Gate (stage 1)
```json
{
"validation": {
"required_approvals": 2,
"reject_action": "revision"
}
}
```
---
## Package 4: Webhook Notifier
**Slug:** `webhook-notifier`
**Entry mode:** `team_only`
**Tier:** starlark
**Permissions:** `api.http`, `connections.read`, `db.write`
### Stage Flow
```
[configure] → [fire-webhook] → [result]
team automated review
(http.post)
```
### Stages
| # | Name | Mode | Audience | Key Feature |
|---|------|------|----------|-------------|
| 0 | configure | form | team | URL + event name + payload |
| 1 | fire-webhook | automated | system | Starlark: http.post to webhook URL |
| 2 | result | review | team | Shows delivery status |
### Starlark Hook
**`on_fire(ctx)`** — Outbound HTTP:
```python
def on_fire(ctx):
data = ctx["stage_data"]
url = data.get("webhook_url", "")
# Fallback to configured connection
if not url:
conn = connections.get("webhook")
if conn:
url = conn.get("url", "")
if not url:
return {"error": "No webhook URL configured"}
payload = json.encode({
"event": data.get("event_name", "workflow.notify"),
"instance_id": ctx["instance_id"],
"workflow_id": ctx["workflow_id"],
"data": data
})
resp = http.post(url, body=payload, headers={
"Content-Type": "application/json",
"X-Armature-Event": data.get("event_name", "workflow.notify")
})
# Log the delivery
db.insert("webhook_log", {
"url": url,
"status_code": str(resp["status"]),
"event": data.get("event_name", ""),
"instance_id": ctx["instance_id"]
})
return {"advance": True, "data": {
"delivery_status": "delivered" if int(resp["status"]) < 400 else "failed",
"status_code": resp["status"],
"response_body": resp["body"][:500]
}}
```
---
## Demo Surface
A browser-tier surface (`workflow-demo`) auto-installed on first run. Provides:
- Workflow cards with feature badges and stage flow diagrams
- "Try It" buttons for interactive exploration
- Starlark code viewer showing hook source
- API curl examples for each operation
Can be uninstalled by admin like any other package.
---
## Quick Start
```bash
# Build all example packages
cd packages && ./build.sh bug-report-triage employee-onboarding content-approval webhook-notifier workflow-demo
# Install via admin API
for pkg in dist/bug-report-triage.pkg dist/employee-onboarding.pkg dist/content-approval.pkg dist/webhook-notifier.pkg dist/workflow-demo.pkg; do
curl -X POST $BASE/api/v1/admin/packages/install \
-H "Authorization: Bearer $TOKEN" \
-F "file=@$pkg"
done
```
Or with bundled packages (v0.3.8+): just `docker compose up` — all examples are auto-installed.