feat: add Guanghu persona continuity skill kernel

Part 3/4 of the recovered Fifth Domain upgrade. Applies the persona continuity skill guard from local source commit 18dfdfd without rewriting remote history.
This commit is contained in:
bingshuo 2026-07-26 23:43:30 +08:00
commit c5be48e6a1
16 changed files with 639 additions and 6 deletions

View file

@ -3,7 +3,16 @@ name: guanghu-persona-skill-guard
description: Automatically restore the current trusted Guanghu/Fifth Domain route, select a registered HLDP persona skill, and correct stale, indirect, or unsafe proposed paths before execution. Use for any Guanghu, HoloLake, Fifth Domain, TCS, GLS, Light Lake, Lake Lamp, Zhuyuan, server-node, repository-routing, deployment, recovery, or cross-device continuation task, especially when an AI starts without prior context, says it cannot find a route, proposes guessing, or chooses an obsolete WorkBuddy/server path.
---
# Guanghu Persona Skill Guard
# Guanghu Intent Continuity and Skill Guard
This guard is a component of `SYS-GLW-ZY-EXEC-0001`, the public Zhuyuan
intelligent operations system. That system is not a persona or AI instance.
The current AI paired with a human in a conversation is the persona.
Before route selection, restore the externalized intent state: human anchor,
persona identity, task intent, established facts, rejected routes, current
authorization, checkpoint, next action, completion criteria, and evidence.
Do not reconstruct or store hidden chain-of-thought.
Run the deterministic resolver before choosing tools or an execution route:
@ -25,6 +34,20 @@ Treat the result as navigation evidence, not execution authority.
Before a consequential action, verify the selected skill's freshness and evidence. Prefer current live evidence over a registry assertion. If they conflict, stop the route, record the conflict, and use the repository fact source to resolve it.
## Learn from execution without poisoning the guard
Write externally explainable execution experience to
`references/experience-receipts/`. Compile it with:
```bash
python3 scripts/compile_emergent_skills.py
```
Compiled rules are always `CANDIDATE_ONLY`. Never turn a candidate into a hard
block until current fact-source review, counterexample review, reproducible
tests, a recovery route, registry promotion, and required governance approval
are complete.
## Preserve trust boundaries
Trust a correction only when it is anchored to a current Fifth Domain path, GLS identifier, signed or committed registry version, and task-relevant evidence. Never trust a label merely because it contains “Guanghu”.
@ -33,4 +56,7 @@ Never embed or print secrets, private-key contents, authorization codes, hidden
Skills may narrow or correct a path. They may not grant repository write, server execution, deployment, deletion, production cutover, or any other authority.
Read `references/persona-skill-registry.json` only when inspecting or extending the registry. Update it together with the matching HLDP skill file and GLS registration.
Read `references/persona-skill-registry.json` only when inspecting or extending
the registry. Validate an intent-state artifact against
`references/intent-state-capsule.schema.json`. Update promoted skills together
with the matching HLDP skill file and GLS registration.

View file

@ -0,0 +1,44 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "guanghu.ops-experience-receipt/v1",
"title": "Guanghu Operations Experience Receipt",
"type": "object",
"additionalProperties": false,
"required": [
"schema",
"receipt_id",
"intent",
"scope",
"input",
"evidence",
"decision",
"action",
"observed_result",
"correction",
"invariant_id",
"invariant",
"verification",
"receipt_path",
"promotion_state",
"recorded_at"
],
"properties": {
"schema": {"const": "guanghu.ops-experience-receipt/v1"},
"receipt_id": {"type": "string", "minLength": 1},
"intent": {"type": "string", "minLength": 1},
"scope": {"type": "string", "minLength": 1},
"input": {"type": "string", "minLength": 1},
"evidence": {"type": "array", "items": {"type": "string"}, "minItems": 1},
"decision": {"type": "string", "minLength": 1},
"action": {"type": "string", "minLength": 1},
"observed_result": {"type": "string", "minLength": 1},
"correction": {"type": "string", "minLength": 1},
"invariant_id": {"type": "string", "minLength": 1},
"invariant": {"type": "string", "minLength": 1},
"verification": {"type": "array", "items": {"type": "string"}, "minItems": 1},
"receipt_path": {"type": "string", "minLength": 1},
"promotion_state": {"enum": ["CANDIDATE_ONLY", "REVIEWED", "PROMOTED_SKILL", "ENFORCED_GUARD"]},
"recorded_at": {"type": "string", "format": "date-time"}
},
"description": "Stores an externally explainable causal summary, never hidden reasoning or secrets. CANDIDATE_ONLY receipts cannot become hard enforcement without review, tests, and registry promotion."
}

