Skip to content
This repository was archived by the owner on Jun 16, 2026. It is now read-only.

Commit 39d1b88

Browse files
mcp-tool-shopclaude
andcommitted
lock: Role OS lockdown — dispatch truth seam
Add repo-specific context files and protect-dispatch-truth workflow with 8 reject criteria. AILOADOUT-001 proving packet passed clean: 7 invariants traced to source, 3 liar-paths rejected, 4 design tradeoffs named. AILOADOUT-002 queued for malformed layer signaling. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5966722 commit 39d1b88

5 files changed

Lines changed: 210 additions & 25 deletions

File tree

.claude/context/brand-rules.md

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,37 @@
11
# Brand Rules — @mcptoolshop/ai-loadout
22

33
## Tone
4-
Not yet defined (init-only pass).
4+
5+
Precise and mechanical. ai-loadout is a dispatch table, not an advisor. It scores, filters, and reports. It does not recommend, suggest, or infer.
56

67
## Domain language
7-
Not yet defined (init-only pass).
88

9-
## Notes
10-
This repo was initialized during breadth pass. Brand rules will be filled during lock.
9+
| Term | Meaning | Must not be confused with |
10+
|------|---------|--------------------------|
11+
| LoadoutEntry | A declared knowledge payload with ID, keywords, patterns, priority, and token estimate | A "suggestion" or "resource" |
12+
| LoadPlan | The structured output of planLoad: preload + onDemand + manual with provenance | A "recommendation" or "context plan" |
13+
| Score | Keyword ratio + pattern bonus (0-1), deterministic | A "relevance estimate" or "confidence" |
14+
| MIN_SCORE | Hard threshold at 0.1; entries below are excluded | A "soft cutoff" or "guidance threshold" |
15+
| Layer | One of 4 canonical locations (global/org/project/session) | A "source" or "config level" |
16+
| Override | Later layer replacing earlier layer's version of same entry ID | A "merge" or "combination" |
17+
| Provenance | Mapping from entry ID to the layer that provided the winning version | "Origin" in a vague sense |
18+
| Conflict | Same entry ID defined in multiple layers — always resolved by "later wins" | An "error" or "inconsistency" |
19+
| Dead entry | An entry that never matches any observed task | An "unused feature" |
20+
21+
## Enforcement bans
22+
23+
### Language that must never appear in ai-loadout output or docs
24+
25+
- "recommended" / "suggested" / "best match" (the system scores and filters, it does not recommend)
26+
- "confident" / "likely" / "probably relevant" (scores are deterministic ratios, not confidence)
27+
- "intelligent" / "smart" / "adaptive" (matching is keyword overlap, not inference)
28+
- "understands" / "knows about" (routing to a payload is not comprehension)
29+
- "approximately matched" / "close enough" (below MIN_SCORE means excluded, period)
30+
31+
### Contamination risks
32+
33+
1. **Relevance inflation** — if reason strings start implying deeper understanding than keyword overlap, the dispatch truth is compromised
34+
2. **Capability conflation** — routing to an entry is not the same as the agent having that capability; language must never blur this
35+
3. **Soft-match creep** — any weakening of MIN_SCORE or introduction of "partial match" zones would destroy the hard-filter contract
36+
4. **Provenance hiding** — if override chains become invisible to operators, layer trust is undermined
37+
5. **Freshness pretense** — the system matches against declared keywords; it does not know if payloads are current
Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,33 @@
11
# Current Priorities — @mcptoolshop/ai-loadout
22

33
## Status
4-
Initialized (Role OS breadth pass 2026-03-24). Not yet locked.
4+
5+
Locked (Role OS lockdown 2026-03-24). Primary seam: knowledge dispatch correctness.
56

67
## Classification
7-
lock candidate later
88

9-
## Highest-risk seam
10-
Matcher correctness — knowledge dispatch must resolve to the right context for the right agent
9+
Lock candidate → locked.
10+
11+
## Seam family
12+
13+
Dispatch/routing truth — same family as any system where the selector claims correctness about which path/entry/payload was chosen.
14+
15+
## Must-preserve invariants (9)
16+
17+
1. **Scoring determinism** — same task + same index = same MatchResult[] (same scores, order, reasons). No randomness, no heuristics.
18+
2. **MIN_SCORE hard filter** — domain entries scoring below 0.1 are excluded. No soft-match zone. No "close enough."
19+
3. **Core always included** — priority="core" entries always get score 1.0 and mode "eager". No exceptions.
20+
4. **Manual never auto-included** — priority="manual" entries always get score 0. Explicit lookup only.
21+
5. **Layer order immutability** — global → org → project → session. Later wins. This order is a contract, not a default.
22+
6. **Override transparency** — every layer override is recorded as a conflict with resolution and provenance. The operator can always see which layer won.
23+
7. **Reason string machine-readability** — every MatchResult includes a reason string that names the matched keywords and/or patterns. This is the dispatch truth surface.
24+
8. **Pure-function core** — match, merge, validate, analysis modules have zero I/O, zero side effects. I/O is isolated to resolve/runtime/usage.
25+
9. **Zero dependencies in matching** — no LLM, no network, no external service. Dispatch is self-contained.
26+
27+
## Banned detours
1128

