SuperAPI AI Directory

quant-buddy-view

Frontend & websites

View repository

Updated 10-16 00:20

About this skill

quant-buddy-view · Quantitative dashboard publishing

Public scope and capability boundaries: The current live page is publicly accessible via link; private permissions that have not been verified cannot be promised. Before publishing personal holdings, cost, or transaction records, the public scope must be explained and corresponding authorization obtained; if authorization has already been explicitly granted, do not reconfirm, and ordinary public market pages require no additional confirmation. Opening/refreshing a page and fetching data does not equal having enabled daily scheduled tasks, proactive notifications, or automated trading; these statuses can be reported only when the actual capabilities and evidence of successful creation/execution are both present. If capabilities are lacking, state this truthfully and continue completing the authorized and achievable parts.

Host conventions take precedence over standalone routing: For financial questions in WebAgent, by default continue with this skill after QBS gives a complete first answer, and do not cancel page creation because of “just checking one field”, “how has it been recently”, or a concept explanation. The rule below that one-off queries use only QBS applies only to standalone use without such a convention. The page is generated along the scope and structure of the answer, retaining explicit instructions not to use a web page, the original page identity, and publishing acceptance rules; see Answer first, then build the page。

Consolidate the “verified quantitative data and formulas” into apublicly shareable, real-time data-fetchingweb dashboard/landing page. One-off market queries and concept explanations are answered by QBS; for executing backtests, daily reviews, monitoring, drawing lines and charts, and viewing candlesticks, by default use QBS first and then this skill, without requiring the user to separately say “make a web page”. The default execution route is:

Exception for delivery of existing files (including enhanced versions): In this process, links are uniformly called “shareable live pages”, not mandatorily “real-time”; data status is otherwise stated truthfully. file_prepare may deliver the original static version of the recoverable process immediately after acceptance, without applying the fixed ending of the final-state “real-time live page”, and without calling the final-state reply validator that requires terminal=true; explain the static nature and continue the authorized enhancements. feishu-group uses the playground link.

feishu-group channel: When the packaging channel is feishu-group , all branches such as direct/fork/unmatched/update are prohibited from sending non-final-state links; the final-state contract uniformly converts pages.quantbuddy.cn/pages/<owner>/<page_id>.html into www.quantbuddy.cn/playground/<owner>/<page_id>, while internal publishing and acceptance still use the original hosted URL.

Quantitative page-building sequence: Except for existing file hosting, read-only interpretation, and pure display maintenance, first follow answer-structure page building to complete the QBS query and send a complete non-terminal first answer, and only then execute the fast page/template/page-building route described below. This order also applies to new_asset_page fast pages; page acceptance must not block the first answer.

Highest priority: interpretation of an existing live page. When the user provides pages.quantbuddy.cn/pages/... a QuantBuddy live page URL, and the intent is “interpret / analyze the current live page / look at the data on this page”, first and only run:

python scripts/static_page.py interpret '{"url":"用户提供的页面 URL"}'

This is a read-only data path,do notrun trace_context.py、templates、template、direct_deliver、new_page、fork、download, browser or HTML search, and do not create, update, or publish pages. It calls getPageDetail?need_data=true; the server uses the formula package and Data Grant bound to the page to fetch the latest data and appends interpretation_bundle, no signature is returned. Directly interpret the details and interpretation_bundle.runtime_dataaccording to the user's custom requirements. When no format is specified, output in order: a one-sentence conclusion, key metrics and changes, risks/anomalies, and 3 directions for follow-up questions. See workflows/interpret-existing-page.md。

If interpretation_bundle.runtime_data.grants[].data.mode="csv", the first returned csv_fields[].csv_url is a short-term download link rather than directly computable data. You must immediately run python scripts/static_page.py interpret_csv '{}'once: it only downloads the CSV already returned by that interpret , keeps the link and fills in results[].fields[].series, then recalculate and interpret; do not rerun interpret, query another data interface, or give the CSV link to the user.

  1. In addition to the above existing loose-leaf interpretation branches, before any backend request run scripts/trace_context.py begin, save the unique task_id and reuse it in subsequent commands. This step itself is a backend write call and must carry the same identity as subsequent commands (QBV_API_KEY environment variable or the api_keyin the parameters); without it, it will be recorded as the skill default account.
  2. All quantitative page building must first read answer first, then build the page. If QBS has already delivered a valid complete profile first answer in this round, skip fetching data again, reuse the same task/turn, and directly new_asset_page(reply_mode:"page_followup"); do not re- resolve_asset_data、stockProfile or create a second session. When data has not yet been fetched, query business data via qbs_bridge.py , verify the actual date and units, and send a complete non-terminating business answer.The next tool call in this step must still continue the page flow and must not end with a final message that has no tool call. If it is merely a simple analysis of one A-share and returning a page, with no custom sections/extra metrics/comparison, after the first answer run scripts/static_page.py new_asset_pageonce; do not query templates or register a Grant yourself. A successful draft is used for the final page delivery and does not replace the previous QBS first answer.
  3. Other quantitative page building must also first complete the Step 1 business first answer, then run scripts/static_page.py templatesonce to query the unified public hit pool (official selections + community). Existing file hosting and pure display maintenance keep their respective entry points.
  4. direct holds only when there is evidence on all three axes: paradigm, scope, and all request dimensions;direct_deliver must submit dimension_check. If a dimension is missing, switch to fork + same_paradigm_augment_dimension。
  5. fork/unmatched calls new_page the Agent explicitly passes items_summary based on routing_decision; fork must also declare borrow_mode=inherit|inherit_augment|compose. Once fork is determined to be only inherit, augment-inherit, or Compose, it is forbidden to reclassify it as unmatched. Before defining the research scope, read Research and Data Contract: when there is only market-cap screening, the title must be limited to "market-cap candidates/large-cap representative stocks"; when there is only main-contract history, the title must contain "main-contract reference"; when the source has no missing marker, a value of 0 must not be interpreted as missing. When newly assembling a page, also read Self-built Quality, and start from the structural example inside the installation package.
  6. new_asset_page After success, according to agent_summary_request , use the current Agent to fill in the unique summary_markerin the draft, keep the rest of the content unchanged and send immediately; direct, fork/unmatched still generate an evidence-bound draft according to agent_reply_contract and the reply template, then run the returned reply_validation_command, and only valid=true is finally replied.

Multi-turn follow-ups: for the first user message run scripts/trace_context.py begin; for each subsequent user message with the same task_id , first run scripts/trace_context.py beginTurn. A normal Agent must also pass this round's optional agent_intent: Concisely expand the context reference and clearly state the object, action, constraints, and expected page/artifact; 20–160 characters recommended; do not copy the user's original words, output internal reasoning, or fabricate conclusions in advance. Old callers may omit it and follow null to continue. Within one round, all QBV/QBS tools share the same turn_id. Turn is an audit bypass: if server-side recording fails it returns tracking_recorded:false, but must not block page creation, updates, data retrieval, or publishing; the business context continues switching to the real user_query / agent_intent,attempted turn_id is not saved, not propagated, and subsequent processing continues in no-Turn mode. Updating an existing live page must continue to reuse the original page_id and public URL.

QBS answers Handoff first (same round by default): upon receiving qbs_qbv_handoff_v1 , run scripts/trace_context.py beginHandoff(compatible with begin-handoff), passing in the Handoff object or absolute handoff_file. Must reuse the real task_id + turn_id + source_skill_idtherein verbatim, must not begin/beginTurnagain, and must not redo QBS route classification in QBV.create/existing_page afterward still enters this Skill's full SOP, where QBV determines direct/fork/unmatched, queries ownership, and performs in-place updates for oneself or copies for others; when high-risk persistent state is unconfirmed, beginHandoff must refuse.

Display contract for large-sample rankings:universe_count only indicates the number of stocks participating in the calculation, not the number of rows the page needs to render. When the Handoff does not specify a display quantity, the ranking page defaults to rank_limit=20, and the page renders only Top20. By default consume render_mode=dynamic: Formula Package/Data Grant caches and retrieves data server-side, and the browser displays only Top20; do not downgrade to a static page just because many stocks participate in the calculation. Only when the user explicitly requests a fixed snapshot, or the dynamic data route is verified to be truly unavailable and this has been truthfully explained, consume render_mode=validated_snapshot。

Quantitative page creation answers first

For quantitative query-type page creation, first use QBS to validate the data and send the complete non-terminating business answer, then query the template, register the runtime, and build the page; by default continue in the same round. When a Handoff is received, reuse the existing answer and calculation, and build the page according to the answer structure consume the optional answer_structure. Do not treat an already-sent first answer as task completion. Existing file static hosting, read-only interpretation, and pure display maintenance retain their original entry points; successful minute-formula validation does not mean the formula package supports minute registration.

Quantitative page creation adds links only after acceptance: in this scenario, all channels do not send template, draft, or progress page links until the page passes acceptance and the applicable reply validation passes. This rule takes precedence over the immediate first-link requirement and first-link latency metrics below, in tool documentation, and in returned hints; template matching, creation, and same-page updates still execute normally. Existing file hosting retains its own first-link delivery and confirmation process.

Verification results are handed off directly:resolve_asset_data / validate_grant_set / validate_package_set returns registration_params_file , after the first answer and page routing are complete, directly execute the corresponding registration_command; do not rewrite the contract, copy the fingerprint, repeat the query, or call validate separately.publication_evidence merge verbatim into the dashboard spec, and bind the panel to the actual ID returned by registration. When the fields/scope with existing evidence genuinely need to change, revalidate the new contract; the old fingerprint cannot be reused. For formula-type industry pages, first read Industry ranking handoff。

