feat: migrate fix-title skill
This commit is contained in:
parent
ef50a19d89
commit
fa61d46933
|
|
@ -29,6 +29,10 @@ tmp/
|
|||
temp/
|
||||
*.log
|
||||
|
||||
# Manual Skill test artifacts
|
||||
skills/*/manual-test/*.md
|
||||
!skills/*/manual-test/README.md
|
||||
|
||||
# Secrets
|
||||
.env
|
||||
.env.*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,107 @@
|
|||
# Installation
|
||||
|
||||
This repository separates Skill development source from the local public installation surface.
|
||||
|
||||
## Paths
|
||||
|
||||
Development source:
|
||||
|
||||
```text
|
||||
C:\Users\wangq\Documents\Codex\skills-vault
|
||||
```
|
||||
|
||||
Public local Skill installation surface:
|
||||
|
||||
```text
|
||||
C:\Users\wangq\.agents\skills
|
||||
```
|
||||
|
||||
Agent-specific private Skill folders, such as `C:\Users\wangq\.claude\skills`, should link to the public installation surface instead of linking directly to the development source.
|
||||
|
||||
## Conda Environment
|
||||
|
||||
Use the shared repository environment by default:
|
||||
|
||||
```powershell
|
||||
conda env create -f environment.yml
|
||||
conda activate skills-vault
|
||||
```
|
||||
|
||||
If the environment already exists:
|
||||
|
||||
```powershell
|
||||
conda activate skills-vault
|
||||
```
|
||||
|
||||
Most lightweight Skills should use this shared environment. Create a dedicated environment only when a Skill has conflicting or heavy dependencies.
|
||||
|
||||
## Install One Skill
|
||||
|
||||
PowerShell:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File .\scripts\install-skill.ps1 -Skill fix-title
|
||||
```
|
||||
|
||||
Git Bash / Linux / macOS:
|
||||
|
||||
```bash
|
||||
bash scripts/install-skill.sh fix-title
|
||||
```
|
||||
|
||||
## Install All Default Skills
|
||||
|
||||
PowerShell:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File .\scripts\install-skill.ps1 -All
|
||||
```
|
||||
|
||||
Git Bash / Linux / macOS:
|
||||
|
||||
```bash
|
||||
bash scripts/install-skill.sh --all
|
||||
```
|
||||
|
||||
Full installation uses `registry/skills-index.md` and installs only Skills with:
|
||||
|
||||
```text
|
||||
Status: tested, installable, or installed
|
||||
Install Policy: default
|
||||
```
|
||||
|
||||
Conditional, optional, disabled, candidate, deprecated, and archived Skills are skipped during full installation.
|
||||
|
||||
## Updating An Existing Installed Skill
|
||||
|
||||
By default, install scripts refuse to overwrite an existing Skill.
|
||||
|
||||
Use `-Force` or `--force` to back up the current installed directory and copy the repository version:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File .\scripts\install-skill.ps1 -Skill fix-title -Force
|
||||
```
|
||||
|
||||
```bash
|
||||
bash scripts/install-skill.sh fix-title --force
|
||||
```
|
||||
|
||||
Backups are created next to the installed Skill:
|
||||
|
||||
```text
|
||||
C:\Users\wangq\.agents\skills\fix-title.backup-YYYYMMDDHHMMSS
|
||||
```
|
||||
|
||||
## Claude Link
|
||||
|
||||
To create or update the Claude private Skill entry as a link to the public installation surface:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File .\scripts\install-skill.ps1 -Skill fix-title -InstallClaudeLink
|
||||
```
|
||||
|
||||
```bash
|
||||
bash scripts/install-skill.sh fix-title --install-claude-link
|
||||
```
|
||||
|
||||
Codex is not currently treated as a separate private install target for these shared automation Skills.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
name: skills-vault
|
||||
channels:
|
||||
- conda-forge
|
||||
dependencies:
|
||||
- python=3.11
|
||||
- pip
|
||||
|
|
@ -11,9 +11,9 @@ Existing CCPE content is not migrated here.
|
|||
|
||||
## Skills
|
||||
|
||||
| Skill | Purpose | Source | Status | Installed Path | CCPE Registration |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| _none yet_ | | | | | |
|
||||
| Skill | Purpose | Source | Status | Install Policy | Installed Path | CCPE Registration |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| `fix-title` | Shift Markdown ATX heading depth for pasted LLM replies before insertion under parent sections. | `C:\Users\wangq\Documents\Codex\knowledge-vault\skills\fix-title` | `installed` | `default` | `C:\Users\wangq\.agents\skills\fix-title` | none |
|
||||
|
||||
## Status Values
|
||||
|
||||
|
|
@ -25,3 +25,12 @@ installed
|
|||
deprecated
|
||||
archived
|
||||
```
|
||||
|
||||
## Install Policy Values
|
||||
|
||||
```text
|
||||
default
|
||||
optional
|
||||
conditional
|
||||
disabled
|
||||
```
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ Examples of future scripts:
|
|||
|
||||
- validate Skill directory structure
|
||||
- list registered Skills
|
||||
- install selected Skills to `C:\Users\wangq\.agents\skills`
|
||||
- sync selected Skills
|
||||
- install selected or default Skills to `C:\Users\wangq\.agents\skills`
|
||||
- create Agentic private Skill links that point to `.agents\skills`
|
||||
- check registry consistency
|
||||
|
||||
Skill-specific scripts should live under:
|
||||
|
|
@ -15,3 +15,15 @@ Skill-specific scripts should live under:
|
|||
```text
|
||||
skills/<skill-name>/scripts/
|
||||
```
|
||||
|
||||
Current install scripts:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File .\scripts\install-skill.ps1 -Skill fix-title
|
||||
powershell -ExecutionPolicy Bypass -File .\scripts\install-skill.ps1 -All
|
||||
```
|
||||
|
||||
```bash
|
||||
bash scripts/install-skill.sh fix-title
|
||||
bash scripts/install-skill.sh --all
|
||||
```
|
||||
|
|
|
|||
|
|
@ -0,0 +1,184 @@
|
|||
param(
|
||||
[string]$Skill,
|
||||
[switch]$All,
|
||||
[switch]$Force,
|
||||
[switch]$InstallClaudeLink,
|
||||
[string]$InstallRoot = "$HOME\.agents\skills",
|
||||
[string]$ClaudeSkillsRoot = "$HOME\.claude\skills"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
function Show-Usage {
|
||||
Write-Host "Usage:"
|
||||
Write-Host " powershell -ExecutionPolicy Bypass -File .\scripts\install-skill.ps1 -Skill fix-title"
|
||||
Write-Host " powershell -ExecutionPolicy Bypass -File .\scripts\install-skill.ps1 -All"
|
||||
Write-Host ""
|
||||
Write-Host "Options:"
|
||||
Write-Host " -Force Back up and replace existing installed Skill"
|
||||
Write-Host " -InstallClaudeLink Create/update .claude\skills link to .agents\skills"
|
||||
}
|
||||
|
||||
if (($Skill -and $All) -or (-not $Skill -and -not $All)) {
|
||||
Show-Usage
|
||||
exit 2
|
||||
}
|
||||
|
||||
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$RepoRoot = Resolve-Path (Join-Path $ScriptDir "..")
|
||||
$SkillsRoot = Join-Path $RepoRoot "skills"
|
||||
$RegistryPath = Join-Path $RepoRoot "registry\skills-index.md"
|
||||
|
||||
function Get-RegistryMeta {
|
||||
param([string]$Name)
|
||||
|
||||
if (-not (Test-Path -LiteralPath $RegistryPath)) {
|
||||
return $null
|
||||
}
|
||||
|
||||
$escaped = [regex]::Escape("`$Name")
|
||||
$line = Get-Content -LiteralPath $RegistryPath | Where-Object { $_ -match "^\|\s*``$([regex]::Escape($Name))``\s*\|" } | Select-Object -First 1
|
||||
if (-not $line) {
|
||||
return $null
|
||||
}
|
||||
|
||||
$parts = $line.Trim() -split "\|"
|
||||
$cells = @()
|
||||
foreach ($part in $parts) {
|
||||
$cell = $part.Trim()
|
||||
if ($cell.Length -gt 0) {
|
||||
$cells += $cell
|
||||
}
|
||||
}
|
||||
|
||||
if ($cells.Count -lt 7) {
|
||||
return $null
|
||||
}
|
||||
|
||||
return [PSCustomObject]@{
|
||||
Skill = $cells[0].Trim("``")
|
||||
Purpose = $cells[1]
|
||||
Source = $cells[2]
|
||||
Status = $cells[3].Trim("``")
|
||||
InstallPolicy = $cells[4].Trim("``")
|
||||
InstalledPath = $cells[5]
|
||||
CcpeRegistration = $cells[6]
|
||||
}
|
||||
}
|
||||
|
||||
function Get-AllDefaultSkills {
|
||||
$allowedStatuses = @("tested", "installable", "installed")
|
||||
$skills = @()
|
||||
|
||||
Get-ChildItem -LiteralPath $SkillsRoot -Directory | ForEach-Object {
|
||||
$skillName = $_.Name
|
||||
$skillFile = Join-Path $_.FullName "SKILL.md"
|
||||
if (-not (Test-Path -LiteralPath $skillFile)) {
|
||||
return
|
||||
}
|
||||
|
||||
$meta = Get-RegistryMeta -Name $skillName
|
||||
if (-not $meta) {
|
||||
Write-Host "Skipping ${skillName}: no registry row"
|
||||
return
|
||||
}
|
||||
|
||||
if ($allowedStatuses -notcontains $meta.Status) {
|
||||
Write-Host "Skipping ${skillName}: status is $($meta.Status)"
|
||||
return
|
||||
}
|
||||
|
||||
if ($meta.InstallPolicy -ne "default") {
|
||||
Write-Host "Skipping ${skillName}: install policy is $($meta.InstallPolicy)"
|
||||
return
|
||||
}
|
||||
|
||||
$skills += $skillName
|
||||
}
|
||||
|
||||
return $skills
|
||||
}
|
||||
|
||||
function Copy-SkillDirectory {
|
||||
param(
|
||||
[string]$Name,
|
||||
[string]$Source,
|
||||
[string]$Target
|
||||
)
|
||||
|
||||
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $Target) | Out-Null
|
||||
New-Item -ItemType Directory -Force -Path $Target | Out-Null
|
||||
|
||||
Get-ChildItem -Force -LiteralPath $Source | Where-Object {
|
||||
$_.Name -notin @("manual-test", "__pycache__", ".pytest_cache")
|
||||
} | ForEach-Object {
|
||||
Copy-Item -LiteralPath $_.FullName -Destination $Target -Recurse -Force
|
||||
}
|
||||
}
|
||||
|
||||
function Backup-ExistingPath {
|
||||
param([string]$Path)
|
||||
|
||||
$stamp = Get-Date -Format "yyyyMMddHHmmss"
|
||||
$backup = "$Path.backup-$stamp"
|
||||
Move-Item -LiteralPath $Path -Destination $backup
|
||||
return $backup
|
||||
}
|
||||
|
||||
function Install-OneSkill {
|
||||
param([string]$Name)
|
||||
|
||||
if ($Name -notmatch "^[a-z0-9][a-z0-9-]*$") {
|
||||
throw "Invalid Skill name: $Name"
|
||||
}
|
||||
|
||||
$source = Join-Path $SkillsRoot $Name
|
||||
$skillFile = Join-Path $source "SKILL.md"
|
||||
if (-not (Test-Path -LiteralPath $skillFile)) {
|
||||
throw "Skill source not found: $skillFile"
|
||||
}
|
||||
|
||||
$meta = Get-RegistryMeta -Name $Name
|
||||
if ($meta -and $meta.InstallPolicy -eq "disabled" -and -not $Force) {
|
||||
throw "Skill $Name has install policy disabled. Use -Force only if you intentionally want to install it."
|
||||
}
|
||||
|
||||
$target = Join-Path $InstallRoot $Name
|
||||
if (Test-Path -LiteralPath $target) {
|
||||
if (-not $Force) {
|
||||
throw "Installed Skill already exists: $target. Re-run with -Force to back it up and replace it."
|
||||
}
|
||||
$backup = Backup-ExistingPath -Path $target
|
||||
Write-Host "Backed up existing Skill to $backup"
|
||||
}
|
||||
|
||||
Copy-SkillDirectory -Name $Name -Source $source -Target $target
|
||||
Write-Host "Installed $Name to $target"
|
||||
|
||||
if ($InstallClaudeLink) {
|
||||
New-Item -ItemType Directory -Force -Path $ClaudeSkillsRoot | Out-Null
|
||||
$claudeTarget = Join-Path $ClaudeSkillsRoot $Name
|
||||
if (Test-Path -LiteralPath $claudeTarget) {
|
||||
if (-not $Force) {
|
||||
throw "Claude Skill link/path already exists: $claudeTarget. Re-run with -Force to back it up and replace it."
|
||||
}
|
||||
$backup = Backup-ExistingPath -Path $claudeTarget
|
||||
Write-Host "Backed up existing Claude path to $backup"
|
||||
}
|
||||
New-Item -ItemType Junction -Path $claudeTarget -Target $target | Out-Null
|
||||
Write-Host "Linked Claude Skill $claudeTarget -> $target"
|
||||
}
|
||||
}
|
||||
|
||||
if ($All) {
|
||||
$skillNames = Get-AllDefaultSkills
|
||||
if ($skillNames.Count -eq 0) {
|
||||
Write-Host "No default installable Skills found."
|
||||
exit 0
|
||||
}
|
||||
foreach ($name in $skillNames) {
|
||||
Install-OneSkill -Name $name
|
||||
}
|
||||
} else {
|
||||
Install-OneSkill -Name $Skill
|
||||
}
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
bash scripts/install-skill.sh fix-title
|
||||
bash scripts/install-skill.sh --all
|
||||
|
||||
Options:
|
||||
--force Back up and replace existing installed Skill
|
||||
--install-claude-link Create/update .claude/skills link to .agents/skills
|
||||
EOF
|
||||
}
|
||||
|
||||
skill=""
|
||||
install_all=0
|
||||
force=0
|
||||
install_claude_link=0
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--all)
|
||||
install_all=1
|
||||
shift
|
||||
;;
|
||||
--force)
|
||||
force=1
|
||||
shift
|
||||
;;
|
||||
--install-claude-link)
|
||||
install_claude_link=1
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-*)
|
||||
echo "Unknown option: $1" >&2
|
||||
usage
|
||||
exit 2
|
||||
;;
|
||||
*)
|
||||
if [[ -n "$skill" ]]; then
|
||||
echo "Only one Skill name may be provided." >&2
|
||||
usage
|
||||
exit 2
|
||||
fi
|
||||
skill="$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ "$install_all" -eq 1 && -n "$skill" ]] || [[ "$install_all" -eq 0 && -z "$skill" ]]; then
|
||||
usage
|
||||
exit 2
|
||||
fi
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
repo_root="$(cd "$script_dir/.." && pwd)"
|
||||
skills_root="$repo_root/skills"
|
||||
registry_path="$repo_root/registry/skills-index.md"
|
||||
|
||||
if [[ -n "${USERPROFILE:-}" ]]; then
|
||||
home_dir="$USERPROFILE"
|
||||
else
|
||||
home_dir="$HOME"
|
||||
fi
|
||||
|
||||
install_root="${SKILLS_VAULT_INSTALL_ROOT:-$home_dir/.agents/skills}"
|
||||
claude_skills_root="${SKILLS_VAULT_CLAUDE_SKILLS_ROOT:-$home_dir/.claude/skills}"
|
||||
|
||||
registry_meta() {
|
||||
local name="$1"
|
||||
[[ -f "$registry_path" ]] || return 1
|
||||
grep -E "^\|[[:space:]]*\`$name\`[[:space:]]*\|" "$registry_path" | head -n 1 || true
|
||||
}
|
||||
|
||||
registry_cell() {
|
||||
local line="$1"
|
||||
local index="$2"
|
||||
printf '%s\n' "$line" | awk -F'|' -v i="$index" '{gsub(/^ +| +$/, "", $(i + 1)); gsub(/`/, "", $(i + 1)); print $(i + 1)}'
|
||||
}
|
||||
|
||||
all_default_skills() {
|
||||
local allowed_statuses=" tested installable installed "
|
||||
for dir in "$skills_root"/*; do
|
||||
[[ -d "$dir" ]] || continue
|
||||
[[ -f "$dir/SKILL.md" ]] || continue
|
||||
local name
|
||||
name="$(basename "$dir")"
|
||||
local line
|
||||
line="$(registry_meta "$name")"
|
||||
if [[ -z "$line" ]]; then
|
||||
echo "Skipping $name: no registry row" >&2
|
||||
continue
|
||||
fi
|
||||
local status policy
|
||||
status="$(registry_cell "$line" 4)"
|
||||
policy="$(registry_cell "$line" 5)"
|
||||
if [[ "$allowed_statuses" != *" $status "* ]]; then
|
||||
echo "Skipping $name: status is $status" >&2
|
||||
continue
|
||||
fi
|
||||
if [[ "$policy" != "default" ]]; then
|
||||
echo "Skipping $name: install policy is $policy" >&2
|
||||
continue
|
||||
fi
|
||||
printf '%s\n' "$name"
|
||||
done
|
||||
}
|
||||
|
||||
backup_existing_path() {
|
||||
local path="$1"
|
||||
local stamp
|
||||
stamp="$(date +%Y%m%d%H%M%S)"
|
||||
local backup="$path.backup-$stamp"
|
||||
mv "$path" "$backup"
|
||||
printf '%s\n' "$backup"
|
||||
}
|
||||
|
||||
copy_skill_directory() {
|
||||
local source="$1"
|
||||
local target="$2"
|
||||
mkdir -p "$target"
|
||||
shopt -s dotglob nullglob
|
||||
for item in "$source"/*; do
|
||||
local base
|
||||
base="$(basename "$item")"
|
||||
case "$base" in
|
||||
manual-test|__pycache__|.pytest_cache)
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
cp -a "$item" "$target/"
|
||||
done
|
||||
shopt -u dotglob nullglob
|
||||
}
|
||||
|
||||
create_claude_link() {
|
||||
local name="$1"
|
||||
local target="$2"
|
||||
local link="$claude_skills_root/$name"
|
||||
mkdir -p "$claude_skills_root"
|
||||
if [[ -e "$link" || -L "$link" ]]; then
|
||||
if [[ "$force" -ne 1 ]]; then
|
||||
echo "Claude Skill link/path already exists: $link. Re-run with --force to back it up and replace it." >&2
|
||||
exit 1
|
||||
fi
|
||||
local backup
|
||||
backup="$(backup_existing_path "$link")"
|
||||
echo "Backed up existing Claude path to $backup"
|
||||
fi
|
||||
|
||||
if [[ "${OS:-}" == "Windows_NT" ]]; then
|
||||
cmd.exe /c mklink /J "$(cygpath -w "$link")" "$(cygpath -w "$target")" >/dev/null
|
||||
else
|
||||
ln -s "$target" "$link"
|
||||
fi
|
||||
echo "Linked Claude Skill $link -> $target"
|
||||
}
|
||||
|
||||
install_one_skill() {
|
||||
local name="$1"
|
||||
if [[ ! "$name" =~ ^[a-z0-9][a-z0-9-]*$ ]]; then
|
||||
echo "Invalid Skill name: $name" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local source="$skills_root/$name"
|
||||
if [[ ! -f "$source/SKILL.md" ]]; then
|
||||
echo "Skill source not found: $source/SKILL.md" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local line
|
||||
line="$(registry_meta "$name")"
|
||||
if [[ -n "$line" ]]; then
|
||||
local policy
|
||||
policy="$(registry_cell "$line" 5)"
|
||||
if [[ "$policy" == "disabled" && "$force" -ne 1 ]]; then
|
||||
echo "Skill $name has install policy disabled. Use --force only if you intentionally want to install it." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
local target="$install_root/$name"
|
||||
mkdir -p "$install_root"
|
||||
if [[ -e "$target" || -L "$target" ]]; then
|
||||
if [[ "$force" -ne 1 ]]; then
|
||||
echo "Installed Skill already exists: $target. Re-run with --force to back it up and replace it." >&2
|
||||
exit 1
|
||||
fi
|
||||
local backup
|
||||
backup="$(backup_existing_path "$target")"
|
||||
echo "Backed up existing Skill to $backup"
|
||||
fi
|
||||
|
||||
copy_skill_directory "$source" "$target"
|
||||
echo "Installed $name to $target"
|
||||
|
||||
if [[ "$install_claude_link" -eq 1 ]]; then
|
||||
create_claude_link "$name" "$target"
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ "$install_all" -eq 1 ]]; then
|
||||
mapfile -t skills < <(all_default_skills)
|
||||
if [[ "${#skills[@]}" -eq 0 ]]; then
|
||||
echo "No default installable Skills found."
|
||||
exit 0
|
||||
fi
|
||||
for name in "${skills[@]}"; do
|
||||
install_one_skill "$name"
|
||||
done
|
||||
else
|
||||
install_one_skill "$skill"
|
||||
fi
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
# Install fix-title
|
||||
|
||||
`fix-title` uses the repository-level `skills-vault` Conda environment.
|
||||
|
||||
## Prepare Environment
|
||||
|
||||
From the repository root:
|
||||
|
||||
```powershell
|
||||
conda env create -f environment.yml
|
||||
conda activate skills-vault
|
||||
```
|
||||
|
||||
If the environment already exists:
|
||||
|
||||
```powershell
|
||||
conda activate skills-vault
|
||||
```
|
||||
|
||||
## Test
|
||||
|
||||
```powershell
|
||||
python -m unittest discover -s skills\fix-title\tests -v
|
||||
```
|
||||
|
||||
## Install To Public Skill Surface
|
||||
|
||||
PowerShell:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File .\scripts\install-skill.ps1 -Skill fix-title
|
||||
```
|
||||
|
||||
Replace an existing installed copy after backing it up:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File .\scripts\install-skill.ps1 -Skill fix-title -Force
|
||||
```
|
||||
|
||||
Git Bash / Linux / macOS:
|
||||
|
||||
```bash
|
||||
bash scripts/install-skill.sh fix-title
|
||||
bash scripts/install-skill.sh fix-title --force
|
||||
```
|
||||
|
||||
## Optional Claude Link
|
||||
|
||||
PowerShell:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File .\scripts\install-skill.ps1 -Skill fix-title -InstallClaudeLink
|
||||
```
|
||||
|
||||
Git Bash / Linux / macOS:
|
||||
|
||||
```bash
|
||||
bash scripts/install-skill.sh fix-title --install-claude-link
|
||||
```
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# fix-title Migration
|
||||
|
||||
## Source
|
||||
|
||||
```text
|
||||
C:\Users\wangq\Documents\Codex\knowledge-vault\skills\fix-title
|
||||
```
|
||||
|
||||
## Target
|
||||
|
||||
```text
|
||||
C:\Users\wangq\Documents\Codex\skills-vault\skills\fix-title
|
||||
```
|
||||
|
||||
## Policy
|
||||
|
||||
This migration copies the automation Skill source into `skills-vault`.
|
||||
|
||||
The original `knowledge-vault` directory is intentionally left in place. Deleting the old source is a manual user action.
|
||||
|
||||
## Install Model
|
||||
|
||||
`skills-vault` is the development source repository.
|
||||
|
||||
The local public installation surface remains:
|
||||
|
||||
```text
|
||||
C:\Users\wangq\.agents\skills\fix-title
|
||||
```
|
||||
|
||||
Claude, OpenClaw, and other Agentic private Skill folders may link to the public installation surface instead of linking directly to this development source.
|
||||
|
||||
## Status
|
||||
|
||||
```text
|
||||
migration status: migrated-source-and-installed
|
||||
installed version updated: yes
|
||||
installed backup: C:\Users\wangq\.agents\skills\fix-title.backup-20260613235817
|
||||
manual test: passed
|
||||
```
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
---
|
||||
name: fix-title
|
||||
description: Use when a pasted ChatGPT or LLM Markdown reply has heading levels that need to be shifted down before insertion under a parent section such as "## GPT"; also use for Markdown title repair, heading nesting fixes, ATX header adjustment, and adding one or more # levels to headings in a file.
|
||||
---
|
||||
|
||||
# Fix Title
|
||||
|
||||
## Overview
|
||||
|
||||
Fix Markdown heading depth for copied LLM replies before inserting them into a discussion record. Use the bundled script for deterministic file edits instead of asking the model to rewrite the document.
|
||||
|
||||
The default operation adds two heading levels, turning `# Title` into `### Title`, which fits content placed under a parent heading like `## GPT`.
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Confirm the input is a Markdown file containing the raw reply to adjust.
|
||||
2. Choose the number of levels to add. Default to `2` unless the user specifies another value.
|
||||
3. Run `scripts/fix_markdown_titles.py` on the file.
|
||||
4. If the target is important or the requested level shift is unusual, use `--dry-run` or `--output` first and inspect the result.
|
||||
5. Report the path modified and the level shift used.
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
python scripts/fix_markdown_titles.py path/to/reply.md
|
||||
python scripts/fix_markdown_titles.py path/to/reply.md --levels 1
|
||||
python scripts/fix_markdown_titles.py path/to/reply.md --levels 3 --dry-run
|
||||
python scripts/fix_markdown_titles.py path/to/reply.md --levels 2 --output path/to/fixed.md
|
||||
```
|
||||
|
||||
On Windows PowerShell, quote paths that contain spaces:
|
||||
|
||||
```powershell
|
||||
python .\scripts\fix_markdown_titles.py "C:\path with spaces\reply.md" --levels 2
|
||||
```
|
||||
|
||||
## Behavior
|
||||
|
||||
| Input | `--levels 2` output |
|
||||
| --- | --- |
|
||||
| `# A` | `### A` |
|
||||
| `## B` | `#### B` |
|
||||
| `###### C` | `###### C` |
|
||||
|
||||
The script only changes ATX headings: lines beginning with up to three spaces followed by `#` through `######` and then whitespace. It does not change headings inside fenced code blocks, quoted lines such as `> # text`, or indented code.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Do not use a broad replace like `#` to `###`; it will corrupt code blocks, quoted content, tags, and inline text.
|
||||
- Do not increase headings past level six; Markdown ATX headings stop at `######`.
|
||||
- Do not change the recorder's outer headings such as `# 1` or `## GPT` unless the user explicitly points the skill at the recorder file and requests that behavior.
|
||||
- Do not use prompt rewriting for this task when the script can perform the edit directly.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
display_name: Fix Markdown Titles
|
||||
short_description: Shift Markdown headings down before inserting pasted chat replies.
|
||||
default_prompt: Fix the Markdown heading levels in this file so it can be pasted under a parent section.
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# Manual Test Input
|
||||
|
||||
Place one raw Markdown file here for manual validation.
|
||||
|
||||
Recommended filename:
|
||||
|
||||
```text
|
||||
raw-reply.md
|
||||
```
|
||||
|
||||
The file should be an original pasted LLM reply before heading repair.
|
||||
|
||||
After the file is added, run the Skill against a copy or with `--output` first, then compare the result before updating the installed version.
|
||||
|
|
@ -0,0 +1,371 @@
|
|||
结论:**V4.1 已经基本补齐了前面讨论里最关键的纲领级缺口**,尤其是这五个补得很准:
|
||||
|
||||
1. **生产工坊**补上了 `video-workbench / PPT / 多模态素材生产` 这类场景的位置。
|
||||
2. **QPI Drift Guard**补上了“P 域任务滑入 I 域治理项目”的防线。
|
||||
3. **Whole-source Gestalt First**吸收了你素材提炼测试里的关键教训。
|
||||
4. **Execution Authenticity**吸收了第一次多 Agent 评审测试里的“伪执行”教训。
|
||||
5. **Cost Ledger + Stop Right**吸收了 3000 万 tokens 的 ROI 教训。
|
||||
|
||||
这版已经不是“有没有骨架”的问题,而是**有几处术语、边界和强度需要校准**。我会把它分成三类:必须改的小 bug、建议补入纲领的遗漏、建议下放到 Agentic 守则的内容。
|
||||
|
||||
---
|
||||
|
||||
# 一、必须改的几个小 bug / 强冲突
|
||||
|
||||
## 1. “两种封装策略”要改成“三种封装策略”
|
||||
|
||||
你第 2 节现在写:
|
||||
|
||||
> 根据业务场景的熵值与秩序,我们采用两种不同的封装策略。
|
||||
|
||||
但表格已经是三类:
|
||||
|
||||
```text
|
||||
逻辑轮机
|
||||
生产工坊
|
||||
战略透镜
|
||||
```
|
||||
|
||||
应改为:
|
||||
|
||||
```md
|
||||
根据业务场景的熵值、秩序与产物形态,我们采用三种不同的封装策略。
|
||||
```
|
||||
|
||||
同时,下面这句也要改:
|
||||
|
||||
> 针对 B 类(战略透镜)场景……
|
||||
|
||||
因为加了“生产工坊”之后,如果继续按 A/B/C 排列,战略透镜已经不是 B 类,而是 C 类。最稳妥的写法是不要写字母:
|
||||
|
||||
```md
|
||||
针对“战略透镜”场景,当面临试错成本极高、失败即引发法理追责的“单向门”商业决策时……
|
||||
```
|
||||
|
||||
这是小 bug,但很重要。分类体系一旦留下歧义,后面守则会被带歪。
|
||||
|
||||
---
|
||||
|
||||
## 2. “Agent 输出必须包含 CoT 摘要”建议改掉
|
||||
|
||||
你现在写:
|
||||
|
||||
```md
|
||||
Agent 输出结果时,必须包含 CoT(思维链)摘要,即“我为什么这么判/这么想”
|
||||
```
|
||||
|
||||
这里建议改成:
|
||||
|
||||
```md
|
||||
Agent 输出结果时,必须包含可审计的理由摘要(Decision Rationale),说明其关键依据、适用规则、不确定性、排除选项与可推翻条件。
|
||||
```
|
||||
|
||||
原因不是咬文嚼字。**你真正需要的不是 CoT,而是可校准、可审计、可反驳的理由结构。**
|
||||
|
||||
CoT 这个词容易把系统引向“暴露内部推理过程”。但真实产品里更稳的形态是:
|
||||
|
||||
```text
|
||||
结论
|
||||
依据
|
||||
规则
|
||||
不确定性
|
||||
反例
|
||||
人工确认点
|
||||
可推翻条件
|
||||
```
|
||||
|
||||
这和你的“钢尺与皮尺”“不仅做对,还要好改”更一致。
|
||||
|
||||
---
|
||||
|
||||
## 3. QPI 的 I 域响应里,“强制启动双离合榨取”太重
|
||||
|
||||
你现在写:
|
||||
|
||||
```md
|
||||
【I】系统响应:生态学干预。强制启动后道的“思想考古”与“双离合榨取”……
|
||||
```
|
||||
|
||||
但后面 3.6 又明确说“双离合榨取”是 Beta / 理论沙盘,工程实现成本极高。这两个地方有冲突。
|
||||
|
||||
建议改成:
|
||||
|
||||
```md
|
||||
【I】系统响应:生态学干预。优先启动思想考古、战略透镜与人机回环;仅在高危、非遍历、明确授权的深水区,才考虑进入“双离合榨取”或摩擦蒸馏等 Beta 机制。
|
||||
```
|
||||
|
||||
这样层级就清楚了:
|
||||
|
||||
```text
|
||||
I 域默认:思想考古 + 战略透镜 + 人机回环
|
||||
I 域高危:预设委员会
|
||||
I 域极高危/实验:双离合榨取
|
||||
```
|
||||
|
||||
否则会把一个 Beta 沙盘机制误升成 I 域默认动作,容易再度重工业化。
|
||||
|
||||
---
|
||||
|
||||
## 4. “全源完形前置”需要加适用条件
|
||||
|
||||
这个原则非常重要,但现在写得有点绝对:
|
||||
|
||||
```md
|
||||
严禁对连贯的长篇语料直接采用基于分块的并发提取机制……
|
||||
必须首先调用高上下文承载力的主节点……
|
||||
```
|
||||
|
||||
核心判断对,但建议补上适用边界:
|
||||
|
||||
```md
|
||||
当源材料是连贯长篇语料,且仍处于高上下文参与者可承载范围内时,应优先进行 Whole-source Gestalt。若源材料是混合型,应先做宏主题拆分;若源材料是碎片型,应采用平铺发现,不强行制造层级。
|
||||
```
|
||||
|
||||
这个边界其实你原来的 runbook 已经有:Step 0 会先判断 source 是 coherent、mixed 还是 fragmented,并据此选择 structure-first、macro-topic 或 flat-discovery 模式;它还要求在没有真实参与者输出时停止。
|
||||
|
||||
所以我建议纲领别写成“所有长材料都必须全源完形”,而是写成:
|
||||
|
||||
> **连贯长材料禁止 chunk-first;混合材料先宏拆;碎片材料不强行升层。**
|
||||
|
||||
这更精准。
|
||||
|
||||
---
|
||||
|
||||
## 5. “确定性的专家能力”建议改成“可校准的专家能力”
|
||||
|
||||
第 0 节你写:
|
||||
|
||||
```md
|
||||
通过架构工程封装为确定性的专家能力
|
||||
```
|
||||
|
||||
这句话对逻辑轮机很对,但对战略透镜不完全对。I 域本来就不是确定性求解,而是动态权衡、反馈控制、人类裁决。
|
||||
|
||||
建议改成:
|
||||
|
||||
```md
|
||||
通过架构工程封装为高保真、可校准、可追溯的专家能力。
|
||||
```
|
||||
|
||||
或者:
|
||||
|
||||
```md
|
||||
在 Q/P 域追求确定性执行,在 I 域追求高保真辅助、责任锚定与动态校准。
|
||||
```
|
||||
|
||||
这样不会和你自己的 QPI / 战略透镜冲突。
|
||||
|
||||
---
|
||||
|
||||
## 6. “执行真实性”要和“绿野仙踪”显式解耦
|
||||
|
||||
你现在同时有:
|
||||
|
||||
* 绿野仙踪:人类专家幕后扮演 Agent;
|
||||
* 执行真实性:禁止主控节点代写模拟。
|
||||
|
||||
这两条都对,但需要一条桥接规则,否则读者可能觉得矛盾。
|
||||
|
||||
建议在第 11 条下面加一句:
|
||||
|
||||
```md
|
||||
绿野仙踪阶段允许人类或主控节点模拟 Agent 以验证价值流,但所有此类产物必须标记为 simulation-only,不得作为正式 Agentic 输出进入生产决策链。正式运行阶段必须具备真实 Invocation Record。
|
||||
```
|
||||
|
||||
这很关键。
|
||||
|
||||
因为你的第一次流程测试失败,不是因为“模拟”本身不允许,而是因为**模拟产物被当成正式多 Agent 产物**。你原来的 distillation runbook 已经有类似底线:不能把 packet-only 或 prompt-only 当成已执行,主会话不得做 primary source analysis / routing / topic-doc drafting / material extraction,carrier 不可用时要停在 blocked 状态。
|
||||
|
||||
所以这里要明确:
|
||||
|
||||
```text
|
||||
模拟可以用于价值验证;
|
||||
模拟不能冒充正式执行。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. “绝对停止权”的“代码级”可以稍微下放
|
||||
|
||||
你现在写:
|
||||
|
||||
```md
|
||||
系统必须具备代码级的绝对停止权……
|
||||
```
|
||||
|
||||
作为工程守则可以;作为方法论纲领稍微细了点。
|
||||
|
||||
建议纲领里写成:
|
||||
|
||||
```md
|
||||
系统必须具备可执行、可审计、可由人类覆盖的停止机制。
|
||||
```
|
||||
|
||||
然后把“代码级熔断、状态锁定、预算上限、自动停止条件”放到 Agentic Engineering Handbook。
|
||||
|
||||
更稳的版本:
|
||||
|
||||
```md
|
||||
一旦达到最小充分产物或触发成本 / 范围 / 风险阈值,系统必须停止后续自我扩展,除非人类显式授权升级模式。
|
||||
```
|
||||
|
||||
这样保留原则,又不把实现细节塞进宪法。
|
||||
|
||||
---
|
||||
|
||||
# 二、我认为还缺的纲领级内容
|
||||
|
||||
整体看,V4.1 已经很完整。但如果问“是否还有遗漏”,我认为还有 **4 个纲领级补丁** 值得加入。
|
||||
|
||||
---
|
||||
|
||||
## 1. 增加“方法论与 Agentic 守则的边界”
|
||||
|
||||
你前面已经决定拆分:
|
||||
|
||||
```text
|
||||
HiFi Agent Studio = 纲领
|
||||
Agentic Handbook = 守则
|
||||
CCPE System = 工坊
|
||||
Project Runbook = 项目规程
|
||||
```
|
||||
|
||||
但 V4.1 本文里还没有显式声明这个边界。
|
||||
|
||||
建议加在开头 Profile 后,或者最后加一节:
|
||||
|
||||
```md
|
||||
## 文档边界
|
||||
|
||||
HiFi Agent Studio 是 AI 开发与专家型 Agentic 系统建设的方法论纲领,只规定世界观、产品观、架构底线与最高航行纪律。
|
||||
|
||||
具体的 Project Intake、Mode Selector、Invocation Record、Cost Ledger 模板、Authority Matrix、Evaluation Stack、Runtime Maturity Model、平台适配规则,应下放至 HiFi Agentic Engineering Handbook 与各项目 Runbook。
|
||||
|
||||
当具体工程守则与本纲领冲突时,以本纲领的核心原则为准;当本纲领没有规定时,以守则和项目 Runbook 执行。
|
||||
```
|
||||
|
||||
这个要加。否则 V4.1 会继续向“宪法 + 施工手册混合体”膨胀。
|
||||
|
||||
---
|
||||
|
||||
## 2. 增加“责任不可外包 / Liability Boundary”
|
||||
|
||||
你在 Captain、非遍历性、控制棒里都提到了责任,但我建议把它升成航行纪律之一。
|
||||
|
||||
可以作为第 14 条:
|
||||
|
||||
```md
|
||||
14. **责任不可外包 (Liability Boundary)**
|
||||
* *定义*:在 I 域与高风险 P 域,AI 可以扩展人类专家的认知半径,但不能替代人类承担最终责任。
|
||||
* *红线*:任何涉及法理追责、客户重大利益、不可逆决策或高风险判断的系统,必须明确 AI 建议、人类裁决、组织责任与客户责任的边界。禁止用“模型判断”掩盖人的责任坐标。
|
||||
```
|
||||
|
||||
这条应该进纲领,不应只放守则。
|
||||
|
||||
因为这是 HiFi Agent Studio 区别于“全自动幻觉派”的价值底线。
|
||||
|
||||
---
|
||||
|
||||
## 3. 增加“最小权限与副作用隔离”
|
||||
|
||||
你在产品定义里提到了 Reactor 里的 Authority,但航行纪律里还没有把它作为底线写出来。
|
||||
|
||||
Agentic 系统和普通 prompt 最大区别之一是:它能调用工具、改文件、发请求、写数据库、触发外部动作。这里必须有一条纲领级红线。
|
||||
|
||||
建议加:
|
||||
|
||||
```md
|
||||
15. **最小权限与副作用隔离 (Least Privilege & Side-effect Isolation)**
|
||||
* *定义*:Agent 的工具权限必须小于其语言能力。能说不代表能做,能建议不代表能执行。
|
||||
* *红线*:任何具备文件修改、外部 API、数据库写入、消息发送、支付、发布、删除或客户可见输出能力的 Agent,必须采用最小权限、沙箱隔离、人工确认与可回滚机制。禁止让通用推理能力直接获得不可逆执行权。
|
||||
```
|
||||
|
||||
这条非常适合你的“物理反应堆”隐喻。
|
||||
反应堆不是光靠控制棒,还要有阀门、屏蔽层和紧急停堆。
|
||||
|
||||
---
|
||||
|
||||
## 4. 增加“过程数据的授权与主权”
|
||||
|
||||
你有“过程即数据”,也有“双离合榨取 / 隐性遥测”。但这里最好补一条伦理和数据边界。
|
||||
|
||||
尤其你未来服务客户,专家修改轨迹、光标悬停、编辑距离、反驳意见,这些都可能是高价值、高敏感数据。
|
||||
|
||||
建议在第 3 条“过程即数据”后补一句,或者单独作为第 16 条:
|
||||
|
||||
```md
|
||||
16. **过程数据主权与授权 (Process Data Sovereignty)**
|
||||
* *定义*:专家的修改痕迹、反馈、犹豫、反驳、编辑轨迹与隐性遥测,是高价值认知资产,也是高敏感数据。
|
||||
* *红线*:任何过程数据采集必须具备明确授权、用途边界、最小采集、可撤回机制与隔离存储策略。禁止以“系统学习”为名,默认吞并专家经验或客户场景数据。
|
||||
```
|
||||
|
||||
这条会让你的“双离合榨取”更稳,不会显得像认知压榨机。
|
||||
|
||||
---
|
||||
|
||||
# 三、已有内容中建议弱化或移动的部分
|
||||
|
||||
## 1. “双离合榨取”可以保留,但建议再降半档
|
||||
|
||||
这部分很有你自己的特色,也确实是战略透镜高危区的未来方向。但它现在语言太硬,比如:
|
||||
|
||||
```md
|
||||
在数学底层上绝对不奖励多数派的平庸共识,精准重奖反共识真理
|
||||
```
|
||||
|
||||
建议改柔一点:
|
||||
|
||||
```md
|
||||
尝试提高少数高质量反共识信号的可见性,避免系统被多数派平庸共识吞没。
|
||||
```
|
||||
|
||||
“反共识”不天然等于“真理”。BTS 是一种机制,不是神谕。这里稍微降调,会让方法论更稳。
|
||||
|
||||
---
|
||||
|
||||
## 2. “全源完形前置”应该从思想考古里稍微移出来
|
||||
|
||||
现在它在 3.2 思想考古下面。我理解你的意图:它来自知识加工和长讨论蒸馏。
|
||||
|
||||
但严格说,它更像:
|
||||
|
||||
> 上下文工程 / 材料工程原则
|
||||
|
||||
而不是思想考古本身。
|
||||
|
||||
可以保留在 3.2,但标题可以改成:
|
||||
|
||||
```md
|
||||
3.2 思想考古与上下文完形
|
||||
```
|
||||
|
||||
或者在 3.2 前加一个小节:
|
||||
|
||||
```md
|
||||
3.2 上下文工程:Whole-source Gestalt First
|
||||
3.3 思想考古
|
||||
```
|
||||
|
||||
如果你想保持纲领简洁,当前放法也可以,但建议在表述中明确它是“长材料处理原则”,不是所有思想考古任务的默认动作。
|
||||
|
||||
---
|
||||
|
||||
## 3. “实测去魅”的例子不要只写专家相似度
|
||||
|
||||
你现在写:
|
||||
|
||||
```md
|
||||
构建自动化评测集(如:100 道真题),用数据(如:85% 专家相似度)说话。
|
||||
```
|
||||
|
||||
这对逻辑轮机很好,但对战略透镜不够。
|
||||
|
||||
建议改成:
|
||||
|
||||
```md
|
||||
构建分层评测:对逻辑轮机使用标准答案、专家相似度与自动化测试;对生产工坊使用可用性、转化效率与返工率;对战略透镜使用决策效用、可校准性、反例处理与治理可追踪性。
|
||||
```
|
||||
|
||||
这样不会把所有 HiFi 系统都压成“准确率系统”。
|
||||
|
||||
---
|
||||
|
|
@ -0,0 +1,375 @@
|
|||
# 1
|
||||
|
||||
I said .....
|
||||
|
||||
## GPT
|
||||
|
||||
结论:**V4.1 已经基本补齐了前面讨论里最关键的纲领级缺口**,尤其是这五个补得很准:
|
||||
|
||||
1. **生产工坊**补上了 `video-workbench / PPT / 多模态素材生产` 这类场景的位置。
|
||||
2. **QPI Drift Guard**补上了“P 域任务滑入 I 域治理项目”的防线。
|
||||
3. **Whole-source Gestalt First**吸收了你素材提炼测试里的关键教训。
|
||||
4. **Execution Authenticity**吸收了第一次多 Agent 评审测试里的“伪执行”教训。
|
||||
5. **Cost Ledger + Stop Right**吸收了 3000 万 tokens 的 ROI 教训。
|
||||
|
||||
这版已经不是“有没有骨架”的问题,而是**有几处术语、边界和强度需要校准**。我会把它分成三类:必须改的小 bug、建议补入纲领的遗漏、建议下放到 Agentic 守则的内容。
|
||||
|
||||
---
|
||||
|
||||
### 一、必须改的几个小 bug / 强冲突
|
||||
|
||||
#### 1. “两种封装策略”要改成“三种封装策略”
|
||||
|
||||
你第 2 节现在写:
|
||||
|
||||
> 根据业务场景的熵值与秩序,我们采用两种不同的封装策略。
|
||||
|
||||
但表格已经是三类:
|
||||
|
||||
```text
|
||||
逻辑轮机
|
||||
生产工坊
|
||||
战略透镜
|
||||
```
|
||||
|
||||
应改为:
|
||||
|
||||
```md
|
||||
根据业务场景的熵值、秩序与产物形态,我们采用三种不同的封装策略。
|
||||
```
|
||||
|
||||
同时,下面这句也要改:
|
||||
|
||||
> 针对 B 类(战略透镜)场景……
|
||||
|
||||
因为加了“生产工坊”之后,如果继续按 A/B/C 排列,战略透镜已经不是 B 类,而是 C 类。最稳妥的写法是不要写字母:
|
||||
|
||||
```md
|
||||
针对“战略透镜”场景,当面临试错成本极高、失败即引发法理追责的“单向门”商业决策时……
|
||||
```
|
||||
|
||||
这是小 bug,但很重要。分类体系一旦留下歧义,后面守则会被带歪。
|
||||
|
||||
---
|
||||
|
||||
#### 2. “Agent 输出必须包含 CoT 摘要”建议改掉
|
||||
|
||||
你现在写:
|
||||
|
||||
```md
|
||||
Agent 输出结果时,必须包含 CoT(思维链)摘要,即“我为什么这么判/这么想”
|
||||
```
|
||||
|
||||
这里建议改成:
|
||||
|
||||
```md
|
||||
Agent 输出结果时,必须包含可审计的理由摘要(Decision Rationale),说明其关键依据、适用规则、不确定性、排除选项与可推翻条件。
|
||||
```
|
||||
|
||||
原因不是咬文嚼字。**你真正需要的不是 CoT,而是可校准、可审计、可反驳的理由结构。**
|
||||
|
||||
CoT 这个词容易把系统引向“暴露内部推理过程”。但真实产品里更稳的形态是:
|
||||
|
||||
```text
|
||||
结论
|
||||
依据
|
||||
规则
|
||||
不确定性
|
||||
反例
|
||||
人工确认点
|
||||
可推翻条件
|
||||
```
|
||||
|
||||
这和你的“钢尺与皮尺”“不仅做对,还要好改”更一致。
|
||||
|
||||
---
|
||||
|
||||
#### 3. QPI 的 I 域响应里,“强制启动双离合榨取”太重
|
||||
|
||||
你现在写:
|
||||
|
||||
```md
|
||||
【I】系统响应:生态学干预。强制启动后道的“思想考古”与“双离合榨取”……
|
||||
```
|
||||
|
||||
但后面 3.6 又明确说“双离合榨取”是 Beta / 理论沙盘,工程实现成本极高。这两个地方有冲突。
|
||||
|
||||
建议改成:
|
||||
|
||||
```md
|
||||
【I】系统响应:生态学干预。优先启动思想考古、战略透镜与人机回环;仅在高危、非遍历、明确授权的深水区,才考虑进入“双离合榨取”或摩擦蒸馏等 Beta 机制。
|
||||
```
|
||||
|
||||
这样层级就清楚了:
|
||||
|
||||
```text
|
||||
I 域默认:思想考古 + 战略透镜 + 人机回环
|
||||
I 域高危:预设委员会
|
||||
I 域极高危/实验:双离合榨取
|
||||
```
|
||||
|
||||
否则会把一个 Beta 沙盘机制误升成 I 域默认动作,容易再度重工业化。
|
||||
|
||||
---
|
||||
|
||||
#### 4. “全源完形前置”需要加适用条件
|
||||
|
||||
这个原则非常重要,但现在写得有点绝对:
|
||||
|
||||
```md
|
||||
严禁对连贯的长篇语料直接采用基于分块的并发提取机制……
|
||||
必须首先调用高上下文承载力的主节点……
|
||||
```
|
||||
|
||||
核心判断对,但建议补上适用边界:
|
||||
|
||||
```md
|
||||
当源材料是连贯长篇语料,且仍处于高上下文参与者可承载范围内时,应优先进行 Whole-source Gestalt。若源材料是混合型,应先做宏主题拆分;若源材料是碎片型,应采用平铺发现,不强行制造层级。
|
||||
```
|
||||
|
||||
这个边界其实你原来的 runbook 已经有:Step 0 会先判断 source 是 coherent、mixed 还是 fragmented,并据此选择 structure-first、macro-topic 或 flat-discovery 模式;它还要求在没有真实参与者输出时停止。
|
||||
|
||||
所以我建议纲领别写成“所有长材料都必须全源完形”,而是写成:
|
||||
|
||||
> **连贯长材料禁止 chunk-first;混合材料先宏拆;碎片材料不强行升层。**
|
||||
|
||||
这更精准。
|
||||
|
||||
---
|
||||
|
||||
#### 5. “确定性的专家能力”建议改成“可校准的专家能力”
|
||||
|
||||
第 0 节你写:
|
||||
|
||||
```md
|
||||
通过架构工程封装为确定性的专家能力
|
||||
```
|
||||
|
||||
这句话对逻辑轮机很对,但对战略透镜不完全对。I 域本来就不是确定性求解,而是动态权衡、反馈控制、人类裁决。
|
||||
|
||||
建议改成:
|
||||
|
||||
```md
|
||||
通过架构工程封装为高保真、可校准、可追溯的专家能力。
|
||||
```
|
||||
|
||||
或者:
|
||||
|
||||
```md
|
||||
在 Q/P 域追求确定性执行,在 I 域追求高保真辅助、责任锚定与动态校准。
|
||||
```
|
||||
|
||||
这样不会和你自己的 QPI / 战略透镜冲突。
|
||||
|
||||
---
|
||||
|
||||
#### 6. “执行真实性”要和“绿野仙踪”显式解耦
|
||||
|
||||
你现在同时有:
|
||||
|
||||
* 绿野仙踪:人类专家幕后扮演 Agent;
|
||||
* 执行真实性:禁止主控节点代写模拟。
|
||||
|
||||
这两条都对,但需要一条桥接规则,否则读者可能觉得矛盾。
|
||||
|
||||
建议在第 11 条下面加一句:
|
||||
|
||||
```md
|
||||
绿野仙踪阶段允许人类或主控节点模拟 Agent 以验证价值流,但所有此类产物必须标记为 simulation-only,不得作为正式 Agentic 输出进入生产决策链。正式运行阶段必须具备真实 Invocation Record。
|
||||
```
|
||||
|
||||
这很关键。
|
||||
|
||||
因为你的第一次流程测试失败,不是因为“模拟”本身不允许,而是因为**模拟产物被当成正式多 Agent 产物**。你原来的 distillation runbook 已经有类似底线:不能把 packet-only 或 prompt-only 当成已执行,主会话不得做 primary source analysis / routing / topic-doc drafting / material extraction,carrier 不可用时要停在 blocked 状态。
|
||||
|
||||
所以这里要明确:
|
||||
|
||||
```text
|
||||
模拟可以用于价值验证;
|
||||
模拟不能冒充正式执行。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 7. “绝对停止权”的“代码级”可以稍微下放
|
||||
|
||||
你现在写:
|
||||
|
||||
```md
|
||||
系统必须具备代码级的绝对停止权……
|
||||
```
|
||||
|
||||
作为工程守则可以;作为方法论纲领稍微细了点。
|
||||
|
||||
建议纲领里写成:
|
||||
|
||||
```md
|
||||
系统必须具备可执行、可审计、可由人类覆盖的停止机制。
|
||||
```
|
||||
|
||||
然后把“代码级熔断、状态锁定、预算上限、自动停止条件”放到 Agentic Engineering Handbook。
|
||||
|
||||
更稳的版本:
|
||||
|
||||
```md
|
||||
一旦达到最小充分产物或触发成本 / 范围 / 风险阈值,系统必须停止后续自我扩展,除非人类显式授权升级模式。
|
||||
```
|
||||
|
||||
这样保留原则,又不把实现细节塞进宪法。
|
||||
|
||||
---
|
||||
|
||||
### 二、我认为还缺的纲领级内容
|
||||
|
||||
整体看,V4.1 已经很完整。但如果问“是否还有遗漏”,我认为还有 **4 个纲领级补丁** 值得加入。
|
||||
|
||||
---
|
||||
|
||||
#### 1. 增加“方法论与 Agentic 守则的边界”
|
||||
|
||||
你前面已经决定拆分:
|
||||
|
||||
```text
|
||||
HiFi Agent Studio = 纲领
|
||||
Agentic Handbook = 守则
|
||||
CCPE System = 工坊
|
||||
Project Runbook = 项目规程
|
||||
```
|
||||
|
||||
但 V4.1 本文里还没有显式声明这个边界。
|
||||
|
||||
建议加在开头 Profile 后,或者最后加一节:
|
||||
|
||||
```md
|
||||
## 文档边界
|
||||
|
||||
HiFi Agent Studio 是 AI 开发与专家型 Agentic 系统建设的方法论纲领,只规定世界观、产品观、架构底线与最高航行纪律。
|
||||
|
||||
具体的 Project Intake、Mode Selector、Invocation Record、Cost Ledger 模板、Authority Matrix、Evaluation Stack、Runtime Maturity Model、平台适配规则,应下放至 HiFi Agentic Engineering Handbook 与各项目 Runbook。
|
||||
|
||||
当具体工程守则与本纲领冲突时,以本纲领的核心原则为准;当本纲领没有规定时,以守则和项目 Runbook 执行。
|
||||
```
|
||||
|
||||
这个要加。否则 V4.1 会继续向“宪法 + 施工手册混合体”膨胀。
|
||||
|
||||
---
|
||||
|
||||
#### 2. 增加“责任不可外包 / Liability Boundary”
|
||||
|
||||
你在 Captain、非遍历性、控制棒里都提到了责任,但我建议把它升成航行纪律之一。
|
||||
|
||||
可以作为第 14 条:
|
||||
|
||||
```md
|
||||
14. **责任不可外包 (Liability Boundary)**
|
||||
* *定义*:在 I 域与高风险 P 域,AI 可以扩展人类专家的认知半径,但不能替代人类承担最终责任。
|
||||
* *红线*:任何涉及法理追责、客户重大利益、不可逆决策或高风险判断的系统,必须明确 AI 建议、人类裁决、组织责任与客户责任的边界。禁止用“模型判断”掩盖人的责任坐标。
|
||||
```
|
||||
|
||||
这条应该进纲领,不应只放守则。
|
||||
|
||||
因为这是 HiFi Agent Studio 区别于“全自动幻觉派”的价值底线。
|
||||
|
||||
---
|
||||
|
||||
#### 3. 增加“最小权限与副作用隔离”
|
||||
|
||||
你在产品定义里提到了 Reactor 里的 Authority,但航行纪律里还没有把它作为底线写出来。
|
||||
|
||||
Agentic 系统和普通 prompt 最大区别之一是:它能调用工具、改文件、发请求、写数据库、触发外部动作。这里必须有一条纲领级红线。
|
||||
|
||||
建议加:
|
||||
|
||||
```md
|
||||
15. **最小权限与副作用隔离 (Least Privilege & Side-effect Isolation)**
|
||||
* *定义*:Agent 的工具权限必须小于其语言能力。能说不代表能做,能建议不代表能执行。
|
||||
* *红线*:任何具备文件修改、外部 API、数据库写入、消息发送、支付、发布、删除或客户可见输出能力的 Agent,必须采用最小权限、沙箱隔离、人工确认与可回滚机制。禁止让通用推理能力直接获得不可逆执行权。
|
||||
```
|
||||
|
||||
这条非常适合你的“物理反应堆”隐喻。
|
||||
反应堆不是光靠控制棒,还要有阀门、屏蔽层和紧急停堆。
|
||||
|
||||
---
|
||||
|
||||
#### 4. 增加“过程数据的授权与主权”
|
||||
|
||||
你有“过程即数据”,也有“双离合榨取 / 隐性遥测”。但这里最好补一条伦理和数据边界。
|
||||
|
||||
尤其你未来服务客户,专家修改轨迹、光标悬停、编辑距离、反驳意见,这些都可能是高价值、高敏感数据。
|
||||
|
||||
建议在第 3 条“过程即数据”后补一句,或者单独作为第 16 条:
|
||||
|
||||
```md
|
||||
16. **过程数据主权与授权 (Process Data Sovereignty)**
|
||||
* *定义*:专家的修改痕迹、反馈、犹豫、反驳、编辑轨迹与隐性遥测,是高价值认知资产,也是高敏感数据。
|
||||
* *红线*:任何过程数据采集必须具备明确授权、用途边界、最小采集、可撤回机制与隔离存储策略。禁止以“系统学习”为名,默认吞并专家经验或客户场景数据。
|
||||
```
|
||||
|
||||
这条会让你的“双离合榨取”更稳,不会显得像认知压榨机。
|
||||
|
||||
---
|
||||
|
||||
### 三、已有内容中建议弱化或移动的部分
|
||||
|
||||
#### 1. “双离合榨取”可以保留,但建议再降半档
|
||||
|
||||
这部分很有你自己的特色,也确实是战略透镜高危区的未来方向。但它现在语言太硬,比如:
|
||||
|
||||
```md
|
||||
在数学底层上绝对不奖励多数派的平庸共识,精准重奖反共识真理
|
||||
```
|
||||
|
||||
建议改柔一点:
|
||||
|
||||
```md
|
||||
尝试提高少数高质量反共识信号的可见性,避免系统被多数派平庸共识吞没。
|
||||
```
|
||||
|
||||
“反共识”不天然等于“真理”。BTS 是一种机制,不是神谕。这里稍微降调,会让方法论更稳。
|
||||
|
||||
---
|
||||
|
||||
#### 2. “全源完形前置”应该从思想考古里稍微移出来
|
||||
|
||||
现在它在 3.2 思想考古下面。我理解你的意图:它来自知识加工和长讨论蒸馏。
|
||||
|
||||
但严格说,它更像:
|
||||
|
||||
> 上下文工程 / 材料工程原则
|
||||
|
||||
而不是思想考古本身。
|
||||
|
||||
可以保留在 3.2,但标题可以改成:
|
||||
|
||||
```md
|
||||
3.2 思想考古与上下文完形
|
||||
```
|
||||
|
||||
或者在 3.2 前加一个小节:
|
||||
|
||||
```md
|
||||
3.2 上下文工程:Whole-source Gestalt First
|
||||
3.3 思想考古
|
||||
```
|
||||
|
||||
如果你想保持纲领简洁,当前放法也可以,但建议在表述中明确它是“长材料处理原则”,不是所有思想考古任务的默认动作。
|
||||
|
||||
---
|
||||
|
||||
#### 3. “实测去魅”的例子不要只写专家相似度
|
||||
|
||||
你现在写:
|
||||
|
||||
```md
|
||||
构建自动化评测集(如:100 道真题),用数据(如:85% 专家相似度)说话。
|
||||
```
|
||||
|
||||
这对逻辑轮机很好,但对战略透镜不够。
|
||||
|
||||
建议改成:
|
||||
|
||||
```md
|
||||
构建分层评测:对逻辑轮机使用标准答案、专家相似度与自动化测试;对生产工坊使用可用性、转化效率与返工率;对战略透镜使用决策效用、可校准性、反例处理与治理可追踪性。
|
||||
```
|
||||
|
||||
这样不会把所有 HiFi 系统都压成“准确率系统”。
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Shift Markdown ATX headings down by a fixed number of levels."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import pathlib
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
HEADING_RE = re.compile(r"^( {0,3})(#{1,6})([ \t]+.*)$")
|
||||
FENCE_RE = re.compile(r"^( {0,3})(`{3,}|~{3,})")
|
||||
|
||||
|
||||
def shift_headings(text: str, levels: int) -> str:
|
||||
if levels <= 0:
|
||||
raise ValueError("levels must be a positive integer")
|
||||
|
||||
lines = text.splitlines(keepends=True)
|
||||
in_fence = False
|
||||
fence_marker = ""
|
||||
output: list[str] = []
|
||||
|
||||
for line in lines:
|
||||
body = line[:-1] if line.endswith("\n") else line
|
||||
newline = "\n" if line.endswith("\n") else ""
|
||||
if body.endswith("\r"):
|
||||
body = body[:-1]
|
||||
newline = "\r" + newline
|
||||
|
||||
fence_match = FENCE_RE.match(body)
|
||||
if fence_match:
|
||||
marker = fence_match.group(2)
|
||||
marker_char = marker[0]
|
||||
if not in_fence:
|
||||
in_fence = True
|
||||
fence_marker = marker_char * len(marker)
|
||||
elif marker_char == fence_marker[0] and len(marker) >= len(fence_marker):
|
||||
in_fence = False
|
||||
fence_marker = ""
|
||||
output.append(line)
|
||||
continue
|
||||
|
||||
if in_fence:
|
||||
output.append(line)
|
||||
continue
|
||||
|
||||
heading_match = HEADING_RE.match(body)
|
||||
if heading_match:
|
||||
indent, hashes, rest = heading_match.groups()
|
||||
new_level = min(6, len(hashes) + levels)
|
||||
output.append(f"{indent}{'#' * new_level}{rest}{newline}")
|
||||
else:
|
||||
output.append(line)
|
||||
|
||||
return "".join(output)
|
||||
|
||||
|
||||
def parse_args(argv: list[str]) -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Shift Markdown ATX headings down by adding # characters."
|
||||
)
|
||||
parser.add_argument("path", type=pathlib.Path, help="Markdown file to rewrite")
|
||||
parser.add_argument(
|
||||
"-l",
|
||||
"--levels",
|
||||
type=int,
|
||||
default=2,
|
||||
help="Number of heading levels to add. Default: 2",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--output",
|
||||
type=pathlib.Path,
|
||||
help="Write to this file instead of modifying the source file",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dry-run",
|
||||
action="store_true",
|
||||
help="Print converted content to stdout without writing files",
|
||||
)
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
def main(argv: list[str]) -> int:
|
||||
args = parse_args(argv)
|
||||
|
||||
if args.levels <= 0:
|
||||
print("error: --levels must be a positive integer", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
try:
|
||||
source = args.path.read_text(encoding="utf-8")
|
||||
except OSError as exc:
|
||||
print(f"error: cannot read {args.path}: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
fixed = shift_headings(source, args.levels)
|
||||
|
||||
if args.dry_run:
|
||||
sys.stdout.write(fixed)
|
||||
return 0
|
||||
|
||||
destination = args.output or args.path
|
||||
try:
|
||||
destination.write_text(fixed, encoding="utf-8")
|
||||
except OSError as exc:
|
||||
print(f"error: cannot write {destination}: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main(sys.argv[1:]))
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
import pathlib
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
|
||||
SCRIPT = pathlib.Path(__file__).resolve().parents[1] / "scripts" / "fix_markdown_titles.py"
|
||||
|
||||
|
||||
def run_cli(*args):
|
||||
return subprocess.run(
|
||||
[sys.executable, str(SCRIPT), *args],
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=False,
|
||||
)
|
||||
|
||||
|
||||
class FixMarkdownTitlesTest(unittest.TestCase):
|
||||
def test_shifts_atx_headings_and_leaves_code_blocks(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
target = pathlib.Path(tmp) / "reply.md"
|
||||
target.write_text(
|
||||
"\n".join(
|
||||
[
|
||||
"Intro",
|
||||
"",
|
||||
"# One",
|
||||
"## Two ##",
|
||||
"```md",
|
||||
"# Not a heading",
|
||||
"```",
|
||||
"> # quoted content",
|
||||
" # indented code",
|
||||
"###### Six",
|
||||
"",
|
||||
]
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
result = run_cli(str(target), "--levels", "2")
|
||||
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
self.assertEqual(
|
||||
target.read_text(encoding="utf-8"),
|
||||
"\n".join(
|
||||
[
|
||||
"Intro",
|
||||
"",
|
||||
"### One",
|
||||
"#### Two ##",
|
||||
"```md",
|
||||
"# Not a heading",
|
||||
"```",
|
||||
"> # quoted content",
|
||||
" # indented code",
|
||||
"###### Six",
|
||||
"",
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
def test_dry_run_prints_without_writing(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
target = pathlib.Path(tmp) / "reply.md"
|
||||
target.write_text("# One\n", encoding="utf-8")
|
||||
|
||||
result = run_cli(str(target), "--levels", "1", "--dry-run")
|
||||
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
self.assertEqual(result.stdout, "## One\n")
|
||||
self.assertEqual(target.read_text(encoding="utf-8"), "# One\n")
|
||||
|
||||
def test_output_writes_to_separate_file(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
source = pathlib.Path(tmp) / "reply.md"
|
||||
output = pathlib.Path(tmp) / "fixed.md"
|
||||
source.write_text("# One\n", encoding="utf-8")
|
||||
|
||||
result = run_cli(str(source), "--levels", "3", "--output", str(output))
|
||||
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
self.assertEqual(source.read_text(encoding="utf-8"), "# One\n")
|
||||
self.assertEqual(output.read_text(encoding="utf-8"), "#### One\n")
|
||||
|
||||
def test_rejects_non_positive_levels(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
target = pathlib.Path(tmp) / "reply.md"
|
||||
target.write_text("# One\n", encoding="utf-8")
|
||||
|
||||
result = run_cli(str(target), "--levels", "0")
|
||||
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
self.assertIn("positive integer", result.stderr)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Reference in New Issue