@vectros-ai/blueprints 0.5.0 → 0.6.2

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.
@@ -0,0 +1,210 @@
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
+ - **Range/sort on every artifact's date**, a governance `control` that records its
36
+ own evidence, a `convention` with distinct rule/why/howToApply fields, and a
37
+ glossary `term` with a `unique` exact-lookup.
38
+
39
+ ## 2. Quickstart — install, sign in, provision
40
+
41
+ Install the public CLI, sign in once (browser), and provision the context + the nine
42
+ schemas + a scoped key (and wire your MCP client). `production` is the default
43
+ environment — add `--env staging` only to target staging.
44
+
45
+ **Bash (macOS / Linux / Git Bash):**
46
+
47
+ ```bash
48
+ npm i -g @vectros-ai/cli
49
+ vectros login # one-time, browser sign-in
50
+ vectros bootstrap --blueprint agentic-sdlc --no-seed --yes
51
+ vectros whoami # confirm tenant + scoped key
52
+ ```
53
+
54
+ **PowerShell (Windows):**
55
+
56
+ ```powershell
57
+ npm i -g "@vectros-ai/cli"
58
+ vectros login # one-time, browser sign-in
59
+ vectros bootstrap --blueprint agentic-sdlc --no-seed --yes
60
+ vectros whoami
61
+ ```
62
+
63
+ `bootstrap` provisions the context + schemas + a least-privilege `ssk_*` (written
64
+ once to `~/.vectros/agentic-sdlc.key.json`) and safe-merges the Vectros MCP server
65
+ into your **Claude Desktop** config; use `--client code` for **Claude Code**, or
66
+ `--print` to emit the snippet without writing a file. Restart your MCP client to load
67
+ it. (Prefer not to install globally? Prefix each command with `npx -y`, e.g.
68
+ `npx -y @vectros-ai/cli bootstrap …` — on PowerShell quote the spec:
69
+ `npx -y "@vectros-ai/cli" …`.)
70
+
71
+ Add `--tenant test` to provision into the **test tenant** first (useful for a
72
+ dry-run before committing to your live tenant). Omit for live (the default).
73
+
74
+ ### Seeds
75
+
76
+ This blueprint ships **without bundled seeds** — it provisions the nine schemas +
77
+ the scoped key, and you fill it from your own corpus (next section). So the context
78
+ starts clean; there's no synthetic data to remove. (If you fork a blueprint that
79
+ *does* ship seeds and want a clean production context, `vectros bootstrap
80
+ --no-seed` provisions the schemas + key and skips the seed step.)
81
+
82
+ ## 3. Ingest your corpus
83
+
84
+ There are two ingest paths, by surface — both driven by the **ingest agent**
85
+ (point it at your source files with the
86
+ [orientation prompt](../prompts/agentic-sdlc-agent.md); an LLM maps your
87
+ semi-structured docs to the right type far better than a brittle parser, and it's
88
+ idempotent by `externalId`).
89
+
90
+ ### Documents — the prose artifacts (ADRs, designs, references, runbooks, post-mortems)
91
+
92
+ These keep their markdown **body as-is**; the agent fills the typed metadata and
93
+ ingests via `document_ingest` against the matching schema:
94
+
95
+ ```text
96
+ document_ingest:
97
+ title: <the document's title — intrinsic; documents don't repeat it as metadata>
98
+ text: <the raw markdown file — the body is the artifact>
99
+ schemaId: <the bound `decision` (or design/reference/runbook/postmortem) schema id>
100
+ payload: { summary, status: "accepted", area: "search",
101
+ tags: ["..."], date: "YYYY-MM-DD" } # metadata only; + refs, e.g. supersedes
102
+ ```
103
+
104
+ Scope later searches to one type with `contentTypes: ["documents"], typeName:
105
+ "decision"` (the document-type facet), plus `filters` for `area`/`tags`.
106
+
107
+ ### Records — the structured artifacts (controls, conventions, gotchas, terms)
108
+
109
+ These are typed fields, not prose — the agent extracts the fields and calls
110
+ `record_create` per item (e.g. a `convention`'s distinct rule/why/howToApply, a
111
+ `control`'s evidence + `verifiedBy` runbook, a `term`'s unique key + definition).
112
+
113
+ A one-shot backfill is that agent looped over your `docs/`/ADRs/memory; an ongoing
114
+ sync re-runs it on change, re-ingesting edited source with `upsert: true` so the
115
+ same `externalId`s overwrite in place (a plain re-create returns the existing item
116
+ unchanged, so use `upsert` to propagate edits). Cross-surface edges (a record's
117
+ reference to a document) resolve by the target's `externalId`, so ingest the
118
+ referenced documents before the records that point at them.
119
+
120
+ ### Throttle the backfill — it's rate-limited
121
+
122
+ A bulk backfill is exactly the workload that trips the API's **per-minute rate
123
+ limit**. Two things to know:
124
+
125
+ - The limit is **per tenant**, counts **writes + searches** (read-only `GET`s are
126
+ exempt), and is **shared across all of a tenant's keys** — so don't try to go
127
+ faster by running parallel ingests under different keys; they share one bucket.
128
+ - The **free tier allows only tens of writes per minute**; higher plans allow more.
129
+ Check your plan's exact limit in the API rate-limits documentation.
130
+
131
+ So pace the ingest: keep writes **well under your plan's per-minute limit** — for
132
+ the free tier, roughly one record every couple of seconds is safe (a plain `sleep`
133
+ between `record_create` calls is enough); go faster on higher tiers. On an HTTP
134
+ **429**, **honor the `Retry-After` header** (seconds until the window resets; the
135
+ response also carries `X-RateLimit-*`); if it's absent, back off exponentially with
136
+ jitter, then resume. Because ingest is idempotent by `externalId`, a backfill that
137
+ pauses or restarts simply converges — it never double-writes.
138
+
139
+ ## 4. Query it
140
+
141
+ Documents are queried via search (scoped by `typeName`); records via `record_query`.
142
+
143
+ | You want… | Call |
144
+ |---|---|
145
+ | "Why did we decide X?" (grounded, cited) | `rag_ask "why did we choose X?"` (answers over document bodies) |
146
+ | "Which critical controls are active, and how is each proven?" | `record_query control { kind:"control", criticality:"critical", status:"active" }` → follow `verifiedBy` to the runbook |
147
+ | "What's the active rule for area X?" | `record_query convention { area:"<area>", status:"active" }` |
148
+ | "Have we hit this failure before?" | `hybrid_search "<symptom>" contentTypes:["documents"], typeName:"postmortem"`; plus `record_query gotcha { area:"deploy", status:"active" }` |
149
+ | "Define X" | `record_query term { term:"X" }` (unique lookup) |
150
+ | "Latest decisions / search the designs" | `hybrid_search "<topic>" contentTypes:["documents"], typeName:"decision"` (or `"design"`), `filters:{ area:"<area>" }` |
151
+ | "What supersedes a given decision?" | document lookup on `decision` by `supersedes:"<externalId>"` |
152
+
153
+ ## 5. Customize
154
+
155
+ This is a starting point — fork it for your org:
156
+
157
+ - **`area` vocabulary** — swap in your subsystems.
158
+ - **Add/remove schemas** — keep what fits; the format is the same as the bundled
159
+ source (`src/blueprints/agentic-sdlc.ts`).
160
+ - **Enum vocabularies** — adjust `status`/`severity`/`category` to your lifecycle.
161
+ - **Surface (document vs record)** — content-heavy types belong on the document
162
+ surface (`allowedSurfaces: ['document']`), structure-heavy types are records. Add
163
+ a separate type when the *shape* differs, when a distinct first-class type
164
+ strengthens *references*, or when it's a distinct thing humans **browse** — not
165
+ for a near-identical clone (use a filterable field for sub-kinds, as `reference`
166
+ does with `category`).
167
+ - **Lookups are migration-locked** — the equality-vs-range choice and the 7 fast
168
+ equality slots per schema are fixed once a schema is live; choose deliberately
169
+ (see the package README § "The format, field by field").
170
+ - **Sensitive fields** — SDLC knowledge generally isn't PHI, so this blueprint
171
+ marks nothing sensitive; if a field needs redaction (e.g. an internal endpoint in
172
+ a post-mortem), mark it `sensitive` (see the `clinical-intake` blueprint).
173
+
174
+ ## 6. Bridging your issue tracker — don't mirror it
175
+
176
+ Your issue tracker (GitLab, Jira, Linear) and this knowledge base are **two planes
177
+ with different jobs** — keep them separate:
178
+
179
+ - **Tracker = live status** (open/closed, assignee, the board). Volatile; it stays
180
+ the source of truth for *what's in flight*.
181
+ - **Knowledge base = durable recall** (why/how/lessons). Stable; the source of truth
182
+ for *what we know*.
183
+
184
+ Mirroring issues into the KB creates a stale shadow copy and buries your decisions
185
+ under issue churn. Instead, **promote by reference**:
186
+
187
+ 1. **When you close out work that carries durable knowledge**, distill it into the
188
+ right type — a settled call → `decision`, a trap → `gotcha`, an outage + lesson →
189
+ `postmortem`, a new rule → `convention`/`control`, a procedure → `runbook`.
190
+ 2. **Tag it `issue:<id>`** — e.g. `tags: ["auth", "issue:147"]` (`jira:ENG-12` /
191
+ `linear:OPS-9` work the same way). This is the link back to the live item.
192
+ 3. **Note the `externalId` back in the tracker** ("captured as `adr-token-rotation`")
193
+ — the return link.
194
+
195
+ Then recall an issue's knowledge with `filters:{ tags:"issue:147" }`, and jump to its
196
+ live status via the tag. **Be selective** — most issues (a dependency bump, a
197
+ flaky-test fix) promote *nothing*; only the durable why/how/lesson belongs here. That
198
+ selectivity is what keeps recall high-signal instead of drowning your decisions in
199
+ tracker chatter. The KB never stores status (no open/closed/assignee): status lives
200
+ in the tracker, knowledge lives here, and the tag + back-ref are the seam. (No schema
201
+ change — every type already has `tags`.)
202
+
203
+ ## 7. Keep it healthy
204
+
205
+ - **Record the why** — rationale is the most-recalled field; a statement without it
206
+ is a log entry, not knowledge.
207
+ - **Supersede, don't delete** — flip `status` so the evolution trail survives.
208
+ - **Re-ingest is keyed on `externalId`** — a backfill never double-writes (an
209
+ unchanged item returns as-is), re-ingesting edited source with `upsert: true` keeps
210
+ 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.5.0",
3
+ "version": "0.6.2",
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`."]