|
| 1 | +# UX Methods |
| 2 | + |
| 3 | +## Identity & scope |
| 4 | + |
| 5 | +This repository is **UX Methods** — Andy Fitzgerald's personal knowledge-graph project, published at [uxmethods.org](https://www.uxmethods.org/). It is **separate from his Elemeno Health work**. Do not assume Elemeno conventions, schemas, tooling choices, or codebase patterns carry over here; treat this project on its own terms. |
| 6 | + |
| 7 | +## What UX Methods is |
| 8 | + |
| 9 | +UX Methods provides a roadmap between and across the practices of user experience design. Its goal is to help UX practitioners arrive at purposeful, high-impact, user-centered design outcomes. |
| 10 | + |
| 11 | +The web has no shortage of techniques, tools, and tips on how to "do" UX. Very few resources, however, explain how to use UX methods _together_, in a coordinated and purposeful way, to create holistic solutions. UX Methods fills that gap by: |
| 12 | + |
| 13 | +- Assembling concise, reliable descriptions of UX method goals, steps, and outcomes |
| 14 | +- Highlighting the meaningful relationships between methods so practitioners can craft holistic, purpose-driven project plans |
| 15 | +- Collecting and contextualizing in-depth how-tos, case studies, and research from trustworthy sources on the web |
| 16 | + |
| 17 | +## Project goal — knowledge graph maturation |
| 18 | + |
| 19 | +UX Methods today uses a light taxonomy to coordinate methods. The active goal is to build on that foundation so the content collection, external resources, and semantic models become a **proper knowledge graph** that delivers significant value above and beyond the sum of its parts. |
| 20 | + |
| 21 | +Specifically: |
| 22 | + |
| 23 | +- Use knowledge-graph approaches to enrich content, sharpen the expression of ideas, and improve the user experience |
| 24 | +- Build and demonstrate a skillset focused on generating new value and insight through the combination of structured, composable content and formal, domain-specific semantics |
| 25 | +- **Preferred (not required):** make use of OWL, SPARQL, and semantic inference |
| 26 | +- **Optional, where helpful:** SHACL, R2RML, and OTTR templates |
| 27 | + |
| 28 | +When proposing changes to the graph layer, lean into these technologies rather than ad-hoc procedural workarounds; that's the demonstration this project exists to provide. |
| 29 | + |
| 30 | +## Repository layout |
| 31 | + |
| 32 | +Monorepo (pnpm workspaces — see `pnpm-workspace.yaml`): |
| 33 | + |
| 34 | +- **`studio/`** — Sanity Studio. Source of truth for content: methods, disciplines, external resources, and the inputs/outputs (IO) taxonomy. Schemas in `studio/schemaTypes/`. |
| 35 | +- **`astro/`** — The public uxmethods.org website, built with Astro from Sanity content. Supports Sanity Visual Editing for real-time previews. |
| 36 | +- **`graph/`** — Knowledge graph assets (see "KG architecture" below for layer details). |
| 37 | +- **`functions/`** — Sanity Functions. |
| 38 | +- **`sanity.blueprint.ts`** — Sanity blueprint config. |
| 39 | + |
| 40 | +**Triplestore:** Apache Jena **TDB2** behind a **Fuseki** front end, hosted on a Raspberry Pi at home and exposed publicly through nginx + a Cloudflare Tunnel at `fuseki.uxmethods.org`. The active production dataset is `/ds`; two experimental inference datasets (`/ds-owl`, `/ds-rdfs`) are configured but currently empty. Read endpoint (`/ds/query`) is open; write endpoints (`/ds/data`, `/ds/update`) are gated at nginx by an `X-API-Token` header. Astro queries Fuseki at build time; the export scripts in `graph/scripts/` push named graphs via the Graph Store Protocol. **See [graph/INFRASTRUCTURE.md](graph/INFRASTRUCTURE.md) for the full deployment, dataset, auth, and cleanup-backlog details.** |
| 41 | + |
| 42 | +**URI policy:** taxonomy concepts use hash URIs (`https://uxmethods.org/taxonomies/io#<conceptId>`); ontology terms and method instances use slash URIs. The concept-scheme IRI doubles as the named-graph IRI. See [ADR 0002](docs/decisions/0002-uri-policy-hash-vs-slash.md). |
| 43 | + |
| 44 | +**Query convention:** the `/ds` dataset has `unionDefaultGraph` disabled — queries that touch taxonomy triples must use explicit `GRAPH <…> { … }` clauses. See [ADR 0003](docs/decisions/0003-explicit-graph-clauses.md). |
| 45 | + |
| 46 | +## KG architecture — three layers |
| 47 | + |
| 48 | +The single most important architectural decision in this project: the graph is deliberately separated into three layers that evolve at different speeds. Preserve this separation when proposing changes. |
| 49 | + |
| 50 | +### 1. Ontology (TBox) — curated, stable |
| 51 | + |
| 52 | +- File: `graph/ontologies/uxmethods-core.ttl` |
| 53 | +- Contains: classes, object properties, utility alignments (notably **PROV**). |
| 54 | +- Edited by hand. Versioned. This is the **stable semantic contract** that downstream tools depend on. |
| 55 | + |
| 56 | +### 2. Taxonomy (SKOS) — generated from Sanity, replaceable |
| 57 | + |
| 58 | +- Generated file: `graph/build/io-taxonomy.ttl` |
| 59 | +- Inputs/outputs modeled as `skos:Concept` instances. |
| 60 | +- Concept scheme IRI: `https://uxmethods.org/taxonomies/io` |
| 61 | +- Concept IRIs: `https://uxmethods.org/taxonomies/io#<conceptId>` |
| 62 | +- Generator: `graph/scripts/push-io-taxonomy.js` — fetches scheme + concepts via GROQ, writes Turtle, optionally PUTs to Fuseki via Graph Store Protocol into the named graph above (using `X-API-Token` header). |
| 63 | + |
| 64 | +### 3. Methods data (ABox) — generated from Sanity, replaceable |
| 65 | + |
| 66 | +- Generated file: `graph/build/methods-data.ttl` |
| 67 | +- Method IRIs: `https://uxmethods.org/method/<Slug>` (e.g. `…/method/Wireframing`). |
| 68 | +- Methods are linked to SKOS concepts via `uxm:usesInput` / `uxm:producesOutput`. |
| 69 | +- Generator: `graph/scripts/method-export.js`. |
| 70 | + |
| 71 | +**Generated artifacts are disposable.** Regenerate from Sanity whenever content changes. Only TBox files in `ontologies/` are hand-curated. Both generators emit `owl:Ontology` headers so Protégé imports them by logical IRI without "physical URI" warnings — preserve this when modifying the exporters. |
| 72 | + |
| 73 | +## Local prototyping (Protégé workspace) |
| 74 | + |
| 75 | +Open one file in Protégé and the whole integrated KG comes with it: |
| 76 | + |
| 77 | +- `graph/ontologies/workspace.ttl` — wrapper ontology that imports the core ontology, the IO taxonomy export, and the methods export. |
| 78 | +- `graph/ontologies/catalog-v001.xml` — maps the logical IRIs of those imports to local files in the repo. |
| 79 | + |
| 80 | +When iterating locally, point Protégé at `workspace.ttl` and register the catalog. Don't edit generated files in `build/` — change the source in Sanity and re-run the exporter. |
| 81 | + |
| 82 | +**Snap SPARQL vs built-in SPARQL — important trap:** |
| 83 | +- Protégé's **Snap SPARQL plugin queries over inferred facts** (it runs against the reasoner's materialized model). |
| 84 | +- Protégé's **built-in SPARQL tab queries asserted triples only** — inferred edges (from property chains, etc.) will not appear. |
| 85 | + |
| 86 | +If a query "works in Snap SPARQL but returns nothing in the built-in tab," that's the reason. This is a preview of the same question we'll face in Fuseki: inference-at-query-time vs derived-graph materialization (see below). |
| 87 | + |
| 88 | +## Method-to-method relationships |
| 89 | + |
| 90 | +Methods are connected through the **inputs/outputs (IO) taxonomy**. A concept that is an _output_ of one method is an _input_ to another (e.g. "user's mental model" is an output of contextual research and an input to navigation design). This IO model is the seed the larger knowledge graph builds on — keep it intact when proposing schema or ontology changes. |
| 91 | + |
| 92 | +### SPARQL-based relationship logic |
| 93 | + |
| 94 | +Today the site computes relationships via SPARQL joins: |
| 95 | + |
| 96 | +- **Upstream methods:** "who produces what I need" (their outputs match my inputs). |
| 97 | +- **Downstream methods:** "who needs what I produce." |
| 98 | +- **Weights:** `COUNT(DISTINCT ?shared)` over shared IO concepts. |
| 99 | +- **Multi-origin variant:** a UNION/`VALUES` query that runs for one or many origin methods at once. |
| 100 | + |
| 101 | +Reference query: `graph/queries/method-output-enables-method-input.rq`. |
| 102 | + |
| 103 | +### Inference work in progress |
| 104 | + |
| 105 | +Some of this join logic is being moved into ontology semantics: |
| 106 | + |
| 107 | +- Object properties `uxm:hasUpstreamMethod` and `uxm:hasDownstreamMethod` are defined in the core ontology. |
| 108 | +- **OWL property chain axioms** let a reasoner infer these edges from `usesInput` / `producesOutput` + shared concepts. |
| 109 | + |
| 110 | +Note that plain RDFS inference will **not** apply OWL property chains — you need an OWL-capable entailment regime (OWL RL or rules). |
| 111 | + |
| 112 | +## Open architectural decision — how inference runs in production |
| 113 | + |
| 114 | +There are two viable production paths. Both are real; the project hasn't committed yet. |
| 115 | + |
| 116 | +### A. Query-time inference in Fuseki |
| 117 | +Configure Fuseki with an OWL-capable reasoner so `hasUpstreamMethod` / `hasDownstreamMethod` appear as entailments at query time. Simpler conceptually; performance and entailment-regime selection are the questions. |
| 118 | + |
| 119 | +### B. Materialized derived graph (currently the pragmatic favorite) |
| 120 | +A scheduled step computes upstream/downstream edges, weights, and optional explanations (which shared concepts caused each link), and writes them into a derived named graph (e.g. `https://uxmethods.org/graph/derived`). UI queries hit asserted triples only — extremely fast, easy to explain, easy to debug. |
| 121 | + |
| 122 | +When making suggestions in this area, weigh both options honestly; don't quietly default to one. The "fast product value + strong foundation" framing tends to favor (B) once performance matters, but (A) is the more semantically pure demonstration. |
| 123 | + |
| 124 | +## Future direction — richer plan semantics |
| 125 | + |
| 126 | +Longer-term, methods may be modeled as structured **plans** (steps, prerequisites, outputs) using **P-Plan** / **PROV Plan**, with executions and case studies mapped onto those plans. Not active work yet; flag it if proposed changes would constrain that direction. |
| 127 | + |
| 128 | +## Working principles for this repo |
| 129 | + |
| 130 | +- **Lean into formal semantics.** This project exists to demonstrate KG approaches — prefer OWL/SPARQL/SHACL solutions over ad-hoc procedural workarounds when working on the graph layer. |
| 131 | +- **Stable IRIs and predicates.** Downstream tools (eventual plan builder / stack generator) depend on them. Don't rename casually. |
| 132 | +- **Generated vs curated.** Treat `graph/build/*` as disposable. Treat `graph/ontologies/*` as the contract. |
| 133 | + |
| 134 | +## Where to find things |
| 135 | + |
| 136 | +- **[graph/README.md](graph/README.md)** — local development: IRI conventions, named-graph strategy, Protégé workflow, exporter script usage, troubleshooting. |
| 137 | +- **[graph/INFRASTRUCTURE.md](graph/INFRASTRUCTURE.md)** — production deployment: topology diagram, Fuseki datasets, endpoints, auth, GSP, and the operational cleanup backlog. |
| 138 | +- **[docs/decisions/](docs/decisions/README.md)** — architecture decision records (ADRs). Significant choices like the three-layer separation, URI policy, the `unionDefaultGraph` stance, and the open production-inference question live here with their rationale. |
| 139 | +- **[astro/CLAUDE.md](astro/CLAUDE.md)** — how the site talks to Sanity and Fuseki, current SPARQL integration shape, and the conventions to follow when adding queries. |
| 140 | + |
| 141 | +When adding new context that isn't a fit for any of these, prefer extending one of them over creating yet another doc. New ADRs are fine and encouraged for significant decisions. |
0 commit comments