Skip to content

Commit 1de90e9

Browse files
committed
Release v1.0.2 hardening updates
1 parent 0acbfad commit 1de90e9

59 files changed

Lines changed: 375 additions & 125 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
guide-path: /.well-known/assistant-guide.txt
2-
guide-version: 1.0.0
3-
guide-sha256: dd3912efc5225ba7439ab95c880102ab01789d56ef5a8d8b3882ae2e0c33675d
4-
guide-bytes: 7052
2+
guide-version: 1.0.1
3+
guide-sha256: 498a0038bccfcd242a318c59311d86c91da71f96e3e8e7003727f98bd569deb6
4+
guide-bytes: 7778
55
immutable-release-url: https://github.com/snapsynapse/knowledge-as-code-template
66
profile: human-verifiable-assistant-guide
77
profile-version: 0.3.0
88
canonical-url: https://knowledge-as-code.com/.well-known/assistant-guide.txt
99
repository-url: https://github.com/snapsynapse/knowledge-as-code-template
10-
released-at: 2026-05-25T00:00:00Z
10+
released-at: 2026-06-12T00:00:00Z
1111
changelog-url: https://github.com/snapsynapse/knowledge-as-code-template/blob/main/CHANGELOG.md

‎.well-known/assistant-guide.txt‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ Assistant Guide: Knowledge-as-Code template local verification
44
identifier: assistant-guide
55
profile: human-verifiable-assistant-guide
66
profile-version: 0.3.0
7-
guide-version: 1.0.0
7+
guide-version: 1.0.1
88
applies-to: knowledge-as-code-template
99
canonical-url: https://knowledge-as-code.com/.well-known/assistant-guide.txt
1010
repository-url: https://github.com/snapsynapse/knowledge-as-code-template
1111
source-path: /.well-known/assistant-guide.txt
1212
manifest-url: https://knowledge-as-code.com/.well-known/assistant-guide-manifest.txt
13-
last-reviewed: 2026-05-25
13+
last-reviewed: 2026-06-12
1414
reviewed-by: PAICE.work PBC
1515
status: active
1616
recommended-verifier: https://guidecheck.org/verify
@@ -64,6 +64,19 @@ The task uses local Node.js and shell scripts already present in the repository.
6464
Build actions regenerate tracked static artifacts under docs/ and demo/.
6565
Validation actions inspect local files and do not require network access.
6666

67+
Repository-specific constraints
68+
Entity filenames, mapping IDs, and mapping references must be lowercase slug
69+
IDs using only a-z, 0-9, and single hyphens. The filename without .md is the
70+
entity ID. Do not create data files with spaces, underscores, uppercase
71+
letters, punctuation, path separators, or unsafe URL characters in the ID.
72+
73+
Generated-output handling
74+
docs/ and demo/ are generated outputs in this repository. Do not hand-edit
75+
generated HTML, JSON API files, sitemap, agents.json, llms.txt, RSS, or copied
76+
assets. Update source data, project.yml, or scripts first, then regenerate the
77+
outputs. The build script cleans only generator-owned paths in the selected
78+
output directory and refuses unsafe output directories.
79+
6780
Actions
6881

6982
[action]

‎CHANGELOG.md‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,23 @@ pattern.
1313
1414
## [Unreleased]
1515

16+
## [1.0.2] — 2026-06-12
17+
18+
### Added
19+
- Added eval coverage for unsafe output directories, stale generated-output cleanup, unsafe entity IDs, status badge contrast, generated URL path stability, and JSON-RPC notification silence.
20+
- Documented slug-safe entity IDs, generated-output cleanup behavior, and MCP notification semantics across human docs and agent-facing guides.
21+
22+
### Changed
23+
- Bumped the GuideCheck assistant guide to `1.0.1` with repository-specific generated-output and slug-ID constraints.
24+
- Regenerated tracked `docs/` and `demo/` outputs after status badge contrast hardening.
25+
1626
### Fixed
27+
- Refused unsafe build output directories before cleanup and removed stale files only under generator-owned output paths.
28+
- Rejected unsafe filenames, mapping IDs, and mapping references during validation and build.
29+
- Encoded generated URL path segments after strict ID validation.
30+
- Computed status badge foreground colors from background luminance instead of hard-coding theme text colors.
31+
- Stopped returning JSON-RPC errors for notifications that omit `id`.
32+
- Refreshed content-provenance hashes after intentional README, guide, and tooling updates.
1733
- Made `scripts/build.js` output reproducible by sourcing generated-output timestamps (`meta.generated`, `agents.json` `last_updated`, sitemap `lastmod`, RSS `lastBuildDate`) from the freshest date in the data rather than wall-clock time. The "generated outputs are current" CI gate could never pass before, because each rebuild stamped a new `new Date()` into committed artifacts.
1834

