AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Parallax Make House View

skill-bencharoenwong-parallax-workflows-parallax-make-house-view · by bencharoenwong

Synthesize a draft Parallax house view by orchestrating macro_analyst + get_telemetry MCP outputs across the 14 covered markets, route the draft through the shared confirmation gate, and save through the same path /parallax-load-house-view uses. The synthesized view carries `generator_synthesis` provenance (distinct from ingested views' `prose_extraction`) and lands in `~/.parallax/active-house-v…

No reviews yet
0 installs
1 views
0.0% view→install

Install

$ agentstack add skill-bencharoenwong-parallax-workflows-parallax-make-house-view

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-bencharoenwong-parallax-workflows-parallax-make-house-view)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
yesterday

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Parallax Make House View? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Make House View

When not to use

  • Ingesting a CIO PDF / URL / wizard input → use /parallax-load-house-view
  • Judging an active view against live signals → use /parallax-judge-house-view
  • Stress-testing for internal consistency → use /parallax-stress-house-view
  • Per-cell tilt diff of two saved views (e.g. UBS vs Goldman) → use /parallax-make-house-view --compare
  • Diff of two portfolio outputs (view vs baseline) → use /parallax-house-view-diff

Gotchas

  • JIT-load _parallax/house-view/MCP_FIELD_INVENTORY.md BEFORE assuming any component input is available. valuation_state / market_entropy are prose-extracted; psychological_wavelength is LLM-judged. Confidence caps differ per component.
  • The shared gate (_parallax/house-view/gate_present.py) is REQUIRED — there is no save path that bypasses it. --shadow-diff skips the gate AND the save.
  • --compare is a pure structural file diff of two saved bundles: it skips MCP, synthesis, the gate, the save, the audit row, AND all output disclaimers. It never emits a pillar-confidence block (keep pillar internals out of any cross-firm output).
  • Fan-out budget is 14 markets × 4 components = 56 macroanalyst calls + 1 listmacrocountries + 1 gettelemetry. Concurrency cap 8. Per-market timeout 45s. Hard abort when unreachable_share > 30%.
  • Reuse audit_chain.append_entry, chain_emit.emit_phase_0_chain, provenance_classes.validate_provenance_entry. NEVER reimplement.
  • The generate audit row carries ONLY: schemaversion, ts, viewid, versionid, viewhash, skill, action, applied, parentversionid, provenancehash, sourcetools, calibrationstatus. compositionformula / aggregatorweightsref / sourcesnippets / pillarmissing_inputs MUST go in provenance.yaml, NOT on the audit row.
  • psychological_wavelength judgment is Claude-only (data perimeter — telemetry contains CG-proprietary signals, do NOT dispatch to external models).
  • Synthesized views carry auto_expire_days: 30 (shorter than ingested views' 90) because the underlying macro fan-out is point-in-time.
  • §9.2 exemption: this skill does NOT render the AI-interaction disclosure banner. It emits configuration artifacts (view.yaml + prose.md) whose LLM-synthesized content is gated by the Step 7 operator confirmation gate before any downstream consumer can load the view — and every downstream consumer renders §9.2 in its own output per loader.md §5 rule 6. Rationale and conditions: parallax-conventions.md §9.2 "Exemption". Registered in _NINE_TWO_EXEMPT_SKILLS in the white-label test gate.

Synthesize a draft Parallax house view by orchestrating Parallax MCP tools (list_macro_countries + macro_analyst × 14 markets × 4 components + get_telemetry), aggregate cross-country, compose the four framework components (macro backdrop, valuation, market state, sentiment), route through the shared confirmation gate, and save through the same path /parallax-load-house-view uses.

The synthesized view lives in ~/.parallax/active-house-view/ and is consumed by every downstream skill (portfolio-builder, rebalance, thematic-screen, etc.) exactly like an ingested view — the only difference is the provenance class (generator_synthesis vs prose_extraction) and a shorter default auto_expire_days.

Usage

/parallax-make-house-view                              # synthesize, route to gate, save
/parallax-make-house-view --shadow-diff                # synthesize, DO NOT save; diff vs active view
/parallax-make-house-view --basis ""             # bias synthesis with a textual hint
/parallax-make-house-view --markets us,japan,uk        # restrict fan-out scope (cost / debug)
/parallax-make-house-view --status                     # show last-generated view metadata
/parallax-make-house-view --compare    # diff two saved view bundles; no MCP, no synthesis, no save

Cost: ~282 tokens at the default market set (~14 markets × 4 components; see _parallax/token-costs.md); --markets scales cost proportionally.

Workflow

Call ToolSearch with query "+Parallax" to load the deferred MCP tool schemas before the first mcp__claude_ai_Parallax__* call. JIT-load _parallax/house-view/MCP_FIELD_INVENTORY.md (per-pillar input availability), _parallax/house-view/schema.yaml (view shape + classification_taxonomy.generator_synthesis), and _parallax/house-view/loader.md (esp. §6 audit format with the new generate action).

Step 1 — Resolve covered markets

Call list_macro_countries(). Expect 15 entries (14 country reports + "Global"). Exclude "Global" from per-country fan-out (it's an aggregate, would double-count). When --markets filter is set, intersect with the live coverage.

Fallback: if list_macro_countries fails, use the hardcoded HARDCODED_COVERAGE tuple in maker.py (14 markets matching aggregator_weights.yaml).

Step 2 + 3 — Parallel fan-out

Fire in parallel (concurrency cap 8, per-call timeout 45s):

  • Step 2 (batch): macro_analyst(market=M, component=C) for every (M, C) pair where M ∈ covered_markets and C ∈ {macro_indicators, tactical, sectors, news}. Budget: 14 × 4 = 56 calls. (fixed_income is deferred — no v0 formula consumes it; re-add it in the same change that lands a rates leg in pillar_formulas.py.)
  • Step 3 (single call, parallel with Step 2): get_telemetry(fields=["regime_tag", "divergences", "factor_view.factors", "factor_view.commentary", "signals", "commentary"]).

Per-market timeout: 45s. A market is UNREACHABLE when no component returns a response whose shape can be interpreted — absent, not a mapping, or carrying neither a success nor an error key. That rule is _parallax/house-view/mcp_meta.py (carries_data), the same predicate backing stress.classify_mcp_meta_state's UNREACHABLE branch, so the maker and the stress classifier cannot disagree about what counts as a dead market. A market that returns a successful response with content like "Sector ranking data remains unavailable for this reporting period" — or an explicit success: false — is treated as silent for that component, not UNREACHABLE for the market (per MCPFIELDINVENTORY.md §5.4): the server answered, and only an uninterpretable shape fails closed.

If unreachable_share > 0.30 of the fan-out, HARD ABORT. Aggregation can't recover from that level of degradation.

Step 4 — Cross-country aggregation

Call cross_country.aggregate(per_market_responses, telemetry, weights). Outputs:

  • phi.value / phi.coverage_ok / phi.markets_with_data: weighted-median of per-market valuation_state prose-extracted values when ≥ 60% of weight responded; else NULL + coverage_warning.
  • xi.value etc.: same shape for market_entropy.
  • psi_news_blobs: concatenated per-country news content for psychological_wavelength judgment.
  • regions.: single-market region tilts (bypass coverage threshold per BUG-009).
  • sectors.: cross-country weighted-median, coverage-gated.
  • macro_regime: inferred growth/risk tokens from telemetry.regime_tag.
  • fan_out_summary: market counts.

Step 5 — Component composition

Call pillar_compose.compute_pillars(aggregated, telemetry). Returns four PillarResult(value, confidence, missing_inputs, composition_formula, source_snippets) objects (module/class names kept as field identifiers for data-contract stability).

Component confidence caps (MCPFIELDINVENTORY.md §4):

  • econometrics_phase (macro backdrop): ≤ 0.80 (regime_tag + cross-country growth nudge).
  • valuation_state (valuation): ≤ 0.70 (prose-extracted from per-country macro_indicators). PROSE-BASED — assumed telemetry.signals.valuation_z does NOT exist (verified A0).
  • market_entropy (market state): ≤ 0.50 (composite: prose entropy + normalized len(telemetry.divergences) as fallback proxy; composition_formula documents the weighting).
  • psychological_wavelength (sentiment): ≤ 0.60. Default is heuristic bag-of-words; SKILL.md flow injects a Claude structured-output prompt via psychological_judge_fn for production.

When missing_inputs is non-empty, confidence is capped at 0.35 (strictly below gap_detect.LOW_CONFIDENCE_THRESHOLD = 0.4) so the gap branch fires.

psychological_wavelength judgment is Claude-only. Telemetry contains CG-proprietary signals — do NOT dispatch to external models. Structured-output schema:

{"value": -2..+2, "reasoning": "≤200 chars", "confidence": 0.0-1.0}

Step 6 — Optional gap-fill finishing pass

OPTIONAL. After Steps 4-5, any residually silent leaves (e.g., sectors where coverage was below threshold but a single anchor market had a strong signal) MAY be folded via gap_suggest.fold_responses. Step 4-5 results win on conflict. Skip in v0 — leave the hook for follow-up integration.

Step 7 — Shared confirmation gate

Build the GateContext and call gate_present.run_gate_loop(draft, context, dispose_fn, edit_fn):

GateContext(
    source_label=f"Parallax synthesis {iso_timestamp}",
    uploader_present=False,
    confidence_map={
        "pillars": mean([omega.confidence, phi.confidence, xi.confidence, psi.confidence]),
        "sectors": ,
        "regions": ,
        "factors": ,    # 0.0 in v0 — maker doesn't populate factors
        "macro_regime": ,
    },
    extraction_attempt_action=True,
    disposition_options=["confirm", "edit", "regenerate", "abandon"],
)

Bridge dispose_fn and edit_fn to AskUserQuestion exactly as /parallax-load-house-view Step 3 does — the module is shared.

Branch on GateResult.disposition:

  • confirm / edited → Step 8 (save).
  • regenerate → re-run from Step 2 with the basis hint updated; return to Step 7.
  • abandon → no save, no audit generate row. Done.

Step 8 — Save (reuses load-house-view Step 4 path)

Call maker.MakerOrchestrator.save_view(...). This:

  1. Computes view_hash per schema.yaml §"view_hash computation" (pinned algorithm).
  2. Builds provenance.yaml with one generator_synthesis entry per non-neutral leaf (per schema.yaml § classification_taxonomy.generator_synthesis). Validates via provenance_classes.validate_provenance_entry.
  3. Computes provenance_hash = sha256(JCS(provenance_data)).
  4. Sets extraction.uploader_confirmed = true, metadata.upload_timestamp, metadata.calibration_status = "heuristic_phase0".
  5. Renders prose.md via prose_synth.render_prose (deterministic, no LLM). Computes prose_body_hash.
  6. Writes view.yaml, prose.md (with frontmatter paired_yaml_hash / prose_body_hash / view_id / version_id), provenance.yaml. chmod 0600.
  7. Appends action: "generate" audit row via audit_chain.append_entry — fields per loader.md §6.1/§6.2:

``json { "schema_version": 1, "ts": "...", "view_id": "...", "version_id": "...", "view_hash": "...", "skill": "parallax-make-house-view", "action": "generate", "applied": true, "parent_version_id": null, "provenance_hash": "...", "source_tools": ["macro_analyst:United_States:macro_indicators", ...], "calibration_status": "heuristic_phase0" } ``

FORBIDDEN on the audit row (per loader.md §6.2): composition_formula, aggregator_weights_ref, source_snippets, pillar_missing_inputs. These live in provenance.yaml. The maker raises if any forbidden key appears.

  1. Emits reasoning chain via chain_emit.emit_phase_0_chain:
  • skill_version="parallax-make-house-view@1.0.0"
  • base_scores={"response_inline": , "response_hash": }
  • final_portfolio={"weights": {}} (dummy — maker produces no portfolio)
  • run_id=

Step 9 — Confirmation summary

✓ House view synthesized and saved.
  view_name:      Parallax synthesis YYYY-MM-DD
  view_id:        
  version_id:     
  effective:       through 
  components:     econometrics_phase   valuation_state   market_entropy   psychological_wavelength 
  component conf: econometrics_phase   valuation_state   market_entropy   psychological_wavelength   (avg )
  tilts active:   
  unreachable markets: 

Active in: portfolio-builder, rebalance, thematic-screen, morning-brief, client-review, explain-portfolio.
Conflict-flag only in: should-i-buy, deep-dive.

Try it:
  /parallax-portfolio-builder ""     # build a portfolio with this view applied
  /parallax-judge-house-view                      # compare this synthesis against live signals later

Audit & inspect:
  /parallax-load-house-view --status              # active view summary
  /parallax-load-house-view --why      # why is this tilt set to what it is?
  /parallax-load-house-view --export     # regulator-grade compliance bundle

To clear:  /parallax-load-house-view --clear

Shadow-diff mode

/parallax-make-house-view --shadow-diff runs Steps 1-6, then short-circuits Step 7/8. Instead of routing through the gate, it loads the currently-active bank view and renders an ADDITIVE diff via shadow_diff.render_shadow_diff. No save. The framing is critical — the bank's view is sovereign, the synthesis is offered as data to consider, never as a correction.

Compare mode

/parallax-make-house-view --compare loads two saved view bundles from disk (each arg may be a bundle directory or a view.yaml path) and renders a NEUTRAL per-cell diff of their tilts and excludes. It short-circuits before Step 1 — no MCP calls, no synthesis, no gate, no save, no audit row. Invoke maker.run_compare(Path(path_a), Path(path_b)) and render the returned string.

Unlike --shadow-diff (which synthesizes a Parallax view and frames it as additive against the sovereign active bank view), --compare treats both inputs as equally sovereign: symmetric left_only / right_only / agree / disagree buckets, no synthesis, and no pillar-confidence block (pillar tilt cells appear like any other cell, but the confidence/computation internals never do).

Disambiguation: --shadow-diff = synth-vs-active (synthesis runs); /parallax-judge-house-view = active-view-vs-live-signals; /parallax-house-view-diff = portfolio-OUTPUT diff (Leg A vs Leg B weights, not a tilt-cell diff).

Status mode

/parallax-make-house-view --status shows last-generated view metadata + the standard view_status.banner (same banner the loader emits). No MCP calls.

Modules

  • maker.py — orchestrator + save path. MakerOrchestrator.execute_synthesis(mcp, dispose_fn, edit_fn) is the entry point.
  • cross_country.pyaggregate(per_market_responses, telemetry, weights) with 60% coverage rule.
  • pillar_compose.pycompute_pillars(aggregated, telemetry) packaging.
  • pillar_formulas.pycompute_omega / compute_phi / compute_xi / compute_psi (function names kept as field identifiers). Prose-based valuation_state / market_entropy per A0 findings. Confidence caps + missing-input rule.
  • prose_synth.py — deterministic YAML → markdown narrative (no LLM).
  • shadow_diff.py--shadow-diff rendering (render_shadow_diff) + --compare rendering (render_compare / diff_excludes). maker.run_compare(left, right) is the --compare entry point.

Hard constraints

  • DO NOT modify any existing skill (load-house-view, house-view-diff, stress-house-view).
  • DO NOT modify any shared infra (audit_chain.py, manifest_cache.py, chain_emit.py, view_status.py, gate_present.py, provenance_classes.py). Reuse only.
  • DO NOT dispatch to external models for psychological_wavelength — Claude only (data perimeter).
  • The generate audit row format is fixed by loader.md §6.2 — adding fields requires a loader.md spec update first.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.