refactor: split meta skill CLI and review gates

This commit is contained in:
yaojingang
2026-06-13 19:17:27 +08:00
parent 5ba1c93a09
commit e5c85b394f
30 changed files with 1320 additions and 1149 deletions
+2
View File
@@ -63,8 +63,10 @@ Clean test-only scratch directories after verification with `rm -rf tests/tmp_*`
- `scripts/render_review_studio.py`: Review Studio gate orchestration. Keep gate scoring, evidence links, and action generation separate from layout helpers.
- `scripts/review_studio_layout.py`: Review Studio static layout and CSS contract.
- `scripts/review_studio_formatting.py`: Review Studio dictionary-to-panel formatting and Chinese metric labels.
- `scripts/review_studio_gates.py`: Review Studio gate evaluation, release decision scoring, and gate status labels.
- `scripts/skill_report_model.py`, `scripts/skill_report_metrics.py`, `scripts/skill_report_charts.py`: skill overview data model, scoring, and inline SVG chart generation.
- `scripts/yao_cli_config.py`: CLI target maps, archetype heuristics, diagnosis copy, and side-effect-free shaping helpers.
- `scripts/yao_cli_parser.py`: CLI argparse command surface, flags, choices, and command handler binding.
New helper modules that are imported by CLI/report scripts but are not standalone commands must declare:
+1 -1
View File
@@ -15,7 +15,7 @@
"agent-skills-compatible"
],
"package_metadata": "registry/packages/yao-meta-skill.json",
"package_sha256": "742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f"
"package_sha256": "d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5"
}
]
}
+3 -3
View File
@@ -15,8 +15,8 @@
"trust_level": "local",
"license": "MIT",
"checksums": {
"package_sha256": "742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f",
"archive_sha256": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9"
"package_sha256": "d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5",
"archive_sha256": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451"
},
"compatibility": {
"openai": "pass",
@@ -47,7 +47,7 @@
},
"distribution": {
"archive_verified": true,
"archive_sha256": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9",
"archive_sha256": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451",
"package_verification": "reports/package_verification.json",
"install_simulated": true,
"install_simulation": "reports/install_simulation.json"
+1 -1
View File
@@ -1,7 +1,7 @@
{
"ok": true,
"schema_version": "2.0",
"generated_at": "2026-06-13T10:57:52Z",
"generated_at": "2026-06-13T11:16:31Z",
"skill_dir": ".",
"privacy_contract": {
"storage": "local-first",
+32 -24
View File
@@ -191,6 +191,7 @@
"scripts/render_system_model.py",
"scripts/resource_boundary_check.py",
"scripts/review_studio_formatting.py",
"scripts/review_studio_gates.py",
"scripts/review_studio_layout.py",
"scripts/run_conformance_suite.py",
"scripts/run_description_optimization_suite.py",
@@ -209,7 +210,8 @@
"scripts/validate_skill.py",
"scripts/verify_package.py",
"scripts/yao.py",
"scripts/yao_cli_config.py"
"scripts/yao_cli_config.py",
"scripts/yao_cli_parser.py"
],
"assets": [
"templates/basic_skill.md.j2",
@@ -260,7 +262,7 @@
],
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
}
@@ -498,7 +500,7 @@
"strategy": "Ship the neutral source tree and expose OpenAI-facing interface metadata as a generated companion file.",
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
},
@@ -509,7 +511,7 @@
},
"scripts": {
"strategy": "Keep scripts as local package resources; expose help-smoke and permission metadata for reviewer approval before execution.",
"script_count": 66,
"script_count": 68,
"help_smoke_failed_count": 0
},
"permissions": {
@@ -721,7 +723,7 @@
"strategy": "Ship the neutral source tree and expose OpenAI-facing interface metadata as a generated companion file.",
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
},
@@ -732,7 +734,7 @@
},
"scripts": {
"strategy": "Keep scripts as local package resources; expose help-smoke and permission metadata for reviewer approval before execution.",
"script_count": 66,
"script_count": 68,
"help_smoke_failed_count": 0
},
"permissions": {
@@ -980,6 +982,7 @@
"scripts/render_system_model.py",
"scripts/resource_boundary_check.py",
"scripts/review_studio_formatting.py",
"scripts/review_studio_gates.py",
"scripts/review_studio_layout.py",
"scripts/run_conformance_suite.py",
"scripts/run_description_optimization_suite.py",
@@ -998,7 +1001,8 @@
"scripts/validate_skill.py",
"scripts/verify_package.py",
"scripts/yao.py",
"scripts/yao_cli_config.py"
"scripts/yao_cli_config.py",
"scripts/yao_cli_parser.py"
],
"assets": [
"templates/basic_skill.md.j2",
@@ -1049,7 +1053,7 @@
],
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
}
@@ -1287,7 +1291,7 @@
"strategy": "Preserve the source tree directly; write target notes in targets/claude/README.md.",
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
},
@@ -1298,7 +1302,7 @@
},
"scripts": {
"strategy": "Scripts remain local package resources and must be reviewed through trust and permission reports before use.",
"script_count": 66,
"script_count": 68,
"help_smoke_failed_count": 0
},
"permissions": {
@@ -1510,7 +1514,7 @@
"strategy": "Preserve the source tree directly; write target notes in targets/claude/README.md.",
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
},
@@ -1521,7 +1525,7 @@
},
"scripts": {
"strategy": "Scripts remain local package resources and must be reviewed through trust and permission reports before use.",
"script_count": 66,
"script_count": 68,
"help_smoke_failed_count": 0
},
"permissions": {
@@ -1769,6 +1773,7 @@
"scripts/render_system_model.py",
"scripts/resource_boundary_check.py",
"scripts/review_studio_formatting.py",
"scripts/review_studio_gates.py",
"scripts/review_studio_layout.py",
"scripts/run_conformance_suite.py",
"scripts/run_description_optimization_suite.py",
@@ -1787,7 +1792,8 @@
"scripts/validate_skill.py",
"scripts/verify_package.py",
"scripts/yao.py",
"scripts/yao_cli_config.py"
"scripts/yao_cli_config.py",
"scripts/yao_cli_parser.py"
],
"assets": [
"templates/basic_skill.md.j2",
@@ -1838,7 +1844,7 @@
],
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
}
@@ -2076,7 +2082,7 @@
"strategy": "Preserve references, scripts, assets, evals, reports, and adapter metadata as relative package resources.",
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
},
@@ -2086,7 +2092,7 @@
},
"scripts": {
"strategy": "Expose script and permission metadata for downstream clients or installers to enforce.",
"script_count": 66,
"script_count": 68,
"help_smoke_failed_count": 0
},
"permissions": {
@@ -2292,7 +2298,7 @@
"strategy": "Preserve references, scripts, assets, evals, reports, and adapter metadata as relative package resources.",
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
},
@@ -2302,7 +2308,7 @@
},
"scripts": {
"strategy": "Expose script and permission metadata for downstream clients or installers to enforce.",
"script_count": 66,
"script_count": 68,
"help_smoke_failed_count": 0
},
"permissions": {
@@ -2542,6 +2548,7 @@
"scripts/render_system_model.py",
"scripts/resource_boundary_check.py",
"scripts/review_studio_formatting.py",
"scripts/review_studio_gates.py",
"scripts/review_studio_layout.py",
"scripts/run_conformance_suite.py",
"scripts/run_description_optimization_suite.py",
@@ -2560,7 +2567,8 @@
"scripts/validate_skill.py",
"scripts/verify_package.py",
"scripts/yao.py",
"scripts/yao_cli_config.py"
"scripts/yao_cli_config.py",
"scripts/yao_cli_parser.py"
],
"assets": [
"templates/basic_skill.md.j2",
@@ -2611,7 +2619,7 @@
],
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
}
@@ -2849,7 +2857,7 @@
"strategy": "Keep optional directories as relative resources next to SKILL.md.",
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
},
@@ -2860,7 +2868,7 @@
},
"scripts": {
"strategy": "Scripts remain local optional resources and should advertise --help when executable.",
"script_count": 66,
"script_count": 68,
"help_smoke_failed_count": 0
},
"permissions": {
@@ -3065,7 +3073,7 @@
"strategy": "Keep optional directories as relative resources next to SKILL.md.",
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
},
@@ -3076,7 +3084,7 @@
},
"scripts": {
"strategy": "Scripts remain local optional resources and should advertise --help when executable.",
"script_count": 66,
"script_count": 68,
"help_smoke_failed_count": 0
},
"permissions": {
+3 -3
View File
@@ -6,10 +6,10 @@
"context_budget_tier": "production",
"context_budget_limit": 1000,
"skill_body_tokens": 811,
"other_text_tokens": 869504,
"other_text_tokens": 871624,
"estimated_initial_load_tokens": 987,
"estimated_total_text_tokens": 870315,
"relevant_file_count": 327,
"estimated_total_text_tokens": 872435,
"relevant_file_count": 368,
"unused_resource_dirs": [],
"quality_signal_points": 130,
"quality_density": 131.7
+1 -1
View File
@@ -8,7 +8,7 @@
"installed_skill_dir": "dist/install-simulation/simulate-yao-meta-skill/yao-meta-skill",
"summary": {
"archive_present": true,
"archive_entry_count": 488,
"archive_entry_count": 490,
"archive_extracted": true,
"entrypoint_loaded": true,
"manifest_loaded": true,
+10 -10
View File
@@ -34,7 +34,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 23.11,
"duration_ms": 32.51,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -62,7 +62,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 23.56,
"duration_ms": 32.64,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -85,7 +85,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 24.17,
"duration_ms": 38.43,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -113,7 +113,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 23.84,
"duration_ms": 31.51,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -136,7 +136,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 22.51,
"duration_ms": 31.34,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -164,7 +164,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 26.03,
"duration_ms": 30.94,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -187,7 +187,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 28.48,
"duration_ms": 30.5,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -214,7 +214,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 23.17,
"duration_ms": 31.42,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -237,7 +237,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 23.94,
"duration_ms": 31.18,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -266,7 +266,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 22.69,
"duration_ms": 30.97,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
+10 -10
View File
@@ -23,16 +23,16 @@ Command runner evidence is present. This proves the eval harness executed an ext
| Case | Variant | Mode | Model | Duration ms | Tokens | Score | Status |
| --- | --- | --- | --- | ---: | ---: | ---: | --- |
| skill-package-contract | baseline | command | local-output-eval-runner | 23.11 | 33 | 0.0 | pass |
| skill-package-contract | with_skill | command | local-output-eval-runner | 23.56 | 73 | 100.0 | pass |
| output-eval-expectation | baseline | command | local-output-eval-runner | 24.17 | 36 | 0.0 | pass |
| output-eval-expectation | with_skill | command | local-output-eval-runner | 23.84 | 80 | 100.0 | pass |
| ir-before-packaging | baseline | command | local-output-eval-runner | 22.51 | 33 | 0.0 | pass |
| ir-before-packaging | with_skill | command | local-output-eval-runner | 26.03 | 80 | 100.0 | pass |
| near-neighbor-boundary | baseline | command | local-output-eval-runner | 28.48 | 36 | 0.0 | pass |
| near-neighbor-boundary | with_skill | command | local-output-eval-runner | 23.17 | 65 | 100.0 | pass |
| file-backed-governed-package | baseline | command | local-output-eval-runner | 23.94 | 37 | 0.0 | pass |
| file-backed-governed-package | with_skill | command | local-output-eval-runner | 22.69 | 98 | 100.0 | pass |
| skill-package-contract | baseline | command | local-output-eval-runner | 32.51 | 33 | 0.0 | pass |
| skill-package-contract | with_skill | command | local-output-eval-runner | 32.64 | 73 | 100.0 | pass |
| output-eval-expectation | baseline | command | local-output-eval-runner | 38.43 | 36 | 0.0 | pass |
| output-eval-expectation | with_skill | command | local-output-eval-runner | 31.51 | 80 | 100.0 | pass |
| ir-before-packaging | baseline | command | local-output-eval-runner | 31.34 | 33 | 0.0 | pass |
| ir-before-packaging | with_skill | command | local-output-eval-runner | 30.94 | 80 | 100.0 | pass |
| near-neighbor-boundary | baseline | command | local-output-eval-runner | 30.5 | 36 | 0.0 | pass |
| near-neighbor-boundary | with_skill | command | local-output-eval-runner | 31.42 | 65 | 100.0 | pass |
| file-backed-governed-package | baseline | command | local-output-eval-runner | 31.18 | 37 | 0.0 | pass |
| file-backed-governed-package | with_skill | command | local-output-eval-runner | 30.97 | 98 | 100.0 | pass |
## Next Fixes
+2 -2
View File
@@ -8,8 +8,8 @@
"target_count": 3,
"adapter_count": 3,
"archive_present": true,
"archive_sha256": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9",
"archive_entry_count": 488,
"archive_sha256": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451",
"archive_entry_count": 490,
"failure_count": 0,
"warning_count": 0
},
+1 -1
View File
@@ -4,7 +4,7 @@
- Package directory: `dist`
- Targets: `3 / 3` adapters present
- Archive present: `True`
- Archive SHA256: `7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9`
- Archive SHA256: `6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451`
- Failures: `0`
- Warnings: `0`
+4 -4
View File
@@ -20,8 +20,8 @@
"trust_level": "local",
"license": "MIT",
"checksums": {
"package_sha256": "742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f",
"archive_sha256": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9"
"package_sha256": "d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5",
"archive_sha256": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451"
},
"compatibility": {
"openai": "pass",
@@ -52,7 +52,7 @@
},
"distribution": {
"archive_verified": true,
"archive_sha256": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9",
"archive_sha256": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451",
"package_verification": "reports/package_verification.json",
"install_simulated": true,
"install_simulation": "reports/install_simulation.json"
@@ -76,7 +76,7 @@
"agent-skills-compatible"
],
"package_metadata": "registry/packages/yao-meta-skill.json",
"package_sha256": "742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f"
"package_sha256": "d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5"
}
]
},
+2 -2
View File
@@ -6,8 +6,8 @@
- Maturity: `governed`
- Owner: `Yao Team`
- License: `MIT`
- Package SHA256: `742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f`
- Archive SHA256: `7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9`
- Package SHA256: `d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5`
- Archive SHA256: `6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451`
- Install simulated: `True`
## Compatibility
+5 -5
View File
@@ -242,12 +242,12 @@
<section>
<h2>核心指标</h2>
<div class="metrics"><article class='metric'><span>Skill IR</span><strong>2.0.0</strong><p>4 targets in platform-neutral contract</p></article><article class='metric'><span>Compiler</span><strong>4/4</strong><p>target contracts compiled from Skill IR</p></article><article class='metric'><span>Output Delta</span><strong>100.0</strong><p>5 cases; 1 file-backed</p></article><article class='metric'><span>Exec Runs</span><strong>10</strong><p>command 10; model 0; recorded 0</p></article><article class='metric'><span>Blind A/B</span><strong>5</strong><p>review pairs hide baseline vs with-skill labels</p></article><article class='metric'><span>Review A/B</span><strong>0/5</strong><p>adjudication decisions; pending 5</p></article><article class='metric'><span>Runtime</span><strong>5/5</strong><p>target conformance pass rate</p></article><article class='metric'><span>Perm Probe</span><strong>3/3</strong><p>0 native enforcement targets</p></article><article class='metric'><span>Trust</span><strong>0</strong><p>66 scripts scanned; secrets found</p></article><article class='metric'><span>Atlas</span><strong>5</strong><p>12 scanned skills; route collisions</p></article><article class='metric'><span>Drift</span><strong>low</strong><p>1 metadata events; 0 missed triggers</p></article><article class='metric'><span>Waivers</span><strong>0</strong><p>0 gates covered; human risk decisions</p></article><article class='metric'><span>Notes</span><strong>0/0</strong><p>0 open blocker annotations</p></article><article class='metric'><span>Registry</span><strong>1.1.0</strong><p>4 targets; MIT license</p></article><article class='metric'><span>Archive</span><strong>pass</strong><p>488 zip entries; package verification</p></article><article class='metric'><span>Install</span><strong>pass</strong><p>3 adapters readable; local install simulation</p></article><article class='metric'><span>Upgrade</span><strong>minor</strong><p>declared minor; 0 breaking changes</p></article></div>
<div class="metrics"><article class='metric'><span>Skill IR</span><strong>2.0.0</strong><p>4 targets in platform-neutral contract</p></article><article class='metric'><span>Compiler</span><strong>4/4</strong><p>target contracts compiled from Skill IR</p></article><article class='metric'><span>Output Delta</span><strong>100.0</strong><p>5 cases; 1 file-backed</p></article><article class='metric'><span>Exec Runs</span><strong>10</strong><p>command 10; model 0; recorded 0</p></article><article class='metric'><span>Blind A/B</span><strong>5</strong><p>review pairs hide baseline vs with-skill labels</p></article><article class='metric'><span>Review A/B</span><strong>0/5</strong><p>adjudication decisions; pending 5</p></article><article class='metric'><span>Runtime</span><strong>5/5</strong><p>target conformance pass rate</p></article><article class='metric'><span>Perm Probe</span><strong>3/3</strong><p>0 native enforcement targets</p></article><article class='metric'><span>Trust</span><strong>0</strong><p>68 scripts scanned; secrets found</p></article><article class='metric'><span>Atlas</span><strong>5</strong><p>12 scanned skills; route collisions</p></article><article class='metric'><span>Drift</span><strong>low</strong><p>1 metadata events; 0 missed triggers</p></article><article class='metric'><span>Waivers</span><strong>0</strong><p>0 gates covered; human risk decisions</p></article><article class='metric'><span>Notes</span><strong>0/0</strong><p>0 open blocker annotations</p></article><article class='metric'><span>Registry</span><strong>1.1.0</strong><p>4 targets; MIT license</p></article><article class='metric'><span>Archive</span><strong>pass</strong><p>490 zip entries; package verification</p></article><article class='metric'><span>Install</span><strong>pass</strong><p>3 adapters readable; local install simulation</p></article><article class='metric'><span>Upgrade</span><strong>minor</strong><p>declared minor; 0 breaking changes</p></article></div>
</section>
<section>
<h2>审查闸门</h2>
<div class="gates"><article class='gate pass'><div><span>通过</span><h3>意图画布</h3></div><p>intent confidence 100/100; Intent is clear enough to package the first routeable version.</p><footer>reports/intent-confidence.json <a href='intent-confidence.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>触发实验</h3></div><p>13 trigger cases; 0 misroutes; 0 ambiguous</p><footer>reports/route_scorecard.json <a href='route_scorecard.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>输出实验</h3></div><p>5/5 cases; with-skill 100.0; baseline 0.0; file-backed 1; near-neighbor 1; blind A/B 5; exec 10; command 10; model 0; recorded 0; reviewed 0/5</p><footer>reports/output_quality_scorecard.json <a href='output_quality_scorecard.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>上下文</h3></div><p>initial load 987/1000; quality density 131.7</p><footer>reports/context_budget.json <a href='context_budget.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>运行矩阵</h3></div><p>5 / 5 targets pass</p><footer>reports/conformance_matrix.json <a href='conformance_matrix.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>信任报告</h3></div><p>0 secrets; 66 scripts; 2 network-capable scripts; 0 help smoke failures</p><footer>reports/security_trust_report.json <a href='security_trust_report.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>权限批准</h3></div><p>3/3 permissions approved; gaps 0; required file_write, network, subprocess</p><footer>reports/security_trust_report.json + security/permission_policy.json <a href='../security/permission_policy.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>权限探针</h3></div><p>3/3 targets probed; native 0; metadata fallback 3; residual risks 3</p><footer>reports/runtime_permission_probes.json <a href='runtime_permission_probes.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>组合治理</h3></div><p>12 skills, 1 actionable; 0 actionable route collisions; 0 actionable owner gaps; 0 actionable stale; 24 scoped non-actionable issues</p><footer>reports/skill_atlas.json <a href='skill_atlas.html'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>运营回路</h3></div><p>1 metadata events; adoption 100.0; missed 0; bad-output 0; risk low</p><footer>reports/adoption_drift_report.json <a href='adoption_drift_report.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>人工批准</h3></div><p>0 active waivers cover current warnings</p><footer>reports/review_waivers.json <a href='review_waivers.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>注册审计</h3></div><p>yao-meta-skill 1.1.0; 6/6 compatibility entries pass; install pass with 3 adapters</p><footer>reports/registry_audit.json + reports/install_simulation.json <a href='registry_audit.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>发布路线</h3></div><p>0 promote; 3 keep current; 0 blocked; upgrade minor declared / minor recommended</p><footer>reports/promotion_decisions.json + reports/upgrade_check.json + docs/migration-v2.md <a href='promotion_decisions.md'>证据</a></footer></article></div>
<div class="gates"><article class='gate pass'><div><span>通过</span><h3>意图画布</h3></div><p>intent confidence 100/100; Intent is clear enough to package the first routeable version.</p><footer>reports/intent-confidence.json <a href='intent-confidence.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>触发实验</h3></div><p>13 trigger cases; 0 misroutes; 0 ambiguous</p><footer>reports/route_scorecard.json <a href='route_scorecard.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>输出实验</h3></div><p>5/5 cases; with-skill 100.0; baseline 0.0; file-backed 1; near-neighbor 1; blind A/B 5; exec 10; command 10; model 0; recorded 0; reviewed 0/5</p><footer>reports/output_quality_scorecard.json <a href='output_quality_scorecard.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>上下文</h3></div><p>initial load 987/1000; quality density 131.7</p><footer>reports/context_budget.json <a href='context_budget.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>运行矩阵</h3></div><p>5 / 5 targets pass</p><footer>reports/conformance_matrix.json <a href='conformance_matrix.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>信任报告</h3></div><p>0 secrets; 68 scripts; 2 network-capable scripts; 0 help smoke failures</p><footer>reports/security_trust_report.json <a href='security_trust_report.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>权限批准</h3></div><p>3/3 permissions approved; gaps 0; required file_write, network, subprocess</p><footer>reports/security_trust_report.json + security/permission_policy.json <a href='../security/permission_policy.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>权限探针</h3></div><p>3/3 targets probed; native 0; metadata fallback 3; residual risks 3</p><footer>reports/runtime_permission_probes.json <a href='runtime_permission_probes.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>组合治理</h3></div><p>12 skills, 1 actionable; 0 actionable route collisions; 0 actionable owner gaps; 0 actionable stale; 24 scoped non-actionable issues</p><footer>reports/skill_atlas.json <a href='skill_atlas.html'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>运营回路</h3></div><p>1 metadata events; adoption 100.0; missed 0; bad-output 0; risk low</p><footer>reports/adoption_drift_report.json <a href='adoption_drift_report.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>人工批准</h3></div><p>0 active waivers cover current warnings</p><footer>reports/review_waivers.json <a href='review_waivers.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>注册审计</h3></div><p>yao-meta-skill 1.1.0; 6/6 compatibility entries pass; install pass with 3 adapters</p><footer>reports/registry_audit.json + reports/install_simulation.json <a href='registry_audit.md'>证据</a></footer></article><article class='gate pass'><div><span>通过</span><h3>发布路线</h3></div><p>0 promote; 3 keep current; 0 blocked; upgrade minor declared / minor recommended</p><footer>reports/promotion_decisions.json + reports/upgrade_check.json + docs/migration-v2.md <a href='promotion_decisions.md'>证据</a></footer></article></div>
</section>
<div class="twocol">
@@ -313,7 +313,7 @@
</section>
<section id="trust" class="twocol">
<div class="panel"><h2>信任报告</h2><dl class='kv-grid'><div><dt>Secret</dt><dd>0</dd></div><div><dt>脚本数</dt><dd>66</dd></div><div><dt>网络脚本</dt><dd>2</dd></div><div><dt>Help 失败</dt><dd>0</dd></div><div><dt>包体哈希</dt><dd><code>742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f</code></dd></div></dl></div>
<div class="panel"><h2>信任报告</h2><dl class='kv-grid'><div><dt>Secret</dt><dd>0</dd></div><div><dt>脚本数</dt><dd>68</dd></div><div><dt>网络脚本</dt><dd>2</dd></div><div><dt>Help 失败</dt><dd>0</dd></div><div><dt>包体哈希</dt><dd><code>d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5</code></dd></div></dl></div>
<div class="panel"><h2>安全边界</h2><p>高风险 secret、远程 inline execution、缺失依赖策略或无法解释的脚本接口应阻断 governed release。</p></div>
</section>
@@ -344,12 +344,12 @@
<section id="registry" class="twocol">
<div class="panel"><h2>注册审计</h2><p>yao-meta-skill 1.1.0; 6/6 compatibility entries pass; install pass with 3 adapters</p></div>
<div class="panel"><h2>包体元数据</h2><dl class='kv-grid'><div><dt>名称</dt><dd>yao-meta-skill</dd></div><div><dt>版本</dt><dd>1.1.0</dd></div><div><dt>Maturity</dt><dd>governed</dd></div><div><dt>Owner</dt><dd>Yao Team</dd></div><div><dt>License</dt><dd>MIT</dd></div><div><dt>信任级别</dt><dd>local</dd></div><div><dt>目标平台</dt><dd>openai, claude, generic, agent-skills-compatible</dd></div><div><dt>兼容通过</dt><dd>6/6</dd></div><div><dt>归档哈希</dt><dd><code>7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9</code></dd></div></dl></div>
<div class="panel"><h2>包体元数据</h2><dl class='kv-grid'><div><dt>名称</dt><dd>yao-meta-skill</dd></div><div><dt>版本</dt><dd>1.1.0</dd></div><div><dt>Maturity</dt><dd>governed</dd></div><div><dt>Owner</dt><dd>Yao Team</dd></div><div><dt>License</dt><dd>MIT</dd></div><div><dt>信任级别</dt><dd>local</dd></div><div><dt>目标平台</dt><dd>openai, claude, generic, agent-skills-compatible</dd></div><div><dt>兼容通过</dt><dd>6/6</dd></div><div><dt>归档哈希</dt><dd><code>6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451</code></dd></div></dl></div>
</section>
<section id="release" class="twocol">
<div class="panel"><h2>发布路线</h2><p>0 promote; 3 keep current; 0 blocked; upgrade minor declared / minor recommended</p></div>
<div class="panel"><h2>包体验证</h2><dl class='kv-grid'><div><dt>目标数</dt><dd>3</dd></div><div><dt>Adapter</dt><dd>3</dd></div><div><dt>归档存在</dt><dd></dd></div><div><dt>Zip 条目</dt><dd>488</dd></div><div><dt>失败数</dt><dd>0</dd></div><div><dt>警告数</dt><dd>0</dd></div><div><dt>归档哈希</dt><dd><code>7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9</code></dd></div></dl></div>
<div class="panel"><h2>包体验证</h2><dl class='kv-grid'><div><dt>目标数</dt><dd>3</dd></div><div><dt>Adapter</dt><dd>3</dd></div><div><dt>归档存在</dt><dd></dd></div><div><dt>Zip 条目</dt><dd>490</dd></div><div><dt>失败数</dt><dd>0</dd></div><div><dt>警告数</dt><dd>0</dd></div><div><dt>归档哈希</dt><dd><code>6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451</code></dd></div></dl></div>
</section>
</main>
</body>
+117 -71
View File
@@ -59,7 +59,7 @@
"key": "trust-report",
"label": "信任报告",
"status": "pass",
"detail": "0 secrets; 66 scripts; 2 network-capable scripts; 0 help smoke failures",
"detail": "0 secrets; 68 scripts; 2 network-capable scripts; 0 help smoke failures",
"evidence": "reports/security_trust_report.json",
"link": "security_trust_report.md"
},
@@ -581,7 +581,7 @@
"path": "scripts",
"label": "Deterministic helpers or local tooling",
"kind": "folder",
"file_count": 66
"file_count": 68
},
{
"path": "evals",
@@ -596,7 +596,7 @@
"file_count": 170
}
],
"file_count": 300,
"file_count": 302,
"folder_count": 4,
"distribution": [
{
@@ -621,7 +621,7 @@
},
{
"label": "scripts",
"value": 66
"value": 68
},
{
"label": "evals",
@@ -750,7 +750,7 @@
"path": "scripts",
"label": "Deterministic helpers or local tooling",
"kind": "folder",
"file_count": 66
"file_count": 68
},
{
"path": "evals",
@@ -1068,9 +1068,9 @@
"failures": []
},
"trust_security": {
"scanned_files": 150,
"script_count": 66,
"internal_module_count": 7,
"scanned_files": 152,
"script_count": 68,
"internal_module_count": 9,
"secret_findings": 0,
"dependency_files": [
"requirements-ci.txt"
@@ -1088,8 +1088,8 @@
"help_smoke_failed_count": 0,
"interactive_script_count": 0,
"package_hash_scope": "source-contract-without-generated-reports",
"package_hash_file_count": 150,
"package_sha256": "742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f"
"package_hash_file_count": 152,
"package_sha256": "d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5"
},
"skill_atlas": {
"skill_count": 12,
@@ -1123,8 +1123,8 @@
"trust_level": "local",
"license": "MIT",
"checksums": {
"package_sha256": "742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f",
"archive_sha256": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9"
"package_sha256": "d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5",
"archive_sha256": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451"
},
"compatibility": {
"openai": "pass",
@@ -1155,7 +1155,7 @@
},
"distribution": {
"archive_verified": true,
"archive_sha256": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9",
"archive_sha256": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451",
"package_verification": "reports/package_verification.json",
"install_simulated": true,
"install_simulation": "reports/install_simulation.json"
@@ -1171,8 +1171,8 @@
"target_count": 3,
"adapter_count": 3,
"archive_present": true,
"archive_sha256": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9",
"archive_entry_count": 488,
"archive_sha256": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451",
"archive_entry_count": 490,
"failure_count": 0,
"warning_count": 0
},
@@ -1183,7 +1183,7 @@
"ok": true,
"summary": {
"archive_present": true,
"archive_entry_count": 488,
"archive_entry_count": 490,
"archive_extracted": true,
"entrypoint_loaded": true,
"manifest_loaded": true,
@@ -1245,12 +1245,12 @@
{
"field": "archive_sha256",
"from": "",
"to": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9"
"to": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451"
},
{
"field": "package_sha256",
"from": "0000000000000000000000000000000000000000000000000000000000000000",
"to": "742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f"
"to": "d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5"
}
]
},
@@ -2978,7 +2978,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 23.11,
"duration_ms": 23.49,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -3006,7 +3006,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 23.56,
"duration_ms": 23.5,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -3029,7 +3029,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 24.17,
"duration_ms": 22.7,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -3057,7 +3057,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 23.84,
"duration_ms": 23.01,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -3080,7 +3080,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 22.51,
"duration_ms": 22.98,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -3108,7 +3108,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 26.03,
"duration_ms": 22.64,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -3131,7 +3131,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 28.48,
"duration_ms": 22.61,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -3158,7 +3158,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 23.17,
"duration_ms": 22.62,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -3181,7 +3181,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 23.94,
"duration_ms": 23.24,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -3210,7 +3210,7 @@
"execution_mode": "command",
"model_executed": false,
"command_executed": true,
"duration_ms": 22.69,
"duration_ms": 23.29,
"provider": "local-output-eval-runner",
"model": "",
"usage": {
@@ -3703,6 +3703,7 @@
"scripts/render_system_model.py",
"scripts/resource_boundary_check.py",
"scripts/review_studio_formatting.py",
"scripts/review_studio_gates.py",
"scripts/review_studio_layout.py",
"scripts/run_conformance_suite.py",
"scripts/run_description_optimization_suite.py",
@@ -3721,7 +3722,8 @@
"scripts/validate_skill.py",
"scripts/verify_package.py",
"scripts/yao.py",
"scripts/yao_cli_config.py"
"scripts/yao_cli_config.py",
"scripts/yao_cli_parser.py"
],
"assets": [
"templates/basic_skill.md.j2",
@@ -3772,7 +3774,7 @@
],
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
}
@@ -4010,7 +4012,7 @@
"strategy": "Ship the neutral source tree and expose OpenAI-facing interface metadata as a generated companion file.",
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
},
@@ -4021,7 +4023,7 @@
},
"scripts": {
"strategy": "Keep scripts as local package resources; expose help-smoke and permission metadata for reviewer approval before execution.",
"script_count": 66,
"script_count": 68,
"help_smoke_failed_count": 0
},
"permissions": {
@@ -4233,7 +4235,7 @@
"strategy": "Ship the neutral source tree and expose OpenAI-facing interface metadata as a generated companion file.",
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
},
@@ -4244,7 +4246,7 @@
},
"scripts": {
"strategy": "Keep scripts as local package resources; expose help-smoke and permission metadata for reviewer approval before execution.",
"script_count": 66,
"script_count": 68,
"help_smoke_failed_count": 0
},
"permissions": {
@@ -4492,6 +4494,7 @@
"scripts/render_system_model.py",
"scripts/resource_boundary_check.py",
"scripts/review_studio_formatting.py",
"scripts/review_studio_gates.py",
"scripts/review_studio_layout.py",
"scripts/run_conformance_suite.py",
"scripts/run_description_optimization_suite.py",
@@ -4510,7 +4513,8 @@
"scripts/validate_skill.py",
"scripts/verify_package.py",
"scripts/yao.py",
"scripts/yao_cli_config.py"
"scripts/yao_cli_config.py",
"scripts/yao_cli_parser.py"
],
"assets": [
"templates/basic_skill.md.j2",
@@ -4561,7 +4565,7 @@
],
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
}
@@ -4799,7 +4803,7 @@
"strategy": "Preserve the source tree directly; write target notes in targets/claude/README.md.",
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
},
@@ -4810,7 +4814,7 @@
},
"scripts": {
"strategy": "Scripts remain local package resources and must be reviewed through trust and permission reports before use.",
"script_count": 66,
"script_count": 68,
"help_smoke_failed_count": 0
},
"permissions": {
@@ -5022,7 +5026,7 @@
"strategy": "Preserve the source tree directly; write target notes in targets/claude/README.md.",
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
},
@@ -5033,7 +5037,7 @@
},
"scripts": {
"strategy": "Scripts remain local package resources and must be reviewed through trust and permission reports before use.",
"script_count": 66,
"script_count": 68,
"help_smoke_failed_count": 0
},
"permissions": {
@@ -5281,6 +5285,7 @@
"scripts/render_system_model.py",
"scripts/resource_boundary_check.py",
"scripts/review_studio_formatting.py",
"scripts/review_studio_gates.py",
"scripts/review_studio_layout.py",
"scripts/run_conformance_suite.py",
"scripts/run_description_optimization_suite.py",
@@ -5299,7 +5304,8 @@
"scripts/validate_skill.py",
"scripts/verify_package.py",
"scripts/yao.py",
"scripts/yao_cli_config.py"
"scripts/yao_cli_config.py",
"scripts/yao_cli_parser.py"
],
"assets": [
"templates/basic_skill.md.j2",
@@ -5350,7 +5356,7 @@
],
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
}
@@ -5588,7 +5594,7 @@
"strategy": "Preserve references, scripts, assets, evals, reports, and adapter metadata as relative package resources.",
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
},
@@ -5598,7 +5604,7 @@
},
"scripts": {
"strategy": "Expose script and permission metadata for downstream clients or installers to enforce.",
"script_count": 66,
"script_count": 68,
"help_smoke_failed_count": 0
},
"permissions": {
@@ -5804,7 +5810,7 @@
"strategy": "Preserve references, scripts, assets, evals, reports, and adapter metadata as relative package resources.",
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
},
@@ -5814,7 +5820,7 @@
},
"scripts": {
"strategy": "Expose script and permission metadata for downstream clients or installers to enforce.",
"script_count": 66,
"script_count": 68,
"help_smoke_failed_count": 0
},
"permissions": {
@@ -6054,6 +6060,7 @@
"scripts/render_system_model.py",
"scripts/resource_boundary_check.py",
"scripts/review_studio_formatting.py",
"scripts/review_studio_gates.py",
"scripts/review_studio_layout.py",
"scripts/run_conformance_suite.py",
"scripts/run_description_optimization_suite.py",
@@ -6072,7 +6079,8 @@
"scripts/validate_skill.py",
"scripts/verify_package.py",
"scripts/yao.py",
"scripts/yao_cli_config.py"
"scripts/yao_cli_config.py",
"scripts/yao_cli_parser.py"
],
"assets": [
"templates/basic_skill.md.j2",
@@ -6123,7 +6131,7 @@
],
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
}
@@ -6361,7 +6369,7 @@
"strategy": "Keep optional directories as relative resources next to SKILL.md.",
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
},
@@ -6372,7 +6380,7 @@
},
"scripts": {
"strategy": "Scripts remain local optional resources and should advertise --help when executable.",
"script_count": 66,
"script_count": 68,
"help_smoke_failed_count": 0
},
"permissions": {
@@ -6577,7 +6585,7 @@
"strategy": "Keep optional directories as relative resources next to SKILL.md.",
"counts": {
"references": 32,
"scripts": 66,
"scripts": 68,
"assets": 2,
"reports": 41
},
@@ -6588,7 +6596,7 @@
},
"scripts": {
"strategy": "Scripts remain local optional resources and should advertise --help when executable.",
"script_count": 66,
"script_count": 68,
"help_smoke_failed_count": 0
},
"permissions": {
@@ -7152,9 +7160,9 @@
"ok": true,
"skill_dir": ".",
"summary": {
"scanned_files": 150,
"script_count": 66,
"internal_module_count": 7,
"scanned_files": 152,
"script_count": 68,
"internal_module_count": 9,
"secret_findings": 0,
"dependency_files": [
"requirements-ci.txt"
@@ -7172,8 +7180,8 @@
"help_smoke_failed_count": 0,
"interactive_script_count": 0,
"package_hash_scope": "source-contract-without-generated-reports",
"package_hash_file_count": 150,
"package_sha256": "742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f"
"package_hash_file_count": 152,
"package_sha256": "d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5"
},
"failures": [],
"warnings": [],
@@ -7850,6 +7858,20 @@
"network_urls": [],
"network_hosts": []
},
{
"path": "scripts/review_studio_gates.py",
"interface": "internal-module",
"interface_declared": true,
"interface_reason": "Imported by render_review_studio.py to keep Review Studio gate evaluation separate from HTML rendering.",
"has_argparse": false,
"has_main_guard": false,
"uses_input": false,
"uses_network": false,
"uses_file_write": false,
"uses_subprocess": false,
"network_urls": [],
"network_hosts": []
},
{
"path": "scripts/review_studio_layout.py",
"interface": "internal-module",
@@ -8115,6 +8137,20 @@
"uses_subprocess": false,
"network_urls": [],
"network_hosts": []
},
{
"path": "scripts/yao_cli_parser.py",
"interface": "internal-module",
"interface_declared": true,
"interface_reason": "Imported by yao.py to keep CLI parser declarations separate from command orchestration.",
"has_argparse": true,
"has_main_guard": false,
"uses_input": false,
"uses_network": false,
"uses_file_write": false,
"uses_subprocess": false,
"network_urls": [],
"network_hosts": []
}
],
"dependencies": {
@@ -8150,7 +8186,7 @@
"checked_count": 59,
"passed_count": 59,
"failed_count": 0,
"skipped_count": 7,
"skipped_count": 9,
"failed_scripts": [],
"results": [
{
@@ -8749,6 +8785,10 @@
"path": "scripts/review_studio_formatting.py",
"reason": "internal module"
},
{
"path": "scripts/review_studio_gates.py",
"reason": "internal module"
},
{
"path": "scripts/review_studio_layout.py",
"reason": "internal module"
@@ -8772,6 +8812,10 @@
{
"path": "scripts/yao_cli_config.py",
"reason": "internal module"
},
{
"path": "scripts/yao_cli_parser.py",
"reason": "internal module"
}
]
},
@@ -8936,10 +8980,10 @@
"context_budget_tier": "production",
"context_budget_limit": 1000,
"skill_body_tokens": 811,
"other_text_tokens": 869504,
"other_text_tokens": 871465,
"estimated_initial_load_tokens": 987,
"estimated_total_text_tokens": 870315,
"relevant_file_count": 327,
"estimated_total_text_tokens": 872276,
"relevant_file_count": 367,
"unused_resource_dirs": [],
"quality_signal_points": 130,
"quality_density": 131.7
@@ -9846,6 +9890,7 @@
"scripts/render_system_model.py",
"scripts/resource_boundary_check.py",
"scripts/review_studio_formatting.py",
"scripts/review_studio_gates.py",
"scripts/review_studio_layout.py",
"scripts/run_conformance_suite.py",
"scripts/run_description_optimization_suite.py",
@@ -9865,6 +9910,7 @@
"scripts/verify_package.py",
"scripts/yao.py",
"scripts/yao_cli_config.py",
"scripts/yao_cli_parser.py",
"references/artifact-design-doctrine.md",
"references/authoring-discipline.md",
"references/distribution-registry-method.md",
@@ -10646,7 +10692,7 @@
"adoption_drift": {
"ok": true,
"schema_version": "2.0",
"generated_at": "2026-06-13T10:57:52Z",
"generated_at": "2026-06-13T11:10:15Z",
"skill_dir": ".",
"privacy_contract": {
"storage": "local-first",
@@ -10805,8 +10851,8 @@
"trust_level": "local",
"license": "MIT",
"checksums": {
"package_sha256": "742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f",
"archive_sha256": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9"
"package_sha256": "d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5",
"archive_sha256": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451"
},
"compatibility": {
"openai": "pass",
@@ -10837,7 +10883,7 @@
},
"distribution": {
"archive_verified": true,
"archive_sha256": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9",
"archive_sha256": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451",
"package_verification": "reports/package_verification.json",
"install_simulated": true,
"install_simulation": "reports/install_simulation.json"
@@ -10861,7 +10907,7 @@
"agent-skills-compatible"
],
"package_metadata": "registry/packages/yao-meta-skill.json",
"package_sha256": "742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f"
"package_sha256": "d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5"
}
]
},
@@ -10884,8 +10930,8 @@
"target_count": 3,
"adapter_count": 3,
"archive_present": true,
"archive_sha256": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9",
"archive_entry_count": 488,
"archive_sha256": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451",
"archive_entry_count": 490,
"failure_count": 0,
"warning_count": 0
},
@@ -11400,7 +11446,7 @@
"installed_skill_dir": "dist/install-simulation/simulate-yao-meta-skill/yao-meta-skill",
"summary": {
"archive_present": true,
"archive_entry_count": 488,
"archive_entry_count": 490,
"archive_extracted": true,
"entrypoint_loaded": true,
"manifest_loaded": true,
@@ -11581,12 +11627,12 @@
{
"field": "archive_sha256",
"from": "",
"to": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9"
"to": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451"
},
{
"field": "package_sha256",
"from": "0000000000000000000000000000000000000000000000000000000000000000",
"to": "742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f"
"to": "d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5"
}
]
},
+42 -6
View File
@@ -2,9 +2,9 @@
"ok": true,
"skill_dir": ".",
"summary": {
"scanned_files": 150,
"script_count": 66,
"internal_module_count": 7,
"scanned_files": 152,
"script_count": 68,
"internal_module_count": 9,
"secret_findings": 0,
"dependency_files": [
"requirements-ci.txt"
@@ -22,8 +22,8 @@
"help_smoke_failed_count": 0,
"interactive_script_count": 0,
"package_hash_scope": "source-contract-without-generated-reports",
"package_hash_file_count": 150,
"package_sha256": "742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f"
"package_hash_file_count": 152,
"package_sha256": "d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5"
},
"failures": [],
"warnings": [],
@@ -700,6 +700,20 @@
"network_urls": [],
"network_hosts": []
},
{
"path": "scripts/review_studio_gates.py",
"interface": "internal-module",
"interface_declared": true,
"interface_reason": "Imported by render_review_studio.py to keep Review Studio gate evaluation separate from HTML rendering.",
"has_argparse": false,
"has_main_guard": false,
"uses_input": false,
"uses_network": false,
"uses_file_write": false,
"uses_subprocess": false,
"network_urls": [],
"network_hosts": []
},
{
"path": "scripts/review_studio_layout.py",
"interface": "internal-module",
@@ -965,6 +979,20 @@
"uses_subprocess": false,
"network_urls": [],
"network_hosts": []
},
{
"path": "scripts/yao_cli_parser.py",
"interface": "internal-module",
"interface_declared": true,
"interface_reason": "Imported by yao.py to keep CLI parser declarations separate from command orchestration.",
"has_argparse": true,
"has_main_guard": false,
"uses_input": false,
"uses_network": false,
"uses_file_write": false,
"uses_subprocess": false,
"network_urls": [],
"network_hosts": []
}
],
"dependencies": {
@@ -1000,7 +1028,7 @@
"checked_count": 59,
"passed_count": 59,
"failed_count": 0,
"skipped_count": 7,
"skipped_count": 9,
"failed_scripts": [],
"results": [
{
@@ -1599,6 +1627,10 @@
"path": "scripts/review_studio_formatting.py",
"reason": "internal module"
},
{
"path": "scripts/review_studio_gates.py",
"reason": "internal module"
},
{
"path": "scripts/review_studio_layout.py",
"reason": "internal module"
@@ -1622,6 +1654,10 @@
{
"path": "scripts/yao_cli_config.py",
"reason": "internal module"
},
{
"path": "scripts/yao_cli_parser.py",
"reason": "internal module"
}
]
},
+7 -5
View File
@@ -1,9 +1,9 @@
# Security Trust Report
- OK: `True`
- Scanned files: `150`
- Scripts: `66`
- Internal script modules: `7`
- Scanned files: `152`
- Scripts: `68`
- Internal script modules: `9`
- Secret findings: `0`
- Network-capable scripts: `2`
- Network policy covered scripts: `2`
@@ -15,8 +15,8 @@
- CLI help smoke failures: `0`
- Interactive scripts: `0`
- Package hash scope: `source-contract-without-generated-reports`
- Package hash files: `150`
- Package SHA256: `742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f`
- Package hash files: `152`
- Package SHA256: `d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5`
## Failures
@@ -109,6 +109,7 @@
| scripts/render_system_model.py | cli | False | True | True | False | False | True | False | Default CLI classification; add SCRIPT_INTERFACE for internal modules. |
| scripts/resource_boundary_check.py | cli | False | True | True | False | False | False | False | Default CLI classification; add SCRIPT_INTERFACE for internal modules. |
| scripts/review_studio_formatting.py | internal-module | True | False | False | False | False | False | False | Imported by render_review_studio.py to format report dictionaries as audit UI panels. |
| scripts/review_studio_gates.py | internal-module | True | False | False | False | False | False | False | Imported by render_review_studio.py to keep Review Studio gate evaluation separate from HTML rendering. |
| scripts/review_studio_layout.py | internal-module | True | False | False | False | False | False | False | Imported by render_review_studio.py to keep Review Studio layout and CSS out of gate logic. |
| scripts/run_conformance_suite.py | cli | False | True | True | False | False | True | False | Default CLI classification; add SCRIPT_INTERFACE for internal modules. |
| scripts/run_description_optimization_suite.py | cli | False | True | True | False | False | True | False | Default CLI classification; add SCRIPT_INTERFACE for internal modules. |
@@ -128,3 +129,4 @@
| scripts/verify_package.py | cli | False | True | True | False | False | True | False | Default CLI classification; add SCRIPT_INTERFACE for internal modules. |
| scripts/yao.py | cli | False | True | True | False | False | False | True | Default CLI classification; add SCRIPT_INTERFACE for internal modules. |
| scripts/yao_cli_config.py | internal-module | True | False | False | False | False | False | False | Imported by yao.py for CLI target maps and side-effect-free shaping helpers. |
| scripts/yao_cli_parser.py | internal-module | True | True | False | False | False | False | False | Imported by yao.py to keep CLI parser declarations separate from command orchestration. |
+1 -1
View File
@@ -771,7 +771,7 @@
<p><span data-lang="zh-CN">让 reviewer 快速确认关键文件、目录和资产分布。</span><span data-lang="en">Lets reviewers confirm key files, directories, and asset distribution quickly.</span></p>
</div>
<div class="two-col">
<figure class="chart-figure" data-chart="asset_donut"><svg viewBox="0 0 430 270" role="img" aria-label="资产分布"><text x="20" y="30" class="chart-title">资产分布</text><circle cx="130" cy="130" r="70" fill="none" stroke="#1B365D" stroke-width="24" stroke-dasharray="1.0 99.0" stroke-dashoffset="0.0" pathLength="100" transform="rotate(-90 130 130)"/><circle cx="130" cy="130" r="70" fill="none" stroke="#2D5A8A" stroke-width="24" stroke-dasharray="1.0 99.0" stroke-dashoffset="-1.0" pathLength="100" transform="rotate(-90 130 130)"/><circle cx="130" cy="130" r="70" fill="none" stroke="#D0DCE9" stroke-width="24" stroke-dasharray="1.0 99.0" stroke-dashoffset="-2.0" pathLength="100" transform="rotate(-90 130 130)"/><circle cx="130" cy="130" r="70" fill="none" stroke="#E4ECF5" stroke-width="24" stroke-dasharray="1.0 99.0" stroke-dashoffset="-2.9" pathLength="100" transform="rotate(-90 130 130)"/><circle cx="130" cy="130" r="70" fill="none" stroke="#e8e6dc" stroke-width="24" stroke-dasharray="31.4 68.6" stroke-dashoffset="-3.9" pathLength="100" transform="rotate(-90 130 130)"/><circle cx="130" cy="130" r="70" fill="none" stroke="#504e49" stroke-width="24" stroke-dasharray="64.7 35.3" stroke-dashoffset="-35.3" pathLength="100" transform="rotate(-90 130 130)"/><text x="130" y="136" text-anchor="middle">300</text><text x="235" y="78">SKILL.md</text><text x="235" y="100">README.md</text><text x="235" y="122">agents/interface.yaml</text><text x="235" y="144">manifest.json</text><text x="235" y="166">references</text><text x="235" y="188">scripts</text></svg><figcaption>资产分布图展示当前包体的文件和目录重心。</figcaption></figure>
<figure class="chart-figure" data-chart="asset_donut"><svg viewBox="0 0 430 270" role="img" aria-label="资产分布"><text x="20" y="30" class="chart-title">资产分布</text><circle cx="130" cy="130" r="70" fill="none" stroke="#1B365D" stroke-width="24" stroke-dasharray="1.0 99.0" stroke-dashoffset="0.0" pathLength="100" transform="rotate(-90 130 130)"/><circle cx="130" cy="130" r="70" fill="none" stroke="#2D5A8A" stroke-width="24" stroke-dasharray="1.0 99.0" stroke-dashoffset="-1.0" pathLength="100" transform="rotate(-90 130 130)"/><circle cx="130" cy="130" r="70" fill="none" stroke="#D0DCE9" stroke-width="24" stroke-dasharray="1.0 99.0" stroke-dashoffset="-1.9" pathLength="100" transform="rotate(-90 130 130)"/><circle cx="130" cy="130" r="70" fill="none" stroke="#E4ECF5" stroke-width="24" stroke-dasharray="1.0 99.0" stroke-dashoffset="-2.9" pathLength="100" transform="rotate(-90 130 130)"/><circle cx="130" cy="130" r="70" fill="none" stroke="#e8e6dc" stroke-width="24" stroke-dasharray="30.8 69.2" stroke-dashoffset="-3.8" pathLength="100" transform="rotate(-90 130 130)"/><circle cx="130" cy="130" r="70" fill="none" stroke="#504e49" stroke-width="24" stroke-dasharray="65.4 34.6" stroke-dashoffset="-34.6" pathLength="100" transform="rotate(-90 130 130)"/><text x="130" y="136" text-anchor="middle">302</text><text x="235" y="78">SKILL.md</text><text x="235" y="100">README.md</text><text x="235" y="122">agents/interface.yaml</text><text x="235" y="144">manifest.json</text><text x="235" y="166">references</text><text x="235" y="188">scripts</text></svg><figcaption>资产分布图展示当前包体的文件和目录重心。</figcaption></figure>
<table>
<thead><tr><th><span data-lang="zh-CN">路径</span><span data-lang="en">Path</span></th><th><span data-lang="zh-CN">作用</span><span data-lang="en">Role</span></th><th><span data-lang="zh-CN">类型</span><span data-lang="en">Type</span></th></tr></thead>
<tbody><tr><td>SKILL.md</td><td><span data-lang="zh-CN">Skill 入口文件</span><span data-lang="en">Skill entrypoint</span></td><td><span data-lang="zh-CN">文件</span><span data-lang="en">file</span></td></tr><tr><td>README.md</td><td><span data-lang="zh-CN">人类可读使用说明</span><span data-lang="en">Human-readable usage guide</span></td><td><span data-lang="zh-CN">文件</span><span data-lang="en">file</span></td></tr><tr><td>agents/interface.yaml</td><td><span data-lang="zh-CN">跨平台接口元数据</span><span data-lang="en">Neutral interface metadata</span></td><td><span data-lang="zh-CN">文件</span><span data-lang="en">file</span></td></tr><tr><td>manifest.json</td><td><span data-lang="zh-CN">生命周期与打包元数据</span><span data-lang="en">Lifecycle and portability metadata</span></td><td><span data-lang="zh-CN">文件</span><span data-lang="en">file</span></td></tr><tr><td>references</td><td><span data-lang="zh-CN">扩展指导与复用资料</span><span data-lang="en">Extended guidance and reusable notes</span></td><td><span data-lang="zh-CN">目录</span><span data-lang="en">folder</span></td></tr><tr><td>scripts</td><td><span data-lang="zh-CN">确定性脚本或本地工具</span><span data-lang="en">Deterministic helpers or local tooling</span></td><td><span data-lang="zh-CN">目录</span><span data-lang="en">folder</span></td></tr><tr><td>evals</td><td><span data-lang="zh-CN">触发与质量检查</span><span data-lang="en">Trigger and quality checks</span></td><td><span data-lang="zh-CN">目录</span><span data-lang="en">folder</span></td></tr><tr><td>reports</td><td><span data-lang="zh-CN">生成的证据与总结报告</span><span data-lang="en">Generated evidence and overview artifacts</span></td><td><span data-lang="zh-CN">目录</span><span data-lang="en">folder</span></td></tr></tbody>
+17 -17
View File
@@ -433,7 +433,7 @@
"path": "scripts",
"label": "Deterministic helpers or local tooling",
"kind": "folder",
"file_count": 66
"file_count": 68
},
{
"path": "evals",
@@ -448,7 +448,7 @@
"file_count": 170
}
],
"file_count": 300,
"file_count": 302,
"folder_count": 4,
"distribution": [
{
@@ -473,7 +473,7 @@
},
{
"label": "scripts",
"value": 66
"value": 68
},
{
"label": "evals",
@@ -602,7 +602,7 @@
"path": "scripts",
"label": "Deterministic helpers or local tooling",
"kind": "folder",
"file_count": 66
"file_count": 68
},
{
"path": "evals",
@@ -920,9 +920,9 @@
"failures": []
},
"trust_security": {
"scanned_files": 150,
"script_count": 66,
"internal_module_count": 7,
"scanned_files": 152,
"script_count": 68,
"internal_module_count": 9,
"secret_findings": 0,
"dependency_files": [
"requirements-ci.txt"
@@ -940,8 +940,8 @@
"help_smoke_failed_count": 0,
"interactive_script_count": 0,
"package_hash_scope": "source-contract-without-generated-reports",
"package_hash_file_count": 150,
"package_sha256": "742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f"
"package_hash_file_count": 152,
"package_sha256": "d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5"
},
"skill_atlas": {
"skill_count": 12,
@@ -975,8 +975,8 @@
"trust_level": "local",
"license": "MIT",
"checksums": {
"package_sha256": "742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f",
"archive_sha256": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9"
"package_sha256": "d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5",
"archive_sha256": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451"
},
"compatibility": {
"openai": "pass",
@@ -1007,7 +1007,7 @@
},
"distribution": {
"archive_verified": true,
"archive_sha256": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9",
"archive_sha256": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451",
"package_verification": "reports/package_verification.json",
"install_simulated": true,
"install_simulation": "reports/install_simulation.json"
@@ -1023,8 +1023,8 @@
"target_count": 3,
"adapter_count": 3,
"archive_present": true,
"archive_sha256": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9",
"archive_entry_count": 488,
"archive_sha256": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451",
"archive_entry_count": 490,
"failure_count": 0,
"warning_count": 0
},
@@ -1035,7 +1035,7 @@
"ok": true,
"summary": {
"archive_present": true,
"archive_entry_count": 488,
"archive_entry_count": 490,
"archive_extracted": true,
"entrypoint_loaded": true,
"manifest_loaded": true,
@@ -1097,12 +1097,12 @@
{
"field": "archive_sha256",
"from": "",
"to": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9"
"to": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451"
},
{
"field": "package_sha256",
"from": "0000000000000000000000000000000000000000000000000000000000000000",
"to": "742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f"
"to": "d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5"
}
]
},
+2
View File
@@ -107,6 +107,7 @@
"scripts/render_system_model.py",
"scripts/resource_boundary_check.py",
"scripts/review_studio_formatting.py",
"scripts/review_studio_gates.py",
"scripts/review_studio_layout.py",
"scripts/run_conformance_suite.py",
"scripts/run_description_optimization_suite.py",
@@ -126,6 +127,7 @@
"scripts/verify_package.py",
"scripts/yao.py",
"scripts/yao_cli_config.py",
"scripts/yao_cli_parser.py",
"references/artifact-design-doctrine.md",
"references/authoring-discipline.md",
"references/distribution-registry-method.md",
+4 -4
View File
@@ -68,12 +68,12 @@
{
"field": "archive_sha256",
"from": "",
"to": "7bc83805501d24cf8e5932ef76e0454100398d5a73652e7440be47984d0cf4a9"
"to": "6972bb1d72746b6a16c7dbf1ec73f438252756dd850fe474bc3b75af8649d451"
},
{
"field": "package_sha256",
"from": "0000000000000000000000000000000000000000000000000000000000000000",
"to": "742dc905b0d221c4f336e741d168861edaf7b75e97fe1e89f7d454c1cabf928f"
"to": "d53de57f6593fca3dd937832f5923bd5381250e382631a6b6616e2405de748b5"
}
]
},
@@ -88,7 +88,7 @@
"artifacts": {
"previous_package": "registry/examples/yao-meta-skill-1.0.0.json",
"current_package": "reports/registry_audit.json",
"json": "reports/upgrade_check.json",
"markdown": "reports/upgrade_check.md"
"json": "tests/tmp_review_studio/upgrade_check.json",
"markdown": "tests/tmp_review_studio/upgrade_check.md"
}
}
+1 -482
View File
@@ -11,14 +11,8 @@ try:
except ImportError: # pragma: no cover
yaml = None
try:
from trust_check import permission_governance_status as compute_permission_governance_status
from trust_check import script_inventory as trust_script_inventory
except ImportError: # pragma: no cover
compute_permission_governance_status = None
trust_script_inventory = None
from review_studio_formatting import registry_package_summary, render_kv_grid
from review_studio_gates import add_blockers_from_gate, build_gates, status_label, weighted_score
from review_studio_layout import render_review_nav, review_studio_css
@@ -78,9 +72,6 @@ def link_from(output_html: Path, target: Path) -> str:
return os.path.relpath(target.resolve(), output_html.parent.resolve())
def report_link(output_html: Path, skill_dir: Path, rel_path: str) -> str:
return link_from(output_html, skill_dir / rel_path)
def find_line(path: Path, patterns: list[str] | None = None) -> int | None:
if not path.exists():
@@ -124,478 +115,6 @@ def source_refs(
return refs
def gate(key: str, label: str, status: str, detail: str, evidence: str, link: str = "") -> dict[str, str]:
return {
"key": key,
"label": label,
"status": status,
"detail": detail,
"evidence": evidence,
"link": link,
}
def status_label(status: str) -> str:
return {"pass": "通过", "warn": "关注", "block": "阻断"}.get(status, status)
def add_blockers_from_gate(gates: list[dict[str, str]]) -> tuple[list[dict[str, str]], list[dict[str, str]]]:
blockers = [item for item in gates if item["status"] == "block"]
warnings = [item for item in gates if item["status"] == "warn"]
return blockers, warnings
def target_maturity(skill_dir: Path, overview: dict[str, Any]) -> str:
manifest = load_json(skill_dir / "manifest.json")
if manifest.get("maturity_tier"):
return str(manifest["maturity_tier"])
metadata = overview.get("metadata", {}) if isinstance(overview, dict) else {}
if metadata.get("maturity_tier"):
return str(metadata["maturity_tier"])
return "scaffold"
def min_output_cases(maturity: str) -> int:
if maturity in {"library", "governed"}:
return 5
if maturity == "production":
return 3
return 1
def fallback_permission_governance(skill_dir: Path) -> dict[str, Any]:
if compute_permission_governance_status is None or trust_script_inventory is None:
return {}
try:
scripts = trust_script_inventory(skill_dir)
return compute_permission_governance_status(skill_dir, scripts)
except Exception:
return {}
def build_gates(skill_dir: Path, output_html: Path, data: dict[str, dict[str, Any]]) -> list[dict[str, str]]:
overview = data["overview"]
maturity = target_maturity(skill_dir, overview)
gates: list[dict[str, str]] = []
intent = data["intent_confidence"]
intent_score = int(intent.get("score", 0) or 0)
intent_status = "pass" if intent.get("gate_passed") or intent_score >= 75 else "warn"
gates.append(
gate(
"intent-canvas",
"意图画布",
intent_status,
f"intent confidence {intent_score}/100; {intent.get('recommended_action', 'review current intent frame')}",
"reports/intent-confidence.json",
report_link(output_html, skill_dir, "reports/intent-confidence.md"),
)
)
route = data["route_scorecard"]
route_summary = route.get("summary", {})
misroutes = int(route_summary.get("misroute_count", len(route.get("misroutes", []))) or 0)
ambiguous = int(route_summary.get("ambiguous_case_count", len(route.get("ambiguous_cases", []))) or 0)
if not route:
route_status = "warn"
route_detail = "route scorecard is missing; run route-scorecard before release review"
else:
route_status = "block" if misroutes else ("warn" if ambiguous else "pass")
route_detail = f"{route_summary.get('total_cases', 0)} trigger cases; {misroutes} misroutes; {ambiguous} ambiguous"
gates.append(
gate(
"trigger-lab",
"触发实验",
route_status,
route_detail,
"reports/route_scorecard.json",
report_link(output_html, skill_dir, "reports/route_scorecard.md"),
)
)
output = data["output_quality"]
output_execution = data["output_execution"]
output_blind = data["output_blind_review"]
output_review = data["output_review_adjudication"]
output_summary = output.get("summary", {})
output_execution_summary = output_execution.get("summary", {})
output_blind_summary = output_blind.get("summary", {})
output_review_summary = output_review.get("summary", {})
required_cases = min_output_cases(maturity)
case_count = int(output_summary.get("case_count", 0) or 0)
file_backed = int(output_summary.get("file_backed_case_count", 0) or 0)
near_neighbor = int(output_summary.get("near_neighbor_case_count", 0) or 0)
boundary = int(output_summary.get("boundary_case_count", 0) or 0)
blind_pair_count = int(output_blind_summary.get("pair_count", 0) or 0)
execution_variant_count = int(output_execution_summary.get("variant_run_count", 0) or 0)
execution_command_count = int(output_execution_summary.get("command_executed_count", 0) or 0)
execution_model_count = int(output_execution_summary.get("model_executed_count", 0) or 0)
execution_recorded_count = int(output_execution_summary.get("recorded_fixture_count", 0) or 0)
review_pair_count = int(output_review_summary.get("pair_count", 0) or 0)
review_judgment_count = int(output_review_summary.get("judgment_count", 0) or 0)
review_invalid_count = int(output_review_summary.get("invalid_decision_count", 0) or 0)
blind_missing = maturity in {"production", "library", "governed"} and (not output_blind or blind_pair_count < case_count)
execution_failed = bool(output_execution) and (not output_execution.get("ok", True) or int(output_execution_summary.get("failure_count", 0) or 0) > 0)
review_invalid = bool(output_review) and (not output_review.get("ok", True) or review_invalid_count > 0)
output_blocked = (
not output.get("ok", False)
or not output_summary.get("gate_pass", False)
or case_count < required_cases
or execution_failed
or review_invalid
)
output_warn = file_backed == 0 or near_neighbor == 0 or boundary == 0 or blind_missing
if not output:
output_status = "warn"
output_detail = "output eval scorecard is missing; generate it before production review"
else:
output_status = "block" if output_blocked else ("warn" if output_warn else "pass")
output_detail = (
f"{case_count}/{required_cases} cases; with-skill {output_summary.get('with_skill_pass_rate', 0)}; "
f"baseline {output_summary.get('baseline_pass_rate', 0)}; file-backed {file_backed}; near-neighbor {near_neighbor}; "
f"blind A/B {blind_pair_count}"
+ (
f"; exec {execution_variant_count}; command {execution_command_count}; "
f"model {execution_model_count}; recorded {execution_recorded_count}"
if output_execution
else ""
)
+ (f"; reviewed {review_judgment_count}/{review_pair_count}" if output_review else "")
)
gates.append(
gate(
"output-lab",
"输出实验",
output_status,
output_detail,
"reports/output_quality_scorecard.json",
report_link(output_html, skill_dir, "reports/output_quality_scorecard.md"),
)
)
context = data["context_budget"]
context_stats = context.get("stats", {})
context_status = "pass" if context.get("ok") else "block"
if context.get("warnings"):
context_status = "warn" if context_status == "pass" else context_status
if not context:
context_status = "warn"
context_detail = (
f"initial load {context_stats.get('estimated_initial_load_tokens', 'n/a')}/"
f"{context_stats.get('context_budget_limit', 'n/a')}; quality density {context_stats.get('quality_density', 'n/a')}"
)
gates.append(
gate(
"context-budget",
"上下文",
context_status,
context_detail,
"reports/context_budget.json",
report_link(output_html, skill_dir, "reports/context_budget.md"),
)
)
conformance = data["conformance"]
conformance_summary = conformance.get("summary", {})
fail_count = int(conformance_summary.get("fail_count", 0) or 0)
if not conformance:
conformance_status = "warn"
conformance_detail = "runtime conformance matrix is missing"
else:
conformance_status = "block" if fail_count else "pass"
conformance_detail = f"{conformance_summary.get('pass_count', 0)} / {conformance_summary.get('target_count', 0)} targets pass"
gates.append(
gate(
"runtime-matrix",
"运行矩阵",
conformance_status,
conformance_detail,
"reports/conformance_matrix.json",
report_link(output_html, skill_dir, "reports/conformance_matrix.md"),
)
)
trust = data["trust"]
trust_summary = trust.get("summary", {})
if not trust:
trust_status = "warn"
trust_detail = "security trust report is missing"
else:
trust_status = "block" if trust.get("failures") else ("warn" if trust.get("warnings") else "pass")
trust_detail = (
f"{trust_summary.get('secret_findings', 0)} secrets; "
f"{trust_summary.get('script_count', 0)} scripts; "
f"{trust_summary.get('network_script_count', 0)} network-capable scripts; "
f"{trust_summary.get('help_smoke_failed_count', 0)} help smoke failures"
)
gates.append(
gate(
"trust-report",
"信任报告",
trust_status,
trust_detail,
"reports/security_trust_report.json",
report_link(output_html, skill_dir, "reports/security_trust_report.md"),
)
)
permission_governance = trust.get("permission_governance", {}) if isinstance(trust.get("permission_governance", {}), dict) else {}
if trust and not permission_governance:
permission_governance = fallback_permission_governance(skill_dir)
if not trust:
permission_status = "warn"
permission_detail = "permission governance evidence is missing because trust report is missing"
elif not permission_governance:
permission_status = "warn"
permission_detail = "permission governance evidence is missing from trust report"
else:
required = int(permission_governance.get("required_count", 0) or 0)
approved = int(permission_governance.get("approval_count", 0) or 0)
gaps = (
int(permission_governance.get("missing_count", 0) or 0)
+ int(permission_governance.get("invalid_count", 0) or 0)
+ int(permission_governance.get("expired_count", 0) or 0)
)
if gaps:
permission_status = "block" if maturity == "governed" else "warn"
else:
permission_status = "pass"
required_names = ", ".join(permission_governance.get("required_capabilities", []) or []) or "none"
permission_detail = f"{approved}/{required} permissions approved; gaps {gaps}; required {required_names}"
gates.append(
gate(
"permission-gates",
"权限批准",
permission_status,
permission_detail,
"reports/security_trust_report.json + security/permission_policy.json",
report_link(output_html, skill_dir, "security/permission_policy.md"),
)
)
runtime_permissions = data["runtime_permissions"]
runtime_permissions_summary = runtime_permissions.get("summary", {})
if not runtime_permissions:
runtime_permission_status = "block" if maturity == "governed" else "warn"
runtime_permission_detail = "runtime permission probe report is missing"
elif runtime_permissions.get("failures"):
runtime_permission_status = "block"
runtime_permission_detail = f"{runtime_permissions_summary.get('failure_count', len(runtime_permissions.get('failures', [])))} runtime permission probe failures"
else:
runtime_permission_status = "pass"
runtime_permission_detail = (
f"{runtime_permissions_summary.get('pass_count', 0)}/{runtime_permissions_summary.get('target_count', 0)} targets probed; "
f"native {runtime_permissions_summary.get('native_enforcement_count', 0)}; "
f"metadata fallback {runtime_permissions_summary.get('metadata_fallback_count', 0)}; "
f"residual risks {runtime_permissions_summary.get('residual_risk_count', 0)}"
)
gates.append(
gate(
"permission-runtime",
"权限探针",
runtime_permission_status,
runtime_permission_detail,
"reports/runtime_permission_probes.json",
report_link(output_html, skill_dir, "reports/runtime_permission_probes.md"),
)
)
atlas = data["atlas"]
atlas_summary = atlas.get("summary", {})
actionable_route_collisions = int(
atlas_summary.get("actionable_route_collision_count", atlas_summary.get("route_collision_count", 0)) or 0
)
actionable_owner_gaps = int(atlas_summary.get("actionable_owner_gap_count", atlas_summary.get("owner_gap_count", 0)) or 0)
actionable_stale = int(atlas_summary.get("actionable_stale_count", atlas_summary.get("stale_count", 0)) or 0)
atlas_issues = actionable_route_collisions + actionable_owner_gaps + actionable_stale
if not atlas:
atlas_status = "warn"
atlas_detail = "skill atlas is missing; portfolio-level conflicts are unknown"
else:
atlas_status = "warn" if atlas_issues else "pass"
atlas_detail = (
f"{atlas_summary.get('skill_count', 0)} skills, "
f"{atlas_summary.get('actionable_skill_count', atlas_summary.get('skill_count', 0))} actionable; "
f"{actionable_route_collisions} actionable route collisions; "
f"{actionable_owner_gaps} actionable owner gaps; "
f"{actionable_stale} actionable stale; "
f"{atlas_summary.get('non_actionable_issue_count', 0)} scoped non-actionable issues"
)
gates.append(
gate(
"skill-atlas",
"组合治理",
atlas_status,
atlas_detail,
"reports/skill_atlas.json",
report_link(output_html, skill_dir, "reports/skill_atlas.html"),
)
)
adoption = data["adoption_drift"]
adoption_summary = adoption.get("summary", {})
if not adoption:
adoption_status = "warn"
adoption_detail = "adoption drift report is missing; real usage impact is unknown"
elif adoption.get("failures"):
adoption_status = "block"
adoption_detail = f"telemetry privacy or schema failures: {len(adoption.get('failures', []))}"
else:
risk_band = adoption_summary.get("risk_band", "no-data")
adoption_status = "warn" if risk_band in {"no-data", "medium", "high"} else "pass"
adoption_detail = (
f"{adoption_summary.get('event_count', 0)} metadata events; "
f"adoption {adoption_summary.get('adoption_rate', 0)}; "
f"missed {adoption_summary.get('missed_trigger_count', 0)}; "
f"bad-output {adoption_summary.get('bad_output_count', 0)}; "
f"risk {risk_band}"
)
gates.append(
gate(
"operations-loop",
"运营回路",
adoption_status,
adoption_detail,
"reports/adoption_drift_report.json",
report_link(output_html, skill_dir, "reports/adoption_drift_report.md"),
)
)
waiver = data["review_waivers"]
waiver_summary = waiver.get("summary", {})
active_covered = set(waiver_summary.get("covered_gate_keys", []) or [])
prior_blockers = [item for item in gates if item["status"] == "block"]
prior_warnings = [item for item in gates if item["status"] == "warn"]
unwaived_warnings = [item for item in prior_warnings if item["key"] not in active_covered]
if not waiver:
waiver_status = "warn"
waiver_detail = "review waiver ledger is missing; warning acceptance is not auditable"
elif waiver.get("failures"):
waiver_status = "block"
waiver_detail = f"{len(waiver.get('failures', []))} invalid waiver records"
elif prior_blockers:
waiver_status = "block"
waiver_detail = f"{len(prior_blockers)} blocker gates cannot be waived in v0"
elif unwaived_warnings:
waiver_status = "warn"
waiver_detail = (
f"{waiver_summary.get('active_count', 0)} active waivers; "
f"{len(unwaived_warnings)} warning gates still need reviewer decision"
)
else:
waiver_status = "pass"
waiver_detail = f"{waiver_summary.get('active_count', 0)} active waivers cover current warnings"
gates.append(
gate(
"review-waivers",
"人工批准",
waiver_status,
waiver_detail,
"reports/review_waivers.json",
report_link(output_html, skill_dir, "reports/review_waivers.md"),
)
)
registry = data["registry"]
install = data["install_simulation"]
if not registry:
if maturity in {"library", "governed"}:
registry_status = "warn"
registry_detail = "registry audit is missing; package metadata is not reviewable"
else:
registry_status = "pass"
registry_detail = "registry audit is optional until team distribution is required"
else:
compatibility = registry.get("package", {}).get("compatibility", {})
pass_count = sum(1 for status in compatibility.values() if status == "pass")
registry_status = "block" if registry.get("failures") else ("warn" if registry.get("warnings") else "pass")
registry_detail = (
f"{registry.get('package', {}).get('name', 'package')} "
f"{registry.get('package', {}).get('version', 'n/a')}; "
f"{pass_count}/{len(compatibility)} compatibility entries pass"
)
if install:
if install.get("failures"):
registry_status = "block"
install_summary = install.get("summary", {})
registry_detail += (
f"; install {'pass' if install.get('ok') else 'fail'}"
f" with {install_summary.get('adapter_count', 0)} adapters"
)
gates.append(
gate(
"registry-audit",
"注册审计",
registry_status,
registry_detail,
"reports/registry_audit.json + reports/install_simulation.json",
report_link(output_html, skill_dir, "reports/registry_audit.md"),
)
)
promotion = data["promotion"]
migration_path = ROOT / "docs" / "migration-v2.md"
if promotion:
promotion_summary = promotion.get("summary", {})
blocked = int(promotion_summary.get("blocked", 0) or 0)
release_status = "block" if blocked else "pass"
release_detail = f"{promotion_summary.get('promote', 0)} promote; {promotion_summary.get('keep_current', 0)} keep current; {blocked} blocked"
else:
release_status = "warn"
release_detail = "promotion decisions are missing; release notes need reviewer confirmation"
upgrade = data["upgrade_check"]
if upgrade:
upgrade_summary = upgrade.get("summary", {})
if upgrade.get("failures"):
release_status = "block"
elif upgrade.get("warnings") and release_status == "pass":
release_status = "warn"
release_detail += (
f"; upgrade {upgrade_summary.get('declared_bump', 'n/a')}"
f" declared / {upgrade_summary.get('recommended_bump', 'n/a')} recommended"
)
gates.append(
gate(
"release-notes",
"发布路线",
release_status,
release_detail,
"reports/promotion_decisions.json + reports/upgrade_check.json + docs/migration-v2.md",
report_link(output_html, skill_dir, "reports/promotion_decisions.md") if promotion else str(migration_path),
)
)
return gates
def weighted_score(gates: list[dict[str, str]]) -> int:
weights = {
"trigger-lab": 15,
"output-lab": 20,
"context-budget": 10,
"runtime-matrix": 10,
"trust-report": 10,
"permission-gates": 10,
"permission-runtime": 10,
"skill-atlas": 10,
"operations-loop": 10,
"review-waivers": 10,
"registry-audit": 10,
"release-notes": 10,
"intent-canvas": 10,
}
earned = 0.0
total = 0.0
for item in gates:
weight = weights.get(item["key"], 5)
total += weight
if item["status"] == "pass":
earned += weight
elif item["status"] == "warn":
earned += weight * 0.6
return int(round(earned / total * 100)) if total else 0
def evidence_paths(skill_dir: Path) -> dict[str, str]:
rels = {
"skill_overview": "reports/skill-overview.html",
+512
View File
@@ -0,0 +1,512 @@
#!/usr/bin/env python3
"""Gate evaluation contract for Review Studio 2.0."""
import json
import os
from pathlib import Path
from typing import Any
try:
from trust_check import permission_governance_status as compute_permission_governance_status
from trust_check import script_inventory as trust_script_inventory
except ImportError: # pragma: no cover
compute_permission_governance_status = None
trust_script_inventory = None
SCRIPT_INTERFACE = "internal-module"
SCRIPT_INTERFACE_REASON = "Imported by render_review_studio.py to keep Review Studio gate evaluation separate from HTML rendering."
ROOT = Path(__file__).resolve().parent.parent
def _load_json(path: Path) -> dict[str, Any]:
if not path.exists():
return {}
try:
payload = json.loads(path.read_text(encoding="utf-8"))
except json.JSONDecodeError:
return {}
return payload if isinstance(payload, dict) else {}
def _link_from(output_html: Path, target: Path) -> str:
return os.path.relpath(target.resolve(), output_html.parent.resolve())
def _report_link(output_html: Path, skill_dir: Path, rel_path: str) -> str:
return _link_from(output_html, skill_dir / rel_path)
def gate(key: str, label: str, status: str, detail: str, evidence: str, link: str = "") -> dict[str, str]:
return {
"key": key,
"label": label,
"status": status,
"detail": detail,
"evidence": evidence,
"link": link,
}
def status_label(status: str) -> str:
return {"pass": "通过", "warn": "关注", "block": "阻断"}.get(status, status)
def add_blockers_from_gate(gates: list[dict[str, str]]) -> tuple[list[dict[str, str]], list[dict[str, str]]]:
blockers = [item for item in gates if item["status"] == "block"]
warnings = [item for item in gates if item["status"] == "warn"]
return blockers, warnings
def target_maturity(skill_dir: Path, overview: dict[str, Any]) -> str:
manifest = _load_json(skill_dir / "manifest.json")
if manifest.get("maturity_tier"):
return str(manifest["maturity_tier"])
metadata = overview.get("metadata", {}) if isinstance(overview, dict) else {}
if metadata.get("maturity_tier"):
return str(metadata["maturity_tier"])
return "scaffold"
def min_output_cases(maturity: str) -> int:
if maturity in {"library", "governed"}:
return 5
if maturity == "production":
return 3
return 1
def fallback_permission_governance(skill_dir: Path) -> dict[str, Any]:
if compute_permission_governance_status is None or trust_script_inventory is None:
return {}
try:
scripts = trust_script_inventory(skill_dir)
return compute_permission_governance_status(skill_dir, scripts)
except Exception:
return {}
def build_gates(skill_dir: Path, output_html: Path, data: dict[str, dict[str, Any]]) -> list[dict[str, str]]:
overview = data["overview"]
maturity = target_maturity(skill_dir, overview)
gates: list[dict[str, str]] = []
intent = data["intent_confidence"]
intent_score = int(intent.get("score", 0) or 0)
intent_status = "pass" if intent.get("gate_passed") or intent_score >= 75 else "warn"
gates.append(
gate(
"intent-canvas",
"意图画布",
intent_status,
f"intent confidence {intent_score}/100; {intent.get('recommended_action', 'review current intent frame')}",
"reports/intent-confidence.json",
_report_link(output_html, skill_dir, "reports/intent-confidence.md"),
)
)
route = data["route_scorecard"]
route_summary = route.get("summary", {})
misroutes = int(route_summary.get("misroute_count", len(route.get("misroutes", []))) or 0)
ambiguous = int(route_summary.get("ambiguous_case_count", len(route.get("ambiguous_cases", []))) or 0)
if not route:
route_status = "warn"
route_detail = "route scorecard is missing; run route-scorecard before release review"
else:
route_status = "block" if misroutes else ("warn" if ambiguous else "pass")
route_detail = f"{route_summary.get('total_cases', 0)} trigger cases; {misroutes} misroutes; {ambiguous} ambiguous"
gates.append(
gate(
"trigger-lab",
"触发实验",
route_status,
route_detail,
"reports/route_scorecard.json",
_report_link(output_html, skill_dir, "reports/route_scorecard.md"),
)
)
output = data["output_quality"]
output_execution = data["output_execution"]
output_blind = data["output_blind_review"]
output_review = data["output_review_adjudication"]
output_summary = output.get("summary", {})
output_execution_summary = output_execution.get("summary", {})
output_blind_summary = output_blind.get("summary", {})
output_review_summary = output_review.get("summary", {})
required_cases = min_output_cases(maturity)
case_count = int(output_summary.get("case_count", 0) or 0)
file_backed = int(output_summary.get("file_backed_case_count", 0) or 0)
near_neighbor = int(output_summary.get("near_neighbor_case_count", 0) or 0)
boundary = int(output_summary.get("boundary_case_count", 0) or 0)
blind_pair_count = int(output_blind_summary.get("pair_count", 0) or 0)
execution_variant_count = int(output_execution_summary.get("variant_run_count", 0) or 0)
execution_command_count = int(output_execution_summary.get("command_executed_count", 0) or 0)
execution_model_count = int(output_execution_summary.get("model_executed_count", 0) or 0)
execution_recorded_count = int(output_execution_summary.get("recorded_fixture_count", 0) or 0)
review_pair_count = int(output_review_summary.get("pair_count", 0) or 0)
review_judgment_count = int(output_review_summary.get("judgment_count", 0) or 0)
review_invalid_count = int(output_review_summary.get("invalid_decision_count", 0) or 0)
blind_missing = maturity in {"production", "library", "governed"} and (not output_blind or blind_pair_count < case_count)
execution_failed = bool(output_execution) and (not output_execution.get("ok", True) or int(output_execution_summary.get("failure_count", 0) or 0) > 0)
review_invalid = bool(output_review) and (not output_review.get("ok", True) or review_invalid_count > 0)
output_blocked = (
not output.get("ok", False)
or not output_summary.get("gate_pass", False)
or case_count < required_cases
or execution_failed
or review_invalid
)
output_warn = file_backed == 0 or near_neighbor == 0 or boundary == 0 or blind_missing
if not output:
output_status = "warn"
output_detail = "output eval scorecard is missing; generate it before production review"
else:
output_status = "block" if output_blocked else ("warn" if output_warn else "pass")
output_detail = (
f"{case_count}/{required_cases} cases; with-skill {output_summary.get('with_skill_pass_rate', 0)}; "
f"baseline {output_summary.get('baseline_pass_rate', 0)}; file-backed {file_backed}; near-neighbor {near_neighbor}; "
f"blind A/B {blind_pair_count}"
+ (
f"; exec {execution_variant_count}; command {execution_command_count}; "
f"model {execution_model_count}; recorded {execution_recorded_count}"
if output_execution
else ""
)
+ (f"; reviewed {review_judgment_count}/{review_pair_count}" if output_review else "")
)
gates.append(
gate(
"output-lab",
"输出实验",
output_status,
output_detail,
"reports/output_quality_scorecard.json",
_report_link(output_html, skill_dir, "reports/output_quality_scorecard.md"),
)
)
context = data["context_budget"]
context_stats = context.get("stats", {})
context_status = "pass" if context.get("ok") else "block"
if context.get("warnings"):
context_status = "warn" if context_status == "pass" else context_status
if not context:
context_status = "warn"
context_detail = (
f"initial load {context_stats.get('estimated_initial_load_tokens', 'n/a')}/"
f"{context_stats.get('context_budget_limit', 'n/a')}; quality density {context_stats.get('quality_density', 'n/a')}"
)
gates.append(
gate(
"context-budget",
"上下文",
context_status,
context_detail,
"reports/context_budget.json",
_report_link(output_html, skill_dir, "reports/context_budget.md"),
)
)
conformance = data["conformance"]
conformance_summary = conformance.get("summary", {})
fail_count = int(conformance_summary.get("fail_count", 0) or 0)
if not conformance:
conformance_status = "warn"
conformance_detail = "runtime conformance matrix is missing"
else:
conformance_status = "block" if fail_count else "pass"
conformance_detail = f"{conformance_summary.get('pass_count', 0)} / {conformance_summary.get('target_count', 0)} targets pass"
gates.append(
gate(
"runtime-matrix",
"运行矩阵",
conformance_status,
conformance_detail,
"reports/conformance_matrix.json",
_report_link(output_html, skill_dir, "reports/conformance_matrix.md"),
)
)
trust = data["trust"]
trust_summary = trust.get("summary", {})
if not trust:
trust_status = "warn"
trust_detail = "security trust report is missing"
else:
trust_status = "block" if trust.get("failures") else ("warn" if trust.get("warnings") else "pass")
trust_detail = (
f"{trust_summary.get('secret_findings', 0)} secrets; "
f"{trust_summary.get('script_count', 0)} scripts; "
f"{trust_summary.get('network_script_count', 0)} network-capable scripts; "
f"{trust_summary.get('help_smoke_failed_count', 0)} help smoke failures"
)
gates.append(
gate(
"trust-report",
"信任报告",
trust_status,
trust_detail,
"reports/security_trust_report.json",
_report_link(output_html, skill_dir, "reports/security_trust_report.md"),
)
)
permission_governance = trust.get("permission_governance", {}) if isinstance(trust.get("permission_governance", {}), dict) else {}
if trust and not permission_governance:
permission_governance = fallback_permission_governance(skill_dir)
if not trust:
permission_status = "warn"
permission_detail = "permission governance evidence is missing because trust report is missing"
elif not permission_governance:
permission_status = "warn"
permission_detail = "permission governance evidence is missing from trust report"
else:
required = int(permission_governance.get("required_count", 0) or 0)
approved = int(permission_governance.get("approval_count", 0) or 0)
gaps = (
int(permission_governance.get("missing_count", 0) or 0)
+ int(permission_governance.get("invalid_count", 0) or 0)
+ int(permission_governance.get("expired_count", 0) or 0)
)
if gaps:
permission_status = "block" if maturity == "governed" else "warn"
else:
permission_status = "pass"
required_names = ", ".join(permission_governance.get("required_capabilities", []) or []) or "none"
permission_detail = f"{approved}/{required} permissions approved; gaps {gaps}; required {required_names}"
gates.append(
gate(
"permission-gates",
"权限批准",
permission_status,
permission_detail,
"reports/security_trust_report.json + security/permission_policy.json",
_report_link(output_html, skill_dir, "security/permission_policy.md"),
)
)
runtime_permissions = data["runtime_permissions"]
runtime_permissions_summary = runtime_permissions.get("summary", {})
if not runtime_permissions:
runtime_permission_status = "block" if maturity == "governed" else "warn"
runtime_permission_detail = "runtime permission probe report is missing"
elif runtime_permissions.get("failures"):
runtime_permission_status = "block"
runtime_permission_detail = f"{runtime_permissions_summary.get('failure_count', len(runtime_permissions.get('failures', [])))} runtime permission probe failures"
else:
runtime_permission_status = "pass"
runtime_permission_detail = (
f"{runtime_permissions_summary.get('pass_count', 0)}/{runtime_permissions_summary.get('target_count', 0)} targets probed; "
f"native {runtime_permissions_summary.get('native_enforcement_count', 0)}; "
f"metadata fallback {runtime_permissions_summary.get('metadata_fallback_count', 0)}; "
f"residual risks {runtime_permissions_summary.get('residual_risk_count', 0)}"
)
gates.append(
gate(
"permission-runtime",
"权限探针",
runtime_permission_status,
runtime_permission_detail,
"reports/runtime_permission_probes.json",
_report_link(output_html, skill_dir, "reports/runtime_permission_probes.md"),
)
)
atlas = data["atlas"]
atlas_summary = atlas.get("summary", {})
actionable_route_collisions = int(
atlas_summary.get("actionable_route_collision_count", atlas_summary.get("route_collision_count", 0)) or 0
)
actionable_owner_gaps = int(atlas_summary.get("actionable_owner_gap_count", atlas_summary.get("owner_gap_count", 0)) or 0)
actionable_stale = int(atlas_summary.get("actionable_stale_count", atlas_summary.get("stale_count", 0)) or 0)
atlas_issues = actionable_route_collisions + actionable_owner_gaps + actionable_stale
if not atlas:
atlas_status = "warn"
atlas_detail = "skill atlas is missing; portfolio-level conflicts are unknown"
else:
atlas_status = "warn" if atlas_issues else "pass"
atlas_detail = (
f"{atlas_summary.get('skill_count', 0)} skills, "
f"{atlas_summary.get('actionable_skill_count', atlas_summary.get('skill_count', 0))} actionable; "
f"{actionable_route_collisions} actionable route collisions; "
f"{actionable_owner_gaps} actionable owner gaps; "
f"{actionable_stale} actionable stale; "
f"{atlas_summary.get('non_actionable_issue_count', 0)} scoped non-actionable issues"
)
gates.append(
gate(
"skill-atlas",
"组合治理",
atlas_status,
atlas_detail,
"reports/skill_atlas.json",
_report_link(output_html, skill_dir, "reports/skill_atlas.html"),
)
)
adoption = data["adoption_drift"]
adoption_summary = adoption.get("summary", {})
if not adoption:
adoption_status = "warn"
adoption_detail = "adoption drift report is missing; real usage impact is unknown"
elif adoption.get("failures"):
adoption_status = "block"
adoption_detail = f"telemetry privacy or schema failures: {len(adoption.get('failures', []))}"
else:
risk_band = adoption_summary.get("risk_band", "no-data")
adoption_status = "warn" if risk_band in {"no-data", "medium", "high"} else "pass"
adoption_detail = (
f"{adoption_summary.get('event_count', 0)} metadata events; "
f"adoption {adoption_summary.get('adoption_rate', 0)}; "
f"missed {adoption_summary.get('missed_trigger_count', 0)}; "
f"bad-output {adoption_summary.get('bad_output_count', 0)}; "
f"risk {risk_band}"
)
gates.append(
gate(
"operations-loop",
"运营回路",
adoption_status,
adoption_detail,
"reports/adoption_drift_report.json",
_report_link(output_html, skill_dir, "reports/adoption_drift_report.md"),
)
)
waiver = data["review_waivers"]
waiver_summary = waiver.get("summary", {})
active_covered = set(waiver_summary.get("covered_gate_keys", []) or [])
prior_blockers = [item for item in gates if item["status"] == "block"]
prior_warnings = [item for item in gates if item["status"] == "warn"]
unwaived_warnings = [item for item in prior_warnings if item["key"] not in active_covered]
if not waiver:
waiver_status = "warn"
waiver_detail = "review waiver ledger is missing; warning acceptance is not auditable"
elif waiver.get("failures"):
waiver_status = "block"
waiver_detail = f"{len(waiver.get('failures', []))} invalid waiver records"
elif prior_blockers:
waiver_status = "block"
waiver_detail = f"{len(prior_blockers)} blocker gates cannot be waived in v0"
elif unwaived_warnings:
waiver_status = "warn"
waiver_detail = (
f"{waiver_summary.get('active_count', 0)} active waivers; "
f"{len(unwaived_warnings)} warning gates still need reviewer decision"
)
else:
waiver_status = "pass"
waiver_detail = f"{waiver_summary.get('active_count', 0)} active waivers cover current warnings"
gates.append(
gate(
"review-waivers",
"人工批准",
waiver_status,
waiver_detail,
"reports/review_waivers.json",
_report_link(output_html, skill_dir, "reports/review_waivers.md"),
)
)
registry = data["registry"]
install = data["install_simulation"]
if not registry:
if maturity in {"library", "governed"}:
registry_status = "warn"
registry_detail = "registry audit is missing; package metadata is not reviewable"
else:
registry_status = "pass"
registry_detail = "registry audit is optional until team distribution is required"
else:
compatibility = registry.get("package", {}).get("compatibility", {})
pass_count = sum(1 for status in compatibility.values() if status == "pass")
registry_status = "block" if registry.get("failures") else ("warn" if registry.get("warnings") else "pass")
registry_detail = (
f"{registry.get('package', {}).get('name', 'package')} "
f"{registry.get('package', {}).get('version', 'n/a')}; "
f"{pass_count}/{len(compatibility)} compatibility entries pass"
)
if install:
if install.get("failures"):
registry_status = "block"
install_summary = install.get("summary", {})
registry_detail += (
f"; install {'pass' if install.get('ok') else 'fail'}"
f" with {install_summary.get('adapter_count', 0)} adapters"
)
gates.append(
gate(
"registry-audit",
"注册审计",
registry_status,
registry_detail,
"reports/registry_audit.json + reports/install_simulation.json",
_report_link(output_html, skill_dir, "reports/registry_audit.md"),
)
)
promotion = data["promotion"]
migration_path = ROOT / "docs" / "migration-v2.md"
if promotion:
promotion_summary = promotion.get("summary", {})
blocked = int(promotion_summary.get("blocked", 0) or 0)
release_status = "block" if blocked else "pass"
release_detail = f"{promotion_summary.get('promote', 0)} promote; {promotion_summary.get('keep_current', 0)} keep current; {blocked} blocked"
else:
release_status = "warn"
release_detail = "promotion decisions are missing; release notes need reviewer confirmation"
upgrade = data["upgrade_check"]
if upgrade:
upgrade_summary = upgrade.get("summary", {})
if upgrade.get("failures"):
release_status = "block"
elif upgrade.get("warnings") and release_status == "pass":
release_status = "warn"
release_detail += (
f"; upgrade {upgrade_summary.get('declared_bump', 'n/a')}"
f" declared / {upgrade_summary.get('recommended_bump', 'n/a')} recommended"
)
gates.append(
gate(
"release-notes",
"发布路线",
release_status,
release_detail,
"reports/promotion_decisions.json + reports/upgrade_check.json + docs/migration-v2.md",
_report_link(output_html, skill_dir, "reports/promotion_decisions.md") if promotion else str(migration_path),
)
)
return gates
def weighted_score(gates: list[dict[str, str]]) -> int:
weights = {
"trigger-lab": 15,
"output-lab": 20,
"context-budget": 10,
"runtime-matrix": 10,
"trust-report": 10,
"permission-gates": 10,
"permission-runtime": 10,
"skill-atlas": 10,
"operations-loop": 10,
"review-waivers": 10,
"registry-audit": 10,
"release-notes": 10,
"intent-canvas": 10,
}
earned = 0.0
total = 0.0
for item in gates:
weight = weights.get(item["key"], 5)
total += weight
if item["status"] == "pass":
earned += weight
elif item["status"] == "warn":
earned += weight * 0.6
return int(round(earned / total * 100)) if total else 0
+3 -493
View File
@@ -21,11 +21,13 @@ from yao_cli_config import (
resolve_promotion_target,
resolve_target,
)
from yao_cli_parser import build_parser as build_cli_parser
ROOT = Path(__file__).resolve().parent.parent
SCRIPTS = ROOT / "scripts"
def script_path(name: str) -> str:
return str(SCRIPTS / name)
@@ -1157,499 +1159,7 @@ def command_check_update(args: argparse.Namespace) -> int:
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(description="Unified authoring CLI for yao-meta-skill.")
subparsers = parser.add_subparsers(dest="command", required=True)
init_cmd = subparsers.add_parser("init", help="Initialize a minimal skill package.")
init_cmd.add_argument("name")
init_cmd.add_argument("--description", default="Describe what the skill does and when to use it.")
init_cmd.add_argument("--title")
init_cmd.add_argument("--output-dir", default=".")
init_cmd.add_argument("--mode", choices=["scaffold", "production", "library", "governed"], default="scaffold")
init_cmd.add_argument("--archetype", choices=["scaffold", "production", "library", "governed"], default="scaffold")
init_cmd.add_argument("--external-reference", action="append", default=[])
init_cmd.add_argument("--user-reference", action="append", default=[])
init_cmd.add_argument("--local-constraint", action="append", default=[])
init_cmd.add_argument("--github-query")
init_cmd.add_argument("--github-top-n", type=int, default=3)
init_cmd.add_argument("--github-fixture-dir")
init_cmd.add_argument("--intent-job")
init_cmd.add_argument("--intent-real-input", action="append", default=[])
init_cmd.add_argument("--intent-primary-output")
init_cmd.add_argument("--intent-exclusion", action="append", default=[])
init_cmd.add_argument("--intent-constraint", action="append", default=[])
init_cmd.add_argument("--intent-standard", action="append", default=[])
init_cmd.add_argument("--intent-correction")
init_cmd.set_defaults(func=command_init)
quickstart_cmd = subparsers.add_parser(
"quickstart",
help="Interactive fast path for creating a scaffold-first skill package.",
)
quickstart_cmd.add_argument("--name")
quickstart_cmd.add_argument("--job")
quickstart_cmd.add_argument("--real-input", action="append", default=[])
quickstart_cmd.add_argument("--primary-output")
quickstart_cmd.add_argument("--description")
quickstart_cmd.add_argument("--title")
quickstart_cmd.add_argument("--output-dir", default=".")
quickstart_cmd.add_argument("--mode", choices=["scaffold", "production", "library", "governed"])
quickstart_cmd.add_argument("--archetype", choices=["scaffold", "production", "library", "governed"])
quickstart_cmd.add_argument("--external-reference", action="append", default=[])
quickstart_cmd.add_argument("--user-reference", action="append", default=[])
quickstart_cmd.add_argument("--local-constraint", action="append", default=[])
quickstart_cmd.add_argument("--constraint", action="append", default=[])
quickstart_cmd.add_argument("--github-query")
quickstart_cmd.add_argument("--github-top-n", type=int, default=3)
quickstart_cmd.add_argument("--github-fixture-dir")
quickstart_cmd.add_argument("--no-update-check", action="store_true")
quickstart_cmd.set_defaults(func=command_quickstart)
validate_cmd = subparsers.add_parser("validate", help="Run validate, lint, governance, and resource checks.")
validate_cmd.add_argument("skill_dir", nargs="?", default=".")
validate_cmd.add_argument("--require-manifest", action="store_true")
validate_cmd.set_defaults(func=command_validate)
optimize_cmd = subparsers.add_parser("optimize-description", help="Optimize description candidates for a target.")
optimize_cmd.add_argument(
"--target",
choices=["root", "team-frontend-review", "governed-incident-command", "all"],
default="root",
)
optimize_cmd.add_argument("--write", action="store_true", help="Write default report artifacts for the target.")
optimize_cmd.set_defaults(func=command_optimize_description)
promote_cmd = subparsers.add_parser("promote-check", help="Apply promotion policy and build iteration bundles.")
promote_cmd.set_defaults(func=command_promote_check)
review_cmd = subparsers.add_parser("review", help="Locate the current bundle and human review stub for a target.")
review_cmd.add_argument(
"--target",
choices=["root", "team-frontend-review", "governed-incident-command"],
default="root",
)
review_cmd.set_defaults(func=command_review)
snapshot_cmd = subparsers.add_parser("release-snapshot", help="Create a versioned snapshot from current promotion outputs.")
snapshot_cmd.add_argument(
"--target",
choices=["root", "team-frontend-review", "governed-incident-command"],
default="root",
)
snapshot_cmd.add_argument("--label", default="manual")
snapshot_cmd.set_defaults(func=command_release_snapshot)
flow_cmd = subparsers.add_parser(
"workspace-flow",
help="Run optimize, promotion, review refresh, and release snapshots as one authoring flow.",
)
flow_cmd.add_argument(
"--target",
choices=["root", "team-frontend-review", "governed-incident-command", "all"],
default="root",
)
flow_cmd.add_argument("--label", default="manual")
flow_cmd.set_defaults(func=command_workspace_flow)
report_cmd = subparsers.add_parser("report", help="Render route, iteration, regression, and context reports.")
report_cmd.add_argument("--refresh-optimization", action="store_true")
report_cmd.set_defaults(func=command_report)
skill_report_cmd = subparsers.add_parser("skill-report", help="Render the HTML skill report for a skill package.")
skill_report_cmd.add_argument("skill_dir", nargs="?", default=".")
skill_report_cmd.add_argument("--output-html")
skill_report_cmd.add_argument("--output-json")
skill_report_cmd.set_defaults(func=command_skill_report)
review_viewer_cmd = subparsers.add_parser("review-viewer", help="Render a compact HTML review page for a skill package.")
review_viewer_cmd.add_argument("skill_dir", nargs="?", default=".")
review_viewer_cmd.add_argument("--output-html")
review_viewer_cmd.add_argument("--output-json")
review_viewer_cmd.set_defaults(func=command_review_viewer)
review_studio_cmd = subparsers.add_parser("review-studio", help="Render Review Studio 2.0 for a skill package.")
review_studio_cmd.add_argument("skill_dir", nargs="?", default=".")
review_studio_cmd.add_argument("--output-html")
review_studio_cmd.add_argument("--output-json")
review_studio_cmd.set_defaults(func=command_review_studio)
reference_scan_cmd = subparsers.add_parser(
"reference-scan",
help="Render a controlled benchmark scan report for a skill package.",
)
reference_scan_cmd.add_argument("skill_dir", nargs="?", default=".")
reference_scan_cmd.add_argument("--reference", action="append", default=[])
reference_scan_cmd.add_argument("--external-reference", action="append", default=[])
reference_scan_cmd.add_argument("--user-reference", action="append", default=[])
reference_scan_cmd.add_argument("--local-constraint", action="append", default=[])
reference_scan_cmd.add_argument("--output-md")
reference_scan_cmd.add_argument("--output-json")
reference_scan_cmd.set_defaults(func=command_reference_scan)
github_scan_cmd = subparsers.add_parser(
"github-benchmark-scan",
help="Search top public GitHub repositories and extract borrow or avoid patterns for a skill.",
)
github_scan_cmd.add_argument("skill_dir", nargs="?", default=".")
github_scan_cmd.add_argument("--query", required=True)
github_scan_cmd.add_argument("--top-n", type=int, default=3)
github_scan_cmd.add_argument("--fixture-dir")
github_scan_cmd.add_argument("--output-md")
github_scan_cmd.add_argument("--output-json")
github_scan_cmd.set_defaults(func=command_github_benchmark_scan)
intent_confidence_cmd = subparsers.add_parser(
"intent-confidence",
help="Render a confidence report for how well the real job, inputs, outputs, and exclusions are understood.",
)
intent_confidence_cmd.add_argument("skill_dir", nargs="?", default=".")
intent_confidence_cmd.add_argument("--context-json")
intent_confidence_cmd.add_argument("--output-md")
intent_confidence_cmd.add_argument("--output-json")
intent_confidence_cmd.set_defaults(func=command_intent_confidence)
intent_dialogue_cmd = subparsers.add_parser(
"intent-dialogue",
help="Render a front-loaded intent dialogue guide for a skill package.",
)
intent_dialogue_cmd.add_argument("skill_dir", nargs="?", default=".")
intent_dialogue_cmd.add_argument("--output-md")
intent_dialogue_cmd.add_argument("--output-json")
intent_dialogue_cmd.set_defaults(func=command_intent_dialogue)
reference_synthesis_cmd = subparsers.add_parser(
"reference-synthesis",
help="Render a multi-source reference synthesis report for a skill package.",
)
reference_synthesis_cmd.add_argument("skill_dir", nargs="?", default=".")
reference_synthesis_cmd.add_argument("--output-md")
reference_synthesis_cmd.add_argument("--output-json")
reference_synthesis_cmd.set_defaults(func=command_reference_synthesis)
output_risk_cmd = subparsers.add_parser(
"output-risk-profile",
help="Render predicted output failure modes and self-repair checks for a skill package.",
)
output_risk_cmd.add_argument("skill_dir", nargs="?", default=".")
output_risk_cmd.add_argument("--output-md")
output_risk_cmd.add_argument("--output-json")
output_risk_cmd.set_defaults(func=command_output_risk_profile)
artifact_design_cmd = subparsers.add_parser(
"artifact-design-profile",
help="Render artifact design direction and visual quality gates for a skill package.",
)
artifact_design_cmd.add_argument("skill_dir", nargs="?", default=".")
artifact_design_cmd.add_argument("--output-md")
artifact_design_cmd.add_argument("--output-json")
artifact_design_cmd.set_defaults(func=command_artifact_design_profile)
prompt_quality_cmd = subparsers.add_parser(
"prompt-quality-profile",
help="Render prompt-facing need model, RTF mapping, complexity, and quality checks for a skill package.",
)
prompt_quality_cmd.add_argument("skill_dir", nargs="?", default=".")
prompt_quality_cmd.add_argument("--output-md")
prompt_quality_cmd.add_argument("--output-json")
prompt_quality_cmd.set_defaults(func=command_prompt_quality_profile)
system_model_cmd = subparsers.add_parser(
"system-model",
help="Render a systems-thinking model for boundaries, feedback loops, drift, and leverage points.",
)
system_model_cmd.add_argument("skill_dir", nargs="?", default=".")
system_model_cmd.add_argument("--output-md")
system_model_cmd.add_argument("--output-json")
system_model_cmd.set_defaults(func=command_system_model)
iteration_directions_cmd = subparsers.add_parser(
"iteration-directions",
help="Render the top three next iteration directions for a skill package.",
)
iteration_directions_cmd.add_argument("skill_dir", nargs="?", default=".")
iteration_directions_cmd.add_argument("--output-md")
iteration_directions_cmd.add_argument("--output-json")
iteration_directions_cmd.set_defaults(func=command_iteration_directions)
feedback_cmd = subparsers.add_parser(
"feedback",
help="Capture lightweight reviewer feedback without running the full promotion flow.",
)
feedback_cmd.add_argument("skill_dir", nargs="?", default=".")
feedback_cmd.add_argument("--note")
feedback_cmd.add_argument("--rating", type=int, default=3)
feedback_cmd.add_argument("--category", default="general")
feedback_cmd.add_argument("--recommended-action", default="review")
feedback_cmd.set_defaults(func=command_feedback)
adoption_drift_cmd = subparsers.add_parser(
"adoption-drift",
help="Render local-first metadata-only adoption and drift telemetry for a skill package.",
)
adoption_drift_cmd.add_argument("skill_dir", nargs="?", default=".")
adoption_drift_cmd.add_argument("--events-jsonl")
adoption_drift_cmd.add_argument("--output-json")
adoption_drift_cmd.add_argument("--output-md")
adoption_drift_cmd.add_argument("--generated-at")
adoption_drift_cmd.add_argument(
"--record-event",
choices=["review_event", "script_run", "skill_activation", "skill_output"],
)
adoption_drift_cmd.add_argument(
"--activation-type",
choices=["explicit", "implicit", "manual", "unknown"],
default="unknown",
)
adoption_drift_cmd.add_argument(
"--outcome",
choices=["accepted", "edited", "failed", "missed", "rejected", "reviewed", "unknown"],
default="unknown",
)
adoption_drift_cmd.add_argument(
"--failure-type",
choices=[
"bad_output",
"missing_resource",
"none",
"review_overdue",
"script_error",
"under_trigger",
"wrong_trigger",
],
default="none",
)
adoption_drift_cmd.add_argument("--timestamp")
adoption_drift_cmd.add_argument("--skill-name")
adoption_drift_cmd.add_argument("--version")
adoption_drift_cmd.set_defaults(func=command_adoption_drift)
review_waivers_cmd = subparsers.add_parser(
"review-waivers",
help="Render or update human reviewer waiver evidence for Review Studio.",
)
review_waivers_cmd.add_argument("skill_dir", nargs="?", default=".")
review_waivers_cmd.add_argument("--waivers-json")
review_waivers_cmd.add_argument("--output-json")
review_waivers_cmd.add_argument("--output-md")
review_waivers_cmd.add_argument("--generated-at")
review_waivers_cmd.add_argument("--add-waiver", action="store_true")
review_waivers_cmd.add_argument(
"--gate-key",
choices=[
"context-budget",
"intent-canvas",
"operations-loop",
"output-lab",
"registry-audit",
"release-notes",
"runtime-matrix",
"skill-atlas",
"trigger-lab",
"trust-report",
"permission-gates",
"permission-runtime",
],
)
review_waivers_cmd.add_argument(
"--decision",
choices=["accepted-risk", "false-positive", "temporary-exception"],
default="accepted-risk",
)
review_waivers_cmd.add_argument("--reviewer")
review_waivers_cmd.add_argument("--reason")
review_waivers_cmd.add_argument("--expires-at")
review_waivers_cmd.add_argument("--created-at")
review_waivers_cmd.add_argument("--evidence")
review_waivers_cmd.add_argument("--scope", default="current-release")
review_waivers_cmd.set_defaults(func=command_review_waivers)
review_annotations_cmd = subparsers.add_parser(
"review-annotations",
help="Render or update inline reviewer annotations for Review Studio gates and source paths.",
)
review_annotations_cmd.add_argument("skill_dir", nargs="?", default=".")
review_annotations_cmd.add_argument("--annotations-json")
review_annotations_cmd.add_argument("--output-json")
review_annotations_cmd.add_argument("--output-md")
review_annotations_cmd.add_argument("--write-template", action="store_true")
review_annotations_cmd.add_argument("--add-annotation", action="store_true")
review_annotations_cmd.add_argument("--annotation-id")
review_annotations_cmd.add_argument(
"--gate-key",
choices=[
"context-budget",
"intent-canvas",
"operations-loop",
"output-lab",
"registry-audit",
"release-notes",
"review-waivers",
"runtime-matrix",
"skill-atlas",
"trigger-lab",
"trust-report",
"permission-gates",
"permission-runtime",
],
)
review_annotations_cmd.add_argument("--target-path")
review_annotations_cmd.add_argument("--line", type=int)
review_annotations_cmd.add_argument("--severity", choices=["blocker", "info", "note", "warning"], default="note")
review_annotations_cmd.add_argument("--status", choices=["deferred", "open", "resolved"], default="open")
review_annotations_cmd.add_argument("--reviewer")
review_annotations_cmd.add_argument("--created-at")
review_annotations_cmd.add_argument("--body")
review_annotations_cmd.add_argument("--suggested-action")
review_annotations_cmd.add_argument("--evidence")
review_annotations_cmd.set_defaults(func=command_review_annotations)
baseline_compare_cmd = subparsers.add_parser(
"baseline-compare",
help="Render a lightweight with-skill vs baseline comparison across tracked targets.",
)
baseline_compare_cmd.set_defaults(func=command_baseline_compare)
skill_ir_cmd = subparsers.add_parser("skill-ir", help="Export platform-neutral Skill IR for a skill package.")
skill_ir_cmd.add_argument("skill_dir", nargs="?", default=".")
skill_ir_cmd.add_argument("--output-json")
skill_ir_cmd.add_argument("--validate-only", action="store_true")
skill_ir_cmd.set_defaults(func=command_skill_ir)
compile_skill_cmd = subparsers.add_parser(
"compile-skill",
help="Compile Skill IR into target-specific semantic contracts.",
)
compile_skill_cmd.add_argument("skill_dir", nargs="?", default=".")
compile_skill_cmd.add_argument("--target", action="append")
compile_skill_cmd.add_argument("--output-json")
compile_skill_cmd.add_argument("--output-md")
compile_skill_cmd.add_argument("--generated-at")
compile_skill_cmd.set_defaults(func=command_compile_skill)
output_eval_cmd = subparsers.add_parser("output-eval", help="Run Output Eval Lab assertion grading.")
output_eval_cmd.add_argument("--cases")
output_eval_cmd.add_argument("--output-json")
output_eval_cmd.add_argument("--output-md")
output_eval_cmd.add_argument("--blind-pack-json")
output_eval_cmd.add_argument("--blind-pack-md")
output_eval_cmd.add_argument("--blind-answer-key-json")
output_eval_cmd.set_defaults(func=command_output_eval)
output_execution_cmd = subparsers.add_parser(
"output-exec",
help="Record output-eval execution evidence, timing, and token usage.",
)
output_execution_cmd.add_argument("--cases")
output_execution_cmd.add_argument("--output-json")
output_execution_cmd.add_argument("--output-md")
output_execution_cmd.add_argument("--runner-command")
output_execution_cmd.add_argument("--timeout-seconds", type=float)
output_execution_cmd.set_defaults(func=command_output_execution)
output_review_cmd = subparsers.add_parser(
"output-review",
help="Adjudicate blind A/B output review decisions against the answer key.",
)
output_review_cmd.add_argument("--blind-pack")
output_review_cmd.add_argument("--answer-key")
output_review_cmd.add_argument("--decisions")
output_review_cmd.add_argument("--output-json")
output_review_cmd.add_argument("--output-md")
output_review_cmd.add_argument("--write-template", action="store_true")
output_review_cmd.set_defaults(func=command_output_review)
conformance_cmd = subparsers.add_parser("conformance", help="Run runtime conformance checks for Skill OS targets.")
conformance_cmd.add_argument("skill_dir", nargs="?", default=".")
conformance_cmd.add_argument("--target", action="append", choices=["openai", "claude", "agent-skills", "vscode", "generic"])
conformance_cmd.add_argument("--output-json")
conformance_cmd.add_argument("--output-md")
conformance_cmd.set_defaults(func=command_conformance)
runtime_permissions_cmd = subparsers.add_parser(
"runtime-permissions",
help="Probe generated target adapters for runtime permission enforcement metadata.",
)
runtime_permissions_cmd.add_argument("skill_dir", nargs="?", default=".")
runtime_permissions_cmd.add_argument("--package-dir", default="dist")
runtime_permissions_cmd.add_argument("--target", action="append", choices=["openai", "claude", "generic"])
runtime_permissions_cmd.add_argument("--output-json")
runtime_permissions_cmd.add_argument("--output-md")
runtime_permissions_cmd.set_defaults(func=command_runtime_permissions)
trust_cmd = subparsers.add_parser("trust", help="Run trust and security checks for a skill package.")
trust_cmd.add_argument("skill_dir", nargs="?", default=".")
trust_cmd.add_argument("--output-json")
trust_cmd.add_argument("--output-md")
trust_cmd.set_defaults(func=command_trust)
skill_atlas_cmd = subparsers.add_parser("skill-atlas", help="Build a portfolio-level Skill Atlas for a workspace.")
skill_atlas_cmd.add_argument("--workspace-root", default=".")
skill_atlas_cmd.add_argument("--output-dir")
skill_atlas_cmd.add_argument("--report-html")
skill_atlas_cmd.add_argument("--report-json")
skill_atlas_cmd.add_argument("--overlap-threshold", type=float)
skill_atlas_cmd.add_argument("--today")
skill_atlas_cmd.set_defaults(func=command_skill_atlas)
registry_audit_cmd = subparsers.add_parser("registry-audit", help="Build and audit Skill OS registry package metadata.")
registry_audit_cmd.add_argument("skill_dir", nargs="?", default=".")
registry_audit_cmd.add_argument("--registry-dir")
registry_audit_cmd.add_argument("--output-json")
registry_audit_cmd.add_argument("--output-md")
registry_audit_cmd.add_argument("--generated-at")
registry_audit_cmd.set_defaults(func=command_registry_audit)
package_cmd = subparsers.add_parser("package", help="Export compatibility artifacts for selected targets.")
package_cmd.add_argument("skill_dir", nargs="?", default=".")
package_cmd.add_argument("--platform", action="append")
package_cmd.add_argument("--output-dir", default="dist")
package_cmd.add_argument("--expectations")
package_cmd.add_argument("--zip", action="store_true")
package_cmd.set_defaults(func=command_package)
package_verify_cmd = subparsers.add_parser("package-verify", help="Verify generated package artifacts, archive safety, and registry parity.")
package_verify_cmd.add_argument("skill_dir", nargs="?", default=".")
package_verify_cmd.add_argument("--package-dir", default="dist")
package_verify_cmd.add_argument("--expectations", default="evals/packaging_expectations.json")
package_verify_cmd.add_argument("--registry-json", default="reports/registry_audit.json")
package_verify_cmd.add_argument("--output-json")
package_verify_cmd.add_argument("--output-md")
package_verify_cmd.add_argument("--require-zip", action="store_true")
package_verify_cmd.add_argument("--generated-at")
package_verify_cmd.set_defaults(func=command_package_verify)
install_simulate_cmd = subparsers.add_parser("install-simulate", help="Simulate installing a generated package into a temporary local skill root.")
install_simulate_cmd.add_argument("skill_dir", nargs="?", default=".")
install_simulate_cmd.add_argument("--package-dir", default="dist")
install_simulate_cmd.add_argument("--install-root")
install_simulate_cmd.add_argument("--output-json")
install_simulate_cmd.add_argument("--output-md")
install_simulate_cmd.add_argument("--generated-at")
install_simulate_cmd.set_defaults(func=command_install_simulate)
upgrade_check_cmd = subparsers.add_parser("upgrade-check", help="Compare current and previous registry package metadata for upgrade readiness.")
upgrade_check_cmd.add_argument("skill_dir", nargs="?", default=".")
upgrade_check_cmd.add_argument("--previous-package-json", required=True)
upgrade_check_cmd.add_argument("--current-package-json", default="reports/registry_audit.json")
upgrade_check_cmd.add_argument("--output-json")
upgrade_check_cmd.add_argument("--output-md")
upgrade_check_cmd.add_argument("--generated-at")
upgrade_check_cmd.set_defaults(func=command_upgrade_check)
test_cmd = subparsers.add_parser("test", help="Run a Makefile test target.")
test_cmd.add_argument("--target", default="test")
test_cmd.set_defaults(func=command_test)
update_cmd = subparsers.add_parser("check-update", help="Check whether a newer yao-meta-skill version is available.")
update_cmd.add_argument("--force", action="store_true")
update_cmd.add_argument("--no-cache", action="store_true")
update_cmd.add_argument("--version-url")
update_cmd.add_argument("--manifest-url")
update_cmd.add_argument("--timeout", type=float, default=3.0)
update_cmd.add_argument("--allow-custom-update-url", action="store_true")
update_cmd.set_defaults(func=command_check_update)
return parser
return build_cli_parser({name: value for name, value in globals().items() if name.startswith("command_")})
def main() -> None:
+513
View File
@@ -0,0 +1,513 @@
#!/usr/bin/env python3
"""Argparse surface for the Yao CLI."""
import argparse
from collections.abc import Callable
SCRIPT_INTERFACE = "internal-module"
SCRIPT_INTERFACE_REASON = "Imported by yao.py to keep CLI parser declarations separate from command orchestration."
def _handler(command_handlers: dict[str, Callable[[argparse.Namespace], int]], name: str) -> Callable[[argparse.Namespace], int]:
if name not in command_handlers:
raise KeyError(f"Missing CLI command handler: {name}")
return command_handlers[name]
def build_parser(command_handlers: dict[str, Callable[[argparse.Namespace], int]]) -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(description="Unified authoring CLI for yao-meta-skill.")
subparsers = parser.add_subparsers(dest="command", required=True)
init_cmd = subparsers.add_parser("init", help="Initialize a minimal skill package.")
init_cmd.add_argument("name")
init_cmd.add_argument("--description", default="Describe what the skill does and when to use it.")
init_cmd.add_argument("--title")
init_cmd.add_argument("--output-dir", default=".")
init_cmd.add_argument("--mode", choices=["scaffold", "production", "library", "governed"], default="scaffold")
init_cmd.add_argument("--archetype", choices=["scaffold", "production", "library", "governed"], default="scaffold")
init_cmd.add_argument("--external-reference", action="append", default=[])
init_cmd.add_argument("--user-reference", action="append", default=[])
init_cmd.add_argument("--local-constraint", action="append", default=[])
init_cmd.add_argument("--github-query")
init_cmd.add_argument("--github-top-n", type=int, default=3)
init_cmd.add_argument("--github-fixture-dir")
init_cmd.add_argument("--intent-job")
init_cmd.add_argument("--intent-real-input", action="append", default=[])
init_cmd.add_argument("--intent-primary-output")
init_cmd.add_argument("--intent-exclusion", action="append", default=[])
init_cmd.add_argument("--intent-constraint", action="append", default=[])
init_cmd.add_argument("--intent-standard", action="append", default=[])
init_cmd.add_argument("--intent-correction")
init_cmd.set_defaults(func=_handler(command_handlers, "command_init"))
quickstart_cmd = subparsers.add_parser(
"quickstart",
help="Interactive fast path for creating a scaffold-first skill package.",
)
quickstart_cmd.add_argument("--name")
quickstart_cmd.add_argument("--job")
quickstart_cmd.add_argument("--real-input", action="append", default=[])
quickstart_cmd.add_argument("--primary-output")
quickstart_cmd.add_argument("--description")
quickstart_cmd.add_argument("--title")
quickstart_cmd.add_argument("--output-dir", default=".")
quickstart_cmd.add_argument("--mode", choices=["scaffold", "production", "library", "governed"])
quickstart_cmd.add_argument("--archetype", choices=["scaffold", "production", "library", "governed"])
quickstart_cmd.add_argument("--external-reference", action="append", default=[])
quickstart_cmd.add_argument("--user-reference", action="append", default=[])
quickstart_cmd.add_argument("--local-constraint", action="append", default=[])
quickstart_cmd.add_argument("--constraint", action="append", default=[])
quickstart_cmd.add_argument("--github-query")
quickstart_cmd.add_argument("--github-top-n", type=int, default=3)
quickstart_cmd.add_argument("--github-fixture-dir")
quickstart_cmd.add_argument("--no-update-check", action="store_true")
quickstart_cmd.set_defaults(func=_handler(command_handlers, "command_quickstart"))
validate_cmd = subparsers.add_parser("validate", help="Run validate, lint, governance, and resource checks.")
validate_cmd.add_argument("skill_dir", nargs="?", default=".")
validate_cmd.add_argument("--require-manifest", action="store_true")
validate_cmd.set_defaults(func=_handler(command_handlers, "command_validate"))
optimize_cmd = subparsers.add_parser("optimize-description", help="Optimize description candidates for a target.")
optimize_cmd.add_argument(
"--target",
choices=["root", "team-frontend-review", "governed-incident-command", "all"],
default="root",
)
optimize_cmd.add_argument("--write", action="store_true", help="Write default report artifacts for the target.")
optimize_cmd.set_defaults(func=_handler(command_handlers, "command_optimize_description"))
promote_cmd = subparsers.add_parser("promote-check", help="Apply promotion policy and build iteration bundles.")
promote_cmd.set_defaults(func=_handler(command_handlers, "command_promote_check"))
review_cmd = subparsers.add_parser("review", help="Locate the current bundle and human review stub for a target.")
review_cmd.add_argument(
"--target",
choices=["root", "team-frontend-review", "governed-incident-command"],
default="root",
)
review_cmd.set_defaults(func=_handler(command_handlers, "command_review"))
snapshot_cmd = subparsers.add_parser("release-snapshot", help="Create a versioned snapshot from current promotion outputs.")
snapshot_cmd.add_argument(
"--target",
choices=["root", "team-frontend-review", "governed-incident-command"],
default="root",
)
snapshot_cmd.add_argument("--label", default="manual")
snapshot_cmd.set_defaults(func=_handler(command_handlers, "command_release_snapshot"))
flow_cmd = subparsers.add_parser(
"workspace-flow",
help="Run optimize, promotion, review refresh, and release snapshots as one authoring flow.",
)
flow_cmd.add_argument(
"--target",
choices=["root", "team-frontend-review", "governed-incident-command", "all"],
default="root",
)
flow_cmd.add_argument("--label", default="manual")
flow_cmd.set_defaults(func=_handler(command_handlers, "command_workspace_flow"))
report_cmd = subparsers.add_parser("report", help="Render route, iteration, regression, and context reports.")
report_cmd.add_argument("--refresh-optimization", action="store_true")
report_cmd.set_defaults(func=_handler(command_handlers, "command_report"))
skill_report_cmd = subparsers.add_parser("skill-report", help="Render the HTML skill report for a skill package.")
skill_report_cmd.add_argument("skill_dir", nargs="?", default=".")
skill_report_cmd.add_argument("--output-html")
skill_report_cmd.add_argument("--output-json")
skill_report_cmd.set_defaults(func=_handler(command_handlers, "command_skill_report"))
review_viewer_cmd = subparsers.add_parser("review-viewer", help="Render a compact HTML review page for a skill package.")
review_viewer_cmd.add_argument("skill_dir", nargs="?", default=".")
review_viewer_cmd.add_argument("--output-html")
review_viewer_cmd.add_argument("--output-json")
review_viewer_cmd.set_defaults(func=_handler(command_handlers, "command_review_viewer"))
review_studio_cmd = subparsers.add_parser("review-studio", help="Render Review Studio 2.0 for a skill package.")
review_studio_cmd.add_argument("skill_dir", nargs="?", default=".")
review_studio_cmd.add_argument("--output-html")
review_studio_cmd.add_argument("--output-json")
review_studio_cmd.set_defaults(func=_handler(command_handlers, "command_review_studio"))
reference_scan_cmd = subparsers.add_parser(
"reference-scan",
help="Render a controlled benchmark scan report for a skill package.",
)
reference_scan_cmd.add_argument("skill_dir", nargs="?", default=".")
reference_scan_cmd.add_argument("--reference", action="append", default=[])
reference_scan_cmd.add_argument("--external-reference", action="append", default=[])
reference_scan_cmd.add_argument("--user-reference", action="append", default=[])
reference_scan_cmd.add_argument("--local-constraint", action="append", default=[])
reference_scan_cmd.add_argument("--output-md")
reference_scan_cmd.add_argument("--output-json")
reference_scan_cmd.set_defaults(func=_handler(command_handlers, "command_reference_scan"))
github_scan_cmd = subparsers.add_parser(
"github-benchmark-scan",
help="Search top public GitHub repositories and extract borrow or avoid patterns for a skill.",
)
github_scan_cmd.add_argument("skill_dir", nargs="?", default=".")
github_scan_cmd.add_argument("--query", required=True)
github_scan_cmd.add_argument("--top-n", type=int, default=3)
github_scan_cmd.add_argument("--fixture-dir")
github_scan_cmd.add_argument("--output-md")
github_scan_cmd.add_argument("--output-json")
github_scan_cmd.set_defaults(func=_handler(command_handlers, "command_github_benchmark_scan"))
intent_confidence_cmd = subparsers.add_parser(
"intent-confidence",
help="Render a confidence report for how well the real job, inputs, outputs, and exclusions are understood.",
)
intent_confidence_cmd.add_argument("skill_dir", nargs="?", default=".")
intent_confidence_cmd.add_argument("--context-json")
intent_confidence_cmd.add_argument("--output-md")
intent_confidence_cmd.add_argument("--output-json")
intent_confidence_cmd.set_defaults(func=_handler(command_handlers, "command_intent_confidence"))
intent_dialogue_cmd = subparsers.add_parser(
"intent-dialogue",
help="Render a front-loaded intent dialogue guide for a skill package.",
)
intent_dialogue_cmd.add_argument("skill_dir", nargs="?", default=".")
intent_dialogue_cmd.add_argument("--output-md")
intent_dialogue_cmd.add_argument("--output-json")
intent_dialogue_cmd.set_defaults(func=_handler(command_handlers, "command_intent_dialogue"))
reference_synthesis_cmd = subparsers.add_parser(
"reference-synthesis",
help="Render a multi-source reference synthesis report for a skill package.",
)
reference_synthesis_cmd.add_argument("skill_dir", nargs="?", default=".")
reference_synthesis_cmd.add_argument("--output-md")
reference_synthesis_cmd.add_argument("--output-json")
reference_synthesis_cmd.set_defaults(func=_handler(command_handlers, "command_reference_synthesis"))
output_risk_cmd = subparsers.add_parser(
"output-risk-profile",
help="Render predicted output failure modes and self-repair checks for a skill package.",
)
output_risk_cmd.add_argument("skill_dir", nargs="?", default=".")
output_risk_cmd.add_argument("--output-md")
output_risk_cmd.add_argument("--output-json")
output_risk_cmd.set_defaults(func=_handler(command_handlers, "command_output_risk_profile"))
artifact_design_cmd = subparsers.add_parser(
"artifact-design-profile",
help="Render artifact design direction and visual quality gates for a skill package.",
)
artifact_design_cmd.add_argument("skill_dir", nargs="?", default=".")
artifact_design_cmd.add_argument("--output-md")
artifact_design_cmd.add_argument("--output-json")
artifact_design_cmd.set_defaults(func=_handler(command_handlers, "command_artifact_design_profile"))
prompt_quality_cmd = subparsers.add_parser(
"prompt-quality-profile",
help="Render prompt-facing need model, RTF mapping, complexity, and quality checks for a skill package.",
)
prompt_quality_cmd.add_argument("skill_dir", nargs="?", default=".")
prompt_quality_cmd.add_argument("--output-md")
prompt_quality_cmd.add_argument("--output-json")
prompt_quality_cmd.set_defaults(func=_handler(command_handlers, "command_prompt_quality_profile"))
system_model_cmd = subparsers.add_parser(
"system-model",
help="Render a systems-thinking model for boundaries, feedback loops, drift, and leverage points.",
)
system_model_cmd.add_argument("skill_dir", nargs="?", default=".")
system_model_cmd.add_argument("--output-md")
system_model_cmd.add_argument("--output-json")
system_model_cmd.set_defaults(func=_handler(command_handlers, "command_system_model"))
iteration_directions_cmd = subparsers.add_parser(
"iteration-directions",
help="Render the top three next iteration directions for a skill package.",
)
iteration_directions_cmd.add_argument("skill_dir", nargs="?", default=".")
iteration_directions_cmd.add_argument("--output-md")
iteration_directions_cmd.add_argument("--output-json")
iteration_directions_cmd.set_defaults(func=_handler(command_handlers, "command_iteration_directions"))
feedback_cmd = subparsers.add_parser(
"feedback",
help="Capture lightweight reviewer feedback without running the full promotion flow.",
)
feedback_cmd.add_argument("skill_dir", nargs="?", default=".")
feedback_cmd.add_argument("--note")
feedback_cmd.add_argument("--rating", type=int, default=3)
feedback_cmd.add_argument("--category", default="general")
feedback_cmd.add_argument("--recommended-action", default="review")
feedback_cmd.set_defaults(func=_handler(command_handlers, "command_feedback"))
adoption_drift_cmd = subparsers.add_parser(
"adoption-drift",
help="Render local-first metadata-only adoption and drift telemetry for a skill package.",
)
adoption_drift_cmd.add_argument("skill_dir", nargs="?", default=".")
adoption_drift_cmd.add_argument("--events-jsonl")
adoption_drift_cmd.add_argument("--output-json")
adoption_drift_cmd.add_argument("--output-md")
adoption_drift_cmd.add_argument("--generated-at")
adoption_drift_cmd.add_argument(
"--record-event",
choices=["review_event", "script_run", "skill_activation", "skill_output"],
)
adoption_drift_cmd.add_argument(
"--activation-type",
choices=["explicit", "implicit", "manual", "unknown"],
default="unknown",
)
adoption_drift_cmd.add_argument(
"--outcome",
choices=["accepted", "edited", "failed", "missed", "rejected", "reviewed", "unknown"],
default="unknown",
)
adoption_drift_cmd.add_argument(
"--failure-type",
choices=[
"bad_output",
"missing_resource",
"none",
"review_overdue",
"script_error",
"under_trigger",
"wrong_trigger",
],
default="none",
)
adoption_drift_cmd.add_argument("--timestamp")
adoption_drift_cmd.add_argument("--skill-name")
adoption_drift_cmd.add_argument("--version")
adoption_drift_cmd.set_defaults(func=_handler(command_handlers, "command_adoption_drift"))
review_waivers_cmd = subparsers.add_parser(
"review-waivers",
help="Render or update human reviewer waiver evidence for Review Studio.",
)
review_waivers_cmd.add_argument("skill_dir", nargs="?", default=".")
review_waivers_cmd.add_argument("--waivers-json")
review_waivers_cmd.add_argument("--output-json")
review_waivers_cmd.add_argument("--output-md")
review_waivers_cmd.add_argument("--generated-at")
review_waivers_cmd.add_argument("--add-waiver", action="store_true")
review_waivers_cmd.add_argument(
"--gate-key",
choices=[
"context-budget",
"intent-canvas",
"operations-loop",
"output-lab",
"registry-audit",
"release-notes",
"runtime-matrix",
"skill-atlas",
"trigger-lab",
"trust-report",
"permission-gates",
"permission-runtime",
],
)
review_waivers_cmd.add_argument(
"--decision",
choices=["accepted-risk", "false-positive", "temporary-exception"],
default="accepted-risk",
)
review_waivers_cmd.add_argument("--reviewer")
review_waivers_cmd.add_argument("--reason")
review_waivers_cmd.add_argument("--expires-at")
review_waivers_cmd.add_argument("--created-at")
review_waivers_cmd.add_argument("--evidence")
review_waivers_cmd.add_argument("--scope", default="current-release")
review_waivers_cmd.set_defaults(func=_handler(command_handlers, "command_review_waivers"))
review_annotations_cmd = subparsers.add_parser(
"review-annotations",
help="Render or update inline reviewer annotations for Review Studio gates and source paths.",
)
review_annotations_cmd.add_argument("skill_dir", nargs="?", default=".")
review_annotations_cmd.add_argument("--annotations-json")
review_annotations_cmd.add_argument("--output-json")
review_annotations_cmd.add_argument("--output-md")
review_annotations_cmd.add_argument("--write-template", action="store_true")
review_annotations_cmd.add_argument("--add-annotation", action="store_true")
review_annotations_cmd.add_argument("--annotation-id")
review_annotations_cmd.add_argument(
"--gate-key",
choices=[
"context-budget",
"intent-canvas",
"operations-loop",
"output-lab",
"registry-audit",
"release-notes",
"review-waivers",
"runtime-matrix",
"skill-atlas",
"trigger-lab",
"trust-report",
"permission-gates",
"permission-runtime",
],
)
review_annotations_cmd.add_argument("--target-path")
review_annotations_cmd.add_argument("--line", type=int)
review_annotations_cmd.add_argument("--severity", choices=["blocker", "info", "note", "warning"], default="note")
review_annotations_cmd.add_argument("--status", choices=["deferred", "open", "resolved"], default="open")
review_annotations_cmd.add_argument("--reviewer")
review_annotations_cmd.add_argument("--created-at")
review_annotations_cmd.add_argument("--body")
review_annotations_cmd.add_argument("--suggested-action")
review_annotations_cmd.add_argument("--evidence")
review_annotations_cmd.set_defaults(func=_handler(command_handlers, "command_review_annotations"))
baseline_compare_cmd = subparsers.add_parser(
"baseline-compare",
help="Render a lightweight with-skill vs baseline comparison across tracked targets.",
)
baseline_compare_cmd.set_defaults(func=_handler(command_handlers, "command_baseline_compare"))
skill_ir_cmd = subparsers.add_parser("skill-ir", help="Export platform-neutral Skill IR for a skill package.")
skill_ir_cmd.add_argument("skill_dir", nargs="?", default=".")
skill_ir_cmd.add_argument("--output-json")
skill_ir_cmd.add_argument("--validate-only", action="store_true")
skill_ir_cmd.set_defaults(func=_handler(command_handlers, "command_skill_ir"))
compile_skill_cmd = subparsers.add_parser(
"compile-skill",
help="Compile Skill IR into target-specific semantic contracts.",
)
compile_skill_cmd.add_argument("skill_dir", nargs="?", default=".")
compile_skill_cmd.add_argument("--target", action="append")
compile_skill_cmd.add_argument("--output-json")
compile_skill_cmd.add_argument("--output-md")
compile_skill_cmd.add_argument("--generated-at")
compile_skill_cmd.set_defaults(func=_handler(command_handlers, "command_compile_skill"))
output_eval_cmd = subparsers.add_parser("output-eval", help="Run Output Eval Lab assertion grading.")
output_eval_cmd.add_argument("--cases")
output_eval_cmd.add_argument("--output-json")
output_eval_cmd.add_argument("--output-md")
output_eval_cmd.add_argument("--blind-pack-json")
output_eval_cmd.add_argument("--blind-pack-md")
output_eval_cmd.add_argument("--blind-answer-key-json")
output_eval_cmd.set_defaults(func=_handler(command_handlers, "command_output_eval"))
output_execution_cmd = subparsers.add_parser(
"output-exec",
help="Record output-eval execution evidence, timing, and token usage.",
)
output_execution_cmd.add_argument("--cases")
output_execution_cmd.add_argument("--output-json")
output_execution_cmd.add_argument("--output-md")
output_execution_cmd.add_argument("--runner-command")
output_execution_cmd.add_argument("--timeout-seconds", type=float)
output_execution_cmd.set_defaults(func=_handler(command_handlers, "command_output_execution"))
output_review_cmd = subparsers.add_parser(
"output-review",
help="Adjudicate blind A/B output review decisions against the answer key.",
)
output_review_cmd.add_argument("--blind-pack")
output_review_cmd.add_argument("--answer-key")
output_review_cmd.add_argument("--decisions")
output_review_cmd.add_argument("--output-json")
output_review_cmd.add_argument("--output-md")
output_review_cmd.add_argument("--write-template", action="store_true")
output_review_cmd.set_defaults(func=_handler(command_handlers, "command_output_review"))
conformance_cmd = subparsers.add_parser("conformance", help="Run runtime conformance checks for Skill OS targets.")
conformance_cmd.add_argument("skill_dir", nargs="?", default=".")
conformance_cmd.add_argument("--target", action="append", choices=["openai", "claude", "agent-skills", "vscode", "generic"])
conformance_cmd.add_argument("--output-json")
conformance_cmd.add_argument("--output-md")
conformance_cmd.set_defaults(func=_handler(command_handlers, "command_conformance"))
runtime_permissions_cmd = subparsers.add_parser(
"runtime-permissions",
help="Probe generated target adapters for runtime permission enforcement metadata.",
)
runtime_permissions_cmd.add_argument("skill_dir", nargs="?", default=".")
runtime_permissions_cmd.add_argument("--package-dir", default="dist")
runtime_permissions_cmd.add_argument("--target", action="append", choices=["openai", "claude", "generic"])
runtime_permissions_cmd.add_argument("--output-json")
runtime_permissions_cmd.add_argument("--output-md")
runtime_permissions_cmd.set_defaults(func=_handler(command_handlers, "command_runtime_permissions"))
trust_cmd = subparsers.add_parser("trust", help="Run trust and security checks for a skill package.")
trust_cmd.add_argument("skill_dir", nargs="?", default=".")
trust_cmd.add_argument("--output-json")
trust_cmd.add_argument("--output-md")
trust_cmd.set_defaults(func=_handler(command_handlers, "command_trust"))
skill_atlas_cmd = subparsers.add_parser("skill-atlas", help="Build a portfolio-level Skill Atlas for a workspace.")
skill_atlas_cmd.add_argument("--workspace-root", default=".")
skill_atlas_cmd.add_argument("--output-dir")
skill_atlas_cmd.add_argument("--report-html")
skill_atlas_cmd.add_argument("--report-json")
skill_atlas_cmd.add_argument("--overlap-threshold", type=float)
skill_atlas_cmd.add_argument("--today")
skill_atlas_cmd.set_defaults(func=_handler(command_handlers, "command_skill_atlas"))
registry_audit_cmd = subparsers.add_parser("registry-audit", help="Build and audit Skill OS registry package metadata.")
registry_audit_cmd.add_argument("skill_dir", nargs="?", default=".")
registry_audit_cmd.add_argument("--registry-dir")
registry_audit_cmd.add_argument("--output-json")
registry_audit_cmd.add_argument("--output-md")
registry_audit_cmd.add_argument("--generated-at")
registry_audit_cmd.set_defaults(func=_handler(command_handlers, "command_registry_audit"))
package_cmd = subparsers.add_parser("package", help="Export compatibility artifacts for selected targets.")
package_cmd.add_argument("skill_dir", nargs="?", default=".")
package_cmd.add_argument("--platform", action="append")
package_cmd.add_argument("--output-dir", default="dist")
package_cmd.add_argument("--expectations")
package_cmd.add_argument("--zip", action="store_true")
package_cmd.set_defaults(func=_handler(command_handlers, "command_package"))
package_verify_cmd = subparsers.add_parser("package-verify", help="Verify generated package artifacts, archive safety, and registry parity.")
package_verify_cmd.add_argument("skill_dir", nargs="?", default=".")
package_verify_cmd.add_argument("--package-dir", default="dist")
package_verify_cmd.add_argument("--expectations", default="evals/packaging_expectations.json")
package_verify_cmd.add_argument("--registry-json", default="reports/registry_audit.json")
package_verify_cmd.add_argument("--output-json")
package_verify_cmd.add_argument("--output-md")
package_verify_cmd.add_argument("--require-zip", action="store_true")
package_verify_cmd.add_argument("--generated-at")
package_verify_cmd.set_defaults(func=_handler(command_handlers, "command_package_verify"))
install_simulate_cmd = subparsers.add_parser("install-simulate", help="Simulate installing a generated package into a temporary local skill root.")
install_simulate_cmd.add_argument("skill_dir", nargs="?", default=".")
install_simulate_cmd.add_argument("--package-dir", default="dist")
install_simulate_cmd.add_argument("--install-root")
install_simulate_cmd.add_argument("--output-json")
install_simulate_cmd.add_argument("--output-md")
install_simulate_cmd.add_argument("--generated-at")
install_simulate_cmd.set_defaults(func=_handler(command_handlers, "command_install_simulate"))
upgrade_check_cmd = subparsers.add_parser("upgrade-check", help="Compare current and previous registry package metadata for upgrade readiness.")
upgrade_check_cmd.add_argument("skill_dir", nargs="?", default=".")
upgrade_check_cmd.add_argument("--previous-package-json", required=True)
upgrade_check_cmd.add_argument("--current-package-json", default="reports/registry_audit.json")
upgrade_check_cmd.add_argument("--output-json")
upgrade_check_cmd.add_argument("--output-md")
upgrade_check_cmd.add_argument("--generated-at")
upgrade_check_cmd.set_defaults(func=_handler(command_handlers, "command_upgrade_check"))
test_cmd = subparsers.add_parser("test", help="Run a Makefile test target.")
test_cmd.add_argument("--target", default="test")
test_cmd.set_defaults(func=_handler(command_handlers, "command_test"))
update_cmd = subparsers.add_parser("check-update", help="Check whether a newer yao-meta-skill version is available.")
update_cmd.add_argument("--force", action="store_true")
update_cmd.add_argument("--no-cache", action="store_true")
update_cmd.add_argument("--version-url")
update_cmd.add_argument("--manifest-url")
update_cmd.add_argument("--timeout", type=float, default=3.0)
update_cmd.add_argument("--allow-custom-update-url", action="store_true")
update_cmd.set_defaults(func=_handler(command_handlers, "command_check_update"))
return parser
+3 -1
View File
@@ -155,6 +155,7 @@
"scripts/render_system_model.py",
"scripts/resource_boundary_check.py",
"scripts/review_studio_formatting.py",
"scripts/review_studio_gates.py",
"scripts/review_studio_layout.py",
"scripts/run_conformance_suite.py",
"scripts/run_description_optimization_suite.py",
@@ -173,7 +174,8 @@
"scripts/validate_skill.py",
"scripts/verify_package.py",
"scripts/yao.py",
"scripts/yao_cli_config.py"
"scripts/yao_cli_config.py",
"scripts/yao_cli_parser.py"
],
"assets": [
"templates/basic_skill.md.j2",
+2
View File
@@ -66,6 +66,7 @@
"scripts/render_system_model.py",
"scripts/resource_boundary_check.py",
"scripts/review_studio_formatting.py",
"scripts/review_studio_gates.py",
"scripts/review_studio_layout.py",
"scripts/run_conformance_suite.py",
"scripts/run_description_optimization_suite.py",
@@ -85,6 +86,7 @@
"scripts/verify_package.py",
"scripts/yao.py",
"scripts/yao_cli_config.py",
"scripts/yao_cli_parser.py",
"references/artifact-design-doctrine.md",
"references/authoring-discipline.md",
"references/distribution-registry-method.md",
+9 -2
View File
@@ -11,6 +11,7 @@ SCRIPT = ROOT / "scripts" / "render_review_studio.py"
sys.path.insert(0, str(ROOT / "scripts"))
import render_review_studio as review_studio # noqa: E402
import review_studio_formatting as review_formatting # noqa: E402
import review_studio_gates as review_gates # noqa: E402
import review_studio_layout as review_layout # noqa: E402
@@ -79,9 +80,9 @@ def main() -> None:
"--install-root",
str(tmp_root / "install-root"),
"--output-json",
str(ROOT / "reports" / "install_simulation.json"),
str(tmp_root / "install_simulation.json"),
"--output-md",
str(ROOT / "reports" / "install_simulation.md"),
str(tmp_root / "install_simulation.md"),
"--generated-at",
"2026-06-13",
],
@@ -374,6 +375,12 @@ def main() -> None:
assert "案例数" in formatted, formatted
assert "<code>abc123</code>" in formatted, formatted
assert review_formatting.value_text({"case_count": 5}) == "案例数: 5"
assert review_gates.min_output_cases("scaffold") == 1
assert review_gates.min_output_cases("production") == 3
assert review_gates.min_output_cases("governed") == 5
assert review_gates.status_label("warn") == "关注"
assert review_gates.weighted_score([{"key": "output-lab", "status": "pass"}]) == 100
assert review_gates.weighted_score([{"key": "output-lab", "status": "warn"}]) == 60
assert len(review_layout.REVIEW_STUDIO_NAV) == 15, review_layout.REVIEW_STUDIO_NAV
assert "position: sticky" in review_layout.review_studio_css(), review_layout.review_studio_css()[:400]
assert "#overview" in review_layout.render_review_nav(), review_layout.render_review_nav()
+4
View File
@@ -88,23 +88,27 @@ def main() -> None:
script_map = {item["path"]: item for item in payload["scripts"]}
for internal_module in [
"scripts/review_studio_formatting.py",
"scripts/review_studio_gates.py",
"scripts/review_studio_layout.py",
"scripts/skill_report_charts.py",
"scripts/skill_report_layout.py",
"scripts/skill_report_metrics.py",
"scripts/skill_report_model.py",
"scripts/yao_cli_config.py",
"scripts/yao_cli_parser.py",
]:
assert script_map[internal_module]["interface"] == "internal-module", script_map[internal_module]
assert script_map[internal_module]["interface_declared"], script_map[internal_module]
warning_text = "\n".join(payload["warnings"])
assert "review_studio_formatting.py" not in warning_text, payload["warnings"]
assert "review_studio_gates.py" not in warning_text, payload["warnings"]
assert "review_studio_layout.py" not in warning_text, payload["warnings"]
assert "skill_report_charts.py" not in warning_text, payload["warnings"]
assert "skill_report_layout.py" not in warning_text, payload["warnings"]
assert "skill_report_metrics.py" not in warning_text, payload["warnings"]
assert "skill_report_model.py" not in warning_text, payload["warnings"]
assert "yao_cli_config.py" not in warning_text, payload["warnings"]
assert "yao_cli_parser.py" not in warning_text, payload["warnings"]
assert "render_context_reports.py" not in warning_text, payload["warnings"]
assert "render_social_preview.py" not in warning_text, payload["warnings"]
assert "Network-capable scripts require bounded host policy" not in warning_text, payload["warnings"]
+6
View File
@@ -10,7 +10,9 @@ ROOT = Path(__file__).resolve().parent.parent
CLI = ROOT / "scripts" / "yao.py"
BENCHMARK_FIXTURE_DIR = ROOT / "tests" / "fixtures" / "github_benchmark_scan"
sys.path.insert(0, str(ROOT / "scripts"))
import yao as yao_cli_module # noqa: E402
import yao_cli_config # noqa: E402
import yao_cli_parser # noqa: E402
def run(*args: str, input_text: str | None = None) -> dict:
@@ -43,6 +45,10 @@ def main() -> None:
assert yao_cli_config.infer_archetype("Standardize team review workflow.", "")[0] == "production"
assert yao_cli_config.infer_archetype("Govern release policy.", "")[0] == "governed"
assert "--entry" in yao_cli_config.baseline_compare_args()
assert yao_cli_parser.SCRIPT_INTERFACE == "internal-module"
parser_help = yao_cli_module.build_parser().format_help()
assert "quickstart" in parser_help, parser_help
assert "review-studio" in parser_help, parser_help
init_result = run("init", "cli-demo-skill", "--description", "CLI demo skill.", "--output-dir", str(tmp_root))
assert init_result["ok"], init_result