1935
## [1.0.1] — 2026-05-30
@@ -136,7 +152,8 @@ canonical pattern definition at <https://knowledge-as-code.com/>.
136152
site generator, `scripts/validate.js` cross-reference linter, example data for ISO 27001 and
137153
NIST CSF, dark/light themed static site output, JSON API, bridge pages, `CNAME` fixture.
138154

139-
[Unreleased]: https://github.com/snapsynapse/knowledge-as-code-template/compare/v1.0.1...HEAD
155+
[Unreleased]: https://github.com/snapsynapse/knowledge-as-code-template/compare/v1.0.2...HEAD
156+
[1.0.2]: https://github.com/snapsynapse/knowledge-as-code-template/releases/tag/v1.0.2
140157
[1.0.1]: https://github.com/snapsynapse/knowledge-as-code-template/releases/tag/v1.0.1
141158
[1.0.0]: https://github.com/snapsynapse/knowledge-as-code-template/releases/tag/v1.0.0
142159
[0.4.0]: https://github.com/snapsynapse/knowledge-as-code-template/releases/tag/v0.4.0

‎MANIFEST.yaml‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
# - This file itself
2828

2929
bundle: knowledge-as-code-template
30-
bundle_version: 1.0.1
31-
bundle_date: 2026-05-30
30+
bundle_version: 1.0.2
31+
bundle_date: 2026-06-12
3232
description: >
3333
Knowledge as Code starter template — scaffolds a KaC site with
3434
Primary/Container/Authority/Secondary entities, gist ontology binding,
@@ -47,22 +47,22 @@ files:
4747

4848
- path: README.md
4949
role: protocol
50-
hash: sha256:61811994959fe4f8d52f1802593d79957527fa890f3573aeea1f3e96f0105c13
50+
hash: sha256:d17355f0cb940e4d9423b5931c1035df36f675df08fe70b026aa8e82e46b5593
5151
note: Template overview
5252

5353
- path: assistant-guide.txt
5454
role: guidecheck
55-
hash: sha256:dd3912efc5225ba7439ab95c880102ab01789d56ef5a8d8b3882ae2e0c33675d
55+
hash: sha256:498a0038bccfcd242a318c59311d86c91da71f96e3e8e7003727f98bd569deb6
5656
note: Repository-root GuideCheck assistant guide copy
5757

5858
- path: .well-known/assistant-guide.txt
5959
role: guidecheck
60-
hash: sha256:dd3912efc5225ba7439ab95c880102ab01789d56ef5a8d8b3882ae2e0c33675d
60+
hash: sha256:498a0038bccfcd242a318c59311d86c91da71f96e3e8e7003727f98bd569deb6
6161
note: Canonical GuideCheck assistant guide
6262

6363
- path: .well-known/assistant-guide-manifest.txt
6464
role: guidecheck
65-
hash: sha256:6ab8b1b2b9f72be25be2de00c2081cc7d5250531adb859db410b92645f5c8d82
65+
hash: sha256:f9294ffd17a69a09116d4dcb3638b1c7d652952960b624ba3d98eacb973218c8
6666
note: GuideCheck sidecar manifest
6767

6868
- path: project.yml
@@ -72,12 +72,12 @@ files:
7272

7373
- path: scripts/build.js
7474
role: tooling
75-
hash: sha256:eaf0e8aed6fc03f43ac3ead2df3acfa7ac7b392bbd055a11e63540e9fe9cf017
75+
hash: sha256:bcbdbb8d093fc9fe48e0b09f44c7097e333477e92d3c1193bd4606820cdfa83d
7676
note: Static site generator
7777

