Skip to content

About

Evidence-based User Journeys for public administration — schema, lints, renderer, Claude skill

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

JourneyKit

Version License Python

Evidence-based User Journeys for public administration: a JSON model where every claim points to evidence, lints for the known journey-mapping pitfalls, an interactive single-file viewer, and a portable Claude skill that synthesises journeys from raw material.

🇩🇪 Deutsche Version

Overview

Most journey maps are posters: built in a meeting room, biased towards the happy path, never updated, never translated into work. JourneyKit treats a journey as a data set, not a picture. The primary artefact is a JSON file (journey.json) that holds persona, scenario, phases, steps, pain points, recovery paths, KPIs and opportunities — and every statement in it references evidence atoms (quotes, metrics, observations) with a source and an evidence class: observed, reported or assumed. HTML, story map, action list, audit report and version diff are generated from that model.

The vocabulary is translated for public administration, where nobody "converts" or "churns" — people fall back to the phone, the counter, a complaint, or doing nothing. Content is in German (Swiss spelling); schema field names are English.

Features

  • Journey model as JSON Schema (draft 2020-12) with evidence atoms, sources, PII status, owner and review cycle
  • Methodological lints for the five pitfalls — Inside-Out Bias, Happy Path Bias, Static Map Trap, Empathy Vacuum / Overcomplexity, Micro-Level Disconnect — plus Blueprint smell, PII, KPI translation and evidence quality (L001–L103)
  • Interactive viewer: a self-contained HTML file with six layers — overview (share of experience statements backed by primary evidence, per phase as well; statements without primary evidence; evidence per statement type and phase as a bubble matrix; every pain point with its strongest evidence, keyboard-navigable), journey map with emotional curve, evidence-backed phase durations on a common scale, the costs due at each step and links from a pain point to its cause, process and failure paths, evidence heatmap and source register, impact/effort matrix with user stories, audit, and with --compare a comparison with an earlier version (the overview's figures before → after, evidence per phase, both emotional curves overlaid, every model change with a jump into the journey) — evidence drill-down to the original quote on every cell, a "primary evidence only" filter, multi-persona overlay, light/dark, print, interface in German or French
  • Exports: Patton story map (Markdown), action list (CSV), opportunity matrix, audit report (diagnosis, proposed verdict, next steps, costs, findings), evidence heatmap as a self-contained SVG image for reports and slides or as CSV — also downloadable from the viewer's evidence layer
  • Diff between two versions of a journey — what did new evidence change?
  • Claude skill user-journey with three modes: Synthesis (raw material → journey), Workshop (hypothesis-first with research plan), Audit (review an existing journey)
  • Worked examples: kindergarten entry from the parents' perspective, built from a synthetic input mix (3 interviews, 30 inquiries, a survey, web analytics, an internal process document, workshop notes); a building permit for a heat pump (applicant and neighbour as two personas); and a music school enrolment (parents, waiting list, fee reduction, cancellation via the teacher). The last two test transferability to other domains and document where the model reaches its limits – costs, chains of causes, deadlines the persona must meet

Demo

Overview layer of the viewer: share of statements backed by primary evidence, bubble matrix of evidence per phase, pain points with their strongest evidence

Journey layer of the viewer: phases, actions, thoughts, evidence-backed emotional curve, pain points

Open examples/kindergarteneintritt/journey.html in a browser for the full interactive version.

Prerequisites

  • Python 3.10+
  • jsonschema (installed automatically)
  • No JavaScript toolchain: the viewer is plain HTML, CSS and JS in one file

Installation

git clone https://github.com/malkreide/journeykit.git
cd journeykit
pip install -e ".[dev]"

If journeykit is not found afterwards (typical for Windows user installations, where pip puts scripts into %APPDATA%\Python\Python3xx\Scripts), use python -m journeykit … instead — every command below works that way too.

Usage / Quickstart

# Validate against the schema
journeykit validate examples/kindergarteneintritt/journey.json

# Methodological lints (ERROR / WARN / INFO)
journeykit lint examples/kindergarteneintritt/journey.json

# Render the interactive viewer (several files = persona comparison;
# --compare adds an earlier version of the same journey, matched by meta.id)
journeykit render examples/kindergarteneintritt/journey.json \
                  examples/kindergarteneintritt/journey-berufstaetig.json \
                  --compare examples/kindergarteneintritt/workshop-hypothese.json -o journey.html

# Exports
journeykit export examples/kindergarteneintritt/journey.json --format storymap
journeykit export examples/kindergarteneintritt/journey.json --format actions -o massnahmen.csv
journeykit export examples/kindergarteneintritt/journey.json --format audit
journeykit export examples/kindergarteneintritt/journey.json --format heatmap-svg -o heatmap.svg

# What did user evidence change compared to the workshop hypothesis?
journeykit diff examples/kindergarteneintritt/workshop-hypothese.json \
                examples/kindergarteneintritt/journey.json

# Start a new journey (status: hypothesis)
journeykit new kita-anmeldung --title "Kita-Anmeldung" --persona "Eltern" --role "Elternteil" --goal "Platz sicher haben" -o kita.json

Available Commands

Command Description
journeykit validate FILE... [--lang de|fr] JSON Schema validation (exit 2 on errors)
journeykit lint FILE... [--strict] [--quiet] [--format json] [--today DATE] [--lang de|fr] Pitfall lints; --strict makes warnings fail. Messages in German or French (default: meta.language of the file)
journeykit render FILE... [--compare OLD]... [-o OUT] [--title T] [--lang de|fr] Self-contained interactive HTML; multiple files overlay personas, --compare adds an earlier version (matched by meta.id) and the tab «Vergleich» / «Comparaison». Interface and lint messages in German or French (default: meta.language of the first file); journey content stays as it is
journeykit export FILE --format storymap|actions|opportunities|audit|heatmap-svg|heatmap-csv [-o OUT] [--lang de|fr] Markdown / CSV / SVG exports; Markdown and SVG in German or French (default: meta.language), the CSV files have technical column names
journeykit diff OLD NEW [-o OUT] [--lang de|fr] Model changes between versions (exit 1 when there are changes); report in German or French (default: meta.language of the new version)
journeykit new ID --title --persona --role --goal [--lang de|fr] Scaffold a valid journey in status hypothesis; --lang sets meta.language and the language of the placeholders
journeykit schema Print the JSON Schema

Language of all output: --lang per command, otherwise meta.language of the journey, otherwise the environment variable JOURNEYKIT_LANG (de or fr), otherwise German. Texts generated by argparse itself («usage:», «options:») and JSON Schema error details stay English, as before.

Lint rules

Range Pitfall Examples
L001–L004 Integrity dangling evidence references, duplicate IDs, contradictory phase duration (min > typical or typical > max), contradictory cost range (min > amount or amount > max), unknown cause of a pain point or a cause that comes after its consequence
L010–L012 Inside-Out Bias experience claims without primary evidence, or none at all; persona on fewer than 3 primary sources
L020–L023 Happy Path Bias no breakdowns; phase without friction or edge case; breakdown without recovery path; change of channel or counterpart not marked as transition
L030–L035 Static Map Trap no owner, no review cycle, severe pain point without owner; no date
L040–L043 Empathy Vacuum steps without feelings or thoughts; emotions without evidence
L050–L054 Overcomplexity too many phases/steps; no scope exclusions; no end state; no trigger
L060–L065 Micro-Level Disconnect no opportunities; severe pain point without linked opportunity; no stories; opportunity linked to neither a pain point nor a phase; opportunity that addresses only consequences, not their cause
L070–L073 Blueprint smell no diagnosis; more back-stage notes than steps; most steps carried out by intermediaries instead of the persona
L080–L081 Privacy source contains PII; e-mail/phone patterns in evidence text
L090–L092 KPIs none; commercial naming; no leading indicator
L100–L103 Evidence quality unused atoms; contradictions; primary evidence without locator; costs backed only by assumptions such as a fee schedule

Using the Claude skill

The skill lives in skill/user-journey/. Point Claude at it (Claude Code: the folder is picked up through CLAUDE.md; claude.ai: upload the folder as a skill) and describe your material. The skill diagnoses first — is this a user journey or a service blueprint? — chooses a mode, registers sources with PII status, extracts evidence atoms with locators, synthesises the model and runs the lints. It refuses to invent emotions, insists on breakdowns and recovery paths, and says plainly when the material only supports a hypothesis map.

Configuration

None. The viewer has no external dependencies and makes no network requests; rendered HTML files can be shared inside closed networks.

Project Structure

journeykit/
├── src/journeykit/
│   ├── schema/journey.schema.json   # the journey model (single source of truth)
│   ├── model.py                     # index and claim iterator over a journey
│   ├── validate.py                  # JSON Schema validation
│   ├── lint.py                      # pitfall rules L001–L103
│   ├── lint_messages.py             # messages and hints, German and French
│   ├── render.py                    # injects data into the viewer
│   ├── export.py                    # story map, actions CSV, opportunities, audit, heatmap
│   ├── export_texts.py              # export and diff texts, German and French
│   ├── diff.py                      # version diff
│   ├── cli.py                       # journeykit command
│   ├── cli_texts.py                 # CLI messages and help, German and French
│   └── viewer/viewer.html           # self-contained interactive viewer
├── skill/user-journey/              # Claude skill: SKILL.md + references/ + evals/ (extraction test set)
├── examples/kindergarteneintritt/   # worked, synthetic example incl. raw inputs
├── examples/baubewilligung/        # second domain: transferability check and findings
├── examples/musikschule/           # third domain: costs, avoidable contacts, deadlines
├── docs/                            # concept, architecture decisions, demo image
├── scripts/                         # repo checks, scorer for the extraction test set
├── tests/                           # pytest
└── CLAUDE.md                        # entry point for working on this repo with Claude Code

Changelog

See CHANGELOG.md

Contributing

Contributions are welcome — see CONTRIBUTING.md.

Security

Please report vulnerabilities as described in SECURITY.md. Journey files may contain quotes from real people: keep them anonymised (pii_status) before sharing.

License

MIT License — see LICENSE

Author

Hayal Özkan · malkreide

About

Evidence-based User Journeys for public administration — schema, lints, renderer, Claude skill

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages