Curating the Library Knowledge Index
Curate .satk/library-kg/ for better agent block selection. Infer categories and descriptions from block metadata in .satk/library-cache/*.json, save curation to .satk/library-curation.json, then regenerate the KG.
When to Use
- User wants to mark blocks as commonly used or important
- User wants to correct auto-assigned categories
- User wants to improve block descriptions for better selection
- User asks "how do I make the agent prefer certain blocks?"
- Called from
building-simulink-models Gate 3.
When NOT to Use
- Blocking, deprecating, or protecting blocks →
configuring-block-policy
- Actively building a model →
building-simulink-models
- Declaring which libraries exist → Library Setup gate in
building-simulink-models
Prerequisites
satk-libraries.json or .satk/reuse-libraries.json must exist with libraries declared
Curation Rules
- Custom descriptions are mandatory for ALL
metadataQuality: "low" and "medium" blocks across ALL declared libraries. These blocks have no useful information. Write a short intent-focused description for every such block to help with agent block selection. Do not skip blocks because a file is large or because they seem unrelated to the current task.
- Custom descriptions for
"high" quality blocks are encouraged but optional.
- Write custom descriptions for as many blocks as possible. After covering low/medium, covering high blocks too improves the KG.
- Process in batches by category. Group blocks, infer descriptions together, present to user in digestible chunks.
- Never write template or mechanical descriptions. Descriptions like "Mathematical operation: gain" or "Signal routing utility: mux" are useless — they just restate the category and name. Every description MUST be thoughtful, intent-focused description explaining when to use the block and what modeling problem it solves (e.g., "Scale a signal by a constant factor — use for unit conversion, controller gains, or applying physical constants" instead of "Mathematical operation: gain").
Modes
- Automatic (from Gate 3 "Automatic" option) — infer everything, commit without pausing per step, present final result for review.
- Guided (from Gate 3 "Guided setup" or direct user invocation) — propose at each step, wait for user confirmation before proceeding.
Determine mode before starting. Do not proceed without mode selection.
Workflow
If .satk/library-kg/index.md already exists, start at step 1 (review existing state). If not, start at step 2.
- Review (only if KG exists) — Read
index.md and common.md, summarize current state to user (libraries, block count, categories, common blocks).
- Mode selection — Determine Automatic or Guided. Do not proceed without completing this step.
- Descriptions — Ensure cache exists (see API), then read ALL
.satk/library-cache/*.json files in full. If a file exceeds read limits, read it in chunks until every block has been processed. Apply Curation Rules above — write custom descriptions for blocks, prioritizing low/medium quality. Do NOT proceed to Step 4 until descriptions exist for every low/medium quality block across ALL cache files. Save to customDescriptions.
- Common blocks — Propose which blocks should be marked as commonly used. Consider blocks covering diverse categories and frequent modeling workflows. Save to
commonBlocks.
- Categories — Finalize category definitions (names, descriptions, 3-5 keywords each). Allow user to correct individual block assignments via
categoryAssignments.
- Completeness check — Before saving, count total low/medium quality blocks across ALL cache files and count how many have custom descriptions. Report coverage to the user (e.g., "275/275 low/medium blocks described, 120/285 high blocks described"). Do NOT proceed if coverage of low/medium blocks is below 100%.
- Save and generate — Save all curation data via
library.LibraryCuration.save(projectRoot, curation), then run library.kg.Populate.run(projectRoot). Present the output summary to the user.
API
Ensuring cache exists
libConfig = library.LibraryConfig.load(projectRoot);
library.LibraryCatalog.getOrCreate(libConfig, projectRoot);
Reading block metadata
Read .satk/library-cache/*.json directly. Each file:
{
"libraryName": "MotorLib",
"description": "Motor control library",
"blocks": [
{
"name": "SpeedController",
"maskType": "SpeedCtrl",
"blockType": "SubSystem",
"maskDescription": "Closed-loop speed regulation with anti-windup",
"description": "",
"pathCategory": "Controllers",
"metadataQuality": "high",
"referenceBlock": "MotorLib/Controllers/SpeedController"
}
]
}
Saving curation data
projectRoot = prefdir();
curation = library.LibraryCuration.load(projectRoot);
curation.commonBlocks = {'Speed Controller', 'Torque Estimator'};
curation.categories = struct('name', 'motors', 'description', 'Electric motors', 'keywords', {{'motor', 'drive'}});
% Use containers.Map — supports any block name as key
curation.customDescriptions = containers.Map('KeyType', 'char', 'ValueType', 'char');
curation.customDescriptions('Unit Delay') = 'Delay signal by one sample period';
curation.customDescriptions('1-D Lookup Table') = 'Interpolate output from breakpoint-value pairs';
curation.categoryAssignments = containers.Map('KeyType', 'char', 'ValueType', 'char');
curation.categoryAssignments('DC Current Controller') = 'motor-control';
library.LibraryCuration.save(projectRoot, curation);
library.kg.Populate.run(projectRoot);
Important: Use containers.Map (not struct) for customDescriptions and categoryAssignments. Struct field names cannot contain spaces or hyphens, which most Simulink block names have.
JSON format on disk
{
"customDescriptions": [
{"block": "Unit Delay", "value": "Delay signal by one sample period"},
{"block": "1-D Lookup Table", "value": "Interpolate output from breakpoint-value pairs"}
],
"categoryAssignments": [
{"block": "DC Current Controller", "value": "motor-control"}
]
}
Curation Fields
| Field |
Type |
Effect |
commonBlocks |
cell array of strings |
Always shown in common.md regardless of quality score |
categories |
struct array with .name, .description, .keywords |
Defines categories with keyword matching for assignment |
categoryAssignments |
containers.Map (blockName → categoryName) |
Per-block category assignment |
customDescriptions |
containers.Map (blockName → description) |
Per-block custom description (intent) |
Guardrails
Always:
- Read block metadata only from
.satk/library-cache/*.json.
- Persist curation via
library.LibraryCuration.save() and regenerate the KG via library.kg.Populate.run().
- Use
library.kg.Query.search() for KG lookups.
- In user-facing output, use "custom description" or "category assignment" — never the term "override".
Ask first:
- Confirm the proposed curation with the user before calling
library.LibraryCuration.save().
Never:
- Never call
find_system or get_param on library .slx files.
- Never modify
.satk/library-cache/*.json or .satk/library-kg/*.md directly — they are auto-generated.
- Never persist curation through any path other than
library.LibraryCuration.save().
Copyright 2026 The MathWorks, Inc.
1---2name: simulink-curating-library-kg3description: Use this skill when the user wants to curate the SATK library knowledge index for a Simulink project — mark commonly used blocks, correct auto-assigned block categories, or improve block descriptions so the model-building agent picks better blocks from custom libraries. Triggered by phrases like "mark blocks common", "improve block descriptions", "correct block category", "make the agent prefer certain blocks", and from Gate 3 of building-simulink-models.4license: https://www.mathworks.com/content/dam/mathworks/license/pmrl/lic5---6
7# Curating the Library Knowledge Index
8
9Curate `.satk/library-kg/` for better agent block selection. Infer categories and descriptions from block metadata in `.satk/library-cache/*.json`, save curation to `.satk/library-curation.json`, then regenerate the KG.
10
11## When to Use
12
13- User wants to mark blocks as commonly used or important
14- User wants to correct auto-assigned categories
15- User wants to improve block descriptions for better selection
16- User asks "how do I make the agent prefer certain blocks?"
17- Called from `building-simulink-models` Gate 3.
18
19## When NOT to Use
20
21- Blocking, deprecating, or protecting blocks → `configuring-block-policy`
22- Actively building a model → `building-simulink-models`
23- Declaring which libraries exist → Library Setup gate in `building-simulink-models`
24
25## Prerequisites
26
27- `satk-libraries.json` or `.satk/reuse-libraries.json` must exist with libraries declared
28
29## Curation Rules
30
311. **Custom descriptions are mandatory for ALL `metadataQuality: "low"` and `"medium"` blocks across ALL declared libraries.** These blocks have no useful information. Write a short intent-focused description for every such block to help with agent block selection. Do not skip blocks because a file is large or because they seem unrelated to the current task.
322. **Custom descriptions for `"high"` quality blocks are encouraged but optional.**
333. **Write custom descriptions for as many blocks as possible.** After covering low/medium, covering high blocks too improves the KG.
344. **Process in batches by category.** Group blocks, infer descriptions together, present to user in digestible chunks.
355. **Never write template or mechanical descriptions.** Descriptions like "Mathematical operation: gain" or "Signal routing utility: mux" are useless — they just restate the category and name. Every description MUST be thoughtful, intent-focused description explaining *when* to use the block and *what modeling problem* it solves (e.g., "Scale a signal by a constant factor — use for unit conversion, controller gains, or applying physical constants" instead of "Mathematical operation: gain").
36
37## Modes
38
39- **Automatic** (from Gate 3 "Automatic" option) — infer everything, commit without pausing per step, present final result for review.
40- **Guided** (from Gate 3 "Guided setup" or direct user invocation) — propose at each step, wait for user confirmation before proceeding.
41
42Determine mode before starting. Do not proceed without mode selection.
43
44## Workflow
45
46If `.satk/library-kg/index.md` already exists, start at step 1 (review existing state). If not, start at step 2.
47
481. **Review** (only if KG exists) — Read `index.md` and `common.md`, summarize current state to user (libraries, block count, categories, common blocks).
492. **Mode selection** — Determine Automatic or Guided. Do not proceed without completing this step.
503. **Descriptions** — Ensure cache exists (see API), then read ALL `.satk/library-cache/*.json` files **in full**. If a file exceeds read limits, read it in chunks until every block has been processed. Apply Curation Rules above — write custom descriptions for blocks, prioritizing low/medium quality. Do NOT proceed to Step 4 until descriptions exist for every low/medium quality block across ALL cache files. Save to `customDescriptions`.
514. **Common blocks** — Propose which blocks should be marked as commonly used. Consider blocks covering diverse categories and frequent modeling workflows. Save to `commonBlocks`.
525. **Categories** — Finalize category definitions (names, descriptions, 3-5 keywords each). Allow user to correct individual block assignments via `categoryAssignments`.
536. **Completeness check** — Before saving, count total low/medium quality blocks across ALL cache files and count how many have custom descriptions. Report coverage to the user (e.g., "275/275 low/medium blocks described, 120/285 high blocks described"). Do NOT proceed if coverage of low/medium blocks is below 100%.
547. **Save and generate** — Save all curation data via `library.LibraryCuration.save(projectRoot, curation)`, then run `library.kg.Populate.run(projectRoot)`. Present the output summary to the user.
55
56## API
57
58### Ensuring cache exists
59
60```matlab
61libConfig = library.LibraryConfig.load(projectRoot);
62library.LibraryCatalog.getOrCreate(libConfig, projectRoot);
63```
64
65### Reading block metadata
66
67Read `.satk/library-cache/*.json` directly. Each file:
68```json
69{
70 "libraryName": "MotorLib",
71 "description": "Motor control library",
72 "blocks": [
73 {
74 "name": "SpeedController",
75 "maskType": "SpeedCtrl",
76 "blockType": "SubSystem",
77 "maskDescription": "Closed-loop speed regulation with anti-windup",
78 "description": "",
79 "pathCategory": "Controllers",
80 "metadataQuality": "high",
81 "referenceBlock": "MotorLib/Controllers/SpeedController"
82 }
83 ]
84}
85```
86
87### Saving curation data
88
89```matlab
90projectRoot = prefdir();
91curation = library.LibraryCuration.load(projectRoot);
92curation.commonBlocks = {'Speed Controller', 'Torque Estimator'};
93curation.categories = struct('name', 'motors', 'description', 'Electric motors', 'keywords', {{'motor', 'drive'}});
94
95% Use containers.Map — supports any block name as key
96curation.customDescriptions = containers.Map('KeyType', 'char', 'ValueType', 'char');
97curation.customDescriptions('Unit Delay') = 'Delay signal by one sample period';
98curation.customDescriptions('1-D Lookup Table') = 'Interpolate output from breakpoint-value pairs';
99
100curation.categoryAssignments = containers.Map('KeyType', 'char', 'ValueType', 'char');
101curation.categoryAssignments('DC Current Controller') = 'motor-control';
102
103library.LibraryCuration.save(projectRoot, curation);
104library.kg.Populate.run(projectRoot);
105```
106
107**Important:** Use `containers.Map` (not struct) for `customDescriptions` and `categoryAssignments`. Struct field names cannot contain spaces or hyphens, which most Simulink block names have.
108
109### JSON format on disk
110
111```json
112{
113 "customDescriptions": [
114 {"block": "Unit Delay", "value": "Delay signal by one sample period"},
115 {"block": "1-D Lookup Table", "value": "Interpolate output from breakpoint-value pairs"}
116 ],
117 "categoryAssignments": [
118 {"block": "DC Current Controller", "value": "motor-control"}
119 ]
120}
121```
122
123## Curation Fields
124
125| Field | Type | Effect |
126|-------|------|--------|
127| `commonBlocks` | cell array of strings | Always shown in `common.md` regardless of quality score |
128| `categories` | struct array with `.name`, `.description`, `.keywords` | Defines categories with keyword matching for assignment |
129| `categoryAssignments` | `containers.Map` (blockName → categoryName) | Per-block category assignment |
130| `customDescriptions` | `containers.Map` (blockName → description) | Per-block custom description (intent) |
131
132## Guardrails
133
134**Always:**
135- Read block metadata only from `.satk/library-cache/*.json`.
136- Persist curation via `library.LibraryCuration.save()` and regenerate the KG via `library.kg.Populate.run()`.
137- Use `library.kg.Query.search()` for KG lookups.
138- In user-facing output, use "custom description" or "category assignment" — never the term "override".
139
140**Ask first:**
141- Confirm the proposed curation with the user before calling `library.LibraryCuration.save()`.
142
143**Never:**
144- Never call `find_system` or `get_param` on library `.slx` files.
145- Never modify `.satk/library-cache/*.json` or `.satk/library-kg/*.md` directly — they are auto-generated.
146- Never persist curation through any path other than `library.LibraryCuration.save()`.
147
148----
149
150Copyright 2026 The MathWorks, Inc.
151
152----