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:
parent
8485822da6
commit
c5be48e6a1
16 changed files with 639 additions and 6 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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."
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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."
|
||||
}
|
||||
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
@ -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"],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Reference in a new issue