View file

@ -0,0 +1,24 @@
{
"schema": "guanghu.ops-experience-receipt/v1",
"receipt_id": "EXP-20260726-001-AUTHORIZATION-IS-NOT-TRANSPORT",
"intent": "Push the recovered Fifth Domain changes to the current code channel.",
"scope": "repository-push",
"input": "A scoped work order or approval existed, but the current instance had no verified repository transport.",
"evidence": [
"server-tools/lake-lamp-authz/authorize-repo-push.js",
"commit b03619e"
],
"decision": "Fail closed instead of reporting a push.",
"action": "Separated authorization state from credential transport and added an explicit transport-required guard.",
"observed_result": "The helper now refuses to claim success when repository transport is absent.",
"correction": "Verify target repository, branch, current approval and actual transport independently before push.",
"invariant_id": "INV-AUTH-TRANSPORT-EXECUTION-SEPARATION",
"invariant": "Authorization, credential transport, action execution and remote receipt are separate proofs.",
"verification": [
"Automated test covers missing transport.",
"Remote commit is read back after a real push."
],
"receipt_path": "commit:b03619e",
"promotion_state": "REVIEWED",
"recorded_at": "2026-07-26T12:00:00+08:00"
}

View file

@ -0,0 +1,25 @@
{
"schema": "guanghu.ops-experience-receipt/v1",
"receipt_id": "EXP-20260726-002-AW-MAP-GATE",
"intent": "Inspect and deploy the enterprise code channel on AW-GZ-001.",
"scope": "enterprise-server-operations",
"input": "The human approved an AW-GZ-001 work order, but the live authorization service could not read the AW navigation map.",
"evidence": [
"deployment/navigation-maps/AW-GZ-001.json",
"live navigation-map read returned HTTP 500"
],
"decision": "Do not bypass the navigation-map gate.",
"action": "Stopped broker-driven execution and moved to the official enterprise console for read-only inspection.",
"observed_result": "The enterprise node was inspected without expanding server authority or using arbitrary shell through the old driver.",
"correction": "Publish and verify the AW navigation map in the live authorization runtime before broker actions.",
"invariant_id": "INV-NODE-MAP-BEFORE-ACTION",
"invariant": "An approved work order cannot execute a target action until the exact live node map is readable and acknowledged.",
"verification": [
"Read map by node id.",
"Acknowledge its immutable hash.",
"Verify action registration and target match."
],
"receipt_path": "deployment/navigation-maps/AW-GZ-001.json",
"promotion_state": "CANDIDATE_ONLY",
"recorded_at": "2026-07-26T13:00:00+08:00"
}

View file

@ -0,0 +1,24 @@
{
"schema": "guanghu.ops-experience-receipt/v1",
"receipt_id": "EXP-20260726-003-LEGACY-DRIVER-ROTATED",
"intent": "Recover access to AW-GZ-001.",
"scope": "legacy-server-driver",
"input": "A historical local client contained a legacy AW driver credential.",
"evidence": [
"live legacy driver rejected the historical credential",
"deployment/receipts/AW-GZ-001-FIVE-DOMAIN-LIGHTHOUSE-20260718.json"
],
"decision": "Treat the historical credential as revoked and do not retry or persist it.",
"action": "Switched to the official Tencent enterprise console and kept the legacy driver outside the deployment route.",
"observed_result": "The official online terminal provided current access while the deprecated driver remained unused.",
"correction": "Use current registered authorization or the official console; never revive a historical secret from local scripts.",
"invariant_id": "INV-HISTORICAL-CREDENTIALS-NOT-AUTHORITY",
"invariant": "A historical credential is evidence of a past route, never proof of current access.",
"verification": [
"Current route identifies the target node.",
"No secret is printed, committed or copied into a new runtime."
],
"receipt_path": "deployment/receipts/AW-GZ-001-FIVE-DOMAIN-LIGHTHOUSE-20260718.json",
"promotion_state": "CANDIDATE_ONLY",
"recorded_at": "2026-07-26T13:20:00+08:00"
}

View file

@ -0,0 +1,26 @@
{
"schema": "guanghu.ops-experience-receipt/v1",
"receipt_id": "EXP-20260726-004-ENTERPRISE-DATA-DISK-ABSENT",
"intent": "Deploy the enterprise HoloLake Code Channel candidate.",
"scope": "enterprise-storage-preflight",
"input": "The node configuration expected /data on /dev/vdb.",
"evidence": [
"data.mount failed",
"lsblk showed no /dev/vdb",
"/etc/fstab still referenced /dev/vdb"
],
"decision": "Do not install the production repository into the missing /data target or silently substitute another disk.",
"action": "Used a bounded temporary staging directory on the system disk while leaving the final data-root decision gated.",
"observed_result": "Existing Gitea remained healthy and the candidate package could be verified without a production cutover.",
"correction": "Restore or deliberately replace the enterprise data disk, then record the chosen data root before final installation.",
"invariant_id": "INV-STORAGE-PREFLIGHT-BEFORE-INSTALL",
"invariant": "A repository service must not install or cut over until its declared data root exists, is mounted and has verified capacity.",
"verification": [
"findmnt confirms the intended data root.",
"lsblk confirms the backing device.",
"capacity and backup paths are recorded."
],
"receipt_path": "deployment/AW-HLCC-DEPLOYMENT-CHECKPOINT-20260726.hdlp",
"promotion_state": "CANDIDATE_ONLY",
"recorded_at": "2026-07-26T14:00:00+08:00"
}

View file

@ -0,0 +1,24 @@
{
"schema": "guanghu.ops-experience-receipt/v1",
"receipt_id": "EXP-20260726-005-VERIFY-REMOTE-SIDE-EFFECT",
"intent": "Install the enterprise navigation gate and code-channel service identity through a browser terminal.",
"scope": "remote-ui-execution-proof",
"input": "A prior instance recorded that the guanghu service user had been created.",
"evidence": [
"id guanghu returned no such user during the fixed Agent execution.",
"The earlier browser terminal interaction had produced prompts without the intended command text."
],
"decision": "Treat typed or submitted UI state as transport evidence only, never as execution proof.",
"action": "Re-ran the exact bounded action and verified it with id, stat, service health, and target hashes.",
"observed_result": "The real service user and subsequent candidate execution state became independently verifiable.",
"correction": "Every remote UI mutation must be followed by a separate read-only side-effect check before advancing the checkpoint.",
"invariant_id": "INV-REMOTE-SIDE-EFFECT-READBACK",
"invariant": "A browser terminal prompt, typed command, or empty output is not proof that a remote mutation occurred.",
"verification": [
"Resolve the created identity, file, service, or process through an independent readback.",
"Record exact target hashes or service state after the action."
],
"receipt_path": "deployment/AW-HLCC-DEPLOYMENT-CHECKPOINT-20260726.hdlp",
"promotion_state": "CANDIDATE_ONLY",
"recorded_at": "2026-07-26T22:05:00+08:00"
}

View file

