alphacouncil-agent 1.0.3 → 1.0.4
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +25 -0
- package/data/build-profile.v1.json +1 -1
- package/mcp/lib/council-options.mjs +8 -4
- package/mcp/lib/fundamentals.mjs +50 -10
- package/mcp/lib/xbrl-series.mjs +10 -3
- package/package.json +1 -1
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "AlphaCouncil plugins for public-equity research.",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.4"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "alphacouncil-agent",
|
|
14
14
|
"source": "./",
|
|
15
15
|
"description": "Multi-agent company, ETF and index research: evidence packets, method seats, bull/bear debate and portfolio-manager synthesis.",
|
|
16
|
-
"version": "1.0.
|
|
16
|
+
"version": "1.0.4",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "Zhao73"
|
|
19
19
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alphacouncil-agent",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Multi-agent company, ETF and market-index research for Claude Code with sourced evidence, method seats, bull/bear debate and a full portfolio-manager report.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Zhao73"
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
Notable changes per release. Dates are UTC.
|
|
4
4
|
|
|
5
|
+
## [1.0.4] — 2026-07-29
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- **Total liabilities had one tag and many filers use none of it.** Net current asset value, the
|
|
10
|
+
downside asset value and the downside floor all failed on `Liabilities`, silencing Graham,
|
|
11
|
+
Burry, Klarman and Pabrai. It is now reconstructed where a filer tags the balance-sheet total
|
|
12
|
+
and equity instead — but only against the equity tag that INCLUDES non-controlling interests,
|
|
13
|
+
where the identity is exact. With the parent-only tag minority interest lands inside
|
|
14
|
+
"liabilities" and nothing says so, which is why the previous refusal was right and is kept
|
|
15
|
+
wherever that tag is absent.
|
|
16
|
+
- **Revenue growth insisted the last eight filings were its window.** One restated quarter, one
|
|
17
|
+
stub period or one duplicate at the end discarded a company's entire revenue history. It now
|
|
18
|
+
searches backwards for the most recent clean pair of four-quarter blocks; each window is
|
|
19
|
+
checked exactly as strictly as before, only the search moved.
|
|
20
|
+
|
|
21
|
+
Measured: INTC and WMT go from six of eight derived fundamentals to **eight of eight**, GLW to
|
|
22
|
+
seven.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- The seat selector labels an `operator_lens` as a method lens rather than leading with
|
|
27
|
+
"provisional". The machine-verified admission level is unchanged and still published as
|
|
28
|
+
`admission_level`.
|
|
29
|
+
|
|
5
30
|
## [1.0.3] — 2026-07-29
|
|
6
31
|
|
|
7
32
|
Three real runs are the specification: a GLW run put all eight selected seats at `out_of_scope`
|
|
@@ -100,11 +100,15 @@ export function councilOptions({ language = "English" } = {}) {
|
|
|
100
100
|
best_for: field(v3Selection.best_for, "best_for"),
|
|
101
101
|
} : selectorCard(persona, language)),
|
|
102
102
|
maturity: v3?.maturity || pack?.kind || "prompt_lens",
|
|
103
|
+
// The label names what a seat IS. It used to lead with "provisional", which read as a
|
|
104
|
+
// standing warning next to all twenty-seven names in the selector and repeated a review
|
|
105
|
+
// status the assurance section already reports. The machine-verified admission level is
|
|
106
|
+
// unchanged and still published as `admission_level` below.
|
|
103
107
|
maturity_label: copy({
|
|
104
|
-
en: v3?.maturity === "method_model" ? "Validated method model" : v3?.maturity === "candidate" ? "Candidate method" : "
|
|
105
|
-
zh: v3?.maturity === "method_model" ? "已验证方法模型" : v3?.maturity === "candidate" ? "候选方法" : "
|
|
106
|
-
ja: v3?.maturity === "method_model" ? "検証済みメソッドモデル" : v3?.maturity === "candidate" ? "候補メソッド" : "
|
|
107
|
-
ko: v3?.maturity === "method_model" ? "검증된 방법론 모델" : v3?.maturity === "candidate" ? "후보 방법론" : "
|
|
108
|
+
en: v3?.maturity === "method_model" ? "Validated method model" : v3?.maturity === "candidate" ? "Candidate method" : "Operator method lens",
|
|
109
|
+
zh: v3?.maturity === "method_model" ? "已验证方法模型" : v3?.maturity === "candidate" ? "候选方法" : "方法透镜",
|
|
110
|
+
ja: v3?.maturity === "method_model" ? "検証済みメソッドモデル" : v3?.maturity === "candidate" ? "候補メソッド" : "メソッド・レンズ",
|
|
111
|
+
ko: v3?.maturity === "method_model" ? "검증된 방법론 모델" : v3?.maturity === "candidate" ? "후보 방법론" : "방법론 렌즈",
|
|
108
112
|
}),
|
|
109
113
|
runtime_level: v3?.admission?.level || (pack ? "v2_operator" : "v1_prompt"),
|
|
110
114
|
admission_level: v3?.admission?.level || (pack ? "operator_lens" : "prompt_lens"),
|
package/mcp/lib/fundamentals.mjs
CHANGED
|
@@ -182,17 +182,40 @@ function ownerEarnings(series, cik, gaps, proxy) {
|
|
|
182
182
|
});
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
/**
|
|
186
|
+
* Total liabilities, tagged where the filer tags it and reconstructed exactly where not.
|
|
187
|
+
*
|
|
188
|
+
* Many filers never tag `Liabilities`; they tag the balance-sheet total and equity. The
|
|
189
|
+
* subtraction is only safe against the INCLUDING-non-controlling-interests equity tag -- with
|
|
190
|
+
* the parent-only tag, minority interest lands inside "liabilities" and nothing says so. When
|
|
191
|
+
* that tag is absent the figure stays missing, which is why this returns null rather than
|
|
192
|
+
* reaching for the nearest number.
|
|
193
|
+
*/
|
|
194
|
+
function totalLiabilitiesFor(series, gaps, factId) {
|
|
195
|
+
const direct = alignLatest(series, ["current_assets", "total_liabilities"]);
|
|
196
|
+
if (direct.ok) {
|
|
197
|
+
return { alignment: direct, value: direct.entries.total_liabilities.value, basis: "filed_total_liabilities" };
|
|
198
|
+
}
|
|
199
|
+
const derived = alignLatest(series, ["current_assets", "liabilities_and_equity", "equity_including_nci"]);
|
|
200
|
+
if (!derived.ok) {
|
|
201
|
+
gaps.push(alignmentGap(factId, direct, ["current_assets", "total_liabilities"]));
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
alignment: derived,
|
|
206
|
+
value: derived.entries.liabilities_and_equity.value - derived.entries.equity_including_nci.value,
|
|
207
|
+
basis: "balance_sheet_total_less_equity_including_noncontrolling_interests",
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
185
211
|
/** 2. Graham NCAV: current assets - total liabilities. */
|
|
186
212
|
function netCurrentAssetValue(series, cik, gaps) {
|
|
187
213
|
const factId = "financial.net_current_asset_value";
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
gaps.push(alignmentGap(factId, alignment, concepts));
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
214
|
+
const resolved = totalLiabilitiesFor(series, gaps, factId);
|
|
215
|
+
if (!resolved) return null;
|
|
216
|
+
const alignment = resolved.alignment;
|
|
194
217
|
const currentAssets = alignment.entries.current_assets.value;
|
|
195
|
-
const liabilities =
|
|
218
|
+
const liabilities = resolved.value;
|
|
196
219
|
return buildMetric({
|
|
197
220
|
factId,
|
|
198
221
|
valueKind: "monetary",
|
|
@@ -207,6 +230,9 @@ function netCurrentAssetValue(series, cik, gaps) {
|
|
|
207
230
|
assumptions: [
|
|
208
231
|
"Graham NCAV as filed: current assets less ALL liabilities, with no haircut applied to receivables or inventory",
|
|
209
232
|
"an unclassified balance sheet (banks, insurers, many REITs) files no AssetsCurrent, which is reported as a gap rather than substituted",
|
|
233
|
+
resolved.basis === "filed_total_liabilities"
|
|
234
|
+
? "total liabilities taken from the filer's own Liabilities tag"
|
|
235
|
+
: "the filer tags no Liabilities total, so it is the balance-sheet total less equity INCLUDING non-controlling interests, which is exact rather than approximate",
|
|
210
236
|
],
|
|
211
237
|
});
|
|
212
238
|
}
|
|
@@ -465,10 +491,24 @@ function trailingYearOverYear(companyFacts, asOf) {
|
|
|
465
491
|
},
|
|
466
492
|
};
|
|
467
493
|
}
|
|
468
|
-
|
|
469
|
-
|
|
494
|
+
// Search backwards for the most recent pair of clean four-quarter blocks rather than
|
|
495
|
+
// insisting the last eight filings are them. One restated quarter, one stub period or one
|
|
496
|
+
// duplicated filing at the end used to discard a company's entire revenue history -- INTC and
|
|
497
|
+
// GLW both failed here while holding years of usable quarters behind the ragged edge. Each
|
|
498
|
+
// window is still checked exactly as strictly; only the search moved.
|
|
499
|
+
let latest = null;
|
|
500
|
+
let prior = null;
|
|
501
|
+
let offset = 0;
|
|
502
|
+
for (; offset <= quarters.length - 8; offset += 1) {
|
|
503
|
+
const end = quarters.length - 1 - offset;
|
|
504
|
+
latest = fourQuarters(quarters, end);
|
|
505
|
+
prior = fourQuarters(quarters, end - 4);
|
|
506
|
+
if (latest && prior) break;
|
|
507
|
+
latest = null;
|
|
508
|
+
prior = null;
|
|
509
|
+
}
|
|
470
510
|
if (!latest || !prior) {
|
|
471
|
-
return { ...empty, gap: { code: "period_misaligned", detail:
|
|
511
|
+
return { ...empty, gap: { code: "period_misaligned", detail: `no contiguous pair of four-quarter blocks in the ${quarters.length} tagged quarters` } };
|
|
472
512
|
}
|
|
473
513
|
if (!(prior.total > 0)) {
|
|
474
514
|
return { ...empty, gap: { code: "non_positive_base", detail: `prior-year four-quarter revenue is ${prior.total}` } };
|
package/mcp/lib/xbrl-series.mjs
CHANGED
|
@@ -29,9 +29,14 @@ export const MAX_ALIGNMENT_DRIFT_DAYS = 45;
|
|
|
29
29
|
/**
|
|
30
30
|
* Concept aliases, ordered by preference, on top of the ones sec.mjs already publishes.
|
|
31
31
|
*
|
|
32
|
-
* Aliases inside one entry are the same economic quantity under different taxonomies. They
|
|
33
|
-
*
|
|
34
|
-
*
|
|
32
|
+
* Aliases inside one entry are the same economic quantity under different taxonomies. They are
|
|
33
|
+
* never a fallback to a different concept: a missing depreciation tag stays missing.
|
|
34
|
+
*
|
|
35
|
+
* Total liabilities has one sanctioned reconstruction and it is guarded. Subtracting equity
|
|
36
|
+
* from the balance-sheet total is wrong when the two tags disagree about non-controlling
|
|
37
|
+
* interests -- the difference then lands inside "liabilities", silently. Done against the
|
|
38
|
+
* INCLUDING-NCI equity tag the identity is exact, so that tag, and only that tag, may stand in
|
|
39
|
+
* where a filer never tags `Liabilities` directly. See `totalLiabilitiesFor`.
|
|
35
40
|
*/
|
|
36
41
|
export const FUNDAMENTAL_CONCEPTS = Object.freeze({
|
|
37
42
|
revenue: { tags: CONCEPTS.revenue, unit: "USD" },
|
|
@@ -50,6 +55,8 @@ export const FUNDAMENTAL_CONCEPTS = Object.freeze({
|
|
|
50
55
|
},
|
|
51
56
|
current_assets: { tags: ["AssetsCurrent"], unit: "USD" },
|
|
52
57
|
total_liabilities: { tags: ["Liabilities"], unit: "USD" },
|
|
58
|
+
liabilities_and_equity: { tags: ["LiabilitiesAndStockholdersEquity"], unit: "USD" },
|
|
59
|
+
equity_including_nci: { tags: ["StockholdersEquityIncludingPortionAttributableToNoncontrollingInterest"], unit: "USD" },
|
|
53
60
|
goodwill: { tags: ["Goodwill"], unit: "USD" },
|
|
54
61
|
intangibles: { tags: ["IntangibleAssetsNetExcludingGoodwill", "FiniteLivedIntangibleAssetsNet"], unit: "USD" },
|
|
55
62
|
cash: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alphacouncil-agent",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Multi-agent company, ETF and market-index research workflow for Codex & Claude Code: sourced evidence, method seats, bull/bear debate and portfolio-manager synthesis.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|