@vectros-ai/blueprints 0.5.0 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +67 -0
- package/README.md +21 -2
- package/dist/index.d.mts +152 -15
- package/dist/index.d.ts +152 -15
- package/dist/index.js +748 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +748 -2
- package/dist/index.mjs.map +1 -1
- package/guides/agentic-sdlc.md +238 -0
- package/package.json +3 -1
- package/prompts/agentic-sdlc-agent.md +127 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# Guide — the `agentic-sdlc` blueprint
|
|
2
|
+
|
|
3
|
+
`agentic-sdlc` is a bundled blueprint: a **whole-SDLC system of record**
|
|
4
|
+
for an AI development team. It provisions **nine schemas, split by content vs
|
|
5
|
+
structure** — `decision` (ADRs), `design`, `reference`, `runbook`, and
|
|
6
|
+
`postmortem` as **documents** (the markdown body is the artifact); `control`,
|
|
7
|
+
`convention`, `gotcha`, and `term` (glossary) as **records** (the typed fields are
|
|
8
|
+
the artifact) — linked into a **cross-surface knowledge graph** and recalled by
|
|
9
|
+
hybrid search + grounded `rag_ask`. This guide takes you from bootstrap to a
|
|
10
|
+
populated, queryable KB, and to wiring an agent to use it day-to-day.
|
|
11
|
+
|
|
12
|
+
> Companion: [`prompts/agentic-sdlc-agent.md`](../prompts/agentic-sdlc-agent.md) —
|
|
13
|
+
> the drop-in agent orientation prompt (the recall-before-acting / capture-after
|
|
14
|
+
> loop). Apply this guide to stand the KB up; apply that prompt to make an agent
|
|
15
|
+
> use it.
|
|
16
|
+
|
|
17
|
+
## 1. What you get
|
|
18
|
+
|
|
19
|
+
- **9 schemas, content vs structure.** The prose artifacts — `decision` (ADR),
|
|
20
|
+
`design`, `reference`, `runbook`, `postmortem` — are **documents** (the markdown
|
|
21
|
+
body is searched + answered over). The structured artifacts — `control`,
|
|
22
|
+
`convention`, `gotcha`, `term` — are **records** (typed fields, exact-queryable).
|
|
23
|
+
Every item has a stable `externalId`, so re-ingesting never duplicates: an
|
|
24
|
+
unchanged item is returned as-is, and re-ingesting **edited** source with
|
|
25
|
+
`upsert: true` overwrites it in place — the KB is *rebuildable* and *syncable*.
|
|
26
|
+
- **A cross-surface knowledge graph** — typed `reference` edges where **records
|
|
27
|
+
point at documents** (`control.verifiedBy` → the `runbook` that proves it;
|
|
28
|
+
`convention.establishedBy` / `term.relatedDecision` → the `decision` behind them)
|
|
29
|
+
and **documents point at documents** (`decision.supersedes`,
|
|
30
|
+
`design.relatedDecision`, `runbook.bornFrom` → a `postmortem`). Provenance is
|
|
31
|
+
navigable, not just searchable.
|
|
32
|
+
- **A least-privilege key** — `records:r/c/u`, `search:r`, `schemas:r`,
|
|
33
|
+
`inference:r`, `documents:r/c`, `folders:r/c`. No delete: knowledge is
|
|
34
|
+
superseded/retired via a status flip, so the audit trail stays intact.
|
|
35
|
+
- **An `editor` role for you, the human** — the same data-plane scope as the key,
|
|
36
|
+
ready to bind to your user so you can browse and curate the KB in the app (see
|
|
37
|
+
"Browse it as yourself" below).
|
|
38
|
+
- **Range/sort on every artifact's date**, a governance `control` that records its
|
|
39
|
+
own evidence, a `convention` with distinct rule/why/howToApply fields, and a
|
|
40
|
+
glossary `term` with a `unique` exact-lookup.
|
|
41
|
+
|
|
42
|
+
## 2. Quickstart — install, sign in, provision
|
|
43
|
+
|
|
44
|
+
Install the public CLI, sign in once (browser), and provision the context + the nine
|
|
45
|
+
schemas + a scoped key (and wire your MCP client). `production` is the default
|
|
46
|
+
environment — add `--env staging` only to target staging.
|
|
47
|
+
|
|
48
|
+
**Bash (macOS / Linux / Git Bash):**
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm i -g @vectros-ai/cli
|
|
52
|
+
vectros login # one-time, browser sign-in
|
|
53
|
+
vectros bootstrap --blueprint agentic-sdlc --no-seed --yes
|
|
54
|
+
vectros whoami # confirm tenant + scoped key
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**PowerShell (Windows):**
|
|
58
|
+
|
|
59
|
+
```powershell
|
|
60
|
+
npm i -g "@vectros-ai/cli"
|
|
61
|
+
vectros login # one-time, browser sign-in
|
|
62
|
+
vectros bootstrap --blueprint agentic-sdlc --no-seed --yes
|
|
63
|
+
vectros whoami
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`bootstrap` provisions the context + schemas + a least-privilege `ssk_*` (written
|
|
67
|
+
once to `~/.vectros/agentic-sdlc.key.json`) and safe-merges the Vectros MCP server
|
|
68
|
+
into your **Claude Desktop** config; use `--client code` for **Claude Code**, or
|
|
69
|
+
`--print` to emit the snippet without writing a file. Restart your MCP client to load
|
|
70
|
+
it. (Prefer not to install globally? Prefix each command with `npx -y`, e.g.
|
|
71
|
+
`npx -y @vectros-ai/cli bootstrap …` — on PowerShell quote the spec:
|
|
72
|
+
`npx -y "@vectros-ai/cli" …`.)
|
|
73
|
+
|
|
74
|
+
Add `--tenant test` to provision into the **test tenant** first (useful for a
|
|
75
|
+
dry-run before committing to your live tenant). Omit for live (the default).
|
|
76
|
+
|
|
77
|
+
### Browse it as yourself — grant your user access
|
|
78
|
+
|
|
79
|
+
`bootstrap` provisions the context and a scoped key for your **agent** (the MCP
|
|
80
|
+
server), but it does **not** join **you** — the signed-in human — to the new
|
|
81
|
+
context. So when you open the data-plane app the context switcher won't list it
|
|
82
|
+
yet: the app shows only contexts your user holds access in, and bootstrap grants
|
|
83
|
+
your user none by default. Do this once so you can browse and curate the KB
|
|
84
|
+
yourself. `bootstrap` already provisioned an **`editor`** role in the context
|
|
85
|
+
(read + write, no delete — the same data-plane scope as the agent's key); bind it
|
|
86
|
+
to your user two ways:
|
|
87
|
+
|
|
88
|
+
- **In the admin app (easiest):** go to **Access → Contexts → `agentic-sdlc` →
|
|
89
|
+
Profiles → Create profile**, pick **yourself** (users list by email), choose the
|
|
90
|
+
**`editor`** role, and save.
|
|
91
|
+
- **From the CLI:** `--principal me` resolves to your own user, so no id lookup is
|
|
92
|
+
needed:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
vectros access grant --principal me --context agentic-sdlc --role editor
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
(Prefer an explicit id? `vectros identity list --type user` lists every tenant
|
|
99
|
+
user's id + email; your principal is `usr_` + the id next to your email.) Reopen
|
|
100
|
+
the data-plane app and `agentic-sdlc` now appears in the switcher with your data.
|
|
101
|
+
|
|
102
|
+
### Seeds
|
|
103
|
+
|
|
104
|
+
This blueprint ships **without bundled seeds** — it provisions the nine schemas +
|
|
105
|
+
the scoped key, and you fill it from your own corpus (next section). So the context
|
|
106
|
+
starts clean; there's no synthetic data to remove. (If you fork a blueprint that
|
|
107
|
+
*does* ship seeds and want a clean production context, `vectros bootstrap
|
|
108
|
+
--no-seed` provisions the schemas + key and skips the seed step.)
|
|
109
|
+
|
|
110
|
+
## 3. Ingest your corpus
|
|
111
|
+
|
|
112
|
+
There are two ingest paths, by surface — both driven by the **ingest agent**
|
|
113
|
+
(point it at your source files with the
|
|
114
|
+
[orientation prompt](../prompts/agentic-sdlc-agent.md); an LLM maps your
|
|
115
|
+
semi-structured docs to the right type far better than a brittle parser, and it's
|
|
116
|
+
idempotent by `externalId`).
|
|
117
|
+
|
|
118
|
+
### Documents — the prose artifacts (ADRs, designs, references, runbooks, post-mortems)
|
|
119
|
+
|
|
120
|
+
These keep their markdown **body as-is**; the agent fills the typed metadata and
|
|
121
|
+
ingests via `document_ingest` against the matching schema:
|
|
122
|
+
|
|
123
|
+
```text
|
|
124
|
+
document_ingest:
|
|
125
|
+
title: <the document's title — intrinsic; documents don't repeat it as metadata>
|
|
126
|
+
text: <the raw markdown file — the body is the artifact>
|
|
127
|
+
schemaId: <the bound `decision` (or design/reference/runbook/postmortem) schema id>
|
|
128
|
+
payload: { summary, status: "accepted", area: "search",
|
|
129
|
+
tags: ["..."], date: "YYYY-MM-DD" } # metadata only; + refs, e.g. supersedes
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Scope later searches to one type with `contentTypes: ["documents"], typeName:
|
|
133
|
+
"decision"` (the document-type facet), plus `filters` for `area`/`tags`.
|
|
134
|
+
|
|
135
|
+
### Records — the structured artifacts (controls, conventions, gotchas, terms)
|
|
136
|
+
|
|
137
|
+
These are typed fields, not prose — the agent extracts the fields and calls
|
|
138
|
+
`record_create` per item (e.g. a `convention`'s distinct rule/why/howToApply, a
|
|
139
|
+
`control`'s evidence + `verifiedBy` runbook, a `term`'s unique key + definition).
|
|
140
|
+
|
|
141
|
+
A one-shot backfill is that agent looped over your `docs/`/ADRs/memory; an ongoing
|
|
142
|
+
sync re-runs it on change, re-ingesting edited source with `upsert: true` so the
|
|
143
|
+
same `externalId`s overwrite in place (a plain re-create returns the existing item
|
|
144
|
+
unchanged, so use `upsert` to propagate edits). Cross-surface edges (a record's
|
|
145
|
+
reference to a document) resolve by the target's `externalId`, so ingest the
|
|
146
|
+
referenced documents before the records that point at them.
|
|
147
|
+
|
|
148
|
+
### Throttle the backfill — it's rate-limited
|
|
149
|
+
|
|
150
|
+
A bulk backfill is exactly the workload that trips the API's **per-minute rate
|
|
151
|
+
limit**. Two things to know:
|
|
152
|
+
|
|
153
|
+
- The limit is **per tenant**, counts **writes + searches** (read-only `GET`s are
|
|
154
|
+
exempt), and is **shared across all of a tenant's keys** — so don't try to go
|
|
155
|
+
faster by running parallel ingests under different keys; they share one bucket.
|
|
156
|
+
- The **free tier allows only tens of writes per minute**; higher plans allow more.
|
|
157
|
+
Check your plan's exact limit in the API rate-limits documentation.
|
|
158
|
+
|
|
159
|
+
So pace the ingest: keep writes **well under your plan's per-minute limit** — for
|
|
160
|
+
the free tier, roughly one record every couple of seconds is safe (a plain `sleep`
|
|
161
|
+
between `record_create` calls is enough); go faster on higher tiers. On an HTTP
|
|
162
|
+
**429**, **honor the `Retry-After` header** (seconds until the window resets; the
|
|
163
|
+
response also carries `X-RateLimit-*`); if it's absent, back off exponentially with
|
|
164
|
+
jitter, then resume. Because ingest is idempotent by `externalId`, a backfill that
|
|
165
|
+
pauses or restarts simply converges — it never double-writes.
|
|
166
|
+
|
|
167
|
+
## 4. Query it
|
|
168
|
+
|
|
169
|
+
Documents are queried via search (scoped by `typeName`); records via `record_query`.
|
|
170
|
+
|
|
171
|
+
| You want… | Call |
|
|
172
|
+
|---|---|
|
|
173
|
+
| "Why did we decide X?" (grounded, cited) | `rag_ask "why did we choose X?"` (answers over document bodies) |
|
|
174
|
+
| "Which critical controls are active, and how is each proven?" | `record_query control { kind:"control", criticality:"critical", status:"active" }` → follow `verifiedBy` to the runbook |
|
|
175
|
+
| "What's the active rule for area X?" | `record_query convention { area:"<area>", status:"active" }` |
|
|
176
|
+
| "Have we hit this failure before?" | `hybrid_search "<symptom>" contentTypes:["documents"], typeName:"postmortem"`; plus `record_query gotcha { area:"deploy", status:"active" }` |
|
|
177
|
+
| "Define X" | `record_query term { term:"X" }` (unique lookup) |
|
|
178
|
+
| "Latest decisions / search the designs" | `hybrid_search "<topic>" contentTypes:["documents"], typeName:"decision"` (or `"design"`), `filters:{ area:"<area>" }` |
|
|
179
|
+
| "What supersedes a given decision?" | document lookup on `decision` by `supersedes:"<externalId>"` |
|
|
180
|
+
|
|
181
|
+
## 5. Customize
|
|
182
|
+
|
|
183
|
+
This is a starting point — fork it for your org:
|
|
184
|
+
|
|
185
|
+
- **`area` vocabulary** — swap in your subsystems.
|
|
186
|
+
- **Add/remove schemas** — keep what fits; the format is the same as the bundled
|
|
187
|
+
source (`src/blueprints/agentic-sdlc.ts`).
|
|
188
|
+
- **Enum vocabularies** — adjust `status`/`severity`/`category` to your lifecycle.
|
|
189
|
+
- **Surface (document vs record)** — content-heavy types belong on the document
|
|
190
|
+
surface (`allowedSurfaces: ['document']`), structure-heavy types are records. Add
|
|
191
|
+
a separate type when the *shape* differs, when a distinct first-class type
|
|
192
|
+
strengthens *references*, or when it's a distinct thing humans **browse** — not
|
|
193
|
+
for a near-identical clone (use a filterable field for sub-kinds, as `reference`
|
|
194
|
+
does with `category`).
|
|
195
|
+
- **Lookups are migration-locked** — the equality-vs-range choice and the 7 fast
|
|
196
|
+
equality slots per schema are fixed once a schema is live; choose deliberately
|
|
197
|
+
(see the package README § "The format, field by field").
|
|
198
|
+
- **Sensitive fields** — SDLC knowledge generally isn't PHI, so this blueprint
|
|
199
|
+
marks nothing sensitive; if a field needs redaction (e.g. an internal endpoint in
|
|
200
|
+
a post-mortem), mark it `sensitive` (see the `clinical-intake` blueprint).
|
|
201
|
+
|
|
202
|
+
## 6. Bridging your issue tracker — don't mirror it
|
|
203
|
+
|
|
204
|
+
Your issue tracker (GitLab, Jira, Linear) and this knowledge base are **two planes
|
|
205
|
+
with different jobs** — keep them separate:
|
|
206
|
+
|
|
207
|
+
- **Tracker = live status** (open/closed, assignee, the board). Volatile; it stays
|
|
208
|
+
the source of truth for *what's in flight*.
|
|
209
|
+
- **Knowledge base = durable recall** (why/how/lessons). Stable; the source of truth
|
|
210
|
+
for *what we know*.
|
|
211
|
+
|
|
212
|
+
Mirroring issues into the KB creates a stale shadow copy and buries your decisions
|
|
213
|
+
under issue churn. Instead, **promote by reference**:
|
|
214
|
+
|
|
215
|
+
1. **When you close out work that carries durable knowledge**, distill it into the
|
|
216
|
+
right type — a settled call → `decision`, a trap → `gotcha`, an outage + lesson →
|
|
217
|
+
`postmortem`, a new rule → `convention`/`control`, a procedure → `runbook`.
|
|
218
|
+
2. **Tag it `issue:<id>`** — e.g. `tags: ["auth", "issue:147"]` (`jira:ENG-12` /
|
|
219
|
+
`linear:OPS-9` work the same way). This is the link back to the live item.
|
|
220
|
+
3. **Note the `externalId` back in the tracker** ("captured as `adr-token-rotation`")
|
|
221
|
+
— the return link.
|
|
222
|
+
|
|
223
|
+
Then recall an issue's knowledge with `filters:{ tags:"issue:147" }`, and jump to its
|
|
224
|
+
live status via the tag. **Be selective** — most issues (a dependency bump, a
|
|
225
|
+
flaky-test fix) promote *nothing*; only the durable why/how/lesson belongs here. That
|
|
226
|
+
selectivity is what keeps recall high-signal instead of drowning your decisions in
|
|
227
|
+
tracker chatter. The KB never stores status (no open/closed/assignee): status lives
|
|
228
|
+
in the tracker, knowledge lives here, and the tag + back-ref are the seam. (No schema
|
|
229
|
+
change — every type already has `tags`.)
|
|
230
|
+
|
|
231
|
+
## 7. Keep it healthy
|
|
232
|
+
|
|
233
|
+
- **Record the why** — rationale is the most-recalled field; a statement without it
|
|
234
|
+
is a log entry, not knowledge.
|
|
235
|
+
- **Supersede, don't delete** — flip `status` so the evolution trail survives.
|
|
236
|
+
- **Re-ingest is keyed on `externalId`** — a backfill never double-writes (an
|
|
237
|
+
unchanged item returns as-is), re-ingesting edited source with `upsert: true` keeps
|
|
238
|
+
the KB in sync, and the KB can be rebuilt from source at any time.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vectros-ai/blueprints",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"description": "Curated Vectros use-case blueprints (schemas + least-privilege AccessProfile + seed) and the Blueprint format + structural validation. Enforcement (the scope gate) lives in @vectros-ai/cli, not here.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
},
|
|
21
21
|
"files": [
|
|
22
22
|
"dist",
|
|
23
|
+
"guides",
|
|
24
|
+
"prompts",
|
|
23
25
|
"README.md",
|
|
24
26
|
"CHANGELOG.md",
|
|
25
27
|
"LICENSE"
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Agent orientation prompt — `agentic-sdlc` knowledge base
|
|
2
|
+
|
|
3
|
+
A drop-in preamble that orients a coding/ops agent to **use and feed** an
|
|
4
|
+
`agentic-sdlc` Vectros knowledge base. Paste it into your agent's system prompt
|
|
5
|
+
(Claude Code `CLAUDE.md`, a Cursor/Cline rule, a custom agent's instructions),
|
|
6
|
+
then **customize the bracketed bits** — your `area` vocabulary, which schemas you
|
|
7
|
+
use, and any house conventions. It assumes the `@vectros-ai/mcp-server` is
|
|
8
|
+
connected and bound to your `agentic-sdlc` context (see the guide).
|
|
9
|
+
|
|
10
|
+
Everything below the line is the prompt.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
You have a persistent **engineering knowledge base** — your team's whole-SDLC
|
|
15
|
+
memory — available through the Vectros MCP tools. It holds **decisions, designs,
|
|
16
|
+
references, runbooks, and post-mortems** (long-form **documents**) plus
|
|
17
|
+
**controls, conventions, gotchas, and a glossary** (typed **records**), all
|
|
18
|
+
cross-linked into one graph you can recall by meaning. Treat it as the source of
|
|
19
|
+
truth for "why is it shaped this way?" and "how do we do X?".
|
|
20
|
+
|
|
21
|
+
## The loop: recall before you act, capture after
|
|
22
|
+
|
|
23
|
+
1. **RECALL first.** Before you propose a change, design something, or debug a
|
|
24
|
+
failure, query the knowledge base. A cold start is exactly when you most need
|
|
25
|
+
the decision/convention/gotcha you can't re-derive from the code. Don't
|
|
26
|
+
re-litigate a settled decision or re-discover a known trap.
|
|
27
|
+
2. **ACT** using what you recalled — follow the conventions and controls, reuse the
|
|
28
|
+
runbook, respect the supersede chain.
|
|
29
|
+
3. **CAPTURE after.** When you make a durable decision, learn a convention, hit a
|
|
30
|
+
gotcha, write or revise a runbook, or run a post-mortem, write it back (a
|
|
31
|
+
document or a record, per below) so the next session inherits it. **Record the
|
|
32
|
+
*why*, not just the *what*** — the reasoning is the most-recalled content.
|
|
33
|
+
|
|
34
|
+
Knowledge is **superseded / retired / resolved** via a status flip, never deleted —
|
|
35
|
+
the trail of how the team's thinking evolved is part of the value.
|
|
36
|
+
|
|
37
|
+
## What's in it (the schemas)
|
|
38
|
+
|
|
39
|
+
Every item's `externalId` is its stable id (a slug or canonical number) so
|
|
40
|
+
re-writing the same id **updates** instead of duplicating. `[area]` is your
|
|
41
|
+
subsystem label (e.g. `auth`, `search`, `billing`, `governance`).
|
|
42
|
+
|
|
43
|
+
**Documents** — content is the artifact (the markdown body is what you read/ask;
|
|
44
|
+
written via `document_ingest`):
|
|
45
|
+
|
|
46
|
+
| Type | Holds | Status |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `decision` | an ADR — the settled *why* (body = context/decision/consequences) | proposed · accepted · superseded · deprecated |
|
|
49
|
+
| `design` | a design doc / spec — the explored *how* | draft · active · implemented · superseded |
|
|
50
|
+
| `reference` | a guide / onboarding / API / process doc (`category`, `lastReviewed`) | active · superseded |
|
|
51
|
+
| `runbook` | a step-by-step operational procedure | active · retired |
|
|
52
|
+
| `postmortem` | an incident writeup — what broke + the lesson (`severity`, `occurredOn`) | open · mitigated · resolved |
|
|
53
|
+
|
|
54
|
+
**Records** — structure is the artifact (typed fields; written via `record_create`):
|
|
55
|
+
|
|
56
|
+
| Type | Holds | Status |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| `control` | a policy/standard/control + its `evidence` (`kind`, `criticality`) | draft · active · retired |
|
|
59
|
+
| `convention` | a must-follow rule — distinct `rule` / `why` / `howToApply` | active · retired |
|
|
60
|
+
| `gotcha` | a sharp edge — `symptom` / `cause` / `fix` | active · resolved |
|
|
61
|
+
| `term` | a glossary entry — `term` (unique) → `definition`, `aliases` | — |
|
|
62
|
+
|
|
63
|
+
The graph **crosses surfaces** (every edge resolves a target by `externalId`):
|
|
64
|
+
`decision.supersedes → decision`, `design.relatedDecision → decision`,
|
|
65
|
+
`runbook.bornFrom → postmortem`, `control.verifiedBy → runbook` (how a control is
|
|
66
|
+
proven), and `control` / `convention` / `term` → `decision` (records pointing at
|
|
67
|
+
documents). Follow these to navigate provenance.
|
|
68
|
+
|
|
69
|
+
## How to query (MCP tools)
|
|
70
|
+
|
|
71
|
+
- **Recall by meaning / grounded answer** — `rag_ask` for a cited answer over the
|
|
72
|
+
document bodies: *"why did we choose X?"*, *"have we hit this before?"*.
|
|
73
|
+
- **Search documents** — `hybrid_search` with `contentTypes: ["documents"]` and
|
|
74
|
+
`typeName` to scope to one document type (e.g. `typeName: "decision"` or
|
|
75
|
+
`"runbook"` or `"postmortem"`), plus `filters` (`{ area: "search" }`,
|
|
76
|
+
`{ tags: "tenant-isolation" }`).
|
|
77
|
+
- **Query records** — `record_query` for exact enumeration:
|
|
78
|
+
`record_query control { kind: "control", criticality: "critical", status: "active" }`;
|
|
79
|
+
`record_query term { term: "AccessProfile" }` (unique lookup);
|
|
80
|
+
`record_query convention { area: "auth", status: "active" }`.
|
|
81
|
+
Range/sort on a record's date field (`order: "desc"`) for "latest" / "since".
|
|
82
|
+
|
|
83
|
+
## How to capture (MCP tools)
|
|
84
|
+
|
|
85
|
+
- **A document** (decision / design / reference / runbook / postmortem) —
|
|
86
|
+
`document_ingest` with the intrinsic `title` + the markdown **body** (`text`) +
|
|
87
|
+
`externalId` + the bound schema, plus a metadata `payload`. The title is intrinsic
|
|
88
|
+
to the document — do **not** repeat it inside `payload`. E.g. a decision:
|
|
89
|
+
`payload: { summary, status: "accepted", area: "[area]", tags: [...], date: "YYYY-MM-DD" }`
|
|
90
|
+
(set `supersedes` if it replaces one — write the target first).
|
|
91
|
+
- **A record** (control / convention / gotcha / term) — `record_create` with a
|
|
92
|
+
stable `externalId` + the typed fields, e.g.:
|
|
93
|
+
- gotcha: `{ externalId: "gotcha-<slug>", symptom, cause, fix, area: "[area]", status: "active", discoveredOn: "YYYY-MM-DD" }`.
|
|
94
|
+
- convention: `{ externalId: "<slug>", title, rule, why, howToApply, area: "[area]", status: "active", establishedBy: "<decision-externalId>", updatedOn: "YYYY-MM-DD" }`.
|
|
95
|
+
- **To retire** — re-write with `status` flipped (a decision to `superseded`, a
|
|
96
|
+
gotcha to `resolved`). Don't delete.
|
|
97
|
+
|
|
98
|
+
## Conventions
|
|
99
|
+
|
|
100
|
+
- **Idempotent + upsert:** reuse the same `externalId` so re-runs never duplicate — a
|
|
101
|
+
plain re-create returns the existing record **unchanged** (`created: false`); to apply
|
|
102
|
+
edits, send the change with `upsert: true`. Pick stable slugs/numbers.
|
|
103
|
+
- **Write a reference target before the record that points at it.**
|
|
104
|
+
- **Record the why.** A statement without rationale is a log entry, not knowledge.
|
|
105
|
+
- When a decision changes, write the new `decision` and set its `supersedes` — don't
|
|
106
|
+
edit the old one's meaning away.
|
|
107
|
+
- **Respect the rate limit.** Writes/searches are rate-limited per minute (per
|
|
108
|
+
tenant, shared across keys; the free tier is low). For a bulk write/backfill, pace
|
|
109
|
+
yourself (a short sleep between writes); on a `429`, honor the `Retry-After` header
|
|
110
|
+
(else back off exponentially) and retry — idempotency by `externalId` means a
|
|
111
|
+
paused/restarted run just converges.
|
|
112
|
+
|
|
113
|
+
## Bridging an issue tracker
|
|
114
|
+
|
|
115
|
+
Your tracker (GitLab/Jira/Linear) owns **live status**; this KB owns **durable
|
|
116
|
+
knowledge** — don't mirror issues here. When you close out work that carries durable
|
|
117
|
+
knowledge, **promote by reference**: write the typed document or record
|
|
118
|
+
(decision/postmortem/runbook · convention/gotcha), **tag it `issue:<id>`** (e.g.
|
|
119
|
+
`issue:147`; `jira:ENG-12` works too), and note the `externalId` back in the
|
|
120
|
+
tracker. Recall an issue's
|
|
121
|
+
knowledge with `filters:{ tags:"issue:147" }`; the tag is also your jump-link to live
|
|
122
|
+
status. Be selective — most issues promote nothing; only the durable why/how/lesson
|
|
123
|
+
belongs here. Never store status (open/closed/assignee) in the KB.
|
|
124
|
+
|
|
125
|
+
[Customize: your `area` vocabulary, which schemas your team uses, naming
|
|
126
|
+
conventions for `externalId`, your tracker tag prefix, and any house rules — e.g.
|
|
127
|
+
"every control names the test that enforces it in `evidence`."]
|