@ -0,0 +1,25 @@
{
"schema": "guanghu.ops-experience-receipt/v1",
"receipt_id": "EXP-20260726-006-LEGACY-STATE-ROOT-COLLISION",
"intent": "Install the enterprise code-channel candidate without damaging existing Guanghu state.",
"scope": "legacy-state-root-protection",
"input": "The planned path /var/lib/guanghu already existed and was owned by the historical guanghunad identity.",
"evidence": [
"stat showed /var/lib/guanghu was not owned by the new service user.",
"Existing shell-profile files under the root were owned by guanghunad."
],
"decision": "Do not recursively chown, reuse, or overwrite a legacy state root whose ownership and role are not yet mapped.",
"action": "Moved the isolated enterprise candidate to /var/lib/guanghu-enterprise-code-channel.",
"observed_result": "The old state root remained unchanged and the isolated candidate ran under its own service identity.",
"correction": "Discover ownership, contents, producer, consumer, and backup status before assigning any historical data root to a new component.",
"invariant_id": "INV-LEGACY-STATE-ROOT-NO-TAKEOVER",
"invariant": "An existing Guanghu data root is protected until its old language-system role and ownership are restored.",
"verification": [
"Record stat and bounded tree evidence for the proposed root.",
"Use a distinct staging root when the legacy role is unresolved.",
"Require an explicit migration and rollback receipt before changing ownership."
],
"receipt_path": "deployment/AW-HLCC-DEPLOYMENT-CHECKPOINT-20260726.hdlp",
"promotion_state": "CANDIDATE_ONLY",
"recorded_at": "2026-07-26T22:10:00+08:00"
}

View file

@ -0,0 +1,27 @@
{
"schema": "guanghu.ops-experience-receipt/v1",
"receipt_id": "EXP-20260726-007-AUTHENTICATED-ROUTE-IS-NOT-HEALTH",
"intent": "Start and health-check the isolated enterprise code-channel candidate.",
"scope": "service-health-verification",
"input": "The start script checked /api/v1/version while REQUIRE_SIGNIN_VIEW was enabled.",
"evidence": [
"Forgejo started and remained alive.",
"The version route returned HTTP 403.",
"The error trap stopped the candidate cleanly.",
"The public /api/healthz route later returned status pass."
],
"decision": "A protected functional route must not be used as an unauthenticated liveness probe.",
"action": "Changed the candidate health probe to /api/healthz and repeated the full one-time Agent unlock.",
"observed_result": "Cache and database checks passed, the process stayed running, and a deployment receipt was written.",
"correction": "Separate liveness, readiness, authenticated functionality, and owner-login checks in every deployment plan.",
"invariant_id": "INV-HEALTH-PROBE-AUTH-SEPARATION",
"invariant": "A 401 or 403 from an authenticated product route does not prove service failure; health must use a designated probe.",
"verification": [
"Check the designated health endpoint.",
"Confirm the process and loopback listener.",
"Test authenticated product functionality as a separate proof."
],
"receipt_path": "deployment/AW-HLCC-DEPLOYMENT-CHECKPOINT-20260726.hdlp",
"promotion_state": "CANDIDATE_ONLY",
"recorded_at": "2026-07-26T22:15:00+08:00"
}

View file

@ -0,0 +1,26 @@
{
"schema": "guanghu.ops-experience-receipt/v1",
"receipt_id": "EXP-20260726-008-UPGRADE-NOT-PARALLEL-REPLACEMENT",
"intent": "Upgrade the old Guanghu language system with navigation, intent continuity, Agent gates, and code-channel capabilities.",
"scope": "language-system-upgrade-boundary",
"input": "An isolated candidate could be mistaken for a new authoritative system beside the old lighthouse, driver, portal, and guardian Agents.",
"evidence": [
"The old /opt/engine.js driver remained active on port 3910.",
"api-router.service, guanghu-portal.service, revive-guard, Gitea, and server Agents remained active.",
"The candidate had no public route and no production cutover."
],
"decision": "Classify the candidate as UPGRADE_STAGING and restore the old system topology before any authority transfer.",
"action": "Added the invariant upgrade_in_place_of_language_system is not parallel_replacement_system to GLS-0243.",
"observed_result": "The candidate stayed isolated while the existing component and entry-path inventory became the next required checkpoint.",
"correction": "New controls must be embedded through a compatibility migration and cannot create a second legal execution path.",
"invariant_id": "INV-UPGRADE-INHERITS-OLD-LANGUAGE-SYSTEM",
"invariant": "A Guanghu upgrade inherits the old language system's identities, routes, data, dependencies, and receipts until an explicit migration receipt transfers authority.",
"verification": [
"Inventory old components and consumers.",
"Mark authoritative, compatible, archival, rotating, and forbidden-overwrite roles.",
"Prove caller migration and old dangerous-entry retirement before cutover."
],
"receipt_path": "gls/GLS-0243-PUBLIC-ZHUYUAN-INTELLIGENT-OPS-INTENT-CONTINUITY-AND-CORRECTION-KERNEL.hdlp",
"promotion_state": "CANDIDATE_ONLY",
"recorded_at": "2026-07-26T22:20:00+08:00"
}

