@yottagraph-app/aether-instructions 1.1.22 → 1.1.24
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/commands/build_my_app.md +51 -4
- package/package.json +1 -1
- package/rules/api.mdc +56 -0
- package/rules/cookbook.mdc +163 -1
- package/skills/data-model/bny/DATA_DICTIONARY.md +184 -0
- package/skills/data-model/bny/schema.yaml +598 -0
- package/skills/data-model/edgar/schema.yaml +1 -1
- package/skills/elemental-api/SKILL.md +41 -4
- package/skills/elemental-api/entities.md +241 -114
- package/skills/elemental-api/find.md +59 -9
- package/skills/elemental-api/mcp.md +180 -0
- package/skills/elemental-api/overview.md +73 -20
- package/skills/elemental-api/relationships.md +163 -0
- package/skills/elemental-api/schema.md +54 -8
package/commands/build_my_app.md
CHANGED
|
@@ -92,7 +92,47 @@ Key capabilities:
|
|
|
92
92
|
|
|
93
93
|
---
|
|
94
94
|
|
|
95
|
-
## Step 4:
|
|
95
|
+
## Step 4: Verify Data Availability
|
|
96
|
+
|
|
97
|
+
Before designing UX, verify that the data your app needs actually exists
|
|
98
|
+
in the knowledge graph. This prevents building features around empty data.
|
|
99
|
+
|
|
100
|
+
**If MCP tools are available:**
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
elemental_get_schema() → list entity types, confirm your target types exist
|
|
104
|
+
elemental_get_entity(entity="Microsoft") → verify entity lookup works with a known entity
|
|
105
|
+
elemental_get_entity(entity="Apple Inc") → try another known entity
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
If schema calls succeed but entity lookups return "not found," that means
|
|
109
|
+
the entity type exists in the schema but has no data. That's a **data
|
|
110
|
+
issue**, not a broken server. Try different, well-known entity names.
|
|
111
|
+
|
|
112
|
+
**If MCP tools are NOT available, use curl:**
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# Read credentials from broadchurch.yaml
|
|
116
|
+
GW=$(grep 'url:' broadchurch.yaml | head -1 | sed 's/.*"\(.*\)".*/\1/')
|
|
117
|
+
ORG=$(grep 'org_id:' broadchurch.yaml | sed 's/.*"\(.*\)".*/\1/')
|
|
118
|
+
KEY=$(grep 'qs_api_key:' broadchurch.yaml | sed 's/.*"\(.*\)".*/\1/')
|
|
119
|
+
|
|
120
|
+
# List entity types
|
|
121
|
+
curl -s "$GW/api/qs/$ORG/elemental/metadata/schema" -H "X-Api-Key: $KEY"
|
|
122
|
+
|
|
123
|
+
# Search for a known entity
|
|
124
|
+
curl -s "$GW/api/qs/$ORG/entities/search" \
|
|
125
|
+
-X POST -H "Content-Type: application/json" -H "X-Api-Key: $KEY" \
|
|
126
|
+
-d '{"queries":[{"queryId":1,"query":"Microsoft"}],"maxResults":3,"includeNames":true}'
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Document what you find.** If certain entity types have sparse data, note
|
|
130
|
+
it in your UX plan. Design features around data that actually exists, and
|
|
131
|
+
mark aspirational features (that need more data) as future work.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Step 5: Design the UX
|
|
96
136
|
|
|
97
137
|
Based on the brief, think about the right UX for this specific problem. Do NOT default to a sidebar-with-tabs layout. Consider:
|
|
98
138
|
|
|
@@ -116,7 +156,7 @@ Present the plan to the user and ask for approval before proceeding.
|
|
|
116
156
|
|
|
117
157
|
---
|
|
118
158
|
|
|
119
|
-
## Step
|
|
159
|
+
## Step 6: Build
|
|
120
160
|
|
|
121
161
|
Implement the plan:
|
|
122
162
|
|
|
@@ -128,6 +168,13 @@ Implement the plan:
|
|
|
128
168
|
6. Use Vuetify components and the project's dark theme
|
|
129
169
|
7. Update `DESIGN.md` with what you built
|
|
130
170
|
|
|
171
|
+
**Use the pre-built platform utilities:**
|
|
172
|
+
|
|
173
|
+
- `useElementalSchema()` — schema discovery with caching, flavor/PID lookup helpers
|
|
174
|
+
- `buildGatewayUrl()`, `getApiKey()`, `padNeid()` from `utils/elementalHelpers`
|
|
175
|
+
- `searchEntities()`, `getEntityName()` from `utils/elementalHelpers`
|
|
176
|
+
- `useElementalClient()` from `@yottagraph-app/elemental-api/client`
|
|
177
|
+
|
|
131
178
|
**Follow the project's coding conventions:**
|
|
132
179
|
|
|
133
180
|
- `<script setup lang="ts">` for all Vue components
|
|
@@ -136,7 +183,7 @@ Implement the plan:
|
|
|
136
183
|
|
|
137
184
|
---
|
|
138
185
|
|
|
139
|
-
## Step
|
|
186
|
+
## Step 7: Verify
|
|
140
187
|
|
|
141
188
|
After building, check dependencies are installed and run a build:
|
|
142
189
|
|
|
@@ -151,7 +198,7 @@ Then suggest the user run `npm run dev` to preview their app locally.
|
|
|
151
198
|
|
|
152
199
|
---
|
|
153
200
|
|
|
154
|
-
## Step
|
|
201
|
+
## Step 8: Next Steps
|
|
155
202
|
|
|
156
203
|
> Your app is taking shape! Here's what you can do next:
|
|
157
204
|
>
|
package/package.json
CHANGED
package/rules/api.mdc
CHANGED
|
@@ -50,6 +50,29 @@ elemental_get_related(entity="Apple",
|
|
|
50
50
|
MCP tells you the correct flavor IDs, property IDs, and data shapes. Use
|
|
51
51
|
these to inform your REST implementation.
|
|
52
52
|
|
|
53
|
+
**Verify MCP is working with known-good queries:**
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
elemental_get_schema() → should return flavors + properties
|
|
57
|
+
elemental_get_entity(entity="Microsoft") → should resolve to a company
|
|
58
|
+
elemental_get_entity(entity="Apple Inc") → another known entity
|
|
59
|
+
elemental_health() → server health check
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Interpreting MCP errors — do NOT assume the server is broken:**
|
|
63
|
+
|
|
64
|
+
- `entity not found` or 404 in entity lookup → the entity doesn't exist
|
|
65
|
+
in the knowledge graph, not a connectivity problem. Try a different entity.
|
|
66
|
+
- `failed to get property values: 404` → the entity was resolved but has
|
|
67
|
+
no data for those properties. The MCP server is working correctly.
|
|
68
|
+
- Schema calls succeed but entity calls fail → data is sparse for that
|
|
69
|
+
entity type. Try well-known entities (Microsoft, Apple Inc, JPMorgan).
|
|
70
|
+
- If `elemental_health()` fails → actual connectivity problem.
|
|
71
|
+
|
|
72
|
+
**Key insight:** A 404 from an MCP entity/property call means "not found,"
|
|
73
|
+
not "server broken." Always test with known entities before concluding
|
|
74
|
+
the server is down.
|
|
75
|
+
|
|
53
76
|
### Step 2: curl (verify exact request/response shapes)
|
|
54
77
|
|
|
55
78
|
MCP doesn't cover every REST endpoint (e.g. `/elemental/find` expressions).
|
|
@@ -101,11 +124,44 @@ All other endpoints accept `application/json`.
|
|
|
101
124
|
**Interpreting errors:** 400 = expression syntax is wrong. 500 = expression
|
|
102
125
|
is valid but the query failed (wrong PID, unsupported operator for that
|
|
103
126
|
property type). 200 + empty `eids` = query worked but no results match.
|
|
127
|
+
404 from entity/property endpoints = entity or data doesn't exist (not a
|
|
128
|
+
server error). Always test with known entities (e.g. search for "Microsoft")
|
|
129
|
+
before assuming the API is broken.
|
|
104
130
|
|
|
105
131
|
### Step 3: Implement with confidence
|
|
106
132
|
|
|
107
133
|
Now write your composable or server route, knowing the exact API shapes.
|
|
108
134
|
|
|
135
|
+
## Pre-Built Helpers
|
|
136
|
+
|
|
137
|
+
The template includes composables and utilities that handle common
|
|
138
|
+
Elemental API patterns. **Use these instead of writing from scratch:**
|
|
139
|
+
|
|
140
|
+
### `useElementalSchema()` — Schema Discovery with Caching
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
const { flavors, properties, flavorByName, pidByName, refresh } = useElementalSchema();
|
|
144
|
+
await refresh(); // fetches once, then cached
|
|
145
|
+
const articleFid = flavorByName('article'); // → number | null
|
|
146
|
+
const namePid = pidByName('name'); // → typically 8
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Handles the dual response shapes (`res.schema.flavors` vs `res.flavors`)
|
|
150
|
+
and the `fid`/`findex` naming inconsistency automatically.
|
|
151
|
+
|
|
152
|
+
### `utils/elementalHelpers` — Gateway URL Helpers
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { buildGatewayUrl, getApiKey, padNeid, searchEntities, getEntityName } from '~/utils/elementalHelpers';
|
|
156
|
+
|
|
157
|
+
const url = buildGatewayUrl('entities/search'); // full gateway URL
|
|
158
|
+
const key = getApiKey(); // from runtimeConfig
|
|
159
|
+
const neid = padNeid('4926132345040704022'); // → "04926132345040704022"
|
|
160
|
+
|
|
161
|
+
const results = await searchEntities('Microsoft'); // batch name search
|
|
162
|
+
const name = await getEntityName(neid); // display name lookup
|
|
163
|
+
```
|
|
164
|
+
|
|
109
165
|
## Client Usage
|
|
110
166
|
|
|
111
167
|
All API calls go through `useElementalClient()` from `@yottagraph-app/elemental-api/client`.
|
package/rules/cookbook.mdc
CHANGED
|
@@ -388,7 +388,169 @@ Two-column layout with selectable list and detail panel.
|
|
|
388
388
|
</script>
|
|
389
389
|
```
|
|
390
390
|
|
|
391
|
-
## 7.
|
|
391
|
+
## 7. News Feed — Recent Articles with Sentiment
|
|
392
|
+
|
|
393
|
+
Fetch recent articles from the knowledge graph. Uses `useElementalSchema()`
|
|
394
|
+
for runtime flavor/PID discovery and `buildGatewayUrl()` for gateway access.
|
|
395
|
+
|
|
396
|
+
```vue
|
|
397
|
+
<template>
|
|
398
|
+
<div class="d-flex flex-column fill-height pa-4">
|
|
399
|
+
<h1 class="text-h5 mb-4">Recent News</h1>
|
|
400
|
+
<v-alert v-if="error" type="error" variant="tonal" class="mb-4" closable>
|
|
401
|
+
{{ error }}
|
|
402
|
+
</v-alert>
|
|
403
|
+
<v-progress-linear v-if="loading" indeterminate class="mb-4" />
|
|
404
|
+
<v-list v-if="articles.length" lines="three">
|
|
405
|
+
<v-list-item v-for="a in articles" :key="a.neid">
|
|
406
|
+
<template #title>
|
|
407
|
+
<span>{{ a.name || a.neid }}</span>
|
|
408
|
+
<v-chip
|
|
409
|
+
v-if="a.sentiment"
|
|
410
|
+
size="x-small"
|
|
411
|
+
class="ml-2"
|
|
412
|
+
:color="a.sentiment > 0 ? 'success' : a.sentiment < 0 ? 'error' : 'grey'"
|
|
413
|
+
>
|
|
414
|
+
{{ a.sentiment > 0 ? 'Bullish' : a.sentiment < 0 ? 'Bearish' : 'Neutral' }}
|
|
415
|
+
</v-chip>
|
|
416
|
+
</template>
|
|
417
|
+
<template #subtitle>{{ a.neid }}</template>
|
|
418
|
+
</v-list-item>
|
|
419
|
+
</v-list>
|
|
420
|
+
<v-empty-state
|
|
421
|
+
v-else-if="!loading"
|
|
422
|
+
headline="No articles found"
|
|
423
|
+
icon="mdi-newspaper-variant-outline"
|
|
424
|
+
/>
|
|
425
|
+
</div>
|
|
426
|
+
</template>
|
|
427
|
+
|
|
428
|
+
<script setup lang="ts">
|
|
429
|
+
import { useElementalClient } from '@yottagraph-app/elemental-api/client';
|
|
430
|
+
import { padNeid } from '~/utils/elementalHelpers';
|
|
431
|
+
|
|
432
|
+
const client = useElementalClient();
|
|
433
|
+
const { flavorByName, pidByName, refresh: loadSchema } = useElementalSchema();
|
|
434
|
+
|
|
435
|
+
const articles = ref<{ neid: string; name: string; sentiment: number | null }[]>([]);
|
|
436
|
+
const loading = ref(false);
|
|
437
|
+
const error = ref<string | null>(null);
|
|
438
|
+
|
|
439
|
+
onMounted(async () => {
|
|
440
|
+
loading.value = true;
|
|
441
|
+
try {
|
|
442
|
+
await loadSchema();
|
|
443
|
+
const articleFid = flavorByName('article');
|
|
444
|
+
if (!articleFid) {
|
|
445
|
+
error.value = 'Article entity type not found in schema';
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const res = await client.findEntities({
|
|
450
|
+
expression: JSON.stringify({ type: 'is_type', is_type: { fid: articleFid } }),
|
|
451
|
+
limit: 20,
|
|
452
|
+
});
|
|
453
|
+
const neids: string[] = (res as any).eids ?? [];
|
|
454
|
+
|
|
455
|
+
if (!neids.length) {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
const namePid = pidByName('name');
|
|
460
|
+
const sentimentPid = pidByName('sentiment');
|
|
461
|
+
const pids = [namePid, sentimentPid].filter((p): p is number => p !== null);
|
|
462
|
+
|
|
463
|
+
const props = await client.getPropertyValues({
|
|
464
|
+
eids: JSON.stringify(neids),
|
|
465
|
+
pids: JSON.stringify(pids),
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
const valueMap = new Map<string, Record<number, any>>();
|
|
469
|
+
for (const v of (props as any).values ?? []) {
|
|
470
|
+
const eid = padNeid(v.eid ?? v.entity_id ?? '');
|
|
471
|
+
if (!valueMap.has(eid)) valueMap.set(eid, {});
|
|
472
|
+
valueMap.get(eid)![v.pid] = v.value;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
articles.value = neids.map((neid) => {
|
|
476
|
+
const vals = valueMap.get(neid) ?? {};
|
|
477
|
+
return {
|
|
478
|
+
neid,
|
|
479
|
+
name: namePid ? (vals[namePid] as string) ?? neid : neid,
|
|
480
|
+
sentiment: sentimentPid ? (vals[sentimentPid] as number) ?? null : null,
|
|
481
|
+
};
|
|
482
|
+
});
|
|
483
|
+
} catch (e: any) {
|
|
484
|
+
error.value = e.message || 'Failed to load articles';
|
|
485
|
+
} finally {
|
|
486
|
+
loading.value = false;
|
|
487
|
+
}
|
|
488
|
+
});
|
|
489
|
+
</script>
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
## 8. Entity Search with Gateway Helpers
|
|
493
|
+
|
|
494
|
+
Simpler version of recipe #1 using the pre-built `searchEntities()` helper.
|
|
495
|
+
|
|
496
|
+
```vue
|
|
497
|
+
<template>
|
|
498
|
+
<div class="d-flex flex-column fill-height pa-4">
|
|
499
|
+
<h1 class="text-h5 mb-4">Entity Search</h1>
|
|
500
|
+
<v-text-field
|
|
501
|
+
v-model="query"
|
|
502
|
+
label="Search entities"
|
|
503
|
+
prepend-inner-icon="mdi-magnify"
|
|
504
|
+
variant="outlined"
|
|
505
|
+
@keyup.enter="search"
|
|
506
|
+
:loading="loading"
|
|
507
|
+
/>
|
|
508
|
+
<v-alert v-if="error" type="error" variant="tonal" class="mt-2" closable>
|
|
509
|
+
{{ error }}
|
|
510
|
+
</v-alert>
|
|
511
|
+
<v-list v-if="results.length" class="mt-4">
|
|
512
|
+
<v-list-item
|
|
513
|
+
v-for="r in results"
|
|
514
|
+
:key="r.neid"
|
|
515
|
+
:title="r.name"
|
|
516
|
+
:subtitle="r.neid"
|
|
517
|
+
/>
|
|
518
|
+
</v-list>
|
|
519
|
+
<v-empty-state
|
|
520
|
+
v-else-if="searched && !loading"
|
|
521
|
+
headline="No results"
|
|
522
|
+
icon="mdi-magnify-remove-outline"
|
|
523
|
+
/>
|
|
524
|
+
</div>
|
|
525
|
+
</template>
|
|
526
|
+
|
|
527
|
+
<script setup lang="ts">
|
|
528
|
+
import { searchEntities } from '~/utils/elementalHelpers';
|
|
529
|
+
|
|
530
|
+
const query = ref('');
|
|
531
|
+
const results = ref<{ neid: string; name: string }[]>([]);
|
|
532
|
+
const loading = ref(false);
|
|
533
|
+
const error = ref<string | null>(null);
|
|
534
|
+
const searched = ref(false);
|
|
535
|
+
|
|
536
|
+
async function search() {
|
|
537
|
+
if (!query.value.trim()) return;
|
|
538
|
+
loading.value = true;
|
|
539
|
+
error.value = null;
|
|
540
|
+
searched.value = true;
|
|
541
|
+
try {
|
|
542
|
+
results.value = await searchEntities(query.value.trim());
|
|
543
|
+
} catch (e: any) {
|
|
544
|
+
error.value = e.message || 'Search failed';
|
|
545
|
+
results.value = [];
|
|
546
|
+
} finally {
|
|
547
|
+
loading.value = false;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
</script>
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
## 9. Get Filings for a Company
|
|
392
554
|
|
|
393
555
|
Fetch Edgar filings (or any relationship-linked documents) for an organization.
|
|
394
556
|
Uses `$fetch` for the initial entity search because `POST /entities/search`
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Data Dictionary — BNY Arbitrage Rebate Analysis
|
|
2
|
+
|
|
3
|
+
## Source Description
|
|
4
|
+
|
|
5
|
+
Interim Arbitrage Rebate Analysis reports prepared by BLX Group LLC for
|
|
6
|
+
municipal bond issuers. Each report computes the arbitrage rebate liability
|
|
7
|
+
under IRC Section 148 for a bond issue across a computation period. Reports
|
|
8
|
+
include transmittal letters, legal opinions, notes/assumptions, summary
|
|
9
|
+
schedules (rebate analysis, sources/uses of funds), and detailed per-fund
|
|
10
|
+
cash flow and investment data.
|
|
11
|
+
|
|
12
|
+
BNY (Bank of New York Mellon) serves as trustee. Orrick, Herrington &
|
|
13
|
+
Sutcliffe LLP provides the accompanying legal opinion.
|
|
14
|
+
|
|
15
|
+
## Entity Types
|
|
16
|
+
|
|
17
|
+
### bond
|
|
18
|
+
|
|
19
|
+
The municipal bond issue itself. One entity per unique bond across all reports.
|
|
20
|
+
|
|
21
|
+
| Property | Type | Description |
|
|
22
|
+
|----------|------|-------------|
|
|
23
|
+
| `client_matter_number` | string | **Strong ID.** BLX Group client matter number (e.g. `42182-2748`). Invariant across all reports for the same bond. |
|
|
24
|
+
| `bonds_name` | string | Full name of the bonds (e.g. "Multifamily Housing Revenue Refunding Bonds (Presidential Plaza at Newport Project-FHA Insured Mortgages) 1991 Series 1") |
|
|
25
|
+
| `par_amount` | string | Total par amount of the bond issue (e.g. "$142,235,000") |
|
|
26
|
+
| `dated_date` | string | Dated date of the bonds (e.g. "September 15, 1991") |
|
|
27
|
+
| `issue_date` | string | Issue date of the bonds (e.g. "October 17, 1991") |
|
|
28
|
+
| `bond_yield` | string | Arbitrage yield / allowable yield on investments (e.g. "7.420898%") |
|
|
29
|
+
| `computation_period` | string | The computation period for this report (e.g. "October 17, 1991 through October 16, 2024") |
|
|
30
|
+
| `rebate_computation_date` | string | End date of the computation period (e.g. "October 16, 2024") |
|
|
31
|
+
| `cumulative_rebate_liability` | string | Total cumulative rebate liability (e.g. "$0.00") |
|
|
32
|
+
| `rebate_payment_due` | string | Amount due to the US (e.g. "$0.00") |
|
|
33
|
+
| `return_on_investments` | string | Weighted return on investments since prior computation date (e.g. "6.447251%") |
|
|
34
|
+
| `shortfall_pct` | string | Shortfall percentage: return minus yield (e.g. "-0.973647%") |
|
|
35
|
+
| `actual_gross_earnings` | string | Total actual gross earnings across all funds |
|
|
36
|
+
| `allowable_gross_earnings` | string | Total allowable gross earnings at bond yield |
|
|
37
|
+
| `excess_earnings` | string | Total excess (negative = under yield) |
|
|
38
|
+
| `report_date` | string | Date the report was issued (e.g. "December 6, 2024") |
|
|
39
|
+
|
|
40
|
+
### organization
|
|
41
|
+
|
|
42
|
+
Companies, agencies, law firms, and financial institutions named in the reports.
|
|
43
|
+
|
|
44
|
+
| Property | Type | Description |
|
|
45
|
+
|----------|------|-------------|
|
|
46
|
+
| `org_type` | string | Type: `government_agency`, `law_firm`, `financial_services`, `financial_institution`, `trust_company` |
|
|
47
|
+
| `description` | string | Role in the deal (e.g. "Issuer", "Trustee", "Bond Counsel") |
|
|
48
|
+
|
|
49
|
+
Expected entities:
|
|
50
|
+
- New Jersey Housing and Mortgage Finance Agency (Issuer)
|
|
51
|
+
- BLX Group LLC (Rebate Analyst)
|
|
52
|
+
- Orrick, Herrington & Sutcliffe LLP (Bond Counsel)
|
|
53
|
+
- BNY / Bank of New York Mellon (Trustee)
|
|
54
|
+
- Willdan Financial Services (Prior Report preparer)
|
|
55
|
+
- U.S. Department of the Treasury
|
|
56
|
+
|
|
57
|
+
### fund_account
|
|
58
|
+
|
|
59
|
+
Bond proceeds sub-accounts tracked for rebate computation purposes.
|
|
60
|
+
|
|
61
|
+
| Property | Type | Description |
|
|
62
|
+
|----------|------|-------------|
|
|
63
|
+
| `fund_status` | string | Current status: `Active` or `Inactive` |
|
|
64
|
+
| `computation_date_valuation` | string | Fair market value at computation date |
|
|
65
|
+
| `gross_earnings` | string | Total gross earnings for the fund |
|
|
66
|
+
| `internal_rate_of_return` | string | IRR on the fund's investments |
|
|
67
|
+
| `excess_earnings` | string | Excess earnings (negative = below yield) |
|
|
68
|
+
|
|
69
|
+
Expected entities:
|
|
70
|
+
- Reserve I Account
|
|
71
|
+
- Reserve II Account
|
|
72
|
+
- Prior Rebate Liability
|
|
73
|
+
- Liquidity I Account
|
|
74
|
+
- Liquidity II Account
|
|
75
|
+
|
|
76
|
+
Additional fund accounts mentioned in Notes and Assumptions:
|
|
77
|
+
- Revenue Account (bona fide debt service fund, excluded from rebate)
|
|
78
|
+
- Escrow Fund
|
|
79
|
+
- Debt Service Reserve Account
|
|
80
|
+
- Construction Account
|
|
81
|
+
|
|
82
|
+
### financial_instrument
|
|
83
|
+
|
|
84
|
+
Securities held within fund accounts (investments of bond proceeds).
|
|
85
|
+
|
|
86
|
+
| Property | Type | Description |
|
|
87
|
+
|----------|------|-------------|
|
|
88
|
+
| `par_amount` | string | Par amount of the security |
|
|
89
|
+
| `coupon` | string | Coupon rate (e.g. "7.000%" or "Variable") |
|
|
90
|
+
| `maturity_date` | string | Maturity date |
|
|
91
|
+
| `settlement_date` | string | Settlement date |
|
|
92
|
+
| `settlement_price` | string | Settlement price (e.g. "100.000") |
|
|
93
|
+
| `yield` | string | Yield on the security |
|
|
94
|
+
| `accreted_price` | string | Accreted price |
|
|
95
|
+
| `accrued_interest` | string | Accrued interest amount |
|
|
96
|
+
| `value` | string | Total value (par + accrued interest) |
|
|
97
|
+
|
|
98
|
+
Expected entities (scoped per fund via `entity_context_from_title`):
|
|
99
|
+
- Morgan IA (7% coupon, institutional investment)
|
|
100
|
+
- Federated MM (variable rate money market fund)
|
|
101
|
+
|
|
102
|
+
### legal_agreement
|
|
103
|
+
|
|
104
|
+
Governing legal documents referenced in the reports.
|
|
105
|
+
|
|
106
|
+
| Property | Type | Description |
|
|
107
|
+
|----------|------|-------------|
|
|
108
|
+
| `agreement_type` | string | Type: `arbitrage_certificate`, `trust_indenture`, `engagement_letter` |
|
|
109
|
+
| `description` | string | Description of the agreement's role |
|
|
110
|
+
|
|
111
|
+
Expected entities:
|
|
112
|
+
- Certificate as to Arbitrage (Section 8, Section 21 referenced)
|
|
113
|
+
- Prior Report (Willdan Financial Services, December 17, 2008)
|
|
114
|
+
|
|
115
|
+
### location
|
|
116
|
+
|
|
117
|
+
Addresses and jurisdictions.
|
|
118
|
+
|
|
119
|
+
Expected entities:
|
|
120
|
+
- Trenton, NJ (Issuer address)
|
|
121
|
+
- Dallas, TX (BLX Group address)
|
|
122
|
+
- New York, NY (Orrick address)
|
|
123
|
+
- State of New Jersey
|
|
124
|
+
|
|
125
|
+
### person
|
|
126
|
+
|
|
127
|
+
Signatories, if extractable from signatures on transmittal letters and opinions.
|
|
128
|
+
May be sparse — many PDFs have illegible or absent signature blocks.
|
|
129
|
+
|
|
130
|
+
## Relationships
|
|
131
|
+
|
|
132
|
+
| Relationship | Domain | Target | Description |
|
|
133
|
+
|-------------|--------|--------|-------------|
|
|
134
|
+
| `issuer_of` | organization | bond | Issuer issued the bonds |
|
|
135
|
+
| `trustee_of` | organization | bond | Trustee of the bond issue |
|
|
136
|
+
| `advisor_to` | organization | bond | BLX Group as rebate analyst; Orrick as bond counsel |
|
|
137
|
+
| `fund_of` | fund_account | bond | Fund account belongs to the bond issue |
|
|
138
|
+
| `holds_investment` | fund_account | financial_instrument | Fund holds a security as an investment |
|
|
139
|
+
| `party_to` | organization | legal_agreement | Entity is party to an agreement |
|
|
140
|
+
| `located_at` | organization | location | Organization's address |
|
|
141
|
+
| `predecessor_of` | legal_agreement | legal_agreement | Prior Report preceded current Report |
|
|
142
|
+
|
|
143
|
+
## Events
|
|
144
|
+
|
|
145
|
+
| Event | Severity | Description |
|
|
146
|
+
|-------|----------|-------------|
|
|
147
|
+
| Rebate computation | medium | Periodic computation of arbitrage rebate liability |
|
|
148
|
+
| Bond issuance | high | Original issuance of the bonds (October 17, 1991) |
|
|
149
|
+
| Bond refunding | high | Refunding of prior 1985 Series F and G bonds |
|
|
150
|
+
| Fund valuation | medium | Valuation of fund accounts at computation date |
|
|
151
|
+
| Rebate payment determination | high | Determination that rebate payment is/isn't due |
|
|
152
|
+
| Report issuance | low | Issuance of this rebate analysis report |
|
|
153
|
+
|
|
154
|
+
## Table Extraction
|
|
155
|
+
|
|
156
|
+
### Schedule A — Summary of Rebate Analysis
|
|
157
|
+
|
|
158
|
+
Maps to `rebate_analysis` table config. Key column: Fund Description.
|
|
159
|
+
Each row becomes a `fund_account` entity with properties for status,
|
|
160
|
+
valuation, earnings, IRR, and excess earnings.
|
|
161
|
+
|
|
162
|
+
### Schedule B — Sources & Uses of Funds
|
|
163
|
+
|
|
164
|
+
Maps to `sources_of_funds` and `uses_of_funds` table configs. Uses
|
|
165
|
+
`document_entity_from_title` mode to attach line items as properties
|
|
166
|
+
on the bond entity.
|
|
167
|
+
|
|
168
|
+
### Security Holdings (Schedules C1, D1, F1, G1)
|
|
169
|
+
|
|
170
|
+
Maps to `security_tables` config. Key column: Security Type. Each
|
|
171
|
+
security becomes a `financial_instrument` entity scoped by fund
|
|
172
|
+
account title. Properties: par amount, coupon, maturity, yield, etc.
|
|
173
|
+
|
|
174
|
+
### Cash Flow Tables (Schedules C2, D2, E1, F2, G2)
|
|
175
|
+
|
|
176
|
+
New table config needed. These are the largest tables — hundreds of rows
|
|
177
|
+
of deposit/withdrawal transactions for each fund account. Columns:
|
|
178
|
+
Date, Description, Cash Flow, Muni-Days/Computation Date, FV Factor
|
|
179
|
+
at bond yield, FV As Of at bond yield, FV Factor at IRR, FV As Of at IRR.
|
|
180
|
+
|
|
181
|
+
## Citations
|
|
182
|
+
|
|
183
|
+
All extracted data should cite the specific schedule and page number
|
|
184
|
+
within the source PDF. The PDF filename serves as the document identifier.
|