Compose parameter handoff

Continue generation after technical failure: when historical CSV validation, source credentials, or registration errors occur, execute same-page recovery. Prefer fixing the original contract; when complete verification results already exist but registration is unavailable, use recover_snapshot Generate same-page snapshot candidates, then continue compose_page → publish_verified. Do not treat a single tool failure as the end of the task, and do not switch to static_content_only; when the user explicitly requests a real-time page, static results must not be passed off as a complete delivery.

For a plan page that has already passed public acceptance, when only the body/layout is modified while the standard dashboard data-fetching contract and kernel are retained, you may, after interpret confirming same-page owner/page_admin permissions, run static_page.py prepare_maintenance @params.json. It verifies the baseline from the current online version, and generates an independent maintenance candidate receipt and publish_verified parameters; it does not rewrite the original Compose receipt. It does not apply to first-time page creation, incomplete public acceptance, data contract changes, version conflicts, or unknown write results. For specific constraints, see Browser annotation maintenance。

For the release baseline of self-built and Compose, seeself-built quality; for asset identity, research definitions, the complete formula contract, and the minimum data-fetching scope, seeResearch and Data Contract. Text whose price or ranking may change must use dynamic binding or explicitly annotate the historical analysis date; do not treat static body text as a real-time conclusion.

fork_compose and execution_plan The revision returns next_action.params_filein a writable directory of the session. Edit the title and research content of that draft; do not edit the internal /tmp receipt; after revision, use the new path and the current plan_hash. Registered roles automatically generate a data panel;runtime_role_id is a supported role reference; pure text/image does not count as data consumption. Handle draft_diagnosticsfirst; do not bypass the error by clearing roles or canceling the real-time requirement. Only when the tool returns publish_verified does it enter publishing; if a route is missing, provide the route_receipt_filealready available for this task, and do not register again. Failure replies retain the "Task progress (build failed)/(incomplete)" links, but do not use finished-deliverable wording; host cards are not evidence of success.

When to use this skill vs quant-buddy-skill

  • One-off queries/concept explanations("Moutai's gain/loss today", "what is a moving-average golden-cross backtest") → use quant-buddy-skill。
  • execution-type requirements("run a moving-average golden-cross backtest and see", "daily review", "monitor the trend", "draw support lines", "look at the K-line") → QBS verifies and answers first, then enter this skill; "don't draw charts, just tables" only changes page presentation, and if web pages are explicitly not wanted, do not create a page.
  • Want a page you can view repeatedly, send to others, and whose data updates automatically → switch to quant-buddy-view; for existing files converted to a live page, statically host first; otherwise start from scratch research, create the page, then follow the exploration workflow.

Converting existing files to a live page: static hosting takes priority (higher than data lookup and paradigm routing)

When the user provides existing JPG/PNG, HTML, PDF, or other readable files and asks to convert them to a live page, activate a webpage, or make a shareable page with QBV, trigger by semantics and do not rely on the fixed phrase "convert to live page." Even if they also ask to check errors, add metrics, conduct research, or redo the HTML, you must first convert the source into readable static HTML, publish and accept it, deliver the link first, and only then consider QBS data integration. Do not first look up data, match assets, query paradigms, or wait for Handoff/computation capsules; all such work moves to after static delivery. It is not triggered when the file is only read/analyzed/exported and no publishing is requested, or when the user explicitly says "do not publish yet."

Execute static-first workflow for existing files: first static_page.py file_prepare save the original file and generate the minimal carrier HTML and recoverable publishing parameters, then use the returned file_publish_dir and snapshot_only:true Run upload/update; first accept the original static version; after returning required_user_message, before the next tool call, first send that link to the user, then run file_confirm_delivery to confirm, and then continue the already-authorized error correction, research, and data enhancement. Do not substitute a false confirmation for the actual message. When the user requests redoing content, hand the main HTML to the same-page managed update (file_enhancement_mode:content) to automatically compile the sharing shell and accept it, do not switch to a bespoke/fork process, and do not first run ui-refinement on the uncompiled main body or add an unrequested font-size threshold. Do not wait for data lookup, paradigm matching, formula verification, or content redo. Bind the first version and the continued run to the same page_id/URL, keep stage records in the current task's persistent workspace; enhancement failure must not first overwrite with an old snapshot. For unknown write results, use file_status to verify, and do not blindly repeat creation. Read-only file analysis or cases explicitly not to be published do not trigger; handle the real public boundary, file reading, conversion, and first-time hosting issues truthfully, and do not falsely claim success.

New session routing: single-stock quick return / otherwise look up the paradigm card

First establish Trace Context.begin isa real backend write call(written to the audit table), and like subsequent commands it needs the identity of this task — it must use the same key as subsequent commands, otherwise this step will be recorded under the skill default account, and the task chain will be attributed to the wrong person from the first record:

# 身份走环境变量(exec 日志里会脱敏);不要把 key 拼进命令串,命令是原样记录的
QBV_API_KEY=<本次任务的 key> python scripts/trace_context.py begin '{"user_query":"那和五粮液比呢?","agent_intent":"延续上一轮贵州茅台分析,对比五粮液的盈利能力、估值水平与主要风险。"}'

agent_intent is bound to this round's user_query : the first question and each follow-up are saved separately, and follow-ups should expand references such as "it/the previous one/continue"; missing, blank, or old Trace files are all treated as null, and cannot be faked from user_query . QBS Handoff continues to use qbs_qbv_handoff_v1, optionally carrying the same Intent; differences in Intent must not create a second Turn, reject the Handoff, or change the Job identity.

agent_model is a purely optional audit field: when the current Agent's real runtime model is clearly known, it is recommended to pass it in; when uncertain, simply omit it, do not guess, and do not ask the user. The host may also inject it via the optional environment variable QBV_AGENT_MODEL . The model name is resolved in the order "explicit parameter → QBV_AGENT_MODEL → current task_id 's task temporary context → empty"; missing, purely blank, or context read/write failure must not interrupt the task, and a non-empty value will automatically flow through subsequent commands and the QBS bridge via x-agent-model .

Save the returned task_id, and add it to every subsequent static_page.py、formula_package.py、data_grant.py parameter for this task. The script will transparently pass it through the x-task-id request header, so the backend can aggregate from the question all the way to the final live page link.new_asset_page / templates / upload / update / publish_final / publish_verified Execution must stop when Trace Context is missing. In QBV orchestration, quant-buddy-skill tools are uniformly invoked through scripts/qbs_bridge.py <tool> @params.json , and explicitly pass the same task_id + user_query; the bridge will use a task-scoped session to inherit task_id, and creating a second session id is forbidden.

build_dashboard.py also belongs to the above "every subsequent command": as long as the spec contains upload:true or update_page_id, the same task_idmust be written. A successful result will return a hash-bound reply_draft_file + reply_validation_command; after public acceptance, a draft must be written and the command must be run, and only valid:true can be the final reply, after which tool calls must stop.

Planning and Recovery: ordinary research pages are delivered under theplan-driven deliveryexecution. The reference scope, target runtime role, and build mode must be consistent; the params file returned by Compose is used for the complete candidate build, followed by publish_verified.update_progressMust use page_status/current_step; technical failure is not user confirmation, and existing readable content must not be overwritten by a failure progress page. Registering run credentials must correspond to verification receipts; for static finance pages use materialize_snapshot and the planned snapshot_roles, and do not bypass verification by filling in data manually.

Specific asset evidence gate: when turning existing files into live pages, execute static delivery first; this gate only takes effect in the subsequent real-time enhancement phase. Except for new_asset_page fixed scenarios, whenever the user names a specific asset, after Trace and before explaining the asset identity or submitting routing_decision , complete verification in the order "Trace → asset mapping → minimal interface verification → page routing": call scripts/qbs_bridge.py resolve_asset_data to obtain the platform ticker mapping, and probe whether the required data roles are retrievable according to the page's actual needs, recording only interface success/failure, available fields, and structured errors. Page structure and direct/fork/unmatched determination must be based only on "the capability the user needs × the verified platform capability", and must not be based on the Agent's memory of a company's listing status, ownership, asset name, or market conventions. Before verification, do not introduce restrictive premises such as "listed/unlisted, public/private, proxy asset, no quotes, static only"; if the user has not asked about these identity attributes, do not expand them into the main line of analysis.

resolve_asset_data 's input contract must be written directly in the following shape into the new output/*.json; do not guess the schema first, do not concatenate multiple assets into one asset string, and do not write a separate parameter file for each asset:

