chore(release): document premium skill package flow
This commit is contained in:
@@ -55,6 +55,52 @@ Do not add private birth data, API keys, or desktop oracle screenshots to this p
|
||||
## Birth-Time Rectification
|
||||
|
||||
请使用主动问询式校时:先生成候选时间扫描和选择题,我只回答 A/B/C/D。
|
||||
""",
|
||||
"SALES_PACKAGE.md": """# Premium Skill Sales Package
|
||||
|
||||
Edition: premium_cloud_drive
|
||||
|
||||
## What This Package Includes
|
||||
|
||||
- Unified Jyotish runtime entrypoints for skill, MCP, API, and local scripts.
|
||||
- Evidence packet workflow for D1/D9/D10/D2/D4, dasha boundaries, audit rows, and external oracle status.
|
||||
- Guided topic entrypoint for users who do not know what to ask.
|
||||
- Strict workflow prompts for high-rigor readings.
|
||||
- Release hygiene checks for privacy, clean unzip usage, and user invocation acceptance.
|
||||
|
||||
## What This Package Does Not Include
|
||||
|
||||
- Private birth data, private case reports, API keys, or desktop oracle screenshots.
|
||||
- Guaranteed VedAstro cloud closure without `official_raw_response`.
|
||||
- Completed PyJHora/JHora parity rows unless the operator imports external raw oracle outputs.
|
||||
- Completed real case replay unless structured case outcomes are imported.
|
||||
|
||||
Do not include private birth data in this package. Users provide their own birth data at runtime.
|
||||
""",
|
||||
"GUIDED_ENTRYPOINT.md": """# Guided Entrypoint
|
||||
|
||||
Use this when the user loads the skill but does not know how to ask.
|
||||
|
||||
## Default Flow
|
||||
|
||||
1. Ask for birth date, exact or approximate birth time, birthplace, and question language.
|
||||
2. Run `direct_chart` when birth time is reliable; run `rectification` when birth time is uncertain.
|
||||
3. Generate `evidence_packet`, `guided_topics`, and `Technique Audit Table` before interpretation.
|
||||
4. Use `blind=true` when prior personal feedback must not influence the reading.
|
||||
5. Mark VedAstro as `official_verified`, `official_blocked`, or `local_fallback`.
|
||||
6. Mark PyJHora/JHora, jyotishganit, Western oracle, and Real Case Calibration as `used`, `partial`, or `blocked`.
|
||||
|
||||
## User-Facing Starter
|
||||
|
||||
请提供出生日期、出生时间、出生地点和想看的语言。
|
||||
如果你不知道该问什么,我会先运行 evidence packet,然后给出 3-5 个最值得继续看的主题。
|
||||
|
||||
## Output Requirements
|
||||
|
||||
- Start from evidence, not story.
|
||||
- Show blocked or partial techniques.
|
||||
- Never claim official cloud evidence without raw official evidence.
|
||||
- Keep `guided_topics` available for the next turn.
|
||||
""",
|
||||
}
|
||||
|
||||
|
||||
@@ -96,22 +96,31 @@ def _case_from_args(args: argparse.Namespace, themes: list[str]) -> dict[str, An
|
||||
|
||||
|
||||
def _run_capability_catalog(case: dict[str, Any]) -> dict[str, Any]:
|
||||
completed = subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
str(RUNNER),
|
||||
"--bundle",
|
||||
"official_full_capability_catalog",
|
||||
"--birth-json",
|
||||
json.dumps(case, ensure_ascii=False),
|
||||
],
|
||||
cwd=ROOT,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
timeout=max(5.0, float(os.environ.get("VEDASTRO_TIMEOUT_SECONDS", "5") or 5)),
|
||||
check=False,
|
||||
env=os.environ.copy(),
|
||||
)
|
||||
try:
|
||||
completed = subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
str(RUNNER),
|
||||
"--bundle",
|
||||
"official_full_capability_catalog",
|
||||
"--birth-json",
|
||||
json.dumps(case, ensure_ascii=False),
|
||||
],
|
||||
cwd=ROOT,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
timeout=max(5.0, float(os.environ.get("VEDASTRO_TIMEOUT_SECONDS", "5") or 5)),
|
||||
check=False,
|
||||
env=os.environ.copy(),
|
||||
)
|
||||
except subprocess.TimeoutExpired:
|
||||
return {
|
||||
"available": False,
|
||||
"status": "official_full_capability_catalog_timeout",
|
||||
"summary": {},
|
||||
"domain_routing": {},
|
||||
"sample_outputs": {},
|
||||
}
|
||||
if completed.returncode != 0:
|
||||
return {
|
||||
"available": False,
|
||||
|
||||
@@ -36,6 +36,8 @@ def test_premium_skill_zip_runs_from_clean_directory(tmp_path: Path) -> None:
|
||||
required = [
|
||||
"INSTALL.md",
|
||||
"USER_PROMPTS.md",
|
||||
"SALES_PACKAGE.md",
|
||||
"GUIDED_ENTRYPOINT.md",
|
||||
"PACKAGE_ACCEPTANCE.json",
|
||||
"references/real_case_calibration/replay_manifest.json",
|
||||
"references/oracle/three_engine_parity_replay_manifest.json",
|
||||
|
||||
@@ -20,6 +20,8 @@ def test_skill_release_package_dry_run_uses_safe_tracked_files() -> None:
|
||||
assert not any("private" in path.lower() for path in plan["files"])
|
||||
assert "RELEASE_MANIFEST.json" in plan["generated_files"]
|
||||
assert "PACKAGE_ACCEPTANCE.json" in plan["generated_files"]
|
||||
assert "SALES_PACKAGE.md" in plan["generated_files"]
|
||||
assert "GUIDED_ENTRYPOINT.md" in plan["generated_files"]
|
||||
assert plan["required_contracts"]["references/real_case_calibration/replay_manifest.json"] is True
|
||||
assert plan["required_contracts"]["references/oracle/three_engine_parity_replay_manifest.json"] is True
|
||||
assert "references/real_case_calibration/replay_manifest.json" in plan["files"]
|
||||
@@ -41,6 +43,8 @@ def test_skill_release_package_can_write_zip(tmp_path) -> None:
|
||||
assert "USER_PROMPTS.md" in names
|
||||
assert "RELEASE_MANIFEST.json" in names
|
||||
assert "PACKAGE_ACCEPTANCE.json" in names
|
||||
assert "SALES_PACKAGE.md" in names
|
||||
assert "GUIDED_ENTRYPOINT.md" in names
|
||||
assert "references/real_case_calibration/replay_manifest.json" in names
|
||||
assert "references/oracle/three_engine_parity_replay_manifest.json" in names
|
||||
assert "references/oracle/western_oracle_adapter_contract.md" in names
|
||||
@@ -48,11 +52,18 @@ def test_skill_release_package_can_write_zip(tmp_path) -> None:
|
||||
with zipfile.ZipFile(target) as archive:
|
||||
install = archive.read("INSTALL.md").decode("utf-8")
|
||||
prompts = archive.read("USER_PROMPTS.md").decode("utf-8")
|
||||
sales = archive.read("SALES_PACKAGE.md").decode("utf-8")
|
||||
guided = archive.read("GUIDED_ENTRYPOINT.md").decode("utf-8")
|
||||
acceptance = json.loads(archive.read("PACKAGE_ACCEPTANCE.json").decode("utf-8"))
|
||||
assert "python3 scripts/user_invocation_acceptance_check.py" in install
|
||||
assert "https://github.com/732642856/yinduzhanxing" in install
|
||||
assert "guided_topics" in prompts
|
||||
assert "official_blocked" in prompts
|
||||
assert "western_oracle_payload" in prompts
|
||||
assert "premium_cloud_drive" in sales
|
||||
assert "Do not include private birth data" in sales
|
||||
assert "blind=true" in guided
|
||||
assert "Technique Audit Table" in guided
|
||||
assert "guided_topics" in guided
|
||||
assert acceptance["status"] in {"pass", "blocked"}
|
||||
assert acceptance["required_contracts"]["references/oracle/three_engine_parity_replay_manifest.json"] is True
|
||||
|
||||
@@ -6,10 +6,25 @@ import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from scripts import vedastro_user_entrypoint
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def test_capability_catalog_timeout_degrades_to_blocked(monkeypatch) -> None:
|
||||
def timeout_run(*args, **kwargs):
|
||||
raise subprocess.TimeoutExpired(cmd=args[0], timeout=kwargs.get("timeout"))
|
||||
|
||||
monkeypatch.setattr(vedastro_user_entrypoint.subprocess, "run", timeout_run)
|
||||
|
||||
report = vedastro_user_entrypoint._run_capability_catalog({"year": 2000})
|
||||
|
||||
assert report["available"] is False
|
||||
assert report["status"] == "official_full_capability_catalog_timeout"
|
||||
assert report["summary"] == {}
|
||||
|
||||
|
||||
def test_user_entrypoint_runs_catalog_and_strict_workflow_contract() -> None:
|
||||
catalog_stub = {
|
||||
"available": True,
|
||||
|
||||
Reference in New Issue
Block a user