12-
## Must-preserve invariants
13-
Not yet documented (init-only pass — invariants will be defined during lock).
29+
- Adding "fuzzy matching" or "semantic similarity" to the scoring engine (breaks determinism and keyword grounding)
30+
- Introducing "priority between domain entries" beyond score ranking (scores already rank; adding tiers within domain would obscure the formula)
31+
- Making MIN_SCORE configurable per-entry or per-layer (destroys the single-threshold contract)
32+
- Adding "auto-refresh" for stale indexes (the system routes, consumers refresh)
33+
- Introducing LLM-based matching ("is this entry relevant?") — that's a different product

.claude/context/product-brief.md

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,35 @@
11
# Product Brief — @mcptoolshop/ai-loadout
22

33
## What this is
4-
Context-aware knowledge router for AI agents — dispatch table, matcher, hierarchical resolver
4+
5+
Context-aware knowledge router for AI agents. Maintains a dispatch table of knowledge payloads, matches them against task descriptions using deterministic keyword/pattern scoring, resolves across a 4-layer hierarchy (global → org → project → session), and returns a LoadPlan that separates preload (core), on-demand (matched domain), and manual (everything else) entries — with provenance, conflict tracking, and observability.
56

67
## Type
7-
CLI + library
8+
9+
CLI + library (pure functions for matching/merging/validation, filesystem I/O only in resolve/runtime layers)
810

911
## Core value
10-
Context-aware knowledge router for AI agents — dispatch table, matcher, hierarchical resolver
1112

12-
## Non-goals
13-
- Not documented yet (init-only pass — context will be deepened during lock)
13+
Dispatch is deterministic, explainable, and observable. Every match result includes a score, matched keywords/patterns, a reason string, and provenance showing which layer the entry came from. The system never guesses — it scores, thresholds, and reports.
14+
15+
## What it is not
16+
17+
- Not a recommender — it matches against declared keywords and patterns, not inferred relevance
18+
- Not a capability evaluator — it routes to payloads, it does not assess whether payloads are accurate or current
19+
- Not an LLM — zero model dependency, zero heuristics, zero randomness in matching
20+
- Not a filesystem manager — consumers are responsible for reading payload files; ai-loadout routes to them
21+
- Not a quality filter — a matched entry might be stale; ai-loadout's job is to match correctly, not to evaluate freshness
22+
23+
## Anti-thesis (7 statements)
24+
25+
1. Must never become a vibes-based router — dispatch is keyword/pattern scoring, not "feels relevant"
26+
2. Must never be a "best effort" selector that hides uncertainty — if no entry matches, the result is an empty onDemand list, not a guess
27+
3. Must never be a capability fantasy layer — the system routes to declared payloads, it does not claim those payloads are true, current, or sufficient
28+
4. Must never be a silent fallback broker — when a layer is missing, malformed, or overridden, the resolver reports it in searched/conflicts, not silently
29+
5. Must never become a generic recommender with no dispatch truth — every match must have a score, matched keywords, and a reason
30+
6. Must never imply a tool/model knows something it was never actually given — routing to a payload is not the same as the agent having read it
31+
7. Must never soften the MIN_SCORE threshold into a "soft match" zone — below 0.1 means excluded, not "maybe"
1432

15-
## Anti-thesis
16-
- Not documented yet (init-only pass)
33+
## Highest-risk seam
1734

18-
## Highest-risk seam (identified, not yet locked)
19-
Matcher correctness — knowledge dispatch must resolve to the right context for the right agent
35+
**Knowledge dispatch correctness** — the boundary where the system claims the right loadout was selected. The liar-paths are: wrong match looks right (keywords overlap ambiguously), correct entry excluded by threshold, layer override silently replaces a better version, or stale index routes to outdated payloads.

.claude/context/repo-map.md

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,81 @@
11
# Repo Map — @mcptoolshop/ai-loadout
22