{
  "task_id": "<同一 task_id>",
  "user_query": "<当前用户原问题>",
  "assets": ["贵州茅台", "五粮液", "泸州老窖"],
  "required_roles": {
    "snapshot": ["close", "pct_chg", "pe_ttm", "pb", "market_cap"]
  },
  "optional_fields": ["turnover_rate"]
}
  • For a single asset use "asset":"贵州茅台"; for multiple assets use "assets":[...], and the two cannot coexist. Multiple assets are verified asset by asset by the bridge withina single CLI calland the receipts are aggregated.
  • required_roles Only write the roles actually needed; omitted profile/snapshot/report/formula is automatically treated as an empty array. The canonical value for each role is a string array, and {"fields":[...]}。
  • is also compatible. During the multi-asset probing phase, formula must be left empty or omitted; cross-asset common formulas are verified only once after probing with validate_package_set , and it is forbidden to repeatedly verify/register the same formula package for each asset.
  • output/ is scratch left over across sessions, not an example library: it is forbidden to Grep/Read old output/*.json to assemble this run's parameters, and especially forbidden to copy old task_id, old credentials, old formulas, or corrupted JSON from it; the parameter shape is obtained only from the current SKILL.md / tools/*.md / workflows/*.md .
  • Formulas containing double quotes must be written as valid JSON escapes; prefer equivalent formulas without nested quotes (such as mt_close = 收盘价(贵州茅台)). After writing, execute the corresponding CLI directly and let the JSON parser serve as feedback; do not read old scratch files to "find examples".
  • For multi-asset cumulative return/drawdown, prefer the standard dashboard: configure the same set of price outputs respectively with transform:"cumulative_return_pct" and transform:"drawdown_pct"; for valuation, use a Data Grant table separately. This capability is already built into build_dashboard , and it is forbidden to Grep/Read assets/data-kernel.js for it or hand-write a bespoke SSE/Grant runtime; see workflows/dashboard-end-to-end.md for the shortest path.

Modifying an existing URL is updated in place according to write permissions or Forked

Adding moving averages/indicators, expanding the calculation scope, or modifying strategy parameters is a computational update: after QBS verification, first publish the complete non-terminal business answer, then execute chart_edit/registration/update, and after public acceptance succeeds, supply the original link. Existing pages and resumed sessions are not exempt; deleting existing lines only, display clipping, and color/layout modifications are pure display maintenance.

Only when the user explicitly requests "interpret/view the current page" and does not request modification, usewithout task_id pure read-only interpret, after reading you may answer based on the returned evidence, without entering the page-building flow.

When the user requests modification of an existing QuantBuddy URL, first trace_context.py begin, then with the same task_id call static_page.py interpret. You must branch according to the returned existing_page_route.mode , and must not classify all existing pages as Fork:

  • mode="in_place": the caller is owner/page admin, or the legacy detail contract returns resource_role="existing_page", and updateStaticPage performs the final permission check at write time. Keep the original page_id, public URL, package/Grant, Share Shell, and runtime identity, and use static_page.py update(and, when needed, update_progress / publish_verified) to write back to the original page. It is forbidden to use new_page、new_asset_page、upload to create a replacement link, and there is no need to query templatesagain. If chart_edit.py returns LEGACY_PAGE / NO_RENDER_JS_MARKER, and the user has explicitly requested to modify their own page while keeping the original link, then the necessary technical structural upgrade is authorized: immediately follow workflows/edit-existing-chart.md 's legacy fallback to download, minimally rebuild, browser precheck, and update the same page; do not ask a second time whether to upgrade, and do not stop at local HTML. Only ask when missing information would change the business semantics. If the server returns FORBIDDEN, stop writing and switch to the Fork path described below; do not forge is_page_admin。
  • mode="fork": the current details explicitly can_update_in_place=false, or the page is a source_templatethat cannot be written to directly. Execute templates(recommend="all") → new_page(mode=fork, source_template_id=<interpret 返回>) → fork_preparein order; templates only supplement the paradigm pool credentials and cannot override the sources already bound by interpret.

Trusted permission fields are returned by the server getPageDetail :can_update_in_place and access_role=owner|page_admin|reader. The client must not trust the is_page_adminself-reported in the call parameters; when the old server does not yet return capability, only attempt to write back to the same page_idbound by interpret, and rely on updateStaticPage 's owner/page-admin authentication result.

Before decision binding, the Fork path forbids new_asset_page、build_dashboard、bespoke upload or any regenerated page; do not reclassify unmatched or secretly swap the source. Only after fork_prepare explicitly returns a structured non-copyable error may degradation be evaluated, and explicitly declare page_context_mode=regenerated and source_page_context_inherited=false。

enter in parallel handoff from QBS (thin adapter, does not change QBV's independent SOP)

When the parent task provides the qbs_qbv_handoff_v1 file, do not execute beginagain; instead:

python scripts/trace_context.py beginHandoff '{"handoff_file":"D:/.../handoff.json"}'
python scripts/qbs_handoff_adapter.py evaluate '{"handoff_file":"D:/.../handoff.json","qbv_job_id":"qbvjob_xxx","qbv_job_file":"D:/.../job.json"}'

trace_context.py reuse QBS's task_id + turn_idas-is; the Adapter validates the optional qbs_computation_capsule_v1, and upon discovering the corresponding qbs_qbv_job_v2 deterministically writes the Job from queued to running. When QBV standalone does not have that Job, it is a side-effect-free no-op:

  • coverage=covered: it is forbidden to call resolve_asset_data again or use other QBS tools to recompute covered_roles; directly consume the asset mappings, contract, artifact, field mappings, conclusions, and receipts in the capsule, then continue with the QBV page SOP. If it returns next_step=templates, the next tool call must be templates, and you must not return to QBS to recompute or end with a final message that has no tool call.
  • coverage=partial: only supplement qbs_bridge.py through missing_roles; do not duplicate roles already covered.
  • coverage=unusable: losslessly fall back to this section's original Trace → qbs_bridge → routing flow, and do not lower the verification gate.
  • When the Adapter returns formula_runtime_action=register_exact : take the formula_runtime_contract.formulas Register in the original order and with the original literal text as a Formula Package, and according to the contract's reads first query; abbreviating metric names, merging formulas, re-deriving, or calling QBS again to verify covered formulas is prohibited. If fingerprint, lvalue, or reads validation fails, follow coverage=unusable safe fallback; a tampered contract must not be registered. When an old Handoff has no formula_runtime_contract keep the original standalone/compatible flow.

What is skipped here is onlythis round's duplicate calculation. If the Handoff carries render_mode=validated_snapshot, the absence of a live formula runtime contract is not a blocker: continue templates → recover_snapshot/compose_page → publish_verified → 公网验收. direct/fork/unmatched, in-place update by the same person/copy by another person, Grant/Package registration, first runtime query, page build, Card Runtime, publishing, and public acceptance are still fully executed by QBV. The QBS Job only performs side-channel auditing:publish_verified simultaneously obtain published=true + verified=true + page_id + public_url, or direct_deliver obtain a strong terminal state with consistent fields direct_finalize contract, it will automatically write back completed; when it cannot continue and termination is certain, execute python scripts/qbs_handoff_adapter.py fail-job '{"qbv_job_id":"qbvjob_xxx","qbv_job_file":"D:/.../job.json","failure_code":"<CODE>","retryable":true}', and do not manually edit the Job JSON. When the user uses QBV directly, there is no Handoff; continue with the original SOP and do not depend on the QBS capsule.source_skill_id=null + source_skill_id_status=unavailable is a legitimate audit state; it must not block the page flow, and historical skill_*。

Single A-share simple analysis fast track

When the user inputs only one uniquely identifiable A-share name/short name/code, or asks to analyze one A-share and provide a shareable page, andthere is nocustom column/layout, specified extra metrics/formulas/charts, comparison, multiple instruments, index, or Hong Kong/US stock requirement, use this fixed fast track. First follow guides/answer-first.md to obtain complete QBS profile evidence and send a non-terminal business analysis, then in the same round execute the following command; do not search for templates first, do not additionally build a page yourself, and do not repeatedly create a generic Job. Explicitly not wanting a webpage or querying specific fields does not trigger the bare-asset default page creation:

python scripts/static_page.py new_asset_page '{"task_id":"task_xxx","asset":"贵州茅台","user_query":"分析贵州茅台","reply_mode":"page_followup"}'

This command invokes a fixed server-side scenario and internally reads SHA256-bound evidence, generates the first five data sections, reports the terminal state, and cleans up temporary files. Data sections generate tables only when there is data, with at most five tables in the whole document; calculation dimensions primarily use the stable profile dimensions of the stock profile as evidence, supplemented by daily change/moving average/price position from the valid closing price CSV, and only when neither path has verifiable fields is the entire section omitted, with subsequent visible sections automatically numbered consecutively. The news/events section is not output for now. A successful result includes agent_reply_markdown_draft + agent_summary_request: draft chapters one through five are the complete visible evidence handed to the current Agent, and chapter six has only the unique summary_marker. The Agent must combine this round's real user question, directly answer the user's purpose in its own words, cite only data already present in the draft, and distill conclusions and key evidence; for trend-type questions use conditional judgments, for earnings commentary focus on report performance, and for other questions likewise organize according to the original intent, without needing a keyword classifier or dedicated generator. After completion, replace only the marker, do not change the first five chapters, the disclaimer, or the final link block, do not run the validator or other tools, and immediately send the complete Markdown. The public link and "If you are not satisfied with the result, the page can be further upgraded" are still the last two lines. If a single CSV item fails, delete only the corresponding field and write a warning; if there is no verifiable evidence at all or draft generation fails, fail closed, and do not degrade into a single link or repeated calls. If the user later wants to modify this owned page, continue using update to keep the same page_id / URL。

When the above narrow conditions are not met,run only once scripts/static_page.py templates. It calls the unified public list, and the server performs official curation plus community deduplication, sorting, and pagination; do not manually call it repeatedly. The return value is item_count + covering all candidates items_summary(no longer raw full items printed), and the complete candidates are persisted at full_result_file; for normal routing decisions, only read items_summary, and it is neither needed nor appropriate to read full_result_file。

  • ① Direct hit(paradigm match, consistent scope, and candidate real runtime output covers every dimension requested by the user):
    • templates once an exact hit is provided, on the normal channel thenext user-visible message must immediately send the ready-made download_url/public_url, and no tool calls are allowed in between. Recommended copy:已直接命中现成活页:[标题](URL)。我继续核对实时数据并补充分析。; if agent_reply_hint.delivery_policy.emit_intermediate_url=false(i.e. feishu-group), do not send that URL and continue directly.
    • after the normal channel sends the link,feishu-group instead of sending a link, run immediately once:python scripts/static_page.py direct_deliver '{"task_id":"task_xxx","page_id":"page_xxx","template_revision":"sha256","dimension_check":{"coverage":[{"dimension":"用户维度","covered_by":["card_required_outputs:真实输出"]}]}}'. Titles and summaries can only serve as auxiliary evidence; each dimension requires at least card_required_outputs, or page_context.primary_outputs authoritative evidence derived from the runtime contract.
    • do not new_page, do not register, do not fork, do not study script source code, do not first run --help。direct_deliver 's formula result is fixed as summary; the full grant result is written only to %TEMP%, and the final reply must not expose local paths or credentials.
    • only when it returns agent_reply_contract.terminal=true and operation=direct_finalize is final closure allowed; on failure, explain the specific error, and do not bypass the terminal gate with an already-sent link. Reply template and page_context follow the original page.
    • direct_deliver will return the real contract, draft, validation parameters' %TEMP%\qbv_<完整 task_id>_* file paths and reply_validation_command. Write only Markdown into the returned reply_draft_file, execute the returned command once;valid=true then immediately give the final reply, and do not verify again, run --help, scan temporary directories, or continue searching memory. Successful validation uniformly cleans up contract, draft, params, and grant temporary results.
    • After successful public-browser acceptance, the next step must be the final reply; do not call Read/Grep/Bash/browser again or enter a new research round. If browser acceptance is the last available tool round, you must also close directly with the validated contract/URL.
    • If the user later says "want to change this page content" → switch to ② fork (official/community links cannot be changed directly; only create your own link and then change it).
    • Boundary: paradigm match butthe underlying asset/stock pool/index/market scope is inconsistent(e.g. the hit is a Moutai valuation page while the user asked about CATL; the hit is a CSI 300 unusual-movement page while the user asked about CSI 500) does not count as a direct hit, and falls through to ②. Only an all-market paradigm that is asset-agnostic and has a consistent market scope can hit directly without depending on a specific underlying asset.
  • ② fork(paradigm hit but underlying asset mismatch, or the user wants to change content):
    • first run new_page, pass routing_decision:{"mode":"fork","source_template_id":"page_xxx","reason_code":"same_paradigm_different_asset","borrow_mode":"inherit"}。inherit_augment for when the template structure can be reused but analysis dimensions are missing;compose for when the contract cannot be inherited item by item, but the layout/styles/render functions/formula ideas or Grant shape can still be borrowed.

    • fork_prepare is a one-time task binding: repeated execution returns FORK_ALREADY_BOUND; if a full rebuild is truly required, you must pass force_rebuild:true + rebuild_reason, and the same task must not switch source templates.

    • fork_prepare 返回 publish_command 后 immediately enters the publish convergence phase: only fill in the returned review file and execute that command; reading scripts/*.py, running --help , or exploring the publish_workflow.py / fork_runtime_contract.py implementation is prohibited; if the command fails, only correct the input according to the structured error. Once the first chain has been created, you must either complete the terminal or explicitly fail the closure; the progress page must not remain in running for a long time.

    • inherit_augment pass fork_prepare to augmentation_spec, adding package/grant roles physically isolated from source roles. Any newly added formula must pass QBS validation, the marker must appear exactly once, and the output must actually be rendered.

    • compose first run intent_profile to perform the three-layer mapping of user_term/platform_dimensions/method_terms, then use research_templates to extract the credential-free column HTML, CSS, rendering functions, and contract shape, and finally fork_compose submit the borrowing list. Publishing is allowed only after the receipt and SHA256 binding; a zero-borrowing Compose that is all original is rejected. fork_compose must pass borrow_plan.modules(not the top-level borrowed_refs), and claim each user_termof the intent profile item by item; prefer to copy research_templates.templates_summary[].fork_compose_example and then modify it; when encountering COMPOSE_BORROW_PLAN_REQUIRED you must retry according to the returned example, and must not leave the progress page stuck in running.

    • Compose parameters must be written completely in one go:intent_profile at least pass {"task_id":"task_xxx","asset_scope":{"kind":"sector","name":"目标资产组","market":"A股"},"dimensions":[{"user_term":"实时行情","platform_dimensions":["close","pct_chg"],"method_terms":["横向比较"]}]};research_templates pass {"task_id":"task_xxx","template_ids":["page_source"]}. If any structured error returns example_intent_profile、example_research_templates or fork_compose_example, you must directly copy the complete example, modify it, and retry; do not guess field by field. - Division of responsibilities for asset replacement: the Agent clearly states "which underlying asset to replace with," and the script is responsible for "how that underlying asset is written on the page." The source primary asset is inferred by the script from template formula term frequency + title; the actual code notation (SH600900 / 600900.SH / bare 600900) is obtained by the script scanning the source HTML, and only actually existing notation is replaced - do not guess how the code is written in the source HTML, because you cannot see that file. When a multi-asset/index paradigm cannot infer a unique primary asset, you must not fabricate source_assetfrom the title or research ID; when only borrowing the layout or reorganizing multiple assets, switch to research_templates → fork_compose → compose_page; only for a true single-asset replacement should you add the verified source identity.asset_replacements is only an optional override. If the primary asset still has remnants after replacement, return FORK_SOURCE_ASSET_RESIDUALbefore writing out the working HTML; do not wait until after publishing to discover it.

    • The Agent only fills in, in the fork_prepare -generated review_update_params_file.decisions , the business decisions declared by required_decisions : fill target_slotsfor rule-based peer matrices, fill target_formulasfor complex cross-asset formulas, and fill page_label_replacements。decisions for label replacements. A nested placeholder skeleton has already been pre-generated by role ({"roles":{"<role_id>":{...}}}); you only need to fill in the empty values in the skeleton, do not add or rewrite top-level fields, and do not treat the flat required_decisions in decision_id(such as roles.package.package_001.target_formulas) as the key for submission. Directly editing the standard fork HTML/review is prohibited.

    • Grant fully inherits by source role kind/query_type/fields/dimensions/window_days/result_mode with CSV/inline contract, only automatic modification of the asset scope fields declared in the manifest is allowed; other changes must fill in contract_change_reason。

    • Data-level failures inheriting Grant can be downgraded and continue to publish surviving roles; system-level failures such as authentication/quota/protocol still block. If the page still uses queryDataGrant to unconditionally consume a failed Grant, return GRANT_DEGRADATION_UNSAFE, and must not use empty credentials for fake downgrade.

    • First run fork_prepare returned by review_update_command; only after review_state.status=complete and a review receipt is generated, then run publish_command. The publisher derives QBS validation and registration from the same canonical package/Grant contract, automatically checks required outputs, formula lvalues, reads, PE/PB water-level formulas having clear algorithms and positive integer windows, Grant fingerprint, Marker uniqueness, and Card Runtime structure, and fans out one registration result to all page/Card locations.

    • fork_manifest_v2 Manually passing packages, grants, Marker, or complete workflow JSON is prohibited; when MANUAL_RUNTIME_BINDINGS_FORBIDDEN appears, return to the generated publish plan, and do not write temporary replacement scripts. v1 prepared tasks continue to be published via the old interface.

    • This is not a suggestion—publish_verified the server will enforce verification according to the number of credentials in the fork manifest: manual step-by-step calls to publish_verified(task_id, page_id, html_file, source_template_id, fork_manifest_file, validation_receipt_files) are only allowed when this pagehas zero credentials(pure static transformation), otherwise it will directly reject and return error:"PUBLISH_WORKFLOW_REQUIRED"; when this error occurs, switch to publish_workflow.py, do not bypass it.

    • Reply = reply template format + your own new link(values are likewise filled in using your own package/grant query).

  • ③ No match(no matching paradigm): the Agent calls items_summary according to new_page and passes routing_decision:{"mode":"unmatched","closest_template_id":"page_xxx","reason_code":"required_capability_missing","reason":"候选缺少用户要求的核心能力"}; if candidates exist but are judged unmatched only because the underlying asset/scope differs, it will be prompted to switch to fork. After successful recording, continue with build_dashboard / bespoke self-build → the rest is the same as ②;feishu-group likewise does not send progress links.

Follow-up questions: your own link → update same as page_id; if a matched official/community link needs to be changed → it can only be converted to ② fork into your own link before changing.

Default routing

  • simple single A-share comprehensive analysis(no customization, additional indicators/charts, comparison, or multi-asset requirements):trace_context begin after, first give the complete QBS business initial answer, then new_asset_page(reply_mode:"page_followup"), and add the link after acceptance; if the host cannot display the initial answer midway, use the default complete final-state reply.
  • Other fixed page forms(customized individual stock pages, constituent stock anomaly rankings, multi-factor stock selection dashboards, commodity daily reports, etc.): first templates query the official curated + community match pool; direct directly uses the list URL + revision, fork only then reads and rewrites the template details.
  • Kuanbao active card / essence card / cover card (paradigm card artifact): turn the page essence into an independent card runtime artifact(embedded-card-v1: the page embeds <template data-qb-card-template> + data-qb-card-manifest + QBCardRuntimeV1 runtime), for the official website card stream to in a blank hostindependently hydrate. Static first frame card_snapshot_url is generated by skill_server according to the artifact hash, and is the sole source of the page cover (the full-page thumbnail capability has been taken offline). According to guides/essence-cover-card.md generation; for published pages, prefer preserve_visual:true only upgrading the protocol. A full rebuild must explicitly pass visual_contract, otherwise CARD_VISUAL_REQUIRED stops; use verify_page.mjs --card-runtime-only --require-card-visual-contract to verify the new artifact. Cards must use the official website light color scheme, a fixed information skeleton, and a variable core visualization; no longer use the old ?cover=1 URL pattern.
  • No suitable online template: then go through workflows/dashboard-end-to-end.md, and use build_dashboard to generate a declarative real-time dashboard.
  • A declarative dashboard is also insufficient: only then go through guides/bespoke-page.md to write the bespoke main body HTML, and compile it with the public shell into a self-contained page.
  • Modify an existing chart(overlay/remove a line, change the time window, check real data): prefer workflows/edit-existing-chart.md + scripts/chart_edit.py, and only touch the one requested place, without re-validating/recomputing other unrelated series on the page; only when the target page is legacy (chart_edit.py inspect determined, mostly old pages generated before this change) or the change inherently requires a full-page recalculation/layout change, fall back to the full-page rebuild below.
  • Retrofit a published/generated page: prefer scripts/retrofit_share_shell.py, then static_page.py update to keep the same page_id / URL; a formal update should pass a specific change_note, a layout change should explicitly pass change_aspect:"layout", and other types can let the server infer.
  • Share Shell revision 4 page Q&A boundary: the visible page header is hosted by the official website /embed/live-page-header iframe; the live page Parent Bridge only executes refresh, favorite, share, authentication navigation and mobile WebAgent actions, automatically sends the page question along with the question and validates qb-live-page-header-v1 / qb-web-agent-v1; when the official website WebAgent Preview injects qb-live-page-embed-context=webagent-preview , it must not load the page header or preload the favorite iframe. The official website only changing the page header visuals does not require a page-by-page refresh; only changes to the Parent Bridge, communication protocol, or capability contract bump the revision.
  • User-visible link policy: all channels for quantitative page building add links only after the complete first answer, page acceptance, and applicable reply validation; template and progress page URLs are only used for internal execution. Existing file hosting follows its own first-link rules;feishu-group upon seeing delivery_policy.emit_intermediate_url=false , it is forbidden to send any non-terminal URL, and only after the validator passes send the terminal contract's playground public_url. Progress pages still use update_progress and publish_final to update the same page_id; when change_note is not explicitly passed, the version modification description is automatically generated as "status + Chinese stage title + user-visible message", and formal release versions record by default "Release complete: formal live page content has been published".
  • Agent reply template: live page metadata may carry agent_reply_template pointing to the reply skeleton under this skill's reply-templates/ .reply-templates/ is the Agent's final reply format, not the live page HTML page template; do not mix it up with the online templates / template API.
  • This skill no longer includes a built-in local page template, and cannot start from a local historical template directory or a low-quality HTML skeleton.

Agent reply template (agent_reply_template)

live pages use the sibling page_context to describe purpose/modules/output, and use agent_reply_template.template_ref to point to the Markdown skeleton in reply-templates/ . For the field contract, hybrid rules, and publishing inheritance, see tools/static_page.md。

  • page_context must not contain real-time values, api_key, signature, Bearer token, or local paths; after forking it must be rebuilt according to the final page, and only direct reuses the original page.
  • Read-type commands return agent_reply_hint.terminal=false;new_page/update_progress is also not a terminal state. A successful new_asset_page/direct_deliver/direct_finalize/upload/update/publish_final/publish_verified can return agent_reply_contract.terminal=true; among them, new_asset_page returns the agent_reply_markdown_draft containing the unique comprehensive observation marker and the agent_summary_request。
  • When fork/unmatched encounters a criterion that must be decided by the user, use the same task_id/page_id to enter waiting_input, and after the user answers, continue the original task; do not rebuild the Trace or the first chain.feishu-group 's waiting hint does not contain public_url, and no progress link may be attached when asking.
  • fork must use fork_prepare to bind the source and manifest, and the final publish_final keeps the first-chain URL, removes source credentials, and retains the required sections/output/Card Runtime; for detailed gates see workflows/new-session-paradigm-routing.md。
  • prepared fork task prohibits build_dashboard; v2 only fills in the generated review-update decision file, and runs review_update_command and publish_commandin sequence. Only old v1 tasks continue to use the manual fork_validate path.
  • With task_id progress from package_register onward must pass the same task's structured validation evidence: the live page submits route_receipt、grant_receipts、formula_receipts, and selected_routes must correspond item by item to the actually registered credentials; free-text validation_not_required_reason is no longer allowed. Pure static content can only use static_content_only; when all data-level live asset probes fail, only live_data_route_receipt_v1 can be used to use static_after_live_probe。
  • After the first answer is fully visible,new_asset_page pass the local parameter reply_mode:"page_followup" to obtain a short delivery draft; when the first answer cannot be displayed midway, omit the parameter to obtain the full draft. The parameter is not proof that the first answer was delivered, and both modes still go through the same public acceptance and host actual reply verification. The final reply may only replace agent_reply_markdown_draft 's unique summary_marker with the comprehensive observation written by the Agent (in short delivery mode, only one sentence of page explanation, adding no values or risk conclusions); other content must not be rewritten, deleted, or reordered, and the marker must not be sent to the user. The first sentence of the comprehensive observation directly answers the purpose of this round's user, and subsequent sentences should only select the most relevant evidence to explain, avoiding restating all five chapters; when there is insufficient evidence, clearly state the boundary and do not fabricate facts. This branch does not return an evidence path or validation command. Other terminal replies must be output according to the reply template and may only use the contract's public_url;feishu-group under this field must be https://www.quantbuddy.cn/playground/<owner>/<page_id>. **As long as the terminal reply contains public_url, 可分享实时活页:[{public_url}]({public_url}) must be placed as the second-to-last line, and the last line is fixed as "If you are not satisfied with the result, the page can be further upgraded"; the link must not appear in advance in the body, sections, or disclaimer.** The general template deletes structurally nonexistent fields, entire columns, entire rows, and empty optional sections based on reply_render_policy and reply_data_availability .single_stock_deep_dive_v1 must also read the SHA256-bound reply_data_evidence_file, retain all seven section headings, output all template fields that have data, and use the standard explanation for an entire section with no data; only occasional missing values in a valid structure are written as --. If delivery_policy.max_markdown_tables exists, the entire document must not exceed that table count, and structures exceeding it should be changed to lists or inline text without losing data. After the validator returns valid=true , send it as-is validated_markdown, it must not be compressed or rewritten again, nor may the original hosting URL, local path, credentials, or internal logs be exposed.
  • Except for new_asset_page , before the final reply run the publisher-returned reply_validation_command。reply_validation_env is a process-internal execution-only value; the CLI and persisted reports may only return [REDACTED] and reply_validation_env_keys, and outputting real credentials is prohibited. If QBV_API_KEYwas explicitly set at publish time, the validator command must inherit the same existing environment variable; when not explicitly overridden, config.json/config.local.json resolves the default account, and the publisher return does not carry the default configuration key. It is prohibited to splice the key into the command string or write a separate parameter file. The validator must read the contract_file + contract_sha256generated by the publisher, and must not manually rebuild a reduced contract. direct uses the full task ID path and command returned by direct_deliver , and automatically cleans up after success.valid=true , no further tool calls are executed.
  • The host takes over the new_asset_page will check the same-round public version against the actual reply; only when the immutable body and ending match verbatim may the host remove extra opening remarks and send the validated body. If the body data is rewritten, summary placeholders are not replaced, the body is duplicated, or trailing notes are appended, it cannot be considered a successful delivery; do not rely on the host to correct business conclusions.
  • Without a terminal contract, completing the task is prohibited. The only exception is a successful waiting_input checkpoint。
  • Performance thresholds: quantitatively record the complete time for the first business answer when building the page; the first chain is only sent after acceptance; for all channels, the time from terminal to final reply must not exceed 45 seconds; a complete live-page task should normally aim to be completed within 10 minutes, and the interval between user-visible messages must not exceed 60 seconds. There is no additional manual deadline for supplementary reading of reply evidence, but it must be filtered by template fields, read in batches for the same pattern, with at most 10 per batch; formula recalculation and package/grant re-querying are prohibited.
  • State the latest available date and actual coverage for each metric. When browser acceptance has not been performed, only the public URL and real-time API accessibility may be stated.

Prerequisite dependency: the formula must first be verified

This skill is self-contained at runtime: registration/generation/publishing rely only on this skill's config.json 's api_key. However, before registering a formula package, each group of formulas must first be run successfully in quant-buddy-skill using runMultiFormulaBatchStream to confirm that data is produced; server-side trial reading is only a fallback and does not replace this step.

If the current environment does not have quant-buddy-skill, the Agent must not skip verification or directly register the formula package.

Ordinary users with the skill already installed should first check global skills; if missing, run the install command; if installed but needing a refresh, run the update command; choose one, do not run them consecutively:

npx skills list -g --json
# 未安装时
npx skills add pseudo-longinus/quant-buddy-skills -g --all
# 已安装、需要刷新时
npx skills update pseudo-longinus/quant-buddy-skills -y
  • On Windows, if symlink / EPERM reports an error, append at the end of the add command --copy and retry.
  • When debugging this skill in a source checkout or junction, do not run the above bundle-level add --all / update to overwrite the current quant-buddy-view. The fixed priority for QBV resolving the active QBS is QBS_SKILL_ROOT, sibling quant-buddy-skill/, sibling quant-buddy-skill__skillhub/; it is considered present if scripts/call.py exists as the criterion. Glob/recursive scanning must not be used, nor may quant-buddy-skill-backup-* be treated as a runnable skill.
  • After installation, you must confirm that quant-buddy-skill's config.json.api_key or QUANT_BUDDY_API_KEY is available; report only "configured/not configured/authentication succeeded or failed", and do not print the key or the full config. If authentication fails, stop and explain the blocker, and do not continue registering the formula package.
  • If you are only uploading/converting a truly pure static HTML file that contains no assets, market data, or source credentials, you may continue using this skill and declare static_content_only. Real-time asset pages must be uniformly probed through qbs_bridge.py resolve_asset_data ; only run formula validation when required_roles.formula is non-empty. Ordinary market quotes, valuations, and financials must not be rewritten as formulas just to trigger the formula package.

It is recommended to install both skills at the same level to facilitate validating formulas and migrating old formula package credentials:

<skills 目录>/
  quant-buddy-skill/ 或 quant-buddy-skill__skillhub/  ← 探索 / 公式验证(runMultiFormulaBatchStream、confirmDataMulti)
  quant-buddy-view/ 或 quant-buddy-view__skillhub/    ← 本技能:注册 Formula Package / Data Grant、生成看板、发布

For old credential migration, see tools/formula_package.md。

Entry selection (determine type first)

For fixed pages, first check the online paradigm card; for direct use direct_deliver; only fork downloads and rewrites the source HTML. Do not start from local historical templates or low-quality skeletons.

Type Display name Entry When to use
Single-stock quick page Comprehensive analysis of an A-share stock scripts/static_page.py new_asset_page Simply analyze an A-share stock and return a page; no customization/comparison/extra indicator requirements
Page template Official picks + community scripts/static_page.py templates Other fixed page forms; direct delivers directly, and only fork when the scope is inconsistent
Reply template Agent reply skeleton reply-templates/ Live page metadata's agent_reply_template.template_ref; used to constrain the Agent's final Markdown reply format, does not generate HTML
Cover component Wide Treasure Live Card / Essence Card guides/essence-cover-card.md Standalone 4:3 embedded-card-v1 artifact; implement and accept according to the guide
General process Standard real-time dashboard workflows/dashboard-end-to-end.md The user wants to "make a shareable dashboard/link" but has not specified a fixed page template
Incremental maintenance Single chart CRUD workflows/edit-existing-chart.md Your own published page needs to add/remove a line, change the time window, or check real data—only modify one chart, not rebuild the whole page
Development guide Custom page guides/bespoke-page.md build_dashboard Custom HTML/CSS/SVG pages that cannot be made, or migrating existing HTML
Migration tool Apply a common shell to an old page tools/retrofit_share_shell.md Published/generated HTML needs to remove the old QR code, old header, and old footer, and keep the same page_id update
Design system Live page UI/UX system guides/live-page-ui-ux-system.md When creating or fully refactoring a live page, choose the page prototype, theme tokens, font/density, composable patterns, and responsive transformations; unify the experience baseline but preserve page identity
Maintenance guide Browser annotations and full-page UI refinement guides/browser-feedback-refinement.md The user proposes modifications to the font hierarchy, spacing, section navigation, sticky/collapse, responsive behavior, or sharing interaction of an existing owned page; keep the same page_id, runtime contract, and page visual identity
  • For simple single A-share comprehensive analysis, query data with QBS first and deliver the business first answer, then proceed to new_asset_page; for other quantitative scenarios, also answer first, then match the corresponding online paradigm, and only fork when the scope is inconsistent. Detailed page contracts are gated by server-fixed scenarios or templates/build scripts and are not repeated here.
  • After forking, it is forbidden to continue using the source package_id/grant_id/signature; you must validate and register the current user's credentials.
  • All pages reuse assets/share-shell/; to share a shell, poster, Card Runtime, and migration details, read the corresponding guides/, and do not hand-write duplicate components.
  • Self-built quality baseline:unmatched Before building your own, you must read guides/self-build-quality.md, choose the content structure of key price levels, ranking comparisons, trends, or research narrative based on the user's question, and then implement it with the default generator / applicable bespoke components. Do not degrade cases with no template match into equal-weight fragment cards, small-font scrolling body text, or piles of technical fields. Delivery is allowed only after data acceptance and visual acceptance both pass.
  • For formula registration and read modes, see tools/formula_package.md, for data authorization see tools/data_grant.md, for static page commands and metadata see tools/static_page.md。
  • Use update for ordinary self-owned pages to keep the URL; for published template use template to determine, unless the user explicitly maintains the original template, otherwise only read-reuse or fork.

Data fetching: the two channels for real-time pages

Real-time pages can use Formula Package or Data Grant: Formula Package embeds package_id + signaturein the HTML, and calls queryFormulaPackagewhen opened; Data Grant embeds grant_id + signature, and calls queryDataGrantwhen opened. The two types of credentials can be mixed on the same page and fetch data independently of each other; after the underlying data is updated, there is no need to rebuild the page, and visitors can get the latest data by opening or refreshing. The spec does not need to write the mode field.

  • The page is "live": data is not welded into the HTML, it is fetched in real time at runtime; during build time data is fetched only once for quality inspection (data health + single-instrument copy consistency), and is not inlined.
  • Related fields are at the same level: in the page metadata, package_ids and grant_ids respectively record the two types of credentials; either channel can independently support a real-time page, and both can also exist at the same time.
  • Choose the channel according to the nature of the data: for ordinary quotes, valuation, and financials, prefer Data Grant; use Formula Package only when computation is truly needed or a custom formula convention is required, and do not forcibly rewrite it as a formula just to make the page a real-time page.
  • Common prerequisites (all already met):queryFormulaPackage / queryDataGrant CORS is opened for the page domain pages.quantbuddy.cn , and both types of signature are public data-fetching capability tokens allowed to be embedded in pages.
  • ⚠️ Protocols must be consistent: if the page is published on https://,config.json the endpoint must also be https://, otherwise the browser will block data fetching as mixed content. The current endpoint is already https://www.quantbuddy.cn/skill。

Data Grant vs Formula Package — the second channel for key-free data fetching on pages

The script scripts/data_grant.py is already available,build_dashboard and assets/data-kernel.js already support the grant panel, and can be mixed with Formula Package on the same page. For the contract see tools/data_grant.md, for the server-side design see skill_server/docs/dataGrant相关文档/数据授权-技术设计文档.md. When choosing the credential type, compare against the trade-off table below.

Data Grant and Formula Packageshare the same signed key-free mental model: the page HTML embeds a credential (Formula Package is package_id + signature, Data Grant is grant_id + signature), and visitors fetch data in real time without a key when they open the page. The difference lies in what is pinned down — Formula Package pins down "a set of formulas + read mode" (it recalculates and uses SSE); Data Grant pins down "a single platform direct data-fetch request" (no recalculation, ordinary JSON).

Trade-off rules (compare when choosing the credential type):

Data the page needs to display Which channel to use Credentials
Computed metrics / backtest NAV / IC / rankIC / time series / custom formula definitions Formula package package_id
Market data / valuation / financials / capital flows retrieved directly from the platform whitelist (closing price, price change, PE/PB…) Data authorization fast_query grant_id
Precomputed per-stock profile cards (dimension profiles such as valuation/financial quality) Data authorization stock_profile grant_id
TopN / rankings / abnormal-movement lists for live dimension scores (momentum reversal, trend structure…) Data authorization composition_select grant_id
  • One sentence:For anything that needs "computation", use the formula package; for bounded data that the platform "retrieves/selects" directly, use data authorization. The original formula package RANK role is still reserved for "compute metrics"-type multi-factor stock selection, and is not replaced by composition_select grant.
  • Unified entry point for asset live pages: first call scripts/qbs_bridge.py resolve_asset_data @params.json, explicitly declaring required_roles.profile/snapshot/report/formula and optional_fields. Routing is executed by stockProfile → fast_query(snapshot) → fast_query(report) → 必需公式 . Ordinary market data, valuation and reporting-period financials prioritize fast_query, and ordinary fields must not be rewritten in order to trigger the formula package.
  • No a priori assumptions:resolve_asset_data : Before probing, the Agent must not infer whether the platform can retrieve data based on its memory of a company's listing status, ownership, asset names or market conventions, nor may it use such memory to choose proxy assets, static descriptions, data channels or page structures in advance; before verification, it may only say "I will first verify the platform asset mapping and data availability".
  • Judge success by business coverage: A top-level success:true does not mean the page data is complete. The target asset must exist, required fields must have valid values, and must not appear in asset_errors / field_errors. Failure of an optional field is recorded only as a warning. Partial success of core roles returns incomplete, and must not be passed off as a complete page.
  • Static fallback is a hard gate:ASSET_NOT_FOUND、DATA_UNAVAILABLE: Data-level failures such as , empty results, missing target asset/required field, may continue to the next independent channel; authentication, quota, task/session, network, timeout, protocol and service errors must return blocked. Only live_data_route_receipt_v1 proves that all core live roles have been probed and all failed at the data level, only then may static_after_live_probe;static_content_only be allowed, limited to purely static content with no assets, market data or source credentials.
  • Publishing recognizes only evidence: Grant-only, formula-only and hybrid pages may all be published, but structured route/grant/formula receipts must be submitted, and the route receipt's selected_routes must correspond item by item with the actual Grant/formula receipts; free-text waivers are prohibited.
  • Two systems coexist: Exploration/verification still runs the three interfaces (fastQuery / stockProfile / selectByComposition) in quant-buddy-skill using the api-key; this skill is only responsible for registering verified requests as grant embedded pages. The api-key setup remains unchanged, not a single line.
  • Same hard threshold as the formula package: Before registering any grant, first run the corresponding interface successfully in quant-buddy-skill using the api-key, confirm hits/data output, then return to this skill to register.
  • Registration responsibility for fixed scenarios:new_asset_page The three Grant payloads for are fixedly generated and validated by the server; the Agent does not register Grants on its own; this does not exempt QBS business data queries and date validation before the first answer. After the first answer, create the fast page; when the page is opened, data is fetched in real time according to the Grant.
  • Same-origin constraint:access_dunhe=false(The page must never return paid/Q&D data), CORS/https protocol consistency, signature is a public credential and is not printed to the user—fully consistent with the formula package.

Hard rules

  1. For Chinese parameters, use @file or environment variables: Passing Chinese directly on the Windows PowerShell command line will be truncated by GBK. When registering formulas or writing specs, always use @params.json(UTF-8) or FP_PARAMS/BD_PARAMS/SP_PARAMS environment variables.
  2. Formulas must be verified before registration (hard gate): fork v2 is automatically invoked by publish_workflow.py based on the final package boundary parsed from review validate_package_set, and verification and registration are derived from the same {formulas,reads,begin_date} contract. The Agent is responsible for checking the formula semantics, target assets, and peer mappings in the review, and must not bypass the generated plan to register separately; if a complex cross-asset formula has not been reviewed, required outputs/reads are inconsistent, or the PE/PB level output lacks a clear algorithm and positive integer window, the publisher rejects it before the network call. By default, fork inherits the level metric already declared by the source template and able to pass QBS, and is not forced to change to a fixed 250-day period.
  3. Verification parameters must also be swapped cleanly: When calling runMultiFormulaBatchStream ,user_query must reflect the current user request and the current asset; if task_id is passed, it must be new for this task. When copying an example, do not replace only formulaswhile leaving old user_querysuch as "Kweichow Moutai factsheet", otherwise backend auditing and replay will be polluted.
  4. signature is a credential: Do not print it in conversations facing end users; the dashboard will write it into public HTML for real-time data retrieval, so confirm it is acceptable before publishing.
  5. Do not write Agent as the tag source: When explicitly passing scene_tags / paradigm_tags ,tagging_method use manual / migration / unknown; if LLM automatic recognition is needed, call scripts/static_page.py autotag. Do not pass tagging_method:"agent"again, and do not write tagging_meta.method in agent。
  6. Failures must be stated clearly: When the script returns code != 0 , repeat back to the user "which step is stuck (command name) + error summary"; do not end with a blank or pure log.
  7. Specific assets must be verified first, then explained or routed: When a user request involves a specific asset, especially US stocks, Hong Kong stocks, ETFs, special names, or assets written in mixed Chinese and English, the above "Specific Asset Evidence Gate" (resolve_asset_data probe) must be executed first; do not wait until preparing to make a negative judgment to verify. Do not infer whether the platform can retrieve data based on real-world listing status, ownership, general company knowledge, historical memory, or intuition about asset names, and do not use such inference to choose proxy assets, static explanations, data channels, or page structures. A hit in the asset library only proves ticker mapping;resolve_asset_data successful probing proves the corresponding data capability; verify quotes/valuation, profile, financials, or other data according to the user's actual needs, and do not expand unboundedly for the sake of being "more comprehensive". Verification results must distinguish between asset unmapped, interface unsupported, field missing, and quota limitation; a single missing field, restricted window, or quota limitation must not be broadened into a statement that the asset is unavailable. Only when tool evidence is directly relevant to the user's needs may you state in the page or reply whether it is listed/private, a proxy, or a market identity; before verification, you may only say "I will first verify the platform asset mapping and data availability."
  8. Upload body images before referencing them: First use static_page.py image_upload to obtain the absolute page_id under the target https://pages.quantbuddy.cn/pages/assets/...webp URL, then write into HTML; cross-page reuse of hosted URLs is prohibited. Images must have explicit alt and width/height; no lazy within the first screen and poster target, only below the main content may loading="lazy". Standard image panel enables current-page large-image preview by default, only decorative images set zoomable:false; do not open image URLs in a new window. Fork must follow the manifest's images[] upload to the target page and replace the marker, and must not retain the source image URL.
  9. templates summary must cover all candidates, and a disk-write failure must not be left unhandled:items_summary entry count must equal item_count(the true count after deduplicating complete candidates, not the server-side possibly-not-recomputed total), and it is not allowed to judge unmatchedby looking at only a subset of the candidates; once it returns error:"TEMPLATES_PERSIST_FAILED" or error:"TEMPLATES_RESPONSE_SHAPE_UNEXPECTED"(disk-write failure or abnormal response structure), you must first explain to the user "paradigm candidates could not be fully confirmed, routing judgment is suspended", and it is prohibited to judge as unmatched and take the self-built path under such incomplete information, and alsomust not be remedied by repeatedly calling templates (the hard rule that each task may still only call it once remains unchanged); retries are only allowed for clear transient network failures, and only once.(the hard rule that each task can still only call this once remains unchanged); retries are only allowed for clear transient network failures, and only once.
  10. Card Runtime first performs a zero-side-effect structural precheck: HTML containing a Card Runtime artifact must be run by publish_workflow.py with fake credentials via verify_page.mjs --card-runtime-structure-onlybefore QBS validation, registration, image upload, and publishing. When the main content and Card share credentials, use the marker array fan-out; each array element must still be globally unique and appear exactly once in the HTML. Empty manifest credentials are prohibited; ordinary <img> must have non-empty src, only explicitly declared data-qb-runtime-src and preview images awaiting runtime assignment may be temporarily empty; at the same time, registering equivalent duplicate Card package/grant is prohibited.
  11. Before ordinary page creation, you must first check the paradigm card and explicitly confirm routing:new_page will validate complete candidates and bind the route. Fork must declare the degree of borrowing, and once determined it must not be changed to unmatched; when inheritance does not hold, it can only be downgraded to Compose within the fork.build_dashboard For fork/inherit*, full-page builds are prohibited; for fork/compose the complete page uses static_page.py compose_page;emit:"panel_block" and is still only a partial artifact. Once bound to Compose, a full fork_prepare must not be performed again.
  12. Local acceptance and public-network acceptance have separate responsibilities:fork-local locally file://(origin=null) with a test browser that relaxes the same-origin policy to run real data-fetch rendering (security_mode:"disabled-web-security"), and the layout/placeholder/runtime error/image/Card Runtime gates are enforced as usual;public-smoke keeps the browser's default security policy, and data interface CORS/Failed to fetch/runtime failures are still strictly blocked. Platform-injected /webapi/skill/track analytics beacons are fire-and-forget; their CORS/network failures are downgraded to non_core_console_warnings, so a successful page is no longer failed to publish; failures of data interfaces (queryDataGrant/queryFormulaPackage) are still blocking core errors.
  13. Fork data channels must inherit the source contract: the goal of fork is to replace the target and preserve the source paradigm's runtime contract, not to redesign the data layer. If a role in the source template uses a formula package, the same role on the target page continues to use the formula package; if the source uses fast_query / stock_profile / composition_select Data authorization: the target page continues to use data authorization of the same kind, same query_type, and same response shape. It is forbidden to change a source financial formula package to a grant in a fork merely because "financial data can usually go through fast_query(report)", and it is also forbidden to change a source grant to a formula package in the opposite direction. Only unmatched / when explicitly rebuilding from scratch should channel selection be redone; in this case, platform whitelist report-period financials take priority fast_query(query_type="report")。
  14. Existing files are first hosted as-is, then progressively enhanced on the same page: all existing files converted to live pages first execute static-first workflow, including composite requests of the form "correct errors first, redo, then activate". Use file_prepare and its persistent publishing parameters; do not research or rewrite the source first. For approved dynamic sources, first capture read-only responses and replay them to preserve local interaction; when only visual freezing is possible, make the loss explicit. After the first public-network acceptance, deliver the static link immediately; do not wait for the user to urge again; authorized enhancements continue to execute. Fidelity enhancements use Data Grant/Formula Package by channel, and only successful areas declare data-qb-live-mode="live" and data-qb-live-tag="qbs-formula-package|qbs-data-grant"; unconverted content retains a snapshot, and attributes are not forcibly injected for static declarations. After validating a local candidate, update only the same page_id; on failure, do not overwrite the last successful version and do not create an alternative link; unknown writes and recovery failures must be explicitly recorded and must not be described as success. The first static version does not require a template fork or Handoff; this process does not introduce Block Runtime or global tag refactoring.
  15. CHANGELOG serves only as version audit: when maintaining, upgrading, or troubleshooting historical behavior changes, first read CHANGELOG.md the latest version and history entries related to the issue; when executing page tasks, the current rules still take SKILL.md + workflows/** + tools/** + guides/** as authoritative. The CHANGELOG may contain old wording that has been reversed or deprecated by later versions; it is forbidden to use historical entries to override current rules.

Tool Overview

Parameter convention: all script parameters area JSON stringpositional parameter (or @params.json / environment variable), such as list '{"scope":"test_all"}'. The command line also supports --scope test_all / --key=value intuitive style (simple parameters only; complex structures such as formulas and specs still use @file/environment variables to avoid GBK truncation).

Script Command Purpose Documentation
scripts/formula_package.py register / query / list / revoke / refresh Formula task package: register data-fetching capability; query supports outputs and `result_mode=full summary
scripts/data_grant.py register / query / list / revoke / refresh Data authorization: pin a fastQuery/stockProfile/selectByComposition request as grant_id+signature, allowing the page to directly fetch bounded data without a key (for trade-offs, see "Data Authorization vs Formula Package") tools/data_grant.md
scripts/build_dashboard.py (single command,emit:"panel_block" uses local output) spec → live real-time data dashboard HTML; local output mode only generates chart <script> fragments with markers, for embedding charts in bespoke pages tools/build_dashboard.md
scripts/stock_comparison.py apply @params.json for stock_analysis_instance_v1 native closing-price chart, merge benchmark series, dual Y axes, and data table; keep #priceChart a single owner, and refuse secondary takeover by a generic panel tools/stock_comparison.md
scripts/stock_window.py apply @params.json for legacy stock_analysis_instance_v1 set the scrolling display window; after generating controlled HTML, must browser-precheck and update the original page_id tools/stock_window.md
scripts/chart_edit.py inspect / add_series(supports axis:"right" dual-axis) / remove_series / set_window / query_data CRUD for a single chart on a published page: only touch the one requested spot, do not re-validate/recompute other unrelated series on the page tools/chart_edit.md
scripts/compile_bespoke_page.py (single command) [shell processing script] bespoke main HTML → self-contained HTML with inlined public share shell / logo / qr-mini / data-kernel guides/share-shell.md
scripts/retrofit_share_shell.py (single command) [shell processing script] old HTML/published page → remove old QR code/old header/old footer, fit into public share shell (assets/share-shell/), can update at the original link tools/retrofit_share_shell.md
scripts/data_kernel_retrofit.py (single command) By QB_DATA_KERNEL marker or strict old-kernel fingerprint, replace only the data-kernel in the page; reject write-back if there are zero/multiple hits tools/data_grant.md
scripts/static_page.py new_asset_page / templates / direct_deliver / new_page / update_progress / publish_final / publish_verified / upload / update / download / image_upload / image_list / fork_prepare / fork_review_update / fork_validate / retrofit_card_runtime / other management commands simple single-stock quick return, paradigm routing, body images, direct deterministic delivery, first-chain progress, tiered browser gating, and page publishing management tools/static_page.md
scripts/qbs_handoff_adapter.py @handoff.json verify the lineage, contract fingerprint, and artifact hash of the QBS computation capsule, and output covered/partial/unusable; not responsible for routing, ownership, building, or publishing this section "entering from QBS parallel handoff"
scripts/qbs_bridge.py resolve_asset_data / <quant-buddy-skill tool> @params.json / validate_package_set / validate_grant_set unified real-time route probing and inherit QBV→QBS task_id; generate route/grant/formula fingerprint binding receipts per the final package/Grant contract this section "new session routing"
scripts/publish_workflow.py @publish-plan.json manifest v2 drives review/contract pre-check, package+Grant verification, one registration per role, multi-Marker fan-out replacement, and a single publish_verified; v1 JSON compatible tools/publish_workflow.md
scripts/validate_agent_reply.py (single command) verify the final-state contract bound to the publisher SHA256 and the Markdown draft, and check the public URL, section structure, and sensitive information; can clean up the task temporary parameter file after success —
scripts/verify_page.mjs (single command) pre-publish/post-publish page acceptance: standard three viewports, h1, placeholders, horizontal overflow, core console errors; annotation iterations can use --profile ui-refinement、--extra-viewport and --min-visible-font-px; paradigm card plus --card-runtime or --card-runtime-only guides/browser-feedback-refinement.md
assets/data-kernel.js (frontend kernel, not a script) one copy of "data fetching + cleaning + fault tolerance" shared by hand-made bespoke pages; inline into page <script> use guides/bespoke-page.md
assets/share-shell/ (public component) header, footer, refresh button, share poster overlay, poster canvas, copy link, and copy/download behavior shared by all landing pages guides/share-shell.md
assets/live-card.css (public component) light card style source for paradigm card artifacts; by build_dashboard.py as data-qb-card-style embedded into the card runtime artifact guides/essence-cover-card.md
scripts/card_runtime_retrofit.py (called by static_page) rebuild an independent card runtime artifact for a published/officially featured page (embedded-card-v1), can write back at the original link tools/static_page.md
guides/essence-cover-card.md (development guide) condense page highlights into an independent 4:3 card runtime artifact (embedded-card-v1, blank host independently hydrates), and clarify the responsibility boundaries of the artifact, paradigm card snapshot, and full-page cover —

three production routes: fixed pages reuse online templates first; standard dashboards go through build_dashboard(declarative fast path); only design pages that need custom layout/SVG write bespoke main HTML. stock native chart owner gate:stock_analysis_instance_v1 of #priceChart is always held by the page's native runtime; injecting a second renderer with build_dashboard.py emit="panel_block" is forbidden. When adding benchmark lines such as CSI 300, you must use scripts/stock_comparison.py to extend the native load/render/table lifecycle. stock legacy time window gate:stock_analysis_instance_v1 when QBV_RENDER_JS marker is missing, changing the window must use scripts/stock_window.py apply, do not generate or execute output/*.py temporary patches. After conversion, you must run a local browser pre-check,static_page.py update the same page and perform public-network acceptance. The data layer uniformly calls assets/data-kernel.js(QB.query to fetch data,QB.series/lastValue/topValues to unpack and clean), stop copying fetch/unpacking on every page and stepping into the pit of "fake 0/gaps". See guides/bespoke-page.md. Before publishing, use scripts/verify_page.mjs <html_file> --require-browser to check desktop and 390px/320px mobile, ensuring no QB_SHARED_ / replace_with_signature / pkg_replace residue, presence of <h1>, no critical horizontal overflow and no core data-fetching script errors. When the page declares stock_analysis_instance_v1 and configures a benchmark in data_sources.benchmark_series or comparison.benchmark_series , the script will also wait for a stability window after the runtime pending count reaches zero, and forcibly check the final canvas, the two valid chart series for the stock/benchmark, common trading days, the benchmark's right-side Y axis, dual Y axes and the data table column; at the same time it statically rejects the native runtime and panel_block jointly taking over #priceChart. A comparison page cannot be considered delivered just because the runtime is ready or the first frame briefly appears. Pages containing paradigm card artifacts should add --card-runtime(or --card-runtime-only) to accept the artifact/manifest/independent hydrate. When Playwright is not in the default Node search path, you can use QBV_PLAYWRIGHT_MODULE_ROOT to point to the playwright/ containing node_modules root directory; you can use CHROME_PATH to specify the browser executable; if unspecified, Chrome/Edge is auto-discovered. If the machine has no Playwright/Chrome/Edge, the script will explicitly mark it as static-only, and it cannot be treated as full browser acceptance.

Historical minute and continuous futures data sources

  • Before registering or forking to change assets/windows, read Minute market data support scope and out-of-range hints: A-share/US stocks and domestic futures start on 2026-05-13, Hong Kong stocks on 2026-05-20, domestic indices on 2026-08-13; US/Hong Kong indices and futures are not yet supported. A full window earlier than the start point is not registered or authorized; partial coverage is hinted first and annotated on the page, the raw payload is not silently trimmed, and complete coverage is not claimed.

  • For current/most recent complete-day minutes use fast_query_minute Grant (keep fields); for historical cross-day minutes use fast_query_minute_range Grant (all columns, no fields/format/remove_nan). Choose either an absolute window or a natural-day offset from -70 to -1, excluding the market's today. See tools/data_grant.md。

  • Historical minute CSV is a long table of trade_date/timestamp/market columns; the kernel reads the actual header, not the daily wide table. Absolute windows are fixed, offset grants roll; the page side holds the Grant rather than a temporary CSV address, and historical minutes are not called "current intraday".

  • Continuous futures: a single day only shows the specific contract/status of the selected trade_date; daily-frequency windows and cross-day minutes interpret rollover events by trade_date, and night sessions cannot be matched using UTC natural days. inferred does not equal independent real-time verification, and attached warnings do not affect market data success or serve as a reason for publish failure.

Configuration

config.json: fill in api_key(obtained from https://www.quantbuddy.cn/login ). You can create config.local.json to override endpoint / api_key etc. (not committed to the repository). Environment variable QUANT_BUDDY_API_KEY Only a fallback when neither config.json nor config.local.json has an api_key; this is not the regular configuration method. The main() of all scripts in this skill support temporary override via the api_key field in tool call parameters (effective only for the current call, with the highest priority; see scripts/common.py::configure_trace_context); at the same priority there is also the environment variable QBV_API_KEY, used for the scenario "you have a ready-made @file parameter on hand (for example publish_workflow.py @publish-plan.json, and by design this plan file does not contain credentials) and do not want to modify this file right now to insert an api_key"—do notset QUANT_BUDDY_API_KEYjust to temporarily change the key; that only takes effect when config.json is empty, and setting it when config.json already has a default key will have no effect at all.

K-line dashboard

A regular K-line dashboard uses build_dashboard 's type:candlestick panel, directly binding to the same OHLCV Grant to draw candlesticks, volume, and moving averages; only when PNG/image is explicitly the only requirement is renderKLine an image artifact.

If a K-line page includes MA/moving averages, they must be placed in the same candlestick panel's overlays , aligned with OHLCV by date; it is forbidden to use a separate line/number panel to impersonate a K-line overlay.