7878
- path: scripts/validate.js
7979
role: tooling
80-
hash: sha256:d1da14cd8659bbfeaa6b6402464597b200c40c656be72cb3b2c6ffe5edebf284
80+
hash: sha256:f7fba6ac85c40a0a46516739128154f754e3f83d25a8e5b79ef6625ff43ae6fc
8181
note: Cross-reference validator
8282

8383
- path: scripts/verify.js

‎PUBLISH-MCP.md‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@ This guide captures the exact prep work, in the order it has to happen.
1010

1111
- Your fork has its own canonical `project.yml`, real data under `data/`, and a
1212
working build (`node scripts/build.js` succeeds).
13+
- Entity filenames, mapping IDs, and mapping references are lowercase slug IDs
14+
using only `a-z`, `0-9`, and single hyphens. Run `node scripts/validate.js`
15+
before publishing so unsafe IDs are rejected before they become MCP-visible
16+
data.
1317
- `node mcp-server.js` works locally — pipe `{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}`
1418
into it and you should get back your tools.
15-
- An npm account ([npmjs.com](https://www.npmjs.com/signup)) with 2FA enabled.
19+
- An npm account ([npmjs.com](https://npmjs.com/signup)) with 2FA enabled.
1620
- A GitHub account that matches the org/user owning the repo.
1721

1822
## Step 1 — choose a package name
@@ -100,6 +104,10 @@ echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | node mcp-ser
100104

101105
You should get back your tools.
102106

107+
The server follows JSON-RPC notification semantics. Messages without an `id`
108+
are notifications and do not receive responses, including unknown-method
109+
notifications.
110+
103111
## Step 4 — publish to npm
104112

105113
Authenticate (a one-time setup; uses your browser):
@@ -186,7 +194,7 @@ After any data update or server change:
186194
**npm:** if you use a "Publish" classic token, every publish requires a 2FA
187195
browser flow. If you use an "Automation" token, it bypasses 2FA — easier for
188196
recurring publishes. Create one at
189-
[npmjs.com/settings/~/tokens](https://www.npmjs.com/settings/~/tokens).
197+
[npmjs.com/settings/~/tokens](https://npmjs.com/settings/~/tokens).
190198

191199
**mcp-publisher:** the registry uses short-lived JWTs. If your session has
192200
been idle for an hour or so, the next `mcp-publisher publish` will fail with

‎README.md‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Built examples using this template:
3131
1. **Use this template** -- on GitHub, click the green "Use this template" button (not "Clone"). This creates a new repo with no git history and no upstream connection. Cloning is fine for local exploration but won't give you a clean starting repo.
3232
2. **Edit `project.yml`** -- start with the entity names (`entities.primary.name`, `entities.container.name`, etc.) and groups. You can adjust colors and navigation later. Leave `url` until your GitHub repo is configured.
3333
3. **Replace example data** -- delete the files in `data/examples/requirements/`, `data/examples/frameworks/`, `data/examples/organizations/`, and `data/examples/mapping/index.yml`, then add your own. See [Replacing example data](#replacing-example-data) and [`data/_schema.md`](data/_schema.md) for the format.
34-
4. **Build** -- `node scripts/build.js`. A successful build prints `Build complete — N HTML pages, N JSON API files`. Check the `docs/` directory for the output, and open any HTML file in a browser to verify it looks right.
34+
4. **Build** -- `node scripts/build.js`. A successful build prints `Build complete — N HTML pages, N JSON API files`. Check the `docs/` directory for the output, and open any HTML file in a browser to verify it looks right. The build cleans generator-owned paths in the output directory before writing fresh files, so removed or renamed entities do not leave stale generated pages behind.
3535
5. **Deploy** -- choose your Pages strategy. This repo validates builds in CI, but it does not auto-deploy template forks by default. If you want automated deployment, add a Pages publish step for your repo.
3636
6. **(Optional) Publish your knowledge base as an MCP server** -- if you want anyone to install your knowledge base as an MCP-aware agent tool via `npx -y your-package`, follow [PUBLISH-MCP.md](PUBLISH-MCP.md). It walks through the package.json prep, npm publish, and Official MCP Registry submission, with the gotchas that bit us when we did this for three sibling projects.
3737

@@ -42,6 +42,7 @@ This repository intentionally tracks generated output in both `docs/` and `demo/
4242
- `docs/` is the template-default generated site output.
4343
- `demo/` is the canonical reference build used for `https://knowledge-as-code.com/demo/`.
4444
- Neither directory should be edited by hand. Regenerate them with `node scripts/build.js` or the `KAC_OUTPUT_DIR=demo KAC_SITE_URL="https://knowledge-as-code.com/demo/" node scripts/build.js` variant.
45+
- During each build, the generator removes only paths it owns in the target output directory (`api/`, `assets/`, entity/bridge page directories, and generated root files). It refuses to clean the repository root or a parent directory.
4546

4647
Template forks do not need to follow this policy. A fork can either:
4748

@@ -151,6 +152,8 @@ All domain-specific settings live in `project.yml`:
151152

152153
Generated pages normalize external URLs to `https` and bare domains. Avoid `http`, `javascript:`, and `www` in project data; unsafe protocols are dropped from generated links. Configured colors should be hex values such as `#4fc3f7`; invalid color values fall back to safe defaults.
153154

155+
Entity filenames and mapping IDs must be lowercase slug IDs: `a-z`, `0-9`, and single hyphens only, such as `access-control` or `iso-27001`. The filename without `.md` is the entity ID. Mapping references must use those same IDs. `node scripts/validate.js` and `node scripts/build.js` both reject unsafe IDs before generated HTML, filesystem paths, JSON discovery files, or MCP responses are produced.
156+
154157
## Replacing example data
155158

156159
The template ships with example data in `data/examples/` (ISO 27001, NIST CSF). To replace it with your own domain:
@@ -177,7 +180,7 @@ npm run eval
177180

178181
That runs the broader smoke/eval suite covering builds, links, API shape, parser fixtures, MCP smoke, and documentation consistency.
179182

180-
The build script looks for data in `data/examples/` first, then `data/`. You can rename `data/examples/` to `data/` if you prefer a flatter structure.
183+
The build script looks for data in `data/examples/` first, then `data/`. You can rename `data/examples/` to `data/` if you prefer a flatter structure. Keep filenames slug-safe because the generated site, JSON API, MCP tools, search index, sitemap, and agents.json all use the filename-derived IDs.
181184

182185
**What to keep:** Only `data/` contents and `project.yml` values need replacing. Do not delete `scripts/`, `.github/workflows/`, `mcp-server.js`, `mcp.json`, or `package.json` — these are the template engine and deployment config.
183186

‎assistant-guide.txt‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ Assistant Guide: Knowledge-as-Code template local verification
44
identifier: assistant-guide
55
profile: human-verifiable-assistant-guide
66
profile-version: 0.3.0
7-
guide-version: 1.0.0
7+
guide-version: 1.0.1
88
applies-to: knowledge-as-code-template
99
canonical-url: https://knowledge-as-code.com/.well-known/assistant-guide.txt
1010
repository-url: https://github.com/snapsynapse/knowledge-as-code-template
1111
source-path: /.well-known/assistant-guide.txt
1212
manifest-url: https://knowledge-as-code.com/.well-known/assistant-guide-manifest.txt
13-
last-reviewed: 2026-05-25
13+
last-reviewed: 2026-06-12
1414
reviewed-by: PAICE.work PBC
1515
status: active
1616
recommended-verifier: https://guidecheck.org/verify
@@ -64,6 +64,19 @@ The task uses local Node.js and shell scripts already present in the repository.
6464
Build actions regenerate tracked static artifacts under docs/ and demo/.
6565
Validation actions inspect local files and do not require network access.
6666

67+
Repository-specific constraints
68+
Entity filenames, mapping IDs, and mapping references must be lowercase slug
69+
IDs using only a-z, 0-9, and single hyphens. The filename without .md is the
70+
entity ID. Do not create data files with spaces, underscores, uppercase
71+
letters, punctuation, path separators, or unsafe URL characters in the ID.
72+
73+
Generated-output handling
74+
docs/ and demo/ are generated outputs in this repository. Do not hand-edit
75+
generated HTML, JSON API files, sitemap, agents.json, llms.txt, RSS, or copied
76+
assets. Update source data, project.yml, or scripts first, then regenerate the
77+
outputs. The build script cleans only generator-owned paths in the selected
78+
output directory and refuses unsafe output directories.
79+
6780
Actions
6881

6982
[action]

‎data/_schema.md‎

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ This file documents the file format for each entity type. All data files use YAM
88

99
**Example:** `requirements/access-control.md`
1010

11+
The filename without `.md` is the entity ID. It must be a lowercase slug using
12+
only `a-z`, `0-9`, and single hyphens, such as `access-control`.
13+
1114
```yaml
1215
---
1316
id: access-control # Required. Kebab-case identifier, must match filename
@@ -43,6 +46,9 @@ One paragraph describing the requirement.
4346

4447
**Example:** `frameworks/iso-27001.md`
4548

49+
The filename without `.md` is the container ID. It must be a lowercase slug
50+
using only `a-z`, `0-9`, and single hyphens, such as `iso-27001`.
51+
4652
```yaml
4753
---
4854
name: ISO 27001 # Required. Human-readable name
@@ -120,6 +126,9 @@ last_verified: 2026-03-25 # Optional. Date of last verification check
120126

121127
**Example:** `organizations/iso.md`
122128

129+
The filename without `.md` is the authority ID. It must be a lowercase slug
130+
using only `a-z`, `0-9`, and single hyphens, such as `iso`.
131+
123132
```yaml
124133
---
125134
id: iso # Required. Kebab-case identifier
@@ -145,7 +154,7 @@ The heading name should match your container entity's plural name (e.g., "Regula
145154

146155
**Path:** `data/examples/mapping/index.yml` (configured in `project.yml` as `mapping.file`)
147156

148-
The mapping file connects containers to primaries through secondary (provision) entities:
157+
The mapping file connects containers to primaries through secondary (provision) entities. Mapping IDs and every entity reference must use the same lowercase slug format as filenames.
149158

150159
```yaml
151160
- id: iso-27001-access-control # Required. Unique provision ID (kebab-case)
@@ -163,9 +172,11 @@ The `regulation` field should use your container entity name from config (the fi
163172

164173
## File naming
165174

166-
- All files use kebab-case: `access-control.md`, `iso-27001.md`
167-
- The filename (without `.md`) is used as the entity ID for primaries and authorities
168-
- Container files use the `name` frontmatter field (lowercased, spaces replaced with hyphens) as their ID
175+
- All files use lowercase slug filenames: `access-control.md`, `iso-27001.md`
176+
- Slugs may contain only `a-z`, `0-9`, and single hyphens
177+
- The filename without `.md` is used as the entity ID for primaries, containers, and authorities
178+
- Mapping IDs and mapping references must use the same slug format
179+
- `node scripts/validate.js` and `node scripts/build.js` reject unsafe IDs
169180

170181
## URL and style safety
171182

@@ -175,6 +186,7 @@ The `regulation` field should use your container entity name from config (the fi
175186
- Group, status, and theme colors in `project.yml` should be hex colors. Invalid values fall back to safe defaults.
176187
- Group and status names are normalized before use as CSS class names.
177188
- Generated comparison-page labels are escaped before client-side insertion.
189+
- Generated URL path segments are derived only from validated entity IDs.
178190

179191
## Adding new entities
180192

‎demo/404.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
.status-badge.active { background: #4caf50; color: #000; }
2323
:is(html, body).light-mode .status-badge.active { background: #1b7d1b; color: #fff; }
2424
.status-badge.draft { background: #ff9800; color: #000; }
25-
:is(html, body).light-mode .status-badge.draft { background: #e65100; color: #fff; }
25+
:is(html, body).light-mode .status-badge.draft { background: #e65100; color: #000; }
2626
.status-badge.deprecated { background: #607d8b; color: #000; }
2727
:is(html, body).light-mode .status-badge.deprecated { background: #455a64; color: #fff; }
2828
:root { --accent: #4fc3f7; }

‎demo/about.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
.status-badge.active { background: #4caf50; color: #000; }
2424
:is(html, body).light-mode .status-badge.active { background: #1b7d1b; color: #fff; }
2525
.status-badge.draft { background: #ff9800; color: #000; }
26-
:is(html, body).light-mode .status-badge.draft { background: #e65100; color: #fff; }
26+
:is(html, body).light-mode .status-badge.draft { background: #e65100; color: #000; }
2727
.status-badge.deprecated { background: #607d8b; color: #000; }
2828
:is(html, body).light-mode .status-badge.deprecated { background: #455a64; color: #fff; }
2929
:root { --accent: #4fc3f7; }

0 commit comments

Comments
 (0)