feat: gate local install sync with preflight
This commit is contained in:
@@ -3,6 +3,7 @@ dist/
|
||||
*.zip
|
||||
__pycache__/
|
||||
tests/tmp/
|
||||
tests/tmp_*/
|
||||
tests/tmp_snapshot/
|
||||
tests/tmp_cli/
|
||||
tests/tmp_skill_overview/
|
||||
@@ -29,3 +30,4 @@ geo-ranking-article-generator/
|
||||
|
||||
# Private or one-off pattern analysis reports should not be committed as factory evidence.
|
||||
reports/*pattern-analysis*.md
|
||||
reports/*research-plan*.md
|
||||
|
||||
@@ -34,7 +34,7 @@ After source changes that affect scripts, package contents, trust evidence, Revi
|
||||
GENERATED_AT="${GENERATED_AT:-$(date +%F)}"
|
||||
python3 scripts/run_output_execution.py --runner-command '["python3","scripts/local_output_eval_runner.py"]'
|
||||
python3 scripts/compile_skill.py . --generated-at "$GENERATED_AT"
|
||||
python3 scripts/cross_packager.py . --platform openai --platform claude --platform generic --expectations evals/packaging_expectations.json --output-dir dist --zip
|
||||
python3 scripts/cross_packager.py . --platform openai --platform claude --platform generic --platform vscode --expectations evals/packaging_expectations.json --output-dir dist --zip
|
||||
python3 scripts/simulate_install.py . --package-dir dist --install-root dist/install-simulation --output-json reports/install_simulation.json --output-md reports/install_simulation.md --generated-at "$GENERATED_AT"
|
||||
python3 scripts/trust_check.py . --output-json reports/security_trust_report.json --output-md reports/security_trust_report.md
|
||||
python3 scripts/registry_audit.py . --generated-at "$GENERATED_AT"
|
||||
@@ -45,7 +45,9 @@ python3 scripts/render_skill_overview.py .
|
||||
python3 scripts/render_review_studio.py . --output-html reports/review-studio.html --output-json reports/review-studio.json
|
||||
```
|
||||
|
||||
Clean test-only scratch directories after verification with `rm -rf tests/tmp_*`. Do not clean unrelated untracked files.
|
||||
Local sync into `~/.agents/skills.disabled/yao-meta-skill` or `~/.agents/skills/yao-meta-skill` must keep the install preflight enabled unless the user explicitly requests a diagnostic bypass. `make sync-local-install` and `make sync-active-install` rebuild the package first, then `scripts/sync_local_install.py` refuses to copy files when install simulation or installer permission enforcement fails.
|
||||
|
||||
Clean test-only scratch directories after verification with `find tests -maxdepth 1 \( -name 'tmp' -o -name 'tmp_*' \) -type d -exec rm -rf {} +`. Do not clean unrelated untracked files.
|
||||
|
||||
## Boundaries
|
||||
|
||||
|
||||
@@ -181,10 +181,10 @@ resource-boundary-check:
|
||||
quality-check:
|
||||
$(PYTHON) tests/verify_quality_checks.py
|
||||
|
||||
sync-local-install:
|
||||
sync-local-install: package-check
|
||||
$(PYTHON) scripts/sync_local_install.py --install-dir "$(LOCAL_SKILL_INSTALL_DIR)"
|
||||
|
||||
sync-active-install:
|
||||
sync-active-install: package-check
|
||||
$(PYTHON) scripts/sync_local_install.py --install-dir "$(ACTIVE_SKILL_INSTALL_DIR)"
|
||||
|
||||
test: eval eval-suite route-scorecard route-confusion-check description-optimization description-optimization-check promotion-check yao-cli-check skill-overview-check skill-report-metrics-check skill-report-charts-check skill-ir-check compiler-check output-eval-check output-execution-check output-review-adjudication-check runtime-conformance-check runtime-permission-check trust-check skill-atlas-check registry-audit-check package-verify-check install-simulation-check upgrade-check review-viewer-check review-studio-check feedback-check adoption-drift-check review-waivers-check review-annotations-check baseline-compare-check reference-scan-check github-benchmark-scan-check intent-confidence-check reference-synthesis-check output-risk-profile-check artifact-design-profile-check prompt-quality-profile-check system-model-check iteration-directions-check description-drift-history iteration-ledger regression-history context-reports portability-report portability-check failure-regression-check package-check package-failure-check security-boundary-check local-install-sync-check snapshot-check validate lint governance-check resource-boundary-check quality-check
|
||||
|
||||
@@ -141,7 +141,7 @@ Sync the current source into the disabled mirror:
|
||||
make sync-local-install
|
||||
```
|
||||
|
||||
The sync command copies Git-tracked files plus new source files in code and guidance directories such as `scripts/`, `tests/`, `references/`, and `docs/`. It skips untracked business-skill folders and untracked private reports by default, so local experiments do not leak into the mirror.
|
||||
The sync command first rebuilds the package and runs install preflight against `dist/yao-meta-skill.zip`. It refuses to sync when package extraction, adapter readability, or installer permission enforcement fails. After the preflight passes, it copies Git-tracked files plus new source files in code and guidance directories such as `scripts/`, `tests/`, `references/`, and `docs/`. It skips untracked business-skill folders and untracked private reports by default, so local experiments do not leak into the mirror.
|
||||
|
||||
Restore an active global Codex install only when you intentionally want this skill discoverable outside the development workspace:
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@ Do not claim archive readiness when package verification reports unsafe zip path
|
||||
|
||||
Do not claim install readiness when install simulation cannot extract the archive into a temporary skill root, load `SKILL.md` frontmatter, read `manifest.json`, read `agents/interface.yaml`, find the overview and Review Studio reports, or load each generated adapter.
|
||||
|
||||
Do not sync a local or active install from source until the same package has passed install preflight. `scripts/sync_local_install.py` must run install simulation against the configured package directory and fail before copying files when any target/capability pair lacks active permission approval or target-specific enforcement evidence. Use `--skip-install-preflight` only for isolated diagnostics, not for release or active install.
|
||||
|
||||
Do not include raw `reports/telemetry_events.jsonl` in a distributed package. Include only aggregate adoption drift reports, and block release review when telemetry contains raw prompts, outputs, transcripts, notes, or messages.
|
||||
|
||||
Review waiver evidence may be distributed as `reports/review_waivers.md/json` because it is metadata-only reviewer accountability. Do not store raw prompts, outputs, transcripts, credentials, or private customer detail in waiver reasons.
|
||||
@@ -53,5 +55,6 @@ A reviewer should be able to answer:
|
||||
5. Which reports prove trust and runtime readiness?
|
||||
6. Was the installable archive verified, and which checksum identifies it?
|
||||
7. Was the archive install-simulated in a temporary local skill root?
|
||||
8. What changed since the previous package, and does the declared version bump match the recommended bump?
|
||||
9. Are adoption and drift signals summarized without packaging raw local telemetry?
|
||||
8. Did local or active install sync preserve that preflight and installer permission gate?
|
||||
9. What changed since the previous package, and does the declared version bump match the recommended bump?
|
||||
10. Are adoption and drift signals summarized without packaging raw local telemetry?
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
"vscode"
|
||||
],
|
||||
"package_metadata": "registry/packages/yao-meta-skill.json",
|
||||
"package_sha256": "69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682"
|
||||
"package_sha256": "44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
"trust_level": "local",
|
||||
"license": "MIT",
|
||||
"checksums": {
|
||||
"package_sha256": "69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682",
|
||||
"archive_sha256": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706"
|
||||
"package_sha256": "44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd",
|
||||
"archive_sha256": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933"
|
||||
},
|
||||
"compatibility": {
|
||||
"openai": "pass",
|
||||
@@ -48,7 +48,7 @@
|
||||
},
|
||||
"distribution": {
|
||||
"archive_verified": true,
|
||||
"archive_sha256": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706",
|
||||
"archive_sha256": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933",
|
||||
"package_verification": "reports/package_verification.json",
|
||||
"install_simulated": true,
|
||||
"install_simulation": "reports/install_simulation.json"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"ok": true,
|
||||
"schema_version": "2.0",
|
||||
"generated_at": "2026-06-13T12:26:25Z",
|
||||
"generated_at": "2026-06-13T13:13:24Z",
|
||||
"skill_dir": ".",
|
||||
"privacy_contract": {
|
||||
"storage": "local-first",
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
"context_budget_tier": "production",
|
||||
"context_budget_limit": 1000,
|
||||
"skill_body_tokens": 751,
|
||||
"other_text_tokens": 911753,
|
||||
"other_text_tokens": 915033,
|
||||
"estimated_initial_load_tokens": 944,
|
||||
"estimated_total_text_tokens": 912504,
|
||||
"relevant_file_count": 390,
|
||||
"estimated_total_text_tokens": 915784,
|
||||
"relevant_file_count": 392,
|
||||
"unused_resource_dirs": [],
|
||||
"quality_signal_points": 130,
|
||||
"quality_density": 137.7
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 32.77,
|
||||
"duration_ms": 33.6,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -62,7 +62,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 33.31,
|
||||
"duration_ms": 33.9,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -85,7 +85,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 32.68,
|
||||
"duration_ms": 37.17,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -113,7 +113,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 32.86,
|
||||
"duration_ms": 49.26,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -136,7 +136,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 33.15,
|
||||
"duration_ms": 32.41,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -164,7 +164,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 32.95,
|
||||
"duration_ms": 33.26,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -187,7 +187,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 33.5,
|
||||
"duration_ms": 33.85,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -214,7 +214,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 33.13,
|
||||
"duration_ms": 34.38,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -237,7 +237,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 33.0,
|
||||
"duration_ms": 34.12,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -266,7 +266,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 31.88,
|
||||
"duration_ms": 34.95,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
|
||||
@@ -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 | 32.77 | 33 | 0.0 | pass |
|
||||
| skill-package-contract | with_skill | command | local-output-eval-runner | 33.31 | 73 | 100.0 | pass |
|
||||
| output-eval-expectation | baseline | command | local-output-eval-runner | 32.68 | 36 | 0.0 | pass |
|
||||
| output-eval-expectation | with_skill | command | local-output-eval-runner | 32.86 | 80 | 100.0 | pass |
|
||||
| ir-before-packaging | baseline | command | local-output-eval-runner | 33.15 | 33 | 0.0 | pass |
|
||||
| ir-before-packaging | with_skill | command | local-output-eval-runner | 32.95 | 80 | 100.0 | pass |
|
||||
| near-neighbor-boundary | baseline | command | local-output-eval-runner | 33.5 | 36 | 0.0 | pass |
|
||||
| near-neighbor-boundary | with_skill | command | local-output-eval-runner | 33.13 | 65 | 100.0 | pass |
|
||||
| file-backed-governed-package | baseline | command | local-output-eval-runner | 33.0 | 37 | 0.0 | pass |
|
||||
| file-backed-governed-package | with_skill | command | local-output-eval-runner | 31.88 | 98 | 100.0 | pass |
|
||||
| skill-package-contract | baseline | command | local-output-eval-runner | 33.6 | 33 | 0.0 | pass |
|
||||
| skill-package-contract | with_skill | command | local-output-eval-runner | 33.9 | 73 | 100.0 | pass |
|
||||
| output-eval-expectation | baseline | command | local-output-eval-runner | 37.17 | 36 | 0.0 | pass |
|
||||
| output-eval-expectation | with_skill | command | local-output-eval-runner | 49.26 | 80 | 100.0 | pass |
|
||||
| ir-before-packaging | baseline | command | local-output-eval-runner | 32.41 | 33 | 0.0 | pass |
|
||||
| ir-before-packaging | with_skill | command | local-output-eval-runner | 33.26 | 80 | 100.0 | pass |
|
||||
| near-neighbor-boundary | baseline | command | local-output-eval-runner | 33.85 | 36 | 0.0 | pass |
|
||||
| near-neighbor-boundary | with_skill | command | local-output-eval-runner | 34.38 | 65 | 100.0 | pass |
|
||||
| file-backed-governed-package | baseline | command | local-output-eval-runner | 34.12 | 37 | 0.0 | pass |
|
||||
| file-backed-governed-package | with_skill | command | local-output-eval-runner | 34.95 | 98 | 100.0 | pass |
|
||||
|
||||
## Next Fixes
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"target_count": 4,
|
||||
"adapter_count": 4,
|
||||
"archive_present": true,
|
||||
"archive_sha256": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706",
|
||||
"archive_sha256": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933",
|
||||
"archive_entry_count": 494,
|
||||
"failure_count": 0,
|
||||
"warning_count": 0
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
- Package directory: `dist`
|
||||
- Targets: `4 / 4` adapters present
|
||||
- Archive present: `True`
|
||||
- Archive SHA256: `2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706`
|
||||
- Archive SHA256: `cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933`
|
||||
- Failures: `0`
|
||||
- Warnings: `0`
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
"trust_level": "local",
|
||||
"license": "MIT",
|
||||
"checksums": {
|
||||
"package_sha256": "69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682",
|
||||
"archive_sha256": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706"
|
||||
"package_sha256": "44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd",
|
||||
"archive_sha256": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933"
|
||||
},
|
||||
"compatibility": {
|
||||
"openai": "pass",
|
||||
@@ -53,7 +53,7 @@
|
||||
},
|
||||
"distribution": {
|
||||
"archive_verified": true,
|
||||
"archive_sha256": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706",
|
||||
"archive_sha256": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933",
|
||||
"package_verification": "reports/package_verification.json",
|
||||
"install_simulated": true,
|
||||
"install_simulation": "reports/install_simulation.json"
|
||||
@@ -78,7 +78,7 @@
|
||||
"vscode"
|
||||
],
|
||||
"package_metadata": "registry/packages/yao-meta-skill.json",
|
||||
"package_sha256": "69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682"
|
||||
"package_sha256": "44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
- Maturity: `governed`
|
||||
- Owner: `Yao Team`
|
||||
- License: `MIT`
|
||||
- Package SHA256: `69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682`
|
||||
- Archive SHA256: `2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706`
|
||||
- Package SHA256: `44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd`
|
||||
- Archive SHA256: `cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933`
|
||||
- Install simulated: `True`
|
||||
|
||||
## Compatibility
|
||||
|
||||
@@ -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>69</dd></div><div><dt>网络脚本</dt><dd>3</dd></div><div><dt>Help 失败</dt><dd>0</dd></div><div><dt>包体哈希</dt><dd><code>69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682</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>69</dd></div><div><dt>网络脚本</dt><dd>3</dd></div><div><dt>Help 失败</dt><dd>0</dd></div><div><dt>包体哈希</dt><dd><code>44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd</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 4 adapters; installer permissions 12 enforced / 0 failures</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, vscode</dd></div><div><dt>兼容通过</dt><dd>6/6</dd></div><div><dt>归档哈希</dt><dd><code>2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706</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, vscode</dd></div><div><dt>兼容通过</dt><dd>6/6</dd></div><div><dt>归档哈希</dt><dd><code>cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933</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>4</dd></div><div><dt>Adapter</dt><dd>4</dd></div><div><dt>归档存在</dt><dd>是</dd></div><div><dt>Zip 条目</dt><dd>494</dd></div><div><dt>失败数</dt><dd>0</dd></div><div><dt>警告数</dt><dd>0</dd></div><div><dt>归档哈希</dt><dd><code>2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706</code></dd></div></dl></div>
|
||||
<div class="panel"><h2>包体验证</h2><dl class='kv-grid'><div><dt>目标数</dt><dd>4</dd></div><div><dt>Adapter</dt><dd>4</dd></div><div><dt>归档存在</dt><dd>是</dd></div><div><dt>Zip 条目</dt><dd>494</dd></div><div><dt>失败数</dt><dd>0</dd></div><div><dt>警告数</dt><dd>0</dd></div><div><dt>归档哈希</dt><dd><code>cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933</code></dd></div></dl></div>
|
||||
</section>
|
||||
|
||||
<section class="twocol">
|
||||
|
||||
+32
-32
@@ -355,7 +355,7 @@
|
||||
"label": "上下文成本",
|
||||
"score": 42,
|
||||
"reasons": [
|
||||
"入口约 350 个词/字,references 约 14640 个词/字。",
|
||||
"入口约 350 个词/字,references 约 14711 个词/字。",
|
||||
"分数越高代表上下文成本越低。",
|
||||
"上下文成本偏高,建议压缩入口或拆分 references。"
|
||||
]
|
||||
@@ -459,7 +459,7 @@
|
||||
"已生成 Output Review Adjudication,可记录盲评决策、一致率和待评审项。"
|
||||
],
|
||||
"gaps": [
|
||||
"上下文成本需要补强:入口约 350 个词/字,references 约 14640 个词/字。"
|
||||
"上下文成本需要补强:入口约 350 个词/字,references 约 14711 个词/字。"
|
||||
],
|
||||
"recommendations": [
|
||||
"先改触发边界,再扩展工作流。",
|
||||
@@ -1228,7 +1228,7 @@
|
||||
"interactive_script_count": 0,
|
||||
"package_hash_scope": "source-contract-without-generated-reports",
|
||||
"package_hash_file_count": 153,
|
||||
"package_sha256": "69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682"
|
||||
"package_sha256": "44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd"
|
||||
},
|
||||
"skill_atlas": {
|
||||
"skill_count": 12,
|
||||
@@ -1266,8 +1266,8 @@
|
||||
"trust_level": "local",
|
||||
"license": "MIT",
|
||||
"checksums": {
|
||||
"package_sha256": "69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682",
|
||||
"archive_sha256": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706"
|
||||
"package_sha256": "44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd",
|
||||
"archive_sha256": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933"
|
||||
},
|
||||
"compatibility": {
|
||||
"openai": "pass",
|
||||
@@ -1298,7 +1298,7 @@
|
||||
},
|
||||
"distribution": {
|
||||
"archive_verified": true,
|
||||
"archive_sha256": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706",
|
||||
"archive_sha256": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933",
|
||||
"package_verification": "reports/package_verification.json",
|
||||
"install_simulated": true,
|
||||
"install_simulation": "reports/install_simulation.json"
|
||||
@@ -1314,7 +1314,7 @@
|
||||
"target_count": 4,
|
||||
"adapter_count": 4,
|
||||
"archive_present": true,
|
||||
"archive_sha256": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706",
|
||||
"archive_sha256": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933",
|
||||
"archive_entry_count": 494,
|
||||
"failure_count": 0,
|
||||
"warning_count": 0
|
||||
@@ -1393,12 +1393,12 @@
|
||||
{
|
||||
"field": "archive_sha256",
|
||||
"from": "",
|
||||
"to": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706"
|
||||
"to": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933"
|
||||
},
|
||||
{
|
||||
"field": "package_sha256",
|
||||
"from": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"to": "69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682"
|
||||
"to": "44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -3128,7 +3128,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 32.77,
|
||||
"duration_ms": 33.6,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -3156,7 +3156,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 33.31,
|
||||
"duration_ms": 33.9,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -3179,7 +3179,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 32.68,
|
||||
"duration_ms": 37.17,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -3207,7 +3207,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 32.86,
|
||||
"duration_ms": 49.26,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -3230,7 +3230,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 33.15,
|
||||
"duration_ms": 32.41,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -3258,7 +3258,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 32.95,
|
||||
"duration_ms": 33.26,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -3281,7 +3281,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 33.5,
|
||||
"duration_ms": 33.85,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -3308,7 +3308,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 33.13,
|
||||
"duration_ms": 34.38,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -3331,7 +3331,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 33.0,
|
||||
"duration_ms": 34.12,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -3360,7 +3360,7 @@
|
||||
"execution_mode": "command",
|
||||
"model_executed": false,
|
||||
"command_executed": true,
|
||||
"duration_ms": 31.88,
|
||||
"duration_ms": 34.95,
|
||||
"provider": "local-output-eval-runner",
|
||||
"model": "",
|
||||
"usage": {
|
||||
@@ -8228,7 +8228,7 @@
|
||||
"interactive_script_count": 0,
|
||||
"package_hash_scope": "source-contract-without-generated-reports",
|
||||
"package_hash_file_count": 153,
|
||||
"package_sha256": "69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682"
|
||||
"package_sha256": "44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd"
|
||||
},
|
||||
"failures": [],
|
||||
"warnings": [],
|
||||
@@ -9792,7 +9792,7 @@
|
||||
"timed_out": false,
|
||||
"passed": true,
|
||||
"has_help_text": true,
|
||||
"stdout_excerpt": "usage: sync_local_install.py [-h] [--root ROOT] [--install-dir INSTALL_DIR]\n [--dry-run]\n\nSync the current yao-meta-skill source into a managed local skill mirror.\n\noptions:\n -h, --help show this help",
|
||||
"stdout_excerpt": "usage: sync_local_install.py [-h] [--root ROOT] [--install-dir INSTALL_DIR]\n [--package-dir PACKAGE_DIR]\n [--generated-at GENERATED_AT]\n [--skip-install-pre",
|
||||
"stderr_excerpt": ""
|
||||
},
|
||||
{
|
||||
@@ -10060,10 +10060,10 @@
|
||||
"context_budget_tier": "production",
|
||||
"context_budget_limit": 1000,
|
||||
"skill_body_tokens": 751,
|
||||
"other_text_tokens": 911753,
|
||||
"other_text_tokens": 915033,
|
||||
"estimated_initial_load_tokens": 944,
|
||||
"estimated_total_text_tokens": 912504,
|
||||
"relevant_file_count": 390,
|
||||
"estimated_total_text_tokens": 915784,
|
||||
"relevant_file_count": 392,
|
||||
"unused_resource_dirs": [],
|
||||
"quality_signal_points": 130,
|
||||
"quality_density": 137.7
|
||||
@@ -11891,7 +11891,7 @@
|
||||
"adoption_drift": {
|
||||
"ok": true,
|
||||
"schema_version": "2.0",
|
||||
"generated_at": "2026-06-13T12:56:47Z",
|
||||
"generated_at": "2026-06-13T13:13:24Z",
|
||||
"skill_dir": ".",
|
||||
"privacy_contract": {
|
||||
"storage": "local-first",
|
||||
@@ -12053,8 +12053,8 @@
|
||||
"trust_level": "local",
|
||||
"license": "MIT",
|
||||
"checksums": {
|
||||
"package_sha256": "69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682",
|
||||
"archive_sha256": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706"
|
||||
"package_sha256": "44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd",
|
||||
"archive_sha256": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933"
|
||||
},
|
||||
"compatibility": {
|
||||
"openai": "pass",
|
||||
@@ -12085,7 +12085,7 @@
|
||||
},
|
||||
"distribution": {
|
||||
"archive_verified": true,
|
||||
"archive_sha256": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706",
|
||||
"archive_sha256": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933",
|
||||
"package_verification": "reports/package_verification.json",
|
||||
"install_simulated": true,
|
||||
"install_simulation": "reports/install_simulation.json"
|
||||
@@ -12110,7 +12110,7 @@
|
||||
"vscode"
|
||||
],
|
||||
"package_metadata": "registry/packages/yao-meta-skill.json",
|
||||
"package_sha256": "69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682"
|
||||
"package_sha256": "44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -12133,7 +12133,7 @@
|
||||
"target_count": 4,
|
||||
"adapter_count": 4,
|
||||
"archive_present": true,
|
||||
"archive_sha256": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706",
|
||||
"archive_sha256": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933",
|
||||
"archive_entry_count": 494,
|
||||
"failure_count": 0,
|
||||
"warning_count": 0
|
||||
@@ -13141,12 +13141,12 @@
|
||||
{
|
||||
"field": "archive_sha256",
|
||||
"from": "",
|
||||
"to": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706"
|
||||
"to": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933"
|
||||
},
|
||||
{
|
||||
"field": "package_sha256",
|
||||
"from": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"to": "69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682"
|
||||
"to": "44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"interactive_script_count": 0,
|
||||
"package_hash_scope": "source-contract-without-generated-reports",
|
||||
"package_hash_file_count": 153,
|
||||
"package_sha256": "69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682"
|
||||
"package_sha256": "44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd"
|
||||
},
|
||||
"failures": [],
|
||||
"warnings": [],
|
||||
@@ -1587,7 +1587,7 @@
|
||||
"timed_out": false,
|
||||
"passed": true,
|
||||
"has_help_text": true,
|
||||
"stdout_excerpt": "usage: sync_local_install.py [-h] [--root ROOT] [--install-dir INSTALL_DIR]\n [--dry-run]\n\nSync the current yao-meta-skill source into a managed local skill mirror.\n\noptions:\n -h, --help show this help",
|
||||
"stdout_excerpt": "usage: sync_local_install.py [-h] [--root ROOT] [--install-dir INSTALL_DIR]\n [--package-dir PACKAGE_DIR]\n [--generated-at GENERATED_AT]\n [--skip-install-pre",
|
||||
"stderr_excerpt": ""
|
||||
},
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
- Interactive scripts: `0`
|
||||
- Package hash scope: `source-contract-without-generated-reports`
|
||||
- Package hash files: `153`
|
||||
- Package SHA256: `69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682`
|
||||
- Package SHA256: `44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd`
|
||||
|
||||
## Failures
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ Yao Meta Skill is no longer only a Meta Skill factory. The current working tree
|
||||
- Review Waivers v0 for human warning acceptance with reviewer, reason, scope, expiry, and blocker-safe policy.
|
||||
- Governed Permission Gates v0 for reviewer-approved network, file-write, and subprocess capabilities with scope, reason, expiry, evidence, and target-enforcement mapping.
|
||||
- Runtime Permission Probes v0 for packaged target adapter checks, explicit native-enforcement flags, metadata fallback evidence, and residual permission risks.
|
||||
- Local Install Sync Preflight v0 so source-to-local and source-to-active install syncs rebuild the package first, run install simulation, enforce installer permission coverage, and refuse to copy files before any destructive sync when the package is not install-ready.
|
||||
- Atlas Scope Policy v0 so examples, evolution snapshots, embedded generated skills, and validator fixtures remain visible in the full portfolio report without polluting release-actionable gates.
|
||||
- Review Annotations v0 for reviewer comments tied to Review Studio gates, source/report paths, and optional line numbers; open blocker annotations now block the Review Studio decision.
|
||||
- Review Studio now avoids over-claiming release readiness when blind A/B adjudication is still pending: the root Meta Skill is in `review` with score `92`, no blockers, two warnings, and explicit actions for Output Lab reviewer adjudication plus waiver handling.
|
||||
@@ -32,7 +33,7 @@ Yao Meta Skill is no longer only a Meta Skill factory. The current working tree
|
||||
- Output Review Adjudication now preserves blind-review integrity by hiding expected winners for pending or invalid reviewer decisions; answer keys are revealed only after a valid A/B decision exists for that case.
|
||||
- Provider Output Eval Runner v0 so `python3 scripts/yao.py output-exec --provider-runner openai` can collect real provider-backed model evidence through a reviewed OpenAI Responses API compatible runner instead of ad hoc shell glue.
|
||||
|
||||
This is still not the final world-class state. Target-native behavior contracts are now explicit, VS Code / Copilot package metadata is auditable, local output-eval command execution is wired, blind-review answers remain hidden until valid decisions exist, a provider-backed output runner exists, installer-level permission coverage is now locally enforced during install simulation, and Skill Atlas now consumes aggregate drift reports. Review Studio keeps pending human adjudication visible as a warning instead of treating it as a clean pass. Deeper provider-native execution transforms, real client telemetry capture, real installer integration, real provider holdout runs, real human adjudication decisions, and native runtime permission enforcement remain open.
|
||||
This is still not the final world-class state. Target-native behavior contracts are now explicit, VS Code / Copilot package metadata is auditable, local output-eval command execution is wired, blind-review answers remain hidden until valid decisions exist, a provider-backed output runner exists, installer-level permission coverage is now locally enforced during install simulation and local install sync, and Skill Atlas now consumes aggregate drift reports. Review Studio keeps pending human adjudication visible as a warning instead of treating it as a clean pass. Deeper provider-native execution transforms, real client telemetry capture, provider-native installer integration, real provider holdout runs, real human adjudication decisions, and native runtime permission enforcement remain open.
|
||||
|
||||
## Coverage Matrix
|
||||
|
||||
@@ -51,6 +52,7 @@ This is still not the final world-class state. Target-native behavior contracts
|
||||
| Registry & Distribution | `registry/*.schema.json`, `scripts/registry_audit.py`, `reports/registry_audit.md`, `registry/packages/yao-meta-skill.json` | v0 landed |
|
||||
| Package Verification | `scripts/verify_package.py`, `reports/package_verification.md`, `tests/verify_package_verification.py` | v0 landed |
|
||||
| Install Simulation | `scripts/simulate_install.py`, `reports/install_simulation.md`, `tests/verify_install_simulation.py` with installer permission coverage checks | v0 landed |
|
||||
| Local Install Sync Preflight | `scripts/sync_local_install.py`, `tests/verify_local_install_sync.py`, `Makefile` package-check prerequisites | v0 landed |
|
||||
| Upgrade Check | `scripts/upgrade_check.py`, `reports/upgrade_check.md`, `tests/verify_upgrade_check.py` | v0 landed |
|
||||
| Telemetry & Drift | `scripts/render_adoption_drift_report.py`, `reports/adoption_drift_report.md`, `tests/verify_adoption_drift.py`, `references/telemetry-drift-method.md` | v0 landed |
|
||||
| Review Waivers | `scripts/render_review_waivers.py`, `reports/review_waivers.md`, `tests/verify_review_waivers.py`, `references/review-waiver-method.md` | v0 landed |
|
||||
@@ -88,7 +90,7 @@ Next move: connect client activations and failure history so Atlas can rank stal
|
||||
|
||||
### 5. Trust report is structural, not full security review
|
||||
|
||||
Trust v0 blocks obvious secrets and remote inline execution, and now makes checksum scope explicit: `package_sha256` is a stable source-contract digest that excludes generated reports, packages, and raw local telemetry; archive integrity is carried by Package Verification and Registry as `archive_sha256`. Registry v0 carries both checksums into distributable metadata. Package Verification v0 now checks generated manifests, target adapters, archive path safety, required source entries, and registry parity. Install Simulation v0 now extracts the generated archive into a temporary local skill root, verifies entrypoint, manifest, interface, reports, and adapters, then checks every packaged target/capability pair against the installed `security/permission_policy.json` approval and `target_enforcement` mapping. Upgrade Check v0 now compares package baselines, recommends semver bumps, and blocks breaking changes without an adequate declared version. Trust Report now distinguishes CLI scripts from declared internal modules, so help-surface warnings focus on executable entrypoints. Network-capable scripts are now covered by `security/network_policy.json`, with `allowed_hosts` checked against HTTPS URL literals. Trust Report also executes `python3 scripts/name.py --help` for CLI scripts with `argparse`, recording pass/fail smoke evidence without executing scripts that lack a help surface. Target adapters now carry `permission_contract` and `target_permission_contract` fields, including network, file-write, subprocess, and interactive capability counts. Governed permission gates now require reviewer-approved scope, reason, expiry, evidence, and target-enforcement mapping in `security/permission_policy.json`. Runtime Permission Probes now verify that packaged adapters expose the target permission contract and explicitly report native-enforcement limits. The remaining trust gap is native runtime permission enforcement in real clients/installers.
|
||||
Trust v0 blocks obvious secrets and remote inline execution, and now makes checksum scope explicit: `package_sha256` is a stable source-contract digest that excludes generated reports, packages, and raw local telemetry; archive integrity is carried by Package Verification and Registry as `archive_sha256`. Registry v0 carries both checksums into distributable metadata. Package Verification v0 now checks generated manifests, target adapters, archive path safety, required source entries, and registry parity. Install Simulation v0 now extracts the generated archive into a temporary local skill root, verifies entrypoint, manifest, interface, reports, and adapters, then checks every packaged target/capability pair against the installed `security/permission_policy.json` approval and `target_enforcement` mapping. Local Install Sync Preflight now runs the same install simulation before syncing source into the disabled or active local install path, so a broken package or permission enforcement gap fails before stale files are removed or new files are copied. Upgrade Check v0 now compares package baselines, recommends semver bumps, and blocks breaking changes without an adequate declared version. Trust Report now distinguishes CLI scripts from declared internal modules, so help-surface warnings focus on executable entrypoints. Network-capable scripts are now covered by `security/network_policy.json`, with `allowed_hosts` checked against HTTPS URL literals. Trust Report also executes `python3 scripts/name.py --help` for CLI scripts with `argparse`, recording pass/fail smoke evidence without executing scripts that lack a help surface. Target adapters now carry `permission_contract` and `target_permission_contract` fields, including network, file-write, subprocess, and interactive capability counts. Governed permission gates now require reviewer-approved scope, reason, expiry, evidence, and target-enforcement mapping in `security/permission_policy.json`. Runtime Permission Probes now verify that packaged adapters expose the target permission contract and explicitly report native-enforcement limits. The remaining trust gap is native runtime permission enforcement in real clients/installers.
|
||||
|
||||
Next move: add real client or installer permission enforcement integration.
|
||||
|
||||
@@ -106,6 +108,7 @@ Next move: add real client or installer permission enforcement integration.
|
||||
| Registry Audit | package metadata generated with version, owner, license, source checksum, archive checksum, Skill IR provenance, and compatibility matrix |
|
||||
| Package Verification | `4 / 4` target adapters present, archive verified, `494` zip entries, `0` failures, `0` warnings |
|
||||
| Install Simulation | archive with `494` entries extracted into a local verification root, entrypoint/manifest/interface loaded, reports present, `4` adapters readable, `12` installer permission checks enforced, `0` permission failures, `0` failures, `0` warnings |
|
||||
| Local Install Sync Preflight | `make sync-local-install` and `make sync-active-install` rebuild the package first, then sync only after install simulation passes with `12` enforced installer permission checks and `0` permission failures |
|
||||
| Upgrade Check | current package declares `minor` over the 1.0.0 baseline, recommended bump is `minor`, and release notes include added targets plus checksum changes |
|
||||
| Adoption Drift | `1` metadata-only review event, `0` adoption samples, adoption `0`, risk band `low`; raw `reports/telemetry_events.jsonl` is gitignored and blocked from zip packages |
|
||||
| Review Waivers | ledger generated; current release has `1` warning gate that still needs reviewer decision or a time-bounded waiver; blockers remain non-waivable in v0 |
|
||||
@@ -117,8 +120,8 @@ Next move: add real client or installer permission enforcement integration.
|
||||
|
||||
## Next Highest-Leverage Moves
|
||||
|
||||
1. Deepen target-native behavior contracts into provider-native execution and installer integrations.
|
||||
2. Add native client or installer enforcement for approved high-permission capabilities.
|
||||
1. Deepen target-native behavior contracts into provider-native execution and provider-native installer integrations.
|
||||
2. Add native client or installer runtime enforcement for approved high-permission capabilities.
|
||||
3. Run the new provider-backed output runner against holdout cases with real credentials, then record the current blind A/B decisions before claiming fully ready status.
|
||||
4. Add real reviewer annotation records during the next human review pass.
|
||||
5. Connect real client telemetry capture and failure history so Atlas drift signals are based on live usage, not manual samples.
|
||||
|
||||
@@ -609,7 +609,7 @@
|
||||
<ul class="list"><li><span data-lang="zh-CN">把一次性经验沉淀为可复用、可评估、可迁移的 Skill 包体。</span><span data-lang="en">把一次性经验沉淀为可复用、可评估、可迁移的 Skill 包体。</span></li><li><span data-lang="zh-CN">Skill 作者、复用团队和后续 reviewer。</span><span data-lang="en">Skill 作者、复用团队和后续 reviewer。</span></li><li><span data-lang="zh-CN">创建完成后建议先打开 reports/skill-overview.html,再继续扩展包体。</span><span data-lang="en">创建完成后建议先打开 reports/skill-overview.html,再继续扩展包体。</span></li></ul>
|
||||
</aside>
|
||||
</div>
|
||||
<div class="score-strip" aria-label="报告关键指标"><article class='score-chip'><span>完整度</span><strong>100</strong><i style='--score:100%'></i><small><span data-lang="zh-CN">SKILL.md 已存在,是 Skill 的入口。</span><span data-lang="en">SKILL.md 已存在,是 Skill 的入口。</span></small></article><article class='score-chip'><span>触发清晰</span><strong>100</strong><i style='--score:100%'></i><small><span data-lang="zh-CN">frontmatter description 已存在,具备基础路由面。</span><span data-lang="en">frontmatter description 已存在,具备基础路由面。</span></small></article><article class='score-chip'><span>证据充分</span><strong>100</strong><i style='--score:100%'></i><small><span data-lang="zh-CN">已生成 20 / 20 类报告证据。</span><span data-lang="en">已生成 20 / 20 类报告证据。</span></small></article><article class='score-chip'><span>上下文成本</span><strong>42</strong><i style='--score:42%'></i><small><span data-lang="zh-CN">入口约 350 个词/字,references 约 14640 个词/字。</span><span data-lang="en">入口约 350 个词/字,references 约 14640 个词/字。</span></small></article></div>
|
||||
<div class="score-strip" aria-label="报告关键指标"><article class='score-chip'><span>完整度</span><strong>100</strong><i style='--score:100%'></i><small><span data-lang="zh-CN">SKILL.md 已存在,是 Skill 的入口。</span><span data-lang="en">SKILL.md 已存在,是 Skill 的入口。</span></small></article><article class='score-chip'><span>触发清晰</span><strong>100</strong><i style='--score:100%'></i><small><span data-lang="zh-CN">frontmatter description 已存在,具备基础路由面。</span><span data-lang="en">frontmatter description 已存在,具备基础路由面。</span></small></article><article class='score-chip'><span>证据充分</span><strong>100</strong><i style='--score:100%'></i><small><span data-lang="zh-CN">已生成 20 / 20 类报告证据。</span><span data-lang="en">已生成 20 / 20 类报告证据。</span></small></article><article class='score-chip'><span>上下文成本</span><strong>42</strong><i style='--score:42%'></i><small><span data-lang="zh-CN">入口约 350 个词/字,references 约 14711 个词/字。</span><span data-lang="en">入口约 350 个词/字,references 约 14711 个词/字。</span></small></article></div>
|
||||
</section>
|
||||
|
||||
<section id="overview">
|
||||
@@ -641,10 +641,10 @@
|
||||
<article class="panel metrics-note">
|
||||
<h3><span data-lang="zh-CN">指标判读</span><span data-lang="en">Reading</span></h3>
|
||||
<p><span data-lang="zh-CN">先看雷达图判断能力短板,再看下方每项分数的证据原因。分数不是装饰数字,必须和本地文件、reports 证据或证据不足提示对应。</span><span data-lang="en">Read the radar first for weak spots, then inspect each score with its evidence. Scores must map to local files, reports, or explicit evidence gaps.</span></p>
|
||||
<ol class='metric-summary-list'><li><span class='metric-status'><span data-lang="zh-CN">稳定</span><span data-lang="en">Stable</span></span><b>完整度</b><em>100</em><small><span data-lang="zh-CN">SKILL.md 已存在,是 Skill 的入口。</span><span data-lang="en">SKILL.md 已存在,是 Skill 的入口。</span></small></li><li><span class='metric-status'><span data-lang="zh-CN">稳定</span><span data-lang="en">Stable</span></span><b>触发清晰</b><em>100</em><small><span data-lang="zh-CN">frontmatter description 已存在,具备基础路由面。</span><span data-lang="en">frontmatter description 已存在,具备基础路由面。</span></small></li><li><span class='metric-status'><span data-lang="zh-CN">稳定</span><span data-lang="en">Stable</span></span><b>证据充分</b><em>100</em><small><span data-lang="zh-CN">已生成 20 / 20 类报告证据。</span><span data-lang="en">已生成 20 / 20 类报告证据。</span></small></li><li><span class='metric-status'><span data-lang="zh-CN">稳定</span><span data-lang="en">Stable</span></span><b>可维护性</b><em>100</em><small><span data-lang="zh-CN">SKILL.md 约 350 个词/字。</span><span data-lang="en">SKILL.md 约 350 个词/字。</span></small></li><li><span class='metric-status'><span data-lang="zh-CN">稳定</span><span data-lang="en">Stable</span></span><b>可迁移性</b><em>100</em><small><span data-lang="zh-CN">agents/interface.yaml 已存在。</span><span data-lang="en">agents/interface.yaml 已存在。</span></small></li><li><span class='metric-status'><span data-lang="zh-CN">关注</span><span data-lang="en">Watch</span></span><b>上下文成本</b><em>42</em><small><span data-lang="zh-CN">入口约 350 个词/字,references 约 14640 个词/字。</span><span data-lang="en">入口约 350 个词/字,references 约 14640 个词/字。</span></small></li></ol>
|
||||
<ol class='metric-summary-list'><li><span class='metric-status'><span data-lang="zh-CN">稳定</span><span data-lang="en">Stable</span></span><b>完整度</b><em>100</em><small><span data-lang="zh-CN">SKILL.md 已存在,是 Skill 的入口。</span><span data-lang="en">SKILL.md 已存在,是 Skill 的入口。</span></small></li><li><span class='metric-status'><span data-lang="zh-CN">稳定</span><span data-lang="en">Stable</span></span><b>触发清晰</b><em>100</em><small><span data-lang="zh-CN">frontmatter description 已存在,具备基础路由面。</span><span data-lang="en">frontmatter description 已存在,具备基础路由面。</span></small></li><li><span class='metric-status'><span data-lang="zh-CN">稳定</span><span data-lang="en">Stable</span></span><b>证据充分</b><em>100</em><small><span data-lang="zh-CN">已生成 20 / 20 类报告证据。</span><span data-lang="en">已生成 20 / 20 类报告证据。</span></small></li><li><span class='metric-status'><span data-lang="zh-CN">稳定</span><span data-lang="en">Stable</span></span><b>可维护性</b><em>100</em><small><span data-lang="zh-CN">SKILL.md 约 350 个词/字。</span><span data-lang="en">SKILL.md 约 350 个词/字。</span></small></li><li><span class='metric-status'><span data-lang="zh-CN">稳定</span><span data-lang="en">Stable</span></span><b>可迁移性</b><em>100</em><small><span data-lang="zh-CN">agents/interface.yaml 已存在。</span><span data-lang="en">agents/interface.yaml 已存在。</span></small></li><li><span class='metric-status'><span data-lang="zh-CN">关注</span><span data-lang="en">Watch</span></span><b>上下文成本</b><em>42</em><small><span data-lang="zh-CN">入口约 350 个词/字,references 约 14711 个词/字。</span><span data-lang="en">入口约 350 个词/字,references 约 14711 个词/字。</span></small></li></ol>
|
||||
</article>
|
||||
</div>
|
||||
<div class="metric-grid"><article class='metric-card'><div class='metric-card-head'><span class='metric-label'>完整度</span><strong>100</strong></div><div class='metric-card-body'><ul class="compact-list"><li><span data-lang="zh-CN">SKILL.md 已存在,是 Skill 的入口。</span><span data-lang="en">SKILL.md 已存在,是 Skill 的入口。</span></li><li><span data-lang="zh-CN">README.md 已存在,便于人工阅读。</span><span data-lang="en">README.md 已存在,便于人工阅读。</span></li><li><span data-lang="zh-CN">agents/interface.yaml 已存在,便于跨平台适配。</span><span data-lang="en">agents/interface.yaml 已存在,便于跨平台适配。</span></li></ul></div></article><article class='metric-card'><div class='metric-card-head'><span class='metric-label'>触发清晰</span><strong>100</strong></div><div class='metric-card-body'><ul class="compact-list"><li><span data-lang="zh-CN">frontmatter description 已存在,具备基础路由面。</span><span data-lang="en">frontmatter description 已存在,具备基础路由面。</span></li><li><span data-lang="zh-CN">description 有足够长度说明任务边界。</span><span data-lang="en">description 有足够长度说明任务边界。</span></li><li><span data-lang="zh-CN">description 已包含使用场景或排除边界信号。</span><span data-lang="en">description 已包含使用场景或排除边界信号。</span></li></ul></div></article><article class='metric-card'><div class='metric-card-head'><span class='metric-label'>证据充分</span><strong>100</strong></div><div class='metric-card-body'><ul class="compact-list"><li><span data-lang="zh-CN">已生成 20 / 20 类报告证据。</span><span data-lang="en">已生成 20 / 20 类报告证据。</span></li><li><span data-lang="zh-CN">skill-ir.json 已存在。</span><span data-lang="en">skill-ir.json 已存在。</span></li><li><span data-lang="zh-CN">compiled_targets.json 已存在。</span><span data-lang="en">compiled_targets.json 已存在。</span></li></ul></div></article><article class='metric-card'><div class='metric-card-head'><span class='metric-label'>可维护性</span><strong>100</strong></div><div class='metric-card-body'><ul class="compact-list"><li><span data-lang="zh-CN">SKILL.md 约 350 个词/字。</span><span data-lang="en">SKILL.md 约 350 个词/字。</span></li><li><span data-lang="zh-CN">入口文件保持克制,可维护性较好。</span><span data-lang="en">入口文件保持克制,可维护性较好。</span></li><li><span data-lang="zh-CN">references/ 已承载扩展指导。</span><span data-lang="en">references/ 已承载扩展指导。</span></li></ul></div></article><article class='metric-card'><div class='metric-card-head'><span class='metric-label'>可迁移性</span><strong>100</strong></div><div class='metric-card-body'><ul class="compact-list"><li><span data-lang="zh-CN">agents/interface.yaml 已存在。</span><span data-lang="en">agents/interface.yaml 已存在。</span></li><li><span data-lang="zh-CN">manifest.json 已存在。</span><span data-lang="en">manifest.json 已存在。</span></li><li><span data-lang="zh-CN">目标平台或 adapter target 已声明。</span><span data-lang="en">目标平台或 adapter target 已声明。</span></li></ul></div></article><article class='metric-card'><div class='metric-card-head'><span class='metric-label'>上下文成本</span><strong>42</strong></div><div class='metric-card-body'><ul class="compact-list"><li><span data-lang="zh-CN">入口约 350 个词/字,references 约 14640 个词/字。</span><span data-lang="en">入口约 350 个词/字,references 约 14640 个词/字。</span></li><li><span data-lang="zh-CN">分数越高代表上下文成本越低。</span><span data-lang="en">分数越高代表上下文成本越低。</span></li><li><span data-lang="zh-CN">上下文成本偏高,建议压缩入口或拆分 references。</span><span data-lang="en">上下文成本偏高,建议压缩入口或拆分 references。</span></li></ul></div></article></div>
|
||||
<div class="metric-grid"><article class='metric-card'><div class='metric-card-head'><span class='metric-label'>完整度</span><strong>100</strong></div><div class='metric-card-body'><ul class="compact-list"><li><span data-lang="zh-CN">SKILL.md 已存在,是 Skill 的入口。</span><span data-lang="en">SKILL.md 已存在,是 Skill 的入口。</span></li><li><span data-lang="zh-CN">README.md 已存在,便于人工阅读。</span><span data-lang="en">README.md 已存在,便于人工阅读。</span></li><li><span data-lang="zh-CN">agents/interface.yaml 已存在,便于跨平台适配。</span><span data-lang="en">agents/interface.yaml 已存在,便于跨平台适配。</span></li></ul></div></article><article class='metric-card'><div class='metric-card-head'><span class='metric-label'>触发清晰</span><strong>100</strong></div><div class='metric-card-body'><ul class="compact-list"><li><span data-lang="zh-CN">frontmatter description 已存在,具备基础路由面。</span><span data-lang="en">frontmatter description 已存在,具备基础路由面。</span></li><li><span data-lang="zh-CN">description 有足够长度说明任务边界。</span><span data-lang="en">description 有足够长度说明任务边界。</span></li><li><span data-lang="zh-CN">description 已包含使用场景或排除边界信号。</span><span data-lang="en">description 已包含使用场景或排除边界信号。</span></li></ul></div></article><article class='metric-card'><div class='metric-card-head'><span class='metric-label'>证据充分</span><strong>100</strong></div><div class='metric-card-body'><ul class="compact-list"><li><span data-lang="zh-CN">已生成 20 / 20 类报告证据。</span><span data-lang="en">已生成 20 / 20 类报告证据。</span></li><li><span data-lang="zh-CN">skill-ir.json 已存在。</span><span data-lang="en">skill-ir.json 已存在。</span></li><li><span data-lang="zh-CN">compiled_targets.json 已存在。</span><span data-lang="en">compiled_targets.json 已存在。</span></li></ul></div></article><article class='metric-card'><div class='metric-card-head'><span class='metric-label'>可维护性</span><strong>100</strong></div><div class='metric-card-body'><ul class="compact-list"><li><span data-lang="zh-CN">SKILL.md 约 350 个词/字。</span><span data-lang="en">SKILL.md 约 350 个词/字。</span></li><li><span data-lang="zh-CN">入口文件保持克制,可维护性较好。</span><span data-lang="en">入口文件保持克制,可维护性较好。</span></li><li><span data-lang="zh-CN">references/ 已承载扩展指导。</span><span data-lang="en">references/ 已承载扩展指导。</span></li></ul></div></article><article class='metric-card'><div class='metric-card-head'><span class='metric-label'>可迁移性</span><strong>100</strong></div><div class='metric-card-body'><ul class="compact-list"><li><span data-lang="zh-CN">agents/interface.yaml 已存在。</span><span data-lang="en">agents/interface.yaml 已存在。</span></li><li><span data-lang="zh-CN">manifest.json 已存在。</span><span data-lang="en">manifest.json 已存在。</span></li><li><span data-lang="zh-CN">目标平台或 adapter target 已声明。</span><span data-lang="en">目标平台或 adapter target 已声明。</span></li></ul></div></article><article class='metric-card'><div class='metric-card-head'><span class='metric-label'>上下文成本</span><strong>42</strong></div><div class='metric-card-body'><ul class="compact-list"><li><span data-lang="zh-CN">入口约 350 个词/字,references 约 14711 个词/字。</span><span data-lang="en">入口约 350 个词/字,references 约 14711 个词/字。</span></li><li><span data-lang="zh-CN">分数越高代表上下文成本越低。</span><span data-lang="en">分数越高代表上下文成本越低。</span></li><li><span data-lang="zh-CN">上下文成本偏高,建议压缩入口或拆分 references。</span><span data-lang="en">上下文成本偏高,建议压缩入口或拆分 references。</span></li></ul></div></article></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -720,7 +720,7 @@
|
||||
<div>
|
||||
<table>
|
||||
<thead><tr><th><span data-lang="zh-CN">类型</span><span data-lang="en">Type</span></th><th><span data-lang="zh-CN">证据</span><span data-lang="en">Evidence</span></th><th><span data-lang="zh-CN">建议</span><span data-lang="en">Action</span></th></tr></thead>
|
||||
<tbody><tr><td><span data-lang="zh-CN">强项</span><span data-lang="en">Strength</span></td><td><span data-lang="zh-CN">触发面保持精简,并锚定在 frontmatter description。</span><span data-lang="en">The trigger surface stays lean and anchored in the frontmatter description.</span></td><td><span data-lang="zh-CN">保留并复用</span><span data-lang="en">Keep</span></td></tr><tr><td><span data-lang="zh-CN">强项</span><span data-lang="en">Strength</span></td><td><span data-lang="zh-CN">已生成 Skill IR,核心语义可先于平台打包被审查和迁移。</span><span data-lang="en">已生成 Skill IR,核心语义可先于平台打包被审查和迁移。</span></td><td><span data-lang="zh-CN">保留并复用</span><span data-lang="en">Keep</span></td></tr><tr><td><span data-lang="zh-CN">强项</span><span data-lang="en">Strength</span></td><td><span data-lang="zh-CN">已生成目标编译报告,可审查 IR 到 OpenAI、Claude、generic 等目标契约的映射。</span><span data-lang="en">已生成目标编译报告,可审查 IR 到 OpenAI、Claude、generic 等目标契约的映射。</span></td><td><span data-lang="zh-CN">保留并复用</span><span data-lang="en">Keep</span></td></tr><tr><td><span data-lang="zh-CN">缺口</span><span data-lang="en">Gap</span></td><td><span data-lang="zh-CN">上下文成本需要补强:入口约 350 个词/字,references 约 14640 个词/字。</span><span data-lang="en">上下文成本需要补强:入口约 350 个词/字,references 约 14640 个词/字。</span></td><td><span data-lang="zh-CN">纳入下一轮修复</span><span data-lang="en">Fix next</span></td></tr></tbody>
|
||||
<tbody><tr><td><span data-lang="zh-CN">强项</span><span data-lang="en">Strength</span></td><td><span data-lang="zh-CN">触发面保持精简,并锚定在 frontmatter description。</span><span data-lang="en">The trigger surface stays lean and anchored in the frontmatter description.</span></td><td><span data-lang="zh-CN">保留并复用</span><span data-lang="en">Keep</span></td></tr><tr><td><span data-lang="zh-CN">强项</span><span data-lang="en">Strength</span></td><td><span data-lang="zh-CN">已生成 Skill IR,核心语义可先于平台打包被审查和迁移。</span><span data-lang="en">已生成 Skill IR,核心语义可先于平台打包被审查和迁移。</span></td><td><span data-lang="zh-CN">保留并复用</span><span data-lang="en">Keep</span></td></tr><tr><td><span data-lang="zh-CN">强项</span><span data-lang="en">Strength</span></td><td><span data-lang="zh-CN">已生成目标编译报告,可审查 IR 到 OpenAI、Claude、generic 等目标契约的映射。</span><span data-lang="en">已生成目标编译报告,可审查 IR 到 OpenAI、Claude、generic 等目标契约的映射。</span></td><td><span data-lang="zh-CN">保留并复用</span><span data-lang="en">Keep</span></td></tr><tr><td><span data-lang="zh-CN">缺口</span><span data-lang="en">Gap</span></td><td><span data-lang="zh-CN">上下文成本需要补强:入口约 350 个词/字,references 约 14711 个词/字。</span><span data-lang="en">上下文成本需要补强:入口约 350 个词/字,references 约 14711 个词/字。</span></td><td><span data-lang="zh-CN">纳入下一轮修复</span><span data-lang="en">Fix next</span></td></tr></tbody>
|
||||
</table>
|
||||
<div class="two-col quality-panels">
|
||||
<article class="panel">
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
"label": "上下文成本",
|
||||
"score": 42,
|
||||
"reasons": [
|
||||
"入口约 350 个词/字,references 约 14640 个词/字。",
|
||||
"入口约 350 个词/字,references 约 14711 个词/字。",
|
||||
"分数越高代表上下文成本越低。",
|
||||
"上下文成本偏高,建议压缩入口或拆分 references。"
|
||||
]
|
||||
@@ -200,7 +200,7 @@
|
||||
"已生成 Output Review Adjudication,可记录盲评决策、一致率和待评审项。"
|
||||
],
|
||||
"gaps": [
|
||||
"上下文成本需要补强:入口约 350 个词/字,references 约 14640 个词/字。"
|
||||
"上下文成本需要补强:入口约 350 个词/字,references 约 14711 个词/字。"
|
||||
],
|
||||
"recommendations": [
|
||||
"先改触发边界,再扩展工作流。",
|
||||
@@ -969,7 +969,7 @@
|
||||
"interactive_script_count": 0,
|
||||
"package_hash_scope": "source-contract-without-generated-reports",
|
||||
"package_hash_file_count": 153,
|
||||
"package_sha256": "69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682"
|
||||
"package_sha256": "44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd"
|
||||
},
|
||||
"skill_atlas": {
|
||||
"skill_count": 12,
|
||||
@@ -1007,8 +1007,8 @@
|
||||
"trust_level": "local",
|
||||
"license": "MIT",
|
||||
"checksums": {
|
||||
"package_sha256": "69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682",
|
||||
"archive_sha256": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706"
|
||||
"package_sha256": "44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd",
|
||||
"archive_sha256": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933"
|
||||
},
|
||||
"compatibility": {
|
||||
"openai": "pass",
|
||||
@@ -1039,7 +1039,7 @@
|
||||
},
|
||||
"distribution": {
|
||||
"archive_verified": true,
|
||||
"archive_sha256": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706",
|
||||
"archive_sha256": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933",
|
||||
"package_verification": "reports/package_verification.json",
|
||||
"install_simulated": true,
|
||||
"install_simulation": "reports/install_simulation.json"
|
||||
@@ -1055,7 +1055,7 @@
|
||||
"target_count": 4,
|
||||
"adapter_count": 4,
|
||||
"archive_present": true,
|
||||
"archive_sha256": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706",
|
||||
"archive_sha256": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933",
|
||||
"archive_entry_count": 494,
|
||||
"failure_count": 0,
|
||||
"warning_count": 0
|
||||
@@ -1134,12 +1134,12 @@
|
||||
{
|
||||
"field": "archive_sha256",
|
||||
"from": "",
|
||||
"to": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706"
|
||||
"to": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933"
|
||||
},
|
||||
{
|
||||
"field": "package_sha256",
|
||||
"from": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"to": "69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682"
|
||||
"to": "44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -70,12 +70,12 @@
|
||||
{
|
||||
"field": "archive_sha256",
|
||||
"from": "",
|
||||
"to": "2abac4fcfb65ae9a27fee5acad50c70dc63bc889adec293407fd84b9f07d5706"
|
||||
"to": "cdadcbc9a0c92eba0c80a9f4fbd840530d32d19bf3cbb508a24bebb8e8551933"
|
||||
},
|
||||
{
|
||||
"field": "package_sha256",
|
||||
"from": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"to": "69dd8811ae7fef4aa0dcb296cd7c0587751eb2d7c68091953de620dcbf9aa682"
|
||||
"to": "44d9cb1aa096fff1b2c8844a609574c05c8ed9ae12005dc74a5662d3d94013fd"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -26,6 +26,10 @@ PACKAGE_PATHS = (
|
||||
"input",
|
||||
"outputs",
|
||||
)
|
||||
IGNORED_FILE_PATTERNS = {
|
||||
"reports/*pattern-analysis*.md",
|
||||
"reports/*research-plan*.md",
|
||||
}
|
||||
|
||||
|
||||
def estimate_tokens(text: str) -> int:
|
||||
@@ -61,6 +65,8 @@ def should_ignore(path: Path, skill_dir: Path) -> bool:
|
||||
rel = path.relative_to(skill_dir)
|
||||
if any(rel == ignored or ignored in rel.parents for ignored in IGNORED_RELATIVE_DIRS):
|
||||
return True
|
||||
if any(rel.match(pattern) for pattern in IGNORED_FILE_PATTERNS):
|
||||
return True
|
||||
return len(rel.parts) >= 2 and rel.parts[0] == "tests" and rel.parts[1].startswith("tmp_")
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,10 @@ IGNORED_RELATIVE_DIRS = {
|
||||
Path("tests") / "tmp_snapshot",
|
||||
Path("tests") / "tmp_cli",
|
||||
}
|
||||
IGNORED_FILE_PATTERNS = {
|
||||
"reports/*pattern-analysis*.md",
|
||||
"reports/*research-plan*.md",
|
||||
}
|
||||
CANONICAL_PATHS = (
|
||||
"SKILL.md",
|
||||
"manifest.json",
|
||||
@@ -47,6 +51,8 @@ def should_ignore(path: Path, root: Path) -> bool:
|
||||
rel = path.relative_to(root)
|
||||
if any(rel == ignored or ignored in rel.parents for ignored in IGNORED_RELATIVE_DIRS):
|
||||
return True
|
||||
if any(rel.match(pattern) for pattern in IGNORED_FILE_PATTERNS):
|
||||
return True
|
||||
return len(rel.parts) >= 2 and rel.parts[0] == "tests" and rel.parts[1].startswith("tmp_")
|
||||
|
||||
|
||||
|
||||
@@ -3,14 +3,19 @@ import argparse
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
from datetime import date
|
||||
from pathlib import Path
|
||||
|
||||
from simulate_install import simulate_install
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
SKILL_NAME = "yao-meta-skill"
|
||||
SENTINEL_NAME = ".yao-local-install.json"
|
||||
DEFAULT_INSTALL_DIR = Path.home() / ".agents" / "skills.disabled" / SKILL_NAME
|
||||
ACTIVE_INSTALL_DIR = Path.home() / ".agents" / "skills" / SKILL_NAME
|
||||
DEFAULT_PACKAGE_DIR = ROOT / "dist"
|
||||
ALLOW_UNTRACKED_PREFIXES = {
|
||||
".github",
|
||||
"agents",
|
||||
@@ -133,6 +138,31 @@ def write_sentinel(root: Path, install_dir: Path, dry_run: bool) -> None:
|
||||
(install_dir / SENTINEL_NAME).write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
|
||||
|
||||
def install_preflight(root: Path, package_dir: Path, generated_at: str) -> dict:
|
||||
package_dir = package_dir.resolve()
|
||||
with tempfile.TemporaryDirectory(prefix="yao-local-install-preflight-") as temp_dir:
|
||||
report = simulate_install(root, package_dir, Path(temp_dir), generated_at)
|
||||
summary = report.get("summary", {}) if isinstance(report.get("summary"), dict) else {}
|
||||
permission_failures = int(summary.get("installer_permission_failure_count", 0) or 0)
|
||||
if not report.get("ok") or permission_failures:
|
||||
failure_preview = "; ".join(str(item) for item in report.get("failures", [])[:3])
|
||||
if permission_failures and not failure_preview:
|
||||
failure_preview = f"{permission_failures} installer permission failures"
|
||||
raise ValueError(f"Install preflight failed for {package_dir}: {failure_preview or 'unknown failure'}")
|
||||
return {
|
||||
"ok": True,
|
||||
"package_dir": str(package_dir),
|
||||
"archive_extracted": bool(summary.get("archive_extracted")),
|
||||
"adapter_count": int(summary.get("adapter_count", 0) or 0),
|
||||
"installer_permission_enforced_count": int(summary.get("installer_permission_enforced_count", 0) or 0),
|
||||
"installer_permission_failure_count": permission_failures,
|
||||
"permission_target_count": int(summary.get("permission_target_count", 0) or 0),
|
||||
"permission_capability_count": int(summary.get("permission_capability_count", 0) or 0),
|
||||
"failure_count": int(summary.get("failure_count", 0) or 0),
|
||||
"warning_count": int(summary.get("warning_count", 0) or 0),
|
||||
}
|
||||
|
||||
|
||||
def remove_stale_files(install_dir: Path, desired_files: set[Path], dry_run: bool) -> list[str]:
|
||||
removed = []
|
||||
if not install_dir.exists():
|
||||
@@ -176,10 +206,21 @@ def copy_files(root: Path, install_dir: Path, files: list[Path], dry_run: bool)
|
||||
return copied, skipped
|
||||
|
||||
|
||||
def sync_local_install(root: Path, install_dir: Path, dry_run: bool = False) -> dict:
|
||||
def sync_local_install(
|
||||
root: Path,
|
||||
install_dir: Path,
|
||||
dry_run: bool = False,
|
||||
package_dir: Path | None = None,
|
||||
generated_at: str | None = None,
|
||||
skip_install_preflight: bool = False,
|
||||
) -> dict:
|
||||
root = root.resolve()
|
||||
install_dir = install_dir.resolve()
|
||||
validate_install_dir(root, install_dir)
|
||||
preflight = {"ok": True, "skipped": True}
|
||||
if not skip_install_preflight:
|
||||
resolved_package_dir = (package_dir or DEFAULT_PACKAGE_DIR).resolve()
|
||||
preflight = install_preflight(root, resolved_package_dir, generated_at or str(date.today()))
|
||||
files, skipped_untracked = candidate_files(root)
|
||||
desired_files = set(files)
|
||||
desired_files.add(Path(SENTINEL_NAME))
|
||||
@@ -197,6 +238,7 @@ def sync_local_install(root: Path, install_dir: Path, dry_run: bool = False) ->
|
||||
"removed_count": len(removed),
|
||||
"skipped_source_count": len(skipped_sources),
|
||||
"skipped_untracked_count": len(skipped_untracked),
|
||||
"install_preflight": preflight,
|
||||
"copied_samples": copied[:10],
|
||||
"removed_samples": removed[:10],
|
||||
"skipped_source_samples": skipped_sources[:10],
|
||||
@@ -208,13 +250,23 @@ def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="Sync the current yao-meta-skill source into a managed local skill mirror.")
|
||||
parser.add_argument("--root", default=str(ROOT))
|
||||
parser.add_argument("--install-dir", default=str(DEFAULT_INSTALL_DIR))
|
||||
parser.add_argument("--package-dir", default=str(DEFAULT_PACKAGE_DIR))
|
||||
parser.add_argument("--generated-at", default=str(date.today()))
|
||||
parser.add_argument("--skip-install-preflight", action="store_true")
|
||||
parser.add_argument("--dry-run", action="store_true")
|
||||
args = parser.parse_args()
|
||||
root = Path(args.root).resolve()
|
||||
package_dir = Path(args.package_dir)
|
||||
if not package_dir.is_absolute():
|
||||
package_dir = root / package_dir
|
||||
try:
|
||||
result = sync_local_install(
|
||||
Path(args.root),
|
||||
root,
|
||||
resolve_install_dir(args.install_dir),
|
||||
dry_run=args.dry_run,
|
||||
package_dir=package_dir,
|
||||
generated_at=args.generated_at,
|
||||
skip_install_preflight=args.skip_install_preflight,
|
||||
)
|
||||
except (OSError, subprocess.CalledProcessError, ValueError) as exc:
|
||||
result = {"ok": False, "failures": [str(exc)]}
|
||||
|
||||
@@ -3,21 +3,73 @@ import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
SYNC_SCRIPT = ROOT / "scripts" / "sync_local_install.py"
|
||||
TMP = ROOT / "tests" / "tmp" / "local_install_sync"
|
||||
PACKAGER = ROOT / "scripts" / "cross_packager.py"
|
||||
EXPECTATIONS = ROOT / "evals" / "packaging_expectations.json"
|
||||
|
||||
|
||||
def run_sync(install_dir: Path) -> dict:
|
||||
def build_package(out_dir: Path) -> dict:
|
||||
proc = subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
str(PACKAGER),
|
||||
str(ROOT),
|
||||
"--platform",
|
||||
"openai",
|
||||
"--platform",
|
||||
"claude",
|
||||
"--platform",
|
||||
"generic",
|
||||
"--platform",
|
||||
"vscode",
|
||||
"--expectations",
|
||||
str(EXPECTATIONS),
|
||||
"--output-dir",
|
||||
str(out_dir),
|
||||
"--zip",
|
||||
],
|
||||
cwd=ROOT,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
payload = json.loads(proc.stdout) if proc.stdout.strip() else {}
|
||||
return {"ok": proc.returncode == 0, "payload": payload, "stderr": proc.stderr}
|
||||
|
||||
|
||||
def rewrite_archive_json(package_dir: Path, relative_path: str, transform) -> None:
|
||||
archive_path = package_dir / "yao-meta-skill.zip"
|
||||
rewritten_path = package_dir / "yao-meta-skill.rewritten.zip"
|
||||
archive_member = f"yao-meta-skill/{relative_path}"
|
||||
replaced = False
|
||||
with zipfile.ZipFile(archive_path) as archive_in, zipfile.ZipFile(rewritten_path, "w", compression=zipfile.ZIP_DEFLATED) as archive_out:
|
||||
for info in archive_in.infolist():
|
||||
data = archive_in.read(info.filename)
|
||||
if info.filename == archive_member:
|
||||
payload = json.loads(data.decode("utf-8"))
|
||||
data = (json.dumps(transform(payload), ensure_ascii=False, indent=2) + "\n").encode("utf-8")
|
||||
replaced = True
|
||||
archive_out.writestr(info, data)
|
||||
assert replaced, archive_member
|
||||
rewritten_path.replace(archive_path)
|
||||
|
||||
|
||||
def run_sync(install_dir: Path, package_dir: Path) -> dict:
|
||||
proc = subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
str(SYNC_SCRIPT),
|
||||
"--install-dir",
|
||||
str(install_dir),
|
||||
"--package-dir",
|
||||
str(package_dir),
|
||||
"--generated-at",
|
||||
"2026-06-13",
|
||||
],
|
||||
cwd=ROOT,
|
||||
capture_output=True,
|
||||
@@ -33,13 +85,17 @@ def run_sync(install_dir: Path) -> dict:
|
||||
}
|
||||
|
||||
|
||||
def run_sync_raw(install_dir: Path) -> subprocess.CompletedProcess[str]:
|
||||
def run_sync_raw(install_dir: Path, package_dir: Path) -> subprocess.CompletedProcess[str]:
|
||||
return subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
str(SYNC_SCRIPT),
|
||||
"--install-dir",
|
||||
str(install_dir),
|
||||
"--package-dir",
|
||||
str(package_dir),
|
||||
"--generated-at",
|
||||
"2026-06-13",
|
||||
],
|
||||
cwd=ROOT,
|
||||
capture_output=True,
|
||||
@@ -51,6 +107,9 @@ def main() -> None:
|
||||
if TMP.exists():
|
||||
shutil.rmtree(TMP)
|
||||
TMP.mkdir(parents=True, exist_ok=True)
|
||||
package_dir = TMP / "dist"
|
||||
package = build_package(package_dir)
|
||||
assert package["ok"], package
|
||||
|
||||
install_dir = TMP / "installed-skill"
|
||||
install_dir.mkdir(parents=True)
|
||||
@@ -67,15 +126,33 @@ def main() -> None:
|
||||
untracked_file = ROOT / "sync-local-untracked.tmp"
|
||||
untracked_file.write_text("do not copy me\n", encoding="utf-8")
|
||||
try:
|
||||
result = run_sync(install_dir)
|
||||
result = run_sync(install_dir, package_dir)
|
||||
finally:
|
||||
untracked_file.unlink(missing_ok=True)
|
||||
|
||||
policy_gap_dir = TMP / "policy-gap-dist"
|
||||
shutil.copytree(package_dir, policy_gap_dir)
|
||||
|
||||
def remove_vscode_network_enforcement(payload: dict) -> dict:
|
||||
payload["capabilities"]["network"]["target_enforcement"].pop("vscode", None)
|
||||
return payload
|
||||
|
||||
rewrite_archive_json(policy_gap_dir, "security/permission_policy.json", remove_vscode_network_enforcement)
|
||||
refused_install_dir = TMP / "preflight-refused-install"
|
||||
refused_install_dir.mkdir(parents=True)
|
||||
(refused_install_dir / "SKILL.md").write_text(
|
||||
"---\nname: yao-meta-skill\ndescription: local install fixture\n---\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
refused_stale = refused_install_dir / "stale.txt"
|
||||
refused_stale.write_text("must not be touched after preflight failure\n", encoding="utf-8")
|
||||
preflight_refused = run_sync_raw(refused_install_dir, policy_gap_dir)
|
||||
|
||||
ordinary_dir = TMP / "ordinary-folder"
|
||||
ordinary_dir.mkdir(parents=True)
|
||||
ordinary_file = ordinary_dir / "keep.txt"
|
||||
ordinary_file.write_text("must survive a refused sync\n", encoding="utf-8")
|
||||
refused = run_sync_raw(ordinary_dir)
|
||||
refused = run_sync_raw(ordinary_dir, package_dir)
|
||||
|
||||
makefile_text = (ROOT / "Makefile").read_text(encoding="utf-8")
|
||||
readme_text = (ROOT / "README.md").read_text(encoding="utf-8")
|
||||
@@ -89,6 +166,10 @@ def main() -> None:
|
||||
"stale_file_removed": not stale_file.exists(),
|
||||
"install_git_metadata_preserved": git_config.exists(),
|
||||
"install_sentinel_written": (install_dir / ".yao-local-install.json").exists(),
|
||||
"install_preflight_enforced": result["payload"]["install_preflight"]["installer_permission_enforced_count"] == 12,
|
||||
"install_preflight_permission_failures_zero": result["payload"]["install_preflight"]["installer_permission_failure_count"] == 0,
|
||||
"install_preflight_blocks_sync": preflight_refused.returncode != 0,
|
||||
"install_preflight_failure_preserves_files": refused_stale.exists(),
|
||||
"ordinary_dir_refused": refused.returncode != 0,
|
||||
"ordinary_dir_preserved": ordinary_file.exists(),
|
||||
"makefile_target_present": "sync-local-install" in makefile_text,
|
||||
|
||||
@@ -3,6 +3,7 @@ import json
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
@@ -59,6 +60,57 @@ def require_context_targets(case: dict, max_initial: int, min_density: float) ->
|
||||
)
|
||||
|
||||
|
||||
def verify_private_report_ignored() -> dict:
|
||||
with TemporaryDirectory(prefix="yao-private-report-ignore-") as temp_dir:
|
||||
skill_dir = Path(temp_dir) / "skill"
|
||||
(skill_dir / "reports").mkdir(parents=True)
|
||||
(skill_dir / "SKILL.md").write_text(
|
||||
"---\n"
|
||||
"name: report-ignore-fixture\n"
|
||||
"description: Test fixture for ignored private reports.\n"
|
||||
"---\n"
|
||||
"Use this fixture to validate context sizing.\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(skill_dir / "reports" / "kept.md").write_text("stable evidence\n", encoding="utf-8")
|
||||
baseline = run(
|
||||
"private_report_ignore_baseline",
|
||||
[sys.executable, "scripts/context_sizer.py", str(skill_dir), "--json"],
|
||||
)
|
||||
(skill_dir / "reports" / "client-research-plan.md").write_text(
|
||||
"private notes\n" * 500,
|
||||
encoding="utf-8",
|
||||
)
|
||||
context_case = run(
|
||||
"private_report_ignore_context_sizer",
|
||||
[sys.executable, "scripts/context_sizer.py", str(skill_dir), "--json"],
|
||||
)
|
||||
boundary_case = run(
|
||||
"private_report_ignore_resource_boundary",
|
||||
[sys.executable, "scripts/resource_boundary_check.py", str(skill_dir), "--max-initial-tokens", "5000"],
|
||||
)
|
||||
|
||||
baseline_total = baseline.get("payload", {}).get("estimated_total_text_tokens")
|
||||
context_total = context_case.get("payload", {}).get("estimated_total_text_tokens")
|
||||
boundary_files = boundary_case.get("payload", {}).get("stats", {}).get("relevant_file_count")
|
||||
passed = (
|
||||
baseline["passed"]
|
||||
and context_case["passed"]
|
||||
and boundary_case["passed"]
|
||||
and baseline_total == context_total
|
||||
and boundary_files == 2
|
||||
)
|
||||
return {
|
||||
"name": "private_report_ignore",
|
||||
"passed": passed,
|
||||
"baseline_total_tokens": baseline_total,
|
||||
"observed_total_tokens": context_total,
|
||||
"resource_relevant_file_count": boundary_files,
|
||||
"context_stdout": context_case["stdout"],
|
||||
"boundary_stdout": boundary_case["stdout"],
|
||||
}
|
||||
|
||||
|
||||
def main() -> None:
|
||||
python = sys.executable
|
||||
cases = []
|
||||
@@ -115,6 +167,7 @@ def main() -> None:
|
||||
require_min_score(governed_example, 90)
|
||||
cases.insert(4, governed_example)
|
||||
cases.insert(5, governed_resource)
|
||||
cases.append(verify_private_report_ignored())
|
||||
|
||||
report = {"ok": all(case["passed"] for case in cases), "cases": cases}
|
||||
print(json.dumps(report, ensure_ascii=False, indent=2))
|
||||
|
||||
Reference in New Issue
Block a user