已合并
docs: 添加仓库本地 Codex 知识库框架 #14
tkzty创建于 6月17日
docs: 添加仓库本地 Codex 知识库框架 #14
已合并
共 25 个文件变更+875-1
| @@ -0,0 +1,19 @@ | |||
| 1 | +# Local generated state | ||
| 2 | +*.log | ||
| 3 | +*.tmp | ||
| 4 | +*.bak | ||
| 5 | +__pycache__/ | ||
| 6 | +*.py[cod] | ||
| 7 | + | ||
| 8 | +# Private or machine-local material | ||
| 9 | +.env | ||
| 10 | +.env.* | ||
| 11 | +*.pem | ||
| 12 | +*.key | ||
| 13 | +*token* | ||
| 14 | +*secret* | ||
| 15 | +*password* | ||
| 16 | + | ||
| 17 | +# Keep inbox discoverable but avoid committing scratch notes by default. | ||
| 18 | +inbox/* | ||
| 19 | +!inbox/README.md | ||
| @@ -0,0 +1,38 @@ | |||
| 1 | +# elec-ops-inspection Knowledge Scaffold | ||
| 2 | + | ||
| 3 | +This directory is a repo-local Codex knowledge scaffold for | ||
| 4 | +`cann/elec-ops-inspection`. | ||
| 5 | + | ||
| 6 | +It provides structure for durable, reviewable project context without importing | ||
| 7 | +the contents of any personal knowledge base. Keep notes small, factual, and tied | ||
| 8 | +to public repository evidence or user-provided task context. | ||
| 9 | + | ||
| 10 | +## How To Use | ||
| 11 | + | ||
| 12 | +1. Read `registry.yaml`. | ||
| 13 | +2. Choose the matching `projects`, `domains`, or `learning` entry. | ||
| 14 | +3. Read only the bootstrap files listed for that entry. | ||
| 15 | +4. If a task changes project status or durable decisions, update the relevant | ||
| 16 | + project package file. | ||
| 17 | + | ||
| 18 | +## What Belongs Here | ||
| 19 | + | ||
| 20 | +- Repository-level context that helps future Codex sessions resume work. | ||
| 21 | +- Public operator documentation reading paths. | ||
| 22 | +- Decisions about how this repository organizes Codex skills and knowledge. | ||
| 23 | +- Templates for adding new project, domain, or learning packages. | ||
| 24 | + | ||
| 25 | +## What Does Not Belong Here | ||
| 26 | + | ||
| 27 | +- Personal user profiles or cross-workspace memories. | ||
| 28 | +- Private datasets, logs, access tokens, account credentials, or local secrets. | ||
| 29 | +- Claimed accuracy, latency, throughput, or hardware support without evidence. | ||
| 30 | +- Generated build outputs, caches, or environment-specific state. | ||
| 31 | + | ||
| 32 | +## Validation | ||
| 33 | + | ||
| 34 | +Run from the repository root: | ||
| 35 | + | ||
| 36 | +```bash | ||
| 37 | +python .agents/knowledge/tools/validate_kb.py --root .agents/knowledge | ||
| 38 | +``` | ||
| @@ -0,0 +1,14 @@ | |||
| 1 | +# Operator Documentation Bootstrap | ||
| 2 | + | ||
| 3 | +For a new Codex session working on repository context, skill authoring, or | ||
| 4 | +operator documentation: | ||
| 5 | + | ||
| 6 | +1. Read `.agents/knowledge/registry.yaml`. | ||
| 7 | +2. Read `projects/elec-ops-inspection/project-summary.md`. | ||
| 8 | +3. Read `projects/elec-ops-inspection/current-status.md`. | ||
| 9 | +4. Read `projects/elec-ops-inspection/entrypoints.md`. | ||
| 10 | +5. Read this domain's `evidence-rules.md` when the task involves claims about | ||
| 11 | + accuracy, performance, hardware, reproducibility, or PR readiness. | ||
| 12 | + | ||
| 13 | +Do not load unrelated knowledge packages. If a task needs fresh facts, inspect | ||
| 14 | +the live repository files and treat them as the source of truth. | ||
| @@ -0,0 +1,37 @@ | |||
| 1 | +# Evidence Rules | ||
| 2 | + | ||
| 3 | +Use these rules before recording knowledge or drafting PR text. | ||
| 4 | + | ||
| 5 | +## Allowed Without Extra Evidence | ||
| 6 | + | ||
| 7 | +- Public repository paths and file names. | ||
| 8 | +- The existence of operators, skills, templates, or docs in this checkout. | ||
| 9 | +- Task status that is limited to the current PR branch. | ||
| 10 | + | ||
| 11 | +## Requires Source Evidence | ||
| 12 | + | ||
| 13 | +- Accuracy, latency, throughput, memory, or speedup numbers. | ||
| 14 | +- Hardware, CANN version, driver, firmware, or runtime compatibility. | ||
| 15 | +- Dataset coverage, real deployment status, or production readiness. | ||
| 16 | +- Claims that an operator fully matches a framework API. | ||
| 17 | + | ||
| 18 | +## How To Record Unverified Claims | ||
| 19 | + | ||
| 20 | +Write them as requirements or open questions, not facts. Prefer: | ||
| 21 | + | ||
| 22 | +```text | ||
| 23 | +Required evidence: benchmark logs for Ascend 910B with workload shape ... | ||
| 24 | +``` | ||
| 25 | + | ||
| 26 | +Avoid: | ||
| 27 | + | ||
| 28 | +```text | ||
| 29 | +The operator is production-ready and accelerates all workloads. | ||
| 30 | +``` | ||
| 31 | + | ||
| 32 | +## Privacy And Hygiene | ||
| 33 | + | ||
| 34 | +- Never store credentials, tokens, account cookies, private URLs, or secrets. | ||
| 35 | +- Do not copy private user knowledge into this repository. | ||
| 36 | +- Keep local absolute paths out of committed notes unless they are only examples. | ||
| 37 | +- Do not commit scratch files from `inbox/` unless they are cleaned and reviewed. | ||
| @@ -0,0 +1,30 @@ | |||
| 1 | +# Operator Documentation And Evidence Review | ||
| 2 | + | ||
| 3 | +## Scope | ||
| 4 | + | ||
| 5 | +Use this domain for tasks that preserve reusable context about | ||
| 6 | +`elec-ops-inspection` operator documentation, local Codex skills, benchmark | ||
| 7 | +evidence expectations, and PR-ready review notes. | ||
| 8 | + | ||
| 9 | +## Goals | ||
| 10 | + | ||
| 11 | +- Keep future Codex sessions oriented without rereading unrelated files. | ||
| 12 | +- Separate durable project context from task-specific scratch work. | ||
| 13 | +- Record evidence requirements before claiming accuracy, performance, hardware | ||
| 14 | + support, or production readiness. | ||
| 15 | +- Keep the knowledge base public and reviewable. | ||
| 16 | + | ||
| 17 | +## Common Inputs | ||
| 18 | + | ||
| 19 | +- Root `README.md`. | ||
| 20 | +- Operator README or usage documents under `optimized_transducer/` and | ||
| 21 | + `unique_v3/`. | ||
| 22 | +- `.agents/skills/*/SKILL.md` and nearby references. | ||
| 23 | +- User-provided benchmark logs, accuracy reports, or PR diffs. | ||
| 24 | + | ||
| 25 | +## Common Outputs | ||
| 26 | + | ||
| 27 | +- A small status update in `projects/elec-ops-inspection/current-status.md`. | ||
| 28 | +- A durable decision in `projects/elec-ops-inspection/decisions.md`. | ||
| 29 | +- A new template or checklist when repeated tasks need structure. | ||
| 30 | +- A PR-ready summary that distinguishes facts from required follow-up evidence. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | +# Inbox | ||
| 2 | + | ||
| 3 | +Temporary holding area for cleaned, non-secret notes that may become public | ||
| 4 | +knowledge-base entries. | ||
| 5 | + | ||
| 6 | +Files in this folder are ignored by default except this README. Review and move | ||
| 7 | +useful material into `projects/`, `domains/`, `learning/`, or `references/` | ||
| 8 | +before committing it. | ||
| @@ -0,0 +1,7 @@ | |||
| 1 | +# Learning Topic Index | ||
| 2 | + | ||
| 3 | +This folder is reserved for public, repository-relevant learning routes. | ||
| 4 | + | ||
| 5 | +Add a learning topic only when it helps contributors understand this repository, | ||
| 6 | +such as an operator development reading path or an Ascend/CANN documentation | ||
| 7 | +route. Do not add personal study journals or private notes. | ||
| @@ -0,0 +1,26 @@ | |||
| 1 | +# elec-ops-inspection Current Status | ||
| 2 | + | ||
| 3 | +Last updated: 2026-06-17 | ||
| 4 | + | ||
| 5 | +## Current Phase | ||
| 6 | + | ||
| 7 | +Adding a repo-local Codex knowledge scaffold that preserves framework structure | ||
| 8 | +without importing personal knowledge content. | ||
| 9 | + | ||
| 10 | +## Completed | ||
| 11 | + | ||
| 12 | +- Added `.agents/knowledge/registry.yaml` with repo-local project, domain, and | ||
| 13 | + learning entries. | ||
| 14 | +- Added bootstrap docs for `projects/elec-ops-inspection`. | ||
| 15 | +- Added operator-documentation evidence rules. | ||
| 16 | +- Added templates and an offline validator. | ||
| 17 | + | ||
| 18 | +## Next Steps | ||
| 19 | + | ||
| 20 | +- Keep future updates small and tied to public repository evidence. | ||
| 21 | +- Record durable decisions in `decisions.md` only when they affect future work. | ||
| 22 | +- Run the offline validator before submitting knowledge-base changes. | ||
| 23 | + | ||
| 24 | +## Blockers | ||
| 25 | + | ||
| 26 | +- None recorded. | ||
| @@ -0,0 +1,26 @@ | |||
| 1 | +# elec-ops-inspection Decisions | ||
| 2 | + | ||
| 3 | +## 2026-06-17: Keep Repo Knowledge Under .agents/knowledge | ||
| 4 | + | ||
| 5 | +Decision: Store Codex-oriented repository knowledge under `.agents/knowledge` | ||
| 6 | +instead of placing a separate personal knowledge-base layout at the repository | ||
| 7 | +root. | ||
| 8 | + | ||
| 9 | +Reason: The repository already uses `.agents/skills`, so `.agents/knowledge` | ||
| 10 | +keeps Codex assets together and avoids confusing project source files with | ||
| 11 | +assistant support files. | ||
| 12 | + | ||
| 13 | +Impact: Knowledge-base paths in `registry.yaml` are relative to | ||
| 14 | +`.agents/knowledge`; the repository root keeps only a lightweight `AGENTS.md` | ||
| 15 | +entry point. | ||
| 16 | + | ||
| 17 | +## 2026-06-17: Do Not Import Personal Knowledge Content | ||
| 18 | + | ||
| 19 | +Decision: Only commit the reusable framework, templates, validator, and public | ||
| 20 | +repository context. | ||
| 21 | + | ||
| 22 | +Reason: Personal profiles, cross-workspace memories, private project notes, and | ||
| 23 | +account-specific workflow details do not belong in the public repository. | ||
| 24 | + | ||
| 25 | +Impact: Future notes must be public, reviewable, and connected to repository | ||
| 26 | +evidence or explicit task context. | ||
| @@ -0,0 +1,14 @@ | |||
| 1 | +# elec-ops-inspection Entrypoints | ||
| 2 | + | ||
| 3 | +New Codex sessions should restore context in this order: | ||
| 4 | + | ||
| 5 | +1. `.agents/knowledge/registry.yaml` | ||
| 6 | +2. `.agents/knowledge/projects/elec-ops-inspection/project-summary.md` | ||
| 7 | +3. `.agents/knowledge/projects/elec-ops-inspection/current-status.md` | ||
| 8 | +4. `.agents/knowledge/projects/elec-ops-inspection/entrypoints.md` | ||
| 9 | + | ||
| 10 | +Load `decisions.md` only when the task involves existing decisions, path | ||
| 11 | +conventions, repeated judgments, or knowledge-base maintenance. | ||
| 12 | + | ||
| 13 | +After reading these files, inspect the live repository files relevant to the | ||
| 14 | +task before changing source code, docs, or skills. | ||
| @@ -0,0 +1,25 @@ | |||
| 1 | +# elec-ops-inspection Project Summary | ||
| 2 | + | ||
| 3 | +## Project Positioning | ||
| 4 | + | ||
| 5 | +`elec-ops-inspection` is a CANN community repository for power equipment | ||
| 6 | +inspection operators and related Ascend/CANN documentation. | ||
| 7 | + | ||
| 8 | +## Current Repository Areas | ||
| 9 | + | ||
| 10 | +- `optimized_transducer/`: RNN-T related operator implementation and docs. | ||
| 11 | +- `unique_v3/`: high-performance unique/deduplication operator implementation | ||
| 12 | + and docs. | ||
| 13 | +- `.agents/skills/`: repository-local Codex skills. | ||
| 14 | +- `.agents/knowledge/`: repo-local knowledge scaffold for durable context. | ||
| 15 | + | ||
| 16 | +## External Links | ||
| 17 | + | ||
| 18 | +- Upstream repository: `https://gitcode.com/cann/elec-ops-inspection` | ||
| 19 | + | ||
| 20 | +## Reading Entry Points | ||
| 21 | + | ||
| 22 | +- `README.md` | ||
| 23 | +- `optimized_transducer/README.md` | ||
| 24 | +- `unique_v3/README.md` | ||
| 25 | +- `.agents/skills/*/SKILL.md` | ||
| @@ -0,0 +1,7 @@ | |||
| 1 | +# References | ||
| 2 | + | ||
| 3 | +Use this folder for small, curated references that support repository work. | ||
| 4 | + | ||
| 5 | +Each reference should explain why it matters, which section to read, and what | ||
| 6 | +current conclusion it supports. Prefer links and short notes over copied source | ||
| 7 | +material. | ||
| @@ -0,0 +1,50 @@ | |||
| 1 | +version: 1 | ||
| 2 | +root: . | ||
| 3 | + | ||
| 4 | +usage: | ||
| 5 | + purpose: Repo-local Codex knowledge scaffold for cann/elec-ops-inspection. | ||
| 6 | + startup_rule: Read this registry first, then load only matching bootstrap docs. | ||
| 7 | + path_rule: Paths are relative to .agents/knowledge unless otherwise stated. | ||
| 8 | + avoid: Do not bulk-read the knowledge base or import personal knowledge content. | ||
| 9 | + precedence: | ||
| 10 | + - System/developer instructions | ||
| 11 | + - Current user request | ||
| 12 | + - Repository AGENTS.md, README files, source code, and tests | ||
| 13 | + - This repo-local knowledge base | ||
| 14 | + | ||
| 15 | +domains: | ||
| 16 | + operator-documentation: | ||
| 17 | + title: Operator documentation and evidence review | ||
| 18 | + kb: domains/operator-documentation | ||
| 19 | + bootstrap: | ||
| 20 | + - overview.md | ||
| 21 | + - bootstrap.md | ||
| 22 | + - evidence-rules.md | ||
| 23 | + | ||
| 24 | +projects: | ||
| 25 | + elec-ops-inspection: | ||
| 26 | + title: elec-ops-inspection repository context | ||
| 27 | + kind: operator-documentation | ||
| 28 | + workspace: ../.. | ||
| 29 | + kb: projects/elec-ops-inspection | ||
| 30 | + bootstrap: | ||
| 31 | + - project-summary.md | ||
| 32 | + - current-status.md | ||
| 33 | + - entrypoints.md | ||
| 34 | + related_domains: | ||
| 35 | + - operator-documentation | ||
| 36 | + | ||
| 37 | +learning: | ||
| 38 | + index: | ||
| 39 | + title: Learning topic index | ||
| 40 | + kb: learning | ||
| 41 | + bootstrap: | ||
| 42 | + - README.md | ||
| 43 | + | ||
| 44 | +conventions: | ||
| 45 | + status_file: current-status.md | ||
| 46 | + decision_file: decisions.md | ||
| 47 | + decision_load_strategy: on_demand_unless_listed_in_bootstrap | ||
| 48 | + entrypoint_file: entrypoints.md | ||
| 49 | + project_summary_file: project-summary.md | ||
| 50 | + date_format: YYYY-MM-DD | ||
| @@ -0,0 +1,19 @@ | |||
| 1 | +# <Project Name> Current Status | ||
| 2 | + | ||
| 3 | +Last updated: YYYY-MM-DD | ||
| 4 | + | ||
| 5 | +## Current Phase | ||
| 6 | + | ||
| 7 | +TODO. | ||
| 8 | + | ||
| 9 | +## Completed | ||
| 10 | + | ||
| 11 | +TODO. | ||
| 12 | + | ||
| 13 | +## Next Steps | ||
| 14 | + | ||
| 15 | +TODO. | ||
| 16 | + | ||
| 17 | +## Blockers | ||
| 18 | + | ||
| 19 | +TODO. | ||
| @@ -0,0 +1,9 @@ | |||
| 1 | +# <Project Name> Decisions | ||
| 2 | + | ||
| 3 | +## YYYY-MM-DD: <Decision Title> | ||
| 4 | + | ||
| 5 | +Decision: TODO. | ||
| 6 | + | ||
| 7 | +Reason: TODO. | ||
| 8 | + | ||
| 9 | +Impact: TODO. | ||
| @@ -0,0 +1,17 @@ | |||
| 1 | +# <Domain Name> | ||
| 2 | + | ||
| 3 | +## Scope | ||
| 4 | + | ||
| 5 | +TODO. | ||
| 6 | + | ||
| 7 | +## Goals | ||
| 8 | + | ||
| 9 | +TODO. | ||
| 10 | + | ||
| 11 | +## Common Inputs | ||
| 12 | + | ||
| 13 | +TODO. | ||
| 14 | + | ||
| 15 | +## Common Outputs | ||
| 16 | + | ||
| 17 | +TODO. | ||
| @@ -0,0 +1,14 @@ | |||
| 1 | +# <Project Name> Entrypoints | ||
| 2 | + | ||
| 3 | +New Codex sessions should restore context in this order: | ||
| 4 | + | ||
| 5 | +1. `<kb-root>/registry.yaml` | ||
| 6 | +2. `<project-kb>/project-summary.md` | ||
| 7 | +3. `<project-kb>/current-status.md` | ||
| 8 | +4. `<project-kb>/entrypoints.md` | ||
| 9 | + | ||
| 10 | +Load `<project-kb>/decisions.md` only when the task involves existing | ||
| 11 | +decisions, path conventions, repeated judgments, or knowledge-base maintenance. | ||
| 12 | + | ||
| 13 | +After reading these files, inspect the live repository files relevant to the | ||
| 14 | +task. | ||
| @@ -0,0 +1,21 @@ | |||
| 1 | +# <Learning Topic> | ||
| 2 | + | ||
| 3 | +## Learning Goal | ||
| 4 | + | ||
| 5 | +TODO. | ||
| 6 | + | ||
| 7 | +## Current Progress | ||
| 8 | + | ||
| 9 | +TODO. | ||
| 10 | + | ||
| 11 | +## Reading Route | ||
| 12 | + | ||
| 13 | +TODO. | ||
| 14 | + | ||
| 15 | +## Questions | ||
| 16 | + | ||
| 17 | +TODO. | ||
| 18 | + | ||
| 19 | +## References | ||
| 20 | + | ||
| 21 | +TODO. | ||
| @@ -0,0 +1,21 @@ | |||
| 1 | +# <Project Name> Project Summary | ||
| 2 | + | ||
| 3 | +## Project Positioning | ||
| 4 | + | ||
| 5 | +TODO. | ||
| 6 | + | ||
| 7 | +## Current Goal | ||
| 8 | + | ||
| 9 | +TODO. | ||
| 10 | + | ||
| 11 | +## Repository Paths | ||
| 12 | + | ||
| 13 | +TODO. | ||
| 14 | + | ||
| 15 | +## External Links | ||
| 16 | + | ||
| 17 | +TODO. | ||
| 18 | + | ||
| 19 | +## Key Files And Directories | ||
| 20 | + | ||
| 21 | +TODO. | ||
| @@ -0,0 +1,274 @@ | |||
| 1 | +#!/usr/bin/env python3 | ||
| 2 | +"""Offline validator for the elec-ops-inspection repo-local knowledge base.""" | ||
| 3 | + | ||
| 4 | +from __future__ import annotations | ||
| 5 | + | ||
| 6 | +import argparse | ||
| 7 | +import sys | ||
| 8 | +from dataclasses import dataclass | ||
| 9 | +from pathlib import Path | ||
| 10 | +from typing import Any | ||
| 11 | + | ||
| 12 | + | ||
| 13 | +UTF8_BOM = b"\xef\xbb\xbf" | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + | ||
| 17 | +class Finding: | ||
| 18 | + level: str | ||
| 19 | + path: str | ||
| 20 | + message: str | ||
| 21 | + | ||
| 22 | + | ||
| 23 | +def parse_args() -> argparse.Namespace: | ||
| 24 | + default_root = Path(__file__).resolve().parents[1] | ||
| 25 | + parser = argparse.ArgumentParser( | ||
| 26 | + description="Validate .agents/knowledge without network access." | ||
| 27 | + ) | ||
| 28 | + parser.add_argument( | ||
| 29 | + "--root", | ||
| 30 | + type=Path, | ||
| 31 | + default=default_root, | ||
| 32 | + help="Knowledge base root. Default: inferred from this script.", | ||
| 33 | + ) | ||
| 34 | + parser.add_argument( | ||
| 35 | + "--fail-on-warning", | ||
| 36 | + action="store_true", | ||
| 37 | + help="Return non-zero when warnings are found.", | ||
| 38 | + ) | ||
| 39 | + return parser.parse_args() | ||
| 40 | + | ||
| 41 | + | ||
| 42 | +def display_path(path: Path, root: Path) -> str: | ||
| 43 | + try: | ||
| 44 | + return path.resolve().relative_to(root.resolve()).as_posix() | ||
| 45 | + except ValueError: | ||
| 46 | + return path.as_posix() | ||
| 47 | + | ||
| 48 | + | ||
| 49 | +def add(findings: list[Finding], level: str, path: Path, message: str, root: Path) -> None: | ||
| 50 | + findings.append(Finding(level, display_path(path, root), message)) | ||
| 51 | + | ||
| 52 | + | ||
| 53 | +def parse_scalar(value: str) -> Any: | ||
| 54 | + value = value.strip() | ||
| 55 | + if value == "": | ||
| 56 | + return "" | ||
| 57 | + if value in ("true", "false"): | ||
| 58 | + return value == "true" | ||
| 59 | + if value.isdigit(): | ||
| 60 | + return int(value) | ||
| 61 | + return value.strip("'\"") | ||
| 62 | + | ||
| 63 | + | ||
| 64 | +def parse_registry_subset(path: Path) -> dict[str, Any]: | ||
| 65 | + data: dict[str, Any] = { | ||
| 66 | + "domains": {}, | ||
| 67 | + "projects": {}, | ||
| 68 | + "learning": {}, | ||
| 69 | + "conventions": {}, | ||
| 70 | + } | ||
| 71 | + section: str | None = None | ||
| 72 | + item_name: str | None = None | ||
| 73 | + current_list: tuple[str, str | None, str] | None = None | ||
| 74 | + | ||
| 75 | + for raw_line in path.read_text(encoding="utf-8").splitlines(): | ||
| 76 | + if not raw_line.strip() or raw_line.lstrip().startswith("#"): | ||
| 77 | + continue | ||
| 78 | + indent = len(raw_line) - len(raw_line.lstrip(" ")) | ||
| 79 | + text = raw_line.strip() | ||
| 80 | + | ||
| 81 | + if indent == 0: | ||
| 82 | + item_name = None | ||
| 83 | + current_list = None | ||
| 84 | + if text.endswith(":"): | ||
| 85 | + section = text[:-1] | ||
| 86 | + data.setdefault(section, {}) | ||
| 87 | + continue | ||
| 88 | + key, value = text.split(":", 1) | ||
| 89 | + data[key.strip()] = parse_scalar(value) | ||
| 90 | + section = key.strip() | ||
| 91 | + continue | ||
| 92 | + | ||
| 93 | + if section in ("domains", "projects", "learning"): | ||
| 94 | + if indent == 2 and text.endswith(":"): | ||
| 95 | + item_name = text[:-1] | ||
| 96 | + data[section][item_name] = {} | ||
| 97 | + current_list = None | ||
| 98 | + continue | ||
| 99 | + if indent == 4 and item_name and ":" in text: | ||
| 100 | + key, value = text.split(":", 1) | ||
| 101 | + key = key.strip() | ||
| 102 | + if value.strip() == "": | ||
| 103 | + data[section][item_name][key] = [] | ||
| 104 | + current_list = (section, item_name, key) | ||
| 105 | + else: | ||
| 106 | + data[section][item_name][key] = parse_scalar(value) | ||
| 107 | + current_list = None | ||
| 108 | + continue | ||
| 109 | + if indent == 6 and text.startswith("- ") and current_list: | ||
| 110 | + list_section, list_item, list_key = current_list | ||
| 111 | + data[list_section][list_item][list_key].append(parse_scalar(text[2:])) | ||
| 112 | + continue | ||
| 113 | + | ||
| 114 | + if section == "conventions" and indent == 2 and ":" in text: | ||
| 115 | + key, value = text.split(":", 1) | ||
| 116 | + data["conventions"][key.strip()] = parse_scalar(value) | ||
| 117 | + | ||
| 118 | + return data | ||
| 119 | + | ||
| 120 | + | ||
| 121 | +def load_registry(path: Path) -> dict[str, Any]: | ||
| 122 | + try: | ||
| 123 | + import yaml # type: ignore | ||
| 124 | + | ||
| 125 | + parsed = yaml.safe_load(path.read_text(encoding="utf-8")) | ||
| 126 | + if isinstance(parsed, dict): | ||
| 127 | + return parsed | ||
| 128 | + except Exception: | ||
| 129 | + pass | ||
| 130 | + return parse_registry_subset(path) | ||
| 131 | + | ||
| 132 | + | ||
| 133 | +def as_list(value: Any) -> list[Any]: | ||
| 134 | + if value is None: | ||
| 135 | + return [] | ||
| 136 | + if isinstance(value, list): | ||
| 137 | + return value | ||
| 138 | + return [value] | ||
| 139 | + | ||
| 140 | + | ||
| 141 | +def validate_bootstrap( | ||
| 142 | + findings: list[Finding], | ||
| 143 | + root: Path, | ||
| 144 | + registry_path: Path, | ||
| 145 | + item_label: str, | ||
| 146 | + item: dict[str, Any], | ||
| 147 | +) -> None: | ||
| 148 | + kb_value = item.get("kb") | ||
| 149 | + if not kb_value: | ||
| 150 | + add(findings, "ERROR", registry_path, f"{item_label} is missing kb", root) | ||
| 151 | + return | ||
| 152 | + | ||
| 153 | + kb_dir = root / str(kb_value) | ||
| 154 | + if not kb_dir.is_dir(): | ||
| 155 | + add(findings, "ERROR", kb_dir, f"{item_label} kb directory does not exist", root) | ||
| 156 | + return | ||
| 157 | + | ||
| 158 | + for rel_file in as_list(item.get("bootstrap")): | ||
| 159 | + target = kb_dir / str(rel_file) | ||
| 160 | + if not target.is_file(): | ||
| 161 | + add(findings, "ERROR", target, f"{item_label} bootstrap file does not exist", root) | ||
| 162 | + | ||
| 163 | + | ||
| 164 | +def validate_registry(findings: list[Finding], root: Path, registry: dict[str, Any]) -> None: | ||
| 165 | + registry_path = root / "registry.yaml" | ||
| 166 | + for section in ("domains", "projects", "learning"): | ||
| 167 | + section_items = registry.get(section, {}) | ||
| 168 | + if not isinstance(section_items, dict): | ||
| 169 | + add(findings, "ERROR", registry_path, f"{section} must be a mapping", root) | ||
| 170 | + continue | ||
| 171 | + for name, item in section_items.items(): | ||
| 172 | + if not isinstance(item, dict): | ||
| 173 | + add(findings, "ERROR", registry_path, f"{section}.{name} must be a mapping", root) | ||
| 174 | + continue | ||
| 175 | + validate_bootstrap(findings, root, registry_path, f"{section}.{name}", item) | ||
| 176 | + | ||
| 177 | + domains = registry.get("domains", {}) | ||
| 178 | + projects = registry.get("projects", {}) | ||
| 179 | + if isinstance(projects, dict): | ||
| 180 | + for name, item in projects.items(): | ||
| 181 | + if not isinstance(item, dict): | ||
| 182 | + continue | ||
| 183 | + for domain in as_list(item.get("related_domains")): | ||
| 184 | + if domain not in domains: | ||
| 185 | + add( | ||
| 186 | + findings, | ||
| 187 | + "ERROR", | ||
| 188 | + registry_path, | ||
| 189 | + f"projects.{name} references unknown related_domain {domain!r}", | ||
| 190 | + root, | ||
| 191 | + ) | ||
| 192 | + workspace_value = item.get("workspace") | ||
| 193 | + if workspace_value: | ||
| 194 | + workspace = (root / str(workspace_value)).resolve() | ||
| 195 | + if not workspace.exists(): | ||
| 196 | + add(findings, "WARN", workspace, f"projects.{name}.workspace does not exist", root) | ||
| 197 | + | ||
| 198 | + | ||
| 199 | +def validate_project_packages( | ||
| 200 | + findings: list[Finding], root: Path, registry: dict[str, Any] | ||
| 201 | +) -> None: | ||
| 202 | + conventions = registry.get("conventions", {}) | ||
| 203 | + if not isinstance(conventions, dict): | ||
| 204 | + conventions = {} | ||
| 205 | + required = [ | ||
| 206 | + conventions.get("project_summary_file", "project-summary.md"), | ||
| 207 | + conventions.get("status_file", "current-status.md"), | ||
| 208 | + conventions.get("decision_file", "decisions.md"), | ||
| 209 | + conventions.get("entrypoint_file", "entrypoints.md"), | ||
| 210 | + ] | ||
| 211 | + | ||
| 212 | + projects = registry.get("projects", {}) | ||
| 213 | + if not isinstance(projects, dict): | ||
| 214 | + return | ||
| 215 | + for name, item in projects.items(): | ||
| 216 | + if not isinstance(item, dict) or not item.get("kb"): | ||
| 217 | + continue | ||
| 218 | + kb_dir = root / str(item["kb"]) | ||
| 219 | + for filename in required: | ||
| 220 | + target = kb_dir / str(filename) | ||
| 221 | + if not target.is_file(): | ||
| 222 | + add(findings, "ERROR", target, f"projects.{name} is missing {filename}", root) | ||
| 223 | + | ||
| 224 | + | ||
| 225 | +def validate_no_utf8_bom(findings: list[Finding], root: Path) -> None: | ||
| 226 | + for path in sorted(root.rglob("*")): | ||
| 227 | + if ".git" in path.parts or not path.is_file(): | ||
| 228 | + continue | ||
| 229 | + try: | ||
| 230 | + with path.open("rb") as handle: | ||
| 231 | + prefix = handle.read(len(UTF8_BOM)) | ||
| 232 | + except OSError: | ||
| 233 | + continue | ||
| 234 | + if prefix == UTF8_BOM: | ||
| 235 | + add(findings, "ERROR", path, "file starts with UTF-8 BOM", root) | ||
| 236 | + | ||
| 237 | + | ||
| 238 | +def print_findings(findings: list[Finding]) -> None: | ||
| 239 | + for finding in findings: | ||
| 240 | + print(f"{finding.level}: {finding.path}: {finding.message}") | ||
| 241 | + | ||
| 242 | + | ||
| 243 | +def main() -> int: | ||
| 244 | + args = parse_args() | ||
| 245 | + root = args.root.resolve() | ||
| 246 | + findings: list[Finding] = [] | ||
| 247 | + | ||
| 248 | + registry_path = root / "registry.yaml" | ||
| 249 | + if not registry_path.is_file(): | ||
| 250 | + add(findings, "ERROR", registry_path, "registry.yaml does not exist", root) | ||
| 251 | + print_findings(findings) | ||
| 252 | + return 1 | ||
| 253 | + | ||
| 254 | + registry = load_registry(registry_path) | ||
| 255 | + validate_registry(findings, root, registry) | ||
| 256 | + validate_project_packages(findings, root, registry) | ||
| 257 | + validate_no_utf8_bom(findings, root) | ||
| 258 | + | ||
| 259 | + print_findings(findings) | ||
| 260 | + error_count = sum(1 for finding in findings if finding.level == "ERROR") | ||
| 261 | + warn_count = sum(1 for finding in findings if finding.level == "WARN") | ||
| 262 | + | ||
| 263 | + if error_count: | ||
| 264 | + print(f"FAILED: {error_count} error(s), {warn_count} warning(s)") | ||
| 265 | + return 1 | ||
| 266 | + if warn_count and args.fail_on_warning: | ||
| 267 | + print(f"FAILED: 0 error(s), {warn_count} warning(s)") | ||
| 268 | + return 1 | ||
| 269 | + print(f"OK: offline validation passed with {warn_count} warning(s)") | ||
| 270 | + return 0 | ||
| 271 | + | ||
| 272 | + | ||
| 273 | +if __name__ == "__main__": | ||
| 274 | + raise SystemExit(main()) | ||
| @@ -0,0 +1,95 @@ | |||
| 1 | +--- | ||
| 2 | +name: electric-inspection-knowledge-base | ||
| 3 | +description: Use when maintaining or using the repo-local Codex knowledge base for elec-ops-inspection, including .agents/knowledge registry updates, bootstrap files, public project context, durable decisions, templates, validation, and PR preparation without importing personal knowledge content. | ||
| 4 | +--- | ||
| 5 | + | ||
| 6 | +# Electric Inspection Knowledge Base | ||
| 7 | + | ||
| 8 | +Maintain and use the repo-local knowledge scaffold for | ||
| 9 | +`cann/elec-ops-inspection`. | ||
| 10 | + | ||
| 11 | +## Scope | ||
| 12 | + | ||
| 13 | +Use this skill for: | ||
| 14 | + | ||
| 15 | +- Restoring repository context through `.agents/knowledge/registry.yaml`. | ||
| 16 | +- Adding or updating public project, domain, learning, or reference packages. | ||
| 17 | +- Recording durable decisions that help future Codex sessions. | ||
| 18 | +- Validating the knowledge scaffold before PR submission. | ||
| 19 | + | ||
| 20 | +Do not use this skill to store personal memories, credentials, private datasets, | ||
| 21 | +machine-local state, or unsupported claims. | ||
| 22 | + | ||
| 23 | +Do not use this skill to design new `.agents/skills` contributions or to review | ||
| 24 | +operator PR evidence. Use `electric-inspection-skill-creator` for skill | ||
| 25 | +authoring and a task-specific operator review skill for PR readiness. | ||
| 26 | + | ||
| 27 | +## Workflow | ||
| 28 | + | ||
| 29 | +### Step 1: Load The Registry | ||
| 30 | + | ||
| 31 | +Read `.agents/knowledge/registry.yaml` first. Choose the smallest matching entry | ||
| 32 | +under `projects`, `domains`, or `learning`. | ||
| 33 | + | ||
| 34 | +### Step 2: Read Bootstrap Files Only | ||
| 35 | + | ||
| 36 | +Read only the bootstrap files listed for the matched entry. Load | ||
| 37 | +`decisions.md` only when the task concerns existing decisions, path conventions, | ||
| 38 | +repeated judgments, or knowledge-base maintenance. | ||
| 39 | + | ||
| 40 | +### Step 3: Check Live Repository Evidence | ||
| 41 | + | ||
| 42 | +Before recording facts, inspect the relevant live files such as: | ||
| 43 | + | ||
| 44 | +```text | ||
| 45 | +README.md | ||
| 46 | +optimized_transducer/README.md | ||
| 47 | +unique_v3/README.md | ||
| 48 | +.agents/skills/*/SKILL.md | ||
| 49 | +``` | ||
| 50 | + | ||
| 51 | +Repository files and user-provided evidence override knowledge-base notes. | ||
| 52 | + | ||
| 53 | +### Step 4: Update The Smallest File | ||
| 54 | + | ||
| 55 | +Use `references/maintenance-checklist.md`. | ||
| 56 | + | ||
| 57 | +- Status or next work: update `projects/elec-ops-inspection/current-status.md`. | ||
| 58 | +- Durable conventions: update `projects/elec-ops-inspection/decisions.md`. | ||
| 59 | +- New repeated workflow: add or update a domain file. | ||
| 60 | +- New public reference: add a short note under `references/`. | ||
| 61 | +- New reusable package: start from `templates/`. | ||
| 62 | + | ||
| 63 | +### Step 5: Validate | ||
| 64 | + | ||
| 65 | +Run: | ||
| 66 | + | ||
| 67 | +```bash | ||
| 68 | +python .agents/knowledge/tools/validate_kb.py --root .agents/knowledge | ||
| 69 | +git diff --check | ||
| 70 | +``` | ||
| 71 | + | ||
| 72 | +Also scan changed files for tokens, private keys, passwords, account cookies, | ||
| 73 | +and local-only paths before preparing a PR. | ||
| 74 | + | ||
| 75 | +### Step 6: Prepare PR Text | ||
| 76 | + | ||
| 77 | +Use `references/pr-description-template.md`. State that this PR adds a | ||
| 78 | +repo-local knowledge scaffold and does not import personal knowledge content. | ||
| 79 | +Also state how the knowledge scaffold differs from existing repository-local | ||
| 80 | +skills: it preserves durable context and bootstrap paths, while other skills | ||
| 81 | +execute task workflows. | ||
| 82 | + | ||
| 83 | +## Error Handling | ||
| 84 | + | ||
| 85 | +- Missing evidence: record the missing input as a requirement, not a fact. | ||
| 86 | +- Private content found: remove it before validation and PR preparation. | ||
| 87 | +- Duplicate package: update the existing package instead of creating another. | ||
| 88 | +- Duplicate skill scope: stop and use the existing task skill instead of | ||
| 89 | + putting workflow instructions into the knowledge base. | ||
| 90 | +- Validator failure: fix the registry, bootstrap path, or required project file. | ||
| 91 | + | ||
| 92 | +## References | ||
| 93 | + | ||
| 94 | +- [Maintenance Checklist](references/maintenance-checklist.md) | ||
| 95 | +- [PR Description Template](references/pr-description-template.md) | ||
| @@ -0,0 +1,46 @@ | |||
| 1 | +# Maintenance Checklist | ||
| 2 | + | ||
| 3 | +Use this checklist before committing knowledge-base changes. | ||
| 4 | + | ||
| 5 | +## Structure | ||
| 6 | + | ||
| 7 | +- `registry.yaml` points to existing `kb` directories. | ||
| 8 | +- Each bootstrap file listed in the registry exists. | ||
| 9 | +- Project packages include `project-summary.md`, `current-status.md`, | ||
| 10 | + `entrypoints.md`, and `decisions.md`. | ||
| 11 | +- Paths are relative to `.agents/knowledge` unless the file says otherwise. | ||
| 12 | + | ||
| 13 | +## Content | ||
| 14 | + | ||
| 15 | +- Notes are public, reviewable, and connected to repository evidence. | ||
| 16 | +- Status entries are concise and dated. | ||
| 17 | +- Decisions include decision, reason, and impact. | ||
| 18 | +- Knowledge entries preserve durable context; task execution workflows belong in | ||
| 19 | + `.agents/skills`, not in `.agents/knowledge`. | ||
| 20 | +- Claims about performance, accuracy, hardware, datasets, or production use are | ||
| 21 | + backed by source evidence or written as required evidence. | ||
| 22 | + | ||
| 23 | +## Privacy | ||
| 24 | + | ||
| 25 | +- No personal profiles or cross-workspace memories. | ||
| 26 | +- No tokens, cookies, private keys, passwords, or account credentials. | ||
| 27 | +- No private datasets, private URLs, or local generated logs. | ||
| 28 | +- No copied content from a personal knowledge base except generic framework | ||
| 29 | + structure and templates. | ||
| 30 | + | ||
| 31 | +## Validation | ||
| 32 | + | ||
| 33 | +```bash | ||
| 34 | +python .agents/knowledge/tools/validate_kb.py --root .agents/knowledge | ||
| 35 | +git diff --check | ||
| 36 | +``` | ||
| 37 | + | ||
| 38 | +Perform a changed-file secret scan before PR submission. | ||
| 39 | + | ||
| 40 | +## Differentiation | ||
| 41 | + | ||
| 42 | +- This scaffold is not another skill authoring workflow. | ||
| 43 | +- It should not duplicate operator readiness, benchmark evidence, or skill | ||
| 44 | + creation instructions. | ||
| 45 | +- Its PR value is durable context restoration, evidence discipline, templates, | ||
| 46 | + and offline validation. | ||
| @@ -0,0 +1,31 @@ | |||
| 1 | +# PR Description Template | ||
| 2 | + | ||
| 3 | +```markdown | ||
| 4 | +## Summary | ||
| 5 | + | ||
| 6 | +- Added: | ||
| 7 | +- Updated: | ||
| 8 | +- Why this belongs in elec-ops-inspection: | ||
| 9 | + | ||
| 10 | +## Knowledge-Base Scope | ||
| 11 | + | ||
| 12 | +- Framework files added: | ||
| 13 | +- Public repository context added: | ||
| 14 | +- Personal or private knowledge intentionally excluded: | ||
| 15 | + | ||
| 16 | +## Differentiation | ||
| 17 | + | ||
| 18 | +- Existing related skills: | ||
| 19 | +- What this knowledge scaffold adds instead: | ||
| 20 | + | ||
| 21 | +## Validation | ||
| 22 | + | ||
| 23 | +- `python .agents/knowledge/tools/validate_kb.py --root .agents/knowledge` | ||
| 24 | +- `git diff --check` | ||
| 25 | +- Changed-file secret scan: | ||
| 26 | + | ||
| 27 | +## Known Limits | ||
| 28 | + | ||
| 29 | +- Hardware or benchmark data not validated: | ||
| 30 | +- Follow-up evidence needed: | ||
| 31 | +``` | ||
| @@ -0,0 +1,20 @@ | |||
| 1 | +# AGENTS.md | ||
| 2 | + | ||
| 3 | +## Repo-Local Knowledge Base | ||
| 4 | + | ||
| 5 | +This repository contains a Codex-oriented knowledge scaffold under | ||
| 6 | +`.agents/knowledge`. | ||
| 7 | + | ||
| 8 | +When a task involves repository context, operator documentation, local skill | ||
| 9 | +authoring, long-running work, recovering previous progress, or knowledge-base | ||
| 10 | +maintenance: | ||
| 11 | + | ||
| 12 | +1. Read `.agents/knowledge/registry.yaml` first. | ||
| 13 | +2. Load only the matching bootstrap files listed in the registry. | ||
| 14 | +3. Treat repository source code, README files, tests, and this `AGENTS.md` as | ||
| 15 | + stronger than notes in `.agents/knowledge`. | ||
| 16 | +4. Do not bulk-read or bulk-import knowledge files. | ||
| 17 | + | ||
| 18 | +The repository knowledge base is for public, reviewable project context only. | ||
| 19 | +Do not store personal notes, private datasets, credentials, account tokens, | ||
| 20 | +local machine secrets, or unverifiable performance claims in it. | ||
| @@ -46,13 +46,19 @@ | |||
| 46 | 3. 参与 Electrical Engineering SIG 定期研讨会 | 46 | 3. 参与 Electrical Engineering SIG 定期研讨会 |
| 47 | 4. 完善文档与示例 | 47 | 4. 完善文档与示例 |
| 48 | 48 | ||
| 49 | -贡献规范请参考 [`CONTRIBUTING.md`]()。 | 49 | +贡献规范请参考 [`CONTRIBUTING.md`](CONTRIBUTING.md),新增算子请统一放入 [`operators/`](operators/) 目录。 |
| 50 | 新增或重写算子说明时,可参考 [`docs/operator-readme-template.md`](docs/operator-readme-template.md)。 | 50 | 新增或重写算子说明时,可参考 [`docs/operator-readme-template.md`](docs/operator-readme-template.md)。 |
| 51 | +设计和记录算子测试时,可使用 [`docs/operator-test-plan-template.md`](docs/operator-test-plan-template.md)。 | ||
| 52 | +涉及接口、行为或安装兼容性变化时,可使用 [`docs/operator-change-note-template.md`](docs/operator-change-note-template.md)。 | ||
| 51 | 53 | ||
| 52 | 仓库提供了面向算子性能证据整理的辅助 Skill:[`inspection-benchmark-evidence`](.agents/skills/inspection-benchmark-evidence/SKILL.md),用于在提交 PR 前检查巡检算子的 benchmark 环境、shape 矩阵、baseline、统计口径和可复现命令。 | 54 | 仓库提供了面向算子性能证据整理的辅助 Skill:[`inspection-benchmark-evidence`](.agents/skills/inspection-benchmark-evidence/SKILL.md),用于在提交 PR 前检查巡检算子的 benchmark 环境、shape 矩阵、baseline、统计口径和可复现命令。 |
| 53 | 55 | ||
| 54 | 仓库提供了面向技能贡献的辅助 Skill:[`electric-inspection-skill-creator`](.agents/skills/electric-inspection-skill-creator/SKILL.md),用于为电力巡检算子场景创建差异化、可验证、可提 PR 的仓库本地 Skill。 | 56 | 仓库提供了面向技能贡献的辅助 Skill:[`electric-inspection-skill-creator`](.agents/skills/electric-inspection-skill-creator/SKILL.md),用于为电力巡检算子场景创建差异化、可验证、可提 PR 的仓库本地 Skill。 |
| 55 | 57 | ||
| 58 | +仓库提供了面向算子贡献的辅助 Skill:[`electric-inspection-op-readiness`](.agents/skills/electric-inspection-op-readiness/SKILL.md),用于在提交 PR 前检查电力巡检场景说明、接口约束、精度证据、性能证据和文档完整性。 | ||
| 59 | + | ||
| 60 | +仓库提供了本地 Codex 知识库框架:[`electric-inspection-knowledge-base`](.agents/skills/electric-inspection-knowledge-base/SKILL.md) 与 [`.agents/knowledge`](.agents/knowledge/README.md),用于记录公开、可审查、可渐进加载的项目上下文,不包含个人知识库内容。 | ||
| 61 | + | ||
| 56 | --- | 62 | --- |
| 57 | 63 | ||
| 58 | ## 👥 维护团队 | 64 | ## 👥 维护团队 |