✅ fresh
last synced 2026-06-17T22:39:35.514075+00:00 · coverage 100% (
onboarding)Validation by Beadloom
doc_sync— same source assync-check.
Onboarding
Project bootstrap, documentation import, and architecture-aware initialization.
Features
Each feature has its own SPEC.md:
- Agent Prime — compact project context for AI sessions (
beadloom prime). - Doc Generator — doc skeletons + polish data from the graph (
beadloom docs generate/polish). - Config Check — AgentConfigAsCode drift detection (
beadloom config-check). - Branch Protection — strict trunk-based
mainprotection (beadloom setup-branch-protection). - Agentic Flow Setup — scaffold the multi-agent dev flow 1:1 (
beadloom setup-agentic-flow). - AI Tech-Writer Setup — scaffold the packaged AI tech-writer harness (
beadloom setup-ai-techwriter). - Flow Config —
.beadloom/flow.ymlschema + loader (FlowConfig) — declares tools/architecture/stack/quality for the role configurator. - Role Composer — deterministic role assembly from CORE + architecture + stack overlays (
compose_role). - Role Adapters — per-tool role adapter sets (
.claude/agents/*,.cursor/agents/*) from composed roles (generate_adapters).
Specification
Modules
- scanner/ — package (decomposed by cohesion in BDL-059 S4 into one module per responsibility —
constants,project_scan,summary,entry_points,import_scan,readme,doc_classify,rules_gen,agents_md,prime,claude_md,bootstrap,init_flow,types; the package__init__re-exports the full public surface, sobeadloom.onboarding.scannerimport paths are unchanged).bootstrap_project()scans source directories, classifies subdirectories using preset rules, infers edges from directory nesting, generates.beadloom/_graph/services.yml+.beadloom/config.yml. Also detects project name, generates architecture rules, configures MCP for the detected editor, and creates IDE adapter files viasetup_rules_auto(). Providesimport_docs()for classifying existing .md files (ADR, feature, architecture, other).generate_rules()creates structural rules with emptyhas_edge_to: {}matcher for hierarchy validation._detect_framework_summary()detects 20+ framework patterns (Django, Flask, FastAPI, NestJS, Angular, Next.js, Expo, React Native, Spring Boot, Actix, Gin, Vue, SwiftUI, Jetpack Compose, UIKit, Express, etc.)._build_contextual_summary()combines framework detection, tree-sitter symbol counts, README excerpts, and entry-point labels into a 120-char summary._sanitize_ref_id()strips parentheses from Expo router dirs.generate_agents_md()creates.beadloom/AGENTS.mdwith the MCP tool list (built from the canonicalMCP_TOOL_CATALOG, currently 18 tools) and architecture rules; preserves user content between<!-- beadloom:custom-start -->/<!-- beadloom:custom-end -->HTML comment markers (migrates old## Customformat automatically). It delegates tobuild_agents_md_content()— a pure in-memory builder (extracting the preserved custom block via_extract_agents_custom_content()) — so the AgentConfigAsCode drift checker (config_sync.py) can re-run the exact same generation logic without writing to disk._detect_rule_type()maps all 7 YAML keys (require,deny,forbid_cycles,layers,check,forbid_import,forbid) to canonical type strings._build_rules_section()uses_detect_rule_type()to produce accurate rule type labels for all 9 rules.prime_context()returns compact project context (static config + dynamic DB queries) for AI agent sessions._discover_entry_points()detects CLI, script, server, and app entry points across 8 languages (Python Click/Typer/argparse, Go, Rust, Java, Kotlin, Swift, JS/TS)._quick_import_scan()infersdepends_onedges between clusters by sampling code imports via tree-sitter.interactive_init()runs the interactive initialization wizard with re-init detection, mode selection, and auto-reindex.non_interactive_init()runs initialization without prompts for CI/script use, supportingmode(bootstrap/import/both),force(delete existing .beadloom/), and automatic doc linking + skeleton generation + reindex.auto_link_docs()fuzzy-matches existingdocs/markdown files to graph nodes by ref_id similarity (exact path, stem match, partial match) and patches thedocs:field inservices.yml._ingest_readme()extracts project metadata (description, tech stack, architecture notes) from README/CONTRIBUTING/ARCHITECTURE files.refresh_claude_md()refreshes auto-managed sections in.claude/CLAUDE.mdbetween<!-- beadloom:auto-start SECTION -->/<!-- beadloom:auto-end -->marker pairs by regenerating dynamic content (project info facts) while preserving everything outside markers. Supportsdry_runmode for preview._parse_markers()extracts marker pairs from text._auto_insert_markers()inserts markers around section 0.1 on first refresh if no markers exist._render_project_info_section()generates the dynamic project-info content (stack, distribution, tests, linter, type checking, docs, architecture, version). - scanner/types.py — TypedDicts that sharpen the static types for scanner results (BDL-059 S5).
ScanResult(keys:manifests,source_dirs,file_count,languages) is the return type ofscan_project();ClusterEntry(keys:files,children,source_dir) is the value type returned by_cluster_with_children()and consumed by_quick_import_scan(). Same runtime shape as the priordict[str, Any]; the TypedDicts only improve static analysis for callers. - presets.py — Architecture presets (
monolith,microservices,monorepo) with directory classification rules and edge inference logic.Presetdataclass definesname,description,dir_rules,default_kind,infer_part_of,infer_deps_from_manifests.PresetRuledataclass maps directory name patterns to node kinds with confidence levels.detect_preset()checks for mobile app indicators (React Native/Expo viapackage.json, Flutter viapubspec.yaml) before falling back to directory heuristics. - doc_generator.py —
generate_skeletons()creates docs/ tree from graph nodes (architecture.md, domain READMEs, service pages, feature SPECs with_doc_path_for_node()resolution), writesdocs:field back toservices.ymlvia_patch_docs_field(), and generates.beadloom/README.mdquick-start.generate_polish_data()returns structured JSON for AI-driven doc enrichment with SQLite dependency edges via_enrich_edges_from_sqlite(), symbol change detection (_detect_symbol_changes()/_detect_symbol_changes_with_conn()), and routes/activity/tests fromnodes.extravia_load_extra_from_sqlite().format_polish_text()renders multi-line human-readable polish output including symbol drift warnings, routes, activity level, and test metadata. SQLite operations in_load_symbols_by_source()and_load_extra_from_sqlite()catchsqlite3.OperationalErrorand log at debug level (non-fatal degradation when tables are missing). - config_reader.py —
read_deep_config()extracts scripts, workspaces, path aliases, and build metadata from project configuration files. Parsespyproject.toml([project.scripts], [tool.pytest], [tool.ruff], [build-system]),package.json(scripts, workspaces, engines),tsconfig.json(compilerOptions.paths, baseUrl),Cargo.toml([workspace] members, [features]), andbuild.gradle/build.gradle.kts(plugins, dependencies via regex). Merges results from multiple config sources with deduplication for scripts and workspaces. - ai_techwriter_setup.py — Backs
beadloom setup-ai-techwriter --platform {github,gitlab}(BDL-047 / F4.1, G8; BDL-051 / S2). Since the harness now ships INSIDE the installedbeadloompackage (beadloom.ai_agents.ai_techwriter), the scaffold no longer vendors any Python (the BDL-047/048HARNESS_MODULES/vendor_harness/sync_vendored_harnessdrift-guard machinery is retired).scaffold(target_root, platform=...)idempotently drops: the chosen platform's CI wrapper (_scaffold_github()/_scaffold_gitlab()— GitLab appends job-only to an existing.gitlab-ci.yml, never blindly clobbering, and skips an already-wired file) which invokespython -m beadloom.ai_agents.ai_techwriter; the operator artifactstools/ai_techwriter/{recipe.yaml, provision-runner.sh}(_scaffold_recipe()/_scaffold_provision_runner()) copied from the harness package data viaimportlib.resources— the recipe a readable reference of the agent's blast radius, the provisioner a hardened, idempotent (0o755) runner-stand-up script (--platform/--repo/--token,set -euo pipefail, fail-hard RAM (~2 GB min, ~4 GB recommended) + disk (~5 GB) prechecks, swap guaranteed before apt, GitHub Actions runner or GitLab Runner registration, best-effort+verified Goose/beadloom/bd installs); and the ≤3-stepdocs/guides/ai-techwriter.md(_scaffold_guide()). RaisesValueErroron an unknown platform.templates_root()locates the packaged workflow/guide assets;_read_harness_data()reads the recipe/provisioner from the harness package. - agentic_flow_setup.py — Backs
beadloom setup-agentic-flow(BDL-048).scaffold(project_root, *, force=False)idempotently drops Beadloom's proven multi-agent dev flow into a target repo: the role subagents (AGENT_FILES→.claude/agents/{dev,test,review,tech-writer}.md) + slash skills (COMMAND_FILES→.claude/commands/{coordinator,task-init,checkpoint,templates}.md) are vendored byte-identical from the package-data assets (onboarding/templates/agentic_flow/, inert.md.txtcopies of the live.claude/), and.claude/CLAUDE.mdis dropped (only when absent, or withforce) then itsproject-infoauto-region is regenerated for the TARGET project viarefresh_claude_md._scaffold_vendored()is idempotent — a matching file is left alone, a hand-edited file is skipped (unlessforce) so user edits are not clobbered; returnsScaffoldResult(files written/skipped + the CLAUDE.md path + changed sections). The vendored CLAUDE.md carries a neutral__BEADLOOM_PROJECT_NAME__token in its## 0.1 Project:heading, substituted with the detected project name on scaffold (_claude_md_base()).sync_agentic_flow(live_claude_root)is the drift guard (principle: preserve the flow 1:1): it refreshes the packaged.md.txtassets from the live.claude/(and snapshotsCLAUDE.mdwith the project name tokenized), asserted byte-for-byte in the test suite.templates_root()/vendored_flow_root()locate the packaged assets. - branch_protection.py — Backs
beadloom setup-branch-protection(BDL-049, contexts updated in BDL-050). An idempotentmain-branch-protection helper for the trunk-based flow (CLAUDE.md §6): every change integrates via a PR (no direct push) and the consolidatedci.ymlchecks are required status checks, so the pipeline becomes true enforcement (hardening BDL-048 G5).build_protection_payload(*, status_check_contexts=DEFAULT_STATUS_CHECK_CONTEXTS)builds the GitHub request body —required_status_checks {strict: true, contexts},enforce_admins: true,required_pull_request_reviews {required_approving_review_count: 0},restrictions: null— so a PR IS required and even admins cannot direct-push (strict trunk-based), but the owner is NOT locked out (can self-merge once the pipeline is green, since 0 required reviews + the un-filteredci.ymlchecks).DEFAULT_STATUS_CHECK_CONTEXTS = ("gate", "tests (3.10)", "tests (3.11)", "tests (3.12)", "tests (3.13)", "site-build", "ai-techwriter")are the real consolidatedci.ymlcheck-run names (BDL-050 — the job names + the un-filtered 3.10-3.13 matrix legs); a required context MUST match a real check-run name EXACTLY and must NOT be a path-filtered workflow's check (understrictit would never run → permanently-unmergeable PR/main), which is why BDL-050 dropped thetestspaths filter.BranchProtectionRequest(frozen dataclass: owner/repo/branch/status_check_contexts) exposesendpoint(),payload_json()(deterministicsort_keys), andgh_args()(thegh api --method PUT … --input -argv).apply_branch_protection(owner, repo, *, branch="main", status_check_contexts=..., runner=None)builds the declarativePUT .../protectionand runs it through an injectableGhRunnerseam (defaults to the realghCLI; tests pass a fake that records argv + stdin without touching GitHub).PUT .../protectionis declarative, so re-running re-settles the same state (idempotent). - config_sync.py — AgentConfigAsCode drift detection.
check_config_drift(project_root, conn)re-runs the SAMEsetup-rules --refreshgenerator in memory and diffs its output against on-disk content, returning aConfigDrift(file, reason)per drifted artifact (deterministically sorted by file). It reusesbuild_agents_md_content()(AGENTS.md),refresh_claude_md(dry_run=True)(CLAUDE.md auto-managed sections), and the_RULES_ADAPTER_TEMPLATE/_is_beadloom_adapter()adapter helpers — never a parallel reimplementation. Checks ONLY auto-managed regions: AGENTS.md diffing ignores the usercustomblock (_agents_auto_region()), CLAUDE.md diffing covers only theauto-start/auto-endmarker sections, so editing human prose can never trip it (avoids the #73 false-positive class). Absent target files are skipped (not drift). As of BDL-048,check_config_driftalso covers the scaffolded agentic-flow files: when the flow is fully scaffolded (_agentic_flow_scaffolded()),_agentic_flow_drifts()byte-compares each present vendoredagents/*+commands/*file against the shipped template.refresh_agentic_flow_files(project_root)is theconfig-check --fixcompanion — it re-drops the vendored flow files into a scaffolded repo (gated on the flow already being present, so it never forces the flow onto a repo that did not adopt it). Theconnparameter is accepted for signature symmetry with thebeadloom ciorchestrator. Backs thebeadloom config-check [--fix]command. As of BDL-052 S3 it also validates.beadloom/flow.yml(_flow_config_drift()) and checks each composed role adapter againstcompose_role(...)for the configured architecture+stack (_composed_adapter_drifts());refresh_composed_adapters()is the--fixcompanion that recomposes the per-tool adapter sets. When aflow.ymlis present the role files (.claude/agents/*) are composer-owned, so the vendored byte-compare is skipped foragents(it would false-positive on a non-python stack). - flow_config.py — The role-configurator config (BDL-052 S3). Backs
.beadloom/flow.yml(tools,architecture[one ofddd/fsd],stack[python/fastapi/javascript/typescript/vuejs],quality).FlowConfigis the validated frozen result;build_flow_config(data)validates a parsed mapping (unknown tool/architecture/stack →FlowConfigErrornaming the value + allowed set; architecture must be exactly one;tools/stackrequired + de-duped + sorted for deterministic composition);load_flow_config(project_root)reads + validates the file;load_flow_config_or_default()falls back to a default when absent (but still raises on a present-but-bad file);detect_stack()infers a default stack from source file extensions;resolve_flow_config(..., tools, architecture, stack)applies flag-over-flow.yml-over-default precedence for the setup command. - role_composer.py — Composes a role file from CORE + one architecture overlay + stack overlays (BDL-052 S3).
compose_role(role, *, architecture, stack)concatenates the CORE body (templates/roles/core/<role>.md.txt), the single architecture overlay (templates/roles/architecture/<arch>/<role>.md.txt), then each stack overlay in sorted order (templates/roles/stack/<stack>/<role>.md.txt) — deterministic for a given(role, architecture, stack); an unknown role/architecture/stack raisesFlowConfigError, a missing per-role overlay fragment contributes nothing.compose_all_roles(config)composes every role for aFlowConfig.ROLE_NAMESaredev/test/review/tech-writer. - role_adapters.py — Writes per-tool role adapters from composed roles (BDL-052 S3).
generate_adapters(config, project_root)composes each role once and writes every configured tool's set:claude→.claude/agents/<role>.md,cursor→.cursor/agents/<role>.md+ a.cursor/rules/beadloom-flow.mdorchestrator pointer. Idempotent (bytes depend only onconfig+ the overlay sources); the single writer the drift-guard verifies against.AdapterResultreports the paths written;TOOL_AGENT_DIRSmaps a tool to its agent dir.
CLI Commands
beadloom init --bootstrap [--preset {monolith,microservices,monorepo}]
beadloom init --import DOCS_DIR
beadloom init # interactive mode
beadloom init --yes [--mode {bootstrap,import,both}] [--force] # non-interactive mode
beadloom docs generate # create doc skeletons from graph
beadloom docs polish # structured data for AI enrichment (text or JSON)
beadloom docs audit # scan project docs for stale fact mentions (text or JSON)
beadloom prime # compact project context for AI agent injection
beadloom setup-rules # create IDE adapter files (.cursorrules, etc.)
beadloom setup-rules --refresh # refresh auto-managed CLAUDE.md sections
beadloom setup-rules --refresh --dry-run # preview changes without writing
beadloom setup-agentic-flow # scaffold the packaged multi-agent dev flow into .claude/
beadloom setup-agentic-flow --force # overwrite hand-edited scaffolded flow files
beadloom config-check # detect agent-config drift (exit 1 on drift)
beadloom config-check --fix # regenerate drifted artifacts (+ restore flow files), then re-check
beadloom setup-branch-protection --repo OWNER/NAME # protect main: PR required + consolidated ci.yml checks required (gate/tests (3.10..3.13)/site-build/ai-techwriter) (GitHub)
beadloom setup-branch-protection --repo OWNER/NAME --dry-run # print the gh api call + payload without touching GitHub
beadloom snapshot save [--label LABEL] # save current graph state
beadloom snapshot list [--json] # list all saved snapshots
beadloom snapshot compare OLD_ID NEW_ID [--json] # compare two snapshotsAPI
Module src/beadloom/onboarding/scanner/ (package; public surface re-exported from __init__):
ScanResult-- TypedDict (manifests,source_dirs,file_count,languages); return type ofscan_project()ClusterEntry-- TypedDict (files,children,source_dir); value type for_cluster_with_children()output, consumed by_quick_import_scan()scan_project(project_root) -> ScanResult-- scan project structure, return manifests, source_dirs, file_count, languagesclassify_doc(doc_path)-- classify a markdown document (adr, feature, architecture, other)bootstrap_project(root, *, preset_name=None)-- auto-generate graph from code structure (incl. root node, rules, MCP config, AGENTS.md, IDE rules)import_docs(root, docs_dir)-- classify and import existing documentationgenerate_rules(nodes, edges, project_name, rules_path)-- generate architecture rules with empty matcher for hierarchy validationsetup_mcp_auto(project_root)-- auto-detect editor and create MCP configsetup_rules_auto(project_root)-- auto-detect IDEs and create adapter files (.cursorrules,.windsurfrules,.clinerules); content-aware: skips user-edited filesgenerate_agents_md(project_root)-- generate.beadloom/AGENTS.mdwith the MCP tool list (fromMCP_TOOL_CATALOG, currently 18 tools) and rules; preserves content between<!-- beadloom:custom-start -->/<!-- beadloom:custom-end -->HTML comment markers (auto-migrates old## Customformat)prime_context(project_root, *, fmt="markdown")->str | dict[str, Any]-- compact project context for AI agent injection (static + dynamic layers, <=2K tokens); returns markdown string or JSON dict depending on fmtinteractive_init(project_root)-- interactive wizard with re-init detection, mode selection, review table, auto-reindexnon_interactive_init(project_root, *, mode="bootstrap", force=False)-- non-interactive init for CI/scripts; supports bootstrap/import/both modes, force-deletes existing .beadloom/ when force=True, auto-links docs, generates skeletons, runs reindexauto_link_docs(project_root, nodes)-- fuzzy-match existing docs/ files to graph nodes by ref_id (exact path, stem, partial match); patches docs: field in services.yml via _patch_docs_field; returns count of linked docs
All scanner YAML writes (
services.yml/config.ymlfrombootstrap_project(),imported.ymlfrom doc classification,rules.ymlfrom rule generation, and the_patch_docs_fieldwriteback) go through the atomic-io primitive (write_yaml_atomic: temp file +fsync+ atomicos.replace), so an interrupted scaffold never truncates a source-of-truth*.yml. Integrity is guaranteed; the last write may be lost (never corrupted) across an OS/power crash — see the atomic-io durability boundary.
refresh_claude_md(project_root, *, dry_run=False)->list[str]-- refresh auto-managed sections in.claude/CLAUDE.mdbetween marker pairs; returns list of change descriptions; supports dry_run for preview without writing
Module src/beadloom/onboarding/scanner/project_scan.py:
_cluster_by_dirs(project_root, source_dirs=None) -> dict[str, list[str]]-- cluster source files by top-level subdirectories_cluster_with_children(project_root, source_dirs=None) -> dict[str, ClusterEntry]-- two-level directory scan for preset-aware bootstrap; each entry containsfiles,children, andsource_dir_detect_project_name(project_root) -> str-- detect project name from pyproject.toml / package.json / go.mod / Cargo.toml (fallback: directory name)_read_manifest_deps(package_dir) -> list[str]-- read internal dependency names from package.json workspace/file/link dependencies
Module src/beadloom/onboarding/scanner/import_scan.py:
_quick_import_scan(project_root, clusters: dict[str, ClusterEntry], seen_ref_ids) -> list[dict[str, str]]-- inferdepends_onedges between clusters by sampling up to 10 code files per cluster via tree-sitterextract_imports(); capped at_MAX_IMPORT_EDGES(50)
Module src/beadloom/onboarding/presets.py:
Preset-- frozen dataclass: name, description, dir_rules, default_kind, infer_part_of, infer_deps_from_manifestsPresetRule-- frozen dataclass: pattern, kind, confidencePreset.classify_dir(dir_name)-- return (kind, confidence) for a directory namePRESETS-- dict mapping preset names toPresetinstancesdetect_preset(root)-- auto-detect architecture (mobile-aware: checks React Native/Expo/Flutter first)
Module src/beadloom/onboarding/doc_generator.py:
generate_skeletons(project_root, nodes?, edges?)-- create docs/ tree from graph, writedocs:back to YAML, generate.beadloom/README.mdgenerate_polish_data(project_root, ref_id?)-- return structured JSON with SQLite dependency edges, symbol change detection, routes/activity/testsformat_polish_text(data)-- render polish data as multi-line human-readable text with symbol drift, routes, activity, tests
Module src/beadloom/onboarding/config_sync.py:
ConfigDrift(file, reason)-- frozen dataclass describing one drifted agent-config artifactcheck_config_drift(project_root, conn)-- regenerate AGENTS.md + CLAUDE.md auto-sections + IDE adapters in memory and diff vs disk; returns sortedlist[ConfigDrift](auto-managed regions only)
Module src/beadloom/onboarding/ai_techwriter_setup.py:
scaffold(target_root, platform=...)-- drop the platform CI wrapper (callingpython -m beadloom.ai_agents.ai_techwriter) + the operator artifacts (recipe.yaml/provision-runner.shfrom package data) + the getting-started guide (idempotent); raisesValueErroron an unknown platform. No Python vendoring (BDL-051 / S2 — the harness ships in the wheel)._scaffold_provision_runner(target_root)-- drop the hardened, idempotent, executableprovision-runner.sh(swap-first, RAM/disk prechecks, GitHub/GitLab runner registration) intotools/ai_techwriter/(from harness package data)_scaffold_recipe(target_root)-- drop a readable copy of the Goose recipe (harness package data) intotools/ai_techwriter/for operator referencetemplates_root()-- locate the packaged workflow/guide scaffold assetsPLATFORMS-- supported CI platforms (github,gitlab)
Module src/beadloom/onboarding/agentic_flow_setup.py:
scaffold(project_root, *, force=False)-- scaffold the packaged dev flow (vendoredagents/*+commands/*byte-identical + CLAUDE.md auto-regions per-project); idempotent; returnsScaffoldResultsync_agentic_flow(live_claude_root)-- refresh the packaged.md.txtassets from the live.claude/(drift guard; asserted byte-for-byte in tests)templates_root()/vendored_flow_root()-- locate the packaged scaffold assetsAGENT_FILES/COMMAND_FILES-- the vendored role + command file stemsScaffoldResult-- dataclass: files written/skipped + CLAUDE.md path + changed sections
Module src/beadloom/onboarding/config_sync.py (BDL-048 additions):
refresh_agentic_flow_files(project_root)-- re-drop the vendored agentic-flow files into a scaffolded repo (theconfig-check --fixcompanion; gated on the flow already being present)
Module src/beadloom/onboarding/branch_protection.py (BDL-049):
build_protection_payload(*, status_check_contexts=DEFAULT_STATUS_CHECK_CONTEXTS)-- build the GitHub branch-protection request body (PR required, the consolidatedci.ymlchecks required understrict,enforce_admins: true→ strict trunk-based even for admins, 0 required reviews,restrictions: null→ owner NOT locked out, can self-merge once the pipeline is green)apply_branch_protection(owner, repo, *, branch="main", status_check_contexts=..., runner=None)-- configure branch protection viagh apiPUT (idempotent/declarative);runneris an injectableGhRunner(defaults to the realghCLI); returns theBranchProtectionRequestsentBranchProtectionRequest-- frozen dataclass (owner/repo/branch/status_check_contexts);endpoint(),payload_json()(deterministic),gh_args()GhRunner--Protocolfor the injectedghrunner ((argv, stdin) -> stdout)DEFAULT_STATUS_CHECK_CONTEXTS = ("gate", "tests (3.10)", "tests (3.11)", "tests (3.12)", "tests (3.13)", "site-build", "ai-techwriter")/DEFAULT_BRANCH = "main"-- the consolidatedci.ymlrequired check-runs (BDL-050) + the default trunk
Module src/beadloom/onboarding/config_reader.py:
read_deep_config(project_root)-- extract scripts, workspaces, path aliases from pyproject.toml, package.json, tsconfig.json, Cargo.toml, build.gradle
Testing
Tests: tests/test_onboarding.py, tests/test_presets.py, tests/test_doc_generator.py, tests/test_cli_docs.py, tests/test_integration_onboarding.py, tests/test_bead06_misc_fixes.py, tests/test_config_reader.py, tests/test_auto_link_docs.py, tests/test_init_doc_generation.py, tests/test_snapshot.py, tests/test_cli_snapshot.py, tests/test_refresh_claude_md.py, tests/test_config_sync.py, tests/test_cli_config_check.py, tests/test_cli_setup_ai_techwriter.py, tests/test_cli_setup_agentic_flow.py, tests/test_branch_protection.py