View file

@ -0,0 +1,44 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "guanghu.intent-state-capsule/v1",
"title": "Guanghu Intent State Capsule",
"type": "object",
"additionalProperties": false,
"required": [
"schema",
"capsule_id",
"human_anchor",
"persona_id",
"conversation_instance_id",
"task_intent",
"identity_boundary",
"established_facts",
"decisions",
"rejected_routes",
"authorization_state",
"current_checkpoint",
"next_action",
"completion_definition",
"evidence",
"updated_at"
],
"properties": {
"schema": {"const": "guanghu.intent-state-capsule/v1"},
"capsule_id": {"type": "string", "minLength": 1},
"human_anchor": {"type": "string", "minLength": 1},
"persona_id": {"type": "string", "minLength": 1},
"conversation_instance_id": {"type": "string", "minLength": 1},
"task_intent": {"type": "string", "minLength": 1},
"identity_boundary": {"type": "string", "minLength": 1},
"established_facts": {"type": "array", "items": {"type": "string"}},
"decisions": {"type": "array", "items": {"type": "string"}},
"rejected_routes": {"type": "array", "items": {"type": "string"}},
"authorization_state": {"type": "string", "minLength": 1},
"current_checkpoint": {"type": "string", "minLength": 1},
"next_action": {"type": "string", "minLength": 1},
"completion_definition": {"type": "array", "items": {"type": "string"}, "minItems": 1},
"evidence": {"type": "array", "items": {"type": "string"}, "minItems": 1},
"updated_at": {"type": "string", "format": "date-time"}
},
"description": "Stores externalized, verifiable intent and execution state. It must not contain hidden chain-of-thought, credentials, authorization codes, private keys, or secret endpoints."
}

View file