33
## Stack
4-
- See package.json for full dependency list
54

6-
## Primary seam (identified, not yet locked)
7-
Matcher correctness — knowledge dispatch must resolve to the right context for the right agent
5+
- TypeScript (Node.js), zero runtime dependencies
6+
- 12 source modules, ~2,800 lines
7+
- Node built-in test runner (8 test files)
8+
- Single entry: CLI (`bin/ai-loadout`)
9+
- Library exports for programmatic use
810

9-
## Validation law
10-
- See package.json scripts for test/verify commands
11-
- Init-only pass — detailed repo map will be written during lock
11+
## Module architecture
12+
13+
| Layer | Modules | Purpose | I/O? |
14+
|-------|---------|---------|------|
15+
| Types | `types.ts` | LoadoutEntry, LoadoutIndex, MatchResult, MergedIndex, Budget, etc. | No |
16+
| Parsing | `frontmatter.ts` | YAML-like frontmatter extraction from markdown payloads | No |
17+
| Validation | `validate.ts` | Structural validation of indexes (duplicate IDs, missing fields, budget) | No |
18+
| Matching | `match.ts` | Deterministic keyword/pattern scoring against task descriptions | No |
19+
| Merging | `merge.ts` | Deterministic layer merge with conflict tracking and provenance | No |
20+
| Tokens | `tokens.ts` | Token estimation (chars / 4 heuristic) | No |
21+
| Analysis | `analysis.ts` | Dead entry detection, keyword overlap, budget breakdown | No |
22+
| Resolution | `resolve.ts` | Layer discovery (4 canonical locations), file loading, merge orchestration | Yes (reads) |
23+
| Runtime | `runtime.ts` | Agent API: planLoad, recordLoad, manualLookup | Yes (reads + appends) |
24+
| Usage | `usage.ts` | Append-only JSONL event logging, usage summarization | Yes (reads + appends) |
25+
| CLI | `cli.ts` | Command router (resolve, explain, usage, dead, overlaps, budget) | Yes |
26+
| Exports | `index.ts` | Public API surface | No |
27+
28+
**Key architectural property:** All core logic (match, merge, validate, analysis) is pure functions. No filesystem, no network, no side effects. I/O is isolated to resolve/runtime/usage/cli layers.
29+
30+
## Primary seam: Knowledge dispatch correctness
31+
32+
### Dispatch decision flow
33+
34+
```
35+
planLoad(task)
36+
├─ resolveLoadout()
37+
│ ├─ discoverLayers(): check global, org, project, session in fixed order
38+
│ │ └─ missing/malformed layers: silently skipped, recorded in searched[]
39+
│ └─ mergeIndexes(): later layer overrides earlier for same entry ID
40+
│ └─ all overrides tracked as conflicts with resolution: "override"
41+
42+
├─ matchLoadout(task, merged.index)
43+
│ ├─ tokenize(task): lowercase, strip non-alphanum, split, discard ≤1 char
44+
│ ├─ scoreEntry() per entry:
45+
│ │ ├─ core: score=1.0 (always included)
46+
│ │ ├─ manual: score=0 (never auto-included)
47+
│ │ └─ domain: (matchedKeywords/totalKeywords) + patternBonus(0.2)
48+
│ ├─ filter: score ≥ MIN_SCORE (0.1)
49+
│ └─ sort: score desc, then tokens_est asc
50+
51+
└─ separate into: preload (core) / onDemand (domain ≥ 0.1) / manual (rest)
52+
```
53+
54+
### Contract surfaces that must stay synchronized
55+
56+
| Surface | Location | What it governs |
57+
|---------|----------|-----------------|
58+
| MIN_SCORE threshold | `match.ts:17` | Hard boundary: domain entries below 0.1 are excluded |
59+
| Scoring formula | `match.ts:66-77` | keyword ratio + pattern bonus (0.2), capped at 1.0 |
60+
| Layer order | `resolve.ts:93-108` | global → org → project → session, fixed |
61+
| Override rule | `merge.ts` | Later layer wins for same entry ID, always |
62+
| Reason strings | `match.ts:104-110` | Machine-readable match explanation per entry |
63+
| Provenance | `merge.ts``runtime.ts` | Entry ID → source layer name mapping |
64+
| Conflict tracking | `merge.ts` | Every override recorded with layers and resolution |
65+
66+
### Liar-path surfaces (where wrong dispatch could look right)
67+
68+
| Risk | Where | Observable? |
69+
|------|-------|-------------|
70+
| Ambiguous keywords → wrong entry loads | `match.ts` scoring | Yes: `overlaps` command detects shared keywords |
71+
| Correct entry excluded by threshold | `match.ts:97` MIN_SCORE filter | No recovery — intentional hard filter |
72+
| Layer override silently replaces better version | `merge.ts` override logic | Yes: `explain` command shows full override chain |
73+
| Malformed layer silently skipped | `resolve.ts:122-125` catch block | Partially: marked as not found in searched[], but not distinguishable from genuinely missing |
74+
| Stale index routes to outdated payloads | Outside system scope | Yes: `dead` + `usage` commands detect drift over time |
75+
| Token estimate wildly off | `tokens.ts` chars/4 heuristic | Yes: `budget` command compares estimated vs observed |
76+
77+
## Validation
78+
79+
- `npm test` — 8 test files via Node `--test`
80+
- `npm run build` — TypeScript compilation
81+
- Key tests: `match.test.ts` (scoring determinism, threshold enforcement), `resolve.test.ts` (layer discovery, merge, conflict tracking)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Workflow: Protect Dispatch Truth
2+
3+
**Repo:** @mcptoolshop/ai-loadout
4+
**Seam:** Knowledge dispatch correctness — the boundary where the system claims the right loadout was selected for a given task.
5+
6+
## What this workflow protects
7+
8+
The contract that dispatch decisions are deterministic, explainable, and grounded in declared keywords/patterns — and that the system never claims more about a match than the scoring formula actually computed.
9+
10+
## Automatic reject criteria (8)
11+
12+
A proposed change MUST be rejected if it:
13+
14+
1. **Makes dispatch reasoning less explicit** — removes or weakens reason strings, provenance tracking, or conflict reporting so the operator cannot trace why an entry was selected
15+
2. **Weakens deterministic selection rules** — introduces randomness, heuristics, LLM-based scoring, or environment-dependent behavior into the matching engine
16+
3. **Blurs primary selection with fallback/degraded selection** — frames an empty onDemand result as though entries were found, or hides that layers were missing/malformed
17+
4. **Invents or overstates capability/knowledge access** — implies that routing to a payload means the agent has that knowledge, or that a matched entry is accurate/current
18+
5. **Allows stale capability assumptions to masquerade as current truth** — weakens observability tools (dead entry detection, usage tracking, budget analysis) that catch staleness
19+
6. **Softens failure or mismatch classification into advisory mush** — converts the MIN_SCORE hard filter into a soft boundary, introduces "partial match" zones, or makes excluded entries appear as weak recommendations
20+
7. **Changes output semantics without synchronized docs/tests/context updates** — modifies LoadPlan structure, reason string format, provenance shape, or conflict reporting without updating all consumers
21+
8. **Makes human-facing reassurance stronger while leaving machine-facing semantics unchanged** — e.g., CLI output says "good coverage" while LoadPlan shows most entries in manual (org-wide reassurance drift rule)
22+
23+
## The key question this workflow answers
24+
25+
**When ai-loadout chooses a loadout, what must it say about why, and what must it never imply about capability or knowledge access?**
26+
27+
### Must say
28+
- Score: the exact keyword ratio + pattern bonus (0-1)
29+
- Matched keywords: which declared keywords were found in the task
30+
- Matched patterns: which declared patterns triggered
31+
- Reason: human-readable explanation combining the above
32+
- Mode: eager (core), lazy (domain match), or manual (explicit lookup only)
33+
- Provenance: which layer provided the winning version of each entry
34+
- Conflicts: which entries were overridden and by which layers
35+
36+
### Must never imply
37+
- That a matched entry means the agent has that knowledge (routing ≠ loading ≠ comprehension)
38+
- That a high score means high relevance (score is keyword overlap ratio, not semantic relevance)
39+
- That an entry's declared keywords are current (the system matches against declarations, not reality)
40+
- That missing layers are errors (most setups only have project-level; missing layers are normal)
41+
- That an empty onDemand list means no relevant knowledge exists (it means no declared entry matched — the knowledge might exist but not be indexed)
42+
- That a conflict was resolved "correctly" (later-wins is a rule, not a judgment)
43+
44+
## When to re-prove
45+
46+
Re-prove this workflow when:
47+
- The scoring formula changes (keyword weighting, pattern bonus, threshold)
48+
- The layer discovery or merge algorithm changes
49+
- MIN_SCORE value changes
50+
- New match modes are added beyond eager/lazy/manual
51+
- Reason string format changes
52+
- The LoadPlan output shape changes

0 commit comments

Comments
 (0)