Skip to content

Commit c312259

Browse files
snapsynapseclaude
andcommitted
Add verification system, MCP server, and contributor docs
New: CI verification workflow, verify.js + check-links.js scripts, VERIFICATION.md, CONTRIBUTING.md, MCP server (mcp-server.js + mcp.json). Updated: README, ONTOLOGY design doc, styles, project.yml. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2b0a4c6 commit c312259

11 files changed

Lines changed: 1661 additions & 0 deletions

File tree

.github/workflows/verify.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Verify
2+
3+
on:
4+
schedule:
5+
- cron: '0 9 * * 1'
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
verify:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
- uses: actions/setup-node@v4
17+
with:
18+
node-version: '20'
19+
- name: Verify freshness
20+
run: node scripts/verify.js
21+
continue-on-error: true

CONTRIBUTING.md

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
# Contributing
2+
3+
This project follows a zero-dependency, config-driven approach. All domain-specific settings live in `project.yml`, and all scripts use only Node.js built-ins.
4+
5+
## Adding Entities
6+
7+
### 1. Create the Markdown File
8+
9+
Create a `.md` file in the appropriate `data/examples/` subdirectory:
10+
11+
| Entity Role | Directory | Example |
12+
|-------------|-----------|---------|
13+
| Primary | `data/examples/requirements/` | `data-encryption.md` |
14+
| Container | `data/examples/frameworks/` | `iso-27001.md` |
15+
| Authority | `data/examples/organizations/` | `iso.md` |
16+
17+
Directory names are configured in `project.yml` under `entities.<role>.directory`.
18+
19+
### 2. Add YAML Frontmatter
20+
21+
Every entity file starts with YAML frontmatter between `---` delimiters. See existing files for the required fields. At minimum:
22+
23+
**Primary entities:**
24+
```yaml
25+
---
26+
title: Data Encryption
27+
group: technical
28+
last_verified: 2025-01-15
29+
---
30+
```
31+
32+
**Container entities:**
33+
```yaml
34+
---
35+
title: ISO 27001
36+
status: active
37+
authority: iso
38+
last_verified: 2025-01-15
39+
---
40+
```
41+
42+
**Authority entities:**
43+
```yaml
44+
---
45+
title: International Organization for Standardization
46+
type: standards-body
47+
last_verified: 2025-01-15
48+
---
49+
```
50+
51+
### 3. Add Mapping Entries
52+
53+
For containers that reference primary entities, add entries to `data/examples/mapping/index.yml` (or the path configured in `project.yml` under `mapping.file`):
54+
55+
```yaml
56+
- id: provision-id
57+
regulation: framework-id
58+
obligations:
59+
- primary-id-1
60+
- primary-id-2
61+
```
62+
63+
### 4. Validate and Build
64+
65+
```bash
66+
# Check cross-references
67+
node scripts/validate.js
68+
69+
# Check staleness and completeness
70+
node scripts/verify.js
71+
72+
# Build the site and JSON API
73+
node scripts/build.js
74+
```
75+
76+
Fix any errors reported by `validate.js` before submitting.
77+
78+
## Modifying the Ontology
79+
80+
The entity model is defined in `project.yml` under `entities:`. Each role has:
81+
82+
- `name` — singular display name
83+
- `plural` — plural display name
84+
- `directory` — subdirectory under `data/examples/`
85+
- Role-specific fields (groups, statuses, etc.)
86+
87+
When changing entity names or directories:
88+
1. Update `project.yml`
89+
2. Rename the corresponding data directory
90+
3. Run `validate.js` to confirm references still resolve
91+
4. Run `build.js` to regenerate the site
92+
93+
## Code Style
94+
95+
- **Zero dependencies.** All scripts use only Node.js built-ins. Do not add npm packages.
96+
- Use the existing YAML parser (`parseYaml`) rather than importing a YAML library.
97+
- Keep functions pure where possible.
98+
- Use `'use strict'` at the top of every script.
99+
100+
## Testing Changes Locally
101+
102+
```bash
103+
# 1. Validate cross-references
104+
node scripts/validate.js
105+
106+
# 2. Check entity freshness
107+
node scripts/verify.js
108+
109+
# 3. Build the site
110+
node scripts/build.js
111+
112+
# 4. Preview locally (any static file server works)
113+
npx serve docs
114+
# or
115+
python3 -m http.server -d docs 8000
116+
```
117+
118+
Check the generated `docs/` directory for the HTML site and `docs/api/v1/` for the JSON API.
119+
120+
## Pull Request Process
121+
122+
1. Create a feature branch from `main`
123+
2. Make your changes (add entities, update config, fix bugs)
124+
3. Run `validate.js` and `verify.js` — ensure no errors
125+
4. Run `build.js` — ensure it completes without errors
126+
5. Commit the source files (`data/`, `project.yml`, `scripts/`). Generated output in `docs/` may or may not be committed depending on your deployment strategy.
127+
6. Open a PR against `main` with a clear description of what changed and why
128+
129+
## Container File Format
130+
131+
Container entity files have a specific structure with a timeline table and provision sections separated by `---`:
132+
133+
```markdown
134+
---
135+
title: Example Framework
136+
status: active
137+
authority: org-id
138+
---
139+
140+
## Timeline
141+
142+
| Date | Event |
143+
|------|-------|
144+
| 2024-01-01 | Published |
145+
146+
---
147+
148+
## Provision Name
149+
150+
| Property | Value |
151+
|----------|-------|
152+
| Category | example |
153+
154+
### Requirements
155+
156+
| Requirement | Description |
157+
|-------------|-------------|
158+
| req-id | Details here |
159+
```
160+
161+
See existing container files for complete examples.