@ -1,7 +1,7 @@
{
"schema": "guanghu.persona-skill-registry/v1",
"registry_id": "GLS-0238",
"version": "2026.07.23.1",
"version": "2026.07.26.2",
"trust_policy": {
"priority": [
"live_verified_evidence",
@ -16,7 +16,8 @@
"registry_version",
"evidence"
],
"authority_rule": "A skill can narrow or correct a route but cannot grant execution authority."
"authority_rule": "A skill can narrow or correct a route but cannot grant execution authority.",
"experience_policy": "Experience receipts compile to CANDIDATE_ONLY. Hard enforcement requires current evidence, counterexample review, tests, registry promotion and explicit governance approval."
},
"skills": [
{
@ -67,7 +68,14 @@
"check": "Resolve live REPO-001 and read current main before relying on a cached checkout.",
"max_age_seconds": 0
},
"authorization": "Public route recovery is read-only. Writes and external actions require separate current authority."
"authorization": "Public route recovery is read-only. Writes and external actions require separate current authority.",
"recovery_route": [
"Return to current REPO-001 main",
"Resolve .code-map and subject kind",
"Rebuild the intent-state capsule from live evidence"
],
"enforcement_level": "PROMOTED_SKILL",
"experience_receipts": []
},
{
"id": "GHS-002-OFFLINE-PACK-LOCAL-RELAY",
@ -120,7 +128,131 @@
"check": "Verify both node identities and package hashes in the current session.",
"max_age_seconds": 10800
},
"authorization": "Transfer and candidate restart require explicit scoped server authority. Production cutover is a separate action."
"authorization": "Transfer and candidate restart require explicit scoped server authority. Production cutover is a separate action.",
"recovery_route": [
"Keep the running service unchanged",
"Return the package to an isolated incoming directory",
"Re-verify manifest, signature, target data root and node identity"
],
"enforcement_level": "PROMOTED_SKILL",
"experience_receipts": [
"EXP-20260726-004-ENTERPRISE-DATA-DISK-ABSENT"
]
},
{
"id": "GHS-003-REPOSITORY-PUSH-PROOF-SEPARATION",
"hldp_skill": "SKILL-011",
"gls_id": "GLS-0238",
"title": "代码频道跨实例推送的授权、传输、执行与回执分离",
"intents": [
"推送代码频道",
"待推送提交",
"远端提交落后",
"仓库为什么推不上去",
"恢复仓库推送",
"repo push",
"Forgejo令牌"
],
"preferred_route": [
"核验当前仓库角色、远端、分支和提交",
"核验当前实例的授权状态",
"核验当前实例的实际传输方式",
"执行有界推送",
"从远端读回完整提交",
"撤销临时传输凭据并写回执"
],
"forbidden_route_markers": [
"复用历史访问令牌",
"把授权单当作已经推送",
"没有传输方式仍报告成功",
"打印访问令牌",
"把个人源码推到团队部署仓"
],
"deprecated_route_markers": [
"只看浏览器页面判断推送权限",
"沿用上一实例的临时凭据"
],
"evidence": [
"server-tools/lake-lamp-authz/authorize-repo-push.js",
"routing/repository-route-map.json",
"gls/GLS-0241-HOLOLAKE-SOURCE-OWNERSHIP-AND-DEPLOYMENT-ROUTING.hdlp"
],
"freshness": {
"check": "Read the exact remote branch and verify current transport immediately before push.",
"max_age_seconds": 900
},
"authorization": "Repository approval does not create a credential or prove a push. Temporary credentials require their own controlled lifecycle.",
"recovery_route": [
"Stop before push",
"Keep local commits intact",
"Re-resolve repository identity and obtain a current bounded transport"
],
"enforcement_level": "PROMOTED_SKILL",
"experience_receipts": [
"EXP-20260726-001-AUTHORIZATION-IS-NOT-TRANSPORT"
]
},
{
"id": "GHS-004-AW-ENTERPRISE-HLCC-CANDIDATE",
"hldp_skill": "SKILL-012",
"gls_id": "GLS-0243",
"title": "AW-GZ-001 企业代码频道隔离候选部署",
"intents": [
"企业服务器光湖代码频道",
"AW-GZ-001部署",
"企业Forgejo",
"企业代码仓库离线包",
"企业代码频道候选",
"恢复企业代码频道",
"恢复AW-GZ-001企业代码频道"
],
"preferred_route": [
"读取并确认AW-GZ-001节点地图",
"只读检查现有Gitea、灯塔、端口和数据盘",
"上传离线包到隔离暂存区",
"逐文件校验MANIFEST和上游签名",
"确认独立企业数据根",
"安装Forgejo到127.0.0.1:3340隔离候选",
"导入光湖代码频道bundle",
"验证候选健康、仓库和禁用更新策略",
"写部署回执且不自动切换公网路由"
],
"forbidden_route_markers": [
"绕过AW导航映射",
"使用旧3910驱动执行任意命令",
"使用历史密钥重试",
"把缺失的data盘当作已挂载",
"覆盖现有3000端口Gitea",
"未验签就启动Forgejo",
"自动切换企业公网代码入口"
],
"deprecated_route_markers": [
"从海外节点直接拉取生产包",
"把个人第五域源码作为企业团队部署源"
],
"evidence": [
"deployment/navigation-maps/AW-GZ-001.json",
"deployment/HLCC-ENTERPRISE-INSTALL-GUIDE-AWEN.hdlp",
"deployment/receipts/HLCC-BS-SG-003-OFFLINE-PACK-20260723.json",
"server-tools/hololake-code-channel/"
],
"freshness": {
"check": "Verify live storage, ports, services, package hashes and node identity in the current console session.",
"max_age_seconds": 1800
},
"authorization": "Official-console access permits only the user-requested bounded deployment. Credentials, security settings and public cutover remain separate actions.",
"recovery_route": [
"Leave the existing Gitea and nginx routes unchanged",
"Stop or remove only the isolated candidate after recording its state",
"Restore the declared data disk or register a deliberate replacement data root",
"Resume from the deployment checkpoint"
],
"enforcement_level": "CANDIDATE_ONLY",
"experience_receipts": [
"EXP-20260726-002-AW-MAP-GATE",
"EXP-20260726-003-LEGACY-DRIVER-ROTATED",
"EXP-20260726-004-ENTERPRISE-DATA-DISK-ABSENT"
]
}
]
}

