diff --git a/.github/workflows/deploy-public-preview.yml b/.github/workflows/deploy-public-preview.yml
new file mode 100644
index 0000000..d8193c4
--- /dev/null
+++ b/.github/workflows/deploy-public-preview.yml
@@ -0,0 +1,34 @@
+name: Deploy Atlas public preview
+
+on:
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+concurrency:
+ group: pages
+ cancel-in-progress: false
+
+jobs:
+ build-and-deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 22
+ - name: Rebuild and verify public preview
+ run: npm run compendium:build && npm run compendium:check && npm run test:compendium && npm run pages:build && npm run test:pages
+ - uses: actions/configure-pages@v5
+ - uses: actions/upload-pages-artifact@v3
+ with:
+ path: dist/pages
+ - id: deployment
+ uses: actions/deploy-pages@v4
diff --git a/.github/workflows/package-navigator-preview.yml b/.github/workflows/package-navigator-preview.yml
new file mode 100644
index 0000000..7fbfdd6
--- /dev/null
+++ b/.github/workflows/package-navigator-preview.yml
@@ -0,0 +1,39 @@
+name: Package Navigator public preview
+
+on:
+ workflow_dispatch:
+ pull_request:
+ paths:
+ - "navigator-preview/**"
+ - "config/navigator-preview-allowlist.json"
+ - "scripts/build-navigator-preview.mjs"
+ - "content/nodes/**"
+ - "tests/navigator-preview.spec.cjs"
+ - "package.json"
+
+permissions:
+ contents: read
+
+jobs:
+ package:
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 22
+ - name: Test public preview core
+ run: npm run test:navigator-preview
+ - name: Build checksum-listed VSIX
+ run: npm run navigator:build
+ - name: Test and package demo workspace
+ run: npm run test:navigator-demo && npm run navigator:demo:package
+ - uses: actions/upload-artifact@v4
+ with:
+ name: atlas-navigator-public-preview
+ path: |
+ dist/navigator-preview/*
+ dist/navigator-demo/*
+ if-no-files-found: error
+ retention-days: 30
diff --git a/.github/workflows/public-boundary.yml b/.github/workflows/public-boundary.yml
index 213e81e..f243c27 100644
--- a/.github/workflows/public-boundary.yml
+++ b/.github/workflows/public-boundary.yml
@@ -19,5 +19,6 @@ jobs:
node-version: 22
cache: npm
- run: npm ci
+ - run: npm run verify:public-preview
- run: npx playwright install --with-deps chromium
- - run: npm test
+ - run: npm run test:browser
diff --git a/.gitignore b/.gitignore
index 7295a0f..29a6826 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,5 @@ test-results/
Thumbs.db
*.zip
*.vsix
+
+dist/
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8951dd8..449b2ad 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,11 @@
## Unreleased
+- Rebuilt Control Lite as a complete Prepare → Instruct → Inspect → Evidence → Decide → Export workflow with autosave, editable sessions, scope comparison, evidence states, and decision-alignment guidance.
+- Added a dependency-free bounded-change exercise with Accept, Revise, and Reject paths, runnable behavior and safety verification, honest evidence records, and maintained Playwright lifecycle coverage.
+- Added a limited public Navigator VSIX, two synthetic Laravel demo workspaces, strict knowledge allowlisting, checksum-listed packages, and a manual packaging workflow without copying the private Navigator engine.
+- Added a clean-room six-node Compendium preview generated only from public Markdown and evidence sidecars, plus an integrated manual GitHub Pages deployment containing Control Lite and Compendium.
+- Added a reproducible release gate and release-review checklist that keep generated artifacts outside the canonical public-tree manifest.
- Restored public node integrity with valid frontmatter, canonical and public-content hashes, and one-to-one evidence validation.
- Added a canonical public-tree manifest so public-only drift fails validation.
- Added a pull-request control workflow and documented required branch protections.
diff --git a/README.md b/README.md
index b5a8414..e318664 100644
--- a/README.md
+++ b/README.md
@@ -5,190 +5,123 @@
[](docs/product/ROADMAP.md)
[](docs/public/privacy-and-safety.md)
-**Human-controlled AI development for Laravel and Vue: define scope, understand changes, review
-evidence, and make the final decision.**
+## Keep control of AI-generated code changes
+
+**Define what may change, inspect what actually changed, record real evidence, and make the final human decision.**

-### [Build a local Change Contract with Control Lite →](control-lite/README.md)
+### Start with one controlled change
-**[Try the guided 15-minute Control walkthrough](docs/getting-started/TRY_ATLAS.md)**
-**[See current Navigator preview access](https://github.com/DeveloperAtlas5/DeveloperAtlas-Public/blob/main/docs/testing/START_TESTING.md)**
-**[Browse all public documentation](docs/README.md)**
+1. **[Open Control Lite](control-lite/index.html)** and define a bounded change.
+2. Generate a scoped AI instruction and review record.
+3. Compare the supplied or real patch with the allowed scope.
+4. Record checks as **Passed**, **Failed**, or **Not run**.
+5. Decide to **Accept**, **Revise**, or **Reject**.
+6. Open the related public Compendium node when a concept or boundary needs explanation.
-> **Current status:** public preview and internal alpha. The software and control lifecycle are real
-> and extensively tested. Broad usability, retention, independent review, and paid demand remain
-> unproven.
+[Try the guided Control walkthrough →](docs/getting-started/TRY_ATLAS.md)
-## Keep AI-assisted work understandable and bounded
+> **Current status:** public preview and internal alpha. The technical lifecycle is real and tested,
+> while broad usability, repeat use, independent review, and willingness to pay remain unproven.
-AI can produce code faster than a person can understand, review, and remember it. Atlas is being
-built around one explicit loop:
+## The Atlas control loop
```mermaid
flowchart LR
- Goal["Human goal"] --> Instruction["Scoped AI instruction"]
- Instruction --> Change["Traceable change"]
- Change --> Understand["Understand impact"]
- Understand --> Verify["Review evidence"]
- Verify --> Decision["Accept, revise, or reject"]
- Decision --> Memory["Remember the decision"]
- Memory --> Goal
+ Goal["Human goal"] --> Scope["Bound the change"]
+ Scope --> Instruction["Scoped AI instruction"]
+ Instruction --> Change["Inspect the patch"]
+ Change --> Evidence["Record observed evidence"]
+ Evidence --> Decision["Accept, revise, or reject"]
+ Decision --> Memory["Preserve the decision"]
```
-### Keep the AI in scope
-
-Declare allowed files, protected behavior, acceptance criteria, and parked ideas before a patch
-begins. Risky expansion remains a human confirmation boundary.
-
-### Understand what changed
-
-Navigator connects routes, controllers, views, dependencies, and learning context so the reviewer can
-reason about the change instead of accepting a diff on trust.
-
-### Verify before accepting
-
-Atlas separates scope conformance from observed checks. A missing test result remains “not run”; the
-AI cannot promote its own claim into evidence or make the final decision.
-
-## One concrete example
-
-The public exercise starts with this request:
-
-> Improve the status page so a reviewer knows the application is ready for a human check.
-
-The baseline prompt contains no file boundary or proof requirement. The Atlas-controlled version
-allows two Laravel files, protects routes and authentication, defines visible acceptance criteria,
-and requires honest test reporting.
+Atlas does not ask an AI to certify its own work. Missing evidence remains **Not run**, scope expansion
+remains visible, and the accountable human keeps the final decision.
-The supplied patch stays in scope, but the completed decision is **revise** because this static
-repository cannot run the real Laravel test command. That is the product thesis in practice: preserve
-useful work without pretending missing evidence is a pass.
+## Three connected product surfaces
-[Open the complete worked example](control/examples/laravel-status-label/README.md).
-
-## Control, Navigator, and Compendium
-
-Near the top, Atlas has three jobs:
+| Surface | Job | Public experience |
+| --- | --- | --- |
+| **Control** | Define scope, evidence requirements, and the final decision | [Control Lite](control-lite/README.md) and the [15-minute walkthrough](docs/getting-started/TRY_ATLAS.md) |
+| **Navigator** | Show a bounded Laravel route → controller → Blade flow in VS Code | [Build the limited public VSIX](navigator-preview/README.md) |
+| **Compendium** | Explain unfamiliar concepts with version scope, evidence, and practical boundaries | [Open the six-node public preview](compendium-preview/index.html) |
-- **Control** defines the change, records supplied evidence, and preserves the human decision.
-- **Navigator** brings the lifecycle into VS Code beside code flow and impact.
-- **Compendium** supplies primary-source-mapped context when the reviewer needs to understand a
- concept or boundary.
+The learning missions and packs support onboarding, but they are not the primary product.
-Control Lite now provides Prepare → Instruct → Evidence → Decide inside Navigator. It writes only to
-the local project, does not launch an AI, does not run the declared verification command, and does not
-infer acceptance.
+## What the public preview demonstrates
-### See code flow
+### Keep the AI in scope
-
+Declare allowed files, protected behavior, acceptance criteria, required checks, and parked ideas before
+a patch begins. Suggestions outside that boundary remain visible without silently entering the change.
-Navigator traces a Laravel request from route to controller, Blade view, and included partial without
-executing arbitrary project commands.
+### Understand what changed
-### Review impact
+Navigator connects Laravel routes, controllers, Blade views, components, and dependencies so a reviewer
+can reason about a patch instead of accepting a diff on trust.

-Impact and Git comparison views expose incoming users, outgoing dependencies, and flow changes while
-project content remains local.
+### Separate claims from evidence
-### Learn in context
+A test command written in an AI response is not evidence that the command ran. Atlas records each
+required check as Passed, Failed, or Not run and keeps known limitations beside the decision.
-
+### Learn without leaving the review
-Compact cards explain unfamiliar code and link to Compendium nodes whose AI-assisted and independent
-review states remain visible.
+Contextual learning cards connect unfamiliar code to Compendium nodes whose source mapping,
+AI-assistance state, version scope, limitations, and independent-review state remain visible.
-### Explore the Compendium preview
+
-
+## One honest worked example
-The Compendium connects a large programming Lexicon with practical mistakes, version scope,
-verification design, and evidence. Public hosting is still being prepared; screenshots and selected
-node samples are available here now.
+The current Laravel exercise asks for a clearer review-ready status page. The proposed patch stays
+inside its two-file boundary, but the repository cannot execute the required Laravel test. The sample
+decision is therefore **Revise**, not an invented pass.
-More images and their review status are listed in [`screenshots/README.md`](screenshots/README.md).
+[Review the complete Laravel example](control/examples/laravel-status-label/README.md), then try the [runnable remaining-count exercise](control/exercises/browser-list-count/README.md).
-## Current availability
+## Availability
-| Experience | Available here | Limitation |
+| Experience | Available | Current boundary |
| --- | --- | --- |
-| Local Control Lite generator | Yes | Runs in the browser; does not execute AI or verification commands |
-| Guided Control walkthrough | Yes | Static Laravel example; no real Laravel runtime |
-| Safe browser example | Yes | Learning example, not the full product |
-| Selected missions and nodes | Yes | Curated preview; independent review pending |
-| Navigator VSIX | Tester access only | General signed release and clean-profile proof pending |
-| Hosted Compendium | Not yet | Static hosting review in progress |
-
-The manual packaging workflow can prepare a checksum-listed exercise archive for maintainer review.
-See [`DOWNLOAD.md`](docs/getting-started/DOWNLOAD.md); no public release is implied until a human publishes one.
-
-## Evidence and limitations
+| Browser-based Control Lite | Yes | Local templates and review workflow; no AI or command execution |
+| Guided Laravel Control exercise | Yes | Static example; the real Laravel test remains Not run |
+| Safe browser teaching example | Yes | Learning fixture, not the full product |
+| Selected missions and nodes | Yes | Curated preview; independent review is incomplete |
+| Limited Navigator VSIX | Buildable public preview | Conventional Laravel controller-array routes only; unsigned and not the private product |
+| Compendium preview | Yes, local and deployable | Six allowlisted public nodes; no private Compendium source or full Lexicon |
-The private development repository currently validates:
+## Evidence, privacy, and limitations
-- 54 maintained Knowledge Nodes and 664 Lexicon entries;
-- 752 generated Compendium pages;
-- Control, Continuity, Navigator, Compendium, policy, security, packaging, and lifecycle checks;
-- founder dogfooding and a five-person embedded design cohort;
-- one preserved external-alpha round whose same-tester retest remains pending.
+The private development repository currently validates 54 maintained Knowledge Nodes, 664 Lexicon
+entries, 752 generated Compendium pages, and the Control, Continuity, Navigator, Compendium, policy,
+security, packaging, and lifecycle checks. Founder dogfooding, a five-person embedded design cohort,
+and one external-alpha round support formative usefulness—not product-market fit.
-Every exported node now shows its evidence date, source count, AI assistance, automated check state,
-version scope, and pending independent human review. “Gold” describes an internal teaching-depth
-target; it does **not** mean final certification.
+The public preview is local-first, contains no telemetry, requires no account, performs no silent AI
+action, and does not execute or infer verification results. Public exports pass through an allowlist,
+secret and path scanning, local-link validation, integrity hashes, and human review.
-This supports technical credibility and formative usefulness. It does not prove product-market fit,
-retention, willingness to pay, universal correctness, or production safety. Read
-[`testing-status.md`](docs/public/testing-status.md),
-[`known-limitations.md`](docs/public/known-limitations.md), and the public [`FAQ`](docs/product/FAQ.md).
+Read the [testing status](docs/public/testing-status.md), [known limitations](docs/public/known-limitations.md),
+[privacy and safety notes](docs/public/privacy-and-safety.md), and [security policy](.github/SECURITY.md).
-## Supporting work
+## Explore and contribute
-The learning material helps people build the understanding needed to use the control loop; it is not
-the primary product demonstration.
-
-| Area | Role | Start |
-| --- | --- | --- |
-| First Expedition and beginner missions | Confidence-building onboarding | [Mission index](content/missions/README.md) |
-| AI Collaboration Pack | Prompt and review habits | [Pack entry](packs/ai-collaboration/README.md) |
-| Public node samples | Just-in-time concept reference | [Node index](content/nodes/README.md) |
-| Continuity research | Local readiness, health, and recovery | Tracked as parallel alpha work in the roadmap |
-| Testing and research | Protocols, facilitator questions, evidence status | [Testing status](docs/public/testing-status.md) |
-
-## Privacy and trust
-
-- Local-first by default.
-- No telemetry in the current Navigator preview.
-- No account or payment requirement in the current free preview.
-- No silent AI actions, verification execution, or acceptance decisions.
-- Remote Compendium links require HTTPS; localhost is allowed for development.
-- Public material passes through a one-way allowlist, secret/path scanning, local-link validation, and
- manual review.
-- Runnable browser teaching code is tested against HTML-like user input and may not assign user data
- through `innerHTML`.
-
-Read [`SECURITY.md`](.github/SECURITY.md) and
-[`privacy-and-safety.md`](docs/public/privacy-and-safety.md).
-
-## Roadmap and feedback
-
-The immediate public focus is to validate Control Lite in a clean profile, repeat the external-alpha
-workflow, publish a safe preview artifact, and measure whether the control loop helps real reviewers.
-The public [`ROADMAP.md`](docs/product/ROADMAP.md) keeps supporting research separate.
-
-Precise feedback is welcome for reproducible bugs, unclear first steps, accessibility barriers,
-privacy concerns, or workflows that would help people retain control. See
-[`CONTRIBUTING.md`](.github/CONTRIBUTING.md) and the public
-[`FEEDBACK.md`](https://github.com/DeveloperAtlas5/DeveloperAtlas-Public/blob/main/docs/testing/FEEDBACK.md).
+- [Public documentation](docs/README.md)
+- [Product roadmap](docs/product/ROADMAP.md)
+- [Mission index](content/missions/README.md)
+- [AI Collaboration Pack](packs/ai-collaboration/README.md)
+- [Feedback instructions](docs/testing/FEEDBACK.md)
+- [Contribution guide](.github/CONTRIBUTING.md)
## License and provenance
-The files committed to this public preview are available under the [MIT License](LICENSE). The
-private Developer Atlas monorepo and unreleased product source are separate and are not licensed by
-this repository.
-
-Development is materially AI-assisted and human-directed. Automated verification is kept separate
-from independent human review and final acceptance. See [`PROVENANCE.md`](docs/governance/PROVENANCE.md) and the
-outcome-focused [`CHANGELOG.md`](CHANGELOG.md).
+The files in this public preview are available under the [MIT License](LICENSE). The private Developer
+Atlas monorepo and unreleased product source are separate and are not licensed by this repository.
+Development is materially AI-assisted and human-directed; automated checks remain separate from
+independent human review and final acceptance. See [PROVENANCE.md](docs/governance/PROVENANCE.md) and
+the outcome-focused [CHANGELOG.md](CHANGELOG.md).
diff --git a/compendium-preview/README.md b/compendium-preview/README.md
new file mode 100644
index 0000000..96c186b
--- /dev/null
+++ b/compendium-preview/README.md
@@ -0,0 +1,21 @@
+# Atlas Compendium — clean-room public preview
+
+This static preview is built only from exact public node and evidence paths in [`config/compendium-preview-allowlist.json`](../config/compendium-preview-allowlist.json). It does not import or copy the private Compendium application, full Canon index, complete Lexicon, internal review packets, or private knowledge source.
+
+## Use locally
+
+Open `compendium-preview/index.html` in a modern browser. The generated data is embedded in `data.js`, so search and node reading work without a server or network connection. External primary-source links require internet access.
+
+## Rebuild and verify
+
+```bash
+npm run compendium:build
+npm run compendium:check
+npm run test:compendium
+```
+
+The builder escapes public Markdown before generating article HTML and fingerprints every allowlisted source and evidence file.
+
+## Publish manually
+
+The `Deploy Atlas public preview` GitHub Actions workflow is manual. It rebuilds and validates the allowlisted data, creates an integrated Pages bundle containing Control Lite and this Compendium preview, tests the cross-surface links, and deploys `dist/pages`. Enable and run it only after reviewing the pull request and repository Pages settings.
diff --git a/compendium-preview/app.js b/compendium-preview/app.js
new file mode 100644
index 0000000..a17e9b6
--- /dev/null
+++ b/compendium-preview/app.js
@@ -0,0 +1,132 @@
+'use strict'
+
+const data = window.ATLAS_COMPENDIUM_DATA
+const catalogView = document.querySelector('#catalog-view')
+const nodeView = document.querySelector('#node-view')
+const nodeGrid = document.querySelector('#node-grid')
+const search = document.querySelector('#search')
+const resultCount = document.querySelector('#result-count')
+
+if (!data || !Array.isArray(data.nodes)) {
+ resultCount.textContent = 'The public Compendium data bundle is unavailable.'
+} else {
+ search.addEventListener('input', renderCatalog)
+ const requestedNode = new URLSearchParams(window.location.search).get('node')
+ const selected = data.nodes.find((node) => node.id === requestedNode)
+ if (selected) renderNode(selected)
+ else renderCatalog()
+}
+
+function renderCatalog() {
+ catalogView.hidden = false
+ nodeView.hidden = true
+ const query = search.value.trim().toLowerCase()
+ const matches = data.nodes.filter((node) => searchable(node).includes(query))
+ nodeGrid.textContent = ''
+ for (const node of matches) nodeGrid.appendChild(nodeCard(node))
+ resultCount.textContent = `${matches.length} of ${data.nodes.length} public nodes shown.`
+}
+
+function nodeCard(node) {
+ const article = document.createElement('article')
+ article.className = 'node-card'
+ const tags = document.createElement('p')
+ tags.className = 'tags'
+ tags.textContent = node.tags.join(' · ')
+ const title = document.createElement('h2')
+ title.textContent = node.title
+ const summary = document.createElement('p')
+ summary.textContent = node.summary
+ const facts = document.createElement('dl')
+ addFact(facts, 'Version', node.versionScope.join('; ') || 'Not recorded')
+ addFact(facts, 'Sources', String(node.sourceCount))
+ addFact(facts, 'Human review', node.independentReview)
+ const link = document.createElement('a')
+ link.href = `?node=${encodeURIComponent(node.id)}`
+ link.textContent = 'Read this node →'
+ article.append(tags, title, summary, facts, link)
+ return article
+}
+
+function renderNode(node) {
+ catalogView.hidden = true
+ nodeView.hidden = false
+ const meta = document.querySelector('#node-meta')
+ const content = document.querySelector('#node-content')
+ const summary = document.querySelector('#evidence-summary')
+ const sourceList = document.querySelector('#source-list')
+ meta.textContent = ''
+ content.textContent = ''
+ summary.textContent = ''
+ sourceList.textContent = ''
+
+ const eyebrow = document.createElement('p')
+ eyebrow.className = 'eyebrow'
+ eyebrow.textContent = node.id
+ const title = document.createElement('h1')
+ title.textContent = node.title
+ const intro = document.createElement('p')
+ intro.className = 'lead'
+ intro.textContent = node.summary
+ const grid = document.createElement('div')
+ grid.className = 'meta-grid'
+ addMeta(grid, 'Version scope', node.versionScope.join('; ') || 'Not recorded')
+ addMeta(grid, 'Primary sources', String(node.sourceCount))
+ addMeta(grid, 'Verification designs', String(node.verificationCount))
+ addMeta(grid, 'Independent review', node.independentReview)
+ meta.append(eyebrow, title, intro, grid)
+
+ // node.html is generated at build time from allowlisted public Markdown after HTML escaping.
+ content.innerHTML = node.html
+
+ const status = document.createElement('p')
+ status.className = node.independentReview === 'complete' ? 'status-complete' : 'status-pending'
+ status.textContent = `Independent human review: ${node.independentReview}.`
+ const reviewed = document.createElement('p')
+ reviewed.textContent = `Primary-source mapping reviewed: ${node.reviewedAt || 'date not recorded'}.`
+ const links = document.createElement('p')
+ const sourceLink = externalLink(node.sourceUrl, 'Open source Markdown')
+ const evidenceLink = externalLink(node.evidenceUrl, 'Open evidence sidecar')
+ links.append(sourceLink, document.createTextNode(' · '), evidenceLink)
+ summary.append(status, reviewed, links)
+
+ for (const source of node.sources) {
+ const item = document.createElement('li')
+ const link = externalLink(source.url, source.title)
+ item.append(link, document.createTextNode(` — ${source.publisher}; checked ${source.checkedAt || 'date not recorded'}`))
+ sourceList.appendChild(item)
+ }
+ document.title = `${node.title} — Atlas Compendium Preview`
+}
+
+function addFact(list, term, definition) {
+ const dt = document.createElement('dt')
+ dt.textContent = term
+ const dd = document.createElement('dd')
+ dd.textContent = definition
+ list.append(dt, dd)
+}
+
+function addMeta(grid, label, value) {
+ const item = document.createElement('div')
+ item.className = 'meta-item'
+ const heading = document.createElement('span')
+ heading.textContent = label
+ const body = document.createElement('strong')
+ body.textContent = value
+ item.append(heading, body)
+ grid.appendChild(item)
+}
+
+function externalLink(url, label) {
+ const link = document.createElement('a')
+ link.href = url
+ link.target = '_blank'
+ link.rel = 'noreferrer'
+ link.textContent = label
+ return link
+}
+
+function searchable(node) {
+ return [node.id, node.title, node.summary, ...node.tags, ...node.versionScope].join(' ').toLowerCase()
+}
diff --git a/compendium-preview/data-manifest.json b/compendium-preview/data-manifest.json
new file mode 100644
index 0000000..3f6d158
--- /dev/null
+++ b/compendium-preview/data-manifest.json
@@ -0,0 +1,63 @@
+{
+ "schemaVersion": "1.0.0",
+ "allowlist": "config/compendium-preview-allowlist.json",
+ "nodeIds": [
+ "CANON-BLADE-VIEW-001",
+ "CANON-CONTROLLER-001",
+ "CANON-DOM-001",
+ "CANON-LARAVEL-REQUEST-LIFECYCLE-001",
+ "CANON-LOCALSTORAGE-001",
+ "CANON-ROUTE-001"
+ ],
+ "sources": [
+ {
+ "path": "content/nodes/evidence/CANON-BLADE-VIEW-001.evidence.json",
+ "sha256": "87d5727720286e42b74a1baada8d0485ddf128a64eb77c8fbcf286a82c2134d2"
+ },
+ {
+ "path": "content/nodes/evidence/CANON-CONTROLLER-001.evidence.json",
+ "sha256": "caac97797224263cb0d2a257119baa05c04af60b4c279d6b2338ab89f35b1be8"
+ },
+ {
+ "path": "content/nodes/evidence/CANON-DOM-001.evidence.json",
+ "sha256": "1ff55cc92ff718667d25bf4833d5c54b9d180646d052c5cb94026dfe80358c84"
+ },
+ {
+ "path": "content/nodes/evidence/CANON-LARAVEL-REQUEST-LIFECYCLE-001.evidence.json",
+ "sha256": "4975cc1001b542028cbcd8f0e70be35d9609dbfbf90dfb70f90d896227f1063c"
+ },
+ {
+ "path": "content/nodes/evidence/CANON-LOCALSTORAGE-001.evidence.json",
+ "sha256": "81ccfb8b540cfbe82e41ed9fe691b528683aa486570fb10e83abc006a8e05b8f"
+ },
+ {
+ "path": "content/nodes/evidence/CANON-ROUTE-001.evidence.json",
+ "sha256": "ec9928f32ad646c1b4d5de8580c0954fd83d08c8ea92ff28e1534f45e7a9878a"
+ },
+ {
+ "path": "content/nodes/gold/CANON-BLADE-VIEW-001.md",
+ "sha256": "676e1d9e222c2fac07d0443031b3f05653c6ebb5312019cca248756867bb957a"
+ },
+ {
+ "path": "content/nodes/gold/CANON-CONTROLLER-001.md",
+ "sha256": "66146df21386862e5a162d6c3707ba828abd20bc1726da595f39b97f9129ff03"
+ },
+ {
+ "path": "content/nodes/gold/CANON-DOM-001.md",
+ "sha256": "e90b6d6432d9ce1aed1c553b8bd80d35a28979501d74df0596d289de4b9fb28c"
+ },
+ {
+ "path": "content/nodes/gold/CANON-LARAVEL-REQUEST-LIFECYCLE-001.md",
+ "sha256": "106053ec2a64f5c8d567f1dfc297facac0304a4ed79056d067ec740d02021df4"
+ },
+ {
+ "path": "content/nodes/gold/CANON-LOCALSTORAGE-001.md",
+ "sha256": "52a63ca661d004903690eca5e313cd6bb64a26f41d73a59f5b2c875842eb5a6c"
+ },
+ {
+ "path": "content/nodes/gold/CANON-ROUTE-001.md",
+ "sha256": "4192d9230394fa3ccbe60f0b7bbd3bb49e1f2ed37fb902ee0328efab9128282e"
+ }
+ ],
+ "dataSha256": "c4ade5ef8c3986694b123619210e0c7d3b23f27f5e8c8874820be144b1858311"
+}
diff --git a/compendium-preview/data.js b/compendium-preview/data.js
new file mode 100644
index 0000000..e8eb2c9
--- /dev/null
+++ b/compendium-preview/data.js
@@ -0,0 +1,300 @@
+window.ATLAS_COMPENDIUM_DATA = {
+ "schemaVersion": "1.0.0",
+ "generatedFrom": "allowlisted public node and evidence files only",
+ "nodeCount": 6,
+ "nodes": [
+ {
+ "id": "CANON-BLADE-VIEW-001",
+ "title": "Blade View",
+ "summary": "A Blade view is a Laravel template, normally stored under resources/views, that compiles to PHP and renders presentation output from supplied data.",
+ "tags": [
+ "Laravel",
+ "Blade",
+ "view"
+ ],
+ "versionScope": [
+ "Laravel 13.x"
+ ],
+ "reviewedAt": "2026-07-12",
+ "sourceCount": 2,
+ "verificationCount": 3,
+ "independentReview": "pending",
+ "sources": [
+ {
+ "title": "Blade Templates",
+ "publisher": "Laravel",
+ "url": "https://laravel.com/docs/13.x/blade",
+ "checkedAt": "2026-07-12"
+ },
+ {
+ "title": "Views",
+ "publisher": "Laravel",
+ "url": "https://laravel.com/docs/13.x/views",
+ "checkedAt": "2026-07-12"
+ }
+ ],
+ "limitations": [
+ "Escaped {{ }} output is safer for untrusted text than raw {!! !!} output.",
+ "A Blade view is one response representation; other response types do not require Blade.",
+ "Blade permits PHP, but request handling and business rules should remain outside presentation templates.",
+ "Independent human review remains required before promotion to gold."
+ ],
+ "sourcePath": "content/nodes/gold/CANON-BLADE-VIEW-001.md",
+ "sourceUrl": "https://github.com/DeveloperAtlas5/DeveloperAtlas-Public/blob/main/content/nodes/gold/CANON-BLADE-VIEW-001.md",
+ "evidenceUrl": "https://github.com/DeveloperAtlas5/DeveloperAtlas-Public/blob/main/content/nodes/evidence/CANON-BLADE-VIEW-001.evidence.json",
+ "html": "\n
Quick answer
\n
A Blade view is a Laravel template, normally stored under resources/views, that compiles to PHP and renders presentation output from supplied data.
\n
Where it fits in the flow
\n
Blade is one possible representation near the end of the request path. A route or controller returns a view with data; Blade renders HTML; Laravel places that HTML in the outgoing response.
\n
controller view data -> Blade template -> rendered HTML -> response
\n
Mental model
\n
Think of Blade as a document template. HTML supplies the structure, Blade directives control simple presentation branches and loops, and escaped echo syntax fills values into the page. The template presents decisions made elsewhere rather than owning request or business logic.
The controller must pass an items value. {{ $item->name }} escapes the displayed text by default.
\n
What you can safely change
\n
Change labels, layout markup, and simple display conditions while preserving the view-data contract.
Rename a Blade variable together with the controller key that supplies it.
Add a route helper only after confirming the named route exists.
Prefer escaped {{ }} output for untrusted values; use raw output only with an explicit trusted-content reason.
\n
Common failure and recovery
\n
Undefined variable. Compare the controller's view-data key with the Blade variable name.
View not found. Translate the dot name, such as items.index, to resources/views/items/index.blade.php and confirm the path.
The list renders empty. Inspect the data passed by the controller and provide an intentional empty state.
HTML contains unsafe or unexpected markup. Replace raw {!! !!} output with escaped {{ }} unless the content is explicitly trusted and sanitized.
\n
How to verify it
\n
V-BLADE-VIEW-001: Render the view with known controller data and confirm the expected escaped values appear in the HTML.
V-BLADE-VIEW-002: Render an empty collection and confirm the intended empty-state message appears without broken markup.
V-BLADE-VIEW-003: Inspect the template and confirm request handling, database queries, and business rules have not moved into Blade.
\n
Boundaries and version notes
\n
Reviewed for Laravel 13.x; .blade.php, resources/views, compilation, directives, and escaped echo behavior are stable in this scope.
Escaped {{ }} and raw {!! !!} output have different cross-site-scripting boundaries.
A Blade view is one response representation; JSON, redirects, files, and empty responses do not require Blade.
Blade permits PHP, but request handling and business rules should remain outside presentation templates.
\n
AI steering rule
\n
AI should inspect the controller's view name and data contract plus the existing layout before editing Blade, preserve escaped output by default, and avoid moving request handling or business logic into the template.
\n
Human readability rule
\n
Keep HTML structure visible, indent Blade directives consistently, give empty and error states explicit markup, and name variables after the data the user sees.
\n
Related nodes
\n
CANON-CONTROLLER-001
CANON-ROUTE-001
CANON-LARAVEL-REQUEST-LIFECYCLE-001
CANON-CRUD-001
\n
Evidence status
\n
Primary-source reviewed on 2026-07-12. Independent human review and promotion are pending. See `../evidence/CANON-BLADE-VIEW-001.evidence.json` for claim mappings, source locations, limitations, and verification contracts.
"
+ },
+ {
+ "id": "CANON-CONTROLLER-001",
+ "title": "Controller",
+ "summary": "A Laravel controller groups related request-handling methods. When a controller route matches, Laravel invokes the configured public action, which coordinates the work needed to return a response.",
+ "tags": [
+ "Laravel",
+ "controller",
+ "action"
+ ],
+ "versionScope": [
+ "Laravel 13.x"
+ ],
+ "reviewedAt": "2026-07-12",
+ "sourceCount": 3,
+ "verificationCount": 3,
+ "independentReview": "pending",
+ "sources": [
+ {
+ "title": "Controllers",
+ "publisher": "Laravel",
+ "url": "https://laravel.com/docs/13.x/controllers",
+ "checkedAt": "2026-07-12"
+ },
+ {
+ "title": "Routing",
+ "publisher": "Laravel",
+ "url": "https://laravel.com/docs/13.x/routing",
+ "checkedAt": "2026-07-12"
+ },
+ {
+ "title": "Validation",
+ "publisher": "Laravel",
+ "url": "https://laravel.com/docs/13.x/validation",
+ "checkedAt": "2026-07-12"
+ }
+ ],
+ "limitations": [
+ "Controllers are optional; routes may use closures or invokable classes.",
+ "A controller does not automatically validate, authorize, or persist data.",
+ "Controllers do not have to extend Laravel's base controller class.",
+ "Independent human review remains required before promotion to gold."
+ ],
+ "sourcePath": "content/nodes/gold/CANON-CONTROLLER-001.md",
+ "sourceUrl": "https://github.com/DeveloperAtlas5/DeveloperAtlas-Public/blob/main/content/nodes/gold/CANON-CONTROLLER-001.md",
+ "evidenceUrl": "https://github.com/DeveloperAtlas5/DeveloperAtlas-Public/blob/main/content/nodes/evidence/CANON-CONTROLLER-001.evidence.json",
+ "html": "\n
Quick answer
\n
A Laravel controller groups related request-handling methods. When a controller route matches, Laravel invokes the configured public action, which coordinates the work needed to return a response.
\n
Where it fits in the flow
\n
The controller comes after route matching and route middleware. It receives request context, may validate or authorize input and call models or services, then returns a view, redirect, JSON response, or another supported response.
\n
matched route -> controller action -> application work -> response
\n
Mental model
\n
Think of a controller action as a coordinator at a service desk. It accepts a specific request, sends work to the right place, and returns the result. It should make the sequence visible without becoming the home for every business rule.
The route selects index(). The action obtains the items and passes them to resources/views/items/index.blade.php under the name $items.
\n
What you can safely change
\n
Change one action's query, validation, or response while keeping its route contract visible.
Rename passed view data together with the Blade variable that receives it.
Rename an action together with the route that references it.
Extract business logic only when the action has a clear, repeated responsibility that benefits from a separate class.
\n
Common failure and recovery
\n
Target class or method does not exist. Confirm the route import, controller namespace, class, and public action name.
Blade reports an undefined variable. Compare the controller's view-data key with the variable used in the template.
A valid request works but invalid input behaves unpredictably. Make validation and the rejected path explicit before persistence.
The controller is difficult to scan. Separate visible blocks for validation, data preparation, action, and response before introducing more architecture.
\n
How to verify it
\n
V-CONTROLLER-001: Send a request through the mapped route and confirm the intended public controller action handles it.
V-CONTROLLER-002: Exercise one valid path and one rejected or missing-input path and confirm their different responses.
V-CONTROLLER-003: Assert the smallest observable contract: status, redirect, view name, essential view data, or JSON data.
\n
Boundaries and version notes
\n
Reviewed for Laravel 13.x; controllers remain optional because routes may use closures or invokable classes.
A controller does not automatically validate, authorize, or persist data.
Laravel controllers do not have to extend the framework's base controller class.
Services, jobs, and repositories may be appropriate later, but they are not prerequisites for a readable beginner controller.
\n
AI steering rule
\n
AI should confirm the mapped route, action contract, input, and expected response before editing a controller, keep the change inside the focused action, and avoid adding service or repository layers unless the responsibility or user request requires them.
\n
Human readability rule
\n
Keep controller actions short enough to scan and organize them as visible input, validation or authorization, data preparation, operation, and response blocks.
\n
Related nodes
\n
CANON-ROUTE-001
SUPPORT-VALIDATE-001
CANON-BLADE-VIEW-001
CANON-LARAVEL-REQUEST-LIFECYCLE-001
CANON-CRUD-001
CANON-FUNCTION-001
\n
Evidence status
\n
Primary-source reviewed on 2026-07-12. Independent human review and promotion are pending. See `../evidence/CANON-CONTROLLER-001.evidence.json` for claim mappings, source locations, limitations, and verification contracts.
"
+ },
+ {
+ "id": "CANON-DOM-001",
+ "title": "DOM",
+ "summary": "The DOM represents a document as a node tree and provides APIs that code can use to inspect and change that in-memory document.",
+ "tags": [
+ "JavaScript",
+ "DOM",
+ "browser"
+ ],
+ "versionScope": [
+ "Current DOM standard",
+ "Evergreen browsers"
+ ],
+ "reviewedAt": "2026-07-12",
+ "sourceCount": 1,
+ "verificationCount": 3,
+ "independentReview": "pending",
+ "sources": [
+ {
+ "title": "Document Object Model (DOM)",
+ "publisher": "Mozilla MDN",
+ "url": "https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model",
+ "checkedAt": "2026-07-12"
+ }
+ ],
+ "limitations": [
+ "The DOM is the browser's current document representation, not an automatic edit to the source HTML file.",
+ "Selector methods can return no match; code must handle that path instead of assuming an element exists.",
+ "DOM availability and timing depend on the host environment and document lifecycle.",
+ "Independent human review remains required before promotion to gold."
+ ],
+ "sourcePath": "content/nodes/gold/CANON-DOM-001.md",
+ "sourceUrl": "https://github.com/DeveloperAtlas5/DeveloperAtlas-Public/blob/main/content/nodes/gold/CANON-DOM-001.md",
+ "evidenceUrl": "https://github.com/DeveloperAtlas5/DeveloperAtlas-Public/blob/main/content/nodes/evidence/CANON-DOM-001.evidence.json",
+ "html": "\n
Hover summary
\n
The DOM is the browser's live version of the HTML page.
\n
One-sentence truth
\n
The DOM represents a document as a node tree and provides APIs that code can use to inspect and change that in-memory document.
\n
Mental model
\n
HTML is the written recipe. The DOM is the meal the browser builds from that recipe.
\n
Beginner explanation
\n
When the browser opens your HTML, it creates a live page structure. JavaScript can find parts of this structure and change them.
\n
Technical explanation
\n
DOM stands for Document Object Model. Browser JavaScript uses DOM methods like querySelector to select elements.
Use DOM methods when JavaScript needs to find or change something on the page.
\n
Common mistakes
\n
Thinking JavaScript edits the HTML file itself.
Selecting the wrong element.
Running JavaScript before the element exists.
\n
AI steering rule
\n
AI should explain the connection between HTML class names and JavaScript selectors before patching DOM bugs.
\n
Human readability rule
\n
DOM-related variable names should name the element clearly, like submitButton or messageText.
\n
Related nodes
\n
CANON-JAVASCRIPT-001
SUPPORT-QUERYSELECTOR-001
\n
Verification
\n
V-DOM-001: Select a known element and confirm the lookup returns the expected node.
V-DOM-002: Change one text value, attribute, or class and observe the corresponding page update.
V-DOM-003: Check the missing-element path so a failed selector is visible rather than silently guessed.
\n
Applicability and boundaries
\n
The DOM is the browser's current document representation, not an automatic edit to the source HTML file.
Selector methods can return no match; code must handle that path instead of assuming an element exists.
DOM availability and timing depend on the host environment and document lifecycle.
\n
Evidence status
\n
Primary-source reviewed on 2026-07-12. Independent human review and promotion are pending. See `../evidence/CANON-DOM-001.evidence.json` for claim mappings, source locations, limitations, and verification contracts.
"
+ },
+ {
+ "id": "CANON-LARAVEL-REQUEST-LIFECYCLE-001",
+ "title": "Laravel Request Lifecycle",
+ "summary": "A Laravel HTTP request enters through public/index.php, passes through application bootstrap and middleware, reaches a matching route action, and returns a response outward through middleware to the client.",
+ "tags": [
+ "Laravel",
+ "request flow",
+ "verification"
+ ],
+ "versionScope": [
+ "Laravel 13.x",
+ "PHP 8.3+",
+ "Standard Laravel HTTP request lifecycle"
+ ],
+ "reviewedAt": "2026-07-12",
+ "sourceCount": 8,
+ "verificationCount": 5,
+ "independentReview": "pending",
+ "sources": [
+ {
+ "title": "Request Lifecycle",
+ "publisher": "Laravel",
+ "url": "https://laravel.com/docs/13.x/lifecycle",
+ "checkedAt": "2026-07-12"
+ },
+ {
+ "title": "Routing",
+ "publisher": "Laravel",
+ "url": "https://laravel.com/docs/13.x/routing",
+ "checkedAt": "2026-07-12"
+ },
+ {
+ "title": "Controllers",
+ "publisher": "Laravel",
+ "url": "https://laravel.com/docs/13.x/controllers",
+ "checkedAt": "2026-07-12"
+ },
+ {
+ "title": "Middleware",
+ "publisher": "Laravel",
+ "url": "https://laravel.com/docs/13.x/middleware",
+ "checkedAt": "2026-07-12"
+ },
+ {
+ "title": "HTTP Responses",
+ "publisher": "Laravel",
+ "url": "https://laravel.com/docs/13.x/responses",
+ "checkedAt": "2026-07-12"
+ },
+ {
+ "title": "Views",
+ "publisher": "Laravel",
+ "url": "https://laravel.com/docs/13.x/views",
+ "checkedAt": "2026-07-12"
+ },
+ {
+ "title": "HTTP Tests",
+ "publisher": "Laravel",
+ "url": "https://laravel.com/docs/13.x/http-tests",
+ "checkedAt": "2026-07-12"
+ },
+ {
+ "title": "Release Notes",
+ "publisher": "Laravel",
+ "url": "https://laravel.com/docs/13.x/releases",
+ "checkedAt": "2026-07-12"
+ }
+ ],
+ "limitations": [
+ "The review covers Laravel 13.x documentation and must be repeated for a future major version.",
+ "The node intentionally omits framework-internal class-by-class execution details that are unnecessary for its beginner mental model.",
+ "Long-running servers such as Octane may add worker lifecycle concerns that are outside this node's request-level scope.",
+ "Application middleware, exception handling, service providers, and response preparation can add project-specific behavior.",
+ "Independent human review remains required before the node can be marked independently_reviewed or gold."
+ ],
+ "sourcePath": "content/nodes/gold/CANON-LARAVEL-REQUEST-LIFECYCLE-001.md",
+ "sourceUrl": "https://github.com/DeveloperAtlas5/DeveloperAtlas-Public/blob/main/content/nodes/gold/CANON-LARAVEL-REQUEST-LIFECYCLE-001.md",
+ "evidenceUrl": "https://github.com/DeveloperAtlas5/DeveloperAtlas-Public/blob/main/content/nodes/evidence/CANON-LARAVEL-REQUEST-LIFECYCLE-001.evidence.json",
+ "html": "\n
Quick answer
\n
A Laravel HTTP request enters through public/index.php, passes through application bootstrap and middleware, reaches a matching route action, and returns a response outward through middleware to the client.
\n
Where it fits in the flow
\n
This is the map for the full server-side journey. Use it before changing code when you do not yet know whether a failure belongs to the request, middleware, route, action, view, or response.
Think of the request as a parcel moving through checkpoints. public/index.php receives it, bootstrap prepares the application, middleware may inspect or stop it, the router chooses a destination, the action creates a response, and middleware handles that response on its way out.
\n
The controller and Blade view are common stops, not mandatory ones. A route closure can produce a response directly, and a controller can return JSON, a redirect, a string, or a response object instead of a view.
// app/Http/Controllers/GroceryController.php\nuse Illuminate\\View\\View;\n\npublic function index(): View\n{\n return view('groceries.index');\n}
\n
For GET /groceries, Laravel boots, runs middleware, matches the route, calls GroceryController::index(), renders the view, and sends the resulting response back through middleware.
\n
What you can safely change
\n
Change one link in the chain at a time, then verify that exact boundary.
When changing the URI or method, update the caller and route together.
When changing the action or view name, update the route or controller reference that points to it.
Keep the response assertion aligned with the response type: view, redirect, or JSON.
\n
Common failure and recovery
\n
The controller breakpoint never runs. Confirm the request method and URI with route:list, then inspect middleware that can return early.
The URI looks right but Laravel rejects the request. Compare the HTTP method as well as the path.
The action runs but the page fails. Inspect the returned response or view name and the data passed to it.
Debugging jumps straight to architecture changes. Trace the first boundary where expected and observed behavior differ, then make the smallest repair there.
\n
How to verify it
\n
V-LRLC-001: Run php artisan route:list --path=groceries and confirm the expected method, URI, action, and middleware.
V-LRLC-002: Request /groceries in a feature test, then assert 200 and assertViewIs('groceries.index').
V-LRLC-003: Add an observable route middleware behavior and confirm it runs before the controller and can return a response without invoking the action.
V-LRLC-004: Send the wrong HTTP method to /groceries and confirm GroceryController::index() is not invoked.
V-LRLC-005: For JSON or redirect variants, assert status plus assertJson(...) or assertRedirect(...) instead of asserting a view.
\n
Boundaries and version notes
\n
Reviewed for Laravel 13.x, which requires PHP 8.3 or newer within its supported PHP range.
This article describes the normal HTTP lifecycle; console commands use the console path.
Application middleware and long-running runtimes can add operational detail without changing the core request-to-response model.
Route closures, controllers, Blade, JSON, and redirects are alternatives at specific points, not universal stages.
\n
AI steering rule
\n
Before changing a Laravel request-flow bug, AI should identify the observed method and URI, matching route, applicable middleware, route action, and returned response; it should not assume the controller ran or introduce new architecture before locating the first broken boundary.
\n
Human readability rule
\n
Present the method, URI, middleware, action, response type, and verification result as one traceable request-to-response chain.
Do not use it for passwords, private data, or real multi-user database needs.
\n
Common mistakes
\n
Forgetting that localStorage stores strings.
Forgetting JSON.stringify.
Forgetting JSON.parse.
Treating localStorage like a real backend database.
\n
AI steering rule
\n
AI should warn when localStorage is being used for data that should be private or server-side.
\n
Human readability rule
\n
Use clear key names and keep save/load logic grouped.
\n
Related nodes
\n
CANON-JAVASCRIPT-001
SUPPORT-JSON-STRINGIFY-001
SUPPORT-JSON-PARSE-001
\n
Verification
\n
V-LOCALSTORAGE-001: Save a known value, refresh or recreate the state, and confirm the value loads again.
V-LOCALSTORAGE-002: Start with a missing key and confirm the application uses its intended default.
V-LOCALSTORAGE-003: Store malformed or unexpected text and confirm parsing failure does not silently corrupt visible state.
\n
Applicability and boundaries
\n
Storage is scoped by origin and behavior for file URLs is not a reliable contract.
Keys and values are strings; structured values require an explicit serialization format such as JSON.
Storage access can fail, is synchronous, has browser-dependent limits, and should not hold secrets or server-authoritative data.
\n
Evidence status
\n
Primary-source reviewed on 2026-07-12. Independent human review and promotion are pending. See `../evidence/CANON-LOCALSTORAGE-001.evidence.json` for claim mappings, source locations, limitations, and verification contracts.
"
+ },
+ {
+ "id": "CANON-ROUTE-001",
+ "title": "Route",
+ "summary": "A Laravel route matches an HTTP method and URI, then dispatches the request to a configured closure, controller action, or other supported route action.",
+ "tags": [
+ "Laravel",
+ "route",
+ "HTTP"
+ ],
+ "versionScope": [
+ "Laravel 13.x"
+ ],
+ "reviewedAt": "2026-07-12",
+ "sourceCount": 2,
+ "verificationCount": 3,
+ "independentReview": "pending",
+ "sources": [
+ {
+ "title": "Routing",
+ "publisher": "Laravel",
+ "url": "https://laravel.com/docs/13.x/routing",
+ "checkedAt": "2026-07-12"
+ },
+ {
+ "title": "URL Generation",
+ "publisher": "Laravel",
+ "url": "https://laravel.com/docs/13.x/urls",
+ "checkedAt": "2026-07-12"
+ }
+ ],
+ "limitations": [
+ "HTTP method and URI are both part of route matching.",
+ "Named routes generate URLs by name but do not change the dispatched action.",
+ "Middleware, model binding, and authorization can affect the request around the action.",
+ "Independent human review remains required before promotion to gold."
+ ],
+ "sourcePath": "content/nodes/gold/CANON-ROUTE-001.md",
+ "sourceUrl": "https://github.com/DeveloperAtlas5/DeveloperAtlas-Public/blob/main/content/nodes/gold/CANON-ROUTE-001.md",
+ "evidenceUrl": "https://github.com/DeveloperAtlas5/DeveloperAtlas-Public/blob/main/content/nodes/evidence/CANON-ROUTE-001.evidence.json",
+ "html": "\n
Quick answer
\n
A Laravel route matches an HTTP method and URI, then dispatches the request to a configured closure, controller action, or other supported route action.
\n
Where it fits in the flow
\n
The route is the decision point after Laravel boots and applicable global middleware runs. It connects an incoming method and URI to the next action and may add route middleware, parameters, and a name used for URL generation.
\n
request method + URI -> route match -> route middleware -> action
\n
Mental model
\n
Think of a route as a signpost with two required coordinates: method and path. The route name is a reusable label for generating a URL; it is not the action itself.
\n
Working example
\n
use App\\Http\\Controllers\\ItemController;\nuse Illuminate\\Support\\Facades\\Route;\n\nRoute::get('/items', [ItemController::class, 'index'])\n ->name('items.index');\n\nRoute::post('/items', [ItemController::class, 'store'])\n ->name('items.store');
\n
GET /items dispatches index; POST /items dispatches store. Blade can generate the first URL with route('items.index') without hard-coding /items.
\n
What you can safely change
\n
Change a route URI together with links, forms, tests, or redirects that call it.
Change a route name together with every route(...) reference.
Change a controller action only when the target public method exists.
Preserve the HTTP meaning: reads normally use GET; state-changing form actions use POST, PUT, PATCH, or DELETE as appropriate.
\n
Common failure and recovery
\n
404 Not Found. Confirm the registered URI and any route prefix with route:list.
405 Method Not Allowed. The path exists but the request method differs; inspect the form method and method spoofing.
Route [name] not defined. Compare the exact route name with the Blade, redirect, or test reference.
Target class or method error. Confirm the controller import and public action name.
\n
How to verify it
\n
V-ROUTE-001: Run php artisan route:list --path=items and confirm method, URI, name, middleware, and action.
V-ROUTE-002: Send a request with the registered method and URI and confirm the configured closure or controller action runs.
V-ROUTE-003: Use one wrong method or route name and confirm the mismatch is observable and the intended action does not run.
\n
Boundaries and version notes
\n
Reviewed for Laravel 13.x; the method-and-URI matching model is stable across supported recent Laravel versions.
Named routes generate URLs by name but do not change the dispatched action.
Middleware, route-model binding, authorization, and domain or prefix groups may affect the request around the action.
A controller is common but optional; a closure or invokable class can also be a route action.
\n
AI steering rule
\n
AI should inspect the current request method and URI plus route:list before editing a route, and should change only the mismatched route property and its direct callers unless broader routing work is requested.
\n
Human readability rule
\n
Group related routes, use consistent resource-oriented names, and keep method, URI, action, middleware, and route name easy to scan on one definition.
\n
Related nodes
\n
CANON-REQUEST-RESPONSE-001
CANON-LARAVEL-REQUEST-LIFECYCLE-001
CANON-CONTROLLER-001
CANON-BLADE-VIEW-001
CANON-CRUD-001
\n
Evidence status
\n
Primary-source reviewed on 2026-07-12. Independent human review and promotion are pending. See `../evidence/CANON-ROUTE-001.evidence.json` for claim mappings, source locations, limitations, and verification contracts.
"
+ }
+ ]
+};
diff --git a/compendium-preview/index.html b/compendium-preview/index.html
new file mode 100644
index 0000000..986a373
--- /dev/null
+++ b/compendium-preview/index.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+ Atlas Compendium — Public Preview
+
+
+
+ Skip to content
+
+ Developer Atlas
+ Compendium public preview
+ Open Control Lite
+
+
+
+
ALLOWLISTED PUBLIC KNOWLEDGE
+
Understand the code before accepting the change.
+
Search a small evidence-mapped preview covering the Laravel request flow and the browser-list verification exercise. Every node keeps its version scope, source count, limitations, AI-assistance disclosure, and independent-review state visible.