README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ A template for building structured, version-controlled knowledge bases with an o
2525
- **Bridge pages** — SEO-targeted pages like "Does X require Y?"
2626
- **Dark/light theme** — with persistence
2727
- **Client-side search** — lazy-loaded, keyboard-navigable
28+
- **Sortable tables** — click any column header to sort
29+
- **MCP server** — AI agent access to your knowledge base
30+
- **Discovery files** — llms.txt, agents.json, RSS for machine consumption
2831
- **Zero dependencies** — Node.js built-ins only
2932

3033
## Project Structure
@@ -85,6 +88,33 @@ node scripts/validate.js # Validate cross-references
8588
- **Bespoke static generation** — the build script _is_ the specification
8689
- **GitOps** — Git is the single source of truth
8790

91+
## AI Agent Support
92+
93+
Every Knowledge-as-Code site includes machine-readable discovery files:
94+
95+
- **MCP Server**`mcp-server.js` provides read-only access to all entities via Model Context Protocol. Tools are dynamically named from your `project.yml` config. Run with `node mcp-server.js` or add to your MCP client config via `mcp.json`.
96+
- **llms.txt** — Generated at `docs/llms.txt` with entity model, API endpoints, and entity listings for LLM context
97+
- **agents.json** — Machine-readable metadata at `docs/agents.json` for agent discovery
98+
- **RSS feed** — Recent updates at `docs/index.xml`
99+
- **JSON API** — Programmatic access at `docs/api/v1/`
100+
101+
## Verification
102+
103+
Knowledge as Code includes a verification scaffold for detecting stale data:
104+
105+
- Add `last_verified: YYYY-MM-DD` to entity frontmatter
106+
- Run `node scripts/verify.js` to check for staleness
107+
- Configure threshold in `project.yml` under `verification.staleness_days`
108+
- See [VERIFICATION.md](VERIFICATION.md) for details on adding AI-assisted verification
109+
110+
## Ecosystem
111+
112+
Knowledge as Code is part of a broader set of open standards:
113+
114+
- **[Graceful Boundaries](https://github.com/snapsynapse/graceful-boundaries)** — How services communicate operational limits to humans and agents
115+
- **[Siteline](https://siteline.snapsynapse.com)** — AI agent readiness scanner for websites
116+
- **[Knowledge as Code](https://knowledge-as-code.com)** — The pattern definition and community hub
117+
88118
## The Pattern
89119

90120
Knowledge as Code has six defining properties:
@@ -102,6 +132,15 @@ Read the full pattern definition at [knowledge-as-code.com](https://knowledge-as
102132

103133
Knowledge as Code was created by [Sam Rogers](https://sam-rogers.com) / [Snap Synapse](https://snapsynapse.com). See [ATTRIBUTION.md](ATTRIBUTION.md) for details.
104134

135+
## Deploying
136+
137+
When you use this template, update the following:
138+
139+
1. Edit `project.yml` with your domain entities, colors, and site identity
140+
2. Replace example data in `data/examples/` with your own
141+
3. Update `docs/CNAME` with your custom domain (or remove it)
142+
4. Push to GitHub — Pages deploys automatically via the included workflow
143+
105144
## License
106145

107146
MIT

VERIFICATION.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Verification
2+
3+
The Knowledge-as-Code template includes a verification system that detects stale entities, validates cross-reference integrity, and provides a foundation for AI-assisted content review.
4+
5+
## How It Works
6+
7+
The verification script (`scripts/verify.js`) performs two categories of checks:
8+
9+
### Staleness Detection
10+
11+
Each entity file can include a `last_verified` date in its YAML frontmatter. The script compares this date against a configurable threshold to identify entities that may contain outdated information.
12+
13+
Entities are reported in three categories:
14+
- **Fresh** — verified within the staleness window
15+
- **Stale**`last_verified` date exceeds the threshold
16+
- **Never verified** — no `last_verified` field present
17+
18+
### Cross-Reference Checking
19+
20+
The script validates that:
21+
- Every container has at least one mapping entry
22+
- Every mapping references valid primary entity IDs
23+
- Every mapping references valid container IDs
24+
25+
## Setting `last_verified` in Entity Frontmatter
26+
27+
Add a `last_verified` field with an ISO date to any entity's frontmatter:
28+
29+
```yaml
30+
---
31+
title: Data Encryption
32+
group: technical
33+
last_verified: 2025-01-15
34+
---
35+
```
36+
37+
When you review an entity and confirm its content is current, update this date. The verification script will then consider it fresh until the staleness threshold is exceeded.
38+
39+
## Configuring the Staleness Threshold
40+
41+
In `project.yml`, set the number of days before an entity is considered stale:
42+
43+
```yaml
44+
verification:
45+
staleness_days: 90
46+
```
47+
48+
The default is 90 days. Adjust this based on how frequently your domain changes. Fast-moving regulatory environments may warrant 30 days; stable reference data might use 180.
49+
50+
## Running Verification
51+
52+
```bash
53+
node scripts/verify.js
54+
```
55+
56+
The script exits with code 0 if no entities are stale, and code 1 if any stale entities are found. This makes it suitable for CI pipelines.
57+
58+
## GitHub Actions Workflow
59+
60+
The included workflow (`.github/workflows/verify.yml`) runs verification on a weekly schedule (Mondays at 9am UTC) and can be triggered manually via `workflow_dispatch`.
61+
62+
The workflow uses `continue-on-error: true` so that stale entities produce warnings rather than blocking other CI processes. Remove this flag if you want stale entities to fail the pipeline.
63+
64+
## AI-Assisted Verification
65+
66+
The `scripts/verify.js` file includes a commented-out placeholder for model-based verification. This pattern sends entity content to an LLM API to check for:
67+
68+
- Outdated facts or references
69+
- Broken or changed URLs
70+
- Superseded standards or regulations
71+
- Factual inaccuracies
72+
73+
To enable AI verification:
74+
75+
1. Set environment variables for your AI provider:
76+
```bash
77+
export AI_API_URL="https://api.example.com/v1/completions"
78+
export AI_API_KEY="your-key"
79+
```
80+
81+
2. Uncomment the `aiVerify` function in `scripts/verify.js`
82+
83+
3. Uncomment the loop that calls `aiVerify` on stale entities
84+
85+
4. Make the `verify` function `async` and add `await` to the AI calls
86+
87+
The placeholder uses Node.js built-in `fetch` (available in Node 18+). No additional dependencies are required.
88+
89+
### Example AI Verification Pattern
90+
91+
```javascript
92+
async function aiVerify(entity) {
93+
const prompt = `Review this entity for accuracy:
94+
Title: ${entity.title}
95+
Content: ${entity._body}
96+
97+
Check for outdated facts, broken URLs, and superseded standards.
98+
Respond with JSON: { "status": "current"|"needs_review", "issues": [] }`;
99+
100+
const response = await fetch(process.env.AI_API_URL, {
101+
method: 'POST',
102+
headers: {
103+
'Content-Type': 'application/json',
104+
'Authorization': `Bearer ${process.env.AI_API_KEY}`
105+
},
106+
body: JSON.stringify({ prompt, max_tokens: 500 })
107+
});
108+
return response.json();
109+
}
110+
```
111+
112+
This can be integrated into the weekly GitHub Actions workflow by adding the API credentials as repository secrets and updating the workflow step to pass them as environment variables.

0 commit comments

Comments
 (0)