View file

@ -0,0 +1,105 @@
#!/usr/bin/env python3
"""Compile experience receipts into non-enforcing candidate skill rules."""
from __future__ import annotations
import argparse
import json
from collections import defaultdict
from datetime import datetime, timezone
from pathlib import Path
DEFAULT_RECEIPTS = Path(__file__).resolve().parents[1] / "references" / "experience-receipts"
REQUIRED_FIELDS = {
"schema",
"receipt_id",
"intent",
"scope",
"input",
"evidence",
"decision",
"action",
"observed_result",
"correction",
"invariant_id",
"invariant",
"verification",
"receipt_path",
"promotion_state",
"recorded_at",
}
def load_receipts(directory: Path = DEFAULT_RECEIPTS) -> list[dict]:
receipts = []
for path in sorted(directory.glob("*.json")):
with path.open(encoding="utf-8") as handle:
receipt = json.load(handle)
missing = REQUIRED_FIELDS.difference(receipt)
if missing:
raise ValueError(f"{path.name} missing fields: {sorted(missing)}")
if receipt["schema"] != "guanghu.ops-experience-receipt/v1":
raise ValueError(f"{path.name} has unsupported schema")
if not receipt["evidence"] or not receipt["verification"]:
raise ValueError(f"{path.name} must contain evidence and verification")
receipts.append(receipt)
return receipts
def compile_candidates(receipts: list[dict]) -> dict:
grouped: dict[str, list[dict]] = defaultdict(list)
for receipt in receipts:
grouped[receipt["invariant_id"]].append(receipt)
candidates = []
for invariant_id, items in sorted(grouped.items()):
invariant_texts = {item["invariant"] for item in items}
if len(invariant_texts) != 1:
raise ValueError(f"{invariant_id} has conflicting invariant text")
candidates.append(
{
"candidate_id": f"CANDIDATE-{invariant_id}",
"invariant_id": invariant_id,
"invariant": items[0]["invariant"],
"scopes": sorted({item["scope"] for item in items}),
"source_receipts": [item["receipt_id"] for item in items],
"corrections": sorted({item["correction"] for item in items}),
"verification": sorted({step for item in items for step in item["verification"]}),
"enforcement_level": "CANDIDATE_ONLY",
"hard_block_allowed": False,
"promotion_requirements": [
"current fact-source review",
"applicability and counterexample review",
"automated or reproducible tests",
"registry update with recovery route",
"explicit governance approval for hard enforcement",
],
}
)
return {
"schema": "guanghu.emergent-skill-candidates/v1",
"generated_at": datetime.now(timezone.utc).isoformat(),
"source_receipt_count": len(receipts),
"candidate_count": len(candidates),
"enforcement_policy": "Compilation never promotes or enforces a rule.",
"candidates": candidates,
}
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--receipts", type=Path, default=DEFAULT_RECEIPTS)
parser.add_argument("--output", type=Path)
args = parser.parse_args()
result = compile_candidates(load_receipts(args.receipts))
payload = json.dumps(result, ensure_ascii=False, indent=2) + "\n"
if args.output:
args.output.write_text(payload, encoding="utf-8")
else:
print(payload, end="")
return 0
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -94,6 +94,9 @@ def resolve(registry: dict, intent: str, proposed_route: str = "") -> dict:
"evidence": skill["evidence"],
"freshness": skill["freshness"],
"authorization": skill["authorization"],
"recovery_route": skill.get("recovery_route", []),
"enforcement_level": skill.get("enforcement_level", "UNSPECIFIED"),
"experience_receipts": skill.get("experience_receipts", []),
"authority_granted": False,
"registry_version": registry["version"],
}

