From 6300a8815a6991ee2f34ee62548534fcb0f4ab7d Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:04:05 -0700 Subject: [PATCH 01/22] sprint-W1: extend create_structure with wiki directories --- scripts/selfmodel.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/selfmodel.sh b/scripts/selfmodel.sh index 2b88c66..c24b7de 100755 --- a/scripts/selfmodel.sh +++ b/scripts/selfmodel.sh @@ -190,9 +190,13 @@ create_structure() { mkdir -p "$dir/.selfmodel/reviews" mkdir -p "$dir/.selfmodel/state" mkdir -p "$dir/.selfmodel/playbook" + mkdir -p "$dir/.selfmodel/wiki/modules" + mkdir -p "$dir/.selfmodel/wiki/decisions" + mkdir -p "$dir/.selfmodel/wiki/patterns" + mkdir -p "$dir/.selfmodel/wiki/entities" # .gitkeep for empty directories - for d in contracts/active contracts/archive inbox/gemini inbox/codex inbox/opus inbox/research inbox/evaluator inbox/e2e reviews; do + for d in contracts/active contracts/archive inbox/gemini inbox/codex inbox/opus inbox/research inbox/evaluator inbox/e2e reviews wiki/modules wiki/decisions wiki/patterns wiki/entities; do touch "$dir/.selfmodel/$d/.gitkeep" done } From f0a980661595782df419c3051ff9653122e103c1 Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:05:18 -0700 Subject: [PATCH 02/22] sprint-W1: add generate_wiki() and reconcile_wiki() functions --- scripts/selfmodel.sh | 414 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 414 insertions(+) diff --git a/scripts/selfmodel.sh b/scripts/selfmodel.sh index c24b7de..361a6c0 100755 --- a/scripts/selfmodel.sh +++ b/scripts/selfmodel.sh @@ -850,6 +850,420 @@ cmd_status() { echo "═══════════════════════════════════════════════════" } +# ─── Generate Wiki ─────────────────────────────────────────────────────────── + +# Code file extensions used to detect whether a directory contains code +WIKI_CODE_EXTENSIONS='*.py *.js *.ts *.tsx *.jsx *.go *.rs *.rb *.java *.kt *.swift *.c *.cpp *.h *.cs *.php *.sh *.lua *.ex *.exs *.zig *.nim *.ml *.hs *.scala *.clj' + +# Directories excluded from module scanning +WIKI_EXCLUDE_PATTERN='^(\.|node_modules|__pycache__|\.venv|venv|vendor|dist|build|\.selfmodel|\.claude|\.github|\.vscode|\.idea|\.next|\.nuxt|coverage|tmp|temp|\.cache|\.turbo|target|out|bin|obj)$' + +# Generate a skeleton module page for a detected code directory +generate_module_page() { + local wiki_dir="$1" + local project_dir="$2" + local module_name="$3" + + local module_file="$wiki_dir/modules/${module_name}.md" + + # Collect up to 10 key files in this module (by extension) + local key_files=() + local find_args=() + for ext in $WIKI_CODE_EXTENSIONS; do + find_args+=(-name "$ext" -o) + done + # Remove trailing -o + unset 'find_args[-1]' + + while IFS= read -r f; do + [[ -z "$f" ]] && continue + # Make path relative to project root + local rel="${f#"$project_dir"/}" + key_files+=("$rel") + done < <(find "$project_dir/$module_name" -maxdepth 3 -type f \( "${find_args[@]}" \) 2>/dev/null | head -10) + + cat > "$module_file" << MODEOF +# ${module_name} + +## Overview +Module detected during project scaffolding. Update this section with a description of what \`${module_name}/\` contains and its role in the architecture. + +## Key Files +MODEOF + + if [[ ${#key_files[@]} -gt 0 ]]; then + for kf in "${key_files[@]}"; do + echo "- \`${kf}\`" >> "$module_file" + done + else + echo "_No code files detected at scan depth._" >> "$module_file" + fi + + cat >> "$module_file" << 'MODEOF2' + +## See Also +_Link related wiki pages here._ + +## Last Updated +Sprint 0 (init) +MODEOF2 +} + +# Main wiki generation function — called during init +generate_wiki() { + local dir="$1" + local wiki_dir="$dir/.selfmodel/wiki" + + # Ensure wiki subdirectories exist + mkdir -p "$wiki_dir"/{modules,decisions,patterns,entities} + + # ── 1. schema.md — page format conventions ────────────────────────────── + cat > "$wiki_dir/schema.md" << 'SCHEMAEOF' +# Wiki Schema + +Page format conventions for the project wiki. + +--- + +## Page Structure + +Every wiki page follows this skeleton: + +```markdown +# Title + +## Overview +Brief description: what this is, why it exists. + +## Details +In-depth content, code references, diagrams. + +## See Also +- [[related-page]] +- [[another-page]] + +## Last Updated +Sprint () +``` + +## Cross-Link Syntax + +Use double-bracket wiki links to reference other pages: +- `[[modules/auth]]` — link to a module page +- `[[decisions/001-database-choice]]` — link to a decision record +- `[[patterns/repository-pattern]]` — link to a pattern page +- `[[entities/user]]` — link to an entity page + +## Naming Conventions + +- **Module pages**: `modules/.md` — one page per code-bearing top-level directory +- **Decision records**: `decisions/-.md` — numbered, append-only +- **Pattern pages**: `patterns/.md` — reusable design patterns +- **Entity pages**: `entities/.md` — domain model entities + +## Update Rules + +1. When a Sprint modifies files in a module, the corresponding `modules/.md` page should be updated. +2. Architectural decisions should be recorded in `decisions/` with rationale and alternatives considered. +3. Updates are logged in `log.md` with timestamp, Sprint reference, and summary. +4. The `index.md` must stay in sync with actual pages — run `selfmodel adapt` to reconcile. + +## Lint Rules + +1. **Page count vs module count**: every code-bearing directory should have a wiki page. +2. **Stale pages**: pages not updated in the last 10 Sprints are flagged. +3. **Broken internal links**: `[[target]]` must resolve to an existing `.md` file. +4. **Empty pages**: pages with 3 or fewer non-blank lines are flagged as stubs. + +## Auto-Sync Spec + +Post-merge, compare `git diff --name-only` against `wiki/modules/`. If code in a module directory changed but its wiki page was not updated, append a warning entry to `log.md`: +``` +[] WARN: code changed in Sprint but wiki page not updated +``` +SCHEMAEOF + + # ── 2. Scan for code-bearing directories ──────────────────────────────── + local module_count=0 + local module_names=() + + for entry in "$dir"/*/; do + [[ ! -d "$entry" ]] && continue + local dirname + dirname=$(basename "$entry") + + # Skip excluded directories + if [[ "$dirname" =~ $WIKI_EXCLUDE_PATTERN ]]; then + continue + fi + + # Check if directory contains code files (up to depth 2) + local find_args=() + for ext in $WIKI_CODE_EXTENSIONS; do + find_args+=(-name "$ext" -o) + done + unset 'find_args[-1]' + + local has_code + has_code=$(find "$entry" -maxdepth 2 -type f \( "${find_args[@]}" \) 2>/dev/null | head -1) + [[ -z "$has_code" ]] && continue + + # Enforce max 20 modules + if [[ $module_count -ge 20 ]]; then + break + fi + + generate_module_page "$wiki_dir" "$dir" "$dirname" + module_names+=("$dirname") + module_count=$((module_count + 1)) + done + + # ── 3. architecture.md from detect_stack results ───────────────────────── + local stacks_str="${DETECTED_STACKS[*]:-none}" + local frameworks_str="${DETECTED_FRAMEWORKS[*]:-none}" + local test_tools_str="${DETECTED_TEST_TOOLS[*]:-none}" + + cat > "$wiki_dir/architecture.md" << ARCHEOF +# Architecture + +## Overview +Project architecture seeded from auto-detection. Update this page as the system evolves. + +## Project Type +${DETECTED_TYPE:-unknown} + +## Tech Stack +- **Languages/Runtimes**: ${stacks_str} +- **Frameworks**: ${frameworks_str} +- **Test Tools**: ${test_tools_str} + +## Directory Tree +ARCHEOF + + # Add top-level directory listing (non-hidden, non-excluded) + for entry in "$dir"/*/; do + [[ ! -d "$entry" ]] && continue + local dirname + dirname=$(basename "$entry") + if [[ "$dirname" =~ $WIKI_EXCLUDE_PATTERN ]]; then + continue + fi + echo "- \`${dirname}/\`" >> "$wiki_dir/architecture.md" + done + + cat >> "$wiki_dir/architecture.md" << 'ARCHEOF2' + +## Key Architectural Decisions +_Record decisions in `decisions/` and link them here._ + +## See Also +- [[modules/]] — per-module documentation +- [[decisions/]] — architectural decision records + +## Last Updated +Sprint 0 (init) +ARCHEOF2 + + # ── 4. index.md listing all generated pages ───────────────────────────── + cat > "$wiki_dir/index.md" << 'INDEXHDR' +# Wiki Index + +Auto-generated page index. Run `selfmodel adapt` to reconcile with actual pages. + +--- + +## Core Pages +- [[schema]] — page format conventions +- [[architecture]] — project architecture overview +- [[log]] — wiki change log + +## Module Pages +INDEXHDR + + for mod in "${module_names[@]}"; do + echo "- [[modules/${mod}]]" >> "$wiki_dir/index.md" + done + + cat >> "$wiki_dir/index.md" << 'INDEXFTR' + +## Decision Records +_None yet. Create `decisions/-.md` to add._ + +## Patterns +_None yet. Create `patterns/.md` to add._ + +## Entities +_None yet. Create `entities/.md` to add._ +INDEXFTR + + # ── 5. log.md with initial entry ───────────────────────────────────────── + local ts + ts=$(date -u +%Y-%m-%dT%H:%M:%SZ) + cat > "$wiki_dir/log.md" << LOGEOF +# Wiki Log + +Chronological record of wiki changes. + +--- + +[${ts}] INIT: wiki created, ${module_count} module page(s) generated +LOGEOF + + ok "Wiki generated: ${module_count} module page(s), schema, architecture, index, log." +} + +# Reconcile wiki during adapt — scan for new modules, update index and log +reconcile_wiki() { + local dir="$1" + local wiki_dir="$dir/.selfmodel/wiki" + + # Ensure wiki subdirectories exist + mkdir -p "$wiki_dir"/{modules,decisions,patterns,entities} + + local new_count=0 + local existing_modules=() + local all_modules=() + + # Collect existing module pages (strip .md extension) + for f in "$wiki_dir"/modules/*.md; do + [[ -f "$f" ]] || continue + local name + name=$(basename "$f" .md) + existing_modules+=("$name") + done + + # Scan for code-bearing directories + local total_scanned=0 + for entry in "$dir"/*/; do + [[ ! -d "$entry" ]] && continue + local dirname + dirname=$(basename "$entry") + + if [[ "$dirname" =~ $WIKI_EXCLUDE_PATTERN ]]; then + continue + fi + + local find_args=() + for ext in $WIKI_CODE_EXTENSIONS; do + find_args+=(-name "$ext" -o) + done + unset 'find_args[-1]' + + local has_code + has_code=$(find "$entry" -maxdepth 2 -type f \( "${find_args[@]}" \) 2>/dev/null | head -1) + [[ -z "$has_code" ]] && continue + + if [[ $total_scanned -ge 20 ]]; then + break + fi + + all_modules+=("$dirname") + total_scanned=$((total_scanned + 1)) + + # Check if module page already exists + local found=false + for existing in "${existing_modules[@]}"; do + if [[ "$existing" == "$dirname" ]]; then + found=true + break + fi + done + + if ! $found; then + generate_module_page "$wiki_dir" "$dir" "$dirname" + new_count=$((new_count + 1)) + fi + done + + # Rebuild index.md with current state + cat > "$wiki_dir/index.md" << 'INDEXHDR' +# Wiki Index + +Auto-generated page index. Run `selfmodel adapt` to reconcile with actual pages. + +--- + +## Core Pages +- [[schema]] — page format conventions +- [[architecture]] — project architecture overview +- [[log]] — wiki change log + +## Module Pages +INDEXHDR + + for mod in "${all_modules[@]}"; do + echo "- [[modules/${mod}]]" >> "$wiki_dir/index.md" + done + + # Include any manually-created module pages not in the scan + for existing in "${existing_modules[@]}"; do + local in_all=false + for mod in "${all_modules[@]}"; do + if [[ "$mod" == "$existing" ]]; then + in_all=true + break + fi + done + if ! $in_all; then + echo "- [[modules/${existing}]]" >> "$wiki_dir/index.md" + fi + done + + # Add decision, pattern, entity sections by scanning actual files + echo "" >> "$wiki_dir/index.md" + echo "## Decision Records" >> "$wiki_dir/index.md" + local has_decisions=false + for f in "$wiki_dir"/decisions/*.md; do + [[ -f "$f" ]] || continue + local name + name=$(basename "$f" .md) + echo "- [[decisions/${name}]]" >> "$wiki_dir/index.md" + has_decisions=true + done + if ! $has_decisions; then + echo "_None yet. Create \`decisions/-.md\` to add._" >> "$wiki_dir/index.md" + fi + + echo "" >> "$wiki_dir/index.md" + echo "## Patterns" >> "$wiki_dir/index.md" + local has_patterns=false + for f in "$wiki_dir"/patterns/*.md; do + [[ -f "$f" ]] || continue + local name + name=$(basename "$f" .md) + echo "- [[patterns/${name}]]" >> "$wiki_dir/index.md" + has_patterns=true + done + if ! $has_patterns; then + echo "_None yet. Create \`patterns/.md\` to add._" >> "$wiki_dir/index.md" + fi + + echo "" >> "$wiki_dir/index.md" + echo "## Entities" >> "$wiki_dir/index.md" + local has_entities=false + for f in "$wiki_dir"/entities/*.md; do + [[ -f "$f" ]] || continue + local name + name=$(basename "$f" .md) + echo "- [[entities/${name}]]" >> "$wiki_dir/index.md" + has_entities=true + done + if ! $has_entities; then + echo "_None yet. Create \`entities/.md\` to add._" >> "$wiki_dir/index.md" + fi + + # Append to log.md + local ts + ts=$(date -u +%Y-%m-%dT%H:%M:%SZ) + echo "[${ts}] ADAPT: wiki reconciled, ${new_count} new module page(s) added, ${total_scanned} total modules" >> "$wiki_dir/log.md" + + if [[ $new_count -gt 0 ]]; then + ok "Wiki reconciled: ${new_count} new module page(s) added." + else + ok "Wiki reconciled: no new modules detected." + fi +} + # ─── Generate Playbook ──────────────────────────────────────────────────────── generate_playbook() { local dir="${1:-.}" From f43dfcc90e72c0f6114bba222f23c867cd698612 Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:05:30 -0700 Subject: [PATCH 03/22] sprint-W1: integrate generate_wiki into cmd_init --- scripts/selfmodel.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/selfmodel.sh b/scripts/selfmodel.sh index 361a6c0..8c3a567 100755 --- a/scripts/selfmodel.sh +++ b/scripts/selfmodel.sh @@ -395,6 +395,9 @@ cmd_init() { # Copy playbook from repo (or generate defaults) generate_playbook "$dir" + # Generate project wiki scaffolding + generate_wiki "$dir" + # Generate hooks and merge settings.json generate_hooks "$dir" From 8f8d813f8b7b63de1130c0f263daf7025a4281a9 Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:05:43 -0700 Subject: [PATCH 04/22] sprint-W1: integrate wiki generate/reconcile into cmd_adapt --- scripts/selfmodel.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/selfmodel.sh b/scripts/selfmodel.sh index 8c3a567..d06f9f1 100755 --- a/scripts/selfmodel.sh +++ b/scripts/selfmodel.sh @@ -496,6 +496,15 @@ cmd_adapt() { # Generate hooks and merge settings.json generate_hooks "$dir" + # Handle wiki — full generate if missing, reconcile if exists + if [[ ! -d "$dir/.selfmodel/wiki" ]]; then + info "No wiki/ found. Generating full wiki scaffolding..." + generate_wiki "$dir" + else + info "Wiki exists. Reconciling modules..." + reconcile_wiki "$dir" + fi + # Handle CLAUDE.md — inject rather than overwrite if [[ -f "$dir/CLAUDE.md" ]]; then if grep -q '' "$dir/CLAUDE.md" 2>/dev/null; then From 403366af0ee2340e425bbb33a8ac9a1c5b740fc6 Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:06:33 -0700 Subject: [PATCH 05/22] sprint-W1: add generate_wiki_protocol to generate_playbook --- scripts/selfmodel.sh | 157 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) diff --git a/scripts/selfmodel.sh b/scripts/selfmodel.sh index d06f9f1..9fdcc13 100755 --- a/scripts/selfmodel.sh +++ b/scripts/selfmodel.sh @@ -1348,9 +1348,166 @@ LESSONSEOF generate_research_protocol "$dir" fi + if [[ ! -f "$dir/.selfmodel/playbook/wiki-protocol.md" ]]; then + info "Generating wiki-protocol.md..." + generate_wiki_protocol "$dir" + fi + ok "Playbook generated." } +# ─── Generate wiki-protocol.md ────────────────────────────────────────────── +generate_wiki_protocol() { + local dir="${1:-.}" + cat > "$dir/.selfmodel/playbook/wiki-protocol.md" << 'WIKIEOF' +# Wiki Protocol + +Project knowledge wiki maintenance protocol. Agents and Leader follow these rules to keep the wiki accurate and useful. + +--- + +## Page Format + +Every wiki page uses this structure: + +```markdown +# Title + +## Overview +Brief description: what this is, why it exists. + +## Details +In-depth content, code references, architecture notes, diagrams. + +## See Also +- [[related-page]] + +## Last Updated +Sprint () +``` + +### Page Types + +| Type | Location | Naming | Purpose | +|------|----------|--------|---------| +| Module | `wiki/modules/.md` | matches top-level directory name | per-module documentation | +| Decision | `wiki/decisions/-.md` | numbered, append-only | architectural decision records | +| Pattern | `wiki/patterns/.md` | descriptive slug | reusable design patterns | +| Entity | `wiki/entities/.md` | domain noun | domain model entities | + +--- + +## Update Rules + +### Sprint-Level Updates + +1. **Contract declaration**: Sprint contracts SHOULD include a `## Wiki Impact` section listing wiki pages that need updating. +2. **Agent responsibility**: When a Sprint modifies code in a module, the agent SHOULD update the corresponding `wiki/modules/.md` page with relevant changes. +3. **Leader validation**: During post-merge review (Step 7), Leader checks if code-changed modules have corresponding wiki page updates. Missing updates are logged to `wiki/log.md` as warnings, not treated as blockers. + +### Update Workflow + +``` +1. Agent modifies code in src/auth/ +2. Agent updates wiki/modules/src.md (or wiki/modules/auth.md if nested) +3. Agent updates "## Last Updated" to current Sprint number +4. Leader verifies wiki update in post-merge diff review +5. If missed: Leader appends warning to wiki/log.md +``` + +### Decision Records + +- Create a new decision record when making significant architectural choices. +- Decision records are append-only — never modify past decisions. +- Format: `decisions/-.md` where NNN is zero-padded sequential. +- Include: context, options considered, chosen option, rationale, consequences. + +--- + +## Lint Rules + +These rules detect wiki staleness and inconsistency: + +### 1. Page Count vs Module Count +Every code-bearing top-level directory should have a corresponding `wiki/modules/.md` page. Run `selfmodel adapt` to auto-generate missing pages. + +**Detection**: Compare `ls -d */` (excluding ignored dirs) against `ls wiki/modules/*.md`. + +### 2. Stale Pages +Pages not updated in the last 10 Sprints are flagged as potentially stale. + +**Detection**: Parse `## Last Updated` line, extract Sprint number, compare against current Sprint from `team.json`. + +### 3. Broken Internal Links +Wiki links (`[[target]]`) must resolve to an existing `.md` file under `wiki/`. + +**Detection**: Extract all `[[...]]` references, verify each resolves to a file at `wiki/.md`. + +### 4. Empty Pages +Pages with 3 or fewer non-blank lines are flagged as stubs needing content. + +**Detection**: `awk 'NF' | wc -l` for each wiki page. + +--- + +## Auto-Sync Spec + +Post-merge automation to detect wiki-code drift: + +### Trigger +After each Sprint merge to main. + +### Detection Logic +```bash +# 1. Get changed code files from Sprint +changed_dirs=$(git diff --name-only HEAD~1..HEAD | \ + grep -v '^\.' | \ + cut -d/ -f1 | \ + sort -u) + +# 2. For each changed dir, check if wiki page was also updated +for dir_name in $changed_dirs; do + wiki_page="wiki/modules/${dir_name}.md" + if [ -f ".selfmodel/$wiki_page" ]; then + # Check if wiki page was in the diff + if ! git diff --name-only HEAD~1..HEAD | grep -q ".selfmodel/$wiki_page"; then + # Wiki page exists but was not updated + echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] WARN: ${dir_name} code changed but wiki page not updated" >> .selfmodel/wiki/log.md + fi + fi +done +``` + +### Output +Warnings are appended to `wiki/log.md`. They are informational — they do not block merges or fail CI. + +--- + +## Wiki Scaffolding + +### During `selfmodel init` +1. `create_structure()` creates `wiki/{modules,decisions,patterns,entities}` with `.gitkeep` files. +2. `generate_wiki()` creates: + - `schema.md` — page format conventions + - `modules/.md` — skeleton page for each detected code-bearing directory (max 20) + - `architecture.md` — seeded from `detect_stack` results + - `index.md` — listing all generated pages + - `log.md` — with initial INIT entry + +### During `selfmodel adapt` +1. If `wiki/` missing → full `generate_wiki()` run. +2. If `wiki/` exists → `reconcile_wiki()`: + - Scan for new code-bearing directories not yet in `wiki/modules/`. + - Generate skeleton pages for new modules. + - Rebuild `index.md` from current state. + - Append ADAPT entry to `log.md`. + +### Excluded Directories +The following directories are never treated as modules: +`.git`, `node_modules`, `__pycache__`, `.venv`, `venv`, `vendor`, `dist`, `build`, `.selfmodel`, `.claude`, `.github`, `.vscode`, `.idea`, `.next`, `.nuxt`, `coverage`, `tmp`, `temp`, `.cache`, `.turbo`, `target`, `out`, `bin`, `obj` +WIKIEOF +} + # ─── Generate Hooks ────────────────────────────────────────────────────────── # Write hook scripts via Heredoc and merge hooks config into settings.json generate_hooks() { From 52498a19ce15ac25de5175e0866f6a5a84b00264 Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:07:02 -0700 Subject: [PATCH 06/22] sprint-W1: create wiki-protocol.md in playbook and skill/references --- .selfmodel/playbook/wiki-protocol.md | 145 +++++++++++++++++++++++++++ skill/references/wiki-protocol.md | 145 +++++++++++++++++++++++++++ 2 files changed, 290 insertions(+) create mode 100644 .selfmodel/playbook/wiki-protocol.md create mode 100644 skill/references/wiki-protocol.md diff --git a/.selfmodel/playbook/wiki-protocol.md b/.selfmodel/playbook/wiki-protocol.md new file mode 100644 index 0000000..c6c970d --- /dev/null +++ b/.selfmodel/playbook/wiki-protocol.md @@ -0,0 +1,145 @@ +# Wiki Protocol + +Project knowledge wiki maintenance protocol. Agents and Leader follow these rules to keep the wiki accurate and useful. + +--- + +## Page Format + +Every wiki page uses this structure: + +```markdown +# Title + +## Overview +Brief description: what this is, why it exists. + +## Details +In-depth content, code references, architecture notes, diagrams. + +## See Also +- [[related-page]] + +## Last Updated +Sprint () +``` + +### Page Types + +| Type | Location | Naming | Purpose | +|------|----------|--------|---------| +| Module | `wiki/modules/.md` | matches top-level directory name | per-module documentation | +| Decision | `wiki/decisions/-.md` | numbered, append-only | architectural decision records | +| Pattern | `wiki/patterns/.md` | descriptive slug | reusable design patterns | +| Entity | `wiki/entities/.md` | domain noun | domain model entities | + +--- + +## Update Rules + +### Sprint-Level Updates + +1. **Contract declaration**: Sprint contracts SHOULD include a `## Wiki Impact` section listing wiki pages that need updating. +2. **Agent responsibility**: When a Sprint modifies code in a module, the agent SHOULD update the corresponding `wiki/modules/.md` page with relevant changes. +3. **Leader validation**: During post-merge review (Step 7), Leader checks if code-changed modules have corresponding wiki page updates. Missing updates are logged to `wiki/log.md` as warnings, not treated as blockers. + +### Update Workflow + +``` +1. Agent modifies code in src/auth/ +2. Agent updates wiki/modules/src.md (or wiki/modules/auth.md if nested) +3. Agent updates "## Last Updated" to current Sprint number +4. Leader verifies wiki update in post-merge diff review +5. If missed: Leader appends warning to wiki/log.md +``` + +### Decision Records + +- Create a new decision record when making significant architectural choices. +- Decision records are append-only — never modify past decisions. +- Format: `decisions/-.md` where NNN is zero-padded sequential. +- Include: context, options considered, chosen option, rationale, consequences. + +--- + +## Lint Rules + +These rules detect wiki staleness and inconsistency: + +### 1. Page Count vs Module Count +Every code-bearing top-level directory should have a corresponding `wiki/modules/.md` page. Run `selfmodel adapt` to auto-generate missing pages. + +**Detection**: Compare `ls -d */` (excluding ignored dirs) against `ls wiki/modules/*.md`. + +### 2. Stale Pages +Pages not updated in the last 10 Sprints are flagged as potentially stale. + +**Detection**: Parse `## Last Updated` line, extract Sprint number, compare against current Sprint from `team.json`. + +### 3. Broken Internal Links +Wiki links (`[[target]]`) must resolve to an existing `.md` file under `wiki/`. + +**Detection**: Extract all `[[...]]` references, verify each resolves to a file at `wiki/.md`. + +### 4. Empty Pages +Pages with 3 or fewer non-blank lines are flagged as stubs needing content. + +**Detection**: `awk 'NF' | wc -l` for each wiki page. + +--- + +## Auto-Sync Spec + +Post-merge automation to detect wiki-code drift: + +### Trigger +After each Sprint merge to main. + +### Detection Logic +```bash +# 1. Get changed code files from Sprint +changed_dirs=$(git diff --name-only HEAD~1..HEAD | \ + grep -v '^\.' | \ + cut -d/ -f1 | \ + sort -u) + +# 2. For each changed dir, check if wiki page was also updated +for dir_name in $changed_dirs; do + wiki_page="wiki/modules/${dir_name}.md" + if [ -f ".selfmodel/$wiki_page" ]; then + # Check if wiki page was in the diff + if ! git diff --name-only HEAD~1..HEAD | grep -q ".selfmodel/$wiki_page"; then + # Wiki page exists but was not updated + echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] WARN: ${dir_name} code changed but wiki page not updated" >> .selfmodel/wiki/log.md + fi + fi +done +``` + +### Output +Warnings are appended to `wiki/log.md`. They are informational — they do not block merges or fail CI. + +--- + +## Wiki Scaffolding + +### During `selfmodel init` +1. `create_structure()` creates `wiki/{modules,decisions,patterns,entities}` with `.gitkeep` files. +2. `generate_wiki()` creates: + - `schema.md` — page format conventions + - `modules/.md` — skeleton page for each detected code-bearing directory (max 20) + - `architecture.md` — seeded from `detect_stack` results + - `index.md` — listing all generated pages + - `log.md` — with initial INIT entry + +### During `selfmodel adapt` +1. If `wiki/` missing → full `generate_wiki()` run. +2. If `wiki/` exists → `reconcile_wiki()`: + - Scan for new code-bearing directories not yet in `wiki/modules/`. + - Generate skeleton pages for new modules. + - Rebuild `index.md` from current state. + - Append ADAPT entry to `log.md`. + +### Excluded Directories +The following directories are never treated as modules: +`.git`, `node_modules`, `__pycache__`, `.venv`, `venv`, `vendor`, `dist`, `build`, `.selfmodel`, `.claude`, `.github`, `.vscode`, `.idea`, `.next`, `.nuxt`, `coverage`, `tmp`, `temp`, `.cache`, `.turbo`, `target`, `out`, `bin`, `obj` diff --git a/skill/references/wiki-protocol.md b/skill/references/wiki-protocol.md new file mode 100644 index 0000000..c6c970d --- /dev/null +++ b/skill/references/wiki-protocol.md @@ -0,0 +1,145 @@ +# Wiki Protocol + +Project knowledge wiki maintenance protocol. Agents and Leader follow these rules to keep the wiki accurate and useful. + +--- + +## Page Format + +Every wiki page uses this structure: + +```markdown +# Title + +## Overview +Brief description: what this is, why it exists. + +## Details +In-depth content, code references, architecture notes, diagrams. + +## See Also +- [[related-page]] + +## Last Updated +Sprint () +``` + +### Page Types + +| Type | Location | Naming | Purpose | +|------|----------|--------|---------| +| Module | `wiki/modules/.md` | matches top-level directory name | per-module documentation | +| Decision | `wiki/decisions/-.md` | numbered, append-only | architectural decision records | +| Pattern | `wiki/patterns/.md` | descriptive slug | reusable design patterns | +| Entity | `wiki/entities/.md` | domain noun | domain model entities | + +--- + +## Update Rules + +### Sprint-Level Updates + +1. **Contract declaration**: Sprint contracts SHOULD include a `## Wiki Impact` section listing wiki pages that need updating. +2. **Agent responsibility**: When a Sprint modifies code in a module, the agent SHOULD update the corresponding `wiki/modules/.md` page with relevant changes. +3. **Leader validation**: During post-merge review (Step 7), Leader checks if code-changed modules have corresponding wiki page updates. Missing updates are logged to `wiki/log.md` as warnings, not treated as blockers. + +### Update Workflow + +``` +1. Agent modifies code in src/auth/ +2. Agent updates wiki/modules/src.md (or wiki/modules/auth.md if nested) +3. Agent updates "## Last Updated" to current Sprint number +4. Leader verifies wiki update in post-merge diff review +5. If missed: Leader appends warning to wiki/log.md +``` + +### Decision Records + +- Create a new decision record when making significant architectural choices. +- Decision records are append-only — never modify past decisions. +- Format: `decisions/-.md` where NNN is zero-padded sequential. +- Include: context, options considered, chosen option, rationale, consequences. + +--- + +## Lint Rules + +These rules detect wiki staleness and inconsistency: + +### 1. Page Count vs Module Count +Every code-bearing top-level directory should have a corresponding `wiki/modules/.md` page. Run `selfmodel adapt` to auto-generate missing pages. + +**Detection**: Compare `ls -d */` (excluding ignored dirs) against `ls wiki/modules/*.md`. + +### 2. Stale Pages +Pages not updated in the last 10 Sprints are flagged as potentially stale. + +**Detection**: Parse `## Last Updated` line, extract Sprint number, compare against current Sprint from `team.json`. + +### 3. Broken Internal Links +Wiki links (`[[target]]`) must resolve to an existing `.md` file under `wiki/`. + +**Detection**: Extract all `[[...]]` references, verify each resolves to a file at `wiki/.md`. + +### 4. Empty Pages +Pages with 3 or fewer non-blank lines are flagged as stubs needing content. + +**Detection**: `awk 'NF' | wc -l` for each wiki page. + +--- + +## Auto-Sync Spec + +Post-merge automation to detect wiki-code drift: + +### Trigger +After each Sprint merge to main. + +### Detection Logic +```bash +# 1. Get changed code files from Sprint +changed_dirs=$(git diff --name-only HEAD~1..HEAD | \ + grep -v '^\.' | \ + cut -d/ -f1 | \ + sort -u) + +# 2. For each changed dir, check if wiki page was also updated +for dir_name in $changed_dirs; do + wiki_page="wiki/modules/${dir_name}.md" + if [ -f ".selfmodel/$wiki_page" ]; then + # Check if wiki page was in the diff + if ! git diff --name-only HEAD~1..HEAD | grep -q ".selfmodel/$wiki_page"; then + # Wiki page exists but was not updated + echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] WARN: ${dir_name} code changed but wiki page not updated" >> .selfmodel/wiki/log.md + fi + fi +done +``` + +### Output +Warnings are appended to `wiki/log.md`. They are informational — they do not block merges or fail CI. + +--- + +## Wiki Scaffolding + +### During `selfmodel init` +1. `create_structure()` creates `wiki/{modules,decisions,patterns,entities}` with `.gitkeep` files. +2. `generate_wiki()` creates: + - `schema.md` — page format conventions + - `modules/.md` — skeleton page for each detected code-bearing directory (max 20) + - `architecture.md` — seeded from `detect_stack` results + - `index.md` — listing all generated pages + - `log.md` — with initial INIT entry + +### During `selfmodel adapt` +1. If `wiki/` missing → full `generate_wiki()` run. +2. If `wiki/` exists → `reconcile_wiki()`: + - Scan for new code-bearing directories not yet in `wiki/modules/`. + - Generate skeleton pages for new modules. + - Rebuild `index.md` from current state. + - Append ADAPT entry to `log.md`. + +### Excluded Directories +The following directories are never treated as modules: +`.git`, `node_modules`, `__pycache__`, `.venv`, `venv`, `vendor`, `dist`, `build`, `.selfmodel`, `.claude`, `.github`, `.vscode`, `.idea`, `.next`, `.nuxt`, `coverage`, `tmp`, `temp`, `.cache`, `.turbo`, `target`, `out`, `bin`, `obj` From b22245ad72b00e12565bc17474d375dcc58f8df3 Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:14:05 -0700 Subject: [PATCH 07/22] sprint-W2: add wiki injection to session-start hook Inject wiki/index.md content and last 10 lines of wiki/log.md into the session-start hook output. Changes applied to both the live hook file and the selfmodel.sh heredoc that generates it. Also adds wiki-protocol.md to the playbook_files consistency check array. Co-Authored-By: Claude Opus 4.6 (1M context) --- scripts/hooks/session-start.sh | 16 ++++++++ scripts/selfmodel.sh | 73 +++++++++++++++++++++++++++++++++- 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/scripts/hooks/session-start.sh b/scripts/hooks/session-start.sh index 0333ce4..a8e3ae5 100755 --- a/scripts/hooks/session-start.sh +++ b/scripts/hooks/session-start.sh @@ -34,6 +34,22 @@ else echo "(next-session.md 不存在,跳过)" fi +echo "" +echo "── Wiki Index ──" +WIKI_INDEX="${PROJECT_ROOT}/.selfmodel/wiki/index.md" +if [[ -f "${WIKI_INDEX}" ]]; then + cat "${WIKI_INDEX}" +else + echo "(wiki not initialized)" +fi + +echo "" +echo "── Wiki Recent ──" +WIKI_LOG="${PROJECT_ROOT}/.selfmodel/wiki/log.md" +if [[ -f "${WIKI_LOG}" ]]; then + tail -10 "${WIKI_LOG}" +fi + echo "" echo "═══════════════════════════════════════════════════" diff --git a/scripts/selfmodel.sh b/scripts/selfmodel.sh index 2b88c66..81179e3 100755 --- a/scripts/selfmodel.sh +++ b/scripts/selfmodel.sh @@ -831,7 +831,7 @@ cmd_status() { echo "────────────────────────────────────────────────────" local playbook_files=("dispatch-rules.md" "quality-gates.md" "sprint-template.md" \ "evaluator-prompt.md" "e2e-protocol.md" "e2e-protocol-v2.md" "orchestration-loop.md" \ - "research-protocol.md" "context-protocol.md" "lessons-learned.md") + "research-protocol.md" "context-protocol.md" "lessons-learned.md" "wiki-protocol.md") local missing=0 for f in "${playbook_files[@]}"; do if [[ ! -f "$selfmodel_dir/playbook/$f" ]]; then @@ -843,6 +843,61 @@ cmd_status() { ok "Playbook: all ${#playbook_files[@]} files present" fi + # Wiki health + echo "────────────────────────────────────────────────────" + local wiki_dir="$selfmodel_dir/wiki" + if [[ -d "$wiki_dir" ]]; then + local wiki_pages wiki_modules wiki_stale wiki_empty wiki_score + + # Count all .md pages (excluding log.md which is append-only) + wiki_pages=$(find "$wiki_dir" -name "*.md" ! -name "log.md" 2>/dev/null | wc -l | tr -d ' ') + + # Count module pages + wiki_modules=0 + if [[ -d "$wiki_dir/modules" ]]; then + wiki_modules=$(find "$wiki_dir/modules" -name "*.md" 2>/dev/null | wc -l | tr -d ' ') + fi + + # Stale detection: pages without "## Last Updated" line + wiki_stale=0 + while IFS= read -r page; do + [[ -z "$page" ]] && continue + if ! grep -q "^## Last Updated" "$page" 2>/dev/null; then + wiki_stale=$((wiki_stale + 1)) + fi + done < <(find "$wiki_dir" -name "*.md" ! -name "log.md" 2>/dev/null) + + # Empty detection: pages with <= 3 lines (excluding schema.md and log.md) + wiki_empty=0 + while IFS= read -r page; do + [[ -z "$page" ]] && continue + local basename_page + basename_page=$(basename "$page") + if [[ "$basename_page" == "schema.md" || "$basename_page" == "log.md" ]]; then + continue + fi + local line_count + line_count=$(wc -l < "$page" | tr -d ' ') + if [[ "$line_count" -le 3 ]]; then + wiki_empty=$((wiki_empty + 1)) + fi + done < <(find "$wiki_dir" -name "*.md" 2>/dev/null) + + # Health score: 10 - empty_count - (stale > 2 ? 2 : 0), minimum 0 + wiki_score=10 + wiki_score=$((wiki_score - wiki_empty)) + if [[ "$wiki_stale" -gt 2 ]]; then + wiki_score=$((wiki_score - 2)) + fi + if [[ "$wiki_score" -lt 0 ]]; then + wiki_score=0 + fi + + echo "Wiki: $wiki_pages pages ($wiki_modules modules) | $wiki_stale stale | $wiki_empty empty | health: $wiki_score/10" + else + warn "Wiki: not initialized (run 'selfmodel init' or 'selfmodel adapt')" + fi + echo "═══════════════════════════════════════════════════" } @@ -986,6 +1041,22 @@ else echo "(next-session.md 不存在,跳过)" fi +echo "" +echo "── Wiki Index ──" +WIKI_INDEX="${PROJECT_ROOT}/.selfmodel/wiki/index.md" +if [[ -f "${WIKI_INDEX}" ]]; then + cat "${WIKI_INDEX}" +else + echo "(wiki not initialized)" +fi + +echo "" +echo "── Wiki Recent ──" +WIKI_LOG="${PROJECT_ROOT}/.selfmodel/wiki/log.md" +if [[ -f "${WIKI_LOG}" ]]; then + tail -10 "${WIKI_LOG}" +fi + echo "" echo "═══════════════════════════════════════════════════" From 6ae8466324bd388396f8277ca781e44e076ad745 Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:14:16 -0700 Subject: [PATCH 08/22] sprint-W2: add Wiki Impact section to sprint templates Add optional '## Wiki Impact' section to both sprint-template.md copies (playbook and skill/references). Placed after Chaos Gate section. Agents list affected wiki pages; Leader validates in post-merge. Co-Authored-By: Claude Opus 4.6 (1M context) --- .selfmodel/playbook/sprint-template.md | 4 ++++ skill/references/sprint-template.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/.selfmodel/playbook/sprint-template.md b/.selfmodel/playbook/sprint-template.md index 17c66e2..2d11475 100644 --- a/.selfmodel/playbook/sprint-template.md +++ b/.selfmodel/playbook/sprint-template.md @@ -41,3 +41,7 @@ DRAFT → ACTIVE → DELIVERED → REVIEWED → MERGED | REJECTED - Budget: 5m - Threshold: resilience >= 70 (Leader dispatches `/rampage --selfmodel` after E2E PASS, see quality-gates.md Step 4.7) + +## Wiki Impact (optional — which wiki pages this Sprint affects) +- +(Agent updates these pages as part of delivery. Leader validates in post-merge.) diff --git a/skill/references/sprint-template.md b/skill/references/sprint-template.md index 0f0b421..684cd93 100644 --- a/skill/references/sprint-template.md +++ b/skill/references/sprint-template.md @@ -78,6 +78,10 @@ - Threshold: resilience >= 70 (Leader 在 E2E PASS 后可选派发 `/rampage --selfmodel`,详见 quality-gates.md Step 4.7) +## Wiki Impact(可选 — 本 Sprint 影响的 wiki 页面) +- +(Agent 在交付时更新这些页面。Leader 在 post-merge 时验证。) + ## Cost (Leader 填写,Sprint 完成后) - Tokens: - Duration: From 0c0620cd22ce93ff0151cfb54f0b4c39ab3295a9 Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:14:21 -0700 Subject: [PATCH 09/22] sprint-W2: add wiki sync and audit to orchestration loop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Step 7.6 POST-MERGE WIKI SYNC after smoke test — extracts changed files, maps to wiki/modules/ pages, logs warnings for stale wiki impact entries. Informational only, does not block merge. Add wiki health audit sub-step (v) to Step 8.5 EVOLUTION CHECK — runs wiki health check every 10 merged sprints, logs warnings when health degrades below 7 or stale pages exceed 5. Co-Authored-By: Claude Opus 4.6 (1M context) --- .selfmodel/playbook/orchestration-loop.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.selfmodel/playbook/orchestration-loop.md b/.selfmodel/playbook/orchestration-loop.md index a669336..8f8b798 100644 --- a/.selfmodel/playbook/orchestration-loop.md +++ b/.selfmodel/playbook/orchestration-loop.md @@ -215,6 +215,14 @@ LOOP: - Write feedback: "Post-merge regression detected: " - Agent must fix in worktree, re-rebase, re-merge + 7.6. POST-MERGE WIKI SYNC (after smoke test passes) + a. Extract changed files: git diff HEAD~1 --name-only + b. Map to wiki/modules/ pages + c. Check Sprint contract ## Wiki Impact — listed pages not updated → log warning + d. Update wiki/index.md if new pages created + e. Informational only — does NOT block merge + f. Append to wiki/log.md: [timestamp] SYNC sprint-: + 8. CHECKPOINT - Write next-session.md (current phase + completed sprints + pending) - Append to quality.jsonl @@ -228,6 +236,10 @@ LOOP: ii. Log: phase= event=evolution_detect candidates= iii. If candidates > 0: notify user "N evolution candidates. Run /selfmodel:evolve" iv. Update team.json: evolution.last_review_sprint = current_sprint + v. Wiki health audit: run `selfmodel status` wiki health check + - If health < 7: log warning "wiki health degraded: /10" + - If stale > 5: log warning "N wiki pages stale — schedule wiki refresh" + - Append to orchestration.log: phase= event=wiki_audit health= stale= empty= d. If count < 10: skip 9. CHECK context health From 2b937c69cd5098791d3621726c648dabcdbc2fdb Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:16:47 -0700 Subject: [PATCH 10/22] sprint-W3: add wiki protocol reference --- CLAUDE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CLAUDE.md b/CLAUDE.md index 816a92d..8fea162 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -254,6 +254,7 @@ Contract template → read `.selfmodel/playbook/sprint-template.md` | E2E 验证协议 v2 | `.selfmodel/playbook/e2e-protocol-v2.md` | | 混沌渗透测试(Rampage) | `/rampage` skill (`~/.claude/skills/rampage/SKILL.md`) | | Context checkpoint + reset protocol | `.selfmodel/playbook/context-protocol.md` | +| Wiki protocol + page format | `.selfmodel/playbook/wiki-protocol.md` | ## Context Management From b21121b69a709fb6feff967882c8eba87cc27b86 Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:16:54 -0700 Subject: [PATCH 11/22] sprint-W3: add wiki scan to session start --- CLAUDE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CLAUDE.md b/CLAUDE.md index 8fea162..ad6c31f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -267,6 +267,7 @@ Contract template → read `.selfmodel/playbook/sprint-template.md` 2. Read .selfmodel/state/next-session.md (last handoff) 3. Read .selfmodel/state/team.json (team state) 4. Scan .selfmodel/contracts/active/ (pending contracts) +4.5. Scan .selfmodel/wiki/index.md (wiki catalog — auto-injected by session-start hook) 5. PRE-FLIGHT CHECK: a. git branch --show-current → MUST be "main", else STOP and fix b. git worktree list → MUST show only main, else merge/discard orphan branches From b521f5fd46183d0efa14c300c50367d8296df37c Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:17:01 -0700 Subject: [PATCH 12/22] sprint-W3: document wiki directory structure --- CLAUDE.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index ad6c31f..4d3ca27 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -350,6 +350,15 @@ selfmodel/ ├── inbox/evaluator/ # Leader→Evaluator eval files ├── inbox/e2e/ # Leader→E2E Agent v2 验证任务 ├── artifacts/ # 验证产物(E2E 截图/日志 + Rampage 韧性报告) + ├── wiki/ # Project knowledge base (auto-managed) + │ ├── index.md # Content catalog + │ ├── log.md # Update log (append-only) + │ ├── schema.md # Page conventions + │ ├── architecture.md # System overview + │ ├── modules/ # Per-module pages + │ ├── decisions/ # Architecture Decision Records + │ ├── patterns/ # Code patterns + │ └── entities/ # Key concepts ├── state/team.json # Team state ├── state/next-session.md # Session handoff ├── state/plan.md # Orchestration plan (phases + sprints) From 4c61da47b899739285cfa0d7ac908b03672fedb8 Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:17:07 -0700 Subject: [PATCH 13/22] sprint-W3: add project wiki overview --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 0cfd5cb..c48bb2c 100644 --- a/README.md +++ b/README.md @@ -198,6 +198,16 @@ Every 10 completed sprints, selfmodel can turn validated local process improveme - **SUBMIT** — Package staged patches into an upstream PR after path audits and applicability checks. Human approval is required before any submission. - **TRACK** — Monitor open PRs and sync ACCEPTED, REJECTED, or CONFLICT states back into `evolution.jsonl`. +### Project Wiki + +selfmodel auto-generates and maintains a project knowledge base at `.selfmodel/wiki/`. No separate command — wiki is woven into existing flows: + +- **`selfmodel init`** scaffolds wiki with detected module pages and architecture overview +- **Session start hook** injects wiki index into Leader context automatically +- **Sprint contracts** can declare `## Wiki Impact` for pages the agent should update +- **Post-merge** (Step 7.6) detects stale wiki pages from code diffs +- **`selfmodel status`** reports wiki health score (page count, staleness, completeness) + ## Chaos Testing: /rampage `/rampage` is a standalone Claude Code skill that acts as the most chaotic, boundary-pushing user imaginable. It finds bugs that systematic QA never catches: race conditions, state corruption, navigation traps, input edge cases. From 1ad357b5f4cc7f069372c1ef010af26a7ab50b13 Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:17:12 -0700 Subject: [PATCH 14/22] sprint-W3: add wiki to skill directory structure --- skill/SKILL.md | 1 + 1 file changed, 1 insertion(+) diff --git a/skill/SKILL.md b/skill/SKILL.md index 7ba2f2e..7d4e5fb 100644 --- a/skill/SKILL.md +++ b/skill/SKILL.md @@ -97,6 +97,7 @@ project/ ├── inbox/{gemini,codex,opus,research,evaluator,e2e}/ ├── hooks/ # Hook scripts (copied from skill) ├── artifacts/ # E2E verification evidence + ├── wiki/ # Project knowledge base (auto-managed) ├── reviews/ # Evaluation verdicts └── state/ ├── team.json # Agent roster + stats From 2b66e33027b698b42099245731d389d2c83683a4 Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:17:21 -0700 Subject: [PATCH 15/22] sprint-W3: expand wiki externalization targets --- .selfmodel/playbook/context-protocol.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.selfmodel/playbook/context-protocol.md b/.selfmodel/playbook/context-protocol.md index 9865fb0..86f7ca1 100644 --- a/.selfmodel/playbook/context-protocol.md +++ b/.selfmodel/playbook/context-protocol.md @@ -84,7 +84,9 @@ Claude Code 的自动 compaction 会压缩历史消息,但: | 信息类型 | 外部化目标 | |----------|-----------| -| 架构决策 | `playbook/lessons-learned.md` | +| 架构决策 | `wiki/decisions/` (ADR) + `playbook/lessons-learned.md` | +| 模块知识 | `wiki/modules/.md` | +| 发现的模式 | `wiki/patterns/.md` | | Sprint 进度 | `state/next-session.md` | | 团队状态 | `state/team.json` | | 质量评分 | `state/quality.jsonl` | From c8867b4dd67ab2b6efb0d6bf7c3bbe3a612f38db Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:47:35 -0700 Subject: [PATCH 16/22] sprint-CLI1: consolidate CLI with smart dashboard, idempotent init, interactive evolve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Six changes to selfmodel CLI UX: 1. cmd_dashboard() — new default command: shows status summary, suggests next action based on state (delivered contracts, missing plan, evolution overdue), and appends 8-line command reference with Terminal + Claude Code columns. 2. cmd_init() idempotent — when .selfmodel/ already exists, runs non-destructive adapt logic instead of erroring out. Adapt body extracted into _adapt_existing_project() shared helper. 3. cmd_adapt() deprecated — prints deprecation warning, delegates to cmd_init. Backward compatible. 4. evolve_interactive() — chains detect -> stage -> offer submit with user confirmation gates between phases. Now the default for 'selfmodel evolve' (no flags). 5. Two-tier help — cmd_help_short() for dashboard (8-line quick ref), cmd_help_full() for --help (full reference with slash commands section). 6. main() routing — default changed from 'help' to 'dashboard', 'version' removed from Commands list (--version flag only), added setup/sync aliases, preserved all backward compat. Zero new shellcheck warnings. All existing commands continue to work. --- scripts/selfmodel.sh | 289 +++++++++++++++++++++++++++++++------------ 1 file changed, 213 insertions(+), 76 deletions(-) diff --git a/scripts/selfmodel.sh b/scripts/selfmodel.sh index 2b88c66..45ea932 100755 --- a/scripts/selfmodel.sh +++ b/scripts/selfmodel.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash # selfmodel — AI Agent Team 工作流初始化与适配工具 -# Usage: selfmodel [options] +# Usage: selfmodel [command] [options] +# With no args, shows smart dashboard. Run selfmodel --help for full reference. # Requires: jq (for JSON processing). macOS + Linux. set -eo pipefail @@ -346,10 +347,11 @@ cmd_init() { info "Initializing selfmodel in $(bold "$dir")" - # Check for existing selfmodel + # Idempotent: if .selfmodel/ already exists, run non-destructive adapt logic if [[ -d "$dir/.selfmodel" ]]; then - warn ".selfmodel/ already exists. Use 'selfmodel adapt' instead." - exit 1 + info ".selfmodel/ exists. Running non-destructive update..." + _adapt_existing_project "$dir" + return 0 fi # Detect if there's an existing project @@ -410,31 +412,12 @@ cmd_init() { info "Next: review CLAUDE.md, then create your first Sprint contract." } -# ─── CMD: adapt ─────────────────────────────────────────────────────────────── -cmd_adapt() { - [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]] && { - echo "Usage: selfmodel adapt [directory]" - echo "" - echo " Adapt selfmodel to an existing project." - echo " Re-detects project stack and updates configuration without overwriting agents or history." - echo "" - echo "Arguments:" - echo " directory Target directory (default: current directory)" - return 0 - } - +# ─── Adapt Helper: non-destructive update for existing .selfmodel/ ──────────── +# Extracted from old cmd_adapt so both cmd_init (idempotent) and cmd_adapt +# (deprecated alias) share the same body. Takes one arg: target directory. +_adapt_existing_project() { local dir="${1:-.}" - # Validate path - if [[ "$dir" != "." && ! -e "$dir" ]]; then - err "Directory does not exist: $dir" - exit 1 - fi - if [[ "$dir" != "." && -e "$dir" && ! -d "$dir" ]]; then - err "Path is not a directory: $dir" - exit 1 - fi - info "Adapting selfmodel to existing project in $(bold "$dir")" # Detect stack @@ -506,6 +489,12 @@ cmd_adapt() { ok "selfmodel adapted! ($SELFMODEL_VERSION)" } +# ─── CMD: adapt (deprecated — delegates to cmd_init) ───────────────────────── +cmd_adapt() { + warn "'selfmodel adapt' is deprecated. Use 'selfmodel init' (now idempotent)." + cmd_init "$@" +} + # ─── CMD: update ────────────────────────────────────────────────────────────── cmd_update() { [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]] && { @@ -3094,6 +3083,62 @@ evolve_status() { echo "═════════════════════════════════════════" } +# ─── evolve_interactive: guided pipeline detect → stage → offer submit ──────── +evolve_interactive() { + local dir="$1" + + info "Running interactive evolution pipeline..." + echo "" + + # Phase 1: detect + info "Phase 1/3: Detecting evolution candidates..." + if ! evolve_detect "$dir"; then + warn "Detection encountered issues. Stopping interactive pipeline." + return 1 + fi + echo "" + + # Check if there are any CANDIDATE entries to stage + local evo_file="$dir/.selfmodel/state/evolution.jsonl" + local candidate_count=0 + if [[ -f "$evo_file" ]] && [[ -s "$evo_file" ]]; then + candidate_count=$(jq -c 'select(.status == "CANDIDATE")' "$evo_file" 2>/dev/null | wc -l | tr -d ' ') + fi + + if [[ "$candidate_count" -eq 0 ]]; then + info "No candidates to stage. Pipeline complete." + return 0 + fi + + # Phase 2: stage + info "Phase 2/3: Staging candidates ($candidate_count found)..." + confirm "Proceed to interactive staging?" || { + info "Skipped staging. Run 'selfmodel evolve --stage' later." + return 0 + } + evolve_stage "$dir" + echo "" + + # Check if there are any STAGED entries to submit + local staged_count=0 + if [[ -f "$evo_file" ]] && [[ -s "$evo_file" ]]; then + staged_count=$(jq -c 'select(.status == "STAGED")' "$evo_file" 2>/dev/null | wc -l | tr -d ' ') + fi + + if [[ "$staged_count" -eq 0 ]]; then + info "No staged entries to submit. Pipeline complete." + return 0 + fi + + # Phase 3: offer submit + info "Phase 3/3: $staged_count staged entries ready for upstream submission." + confirm "Submit staged patches as upstream PR?" || { + info "Skipped submission. Run 'selfmodel evolve --submit' later." + return 0 + } + evolve_submit "$dir" +} + # Main evolve command: parse flags and route. cmd_evolve() { [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]] && { @@ -3102,10 +3147,10 @@ cmd_evolve() { echo " Evolution pipeline: detect local improvements, classify generalizability," echo " package patches, and submit PRs to upstream selfmodel." echo "" + echo " With no flags, runs the interactive pipeline: detect → stage → submit." + echo "" echo "Flags:" echo " --detect Scan playbook/hooks/scripts diffs against upstream baseline" - echo " Writes CANDIDATE entries to .selfmodel/state/evolution.jsonl" - echo " This is the default action when no flag is specified." echo " --status Show evolution pipeline status (counts, timestamps, PR URLs)" echo " --stage Interactively classify CANDIDATE entries (Stage/Reject/Keep)" echo " --submit Create upstream PR from STAGED patches (requires gh CLI)" @@ -3113,8 +3158,8 @@ cmd_evolve() { echo " --help Show this help message" echo "" echo "Examples:" - echo " selfmodel evolve # Run detection (default)" - echo " selfmodel evolve --detect # Explicit detection scan" + echo " selfmodel evolve # Interactive pipeline (default)" + echo " selfmodel evolve --detect # Detection scan only" echo " selfmodel evolve --status # View pipeline status" echo " selfmodel evolve --stage # Classify candidates interactively" echo " selfmodel evolve --submit # Submit staged patches as PR" @@ -3123,7 +3168,7 @@ cmd_evolve() { } local dir="." - local action="detect" + local action="interactive" # Parse flags while [[ $# -gt 0 ]]; do @@ -3144,11 +3189,12 @@ cmd_evolve() { fi case "$action" in - detect) evolve_detect "$dir" ;; - status) evolve_status "$dir" ;; - stage) evolve_stage "$dir" ;; - submit) evolve_submit "$dir" ;; - track) evolve_track "$dir" ;; + interactive) evolve_interactive "$dir" ;; + detect) evolve_detect "$dir" ;; + status) evolve_status "$dir" ;; + stage) evolve_stage "$dir" ;; + submit) evolve_submit "$dir" ;; + track) evolve_track "$dir" ;; *) err "Unknown evolve action: $action" return 1 @@ -3156,50 +3202,141 @@ cmd_evolve() { esac } +# ─── CMD: dashboard (smart default) ────────────────────────────────────────── +cmd_dashboard() { + local dir="${1:-.}" + local selfmodel_dir="$dir/.selfmodel" + + # If no .selfmodel/ exists, suggest init and show short help + if [[ ! -d "$selfmodel_dir" ]]; then + echo "selfmodel $SELFMODEL_VERSION" + echo "" + printf ' %bNo .selfmodel/ found in this project.%b\n' "$YELLOW" "$NC" + printf ' %b-> Next: selfmodel init%b\n' "$CYAN" "$NC" + echo "" + cmd_help_short + return 0 + fi + + # Run existing status display + cmd_status "$dir" + echo "" + + # Suggest next action based on project state + local suggestion="" + + # Check for DELIVERED contracts awaiting review + # Contract format: "## Status\nDELIVERED" — match standalone DELIVERED line + local delivered_count=0 + if [[ -d "$selfmodel_dir/contracts/active" ]]; then + delivered_count=$(grep -rl '^DELIVERED$' "$selfmodel_dir/contracts/active/"*.md 2>/dev/null \ + | wc -l | tr -d ' ') || delivered_count=0 + fi + if [[ "$delivered_count" -gt 0 ]]; then + suggestion="$delivered_count delivered Sprint(s) awaiting review. Run: /selfmodel:review" + fi + + # Check if plan.md exists + if [[ -z "$suggestion" && ! -f "$selfmodel_dir/state/plan.md" ]]; then + suggestion="No orchestration plan found. Run: /selfmodel:plan" + fi + + # Check evolution overdue + if [[ -z "$suggestion" && -f "$selfmodel_dir/state/team.json" ]]; then + local current_sprint last_review + current_sprint=$(jq -r '.current_sprint // 0' "$selfmodel_dir/state/team.json" 2>/dev/null) + last_review=$(jq -r '.evolution.last_review_sprint // 0' "$selfmodel_dir/state/team.json" 2>/dev/null) + local next_detect=$((last_review + 10)) + if [[ "$next_detect" -le "$current_sprint" ]]; then + suggestion="Evolution review overdue. Run: selfmodel evolve" + fi + fi + + # Default: all clear + if [[ -z "$suggestion" ]]; then + suggestion="All clear. Run /selfmodel:sprint for next task" + fi + + printf ' %b-> Next:%b %s\n' "$CYAN" "$NC" "$suggestion" + echo "" + cmd_help_short +} + +# ─── Help: short reference (8 lines, used by dashboard) ────────────────────── +cmd_help_short() { + printf '%b%-24s %-30s%b\n' "$BOLD" "Terminal" "Claude Code" "$NC" + echo "──────────────────────── ──────────────────────────────" + printf "%-24s %-30s\n" "selfmodel init" "/selfmodel:init" + printf "%-24s %-30s\n" "selfmodel status" "/selfmodel:status" + printf "%-24s %-30s\n" "selfmodel update" "/selfmodel:loop" + printf "%-24s %-30s\n" "selfmodel evolve" "/selfmodel:evolve" + printf "%-24s %-30s\n" "" "/selfmodel:plan" + printf "%-24s %-30s\n" "" "/selfmodel:sprint" + printf "%-24s %-30s\n" "" "/selfmodel:review" + printf "%-24s %-30s\n" "selfmodel --help" "Full reference" +} + +# ─── Help: full detailed reference (used by --help) ───────────────────────── +cmd_help_full() { + echo "selfmodel $SELFMODEL_VERSION — AI Agent Team Workflow" + echo "" + echo "Usage: selfmodel [command] [directory]" + echo "" + echo "Commands:" + echo " init Initialize selfmodel (idempotent — safe to re-run on existing projects)" + echo " update Update playbook files to latest version" + echo " --remote Fetch latest from GitHub (instead of local templates)" + echo " --version Specify version/tag (default: main)" + echo " status Show team health dashboard" + echo " evolve Evolution pipeline (interactive by default)" + echo " --detect Scan diffs against upstream baseline" + echo " --status Show pipeline status, timestamps, PR URLs" + echo " --stage Classify CANDIDATE entries (Stage/Reject/Keep)" + echo " --submit Submit staged patches as upstream PR" + echo " --track Monitor submitted PR statuses" + echo "" + echo "Flags:" + echo " -v, --version Show version" + echo " -h, --help Show this help message" + echo "" + echo "Aliases (backward compat):" + echo " adapt -> init (deprecated, prints warning)" + echo " dashboard -> (no args)" + echo "" + echo "Claude Code Slash Commands:" + echo " /selfmodel:init Initialize selfmodel" + echo " /selfmodel:plan Create or update orchestration plan" + echo " /selfmodel:sprint Create Sprint contract and dispatch agent" + echo " /selfmodel:review Review a delivered Sprint" + echo " /selfmodel:loop Auto-orchestration loop" + echo " /selfmodel:status View team status and quality trends" + echo "" + echo "Examples:" + echo " selfmodel # Smart dashboard (default)" + echo " selfmodel init # Initialize in current directory" + echo " selfmodel init ./my-project # Initialize in specific directory" + echo " selfmodel update # Update playbook from local templates" + echo " selfmodel update --remote # Fetch latest from GitHub" + echo " selfmodel update --remote --version v0.3.0 # Fetch specific version" + echo " selfmodel evolve # Interactive evolution pipeline" + echo " selfmodel evolve --detect # Detection scan only" + echo " selfmodel evolve --status # View evolution pipeline status" +} + # ─── Main ───────────────────────────────────────────────────────────────────── main() { - local cmd="${1:-help}" + local cmd="${1:-dashboard}" shift || true case "$cmd" in - init) check_deps; cmd_init "$@" ;; - adapt) check_deps; cmd_adapt "$@" ;; - update) check_deps; cmd_update "$@" ;; - status) check_deps; cmd_status "$@" ;; - evolve) check_deps; cmd_evolve "$@" ;; - version) cmd_version "$@" ;; - -v) cmd_version "$@" ;; - --version) cmd_version "$@" ;; - help|--help|-h) - echo "selfmodel $SELFMODEL_VERSION — AI Agent Team Workflow" - echo "" - echo "Usage: selfmodel [directory]" - echo "" - echo "Commands:" - echo " init Initialize selfmodel in a new or existing project" - echo " adapt Adapt selfmodel to an existing project (non-destructive)" - echo " update Update playbook files to latest version" - echo " --remote Fetch latest from GitHub (instead of local templates)" - echo " --version Specify version/tag (default: main)" - echo " status Show team health dashboard" - echo " evolve Evolution pipeline: detect improvements, classify, submit upstream" - echo " --detect Scan diffs against upstream baseline (default)" - echo " --status Show pipeline status, timestamps, PR URLs" - echo " --stage Interactively classify CANDIDATE entries" - echo " --submit Submit staged patches as upstream PR" - echo " --track Monitor submitted PR statuses" - echo " version Show version" - echo "" - echo "Examples:" - echo " selfmodel init # Initialize in current directory" - echo " selfmodel init ./my-project # Initialize in specific directory" - echo " selfmodel adapt # Adapt to existing project" - echo " selfmodel update # Update playbook from local templates" - echo " selfmodel update --remote # Fetch latest from GitHub (main branch)" - echo " selfmodel update --remote --version v0.3.0 # Fetch specific version" - echo " selfmodel evolve # Detect evolution candidates" - echo " selfmodel evolve --status # View evolution pipeline status" - ;; + dashboard) check_deps; cmd_dashboard "$@" ;; + init|setup) check_deps; cmd_init "$@" ;; + adapt) check_deps; cmd_adapt "$@" ;; + update|sync) check_deps; cmd_update "$@" ;; + status) check_deps; cmd_status "$@" ;; + evolve) check_deps; cmd_evolve "$@" ;; + version|-v|--version) cmd_version "$@" ;; + help|--help|-h) cmd_help_full ;; *) err "Unknown command: $cmd" err "Run 'selfmodel --help' for usage." From 01d42bc8ad9847f8f40cfe58df0c7d1e7321199b Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:52:10 -0700 Subject: [PATCH 17/22] sprint-CLI2: rewrite README quick start --- README.md | 85 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index c48bb2c..3db7354 100644 --- a/README.md +++ b/README.md @@ -27,56 +27,62 @@ selfmodel is not a framework. It's a **living system** where AI agents design, i ## Quick Start -### Install +### 1. Install ```bash git clone https://github.com/VictorVVedtion/selfmodel.git cd selfmodel && bash install.sh ``` -This installs: -- **Claude Code skill** → `~/.claude/skills/selfmodel/` (6 slash commands) -- **CLI tool** → `/usr/local/bin/selfmodel` (may prompt for sudo) +### 2. Setup -Then in Claude Code: +```bash +cd your-project +selfmodel init +``` + +### 3. Build + +In Claude Code: ``` -/selfmodel:init # Initialize selfmodel in your project -/selfmodel:plan # Create a multi-phase orchestration plan -/selfmodel:sprint # Create and dispatch a Sprint -/selfmodel:review # Review a delivered Sprint -/selfmodel:loop # Auto-orchestration: plan → dispatch → review → merge → repeat -/selfmodel:status # View team status and quality trends +/selfmodel:loop ``` -Or from any terminal: +## Commands -```bash -selfmodel init # Initialize in current project -selfmodel adapt # Adapt to existing project (non-destructive) -selfmodel status # Show team health dashboard -selfmodel version # Show version -selfmodel --help # Show all subcommands -``` +### Terminal (Setup & Maintenance) -### Update +| Command | Description | +|---------|-------------| +| `selfmodel` | Smart dashboard — status + next action | +| `selfmodel init [dir]` | Setup or update project (idempotent) | +| `selfmodel update [--remote]` | Sync playbook from upstream | +| `selfmodel evolve` | Contribute improvements upstream | +| `selfmodel --help` | Full command reference | -```bash -# Update an existing project to latest version (hot-update, no restart needed) -selfmodel update --remote +### Claude Code (Team Orchestration) -# Update to a specific version -selfmodel update --remote --version v0.3.0 +| Command | Description | +|---------|-------------| +| `/selfmodel:plan` | Create multi-phase project plan | +| `/selfmodel:sprint` | Create and dispatch a Sprint | +| `/selfmodel:review` | Review a delivered Sprint | +| `/selfmodel:loop` | Auto-orchestration (plan → dispatch → review → merge) | -# If selfmodel CLI is not in PATH, use the script directly: -bash /path/to/selfmodel/scripts/selfmodel.sh update --remote -``` +> **Tip**: Use `selfmodel` in terminal for status. Use `/selfmodel:loop` in Claude Code for orchestration. -Remote update syncs: hooks, playbook, scripts, VERSION, dispatch config. Does NOT overwrite project state (team.json, contracts, plan). +## Update -To update the Claude Code skill definitions (slash commands), re-run `bash install.sh` and start a new session. +```bash +selfmodel update --remote +``` -### Requirements +Use `selfmodel update --remote --version v0.3.0` to pin a specific release. +Re-run `bash install.sh` to refresh the Claude Code slash commands. +If `selfmodel` is not in PATH, use `bash /path/to/selfmodel/scripts/selfmodel.sh update --remote`. + +## Requirements - `jq` (`brew install jq` on macOS, `apt install jq` on Linux) - Claude Code CLI installed (`~/.claude/` exists) @@ -417,15 +423,18 @@ Every deliverable scored on 5 dimensions (see `playbook/quality-gates.md`): ### selfmodel CLI ``` -selfmodel init [directory] Create new selfmodel project -selfmodel adapt [directory] Adapt to existing project (non-destructive) -selfmodel update [--remote] [--version v0.3.0] Update playbook + hooks to latest version -selfmodel status Show team health dashboard -selfmodel version Show version -selfmodel --help Show help +selfmodel Smart dashboard (default) +selfmodel init [directory] Setup or update project +selfmodel update [--remote] [--version v0.3.0] Sync playbook + hooks to latest version +selfmodel status Show team health dashboard +selfmodel evolve Run the evolution pipeline +selfmodel --help Show full command reference +selfmodel --version Show version ``` -All subcommands support `--help` for detailed usage. +Deprecated alias: `selfmodel adapt [directory]` prints a warning and delegates to `selfmodel init`. + +All commands support `--help` for detailed usage where applicable. If `selfmodel` is not in PATH, use `bash /path/to/selfmodel/scripts/selfmodel.sh` instead. From 0809bec271a46ab74428c00121fcf754d67ced80 Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:52:13 -0700 Subject: [PATCH 18/22] sprint-CLI2: align install and command docs --- commands/init.md | 2 +- commands/status.md | 2 +- install.sh | 10 ++++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/commands/init.md b/commands/init.md index 604f5b9..bb34725 100644 --- a/commands/init.md +++ b/commands/init.md @@ -1,5 +1,5 @@ --- -description: "Initialize selfmodel multi-AI orchestration framework in the current project" +description: "Initialize selfmodel in current project (prefer CLI: selfmodel init)" allowed-tools: ["Read", "Write", "Edit", "Bash", "Glob"] argument-hint: "[--force] to reinitialize existing project" --- diff --git a/commands/status.md b/commands/status.md index 0edb7ae..65b6ad7 100644 --- a/commands/status.md +++ b/commands/status.md @@ -1,5 +1,5 @@ --- -description: "View selfmodel team status, active sprints, and quality trends" +description: "View selfmodel team status (prefer CLI: selfmodel)" allowed-tools: ["Read", "Bash", "Glob"] --- diff --git a/install.sh b/install.sh index 5e124b4..e73d9b9 100755 --- a/install.sh +++ b/install.sh @@ -71,9 +71,11 @@ fi echo "" echo "Done! ${SKILL_COUNT} skill files + ${CMD_COUNT} commands installed." echo "" -echo "Commands: /selfmodel:init /selfmodel:sprint /selfmodel:review" -echo " /selfmodel:status /selfmodel:plan /selfmodel:loop" +echo "Quick start:" +echo " cd your-project && selfmodel init" echo "" -echo "CLI: selfmodel init | update --remote | version | status" +echo "Terminal: selfmodel (dashboard)" +echo " selfmodel init (setup)" +echo " selfmodel update (sync)" echo "" -echo "Quick start: cd && run /selfmodel:init in Claude Code" +echo "Claude Code: /selfmodel:loop (orchestrate)" From 3b7e4bd9fcffa1a89a9374613f4994d8b964b229 Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:52:15 -0700 Subject: [PATCH 19/22] sprint-CLI2: mark primary and convenience commands --- skill/SKILL.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/skill/SKILL.md b/skill/SKILL.md index 7d4e5fb..12036df 100644 --- a/skill/SKILL.md +++ b/skill/SKILL.md @@ -16,15 +16,15 @@ specialized agents via Sprint contracts, worktree isolation, and independent qua ## Sub-Commands -| Command | Purpose | -|---------|---------| -| `/selfmodel:init` | Initialize selfmodel in any project | -| `/selfmodel:sprint` | Create contract + dispatch agent | -| `/selfmodel:review` | Evaluate + E2E verify + merge/reject | -| `/selfmodel:status` | View team, sprints, and quality trends | -| `/selfmodel:plan` | Create/update multi-phase orchestration plan | -| `/selfmodel:loop` | Auto-orchestration loop (plan-driven) | -| `/selfmodel:evolve` | Evolution-to-PR pipeline for upstream improvements | +| Command | Type | Purpose | +|---------|------|---------| +| `/selfmodel:plan` | Primary | Create/update multi-phase orchestration plan | +| `/selfmodel:sprint` | Primary | Create contract + dispatch agent | +| `/selfmodel:review` | Primary | Evaluate + E2E verify + merge/reject | +| `/selfmodel:loop` | Primary | Auto-orchestration loop (plan-driven) | +| `/selfmodel:init` | Convenience (CLI preferred) | Initialize selfmodel in any project | +| `/selfmodel:status` | Convenience (CLI preferred) | View team, sprints, and quality trends | +| `/selfmodel:evolve` | Convenience (CLI preferred) | Evolution-to-PR pipeline for upstream improvements | ## Core Architecture From 703ca7483887c4283bafb3572ae3bf595f4f1f96 Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 20:06:47 -0700 Subject: [PATCH 20/22] =?UTF-8?q?fix:=20bash=203.2=20compat=20=E2=80=94=20?= =?UTF-8?q?replace=20unset=20array[-1]=20with=20=5Fwiki=5Ffind=5Fcode=20he?= =?UTF-8?q?lper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit macOS ships bash 3.2 which doesn't support negative array indices. The unset 'find_args[-1]' pattern crashed wiki module scanning. Co-Authored-By: Claude Opus 4.6 (1M context) --- scripts/selfmodel.sh | 48 +++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/scripts/selfmodel.sh b/scripts/selfmodel.sh index 3ef32a8..7d76e22 100755 --- a/scripts/selfmodel.sh +++ b/scripts/selfmodel.sh @@ -911,6 +911,28 @@ cmd_status() { # Code file extensions used to detect whether a directory contains code WIKI_CODE_EXTENSIONS='*.py *.js *.ts *.tsx *.jsx *.go *.rs *.rb *.java *.kt *.swift *.c *.cpp *.h *.cs *.php *.sh *.lua *.ex *.exs *.zig *.nim *.ml *.hs *.scala *.clj' +# Find code files in a directory (bash 3.2 compatible — no negative array indices) +_wiki_find_code() { + local search_dir="$1" + local depth="${2:-2}" + local first_only="${3:-}" + local args="" + local first=true + for ext in $WIKI_CODE_EXTENSIONS; do + if $first; then + args="-name $ext" + first=false + else + args="$args -o -name $ext" + fi + done + if [[ -n "$first_only" ]]; then + eval "find \"$search_dir\" -maxdepth $depth -type f \\( $args \\) 2>/dev/null | head -1" + else + eval "find \"$search_dir\" -maxdepth $depth -type f \\( $args \\) 2>/dev/null | head -10" + fi +} + # Directories excluded from module scanning WIKI_EXCLUDE_PATTERN='^(\.|node_modules|__pycache__|\.venv|venv|vendor|dist|build|\.selfmodel|\.claude|\.github|\.vscode|\.idea|\.next|\.nuxt|coverage|tmp|temp|\.cache|\.turbo|target|out|bin|obj)$' @@ -924,19 +946,11 @@ generate_module_page() { # Collect up to 10 key files in this module (by extension) local key_files=() - local find_args=() - for ext in $WIKI_CODE_EXTENSIONS; do - find_args+=(-name "$ext" -o) - done - # Remove trailing -o - unset 'find_args[-1]' - while IFS= read -r f; do [[ -z "$f" ]] && continue - # Make path relative to project root local rel="${f#"$project_dir"/}" key_files+=("$rel") - done < <(find "$project_dir/$module_name" -maxdepth 3 -type f \( "${find_args[@]}" \) 2>/dev/null | head -10) + done < <(_wiki_find_code "$project_dir/$module_name" 3) cat > "$module_file" << MODEOF # ${module_name} @@ -1054,14 +1068,8 @@ SCHEMAEOF fi # Check if directory contains code files (up to depth 2) - local find_args=() - for ext in $WIKI_CODE_EXTENSIONS; do - find_args+=(-name "$ext" -o) - done - unset 'find_args[-1]' - local has_code - has_code=$(find "$entry" -maxdepth 2 -type f \( "${find_args[@]}" \) 2>/dev/null | head -1) + has_code=$(_wiki_find_code "$entry" 2 first) [[ -z "$has_code" ]] && continue # Enforce max 20 modules @@ -1199,14 +1207,8 @@ reconcile_wiki() { continue fi - local find_args=() - for ext in $WIKI_CODE_EXTENSIONS; do - find_args+=(-name "$ext" -o) - done - unset 'find_args[-1]' - local has_code - has_code=$(find "$entry" -maxdepth 2 -type f \( "${find_args[@]}" \) 2>/dev/null | head -1) + has_code=$(_wiki_find_code "$entry" 2 first) [[ -z "$has_code" ]] && continue if [[ $total_scanned -ge 20 ]]; then From 87323aa9117e1074a6f14e80d599d7b87a2756ab Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 20:07:41 -0700 Subject: [PATCH 21/22] =?UTF-8?q?feat:=20v0.4.0=20=E2=80=94=20wiki,=20evol?= =?UTF-8?q?ution=20pipeline,=20CLI=20consolidation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 (1M context) --- CHANGELOG.md | 32 ++++++++++++++++++++++++++++++++ README.md | 2 +- VERSION | 2 +- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b7d445..fc8bed3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,38 @@ All notable changes to this project will be documented in this file. +## [0.4.0] - 2026-04-07 + +### Added +- **Project Wiki** — auto-generated knowledge base at `.selfmodel/wiki/`, woven into existing flows: + - `selfmodel init` scaffolds wiki with detected module pages and architecture overview + - Session-start hook injects wiki/index.md into Leader context + - Sprint contracts gain `## Wiki Impact` section for agent wiki updates + - Post-merge Step 7.6 detects stale wiki pages from code diffs + - `selfmodel status` reports wiki health score (pages, staleness, completeness) + - Inspired by [Karpathy's LLM Wiki pattern](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f) +- **Evolution-to-PR Pipeline** (`selfmodel evolve`) — detect local improvements, classify generalizability, submit upstream PRs: + - 5 generalizability heuristics (path detection, project name, generic pattern, hook fix, scoring calibration) + - 4-phase pipeline: DETECT → STAGE → SUBMIT → TRACK + - Orchestration loop Step 8.5 auto-triggers detection every 10 merged sprints + - Human approval gate before any PR submission +- **Wiki Protocol** (`wiki-protocol.md`) — page format, update rules, lint rules, auto-sync spec +- **Evolution Protocol** (`evolution-protocol.md`) — full pipeline spec with schema, heuristics, PR template + +### Changed +- **CLI consolidated** — smart dashboard as default (`selfmodel` with no args), idempotent init (absorbs adapt), interactive evolve default, two-tier help +- **`selfmodel init`** is now idempotent — safe to re-run on existing projects (runs adapt logic) +- **`selfmodel adapt`** deprecated — prints warning, delegates to `selfmodel init` +- **`selfmodel evolve`** (no flags) runs full interactive pipeline (detect → stage → offer submit), was detect-only +- **`selfmodel`** (no args) shows smart dashboard with next-action suggestion, was help text +- **Help text** split into two tiers: dashboard shows 8-line reference, `--help` shows full detail +- **README** restructured: 3-step quickstart, Terminal vs Claude Code command tables +- Slash commands `/selfmodel:init`, `/selfmodel:status`, `/selfmodel:evolve` marked as convenience (CLI preferred) + +### Fixed +- **bash 3.2 compatibility** — replaced `unset 'array[-1]'` (requires bash 4.3+) with portable `_wiki_find_code()` helper for macOS default bash +- **`cmd_evolve` exit vs return** inconsistency — `exit 1` changed to `return 1` + ## [0.3.0] - 2026-04-05 ### Added diff --git a/README.md b/README.md index 3db7354..676e05b 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@

MIT License - Version 0.3.0 + Version 0.4.0 7-Role Agent Team Git Worktree Isolation Claude Code diff --git a/VERSION b/VERSION index 0d91a54..1d0ba9e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.0 +0.4.0 From a026302e047888bc9089cedf94e5943aa0b3861f Mon Sep 17 00:00:00 2001 From: VictorVVedtion <135472723+VictorVVedtion@users.noreply.github.com> Date: Mon, 6 Apr 2026 20:16:36 -0700 Subject: [PATCH 22/22] fix: install.sh auto-fallback to ~/.local/bin when sudo unavailable Previously install silently skipped CLI when sudo failed, leaving selfmodel not in PATH. Now auto-installs to ~/.local/bin and adds it to shell profile (.zshrc/.bashrc). Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 2 ++ install.sh | 53 ++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 676e05b..986acbd 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,8 @@ git clone https://github.com/VictorVVedtion/selfmodel.git cd selfmodel && bash install.sh ``` +If `selfmodel` isn't found after install, open a new terminal or run `source ~/.zshrc`. + ### 2. Setup ```bash diff --git a/install.sh b/install.sh index e73d9b9..9daf218 100755 --- a/install.sh +++ b/install.sh @@ -50,21 +50,52 @@ SKILL_COUNT=$(find "${SKILL_DIR}" -type f | wc -l | tr -d ' ') CMD_COUNT=$(find "${CMD_DIR}" -type f | wc -l | tr -d ' ') # Install CLI to PATH +# Strategy: try /usr/local/bin first, fallback to ~/.local/bin (no sudo needed) CLI_SRC="${SRC_DIR}/scripts/selfmodel.sh" -CLI_TARGET="/usr/local/bin/selfmodel" +CLI_INSTALLED=false if [[ -f "${CLI_SRC}" ]]; then chmod +x "${CLI_SRC}" + + # Try 1: /usr/local/bin (system-wide, may need sudo) if [[ -w "/usr/local/bin" ]]; then - ln -sf "${CLI_SRC}" "${CLI_TARGET}" - echo "CLI: selfmodel → ${CLI_TARGET}" - elif command -v sudo &>/dev/null; then - echo "Installing CLI to /usr/local/bin (may need password)..." - sudo ln -sf "${CLI_SRC}" "${CLI_TARGET}" 2>/dev/null && \ - echo "CLI: selfmodel → ${CLI_TARGET}" || \ - echo "Skipped CLI install (no sudo). Run manually: sudo ln -sf ${CLI_SRC} ${CLI_TARGET}" - else - echo "Skipped CLI install. Add to PATH manually:" - echo " ln -sf ${CLI_SRC} /usr/local/bin/selfmodel" + ln -sf "${CLI_SRC}" "/usr/local/bin/selfmodel" + echo "CLI: selfmodel → /usr/local/bin/selfmodel" + CLI_INSTALLED=true + elif command -v sudo &>/dev/null && sudo -n true 2>/dev/null; then + # sudo available without password prompt (e.g. NOPASSWD configured) + sudo ln -sf "${CLI_SRC}" "/usr/local/bin/selfmodel" + echo "CLI: selfmodel → /usr/local/bin/selfmodel" + CLI_INSTALLED=true + fi + + # Try 2: ~/.local/bin (user-local, no sudo needed) + if [[ "$CLI_INSTALLED" == "false" ]]; then + LOCAL_BIN="${HOME}/.local/bin" + mkdir -p "${LOCAL_BIN}" + ln -sf "${CLI_SRC}" "${LOCAL_BIN}/selfmodel" + echo "CLI: selfmodel → ${LOCAL_BIN}/selfmodel" + CLI_INSTALLED=true + + # Ensure ~/.local/bin is in PATH + if ! echo "$PATH" | tr ':' '\n' | grep -q "^${LOCAL_BIN}$"; then + # Detect shell and add to appropriate rc file + SHELL_RC="" + if [[ -n "${ZSH_VERSION:-}" ]] || [[ "$(basename "${SHELL:-}")" == "zsh" ]]; then + SHELL_RC="${HOME}/.zshrc" + elif [[ -n "${BASH_VERSION:-}" ]] || [[ "$(basename "${SHELL:-}")" == "bash" ]]; then + SHELL_RC="${HOME}/.bashrc" + fi + + if [[ -n "$SHELL_RC" ]]; then + if ! grep -q '\.local/bin' "$SHELL_RC" 2>/dev/null; then + echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$SHELL_RC" + echo " Added ~/.local/bin to PATH in $(basename "$SHELL_RC")" + echo " Run: source $SHELL_RC (or open a new terminal)" + fi + else + echo " Add to your shell profile: export PATH=\"\$HOME/.local/bin:\$PATH\"" + fi + fi fi fi