Files
AirCoding/AirPlan/docs/spec/AirPlan-ParaV2/lib/air_runtime/project_bootstrap.py
AirCoding ae44be31d5 chore: push all design docs, V2 plan specs, and current working state
Includes AirPlan design documents, AircOding-alpha1-plan, AirPlanV2,
AirPlan-ParaV2, AirPlan-Para V1 reference docs, and all working code
changes across packages.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-12 17:12:29 +08:00

343 lines
14 KiB
Python
Executable File

from __future__ import annotations
from pathlib import Path
from typing import Dict, Tuple
from .paths import (
agents_path,
airplan_root,
analysis_requirements_path,
architecture_adr_dir,
architecture_c4_module_path,
architecture_solution_path,
debug_log_path,
gui_debug_log_path,
root_agents_bootstrap_path,
state_root,
staticanalysis_path,
validation_root,
)
AIRARC_BEGIN = "<!-- AIRARC:BEGIN -->"
AIRARC_END = "<!-- AIRARC:END -->"
AIRENG_BEGIN = "<!-- AIRENG:BEGIN -->"
AIRENG_END = "<!-- AIRENG:END -->"
AIRDO_BEGIN = "<!-- AIRDO:BEGIN -->"
AIRDO_END = "<!-- AIRDO:END -->"
ROOT_AGENTS_TEMPLATE = """# AGENTS.md
- Canonical workflow context for this repository lives in `AirPlan/AGENTS.md`.
- Always load `AirPlan/AGENTS.md` first for project instructions, workflow rules, plan/todo state, ADR/C4 context, and current Air sync blocks.
- Treat `AirPlan/plan.md`, `AirPlan/todo.md`, and `AirPlan/docs/` as the authoritative workflow documents.
- Treat `AirPlan/state/` as the authoritative plugin and runtime state root.
- This root file is only a bootstrap shim; keep real workflow context maintained inside `AirPlan/AGENTS.md`.
"""
PROJECT_AGENTS_TEMPLATE = f"""# AGENTS.md
## Workflow Root
- This project uses `AirPlan/` as the workflow root.
- Keep planning, execution state, ADR, C4, validation, debug, and plugin runtime data under `AirPlan/`.
- The repo-root `AGENTS.md` only bootstraps into this file.
{AIRARC_BEGIN}
## AirArc Workflow
1. Use `AirPlan/AGENTS.md` as the canonical project context entry point.
2. Load and maintain:
- `AirPlan/docs/analysis/requirements.md`
- `AirPlan/docs/architecture/solution-architecture.md`
- `AirPlan/docs/architecture/c4/module.md`
- `AirPlan/docs/architecture/adr/`
3. Produce or refine `AirPlan/plan.md` and `AirPlan/todo.md`.
4. Keep plans optimized for lower-cost follow-up sessions, including scope, validation, file targets, and parallelization boundaries.
5. AirArc is architecture-only: it may plan tasks and edit planning or architecture documents, but it must not write code or implement tasks directly.
{AIRARC_END}
{AIRENG_BEGIN}
## AirEng Workflow
1. Use `/aireng` as the sole scheduler for confirmed execution.
2. Prefer `AirPlan/state/airarc/reviews/execution-plan.json`, then `AirPlan/state/airarc/reviews/parallel-review.json`, before falling back to local `AirPlan/todo.md`.
3. Dispatch isolated `/airdo` subagents with bounded concurrency instead of defaulting to parent-thread coding.
4. Monitor active workers on a 5-minute cadence, merge ready results, and continue later waves automatically when work remains.
5. Keep `AirPlan/todo.md`, `AirPlan/plan.md`, `AirPlan/AGENTS.md`, ADR, and C4 docs synchronized during dispatch, monitoring, repair, and merge.
6. AirEng owns global debug, XDB, repair, intervention, and document convergence, but it should only intervene directly for hard blockers and must return to scheduler mode immediately afterward.
{AIRENG_END}
{AIRDO_BEGIN}
## AirDo Workflow
1. Use `/airdo` for one narrow task slice from `AirPlan/todo.md`.
2. Before editing, load:
- `AirPlan/AGENTS.md`
- `AirPlan/docs/architecture/adr/`
- `AirPlan/docs/architecture/c4/module.md`
- `AirPlan/plan.md`
- `AirPlan/todo.md`
3. Keep task-local progress resumable in `AirPlan/state/airdo/`.
4. When AirEng owns orchestration, return shared document changes through `documentUpdates`.
5. Route GUI work through AirXDB, debugging through AirDbg, network evidence through AirNDB, and static analysis through AirSDB when needed.
{AIRDO_END}
"""
PLAN_TEMPLATE = """# Implementation Plan
## Read First
1. `AirPlan/AGENTS.md`
2. `AirPlan/docs/analysis/requirements.md`
3. `AirPlan/docs/architecture/solution-architecture.md`
4. `AirPlan/docs/architecture/c4/module.md`
5. `AirPlan/docs/architecture/adr/`
6. `AirPlan/todo.md`
## Goal
- Replace this section with the concrete product or project goal.
## Constraints
- Record technical, organizational, legal, hardware, or platform constraints here.
## Phases
- Add implementation phases once AirArc planning is complete.
## Validation Strategy
- Record build, test, debug, GUI, network, and static-analysis validation commands here.
"""
TODO_TEMPLATE = """# TODO
Status values: TODO / DOING / DONE / BLOCKED
| ID | Status | Module | Task | Files/Dirs | Done When | Validation | Static Analysis | ADR/C4 Update |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| T-001 | TODO | Planning | Replace with the first confirmed execution task | `AirPlan/plan.md`, `AirPlan/docs/` | Acceptance criteria are explicit and testable | Record the exact validation command | Record the static-analysis plan or why it is not applicable | Record required ADR or C4 updates |
## Quality Gates
- Run the validation command listed in `AirPlan/plan.md` before marking a task `DONE`.
- Keep ADR and C4 docs synchronized whenever architecture, module boundaries, dependencies, or ownership change.
- Record skipped validation, residual risk, and follow-up work explicitly.
"""
REQUIREMENTS_TEMPLATE = """# Requirements
## Product Intent
- Replace with the user-visible outcome this repository should deliver.
## Functional Requirements
- Replace with numbered or grouped functional requirements.
## Constraints
- Replace with non-functional constraints, environmental limits, or safety rules.
## Acceptance Notes
- Replace with the most important acceptance criteria and evidence rules.
"""
SOLUTION_ARCHITECTURE_TEMPLATE = """# Solution Architecture
## Overview
- Replace with the top-level architecture summary.
## Major Components
- Replace with the main containers and their responsibilities.
## Data And Control Flow
- Replace with the major interaction paths between components.
## Key Risks
- Replace with the architecture risks, unknowns, and open decisions.
"""
C4_MODULE_TEMPLATE = """# C4 Module
## System Context
- Replace with the project purpose and external actors or systems.
## Containers
- Replace with the main runtime or repository containers.
## Modules
| Module | Responsibility | Public Interfaces | Dependencies | Data Ownership | Quality Notes |
| --- | --- | --- | --- | --- | --- |
| `replace_me` | Replace with the first real module | Replace with interfaces | Replace with dependencies | Replace with owned data | Replace with testing or quality notes |
"""
ADR_TEMPLATE = """# ADR-0001: Use AirPlan As The Workflow Root
- Status: Accepted
- Date: YYYY-MM-DD
## Context
This project needs a durable workflow root for planning, execution state, architecture context, validation evidence, and resumable AI sessions.
## Decision
Store project workflow artifacts under `AirPlan/`, use the repo-root `AGENTS.md` only as a bootstrap shim, and let `aireng` plus `airdo` maintain plan, todo, ADR, and C4 context there.
## Consequences
- Planning and execution context stay resumable across sessions.
- Global workflow docs live in one predictable location.
- Plugin runtime state does not clutter the main project tree.
"""
DEBUG_LOG_TEMPLATE = """# Debug Log
- Add reproducible bug investigations, root-cause notes, and validation outcomes here.
"""
GUI_DEBUG_LOG_TEMPLATE = """# GUI Debug Log
- Add screenshots, GUI observations, Midscene evidence, and visual acceptance notes here.
"""
NETWORK_LOG_TEMPLATE = """# AirNDB Log
- Add packet-capture commands, pcap paths, network observations, and conclusions here.
"""
STATIC_ANALYSIS_TEMPLATE = """# Static Analysis
- Add cppcheck or other static-analysis summaries, report paths, and residual risks here.
"""
VALIDATION_README_TEMPLATE = """# Validation Artifacts
- Save build logs, flash logs, test logs, screenshots, and validation summaries under this directory.
"""
ARTIFACTS_README_TEMPLATE = """# Artifact Output
- Save generated evidence files in this directory.
"""
def _write_if_missing(path: Path, content: str) -> str:
if path.exists():
return "exists"
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(content.rstrip() + "\n", encoding="utf-8", newline="\n")
return "created"
def _upsert_marked_block(existing: str, begin: str, end: str, block: str) -> Tuple[str, bool]:
begin_index = existing.find(begin)
end_index = existing.find(end)
normalized_block = block.rstrip() + "\n"
if begin_index >= 0 and end_index > begin_index:
end_index += len(end)
updated = existing[:begin_index].rstrip() + "\n\n" + normalized_block + existing[end_index:].lstrip()
return updated, updated != existing
updated = existing.rstrip() + "\n\n" + normalized_block
return updated, True
def _ensure_project_agents(path: Path) -> str:
if not path.exists():
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(PROJECT_AGENTS_TEMPLATE.rstrip() + "\n", encoding="utf-8", newline="\n")
return "created"
original = path.read_text(encoding="utf-8-sig")
updated = original
changed = False
for begin, end, block in [
(
AIRARC_BEGIN,
AIRARC_END,
PROJECT_AGENTS_TEMPLATE[
PROJECT_AGENTS_TEMPLATE.index(AIRARC_BEGIN) : PROJECT_AGENTS_TEMPLATE.index(AIRARC_END) + len(AIRARC_END)
],
),
(
AIRENG_BEGIN,
AIRENG_END,
PROJECT_AGENTS_TEMPLATE[
PROJECT_AGENTS_TEMPLATE.index(AIRENG_BEGIN) : PROJECT_AGENTS_TEMPLATE.index(AIRENG_END) + len(AIRENG_END)
],
),
(
AIRDO_BEGIN,
AIRDO_END,
PROJECT_AGENTS_TEMPLATE[
PROJECT_AGENTS_TEMPLATE.index(AIRDO_BEGIN) : PROJECT_AGENTS_TEMPLATE.index(AIRDO_END) + len(AIRDO_END)
],
),
]:
updated, block_changed = _upsert_marked_block(updated, begin, end, block)
changed = changed or block_changed
if not changed:
return "exists"
path.write_text(updated.rstrip() + "\n", encoding="utf-8", newline="\n")
return "updated"
def ensure_project_bootstrap(project_root: Path) -> Dict[str, str]:
airplan_root(project_root).mkdir(parents=True, exist_ok=True)
architecture_adr_dir(project_root).mkdir(parents=True, exist_ok=True)
architecture_c4_module_path(project_root).parent.mkdir(parents=True, exist_ok=True)
analysis_requirements_path(project_root).parent.mkdir(parents=True, exist_ok=True)
debug_log_path(project_root).parent.mkdir(parents=True, exist_ok=True)
gui_debug_log_path(project_root).parent.mkdir(parents=True, exist_ok=True)
(debug_log_path(project_root).parent / "airxdb-artifacts").mkdir(parents=True, exist_ok=True)
(airplan_root(project_root) / "docs" / "network" / "airndb-captures").mkdir(parents=True, exist_ok=True)
(validation_root(project_root) / "logs").mkdir(parents=True, exist_ok=True)
state_root(project_root).mkdir(parents=True, exist_ok=True)
results = {
str(root_agents_bootstrap_path(project_root)): _write_if_missing(
root_agents_bootstrap_path(project_root), ROOT_AGENTS_TEMPLATE
),
str(agents_path(project_root)): _ensure_project_agents(agents_path(project_root)),
str(airplan_root(project_root) / "plan.md"): _write_if_missing(
airplan_root(project_root) / "plan.md", PLAN_TEMPLATE
),
str(airplan_root(project_root) / "todo.md"): _write_if_missing(
airplan_root(project_root) / "todo.md", TODO_TEMPLATE
),
str(analysis_requirements_path(project_root)): _write_if_missing(
analysis_requirements_path(project_root), REQUIREMENTS_TEMPLATE
),
str(architecture_solution_path(project_root)): _write_if_missing(
architecture_solution_path(project_root), SOLUTION_ARCHITECTURE_TEMPLATE
),
str(architecture_c4_module_path(project_root)): _write_if_missing(
architecture_c4_module_path(project_root), C4_MODULE_TEMPLATE
),
str(architecture_adr_dir(project_root) / "ADR-0001-use-airplan-as-the-workflow-root.md"): _write_if_missing(
architecture_adr_dir(project_root) / "ADR-0001-use-airplan-as-the-workflow-root.md",
ADR_TEMPLATE,
),
str(debug_log_path(project_root)): _write_if_missing(
debug_log_path(project_root), DEBUG_LOG_TEMPLATE
),
str(gui_debug_log_path(project_root)): _write_if_missing(
gui_debug_log_path(project_root), GUI_DEBUG_LOG_TEMPLATE
),
str(debug_log_path(project_root).parent / "airxdb-artifacts" / "README.md"): _write_if_missing(
debug_log_path(project_root).parent / "airxdb-artifacts" / "README.md",
ARTIFACTS_README_TEMPLATE,
),
str(airplan_root(project_root) / "docs" / "network" / "airndb-log.md"): _write_if_missing(
airplan_root(project_root) / "docs" / "network" / "airndb-log.md",
NETWORK_LOG_TEMPLATE,
),
str(airplan_root(project_root) / "docs" / "network" / "airndb-captures" / "README.md"): _write_if_missing(
airplan_root(project_root) / "docs" / "network" / "airndb-captures" / "README.md",
ARTIFACTS_README_TEMPLATE,
),
str(validation_root(project_root) / "README.md"): _write_if_missing(
validation_root(project_root) / "README.md", VALIDATION_README_TEMPLATE
),
str(validation_root(project_root) / "logs" / "README.md"): _write_if_missing(
validation_root(project_root) / "logs" / "README.md", ARTIFACTS_README_TEMPLATE
),
str(staticanalysis_path(project_root)): _write_if_missing(
staticanalysis_path(project_root), STATIC_ANALYSIS_TEMPLATE
),
}
return results