Source index

README.md

# Access Atlas

Access Atlas turns a keyboard or focus symptom into a repair plan assembled from a small, source-linked Sanity dataset. A local Qwen2.5 model chooses records through tools; the application renders the retrieved guide's published steps, constraints, proposed checks, and W3C source attribution.

The source contains the local agent, structured public corpus, hosted replay explorer, and actual nine-case evaluation receipts.

## What the two modes do

The hosted explorer is designed to replay saved, actual local model + Sanity Context MCP runs. It shows their timestamps, tool arguments/results, selected guide IDs, sources, and model call counts. Its evidence desk reads counts and source records from the public Sanity dataset. Replaying a saved run does not execute a new model question.

The local server accepts fresh questions at `http://127.0.0.1:4340`. It calls Ollama on the local machine and a real, authenticated Sanity Context MCP endpoint. The server binds to loopback and runs one question at a time. The model has read tools; this application does not repair or test the user's interface.

Public explorer: https://access-atlas-jaye-2026.netlify.app/

Sanity Studio: https://access-atlas-jaye-2026.sanity.studio/ — editing requires an authorized Sanity account. Public data inspection does not require a Studio login.

Source: [browse the repository](https://access-atlas-jaye-2026.netlify.app/code/index.html), [download the source ZIP](https://access-atlas-jaye-2026.netlify.app/access-atlas-source.zip), or clone `https://access-atlas-jaye-2026.netlify.app/access-atlas.git`.

## Content and architecture

The public project is `2mflxxa8`, dataset `accessatlas`. The 21-document corpus comprises seven `guide`, seven `source`, and seven `check` records. Guides reference their official source and proposed check; checks link back to their guide and source. Sources retain URL, checked time, informative status, copyright, license, and derivation metadata. All checks are `manual-review` / `notRun`.

Topics: button activation, modal dialog focus, basic tabs, actual ARIA menu triggers, keyboard task alternatives, visible focus, and Focus Not Obscured (Minimum). The corpus does not cover every WCAG criterion, whole-site conformance, legal certification, contrast calculations, or assistive-technology-specific troubleshooting.

At session start `src/context.mjs` performs the MCP initialization handshake, lists the available tools, and `src/agent.mjs` calls `initial_context` for the real schema overview. Qwen2.5:7b then selects two narrow application tools:

| Model tool | Actual Context MCP operation |
| --- | --- |
| `search_guides({symptom})` | `groq_query` with `score(text::semanticSimilarity(...))`, returning up to three guide candidates |
| `read_guide({id})` | `groq_query` selecting that guide and dereferencing `references[0]` and `checks[0]` |

The adapter builds GROQ from escaped string arguments and a validated guide ID format. The model chooses the symptom query and guide; it does not author raw GROQ. The read operation returns repair steps, prerequisites, constraints, source URL/check time, and proposed check procedure/expected observations/limitations.

The product plan is rendered directly from those retrieved fields. The model's free-form draft remains in `rawAnswer` and the trace for inspection, with its own `draftStatus`; citation membership does not verify every sentence. A search hit alone triggers a retry for `read_guide`. The displayed plan's grounding gate requires successful retrieval, a joined guide, and a returned W3C URL; it rejects unreturned URLs, failed retrieval, missing citations, and incomplete runs. Explicit code-level corpus guards withhold text/color-contrast calculation and whole-site/legal certification after real retrieval. A model refusal may also produce an abstention. Final plan status and draft status are separate.

This uses Sanity Context's live dataset/GROQ mode with embeddings enabled, rather than a separately built website/file Knowledge Base. [Sanity's Context documentation](https://www.sanity.io/docs/ai/sanity-context) explains the two modes. The challenge expressly permits the full-dataset route with embeddings.

## Run fresh questions locally

Use Node.js 24, npm, Git, and a locally installed Ollama runtime. Model performance depends on the machine; no memory, timing, or download-size guarantee is made here.

Clone the public source:

```sh
git clone https://access-atlas-jaye-2026.netlify.app/access-atlas.git
cd access-atlas
npm install
```

Start Ollama on port 11439 in a separate terminal. In PowerShell:

```powershell
$env:OLLAMA_HOST = '127.0.0.1:11439'
$env:OLLAMA_NO_CLOUD = '1'
ollama serve
```

In another terminal, set the same host and pull the model:

```powershell
$env:OLLAMA_HOST = '127.0.0.1:11439'
$env:OLLAMA_NO_CLOUD = '1'
ollama pull qwen2.5:7b
Copy-Item .env.example .env
```

Set `SANITY_CONTEXT_URL` and `SANITY_CONTEXT_TOKEN` in `.env` to an endpoint and organization-level **Context Viewer** token you are authorized to use. The token stays server-side. Public dataset visibility does not grant membership in this project's organization or permission to create its token. The example endpoint requires authorized access; an external reviewer can reproduce the agent against a project they control using the setup below.

Keep `OLLAMA_URL=http://127.0.0.1:11439`, `OLLAMA_MODEL=qwen2.5:7b`, and `PORT=4340`. Then:

```sh
node --env-file=.env scripts/check-context.mjs
npm start
```

Open `http://127.0.0.1:4340` to ask a fresh question. For a CLI run:

```sh
npm run ask -- "Tab leaves my open modal dialog and focus lands behind it. How do I repair that?" --out data/my-local-run.json
```

### Use a Sanity project you control

1. Create a dataset named `accessatlas` in your own Sanity project. Change `projectId`/`dataset` in `sanity.config.ts` and `sanity.cli.ts`, and the routing values in `.env`, to that project. Remove the original `deployment.appId` from `sanity.cli.ts` before deploying your own Studio.
2. Authenticate the Sanity CLI with an account authorized to manage that project. Import `data/public-seed.ndjson` using `npx sanity dataset import data/public-seed.ndjson accessatlas`, deploy the schema with `npm run schema:deploy`, and deploy a hosted Studio using `npx sanity deploy` with your own available Studio hostname. Open the hosted Studio once. This release's observed Context source setup required a hosted Studio; a local Studio and schema deployment alone did not make the source available.
3. Enable Context for your organization and embeddings for the dataset. In the Context app, create a dataset/GROQ MCP endpoint scoped to this corpus. Create your own organization Context Viewer token and set its endpoint/token in `.env`. See the [official setup requirements](https://www.sanity.io/docs/ai/sanity-context).
4. Run the Context probe, then start the local agent. The public release's recorded traces remain historical evidence from the original `2mflxxa8/accessatlas` dataset.

`scripts/seed-data.mjs` is a maintainer helper restricted to the original, initially empty Access Atlas dataset. It is not the general bootstrap command for a personal clone. The fresh agent needs read-only Context access, not that helper's write credential.

## Checks and evaluation

```sh
npm run validate:data
npm run check
npm run evaluate
```

`validate:data` checks the 21-document graph, required public fields, source URL allowlist, provenance/license metadata, proposed-check status, and nine golden questions' citation mappings. `check` runs adapter/RPC/endpoint/citation/failed-retrieval/rendering regressions. Neither command tests an external user's interface.

`evaluate` uses actual fresh local inference and live Context calls for each question, writes run files under `public/runs`, and writes `data/evaluation.json`. Structural results check expected disposition, model/tool execution, expected guide IDs, required source URLs, and absence of URLs not returned by retrieval. Concepts and forbidden claims still require manual review; structural passes do not establish semantic entailment or accessibility conformance.

The recorded evaluation completed on 2 October 2026 at 19:45:25 UTC: **9/9 structural passes**, comprising seven canonical plans and two guarded abstentions. The nine saved runs used **26 local model calls and 25 real Context MCP calls**, including nine `initial_context` bootstraps. Both out-of-corpus model drafts had rejected citations; the product withheld them through its explicit contrast/certification guards. These are results for the nine stated questions, not an external benchmark or a guarantee for new questions. The seven Node regression checks also passed.

Early development exposed two problems: raw model-authored GROQ failed parsing, and a later free-form answer could include a technique absent from the retrieved record despite citing its source. The final architecture uses narrow query tools and publishes the structured retrieved plan. Historical development attempts are not the final evaluation receipts.

## Licenses

Original Access Atlas code is MIT licensed; see `LICENSE`. W3C-derived guidance retains its separate W3C Software and Document license, with source attribution and modification notices in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) and the user-visible [licenses page](public/licenses.html). Qwen2.5-7B-Instruct uses Apache 2.0; Ollama uses MIT. The public source archive does not include model weights or the Ollama binary.

No application review procedures in the content corpus were executed to create its records. Access Atlas offers bounded implementation guidance, not a legal opinion, certification, or completed audit.