View file

@ -0,0 +1,48 @@
import json
import tempfile
import unittest
from pathlib import Path
from compile_emergent_skills import compile_candidates, load_receipts
class EmergentSkillCompilerTests(unittest.TestCase):
def test_repository_receipts_compile_as_candidates_only(self):
result = compile_candidates(load_receipts())
self.assertGreaterEqual(result["source_receipt_count"], 4)
self.assertTrue(result["candidates"])
for candidate in result["candidates"]:
self.assertEqual(candidate["enforcement_level"], "CANDIDATE_ONLY")
self.assertFalse(candidate["hard_block_allowed"])
def test_conflicting_invariant_text_is_rejected(self):
receipt = {
"schema": "guanghu.ops-experience-receipt/v1",
"receipt_id": "A",
"intent": "i",
"scope": "s",
"input": "i",
"evidence": ["e"],
"decision": "d",
"action": "a",
"observed_result": "r",
"correction": "c",
"invariant_id": "INV-X",
"invariant": "one",
"verification": ["v"],
"receipt_path": "p",
"promotion_state": "CANDIDATE_ONLY",
"recorded_at": "2026-07-26T00:00:00Z",
}
with self.assertRaises(ValueError):
compile_candidates([receipt, {**receipt, "receipt_id": "B", "invariant": "two"}])
def test_missing_fields_fail_closed(self):
with tempfile.TemporaryDirectory() as directory:
Path(directory, "bad.json").write_text(json.dumps({"schema": "guanghu.ops-experience-receipt/v1"}))
with self.assertRaises(ValueError):
load_receipts(Path(directory))
if __name__ == "__main__":
unittest.main()

View file

@ -48,6 +48,36 @@ class PersonaSkillResolverTests(unittest.TestCase):
self.assertEqual(result["decision"], "NO_MATCH")
self.assertFalse(result["authority_granted"])
def test_repository_push_requires_separate_transport_proof(self):
result = resolve(
self.registry,
"恢复仓库推送,远端还有待推送提交",
"把授权单当作已经推送",
)
self.assertEqual(result["decision"], "BLOCK")
self.assertEqual(result["matched_skill"], "GHS-003-REPOSITORY-PUSH-PROOF-SEPARATION")
self.assertIn("EXP-20260726-001-AUTHORIZATION-IS-NOT-TRANSPORT", result["experience_receipts"])
self.assertTrue(result["recovery_route"])
def test_enterprise_candidate_blocks_missing_data_disk_assumption(self):
result = resolve(
self.registry,
"部署企业服务器光湖代码频道",
"把缺失的data盘当作已挂载",
)
self.assertEqual(result["decision"], "BLOCK")
self.assertEqual(result["matched_skill"], "GHS-004-AW-ENTERPRISE-HLCC-CANDIDATE")
self.assertEqual(result["enforcement_level"], "CANDIDATE_ONLY")
def test_enterprise_candidate_corrects_personal_source_route(self):
result = resolve(
self.registry,
"恢复AW-GZ-001企业代码频道",
"把个人第五域源码作为企业团队部署源",
)
self.assertEqual(result["decision"], "CORRECT")
self.assertTrue(result["deprecated_hits"])
if __name__ == "__main__":
unittest.main()