Skip to content

Latest commit

 

History

History
3246 lines (3154 loc) · 179 KB

File metadata and controls

3246 lines (3154 loc) · 179 KB

redeploy

Infrastructure migration toolkit: detect → plan → apply

Contents

Metadata

  • name: redeploy
  • version: 0.2.77
  • python_requires: >=3.11
  • license: Apache-2.0
  • ai_model: openrouter/qwen/qwen3-coder-next
  • ecosystem: SUMD + DOQL + testql + taskfile
  • generated_from: pyproject.toml, Makefile, testql(2), app.doql.less, pyqual.yaml, goal.yaml, .env.example, src(13 mod), project/(2 analysis files)

Architecture

SUMD (description) → DOQL/source (code) → taskfile (automation) → testql (verification)

DOQL Application Declaration (app.doql.less)

// LESS format — define @variables here as needed
// Generated by sumd for redeploy

app {
  name: redeploy;
  version: 0.2.77;
}

interface[type="cli"] {
  framework: click;
}

workflow[name="install"] {
  trigger: manual;
  step-1: run cmd=pip install -e .;
}

workflow[name="dev"] {
  trigger: manual;
  step-1: run cmd=pip install -e ".[dev]";
}

workflow[name="build"] {
  trigger: manual;
  step-1: run cmd=python -m build;
}

workflow[name="test"] {
  trigger: manual;
  step-1: run cmd=pytest -q;
}

workflow[name="lint"] {
  trigger: manual;
  step-1: run cmd=ruff check .;
}

workflow[name="fmt"] {
  trigger: manual;
  step-1: run cmd=ruff format .;
}

workflow[name="clean"] {
  trigger: manual;
  step-1: run cmd=rm -rf build/ dist/ *.egg-info;
}

workflow[name="help"] {
  trigger: manual;
  step-1: run cmd=task --list;
}

deploy {
  target: pip;
}

environment[name="local"] {
  runtime: python;
}

Source Modules

  • redeploy.cli
  • redeploy.data_sync
  • redeploy.fleet
  • redeploy.heal
  • redeploy.mcp_server
  • redeploy.observe
  • redeploy.parse
  • redeploy.patterns
  • redeploy.schema
  • redeploy.spec_loader
  • redeploy.ssh
  • redeploy.verify
  • redeploy.version

Interfaces

CLI Entry Points

  • redeploy
  • redeploy-mcp

testql Scenarios

testql-scenarios/generated-cli-tests.testql.toon.yaml

# SCENARIO: CLI Command Tests
# TYPE: cli
# GENERATED: true

CONFIG[2]{key, value}:
  cli_command, python -mredeploy
  timeout_ms, 10000

LOG[3]{message}:
  "Test CLI help command"
  "Test CLI version command"
  "Test CLI main workflow"

testql-scenarios/generated-from-pytests.testql.toon.yaml

# SCENARIO: Auto-generated from Python Tests
# TYPE: integration
# GENERATED: true

LOG[158]{message}:
  "Test: TestParseComposeHealthcheck_test_string_test"
  "Test: test_string_test"
  "Test: TestDockerComposeParserBasic_test_healthcheck"
  "Test: TestDockerComposeParserBasic_test_labels_dict"
  "Test: test_healthcheck"
  "Test: test_labels_dict"
  "Test: test_parse_nginx_conf_ports"
  "Test: test_argocd_application_parser"
  "Test: TestInferAppUrl_test_port_80"
  "Test: TestInferAppUrl_test_port_443"

INCLUDE[14]{file}:
  "/home/tom/github/maskservice/redeploy/redeploy/tests/test_version_cli.py"
  "/home/tom/github/maskservice/redeploy/redeploy/tests/test_version_cli.py"
  "/home/tom/github/maskservice/redeploy/redeploy/tests/test_analyze.py"
  "/home/tom/github/maskservice/redeploy/redeploy/tests/test_analyze.py"
  "/home/tom/github/maskservice/redeploy/redeploy/tests/test_patterns.py"

Workflows

Quality Pipeline (pyqual.yaml)

pipeline:
  name: redeploy-quality

  metrics:
    cc_max: 15
    critical_max: 80

  stages:
    - name: analyze
      tool: code2llm-filtered

    - name: validate
      tool: vallm-filtered

    - name: prefact
      tool: prefact
      optional: true
      when: any_stage_fail
      timeout: 900

    - name: test
      tool: pytest
      timeout: 600

  loop:
    max_iterations: 3
    on_fail: report
    ticket_backends:
      - markdown

  env:
    LLM_MODEL: openrouter/qwen/qwen3-coder-next

Configuration

project:
  name: redeploy
  version: 0.2.77
  env: local

Dependencies

Runtime

pydantic>=2.0
pyyaml>=6.0
markdown-it-py>=3.0
click>=8.0
loguru>=0.7
paramiko>=3.0
httpx>=0.25
rich>=13.0
jmespath>=1.0
goal>=2.1.0
costs>=0.1.20
pfix>=0.1.60

Development

pytest>=8.0
ruff>=0.4
goal>=2.1.0
costs>=0.1.20
pfix>=0.1.60

Deployment

pip install redeploy

# development install
pip install -e .[dev]

Environment Variables (.env.example)

Variable Default Description
OPENROUTER_API_KEY *(not set)* Required: OpenRouter API key (https://openrouter.ai/keys)
LLM_MODEL openrouter/qwen/qwen3-coder-next Model (default: openrouter/qwen/qwen3-coder-next)
PFIX_AUTO_APPLY true true = apply fixes without asking
PFIX_AUTO_INSTALL_DEPS true true = auto pip/uv install
PFIX_AUTO_RESTART false true = os.execv restart after fix
PFIX_MAX_RETRIES 3
PFIX_DRY_RUN false
PFIX_ENABLED true
PFIX_GIT_COMMIT false true = auto-commit fixes
PFIX_GIT_PREFIX pfix: commit message prefix
PFIX_CREATE_BACKUPS false false = disable .pfix_backups/ directory

Release Management (goal.yaml)

  • versioning: semver
  • commits: conventional scope=redeploy
  • changelog: keep-a-changelog
  • build strategies: python, nodejs, rust
  • version files: VERSION, pyproject.toml:version, redeploy/__init__.py:__version__

Makefile Targets

  • PYTHON
  • VENV
  • BIN
  • PIP
  • PYTEST
  • RUFF
  • REDEPLOY
  • help — ── help ──────────────────────────────────────────────────────────────────────
  • install — ── setup ─────────────────────────────────────────────────────────────────────
  • test — ── dev ───────────────────────────────────────────────────────────────────────
  • lint
  • fmt
  • check
  • run — ── run (single spec file) ────────────────────────────────────────────────────
  • run-dry
  • run-plan
  • run-detect
  • detect — ── detect / plan / apply ─────────────────────────────────────────────────────
  • plan
  • apply
  • dry-run
  • migrate
  • push — ── git / release ─────────────────────────────────────────────────────────────
  • tag
  • release
  • quality — ── quality gate (pyqual analyze only — avoids LLM-based stages hanging) ──────
  • quality-check
  • clean — ── clean ─────────────────────────────────────────────────────────────────────

Code Analysis

project/map.toon.yaml

# redeploy | 297f 45323L | python:294,shell:2,less:1 | 2026-05-20
# stats: 862 func | 391 cls | 297 mod | CC̄=4.7 | critical:96 | cycles:0
# alerts[5]: CC version_init=26; CC _bump_single=25; CC _build_manifest=25; CC extract_blueprint=22; CC render_rich=22
# hotspots[5]: run fan=31; fix_cmd fan=29; hardware fan=28; version_init fan=26; import_cmd fan=25
# evolution: baseline
# Keys: M=modules, D=details, i=imports, e=exports, c=classes, f=functions, m=methods
M[297]:
  app.doql.less,60
  examples/redeploy_iac_parsers/argocd_flux.py,130
  examples/redeploy_iac_parsers/gitops_ci.py,138
  examples/redeploy_iac_parsers/helm_ansible.py,95
  examples/redeploy_iac_parsers/helm_kustomize.py,114
  project.sh,42
  redeploy/__init__.py,154
  redeploy/analyze/__init__.py,16
  redeploy/analyze/checkers/__init__.py,48
  redeploy/analyze/checkers/base.py,20
  redeploy/analyze/checkers/binary.py,75
  redeploy/analyze/checkers/command_ref.py,84
  redeploy/analyze/checkers/compose.py,144
  redeploy/analyze/checkers/docker_build.py,161
  redeploy/analyze/checkers/env.py,24
  redeploy/analyze/checkers/path.py,95
  redeploy/analyze/checkers/reference.py,40
  redeploy/analyze/ignore.py,87
  redeploy/analyze/models.py,49
  redeploy/analyze/preflight_schema.py,280
  redeploy/analyze/spec_analyzer.py,119
  redeploy/apply/__init__.py,60
  redeploy/apply/exceptions.py,13
  redeploy/apply/executor.py,355
  redeploy/apply/handlers.py,656
  redeploy/apply/progress.py,108
  redeploy/apply/rollback.py,45
  redeploy/apply/state.py,162
  redeploy/apply/state_apply.py,223
  redeploy/apply/utils/__init__.py,7
  redeploy/apply/utils/run_container_build.py,70
  redeploy/audit/__init__.py,52
  redeploy/audit/auditor.py,156
  redeploy/audit/extractor.py,183
  redeploy/audit/models.py,82
  redeploy/audit/paths.py,35
  redeploy/audit/patterns.py,29
  redeploy/audit/probe.py,79
  redeploy/blueprint/__init__.py,12
  redeploy/blueprint/extractor.py,141
  redeploy/blueprint/generators/__init__.py,1
  redeploy/blueprint/generators/docker_compose.py,191
  redeploy/blueprint/generators/migration.py,180
  redeploy/blueprint/sources/__init__.py,9
  redeploy/blueprint/sources/compose.py,147
  redeploy/blueprint/sources/hardware.py,46
  redeploy/blueprint/sources/infra.py,44
  redeploy/blueprint/sources/migration.py,35
  redeploy/cli/__init__.py,127
  redeploy/cli/commands/__init__.py,45
  redeploy/cli/commands/apply_cmd.py,52
  redeploy/cli/commands/audit.py,127
  redeploy/cli/commands/blueprint.py,340
  redeploy/cli/commands/bump_fix.py,349
  redeploy/cli/commands/detect.py,138
  redeploy/cli/commands/device_map.py,79
  redeploy/cli/commands/device_map_actions.py,175
  redeploy/cli/commands/device_map_renderers.py,171
  redeploy/cli/commands/devices.py,193
  redeploy/cli/commands/devices_display.py,62
  redeploy/cli/commands/diagnose.py,48
  redeploy/cli/commands/diff.py,34
  redeploy/cli/commands/exec_.py,241
  redeploy/cli/commands/export.py,127
  redeploy/cli/commands/gh_workflow.py,292
  redeploy/cli/commands/hardware.py,399
  redeploy/cli/commands/import_.py,358
  redeploy/cli/commands/init.py,112
  redeploy/cli/commands/inspect.py,74
  redeploy/cli/commands/lint.py,87
  redeploy/cli/commands/mcp_cmd.py,55
  redeploy/cli/commands/migrate_cmd.py,76
  redeploy/cli/commands/patterns.py,105
  redeploy/cli/commands/plan_apply.py,10
  redeploy/cli/commands/plan_apply_report.py,297
  redeploy/cli/commands/plan_apply_run.py,105
  redeploy/cli/commands/plan_apply_shared.py,236
  redeploy/cli/commands/plan_cmd.py,79
  redeploy/cli/commands/plugin.py,80
  redeploy/cli/commands/probe.py,92
  redeploy/cli/commands/probe_display.py,78
  redeploy/cli/commands/prompt_cmd.py,344
  redeploy/cli/commands/push.py,111
  redeploy/cli/commands/run_cmd.py,169
  redeploy/cli/commands/state.py,119
  redeploy/cli/commands/status.py,56
  redeploy/cli/commands/target.py,98
  redeploy/cli/commands/version/__init__.py,7
  redeploy/cli/commands/version/commands.py,595
  redeploy/cli/commands/version/helpers.py,350
  redeploy/cli/commands/version/monorepo.py,140
  redeploy/cli/commands/version/release.py,154
  redeploy/cli/commands/version/scanner.py,263
  redeploy/cli/commands/version/utils/__init__.py,9
  redeploy/cli/commands/version/utils/changelog_config.py,28
  redeploy/cli/commands/version/utils/git_config.py,28
  redeploy/cli/commands/workflow.py,88
  redeploy/cli/core.py,180
  redeploy/cli/display.py,390
  redeploy/cli/query.py,43
  redeploy/cli.py,94
  redeploy/config_apply/__init__.py,16
  redeploy/config_apply/applier.py,73
  redeploy/config_apply/handlers/__init__.py,11
  redeploy/config_apply/handlers/display.py,126
  redeploy/config_apply/loader.py,18
  redeploy/data_sync.py,46
  redeploy/detect/__init__.py,6
  redeploy/detect/builtin/__init__.py,3
  redeploy/detect/detector.py,105
  redeploy/detect/hardware.py,84
  redeploy/detect/hardware_rules.py,57
  redeploy/detect/probes.py,284
  redeploy/detect/remote.py,5
  redeploy/detect/templates.py,420
  redeploy/detect/workflow.py,419
  redeploy/discovery/__init__.py,32
  redeploy/discovery/auto_probe.py,187
  redeploy/discovery/helpers.py,33
  redeploy/discovery/probe_parse.py,46
  redeploy/discovery/registry.py,65
  redeploy/discovery/scanners.py,255
  redeploy/discovery/ssh_credentials.py,112
  redeploy/discovery/types.py,39
  redeploy/dsl/__init__.py,31
  redeploy/dsl/loader.py,404
  redeploy/dsl/parser.py,262
  redeploy/dsl_python/__init__.py,78
  redeploy/dsl_python/context.py,40
  redeploy/dsl_python/decorators.py,138
  redeploy/dsl_python/docker_steps.py,212
  redeploy/dsl_python/exceptions.py,45
  redeploy/dsl_python/runner.py,206
  redeploy/dsl_python/steps.py,295
  redeploy/fleet.py,397
  redeploy/hardware/__init__.py,9
  redeploy/hardware/config_txt.py,89
  redeploy/hardware/data/__init__.py,5
  redeploy/hardware/data/hyperpixel.py,42
  redeploy/hardware/data/official.py,19
  redeploy/hardware/data/waveshare.py,49
  redeploy/hardware/fixes.py,204
  redeploy/hardware/kiosk/__init__.py,19
  redeploy/hardware/kiosk/autostart.py,85
  redeploy/hardware/kiosk/browsers.py,79
  redeploy/hardware/kiosk/compositors.py,81
  redeploy/hardware/kiosk/output_profiles.py,69
  redeploy/hardware/panels.py,52
  redeploy/hardware/raspi_config.py,33
  redeploy/heal/__init__.py,38
  redeploy/heal/decider.py,86
  redeploy/heal/hint_provider.py,328
  redeploy/heal/log_writer.py,52
  redeploy/heal/loop_detector.py,62
  redeploy/heal/runner.py,266
  redeploy/heal.py,483
  redeploy/iac/__init__.py,53
  redeploy/iac/base.py,276
  redeploy/iac/config_hints.py,290
  redeploy/iac/docker_compose.py,477
  redeploy/iac/parsers/__init__.py,2
  redeploy/iac/parsers/compose.py,300
  redeploy/iac/registry.py,108
  redeploy/integrations/__init__.py,2
  redeploy/integrations/op3_bridge.py,251
  redeploy/markpact/__init__.py,27
  redeploy/markpact/compiler.py,183
  redeploy/markpact/models.py,27
  redeploy/markpact/parser.py,311
  redeploy/mcp_server.py,357
  redeploy/models/__init__.py,122
  redeploy/models/blueprint.py,96
  redeploy/models/devices.py,171
  redeploy/models/enums.py,70
  redeploy/models/hardware.py,118
  redeploy/models/infra.py,78
  redeploy/models/manifest.py,152
  redeploy/models/persisted.py,28
  redeploy/models/pipeline.py,36
  redeploy/models/plan.py,84
  redeploy/models/spec.py,183
  redeploy/observe.py,314
  redeploy/parse.py,191
  redeploy/patterns.py,408
  redeploy/plan/__init__.py,5
  redeploy/plan/planner.py,628
  redeploy/plugins/__init__.py,181
  redeploy/plugins/builtin/__init__.py,2
  redeploy/plugins/builtin/browser_reload.py,121
  redeploy/plugins/builtin/hardware_diagnostic.py,283
  redeploy/plugins/builtin/notify.py,169
  redeploy/plugins/builtin/process_control.py,124
  redeploy/plugins/builtin/systemd_reload.py,99
  redeploy/schema.py,312
  redeploy/spec_loader.py,48
  redeploy/ssh.py,302
  redeploy/steps/__init__.py,98
  redeploy/steps/docker.py,41
  redeploy/steps/generic.py,88
  redeploy/steps/hardware.py,23
  redeploy/steps/k3s.py,59
  redeploy/steps/kiosk.py,50
  redeploy/steps/podman.py,42
  redeploy/steps/process.py,33
  redeploy/steps/scm.py,23
  redeploy/steps/transfer.py,23
  redeploy/tests/__init__.py,1
  redeploy/tests/test_analyze.py,194
  redeploy/tests/test_audit.py,245
  redeploy/tests/test_cli.py,329
  redeploy/tests/test_data_sync.py,118
  redeploy/tests/test_devices_display.py,34
  redeploy/tests/test_discovery.py,232
  redeploy/tests/test_discovery_probe.py,46
  redeploy/tests/test_dsl.py,355
  redeploy/tests/test_examples.py,519
  redeploy/tests/test_executor.py,733
  redeploy/tests/test_fleet.py,526
  redeploy/tests/test_git_integration.py,326
  redeploy/tests/test_heal.py,183
  redeploy/tests/test_heal_decider.py,92
  redeploy/tests/test_hooks.py,124
  redeploy/tests/test_iac.py,462
  redeploy/tests/test_iac_compose_contract.py,182
  redeploy/tests/test_iac_docker_compose_contract.py,173
  redeploy/tests/test_manifest.py,339
  redeploy/tests/test_markpact_compiler.py,148
  redeploy/tests/test_markpact_parser.py,94
  redeploy/tests/test_models.py,225
  redeploy/tests/test_observe.py,370
  redeploy/tests/test_parse.py,269
  redeploy/tests/test_patterns.py,288
  redeploy/tests/test_plan_apply_report.py,92
  redeploy/tests/test_plan_apply_shared.py,22
  redeploy/tests/test_planner_edge.py,351
  redeploy/tests/test_plugins.py,411
  redeploy/tests/test_probes.py,347
  redeploy/tests/test_public_api.py,244
  redeploy/tests/test_resume.py,272
  redeploy/tests/test_security_hardening.py,94
  redeploy/tests/test_spec_loader.py,106
  redeploy/tests/test_ssh.py,259
  redeploy/tests/test_steps_registry.py,110
  redeploy/tests/test_templates.py,430
  redeploy/tests/test_verify.py,219
  redeploy/tests/test_version.py,220
  redeploy/tests/test_version_changelog.py,357
  redeploy/tests/test_version_cli.py,887
  redeploy/tests/test_version_manifest.py,659
  redeploy/tests/test_version_sources.py,518
  redeploy/tests/test_workflow.py,287
  redeploy/verify.py,93
  redeploy/version/__init__.py,149
  redeploy/version/bump.py,285
  redeploy/version/changelog.py,205
  redeploy/version/commits.py,219
  redeploy/version/diff.py,119
  redeploy/version/git_integration.py,143
  redeploy/version/git_transaction.py,106
  redeploy/version/manifest.py,170
  redeploy/version/sources/__init__.py,66
  redeploy/version/sources/base.py,50
  redeploy/version/sources/json_.py,91
  redeploy/version/sources/plain.py,25
  redeploy/version/sources/regex.py,66
  redeploy/version/sources/toml_.py,105
  redeploy/version/sources/yaml_.py,95
  redeploy/version/transaction.py,163
  redeploy/version.py,24
  scripts/quality_gate.py,49
  tests/contract/__init__.py,2
  tests/contract/test_blueprint_op3_parity.py,71
  tests/contract/test_detect_op3_parity.py,52
  tests/contract/test_hardware_op3_parity.py,57
  tests/integration/__init__.py,2
  tests/integration/test_op3_bridge.py,101
  tests/test_blueprint_sources.py,187
  tests/test_blueprint_sources_compose.py,154
  tests/test_cli_gh_workflow.py,133
  tests/test_cli_query.py,80
  tests/test_example_argocd_flux_plugin.py,83
  tests/test_example_gitops_ci_plugin.py,75
  tests/test_example_helm_kustomize_plugin.py,73
  tests/test_hardware_config.py,163
  tests/test_hardware_kiosk.py,231
  tests/test_hardware_rules.py,192
  tests/test_heal_decider.py,64
  tests/test_heal_loop_detector.py,48
  tests/test_iac.py,512
  tests/test_iac_config_hints.py,130
  tests/test_iac_plugin_loading.py,80
  tests/test_import_plugin_template.py,56
  tests/test_parse.py,158
  tests/test_prompt_llm.py,422
  tests/test_redeploy.py,12
  tests/test_steps_kiosk.py,94
  tree.sh,2
D:
  examples/redeploy_iac_parsers/argocd_flux.py:
    e: ArgoCDApplicationParser,FluxKustomizationParser
    ArgoCDApplicationParser: can_parse(1),parse(1)
    FluxKustomizationParser: can_parse(1),parse(1)
  examples/redeploy_iac_parsers/gitops_ci.py:
    e: _is_gitops_command,GitHubActionsGitOpsParser,GitLabCIGitOpsParser
    GitHubActionsGitOpsParser: can_parse(1),parse(1)
    GitLabCIGitOpsParser: can_parse(1),parse(1)
    _is_gitops_command(text)
  examples/redeploy_iac_parsers/helm_ansible.py:
    e: HelmChartParser,AnsiblePlaybookParser
    HelmChartParser: can_parse(1),parse(1)
    AnsiblePlaybookParser: can_parse(1),parse(1)
  examples/redeploy_iac_parsers/helm_kustomize.py:
    e: _extract_images_from_container_spec,HelmTemplatesParser,KustomizationParser
    HelmTemplatesParser: can_parse(1),parse(1)
    KustomizationParser: can_parse(1),parse(1)
    _extract_images_from_container_spec(container_spec)
  redeploy/__init__.py:
  redeploy/analyze/__init__.py:
  redeploy/analyze/checkers/__init__.py:
  redeploy/analyze/checkers/base.py:
    e: Checker
    Checker: check(4)
  redeploy/analyze/checkers/binary.py:
    e: extract_binaries,BinaryChecker
    BinaryChecker: check(4)  # Warn if commands reference binaries not available locally (b
    extract_binaries(cmd)
  redeploy/analyze/checkers/command_ref.py:
    e: CommandRefChecker
    CommandRefChecker: check(4),_check_external_ref(6)  # Validate command_ref references for nested markdown/script d
  redeploy/analyze/checkers/compose.py:
    e: _is_ignored,_check_build_section,_check_env_files,_check_volumes,scan_compose_file,ComposeChecker
    ComposeChecker: check(4)  # Validate docker-compose files declared in spec or found in p
    _is_ignored(check_path;base_dir;ign)
    _check_build_section(svc_name;svc;base_dir;result;ign)
    _check_env_files(svc_name;svc;base_dir;result;ign)
    _check_volumes(svc_name;svc;base_dir;result;ign)
    scan_compose_file(path;base_dir;result;ign)
  redeploy/analyze/checkers/docker_build.py:
    e: collect_sync_mappings,parse_docker_build,match_local_src,resolve_local_dockerfile,DockerBuildChecker
    DockerBuildChecker: check(4),_check_dockerfile(4),_check_remote_context(7)  # Validate docker build commands: Dockerfile exists, context i
    collect_sync_mappings(spec)
    parse_docker_build(cmd)
    match_local_src(sync_mappings;remote_context)
    resolve_local_dockerfile(local_src;dockerfile;base_dir)
  redeploy/analyze/checkers/env.py:
    e: EnvFileChecker
    EnvFileChecker: check(4)  # Check that .env referenced by target.env_file exists.
  redeploy/analyze/checkers/path.py:
    e: resolve_local_path,is_inside,PathChecker,CommandPathChecker
    PathChecker: check(4),_check_field(5)  # Validate local file paths referenced by steps.
    CommandPathChecker: check(4)  # Scan command strings for hardcoded absolute paths outside th
    resolve_local_path(val;base_dir)
    is_inside(path;base)
  redeploy/analyze/checkers/reference.py:
    e: ReferenceChecker
    ReferenceChecker: check(4)  # Ensure command_ref and insert_before point to existing thing
  redeploy/analyze/ignore.py:
    e: ensure_redeployignore,IgnoreList
    IgnoreList: __init__(1),_load(1),is_ignored(1)  # Read .gitignore and .redeployignore patterns and test if pat
    ensure_redeployignore(base_dir)
  redeploy/analyze/models.py:
    e: IssueSeverity,Issue,AnalysisResult
    IssueSeverity:
    Issue:
    AnalysisResult: add(6),errors(0),warnings(0)
  redeploy/analyze/preflight_schema.py:
    e: generate_preflight_schema,save_preflight_schema,_resolve_command_refs,_collect_local_artifacts,_collect_remote_checks,_resolve_local_path,PreflightResult
    PreflightResult: has_blockers(0)
    generate_preflight_schema()
    save_preflight_schema(schema;output_path)
    _resolve_command_refs(spec;spec_path;blockers)
    _collect_local_artifacts(spec;base_dir;blockers)
    _collect_remote_checks(spec;host)
    _resolve_local_path(val;base_dir)
  redeploy/analyze/spec_analyzer.py:
    e: SpecAnalyzer
    SpecAnalyzer: __init__(3),analyze(2),analyze_file(1)  # Run static checks against a compiled MigrationSpec (and opti
  redeploy/apply/__init__.py:
  redeploy/apply/exceptions.py:
    e: StepError
    StepError: __init__(2)  # Exception raised when a migration step fails.
  redeploy/apply/executor.py:
    e: Executor
    Executor: __init__(11),completed_steps(0),state(0),state_path(0),run(0),_execute_steps_loop(1),_skip_step(2),_handle_step_failure(3),_handle_completion(2),_fire_hooks(1),_eval_hook_condition(2),_execute_hook(2),_handle_hook_failure(2),_compute_skip_set(0),_write_audit(0),_execute_step(1),_rollback(0),summary(0),from_file(1),save_results(1)  # Execute MigrationPlan steps on a remote host.
  redeploy/apply/handlers.py:
    e: _format_step_output,run_ssh,run_scp,run_rsync,_ensure_remote_parent_dir,run_docker_build,run_podman_build,run_docker_health_wait,_parse_container_statuses,_all_containers_healthy,run_container_log_tail,run_http_check,run_version_check,run_plugin,run_wait,run_inline_script,_resolve_command_ref,run_ensure_config_line,run_raspi_config,run_ensure_kanshi_profile,run_ensure_autostart_entry,run_ensure_browser_kiosk_script
    _format_step_output(stdout;stderr;max_chars)
    run_ssh(step;probe)
    run_scp(step;probe;plan)
    run_rsync(step;probe;plan)
    _ensure_remote_parent_dir(probe;remote_dst)
    run_docker_build(step;probe;emitter)
    run_podman_build(step;probe;emitter)
    run_docker_health_wait(step;probe)
    _parse_container_statuses(output)
    _all_containers_healthy(statuses)
    run_container_log_tail(step;probe)
    run_http_check(step;probe;retries;delay)
    run_version_check(step;probe)
    run_plugin(step;probe;plan;emitter;dry_run)
    run_wait(step)
    run_inline_script(step;probe;plan)
    _resolve_command_ref(command_ref;step;plan)
    run_ensure_config_line(step;probe)
    run_raspi_config(step;probe)
    run_ensure_kanshi_profile(step;probe)
    run_ensure_autostart_entry(step;probe)
    run_ensure_browser_kiosk_script(step;probe)
  redeploy/apply/progress.py:
    e: ProgressEmitter
    ProgressEmitter: __init__(1),_ts(0),_elapsed(0),_emit(1),start(1),step_start(2),step_done(2),step_fail(3),progress(2),done(1),failed(3)  # Emits YAML-formatted progress events to a stream (default: s
  redeploy/apply/rollback.py:
    e: rollback_steps
    rollback_steps(completed_steps;probe;state)
  redeploy/apply/state.py:
    e: _now_iso,_slug,state_key,default_state_path,filter_resumable,ResumeState
    ResumeState: load(2),load_or_new(2),save(1),remove(0),mark_done(1),mark_failed(2),reset(0),is_done(1),completed_count(0),remaining(0)  # Checkpoint for a single MigrationPlan execution.
    _now_iso()
    _slug(value)
    state_key(spec_path;host)
    default_state_path(spec_path;host;base_dir)
    filter_resumable(step_ids;state)
  redeploy/apply/state_apply.py:
    e: _update_kanshi,detect_handler,apply_state,ApplyResult,StateHandler,HardwareStateHandler,InfraStateHandler
    ApplyResult: ok(0)
    StateHandler: accept(1),apply(3)  # Base class for a declarative state applier.
    HardwareStateHandler: accept(1),apply(3)  # Applies HardwareInfo-shaped YAML: display transforms, backli
    InfraStateHandler: accept(1),apply(3)  # Placeholder — applies InfraState-shaped YAML (services, port
    _update_kanshi(dsi_outputs;p;console;applied;errors)
    detect_handler(data)
    apply_state(data;p;console)
  redeploy/apply/utils/__init__.py:
  redeploy/apply/utils/run_container_build.py:
    e: run_container_build
    run_container_build(step;probe;emitter;engine)
  redeploy/audit/__init__.py:
    e: audit_spec
    audit_spec(spec_path)
  redeploy/audit/auditor.py:
    e: Auditor
    Auditor: __init__(2),run(0),_add_disk_check(1),_probe_one(1),_check(3),_probe_binary(1),_probe_directory(1),_probe_file(1),_probe_local_file(1),_probe_port_listening(1),_probe_container_image(1),_probe_systemd_unit(1),_probe_apt_package(1)
  redeploy/audit/extractor.py:
    e: Extractor
    Extractor: __init__(1),collect(0),_from_target(0),_from_step(1),_from_command(2)  # Walk a MigrationSpec and emit Expect tuples.
  redeploy/audit/models.py:
    e: AuditCheck,AuditReport,Expect
    AuditCheck: ok(0)  # Outcome of a single audit probe.
    AuditReport: add(1),passed(0),failed(0),warned(0),skipped(0),ok(0),summary(0),to_dict(0)
    Expect: extras(0)
  redeploy/audit/paths.py:
    e: extract_port,normalize_path,strip_remote_dir
    extract_port(url)
    normalize_path(path)
    strip_remote_dir(path)
  redeploy/audit/patterns.py:
  redeploy/audit/probe.py:
    e: Probe
    Probe: __init__(1),has_binary(1),has_path(1),port_listening(1),has_image(1),has_systemd_unit(1),apt_package(1),disk_free_gib(1)  # Thin wrapper around SshClient with sensible audit timeouts.
  redeploy/blueprint/__init__.py:
  redeploy/blueprint/extractor.py:
    e: extract_blueprint
    extract_blueprint()
  redeploy/blueprint/generators/__init__.py:
  redeploy/blueprint/generators/docker_compose.py:
    e: generate_twin,_build_service
    generate_twin(blueprint)
    _build_service(svc)
  redeploy/blueprint/generators/migration.py:
    e: generate_migration
    generate_migration(blueprint)
  redeploy/blueprint/sources/__init__.py:
  redeploy/blueprint/sources/compose.py:
    e: merge_compose_files,_merge_compose,_parse_compose_ports,_parse_compose_volumes,_parse_compose_env,_parse_compose_healthcheck
    merge_compose_files(compose_files;services;seen)
    _merge_compose(path;services;seen)
    _parse_compose_ports(raw)
    _parse_compose_volumes(raw)
    _parse_compose_env(raw)
    _parse_compose_healthcheck(raw)
  redeploy/blueprint/sources/hardware.py:
    e: build_hw_requirements
    build_hw_requirements(hw)
  redeploy/blueprint/sources/infra.py:
    e: extract_services_from_infra,infer_app_url
    extract_services_from_infra(infra;seen)
    infer_app_url(infra)
  redeploy/blueprint/sources/migration.py:
    e: parse_migration_meta
    parse_migration_meta(path)
  redeploy/cli/__init__.py:
    e: _setup_logging,cli,_resolve_device
    _setup_logging(verbose)
    cli(ctx;verbose)
    _resolve_device(console;device_id)
  redeploy/cli/commands/__init__.py:
  redeploy/cli/commands/apply_cmd.py:
    e: apply
    apply(ctx;plan_file;dry_run;step;output)
  redeploy/cli/commands/audit.py:
    e: audit
    audit(last;host;app;only_failed;only_ok;log;as_json;show_report;do_clear)
  redeploy/cli/commands/blueprint.py:
    e: blueprint_cmd,capture,_execute_query_blueprint,twin,deploy,show,list_blueprints,_print_blueprint
    blueprint_cmd()
    capture(host;name;compose_files;migration_file;device_map_file;live;save;out_path;fmt;tags)
    _execute_query_blueprint(bp;query_expr;output_fmt)
    twin(blueprint_file;out_path;platform;port_offset;no_mock_display;print_output)
    deploy(blueprint_file;target_host;out_path;remote_dir;no_transfer;strategy;run_migration;print_output)
    show(blueprint_file;fmt;apply_config;query_expr)
    list_blueprints()
    _print_blueprint(console;bp;fmt)
  redeploy/cli/commands/bump_fix.py:
    e: _find_spec,_prompt_choose_spec,_find_version_file,_bump_patch,_bump_version_file,_update_migration_header,_update_quadlet_service_version,_load_dotenv,bump_cmd,fix_cmd,_print_banner,_detect_version
    _find_spec(spec_arg)
    _prompt_choose_spec(specs;base)
    _find_version_file(spec_path)
    _bump_patch(version)
    _bump_version_file(version_file;console)
    _update_migration_header(spec_path;new_version)
    _update_quadlet_service_version(start;new_version)
    _load_dotenv()
    bump_cmd(spec_or_dir;minor;major)
    fix_cmd(spec_or_dir;hint;bump;minor;major;retries;dry_run;env_name)
    _print_banner(console;hint)
    _detect_version(spec_path)
  redeploy/cli/commands/detect.py:
    e: detect
    detect(ctx;host;app;domain;output;run_workflow;scan_subnet;no_deep;save_yaml;output_fmt)
  redeploy/cli/commands/device_map.py:
    e: device_map_cmd
    device_map_cmd(host;name;tags;save;out_path;output_fmt;no_infra;list_saved;show_file;diff_files;ssh_key;apply_config;query_expr)
  redeploy/cli/commands/device_map_actions.py:
    e: print_saved_maps,print_device_map_diff,probe_device_map,execute_query_device_map,emit_device_map
    print_saved_maps(console)
    print_device_map_diff(console;path_a;path_b)
    probe_device_map(console;host)
    execute_query_device_map(console;dm;query_expr;output_fmt)
    emit_device_map(dm;output_fmt)
  redeploy/cli/commands/device_map_renderers.py:
    e: render_yaml,render_json,_build_header_panel,_build_drm_table,_build_services_table,_build_issues_table,render_rich
    render_yaml(dm)
    render_json(dm)
    _build_header_panel(dm)
    _build_drm_table(dm)
    _build_services_table(dm)
    _build_issues_table(dm)
    render_rich(console;dm)
  redeploy/cli/commands/devices.py:
    e: devices,scan,device_add,device_rm
    devices(tag;strategy;rpi;reachable;as_json)
    scan(subnet;ssh_users;ssh_port;ping;no_mdns;timeout;no_save)
    device_add(host;device_id;name;tags;strategy;app;ssh_port;ssh_key)
    device_rm(device_id)
  redeploy/cli/commands/devices_display.py:
    e: filter_devices,render_devices_table
    filter_devices(devices)
    render_devices_table(console;devices)
  redeploy/cli/commands/diagnose.py:
    e: diagnose
    diagnose(ctx;spec;host;ssh_key;output_fmt;exit_on_fail)
  redeploy/cli/commands/diff.py:
    e: diff
    diff(ci_file;host;from_src;to_src)
  redeploy/cli/commands/exec_.py:
    e: exec_cmd,exec_multi_cmd,_extract_all_scripts,_extract_script_for_ref,_execute_single_script,_print_execution_results
    exec_cmd(ctx;ref;host;markdown_file;dry_run;timeout)
    exec_multi_cmd(ctx;refs;host;markdown_file;dry_run;timeout;parallel)
    _extract_all_scripts(md_path;ref_list;console)
    _extract_script_for_ref(md_content;ref_id)
    _execute_single_script(ref_id;script;host;timeout)
    _print_execution_results(console;results)
  redeploy/cli/commands/export.py:
    e: export_cmd,_find_export_source,_load_manifest_from_css,_load_manifest_from_yaml,_export_to_css,_export_to_yaml
    export_cmd(ctx;output;src_file;fmt)
    _find_export_source(src_file;console)
    _load_manifest_from_css(src)
    _load_manifest_from_yaml(src)
    _export_to_css(manifest;templates)
    _export_to_yaml(manifest)
  redeploy/cli/commands/gh_workflow.py:
    e: _find_repo_root,_resolve_repo_root,_workflows_dir,_load_yaml,_on_section,_trigger_list,_has_workflow_dispatch,_collect_workflow_meta,_resolve_workflow_identifier,_gh_available,_parse_fields,gh_workflow_cmd,gh_workflow_list,gh_workflow_analyze,gh_workflow_run
    _find_repo_root(start)
    _resolve_repo_root(repo_root_opt)
    _workflows_dir(repo_root)
    _load_yaml(path)
    _on_section(raw)
    _trigger_list(on_value)
    _has_workflow_dispatch(on_value)
    _collect_workflow_meta(path)
    _resolve_workflow_identifier(wf_dir;workflow)
    _gh_available()
    _parse_fields(fields)
    gh_workflow_cmd()
    gh_workflow_list(repo_root)
    gh_workflow_analyze(workflow;repo_root)
    gh_workflow_run(workflow;repo_root;ref;fields;watch;dry_run)
  redeploy/cli/commands/hardware.py:
    e: _probe_hardware,_format_output,_print_drm_connectors,_print_backlights,_print_dsi_overlays,_print_i2c_buses,_print_diagnostics,_apply_transform,_execute_query,_apply_fix,hardware
    _probe_hardware(host;ssh_key;console)
    _format_output(hw;output_fmt)
    _print_drm_connectors(console;hw)
    _print_backlights(console;hw)
    _print_dsi_overlays(console;hw)
    _print_i2c_buses(console;hw)
    _print_diagnostics(console;hw;show_fix)
    _apply_transform(console;p;hw;transform)
    _execute_query(hw;query_expr;output_fmt)
    _apply_fix(console;p;hw;apply_fix_component;panel_id)
    hardware(host;output_fmt;show_fix;apply_fix_component;panel_id;list_panels;ssh_key;set_transform;apply_config;query_expr)
  redeploy/cli/commands/import_.py:
    e: import_cmd,_print_import_spec,_default_output,_plugin_templates,_examples_plugin_dir,_print_plugin_templates,_copy_plugin_template,_spec_to_migration_yaml
    import_cmd(source;output;target_host;target_strategy;dry_run;out_format;parser;plugin_template;plugin_dir;list_plugin_templates)
    _print_import_spec(console;spec)
    _default_output(src;spec)
    _plugin_templates()
    _examples_plugin_dir()
    _print_plugin_templates(console)
    _copy_plugin_template(console)
    _spec_to_migration_yaml(spec)
  redeploy/cli/commands/init.py:
    e: init
    init(host;app;domain;strategy;force)
  redeploy/cli/commands/inspect.py:
    e: _find_css_path,inspect
    _find_css_path(css_file;console)
    inspect(ctx;css_file)
  redeploy/cli/commands/lint.py:
    e: lint
    lint(ctx;spec_file;env_name;as_json;exit_zero)
  redeploy/cli/commands/mcp_cmd.py:
    e: mcp_cmd
    mcp_cmd(transport;host;port)
  redeploy/cli/commands/migrate_cmd.py:
    e: migrate
    migrate(ctx;host;app;domain;target;strategy;target_version;compose;env_file;dry_run;infra_out;plan_out)
  redeploy/cli/commands/patterns.py:
    e: patterns
    patterns(name)
  redeploy/cli/commands/plan_apply.py:
  redeploy/cli/commands/plan_apply_report.py:
    e: default_report_path,resolve_audit_entry,step_command_block,_skipped_checksum,build_checksum_verification,_run_rsync_checksum,_parse_rsync_output,_render_checksum_section,render_markdown_report,write_markdown_report
    default_report_path(spec_path)
    resolve_audit_entry(migration;started_at;ok)
    step_command_block(step)
    _skipped_checksum()
    build_checksum_verification(migration;executed)
    _run_rsync_checksum(sync_step;host;local_root;remote_root)
    _parse_rsync_output(result;host;local_root;remote_root;command_preview)
    _render_checksum_section(lines;checksum)
    render_markdown_report(entry;migration;spec_path;checksum)
    write_markdown_report(console;migration;spec_path;started_at;ok;executed;report_file)
  redeploy/cli/commands/plan_apply_run.py:
    e: setup_run_logging,run_lint_phase,run_preflight_phase
    setup_run_logging(resolved_spec)
    run_lint_phase(console;resolved_spec;lint;file_handler_id)
    run_preflight_phase(console)
  redeploy/cli/commands/plan_apply_shared.py:
    e: apply_manifest_to_spec,print_spec_summary,perform_live_detect,run_apply,load_dotenv_for_heal,detect_project_version,print_heal_banner,ensure_redeployignore,inject_project_sync_step,load_spec_for_run
    apply_manifest_to_spec(console;manifest;spec;env_name)
    print_spec_summary(console;spec)
    perform_live_detect(console;spec)
    run_apply(console;migration;dry_run;output)
    load_dotenv_for_heal()
    detect_project_version(spec_path)
    print_heal_banner(console;fix_hint)
    ensure_redeployignore(project_root;console)
    inject_project_sync_step(migration;spec;project_root;console)
    load_spec_for_run(console;spec_file;manifest)
  redeploy/cli/commands/plan_cmd.py:
    e: plan
    plan(ctx;infra;target;strategy;domain;target_version;compose;env_file;output)
  redeploy/cli/commands/plugin.py:
    e: plugin_cmd
    plugin_cmd(ctx;subcommand;name)
  redeploy/cli/commands/probe.py:
    e: probe
    probe(hosts;subnet;users;ssh_port;app_hint;timeout;no_save;as_json)
  redeploy/cli/commands/probe_display.py:
    e: collect_probe_hosts,print_probe_line,print_reachable_devices_table
    collect_probe_hosts(hosts;subnet;console)
    print_probe_line(console;ip;result)
    print_reachable_devices_table(console;results)
  redeploy/cli/commands/prompt_cmd.py:
    e: _call_llm,_parse_llm_response,prompt_cmd,_find_redeploy_bin
    _call_llm(schema;user_prompt)
    _parse_llm_response(raw)
    prompt_cmd(instruction;schema_only;dry_run;yes;show_schema)
    _find_redeploy_bin()
  redeploy/cli/commands/push.py:
    e: push
    push(host;files;dry_run;ssh_key)
  redeploy/cli/commands/run_cmd.py:
    e: run
    run(ctx;spec_file;dry_run;plan_only;do_detect;plan_out;output;report;report_file;sync_project;env_name;progress_yaml;resume;from_step;state_file;no_state;heal;fix_hint;max_heal_retries;lint;preflight;preflight_schema_out;preflight_remote;strict_preflight)
  redeploy/cli/commands/state.py:
    e: _get_state_path,_list_checkpoints,_show_checkpoint,state_cmd
    _get_state_path(spec_file;host;state_file;console)
    _list_checkpoints(console)
    _show_checkpoint(console;path)
    state_cmd(ctx;action;spec_file;host;state_file)
  redeploy/cli/commands/status.py:
    e: status
    status(spec_file)
  redeploy/cli/commands/target.py:
    e: target
    target(device_id;spec_file;dry_run;plan_only;do_detect;plan_out)
  redeploy/cli/commands/version/__init__.py:
  redeploy/cli/commands/version/commands.py:
    e: version_cmd,version_current,version_list,version_verify,version_bump,version_set,version_init,version_diff
    version_cmd()
    version_current(manifest;package_name;all_packages)
    version_list(manifest;package_name;all_packages)
    version_verify(manifest;package_name;all_packages)
    version_bump(type;manifest;package;all_packages;dry_run;analyze;commit;tag;push;sign;allow_dirty;changelog)
    version_set(version;manifest_path_str;package_name;all_packages;dry_run;commit;tag;push;sign;allow_dirty;changelog)
    version_init(scan;review;interactive;excluded_paths;force)
    version_diff(manifest;package_name;all_packages;spec;live;app)
  redeploy/cli/commands/version/helpers.py:
    e: _resolve_monorepo_targets,_build_package_version_manifest,_resolve_package_release_git_config,_resolve_package_release_changelog_config,_print_verify_result,_print_source_drift_status,_load_spec_version_diff,_load_live_version_diff,_run_version_diff_for_manifest,_bump_single
    _resolve_monorepo_targets(manifest_model;package_name;all_packages;console)
    _build_package_version_manifest(manifest_model;package_name)
    _resolve_package_release_git_config(manifest_model;package_name)
    _resolve_package_release_changelog_config(manifest_model;package_name)
    _print_verify_result(console;result;expected_version)
    _print_source_drift_status(console;result;expected_version)
    _load_spec_version_diff(manifest_model;spec)
    _load_live_version_diff(manifest_model;live;app)
    _run_version_diff_for_manifest(console;manifest_model;spec;live;app)
    _bump_single(m;bump_type;dry_run;analyze;commit;tag;push;sign;allow_dirty;changelog)
  redeploy/cli/commands/version/monorepo.py:
    e: _set_monorepo_version,_print_monorepo_set_dry_run,_create_version_set_git,_create_version_set_taggers,_finalize_monorepo_version_set
    _set_monorepo_version(manifest_model;version;targets;manifest_path;dry_run;commit;tag;push;sign;allow_dirty;changelog;console)
    _print_monorepo_set_dry_run(manifest_model;targets;version;console)
    _create_version_set_git(manifest_model;repo_path;package_name;commit;tag;push;allow_dirty)
    _create_version_set_taggers(manifest_model;repo_path;targets)
    _finalize_monorepo_version_set(git;version;touched_files;commit;tag;push;sign;console;package_count)
  redeploy/cli/commands/version/release.py:
    e: _format_release_tag,_update_release_changelog,_create_release_tags,_update_monorepo_release_changelogs,_resolve_package_release_git_config,_resolve_package_release_changelog_config
    _format_release_tag(git_config;version)
    _update_release_changelog(manifest_model;repo_path;version;console)
    _create_release_tags(taggers;version;sign)
    _update_monorepo_release_changelogs(manifest_model;repo_path;version;targets;console)
    _resolve_package_release_git_config(manifest_model;package_name)
    _resolve_package_release_changelog_config(manifest_model;package_name)
  redeploy/cli/commands/version/scanner.py:
    e: _version_scan_specs,_regex_version_scan_specs,_is_scannable_version_path,_normalize_scan_exclusions,_detect_version_sources_in_dir,_detect_source_version,_read_detected_source_versions,_report_version_scan_conflict,_print_version_scan_review,_classify_version_scan_source_confidence,_format_version_scan_source_status,_default_keep_scanned_source,_summarize_version_scan_group,_print_version_scan_group,_iter_version_scan_groups,_review_detected_sources_interactively,_derive_scanned_package_name,_scan_package_version_manifests
    _version_scan_specs()
    _regex_version_scan_specs()
    _is_scannable_version_path(path)
    _normalize_scan_exclusions(excluded_paths)
    _detect_version_sources_in_dir(directory;workspace_root)
    _detect_source_version(sources)
    _read_detected_source_versions(sources)
    _report_version_scan_conflict(console;label;sources;chosen_version)
    _print_version_scan_review(console;root_sources;packages)
    _classify_version_scan_source_confidence(source)
    _format_version_scan_source_status(confidence)
    _default_keep_scanned_source(confidence)
    _summarize_version_scan_group(sources)
    _print_version_scan_group(console;label;sources)
    _iter_version_scan_groups(root_sources;packages)
    _review_detected_sources_interactively(console;root_sources;packages)
    _derive_scanned_package_name(package_dir;workspace_root;used_names)
    _scan_package_version_manifests(workspace_root)
  redeploy/cli/commands/version/utils/__init__.py:
  redeploy/cli/commands/version/utils/changelog_config.py:
    e: resolve_package_release_changelog_config
    resolve_package_release_changelog_config(manifest_model;package_name)
  redeploy/cli/commands/version/utils/git_config.py:
    e: resolve_package_release_git_config
    resolve_package_release_git_config(manifest_model;package_name)
  redeploy/cli/commands/workflow.py:
    e: workflow_cmd,_list_workflows,_execute_workflow
    workflow_cmd(ctx;name;css_file;dry_run;list_only)
    _list_workflows(console;css_path;result)
    _execute_workflow(console;wf;dry_run;css_path)
  redeploy/cli/core.py:
    e: load_spec_or_exit,find_manifest_path,resolve_device,load_spec_with_manifest,overlay_device_onto_spec,run_detect_for_spec,run_detect_workflow
    load_spec_or_exit(console;path)
    find_manifest_path()
    resolve_device(console;device_id)
    load_spec_with_manifest(console;spec_file;dev)
    overlay_device_onto_spec(spec;dev;console)
    run_detect_for_spec(console;spec;do_detect)
    run_detect_workflow(console;hosts;manifest;app;scan_subnet;deep;save_yaml;fmt)
  redeploy/cli/display.py:
    e: print_plan_table,print_infrastructure_summary,print_docker_services,print_k3s_pods,print_conflicts,print_inspect_app_metadata,print_inspect_environments,print_inspect_templates,_get_plugin_hint,_format_workflow_header,_print_workflow_step,print_inspect_workflows,print_inspect_devices,print_inspect_raw_nodes_summary,print_workflow_summary_table,_print_host_header,_print_template_match,_print_alternatives,print_workflow_host_details,generate_workflow_output_css,generate_workflow_output_yaml,_get_status_color,_print_services_table,_print_spec_metadata,print_import_spec
    print_plan_table(console;migration)
    print_infrastructure_summary(console;state;host)
    print_docker_services(console;state)
    print_k3s_pods(console;state)
    print_conflicts(console;state)
    print_inspect_app_metadata(console;result)
    print_inspect_environments(console;result)
    print_inspect_templates(console;result)
    _get_plugin_hint(steps)
    _format_workflow_header(wf;plugin_hint)
    _print_workflow_step(console;step)
    print_inspect_workflows(console;result)
    print_inspect_devices(console;result)
    print_inspect_raw_nodes_summary(console;result)
    print_workflow_summary_table(console;result)
    _print_host_header(console;h)
    _print_template_match(console;best)
    _print_alternatives(console;ranked)
    print_workflow_host_details(console;result)
    generate_workflow_output_css(console;result;app;save_yaml)
    generate_workflow_output_yaml(console;result;save_yaml)
    _get_status_color(confidence)
    _print_services_table(console;services)
    _print_spec_metadata(console;spec)
    print_import_spec(console;spec)
  redeploy/cli/query.py:
    e: execute_query
    execute_query(obj;query_expr;output_fmt;echo)
  redeploy/cli.py:
  redeploy/config_apply/__init__.py:
  redeploy/config_apply/applier.py:
    e: _normalize_hardware,apply_config_dict,apply_config_file
    _normalize_hardware(data)
    apply_config_dict(data;probe;console)
    apply_config_file(path)
  redeploy/config_apply/handlers/__init__.py:
  redeploy/config_apply/handlers/display.py:
    e: _validate_display_inputs,apply_display_transform
    _validate_display_inputs(output_name;transform)
    apply_display_transform(console;probe;output_name;transform)
  redeploy/config_apply/loader.py:
    e: load_config_file
    load_config_file(path)
  redeploy/data_sync.py:
    e: collect_sqlite_counts,rsync_timeout_for_path
    collect_sqlite_counts(app_root;db_specs)
    rsync_timeout_for_path(path;minimum;base;per_mb)
  redeploy/detect/__init__.py:
  redeploy/detect/builtin/__init__.py:
  redeploy/detect/detector.py:
    e: Detector
    Detector: __init__(3),run(0),save(2),probe_hardware(0)  # Probe infrastructure and produce InfraState.
  redeploy/detect/hardware.py:
    e: _wrap_remote_probe,probe_hardware
    _wrap_remote_probe(p)
    probe_hardware(p)
  redeploy/detect/hardware_rules.py:
    e: _hw_info_to_dict,_op3_diag_to_hw_diag,analyze
    _hw_info_to_dict(hw)
    _op3_diag_to_hw_diag(d)
    analyze(hw)
  redeploy/detect/probes.py:
    e: probe_runtime,probe_ports,probe_iptables_dnat,probe_docker_services,probe_k3s_services,probe_systemd_services,probe_health,detect_conflicts,detect_strategy
    probe_runtime(p)
    probe_ports(p)
    probe_iptables_dnat(p;ports)
    probe_docker_services(p)
    probe_k3s_services(p;namespaces)
    probe_systemd_services(p;app)
    probe_health(host;app;domain)
    detect_conflicts(ports;iptables_dnat;runtime;docker_services;k3s_services)
    detect_strategy(runtime;docker_services;k3s_services;systemd_services)
  redeploy/detect/remote.py:
  redeploy/detect/templates.py:
    e: _all_services,build_context,_svc,_port,_load_templates_from_yaml,_build_templates,Condition,DetectionTemplate,FactExtractor,TemplateMatch,DetectionResult,TemplateEngine
    Condition:  # A single scoreable condition.
    DetectionTemplate: score(1),max_score(0)  # Named template for a device+environment+strategy combination
    FactExtractor: __call__(4)  # Extract a single key/value pair into the context dict.
    TemplateMatch: confidence(0),confidence_label(0)  # Scored template match.
    DetectionResult: strategy(0),environment(0),spec_template(0),generated_env_block(2),generated_notes(0)  # Full result of template-based detection.
    TemplateEngine: __init__(1),score_all(1),detect(3)  # Score all templates against a context and return ranked matc
    _all_services(state;probe)
    build_context(state;probe;manifest)
    _svc(name)
    _port(p)
    _load_templates_from_yaml()
    _build_templates()
  redeploy/detect/workflow.py:
    e: HostDetectionResult,WorkflowResult,DetectionWorkflow
    HostDetectionResult: strategy(0),environment(0),confidence(0),template_name(0),spec_template(0),env_block(0),notes(0)  # Full detection result for a single host.
    WorkflowResult: reachable(0),unreachable(0),by_env(0),summary(0),generated_redeploy_yaml(0),generated_migration_yaml(1)  # Aggregated result across all probed hosts.
    DetectionWorkflow: __init__(3),_collect_hosts(4),_probe_ssh(1),_deep_detect(1),_score_template(2),run(5)  # Multi-host detection workflow with template scoring.
  redeploy/discovery/__init__.py:
  redeploy/discovery/auto_probe.py:
    e: parse_probe_input,build_probe_command,build_ssh_command,run_ssh_probe,detect_strategy_remote,detect_app_from_services,_update_existing_from_probe,_new_device_from_probe,auto_probe
    parse_probe_input(ip_or_host;users)
    build_probe_command()
    build_ssh_command(host;port;timeout;key_opts;probe_cmd)
    run_ssh_probe(cmd;timeout)
    detect_strategy_remote(host;key;port;timeout)
    detect_app_from_services(services;app_hint)
    _update_existing_from_probe(existing;result;ssh_user;ssh_key;ip;host_str;port;now)
    _new_device_from_probe(result;ssh_user;ssh_key;ip;host_str;port;now)
    auto_probe(ip_or_host;users;port;timeout;app_hint;save)
  redeploy/discovery/helpers.py:
    e: is_raspberry_pi_mac,run_shell,is_ip
    is_raspberry_pi_mac(mac)
    run_shell(cmd;timeout)
    is_ip(value)
  redeploy/discovery/probe_parse.py:
    e: parse_probe_output,infer_strategy
    parse_probe_output(out)
    infer_strategy(info;services)
  redeploy/discovery/registry.py:
    e: update_registry,_update_existing_device,_new_discovered_device
    update_registry(hosts;registry;save)
    _update_existing_device(existing;host;now)
    _new_discovered_device(device_id;host;now)
  redeploy/discovery/scanners.py:
    e: scan_known_hosts,scan_arp_cache,scan_mdns,ping_sweep,probe_ssh_batch,detect_local_subnet,merge_hosts,discover
    scan_known_hosts(ssh_user)
    scan_arp_cache()
    scan_mdns(timeout)
    ping_sweep(subnet;timeout)
    probe_ssh_batch(hosts;users;port;timeout;max_workers)
    detect_local_subnet()
    merge_hosts(hosts)
    discover(subnet;ssh_users;ssh_port;ping;mdns;probe_ssh;timeout)
  redeploy/discovery/ssh_credentials.py:
    e: collect_ssh_keys,tcp_reachable,try_ssh_credentials
    collect_ssh_keys()
    tcp_reachable(ip;port;timeout)
    try_ssh_credentials(ip;users;keys;port;timeout)
  redeploy/discovery/types.py:
    e: DiscoveredHost,ProbeResult
    DiscoveredHost:
    ProbeResult:  # Full autonomous probe result for a single host.
  redeploy/dsl/__init__.py:
  redeploy/dsl/loader.py:
    e: _build_condition,load_css,load_css_text,_build_from_nodes,_build_manifest,_build_templates,_build_workflows,manifest_to_css,_condition_key,templates_to_css,WorkflowStep,WorkflowDef,LoadResult
    WorkflowStep: from_command(3)
    WorkflowDef: as_shell(0)  # Named deployment workflow parsed from ``workflow[name="…"] {
    LoadResult:  # Full result of loading a ``redeploy.css`` file.
    _build_condition(key;weight)
    load_css(path)
    load_css_text(text;source_file)
    _build_from_nodes(nodes;at_rules;source_file)
    _build_manifest(nodes;at_rules)
    _build_templates(nodes)
    _build_workflows(nodes)
    manifest_to_css(manifest;app)
    _condition_key(c)
    templates_to_css(templates)
  redeploy/dsl/parser.py:
    e: _strip_comments,DSLNode,RedeployDSLParser
    DSLNode: name(0),get(2),__repr__(0)  # One parsed block from the CSS-like file.
    RedeployDSLParser: __init__(0),parse(1),_collect_body(2),_parse_props(1),at_rules(0),nodes_of_type(1)  # Parse a ``redeploy.css`` or ``redeploy.less`` file into a li
    _strip_comments(text)
  redeploy/dsl_python/__init__.py:
  redeploy/dsl_python/context.py:
    e: StepContext
    StepContext: log(1),set_output(2),complete(2),duration_seconds(0)  # Tracks the execution of a single step.
  redeploy/dsl_python/decorators.py:
    e: migration,MigrationMeta,MigrationRegistry,StepManager,step
    MigrationMeta:  # Metadata for a migration.
    MigrationRegistry: register(3),get(2),list(1)  # Global registry of migration functions.
    StepManager: begin(4),end(3)  # Manages step execution and tracking.
    step: __enter__(0),__exit__(3)  # Context manager for a deployment step.
    migration(name;version;description;author)
  redeploy/dsl_python/docker_steps.py:
    e: DockerComposeResult,DockerDSL
    DockerComposeResult:  # Result of docker compose command.
    DockerDSL: compose_up(7),compose_down(4),wait_healthy(4),logs(4),_run_ssh(3),_run_local(3)  # Docker-related DSL actions.
  redeploy/dsl_python/exceptions.py:
    e: DSLException,StepError,TimeoutError,VerificationError,ConnectionError,RollbackError
    DSLException:  # Base exception for DSL errors.
    StepError: __init__(3)  # Raised when a step fails.
    TimeoutError: __init__(2)  # Raised when a step times out.
    VerificationError: __init__(3)  # Raised when verification fails.
    ConnectionError:  # Raised when SSH/connection fails.
    RollbackError: __init__(2)  # Raised when rollback fails.
  redeploy/dsl_python/runner.py:
    e: main,PythonMigrationRunner
    PythonMigrationRunner: __init__(2),run_file(2),_find_migrations(1),list_migrations(1)  # Runner for Python-based migrations.
    main()
  redeploy/dsl_python/steps.py:
    e: ssh,ssh_available,rsync,scp,wait,http_expect,version_check
    ssh(host;command;timeout;check)
    ssh_available(host;timeout;interval)
    rsync(src;dst;exclude;delete;timeout)
    scp(src;dst;timeout)
    wait(seconds;message)
    http_expect(url;expect;timeout;retries;method)
    version_check(manifest_path;expect;host;url)
  redeploy/fleet.py:
    e: DeviceArch,Stage,DeviceExpectation,FleetDevice,FleetConfig,Fleet
    DeviceArch:
    Stage:
    DeviceExpectation:  # Declarative assertions about required infrastructure on a de
    FleetDevice: ssh_user(0),ssh_ip(0),is_local(0),is_prod(0),has_tag(1),has_expectation(1),verify_expectations(1)  # Generic device descriptor — superset of ``deploy``'s DeviceC
    FleetConfig: get_device(1),by_tag(1),by_stage(1),by_strategy(1),prod_devices(0),from_file(3)  # Top-level fleet manifest — list of devices with stage / tag 
    Fleet: __init__(1),from_file(2),from_registry(2),from_config(2),devices(0),get(1),by_tag(1),by_stage(1),by_strategy(1),prod(0),reachable(1),merge(1),__len__(0),__iter__(0),__repr__(0)  # Unified first-class fleet — wraps FleetConfig and/or DeviceR
  redeploy/hardware/__init__.py:
  redeploy/hardware/config_txt.py:
    e: ensure_line,ensure_lines,ConfigEdit
    ConfigEdit:  # Result of a config.txt edit operation.
    ensure_line(content;line)
    ensure_lines(content;lines)
  redeploy/hardware/data/__init__.py:
  redeploy/hardware/data/hyperpixel.py:
  redeploy/hardware/data/official.py:
  redeploy/hardware/data/waveshare.py:
  redeploy/hardware/fixes.py:
    e: _step,_detect_port,fix_dsi_not_enabled,fix_enable_i2c,fix_enable_spi,generate_fix_plan
    _step(id;action;description;risk)
    _detect_port(hw)
    fix_dsi_not_enabled(hw;panel)
    fix_enable_i2c(hw;panel)
    fix_enable_spi(hw;panel)
    generate_fix_plan(hw;component;panel)
  redeploy/hardware/kiosk/__init__.py:
  redeploy/hardware/kiosk/autostart.py:
    e: ensure_autostart_entry,generate_labwc_autostart,AutostartEntry
    AutostartEntry: render(0)  # One entry in a compositor autostart file.
    ensure_autostart_entry(content;entry)
    generate_labwc_autostart(kiosk_script;kanshi_settle_secs;extra_entries)
  redeploy/hardware/kiosk/browsers.py:
    e: BrowserKioskProfile
    BrowserKioskProfile: build_launch_cmd(2)  # Static definition of a browser kiosk launch profile.
  redeploy/hardware/kiosk/compositors.py:
    e: CompositorDefinition
    CompositorDefinition: autostart_abs(1)  # Static definition of a Wayland compositor for kiosk use.
  redeploy/hardware/kiosk/output_profiles.py:
    e: dsi_only_profile,OutputProfile
    OutputProfile: to_kanshi_config(0)  # A kanshi output profile definition.
    dsi_only_profile(dsi_connector;hdmi_connectors;profile_name;transform)
  redeploy/hardware/panels.py:
    e: register,get,all_panels,infer_from_hardware,PanelDefinition
    PanelDefinition: overlay_line(1)  # Definition of a Raspberry Pi display panel.
    register(panel)
    get(panel_id)
    all_panels()
    infer_from_hardware(hw)
  redeploy/hardware/raspi_config.py:
    e: build_raspi_config_command
    build_raspi_config_command(interface;state)
  redeploy/heal/__init__.py:
  redeploy/heal/decider.py:
    e: decide_after_failure,format_decision_message,Action,Decision
    Action:
    Decision:
    decide_after_failure()
    format_decision_message(decision;step_id)
  redeploy/heal/hint_provider.py:
    e: _ssh,collect_diagnostics,ask_llm,_write_llm_log,apply_fix_to_spec,_extract_step_block,_parse_step_block,parse_failed_step
    _ssh(host;command)
    collect_diagnostics(host;failed_step)
    ask_llm(failed_step;step_output;diag;spec_text;fix_hint;log_dir)
    _write_llm_log(path;model;failed_step;prompt;response;error)
    apply_fix_to_spec(spec_path;failed_step;llm_response)
    _extract_step_block(spec_text;step_id)
    _parse_step_block(block)
    parse_failed_step(executor_summary;executor)
  redeploy/heal/log_writer.py:
    e: write_repair_log
    write_repair_log(spec_path;version;repairs)
  redeploy/heal/loop_detector.py:
    e: HealAbort,HealLoopDetector
    HealAbort: __init__(3)  # Raised when a heal loop is detected and retries must stop.
    HealLoopDetector: observe(2),reset(1),reset_all(0)  # Detect repeated non-converging heal hints for a given step.
  redeploy/heal/runner.py:
    e: HealRunner
    HealRunner: __init__(8),_make_executor(1),_reload_migration(0),_heal_step(2),run(0)  # Wraps :class:`Executor` with a self-healing loop.
  redeploy/heal.py:
    e: _ssh,collect_diagnostics,ask_llm,apply_fix_to_spec,write_repair_log,parse_failed_step,HealLoopDetector,HealRunner
    HealLoopDetector: __init__(1),observe(2),reset(1)  # Detect repeated non-converging heal hints for a given step.
    HealRunner: __init__(8),_make_executor(1),_reload_migration(0),_run_executor_attempt(1),_collect_diag_with_hint(1),_extract_diag_hint(1),_ask_and_apply_fix(3),_record_repair(5),_is_repeating_loop(3),_retry_after_heal(0),run(0)  # Wraps Executor with self-healing loop.
    _ssh(host;command)
    collect_diagnostics(host;failed_step)
    ask_llm(failed_step;step_output;diag;spec_text;fix_hint)
    apply_fix_to_spec(spec_path;failed_step;llm_response)
    write_repair_log(spec_path;version;repairs)
    parse_failed_step(executor_summary;executor)
  redeploy/iac/__init__.py:
  redeploy/iac/base.py:
    e: PortInfo,VolumeInfo,ServiceInfo,ConversionWarning,ParsedSpec,Parser,ParserRegistry
    PortInfo: __str__(0)  # A published / exposed port mapping.
    VolumeInfo:  # A volume or bind-mount.
    ServiceInfo:  # One logical service / container / pod / deployment.
    ConversionWarning: __str__(0)  # A warning emitted by a parser or converter about lossy / unc
    ParsedSpec: add_warning(4),all_images(0),all_ports(0),summary(0)  # Common intermediate representation from any IaC/CI-CD parser
    Parser: can_parse(1),parse(1)  # Protocol every format-specific parser must satisfy.
    ParserRegistry: __init__(0),register(1),parser_for(1),parse(1),parse_dir(3),registered(0)  # Dispatch file → registered parser.
  redeploy/iac/config_hints.py:
    e: parse_json_file,ConfigHintsParser
    ConfigHintsParser: can_parse(1),parse(1),_new_spec(3),_read_text(1),_parse_dockerfile(1),_parse_nginx(1),_looks_like_k8s(1),_parse_k8s_yaml(1),_parse_terraform(1),_parse_toml(1),_parse_vite(1),_parse_github_actions(1),_parse_gitlab_ci(1),_parse_jenkinsfile(1)  # Best-effort parser for common DevOps/IaC config files.
    parse_json_file(path)
  redeploy/iac/docker_compose.py:
    e: _resolve_var,_parse_port,_parse_volume,_env_dict,_deep_merge,DockerComposeParser
    DockerComposeParser: can_parse(1),parse(1),_load_merged(2),_find_override(1),_load_dotenv(1),_resolve_image_and_build(2),_parse_service_ports(4),_parse_service_volumes(1),_parse_service_env(2),_parse_service_env_files(1),_parse_service_networks(1),_parse_service_depends_on(1),_parse_service_healthcheck(1),_parse_service_replicas(1),_parse_service_labels(1),_parse_service_command(1),_build_service_info(0),_parse_service(4)  # Parser for docker-compose.yml / compose.yaml files.
    _resolve_var(value;env)
    _parse_port(raw)
    _parse_volume(raw)
    _env_dict(raw)
    _deep_merge(base;override)
  redeploy/iac/parsers/__init__.py:
  redeploy/iac/parsers/compose.py:
    e: DockerComposeParser
    DockerComposeParser: can_parse(1),parse(1),_collect_service_secrets(2),_merge_service_env_files(3),_collect_service_image(2),_parse_service_networks(1),_parse_service_replicas(1),_parse_service(3),_parse_build(1),_parse_command(1),_parse_ports(2),_parse_port_entry(1),_parse_volumes(2),_parse_volume_entry(1),_parse_env(2),_parse_depends_on(1),_parse_labels(1),_parse_healthcheck(1)  # Parser for Docker Compose files (v2 + v3 schema, Compose Spe
  redeploy/iac/registry.py:
    e: _load_entrypoint_parsers,_load_local_parsers,parse_file,parse_dir
    _load_entrypoint_parsers(registry)
    _load_local_parsers(registry)
    parse_file(path)
    parse_dir(root;recursive;skip_errors)
  redeploy/integrations/__init__.py:
  redeploy/integrations/op3_bridge.py:
    e: make_op3_context_from_ssh_client,snapshot_to_infra_state,snapshot_to_hardware_info,diagnostics_to_hardware_diagnostics,snapshot_to_device_map
    make_op3_context_from_ssh_client(ssh_client)
    snapshot_to_infra_state(snapshot;host)
    snapshot_to_hardware_info(snapshot)
    diagnostics_to_hardware_diagnostics(diagnostics)
    snapshot_to_device_map(snapshot;host;tags)
  redeploy/markpact/__init__.py:
  redeploy/markpact/compiler.py:
    e: compile_markpact_document,compile_markpact_document_to_data,_load_block_payload,_normalize_config_payload,_extract_steps,_deep_merge,MarkpactCompileError
    MarkpactCompileError:  # Raised when a markpact document cannot be compiled to Migrat
    compile_markpact_document(document)
    compile_markpact_document_to_data(document)
    _load_block_payload(path;block)
    _normalize_config_payload(payload;path;block)
    _extract_steps(payload;path;block)
    _deep_merge(target;incoming)
  redeploy/markpact/models.py:
    e: MarkpactBlock,MarkpactDocument
    MarkpactBlock: label(0)
    MarkpactDocument:
  redeploy/markpact/parser.py:
    e: parse_markpact_file,parse_markpact_text,_parse_markpact_fence_info,parse_markpact_file_with_refs,extract_script_by_ref,extract_script_from_markdown,_normalize_section_id,_check_heading,_handle_fence_line,resolve_script_ref,MarkpactParseError
    MarkpactParseError:  # Raised when a markdown markpact document cannot be parsed.
    parse_markpact_file(path)
    parse_markpact_text(text)
    _parse_markpact_fence_info(info)
    parse_markpact_file_with_refs(path)
    extract_script_by_ref(text;ref_id;language)
    extract_script_from_markdown(text;section_id;language)
    _normalize_section_id(section_id)
    _check_heading(line;in_target_section;normalized_id;section_id)
    _handle_fence_line(line;code_block_lang;language;script_lines)
    resolve_script_ref(md_content;ref_id;language)
  redeploy/mcp_server.py:
    e: _redeploy_bin,_run,_validate_exec_ssh_inputs,schema,plan_spec,run_spec,fix_spec,bump_version,diagnose,list_specs,exec_ssh,nlp_command,get_spec_content,get_workspace,serve
    _redeploy_bin()
    _run()
    _validate_exec_ssh_inputs(host;command)
    schema(directory)
    plan_spec(spec;cwd)
    run_spec(spec;force;dry_run;heal;fix_hint;cwd)
    fix_spec(spec_or_dir;hint;bump;retries;dry_run;cwd)
    bump_version(spec_or_dir;level;cwd)
    diagnose(host)
    list_specs(directory)
    exec_ssh(host;command)
    nlp_command(instruction;dry_run;cwd)
    get_spec_content(path)
    get_workspace()
    serve(transport;host;port)
  redeploy/models/__init__.py:
  redeploy/models/blueprint.py:
    e: ServicePort,VolumeMount,ServiceSpec,HardwareRequirements,BlueprintSource,DeviceBlueprint
    ServicePort:
    VolumeMount:
    ServiceSpec:
    HardwareRequirements:
    BlueprintSource:
    DeviceBlueprint: service(1),save(1),list_saved(1)  # Self-contained, portable deployment recipe.
  redeploy/models/devices.py:
    e: DeployRecord,KnownDevice,DeviceMap,DeviceRegistry
    DeployRecord:  # Single deployment event recorded for a device.
    KnownDevice: last_deploy(0),is_reachable(0),record_deploy(1)  # Device known to redeploy — persisted in ~/.config/redeploy/d
    DeviceMap: has_errors(0),display_summary(0),save(1),load_for(2),list_saved(1)  # Full, persisted snapshot of a device: identity + InfraState 
    DeviceRegistry: get(1),upsert(1),remove(1),by_tag(1),by_strategy(1),reachable(0),default_path(1),load(2),save(1)  # Persistent device registry — stored at ~/.config/redeploy/de
  redeploy/models/enums.py:
    e: ConflictSeverity,StepAction,StepStatus,DeployStrategy
    ConflictSeverity:
    StepAction:
    StepStatus:
    DeployStrategy:
  redeploy/models/hardware.py:
    e: DrmOutput,BacklightInfo,I2CBusInfo,HardwareDiagnostic,HardwareInfo
    DrmOutput:  # One DRM connector (e.g. card1-DSI-2, card2-HDMI-A-1).
    BacklightInfo:  # Sysfs backlight device.
    I2CBusInfo:
    HardwareDiagnostic:  # Problem found during hardware probe.
    HardwareInfo: has_dsi(0),kms_enabled(0),dsi_connected(0),dsi_physically_connected(0),dsi_enabled(0),backlight_on(0),errors(0),warnings(0)  # Hardware state produced by hardware probe.
  redeploy/models/infra.py:
    e: ServiceInfo,PortInfo,ConflictInfo,RuntimeInfo,AppHealthInfo,InfraState
    ServiceInfo:
    PortInfo:
    ConflictInfo:
    RuntimeInfo:
    AppHealthInfo:
    InfraState:  # Full detected state of infrastructure — output of `detect`.
  redeploy/models/manifest.py:
    e: EnvironmentConfig,ProjectManifest
    EnvironmentConfig:  # One named environment in redeploy.yaml.
    ProjectManifest: find_and_load(2),find_css(2),env(1),resolve_env(1),from_dotenv(2),apply_to_spec(2)  # Per-project redeploy.yaml — replaces repetitive Makefile var
  redeploy/models/persisted.py:
    e: PersistedModel
    PersistedModel: to_yaml(0),load(2)  # Mixin for models that can be persisted to/from YAML files.
  redeploy/models/pipeline.py:
    e: Hook
    Hook:  # Generyczny hook w pipeline: faza + akcja + opcjonalny warune
  redeploy/models/plan.py:
    e: MigrationStep,MigrationPlan
    MigrationStep:
    MigrationPlan:  # Full migration plan — output of `plan`, input to `apply`.
  redeploy/models/spec.py:
    e: _migrate_legacy_post_deploy,TargetConfig,InfraSpec,MigrationSpec
    TargetConfig: _accept_strategy_aliases(2)  # Desired infrastructure state — input to `plan`.
    InfraSpec:  # Declarative description of one infrastructure state (from OR
    MigrationSpec: from_file(2),resolve_versions(1),to_infra_state(0),to_target_config(0)  # Single YAML file describing full migration: from-state → to-
    _migrate_legacy_post_deploy(raw)
  redeploy/observe.py:
    e: AuditEntry,DeployAuditLog,DeployReport
    AuditEntry: __init__(1),ts(0),host(0),app(0),from_strategy(0),to_strategy(0),ok(0),elapsed_s(0),steps_total(0),steps_ok(0),steps_failed(0),pattern(0),version(0),dry_run(0),steps(0),error(0),to_dict(0),__repr__(0)  # Single audit log entry — immutable snapshot of one deploymen
    DeployAuditLog: __init__(1),record(2),_append(1),load(1),tail(1),filter(4),clear(0)  # Persistent audit log — newline-delimited JSON at ``path``.
    DeployReport: __init__(1),text(0),yaml(0),summary_line(0)  # Human-readable post-deploy report from an AuditEntry.
  redeploy/parse.py:
    e: parse_docker_ps,parse_container_line,parse_system_info,parse_diagnostics,_apply_system_line,_apply_git_line,_apply_health_line,_apply_network_line,_parse_section_line,parse_health_info
    parse_docker_ps(output)
    parse_container_line(line)
    parse_system_info(output)
    parse_diagnostics(output)
    _apply_system_line(sys;line)
    _apply_git_line(git;line)
    _apply_health_line(result;line)
    _apply_network_line(result;line)
    _parse_section_line(section;result;line)
    parse_health_info(output)
  redeploy/patterns.py:
    e: _step,get_pattern,list_patterns,DeployPattern,BlueGreenPattern,CanaryPattern,RollbackOnFailurePattern
    DeployPattern: expand(0),__repr__(0)  # Base class for all deploy patterns.
    BlueGreenPattern: __init__(7),expand(0)  # Zero-downtime blue/green deploy via Traefik (or any label-ba
    CanaryPattern: __init__(7),expand(0)  # Gradual canary rollout: deploy new version, scale up in stag
    RollbackOnFailurePattern: __init__(5),expand(0)  # Capture pre-deploy image tag, roll back automatically on fai
    _step(id;action;description)
    get_pattern(name)
    list_patterns()
  redeploy/plan/__init__.py:
  redeploy/plan/planner.py:
    e: Planner
    Planner: __init__(2),run(0),_plan_conflict_fixes(0),_plan_stop_old_services(0),_plan_deploy_new(0),_plan_docker_full(0),_plan_podman_quadlet(0),_plan_kiosk(1),_plan_kiosk_appliance(0),_plan_systemd(0),_plan_pattern(0),_plan_verify(0),_compose_cmd(0),_compose_file(0),_add_step(1),_assess_risk(0),_estimate_downtime(0),from_files(2),from_spec(1),_append_extra_steps(1),save(2)  # Generate a MigrationPlan from detected infra + desired targe
  redeploy/plugins/__init__.py:
    e: register_plugin,_load_builtin_plugins,load_user_plugins,PluginContext,PluginRegistry
    PluginContext:  # Passed to every plugin handler.
    PluginRegistry: __init__(0),register(2),__call__(1),get(1),names(0),_ensure_builtins(0),load_directory(1)  # Central registry mapping plugin_type strings to handler call
    register_plugin(name)
    _load_builtin_plugins()
    load_user_plugins()
  redeploy/plugins/builtin/__init__.py:
  redeploy/plugins/builtin/browser_reload.py:
    e: browser_reload,_cdp_reload_script,_sh_quote
    browser_reload(ctx)
    _cdp_reload_script(port;ws_path;ignore_cache)
    _sh_quote(s)
  redeploy/plugins/builtin/hardware_diagnostic.py:
    e: _run_command,_detect_platform,_get_cpu_info,_get_memory_mb,_get_storage_gb,_check_gpio,_get_usb_devices,_get_audio_devices,_get_network_interfaces,_analyze_hardware,hardware_diagnostic,HardwareInfo
    HardwareInfo:  # Hardware diagnostic information.
    _run_command(cmd)
    _detect_platform()
    _get_cpu_info()
    _get_memory_mb()
    _get_storage_gb()
    _check_gpio()
    _get_usb_devices()
    _get_audio_devices()
    _get_network_interfaces()
    _analyze_hardware(platform;verbose)
    hardware_diagnostic(ctx)
  redeploy/plugins/builtin/notify.py:
    e: notify,_notify_slack,_notify_webhook,_http_post,_http_get,_resolve_env,_fmt
    notify(ctx)
    _notify_slack(ctx)
    _notify_webhook(ctx)
    _http_post(ctx;url;payload;headers)
    _http_get(ctx;url;headers)
    _resolve_env(value)
    _fmt(template;ctx)
  redeploy/plugins/builtin/process_control.py:
    e: _find_pid_on_port,_kill_process,process_control
    _find_pid_on_port(port)
    _kill_process(pid;force)
    process_control(ctx)
  redeploy/plugins/builtin/systemd_reload.py:
    e: systemd_reload,_wait_for_active
    systemd_reload(ctx)
    _wait_for_active(ctx;unit;timeout)
  redeploy/schema.py:
    e: _parse_spec_meta,_discover_specs,_read_version,_git_branch,_iac_info,build_schema
    _parse_spec_meta(path)
    _discover_specs(root;max_specs)
    _read_version(root)
    _git_branch(root)
    _iac_info()
    build_schema(root)
  redeploy/spec_loader.py:
    e: load_migration_spec,SpecLoaderError,UnsupportedSpecFormatError
    SpecLoaderError:  # Base error raised when a deployment spec cannot be loaded.
    UnsupportedSpecFormatError:  # Raised when the spec file uses an unsupported format.
    load_migration_spec(path)
  redeploy/ssh.py:
    e: SshResult,SshClient,RemoteProbe,RemoteExecutor
    SshResult: ok(0),success(0),out(0)
    SshClient: __init__(4),key(0),key(1),run(2),rsync(5),scp(3),put_file(3),is_reachable(1),is_ssh_ready(0),ping(0),_run_local(2),_ssh_opts(0),_scp_opts(0),_detect_ssh_key(0),_detect_key(0)  # Execute commands on a remote host via SSH (or locally).
    RemoteProbe: __init__(1),is_local(0),is_local(1)  # Thin wrapper kept for redeploy.detect compatibility.
    RemoteExecutor: __init__(1),ssh_target(0),ssh_opts(0),scp_opts(0)  # Thin wrapper kept for deploy.core compatibility.
  redeploy/steps/__init__.py:
    e: StepLibrary
    StepLibrary: get(1),list(0),all(0),resolve_from_spec(1)  # Registry of pre-defined named MigrationSteps.
  redeploy/steps/docker.py:
    e: _step
    _step(id;action;description)
  redeploy/steps/generic.py:
    e: _step
    _step(id;action;description)
  redeploy/steps/hardware.py:
    e: _step
    _step(id;action;description)
  redeploy/steps/k3s.py:
    e: _step
    _step(id;action;description)
  redeploy/steps/kiosk.py:
  redeploy/steps/podman.py:
    e: _step
    _step(id;action;description)
  redeploy/steps/process.py:
    e: _step
    _step(id;action;description)
  redeploy/steps/scm.py:
    e: _step
    _step(id;action;description)
  redeploy/steps/transfer.py:
    e: _step
    _step(id;action;description)
  redeploy/tests/__init__.py:
  redeploy/tests/test_analyze.py:
    e: _spec_with_steps,TestDockerBuildChecker,TestIgnoreList,TestEnsureRedeployignore,TestSpecAnalyzerIntegration
    TestDockerBuildChecker: test_missing_dockerfile_error(1),test_standard_dockerfile_ok(1),test_nonstandard_dockerfile_warning(1),test_context_mismatch_with_sync_dest(1),test_context_matches_sync_dest_no_warning(1)
    TestIgnoreList: test_simple_filename_pattern(1),test_directory_pattern(1),test_gitignore_and_redeployignore_combined(1),test_missing_ignore_files(1)
    TestEnsureRedeployignore: test_creates_file_when_missing(1),test_does_not_overwrite_existing(1)
    TestSpecAnalyzerIntegration: test_analyze_file_markpact(1),test_ignored_files_not_reported_as_missing(1)
    _spec_with_steps(extra_steps)
  redeploy/tests/test_audit.py:
    e: _spec,TestExtractor,TestExtractPort,_FakeProbe,TestAuditor,TestReport,TestAuditSpec
    TestExtractor: test_strategy_binaries_for_podman(0),test_target_remote_dir_emits_directory(0),test_verify_url_emits_port(0),test_extra_step_podman_build_image(0),test_extra_step_apt_install(0),test_rsync_dst_emits_directory(0),test_dedup(0)
    TestExtractPort: test_cases(2)
    _FakeProbe: __init__(0),has_binary(1),has_path(2),port_listening(1),has_image(1),has_systemd_unit(2),apt_package(1),disk_free_gib(1)  # Replaces Auditor.probe with a scriptable fake.
    TestAuditor: test_unreachable_short_circuits(0),test_all_pass(0),test_missing_binary_fails(0),test_low_disk_fails(0),test_image_missing_is_warn_not_fail(0)
    TestReport: test_summary_counts(0),test_to_dict_serializable(0)
    TestAuditSpec: test_loads_yaml_spec(2)
    _spec()
  redeploy/tests/test_cli.py:
    e: _migration_yaml,_migration_markdown_supported,_migration_markdown_with_unsupported_block,_runner,TestRunPlanOnly,TestStatus,TestInit,TestDevices,TestTarget,TestApply
    TestRunPlanOnly: test_plan_only_exit_zero(1),test_plan_only_shows_steps(1),test_plan_only_missing_spec_exits_1(1),test_plan_only_k3s_to_docker(1),test_plan_only_saves_plan_out(1),test_run_dry_run(1),test_env_unknown_warns(1),test_env_prod_applied_from_manifest(1),test_run_plan_only_supports_markdown_subset(1),test_run_plan_only_rejects_unsupported_markdown_block(1)
    TestStatus: test_status_no_manifest(1),test_status_with_manifest(1),test_status_supports_markdown_subset(1)
    TestInit: test_init_creates_migration_yaml(1),test_init_idempotent(1)
    TestDevices: test_devices_empty_registry(0),test_devices_lists_known(0),test_devices_filter_by_tag(0),test_devices_json_output(0)
    TestTarget: test_target_supports_markdown_subset(1)
    TestApply: _plan_file(2),test_apply_dry_run(1),test_apply_unknown_step_id(1)
    _migration_yaml(strategy;host)
    _migration_markdown_supported()
    _migration_markdown_with_unsupported_block()
    _runner()
  redeploy/tests/test_data_sync.py:
    e: TestCollectSqliteCounts,TestRsyncTimeoutForPath
    TestCollectSqliteCounts: _db(3),test_basic_counts(1),test_missing_db_skipped(1),test_missing_table_skipped(1),test_empty_table(1),test_multiple_dbs(1),test_empty_specs(1),test_large_row_count(1)
    TestRsyncTimeoutForPath: _file(2),test_minimum_respected(1),test_scales_with_size(1),test_custom_minimum(1),test_custom_per_mb(1),test_base_added(1),test_returns_int(1)
  redeploy/tests/test_devices_display.py:
    e: _device,TestFilterDevices
    TestFilterDevices: test_filter_by_tag(0),test_filter_rpi(0)
    _device()
  redeploy/tests/test_discovery.py:
    e: TestIsIp,TestMerge,TestScanKnownHosts,TestUpdateRegistry
    TestIsIp: test_valid_ipv4(0),test_hostname_not_ip(0),test_partial_ip_not_ip(0),test_empty_string(0),test_ipv6_not_matched(0)
    TestMerge: test_deduplicates_by_ip(0),test_merges_mac_from_second(0),test_merges_hostname_from_second(0),test_existing_hostname_not_overwritten(0),test_ssh_ok_propagates(0),test_distinct_ips_kept_separate(0),test_empty_list(0),test_source_updated_from_unknown(0),test_known_source_not_overwritten(0)
    TestScanKnownHosts: _results(2),test_parses_plain_host(1),test_skips_hashed_entries(1),test_skips_comment_lines(1),test_missing_known_hosts_returns_empty(1),test_ip_address_entry(1),test_bracketed_port_format(1)  # _scan_known_hosts uses __import__('pathlib').Path.home() int
    TestUpdateRegistry: _empty_reg(0),test_adds_ssh_ok_device(0),test_does_not_add_non_ssh_device(0),test_updates_existing_device_last_seen(0),test_updates_existing_mac(0),test_device_id_uses_user_at_ip(0),test_device_id_without_user_uses_ip(0),test_discovered_tag_added(0),test_skips_device_with_empty_ip(0),test_multiple_hosts(0)
  redeploy/tests/test_discovery_probe.py:
    e: TestParseProbeOutput,TestInferStrategy
    TestParseProbeOutput: test_parses_metadata_and_services(0)
    TestInferStrategy: test_docker_full_when_docker_active(0),test_podman_quadlet(0),test_native_kiosk(0),test_systemd_fallback(0)
  redeploy/tests/test_dsl.py:
    e: parse,test_nodes_of_type,test_manifest_to_css_roundtrip,test_templates_to_css,test_load_css_file,TestDSLNode,TestAtRules,TestBlocks,TestComments,TestLoadCssText
    TestDSLNode: test_name_from_name_attr(0),test_name_from_id_attr(0),test_get_default(0),test_get_existing(0),test_repr(0)
    TestAtRules: test_app_at_rule(0),test_multiple_at_rules(0),test_at_rules_dict(0)
    TestBlocks: test_environment_block(0),test_template_block(0),test_workflow_block(0),test_app_block(0),test_empty_block(0),test_multiple_blocks(0)
    TestComments: test_line_comment_before_block_becomes_doc(0),test_block_comment_stripped(0),test_inline_comment_in_body_ignored(0)
    TestLoadCssText: test_manifest_app(0),test_manifest_environments(0),test_templates(0),test_workflows(0),test_workflow_as_shell(0),test_no_manifest_when_empty(0),test_raw_nodes(0)
    parse(text)
    test_nodes_of_type()
    test_manifest_to_css_roundtrip()
    test_templates_to_css()
    test_load_css_file(tmp_path)
  redeploy/tests/test_examples.py:
    e: _load_spec,_plan_from_spec,TestMigrationYaml,TestSupportedMarkdownMigration,TestRedeployYaml,TestMultienvYamls,TestScenario01VpsVersionBump,TestScenario02K3sToDocker,TestScenario03DockerToQuadlet,TestScenario07StagingToProd,TestScenario08Rollback,TestFleetYaml,TestScenario09FleetYaml,TestStepLibraryCompleteness,TestScenario10Multienv,TestScenario11TraefikTls,TestScenario12CiPipeline,TestScenario13Monorepo
    TestMigrationYaml: test_parses_without_error(1),test_has_source_and_target(1),test_plan_generates_steps(1),test_plan_has_no_duplicate_step_ids(1),test_all_steps_have_valid_action(1),test_has_readme(1),test_readme_has_run_section(1),test_has_redeploy_yaml(1)
    TestSupportedMarkdownMigration: test_parses_without_error(1),test_plan_generates_steps(1),test_has_readme(1),test_readme_has_run_section(1)
    TestRedeployYaml: test_parses_as_yaml(1),test_has_app_field(1),test_spec_field_points_to_existing_file_or_env_spec(1)
    TestMultienvYamls: test_parses_without_error(1),test_plan_generates_steps(1),test_same_app_across_envs(1),test_same_version_across_envs(1)
    TestScenario01VpsVersionBump: _spec(0),test_same_strategy(0),test_version_bumped(0),test_plan_has_health_check(0),test_plan_has_version_check(0),test_flush_iptables_in_plan(0),test_flush_iptables_resolved_from_library(0)
    TestScenario02K3sToDocker: _spec(0),test_strategy_change(0),test_plan_has_stop_k3s(0),test_plan_has_disable_k3s(0),test_plan_has_docker_compose_up(0),test_plan_risk_is_medium_or_higher(0)
    TestScenario03DockerToQuadlet: _spec(0),test_strategy_change(0),test_plan_has_daemon_reload(0),test_plan_has_wait(0),test_extra_steps_present(0)
    TestScenario07StagingToProd: _spec(0),test_insert_before_smoke_test(0),test_notify_steps_present(0)
    TestScenario08Rollback: _spec(0),test_version_goes_down(0),test_plan_has_version_check(0)
    TestFleetYaml: test_parses_without_error(1),test_all_devices_have_id(1),test_all_devices_have_stage(1),test_all_devices_have_expectations(1)
    TestScenario09FleetYaml: _config(0),test_prod_devices_have_no_k3s_expectation(0),test_by_tag(0),test_by_stage(0),test_local_device_has_no_ssh_host(0),test_iot_node_has_disk_ok_expectation(0),test_has_readme(0)
    TestStepLibraryCompleteness: test_all_named_steps_in_examples_are_in_library(0),test_library_step_commands_are_non_empty(0),test_library_has_expected_ids(0),test_named_steps_checked_in_all_spec_yamls(0)
    TestScenario10Multienv: test_all_three_specs_exist(0),test_redeploy_yaml_has_local_spec(0),test_prod_has_domain(0),test_dev_host_is_local(0),test_staging_has_different_host_than_prod(0)
    TestScenario11TraefikTls: _dir(0),test_tls_yml_exists(0),test_tls_yml_has_cert_and_key(0),test_plan_has_recreate_traefik(0),test_plan_has_upload_steps(0)
    TestScenario12CiPipeline: _dir(0),test_github_workflow_exists(0),test_gitlab_ci_exists(0),test_github_workflow_has_redeploy_run(0),test_gitlab_ci_has_redeploy_run(0),test_github_workflow_has_ssh_key_secret(0),test_plan_has_audit_step(0)
    TestScenario13Monorepo: _dir(0),test_has_fleet_yaml(0),test_fleet_has_three_envs(0),test_fleet_prod_has_traefik_expectation(0),test_plan_has_rsync_steps(0),test_plan_has_promote_compose(0)
    _load_spec(path)
    _plan_from_spec(spec)
  redeploy/tests/test_executor.py:
    e: _make_step,_make_plan,_executor,TestDryRun,TestExecutorRun,TestRunSsh,TestRunScp,TestRunRsync,TestRunHttpCheck,TestRunVersionCheck,TestRunWait,TestRollback,TestExecutorFromFile,TestRunDockerBuild,TestRunDockerHealthWait,TestRunContainerLogTail,TestRunWait,TestRunInlineScript
    TestDryRun: test_dry_run_returns_true(0),test_dry_run_marks_steps_done(0),test_dry_run_does_not_call_probe(0)
    TestExecutorRun: test_all_steps_pass(0),test_step_failure_stops_execution(0),test_unknown_action_raises_step_error(0),test_summary_all_done(0),test_summary_with_failure(0)
    TestRunSsh: test_success(0),test_no_command_raises(0),test_result_stored(0),test_uses_step_timeout(0)
    TestRunScp: test_local_scp_uses_cp(0),test_remote_scp(0),test_scp_missing_src_fails(0),test_scp_failure_propagates(0)
    TestRunRsync: test_local_rsync(0),test_remote_rsync_prefixes_host(0),test_rsync_failure_propagates(0)
    TestRunHttpCheck: _http_step(2),test_success_no_expect(0),test_success_with_expect(0),test_missing_url_fails(0),test_retries_then_fails(0),test_expect_found_in_output(0)
    TestRunVersionCheck: test_version_found(0),test_version_not_found_fails(0),test_curl_failure_fails(0),test_missing_url_or_expect_fails(0)
    TestRunWait: test_wait_calls_sleep(0),test_zero_seconds(0)
    TestRollback: test_rollback_called_on_failure(0),test_no_rollback_without_rollback_command(0),test_dry_run_no_rollback(0)
    TestExecutorFromFile: test_save_results(1)
    TestRunDockerBuild: test_success_logs_progress(0),test_build_failure_raises(0),test_no_command_raises(0)
    TestRunDockerHealthWait: test_all_healthy_immediately(0),test_timeout_does_not_fail(0),test_no_command_raises(0)
    TestRunContainerLogTail: test_logs_fetched_and_stored(0),test_empty_output_handled(0)
    TestRunWait: test_zero_seconds(0),test_positive_seconds(0)
    TestRunInlineScript: test_multiline_script_success(0),test_script_failure_raises(0),test_no_command_raises(0),test_uses_step_timeout(0),test_command_ref_resolves_from_markdown(1),test_command_ref_missing_section_fails(1)
    _make_step(step_id;action;command)
    _make_plan(steps;host)
    _executor(plan;dry_run)
  redeploy/tests/test_fleet.py:
    e: TestFleetDevice,TestStageDefaults,TestFleetConfigFromFile,TestStepLibrary,TestTargetConfigHost,TestFleet
    TestFleetDevice: test_basic(0),test_local_device(0),test_is_prod_via_stage(0),test_is_prod_via_tag(0),test_has_tag(0),test_has_expectation(0),test_verify_expectations_pass(0),test_verify_expectations_fail_docker(0),test_verify_expectations_no_k3s_fail(0)
    TestStageDefaults: test_prod_has_no_k3s(0),test_local_minimal(0)
    TestFleetConfigFromFile: test_load_deploy_fleet_yaml(1),test_by_tag(1),test_by_strategy(1)
    TestStepLibrary: test_list(0),test_get_known(0),test_get_unknown(0),test_get_with_overrides(0),test_get_returns_copy(0),test_resolve_from_spec_with_library_match(0),test_resolve_from_spec_override_action(0),test_resolve_from_spec_unknown_uses_raw(0),test_all_returns_copies(0),test_new_steps_registered(0),test_stop_podman_has_rollback(0),test_git_pull_has_rollback(0),test_systemctl_restart_action(0),test_systemctl_daemon_reload_command(0),test_enable_podman_unit_command(0)
    TestTargetConfigHost: _make_planner(2),test_uses_state_host_when_target_host_none(0),test_target_host_overrides_state_host(0),test_app_fallback_from_state(0),test_target_app_used_when_set(0)
    TestFleet: _yaml(2),test_from_file_basic(1),test_from_file_iter(1),test_by_tag(1),test_by_stage(1),test_by_strategy(1),test_prod_shortcut(1),test_merge_other_wins(1),test_from_registry_empty(1),test_from_registry_converts_known_device(1),test_from_config_wraps_fleet_config(1),test_repr(1)
  redeploy/tests/test_git_integration.py:
    e: _config,_ok,_fail,TestGitIntegrationRun,TestCleanState,TestCommit,TestTag,TestPush,TestQueryMethods,TestGitVersionBumpTransaction
    TestGitIntegrationRun: test_success(1),test_raises_on_called_process_error(1),test_raises_when_git_not_found(1),test_check_false_does_not_raise_on_nonzero(1)
    TestCleanState: test_require_clean_passes_on_empty_output(1),test_require_clean_raises_on_dirty(1),test_is_clean_true_when_empty(1),test_is_clean_false_when_dirty(1),test_get_dirty_files_empty(1),test_get_dirty_files_returns_paths(1)
    TestCommit: test_commit_uses_message_format(1),test_commit_returns_hash(1),test_commit_stages_files(1)
    TestTag: test_tag_name_uses_format(1),test_tag_default_format_v_prefix(1),test_tag_with_sign(1),test_tag_without_sign(1),test_tag_exists_true(1),test_tag_exists_false(1)
    TestPush: test_push_with_follow_tags(1),test_push_without_follow_tags(1)
    TestQueryMethods: test_get_last_tag(1),test_get_last_tag_none_when_no_tags(1),test_get_commits_since(1),test_get_commits_since_empty(1),test_get_current_branch(1)
    TestGitVersionBumpTransaction: _manifest(2),test_prepare_stages_files(1),test_prepare_fails_on_dirty_when_require_clean(1),test_prepare_bypasses_dirty_with_allow_dirty(1),test_commit_and_tag_returns_result(1),test_rollback_cleans_staged_files(1),test_push_calls_git_push(1),test_git_transaction_result_fields(0)
    _config()
    _ok(stdout;stderr)
    _fail(stdout;stderr)
  redeploy/tests/test_heal.py:
    e: test_loop_detector_triggers_on_identical_hint_streak,test_loop_detector_does_not_trigger_for_varying_hints,test_loop_detector_tracks_each_step_independently,test_loop_detector_reset_clears_step_history,test_heal_runner_stops_on_repeating_hint_pattern,test_heal_runner_reverts_invalid_llm_patch_without_crash,test_heal_runner_skip_marks_state_and_resumes
    test_loop_detector_triggers_on_identical_hint_streak()
    test_loop_detector_does_not_trigger_for_varying_hints()
    test_loop_detector_tracks_each_step_independently()
    test_loop_detector_reset_clears_step_history()
    test_heal_runner_stops_on_repeating_hint_pattern(monkeypatch;tmp_path)
    test_heal_runner_reverts_invalid_llm_patch_without_crash(monkeypatch;tmp_path)
    test_heal_runner_skip_marks_state_and_resumes(monkeypatch;tmp_path)
  redeploy/tests/test_heal_decider.py:
    e: test_decide_abort_on_loop_detected,test_decide_abort_when_failed_step_unknown,test_decide_retry_on_transient_llm_error_before_limit,test_decide_abort_on_llm_error_at_retry_limit,test_decide_abort_when_retry_budget_exhausted,test_decide_retry_when_spec_was_patched,test_decide_skip_when_patch_not_applicable,test_format_decision_message_uses_action_and_reason
    test_decide_abort_on_loop_detected()
    test_decide_abort_when_failed_step_unknown()
    test_decide_retry_on_transient_llm_error_before_limit()
    test_decide_abort_on_llm_error_at_retry_limit()
    test_decide_abort_when_retry_budget_exhausted()
    test_decide_retry_when_spec_was_patched()
    test_decide_skip_when_patch_not_applicable()
    test_format_decision_message_uses_action_and_reason()
  redeploy/tests/test_hooks.py:
    e: _plan,test_legacy_post_deploy_is_migrated_to_hooks,test_executor_fires_hook_phases_on_success,test_executor_fires_failure_hooks
    _plan()
    test_legacy_post_deploy_is_migrated_to_hooks(tmp_path)
    test_executor_fires_hook_phases_on_success(monkeypatch)
    test_executor_fires_failure_hooks(monkeypatch)
  redeploy/tests/test_iac.py:
    e: _write,test_parse_file,test_parse_dir,test_parse_dir_skip_errors,test_warning_str_with_location,test_warning_str_no_location,TestCanParse,TestDockerComposeParse,TestParserRegistry
    TestCanParse: _p(1),test_canonical_names(0),test_override_files(0),test_rejects_other_yaml(0)
    TestDockerComposeParse: _parse(2),test_empty_file(1),test_single_service_image(1),test_service_with_build(1),test_service_build_context_dict(1),test_ports_string_form(1),test_ports_no_host(1),test_ports_with_protocol(1),test_ports_long_form(1),test_volumes_named(1),test_volumes_bind_mount(1),test_volumes_read_only(1),test_env_dict(1),test_env_list(1),test_depends_on_list(1),test_depends_on_dict(1),test_networks(1),test_secrets_referenced(1),test_healthcheck_list(1),test_labels_dict(1),test_labels_list(1),test_command_string(1),test_command_list(1),test_restart_policy(1),test_replicas_from_deploy(1),test_version_hint(1),test_multiple_services(1),test_all_images_deduped(1),test_summary(1),test_corrupt_top_level(1)
    TestParserRegistry: test_registered(0),test_parser_for_compose(1),test_parser_for_unknown(1),test_parse_raises_for_unknown(1)
    _write(tmp_path;name;content)
    test_parse_file(tmp_path)
    test_parse_dir(tmp_path)
    test_parse_dir_skip_errors(tmp_path)
    test_warning_str_with_location()
    test_warning_str_no_location()
  redeploy/tests/test_iac_compose_contract.py:
    e: test_compose_parse_contract_golden
    test_compose_parse_contract_golden(tmp_path)
  redeploy/tests/test_iac_docker_compose_contract.py:
    e: test_docker_compose_parser_service_contract
    test_docker_compose_parser_service_contract(tmp_path)
  redeploy/tests/test_manifest.py:
    e: _spec,_manifest,TestFindAndLoad,TestFromDotenv,TestResolveEnv,TestApplyToSpec,TestDeviceRegistry,TestKnownDevice
    TestFindAndLoad: test_finds_in_cwd(1),test_finds_in_parent(1),test_returns_none_when_missing(1),test_parses_environments(1)
    TestFromDotenv: test_reads_deploy_vars(1),test_returns_none_without_deploy_vars(1),test_returns_none_when_no_dotenv(1),test_strips_quotes(1),test_skips_comment_lines(1),test_reads_ssh_key(1)
    TestResolveEnv: _manifest_with_envs(0),test_returns_env_with_overrides(0),test_falls_back_to_manifest_defaults(0),test_unknown_env_returns_base(0),test_env_file_overridden(0),test_global_env_returns_manifest_defaults(0)
    TestApplyToSpec: test_sets_host(0),test_sets_domain_when_unset(0),test_does_not_override_existing_domain(0),test_sets_env_file(0),test_env_name_applied(0),test_env_strategy_applied(0),test_invalid_strategy_ignored(0)
    TestDeviceRegistry: _reg(0),_device(1),test_get_returns_device(0),test_get_returns_none_for_missing(0),test_upsert_adds_new(0),test_upsert_updates_existing(0),test_remove(0),test_remove_missing_returns_false(0),test_by_tag(0),test_by_strategy(0),test_save_and_load(1),test_load_missing_returns_empty(1)
    TestKnownDevice: _device(0),test_is_reachable_recent(0),test_is_reachable_old(0),test_is_reachable_none(0),test_last_deploy_none_when_empty(0),test_record_deploy(0),test_record_deploy_capped_at_50(0)
    _spec()
    _manifest()
  redeploy/tests/test_markpact_compiler.py:
    e: test_compile_markpact_document_yaml_subset_to_spec,test_compile_markpact_document_supports_toml_config_and_steps,test_compile_markpact_document_rejects_unsupported_block_kind,test_compile_markpact_document_rejects_unsupported_step_keys
    test_compile_markpact_document_yaml_subset_to_spec()
    test_compile_markpact_document_supports_toml_config_and_steps()
    test_compile_markpact_document_rejects_unsupported_block_kind()
    test_compile_markpact_document_rejects_unsupported_step_keys()
  redeploy/tests/test_markpact_parser.py:
    e: test_parse_markpact_text_extracts_blocks_and_lines,test_parse_markpact_text_requires_markpact_blocks,test_extract_script_by_ref_markpact_ref,test_extract_script_by_ref_not_found,test_parse_markpact_text_with_ref_id
    test_parse_markpact_text_extracts_blocks_and_lines()
    test_parse_markpact_text_requires_markpact_blocks()
    test_extract_script_by_ref_markpact_ref()
    test_extract_script_by_ref_not_found()
    test_parse_markpact_text_with_ref_id()
  redeploy/tests/test_models.py:
    e: _make_state,test_plan_k3s_to_docker_generates_stop_k3s,test_plan_no_conflicts_no_stop_k3s,test_plan_risk_elevated_when_stop_steps,test_plan_downtime_rolling_when_same_strategy,test_plan_downtime_includes_seconds_for_cross_strategy,test_infra_state_serializes,_make_spec,test_spec_to_infra_state,test_spec_to_target_config,test_planner_from_spec_generates_steps,test_planner_from_spec_appends_notes,test_planner_from_spec_extra_steps,test_spec_roundtrip_yaml,test_migration_plan_step_count_sane
    _make_state(strategy;conflicts;k3s;docker)
    test_plan_k3s_to_docker_generates_stop_k3s()
    test_plan_no_conflicts_no_stop_k3s()
    test_plan_risk_elevated_when_stop_steps()
    test_plan_downtime_rolling_when_same_strategy()
    test_plan_downtime_includes_seconds_for_cross_strategy()
    test_infra_state_serializes()
    _make_spec(from_strategy;to_strategy;extra_steps)
    test_spec_to_infra_state()
    test_spec_to_target_config()
    test_planner_from_spec_generates_steps()
    test_planner_from_spec_appends_notes()
    test_planner_from_spec_extra_steps()
    test_spec_roundtrip_yaml(tmp_path)
    test_migration_plan_step_count_sane()
  redeploy/tests/test_observe.py:
    e: _plan,_step,test_public_api_all_importable,test_executor_writes_audit,test_executor_audit_disabled,TestAuditEntry,TestDeployAuditLog,TestDeployReport
    TestAuditEntry: _entry(0),test_accessors_ok(0),test_accessor_failed(0),test_pattern_none(0),test_pattern_set(0),test_to_dict_roundtrip(0),test_repr_ok(0),test_repr_fail(0)
    TestDeployAuditLog: _log(1),test_empty_load(1),test_record_creates_file(1),test_record_ok_entry(1),test_record_failed_entry(1),test_record_dry_run(1),test_load_after_record(1),test_tail(1),test_filter_by_ok(1),test_filter_by_host(1),test_filter_by_app(1),test_filter_by_since(1),test_clear(1),test_file_is_jsonl(1),test_corrupt_line_skipped(1),test_creates_parent_dirs(1)
    TestDeployReport: _entry(1),test_text_contains_host(0),test_text_contains_result_success(0),test_text_contains_result_failed(0),test_text_contains_step_ids(0),test_text_shows_strategy(0),test_text_elapsed(0),test_text_pattern_shown(0),test_text_no_pattern_line_when_none(0),test_yaml_output(0),test_summary_line_ok(0),test_summary_line_fail(0),test_dry_run_in_text(0)
    _plan(host;app)
    _step(id;status)
    test_public_api_all_importable()
    test_executor_writes_audit(tmp_path)
    test_executor_audit_disabled(tmp_path)
  redeploy/tests/test_parse.py:
    e: TestParseDockerPs,TestParseContainerLine,TestParseSystemInfo,TestParseDiagnostics,TestParseHealthInfo
    TestParseDockerPs: _out(0),test_returns_list(0),test_count(0),test_name(0),test_image(0),test_status(0),test_state(0),test_empty_output(0),test_no_prefix_line_skipped(0),test_partial_line_two_parts(0),test_multiple_containers(0)
    TestParseContainerLine: test_full_line(0),test_two_parts(0),test_single_part_returns_none(0),test_empty_string_returns_none(0)
    TestParseSystemInfo: _out(0),test_hostname(0),test_uptime(0),test_load(0),test_kernel(0),test_cpu_cores(0),test_disk_parsed(0),test_memory_parsed(0),test_empty_output(0),test_unknown_lines_ignored(0)
    TestParseDiagnostics: _diag(0),test_system_hostname(0),test_system_disk(0),test_containers_count(0),test_container_names(0),test_git_branch(0),test_git_commit(0),test_health_code(0),test_listening_ports(0),test_empty_output_defaults(0),test_no_prefix_lines_skipped(0),test_invalid_health_code_ignored(0),test_docker_section_alias(0)
    TestParseHealthInfo: _out(0),test_hostname(0),test_uptime(0),test_health_code(0),test_disk(0),test_load(0),test_empty_output_defaults(0),test_invalid_health_ignored(0),test_unknown_lines_ignored(0)
  redeploy/tests/test_patterns.py:
    e: test_list_patterns,test_get_pattern_known,test_get_pattern_unknown,test_pattern_registry_keys,TestBlueGreen,TestCanary,TestRollbackOnFailure,TestPlannerPatternIntegration
    TestBlueGreen: _pattern(0),test_expand_returns_steps(0),test_step_ids_present(0),test_with_env_file_adds_scp_step(0),test_without_env_file_no_scp(0),test_green_dir_suffix(0),test_swap_step_has_rollback(0),test_deploy_step_timeout(0),test_all_steps_pending(0),test_repr(0)
    TestCanary: _pattern(0),test_expand_returns_steps(0),test_default_stages(0),test_health_check_per_stage(0),test_wait_between_stages(0),test_no_wait_when_zero(0),test_promote_step_present(0),test_promote_has_rollback(0),test_canary_clone_step(0),test_custom_suffix(0),test_retire_old_step(0)
    TestRollbackOnFailure: _pattern(0),test_expand_returns_steps(0),test_step_ids(0),test_snapshot_step_tees_to_file(0),test_custom_snapshot_file(0),test_deploy_step_has_rollback(0),test_cleanup_is_last(0)
    TestPlannerPatternIntegration: _make_state(0),test_blue_green_via_planner(0),test_canary_via_planner(0),test_rollback_pattern_via_planner(0),test_unknown_pattern_falls_back(0),test_no_pattern_uses_standard_deploy(0),test_pattern_config_passed_through(0)
    test_list_patterns()
    test_get_pattern_known()
    test_get_pattern_unknown()
    test_pattern_registry_keys()
  redeploy/tests/test_plan_apply_report.py:
    e: _migration_with_sync,TestBuildChecksumVerification,TestRenderMarkdownReport,TestStepCommandBlock
    TestBuildChecksumVerification: test_skipped_when_no_sync_step(0),test_skipped_plan_only(0)
    TestRenderMarkdownReport: test_includes_step_logs(0)
    TestStepCommandBlock: test_rsync(0)
    _migration_with_sync()
  redeploy/tests/test_plan_apply_shared.py:
    e: TestEnsureRedeployignore
    TestEnsureRedeployignore: test_creates_file_when_missing(1),test_does_not_overwrite_existing(1)
  redeploy/tests/test_planner_edge.py:
    e: _state,_target,_infra_spec,_plan,TestStepOrdering,TestInsertBefore,TestRiskEscalation,TestVerifySteps,TestK3sConflictFixes,TestPodmanQuadletPlanning,TestNotesAndMetadata,TestPlannerFromSpec
    TestStepOrdering: test_first_step_is_not_verify(0),test_last_steps_are_verify(0),test_wait_appears_before_health_check(0),test_sync_env_before_docker_build(0)
    TestInsertBefore: test_extra_step_appended_at_end_without_insert_before(0),test_insert_before_places_step_correctly(0),test_multiple_extra_steps_order_preserved(0)
    TestRiskEscalation: test_k3s_to_docker_risk_elevated_with_conflict(0),test_same_strategy_bump_low_risk(0),test_podman_quadlet_target_risk(0)
    TestVerifySteps: test_no_verify_url_no_http_check(0),test_verify_url_produces_http_check(0),test_verify_version_produces_version_check(0),test_no_duplicate_verify_steps(0)
    TestK3sConflictFixes: _k3s_state_with_conflict(0),test_stop_k3s_generated_for_k3s_source(0),test_stop_k3s_not_generated_for_docker_source(0),test_stop_k3s_before_docker_compose_up(0)
    TestPodmanQuadletPlanning: test_podman_daemon_reload_in_plan(0),test_docker_compose_down_before_podman_start(0)
    TestNotesAndMetadata: test_notes_propagated(0),test_plan_has_from_to_strategy(0),test_plan_host_matches_state(0)
    TestPlannerFromSpec: _spec(0),test_from_spec_builds_planner(0),test_from_spec_plan_has_steps(0),test_from_spec_with_extra_steps(0),test_from_spec_named_step_resolved(0)
    _state(strategy;k3s;docker;host)
    _target(strategy;version;host;verify_url;verify_version)
    _infra_spec(strategy;host;version)
    _plan(state;target;extra_steps;notes)
  redeploy/tests/test_plugins.py:
    e: _ctx,test_load_user_plugins_empty_dirs,TestPluginRegistry,TestRegisterPlugin,TestPluginContext,TestBrowserReloadPlugin,TestSystemdReloadPlugin,TestNotifyPlugin,TestBuiltinsAutoLoaded
    TestPluginRegistry: test_register_and_get(0),test_get_missing_returns_none(0),test_names_returns_registered(0),test_decorator_syntax(0),test_override_logs_debug(1),test_load_directory_imports_py_files(1),test_load_directory_skips_underscored(1),test_load_directory_missing(1),test_load_directory_bad_syntax_does_not_crash(1)
    TestRegisterPlugin: test_registers_in_global_registry(0),test_handler_callable(0)
    TestPluginContext: test_fields(0),test_dry_run_default_false(0)
    TestBrowserReloadPlugin: _get_handler(0),test_dry_run_sets_done(0),test_live_cdp_not_reachable(0),test_live_no_tabs(0),test_live_reload_success(0)
    TestSystemdReloadPlugin: _get_handler(0),test_dry_run(0),test_daemon_reload_failure_raises(0),test_restart_success_no_wait(0),test_units_as_comma_string(0),test_wait_active_polls_until_active(0),test_wait_active_timeout_raises(0)
    TestNotifyPlugin: _get_handler(0),test_dry_run(0),test_unknown_backend_raises(0),test_slack_missing_webhook_raises(0),test_webhook_missing_url_raises(0),test_slack_success(0),test_webhook_post_success(0),test_env_var_expansion(1)
    TestBuiltinsAutoLoaded: test_browser_reload_in_registry(0),test_systemd_reload_in_registry(0),test_notify_in_registry(0),test_names_include_builtins(0)
    _ctx(params;dry_run)
    test_load_user_plugins_empty_dirs(tmp_path)
  redeploy/tests/test_probes.py:
    e: _probe,TestProbeRuntime,TestProbePorts,TestProbeIptablesDnat,TestProbeDockerServices,TestProbeK3sServices,TestProbeSystemdServices,TestDetectConflicts,TestDetectStrategy
    TestProbeRuntime: test_docker_present(0),test_k3s_present_with_namespaces(0),test_k3s_absent(0),test_podman_present(0),test_nothing_installed(0),test_arch_detected(0)
    TestProbePorts: _ss_output(0),test_parses_ports(0),test_process_name(0),test_pid_parsed(0),test_empty_if_command_fails(0),test_empty_output(0)
    TestProbeIptablesDnat: _iptables_output(0),test_finds_dnat_rules(0),test_returns_empty_if_no_dnat(0),test_returns_empty_on_failure(0)
    TestProbeDockerServices: test_parses_containers(0),test_healthy_flag(0),test_empty_if_no_docker(0),test_ports_from_inspect(0)
    TestProbeK3sServices: test_skips_system_namespaces(0),test_empty_namespaces(0),test_all_system_namespaces_skipped(0)
    TestProbeSystemdServices: test_parses_active_units(0),test_empty_on_failure(0)
    TestDetectConflicts: _rt(2),test_no_conflicts_clean_state(0),test_port_steal_from_dnat(0),test_dual_runtime_conflict(0),test_unexpected_port_owner(0),test_expected_port_owners_no_conflict(0),test_conflict_severity_port_steal_is_high(0)
    TestDetectStrategy: _rt(3),test_k3s_only(0),test_docker_only(0),test_k3s_wins_over_docker_when_both_running(0),test_podman_quadlet(0),test_systemd_without_podman(0),test_nothing_running(0)
    _probe(responses)
  redeploy/tests/test_public_api.py:
    e: test_all_names_importable,test_version_string,test_deploy_strategy_values,test_step_action_values,test_step_status_values,test_conflict_severity_values,test_migration_step_construct,test_target_config_defaults,test_target_config_strategy_alias_docker_compose,test_target_config_strategy_alias_kiosk_appliance,test_target_config_strategy_alias_quadlet,test_target_config_strategy_alias_kubernetes,test_target_config_strategy_alias_k8s,test_target_config_strategy_canonical_passthrough,test_infra_state_construct,test_migration_plan_construct,test_planner_importable,test_executor_importable,test_detector_importable,test_ssh_client_local,test_ssh_result_ok,test_ssh_result_fail,test_device_registry_empty,test_known_device_construct,test_fleet_config_importable,test_step_library_importable,test_fleet_importable,test_fleet_empty,test_fleet_from_registry_empty,test_fleet_merge,test_planner_kiosk_appliance_generates_steps,test_planner_docker_compose_alias
    test_all_names_importable()
    test_version_string()
    test_deploy_strategy_values()
    test_step_action_values()
    test_step_status_values()
    test_conflict_severity_values()
    test_migration_step_construct()
    test_target_config_defaults()
    test_target_config_strategy_alias_docker_compose()
    test_target_config_strategy_alias_kiosk_appliance()
    test_target_config_strategy_alias_quadlet()
    test_target_config_strategy_alias_kubernetes()
    test_target_config_strategy_alias_k8s()
    test_target_config_strategy_canonical_passthrough()
    test_infra_state_construct()
    test_migration_plan_construct()
    test_planner_importable()
    test_executor_importable()
    test_detector_importable()
    test_ssh_client_local()
    test_ssh_result_ok()
    test_ssh_result_fail()
    test_device_registry_empty()
    test_known_device_construct()
    test_fleet_config_importable()
    test_step_library_importable()
    test_fleet_importable()
    test_fleet_empty()
    test_fleet_from_registry_empty()
    test_fleet_merge()
    test_planner_kiosk_appliance_generates_steps()
    test_planner_docker_compose_alias()
  redeploy/tests/test_resume.py:
    e: _step,_plan,_make_executor,TestStateKey,TestResumeStateIO,TestExecutorCheckpoint
    TestStateKey: test_stable_for_same_inputs(0),test_changes_with_host(0),test_changes_with_path(0),test_path_safe(0),test_default_state_path_uses_default_dir(0)
    TestResumeStateIO: test_load_or_new_creates_when_missing(1),test_mark_done_persists(1),test_mark_done_idempotent(1),test_mark_failed_records_error(1),test_remove_deletes_file(1),test_remove_when_missing_is_safe(1),test_save_atomic(1)
    TestExecutorCheckpoint: test_writes_checkpoint_after_each_success(1),test_checkpoint_persists_on_failure(1),test_resume_skips_completed_and_runs_remainder(1),test_from_step_skips_earlier_steps(1),test_from_step_unknown_runs_full_plan(1),test_resume_without_checkpoint_runs_all(1),test_dry_run_does_not_touch_state(1),test_rollback_clears_rolled_back_steps(1)
    _step(sid;command)
    _plan(steps)
    _make_executor(plan)
  redeploy/tests/test_security_hardening.py:
    e: test_apply_display_transform_rejects_unsafe_output_name,test_apply_display_transform_rejects_unsupported_transform,test_probe_k3s_services_skips_unsafe_namespace,test_exec_ssh_rejects_unsafe_command_tokens,test_exec_ssh_allows_override_for_trusted_environments,_Result,_Probe
    _Result: __init__(2)
    _Probe: __init__(0),run(1)
    test_apply_display_transform_rejects_unsafe_output_name()
    test_apply_display_transform_rejects_unsupported_transform()
    test_probe_k3s_services_skips_unsafe_namespace()
    test_exec_ssh_rejects_unsafe_command_tokens(monkeypatch)
    test_exec_ssh_allows_override_for_trusted_environments(monkeypatch)
  redeploy/tests/test_spec_loader.py:
    e: _migration_yaml,_migration_markdown,test_load_migration_spec_reads_yaml,test_load_migration_spec_reads_supported_markdown,test_load_migration_spec_rejects_unsupported_markdown_block
    _migration_yaml()
    _migration_markdown()
    test_load_migration_spec_reads_yaml(tmp_path)
    test_load_migration_spec_reads_supported_markdown(tmp_path)
    test_load_migration_spec_rejects_unsupported_markdown_block(tmp_path)
  redeploy/tests/test_ssh.py:
    e: test_ssh_result_ok,test_ssh_result_success_alias,test_ssh_result_out_strips,test_local_run_echo,test_local_is_reachable,test_ssh_opts_with_key,test_ssh_opts_no_key,test_run_success,test_run_failure,test_run_timeout,test_remote_probe_is_local,test_remote_probe_not_local,test_check_version_match,test_check_version_mismatch,test_check_version_no_local,test_read_local_version,test_collect_sqlite_counts,test_collect_sqlite_missing_db,test_verify_context_pass,test_verify_context_fail,test_verify_data_integrity_ok,test_verify_data_integrity_mismatch,TestPutFile
    TestPutFile: test_local_writes_file(1),test_local_creates_parent_dirs(1),test_local_applies_chmod(1),test_local_write_error_returns_failure(1),test_remote_calls_ssh(0),test_remote_failure_returned(0),test_remote_exception_returns_failure(0)
    test_ssh_result_ok()
    test_ssh_result_success_alias()
    test_ssh_result_out_strips()
    test_local_run_echo()
    test_local_is_reachable()
    test_ssh_opts_with_key()
    test_ssh_opts_no_key()
    test_run_success(mock_run)
    test_run_failure(mock_run)
    test_run_timeout(mock_run)
    test_remote_probe_is_local()
    test_remote_probe_not_local()
    test_check_version_match()
    test_check_version_mismatch()
    test_check_version_no_local()
    test_read_local_version(tmp_path)
    test_collect_sqlite_counts(tmp_path)
    test_collect_sqlite_missing_db(tmp_path)
    test_verify_context_pass()
    test_verify_context_fail()
    test_verify_data_integrity_ok()
    test_verify_data_integrity_mismatch()
  redeploy/tests/test_steps_registry.py:
    e: TestNoDuplicateIds,TestAllStepsReachableViaLibrary,TestLibraryGetReturnsCopy,TestKnownStepsExist
    TestNoDuplicateIds: test_no_duplicate_ids_within_each_module(0),test_no_duplicate_ids_across_all_modules(0)
    TestAllStepsReachableViaLibrary: test_every_step_in_library(1)
    TestLibraryGetReturnsCopy: test_mutating_copy_does_not_affect_template(0)
    TestKnownStepsExist: test_k3s_steps(0),test_docker_steps(0),test_podman_steps(0),test_generic_steps(0),test_scm_steps(0),test_transfer_steps(0),test_process_steps(0),test_hardware_steps(0),test_kiosk_steps(0)
  redeploy/tests/test_templates.py:
    e: _state,_probe,TestBuildContext,TestDetectionTemplateScore,TestTemplateEngine,TestTemplateMatchConfidence,TestBuiltinTemplates,TestDetectionResult
    TestBuildContext: test_has_docker_true(0),test_has_docker_false(0),test_has_k3s(0),test_has_podman(0),test_is_arm(0),test_is_x86(0),test_is_ubuntu(0),test_is_debian(0),test_is_raspberry(0),test_port_mapping(0),test_docker_active_from_services(0),test_k3s_active_from_services(0),test_has_nginx(0),test_has_health(0),test_has_version(0),test_is_local(0),test_probe_ssh_user(0),test_probe_chromium(0),test_dual_runtime_conflict(0),test_port_steal_conflict(0),test_manifest_envs(0)
    TestDetectionTemplateScore: _tpl(2),test_all_conditions_met(0),test_partial_conditions(0),test_required_fail_returns_minus_one(0),test_required_pass_continues_to_conditions(0),test_max_score(0),test_no_conditions_zero_score(0)
    TestTemplateEngine: test_score_all_returns_sorted(0),test_disqualified_excluded(0),test_detect_returns_none_when_all_disqualified(0),test_detect_returns_best(0),test_matched_conditions_populated(0)
    TestTemplateMatchConfidence: _match(2),test_high_confidence(0),test_medium_confidence(0),test_low_confidence(0),test_zero_max_score(0)
    TestBuiltinTemplates: test_vps_docker_wins_for_docker_x86(0),test_k3s_template_wins_for_k3s(0),test_rpi_kiosk_wins_for_arm_chromium(0),test_dual_runtime_conflict_wins_with_required(0),test_podman_template(0),test_all_templates_have_unique_ids(0)  # Smoke-test that built-in templates score plausibly for expec
    TestDetectionResult: _result(3),test_strategy(0),test_environment(0),test_spec_template(0),test_generated_env_block_contains_host(0),test_generated_notes(0)
    _state(host;app;docker;k3s;podman;systemd;arch;os;docker_svcs;k3s_svcs;systemd_svcs;ports;health;conflicts;version)
    _probe(ssh_user;arch;os_info;strategy;app;has_chromium;running_services)
  redeploy/tests/test_verify.py:
    e: _remote,TestVerifyContextCheck,TestVerifyContextManual,TestVerifyContextSummary,TestVerifyDataIntegrity
    TestVerifyContextCheck: test_pass_without_expect(0),test_pass_with_expect_found(0),test_fail_expect_not_found(0),test_fail_remote_error(0),test_non_critical_fail_not_in_errors(0),test_check_returns_true_on_pass(0),test_check_returns_false_on_fail(0),test_checks_list_has_pass_marker(0),test_checks_list_has_fail_marker(0)
    TestVerifyContextManual: test_add_pass(0),test_add_fail(0),test_add_fail_no_detail(0),test_add_warn(0),test_add_info(0),test_mixed_results(0)
    TestVerifyContextSummary: test_ok_true_when_no_failures(0),test_ok_false_when_has_failure(0),test_summary_all_pass(0),test_summary_with_failures(0),test_summary_with_warnings(0),test_empty_context_summary(0)
    TestVerifyDataIntegrity: test_matching_counts_pass(0),test_mismatch_fails(0),test_remote_empty_fails(0),test_missing_remote_table_fails(0),test_empty_local_counts(0),test_dict_local_count_uses_local_key(0),test_multiple_tables_partial_fail(0)
    _remote(ok;stdout;stderr)
  redeploy/tests/test_version.py:
    e: _mock_urlopen,TestReadLocalVersion,TestReadRemoteVersion,TestCheckVersion,TestCheckVersionHttp
    TestReadLocalVersion: test_reads_app_subdir_version(1),test_reads_root_version_fallback(1),test_strips_whitespace(1),test_returns_none_when_missing(1),test_returns_none_for_empty_version(1),test_app_subdir_takes_priority(1)
    TestReadRemoteVersion: _remote(1),test_reads_app_subdir_path(0),test_reads_root_path_fallback(0),test_strips_whitespace(0),test_returns_none_when_not_found(0)
    TestCheckVersion: test_match(0),test_mismatch(0),test_local_none_returns_true(0),test_remote_none_returns_false(0),test_both_none_local_wins(0)
    TestCheckVersionHttp: _payload(4),test_success_match(0),test_mismatch_in_api(0),test_expected_version_mismatch(0),test_http_error(0),test_connection_error(0),test_no_expected_version_passed(0),test_payload_returned(0),test_trailing_slash_stripped_in_url(0),test_versions_in_summary(0)
    _mock_urlopen(payload;status)
  redeploy/tests/test_version_changelog.py:
    e: TestParseConventional,TestAnalyzeCommits,TestFormatAnalysisReport,TestChangelogManager,TestGetCommitsSinceTag
    TestParseConventional: test_simple_feat(0),test_with_scope(0),test_breaking_bang(0),test_breaking_bang_with_scope(0),test_breaking_change_in_body(0),test_breaking_change_hyphen_in_body(0),test_chore(0),test_docs(0),test_non_conventional_returns_none(0),test_multi_word_description(0),test_body_captured(0),test_raw_preserved(0),test_perf_type(0),test_test_type(0)
    TestAnalyzeCommits: _mock_git(1),test_feat_gives_minor(1),test_fix_gives_patch(1),test_breaking_gives_major(1),test_major_wins_over_minor(1),test_minor_wins_over_patch(1),test_chore_no_bump(1),test_no_commits_no_bump(1),test_git_error_returns_none_bump(1),test_git_not_found_returns_gracefully(1),test_commits_analyzed_count(1),test_custom_config_changes_rules(1)
    TestFormatAnalysisReport: test_report_with_bump(0),test_report_no_bump(0)
    TestChangelogManager: test_exists_false_when_missing(1),test_exists_true_when_present(1),test_read_returns_default_template_when_missing(1),test_read_returns_file_content(1),test_write_creates_file(1),test_get_unreleased_section_empty(1),test_get_unreleased_section_with_content(1),test_prepare_release_replaces_unreleased(1),test_prepare_release_date_defaults_to_today(1),test_prepare_release_auto_categorize_from_commits(1),test_prepare_release_breaking_change_in_commits(1),test_prepare_release_no_commits_no_unreleased(1),test_preview_release(1),test_preview_release_empty_shows_placeholder(1),test_scope_formatted_bold_in_release(1)
    TestGetCommitsSinceTag: test_returns_commit_messages(1),test_returns_empty_on_git_error(1),test_returns_empty_on_exception(1)
  redeploy/tests/test_version_cli.py:
    e: _runner,_write_version_workspace,_write_monorepo_version_workspace,TestVersionSet,TestVersionList,TestVersionCurrent,TestVersionInit,TestVersionVerify,TestVersionBump,TestVersionDiff
    TestVersionSet: test_set_updates_manifest_and_sources(1),test_set_dry_run_does_not_modify_files(1),test_set_package_updates_only_selected_package(1)
    TestVersionList: test_list_all_packages_shows_package_sources(1),test_list_package_shows_only_selected_package(1),test_list_all_packages_returns_error_on_drift(1)
    TestVersionCurrent: test_current_shows_manifest_version(1),test_current_package_shows_selected_package_version(1),test_current_all_packages_shows_package_versions(1)
    TestVersionInit: test_init_scan_creates_synced_manifest_from_root_sources(1),test_init_scan_creates_independent_manifest_from_package_dirs(1),test_init_scan_detects_regex_source_in_nested_package(1),test_init_scan_reports_conflict_between_scanned_sources(1),test_init_scan_review_lists_detected_sources_without_writing_manifest(1),test_init_scan_interactive_can_reject_source_and_write_manifest(1),test_init_scan_interactive_rejects_heuristic_source_by_default(1),test_init_interactive_requires_scan(1),test_init_scan_exclude_omits_detected_source_from_manifest(1)
    TestVersionVerify: test_verify_all_packages_succeeds_when_in_sync(1),test_verify_package_checks_only_selected_package(1),test_verify_all_packages_returns_error_on_drift(1),test_set_all_packages_updates_all_packages(1),test_set_package_dry_run_does_not_modify_monorepo(1),test_set_package_with_commit_and_tag_uses_git_integration(1),test_set_all_packages_with_push_allow_dirty_skips_clean_check(1),test_set_all_packages_changelog_skips_global_default_without_package_configs(1),test_set_all_packages_changelog_updates_package_changelogs(1)
    TestVersionBump: test_bump_package_with_tag_uses_package_tag_format(1),test_bump_all_packages_changelog_updates_package_changelogs(1)
    TestVersionDiff: test_diff_all_packages_shows_package_source_status(1),test_diff_package_spec_mismatch_returns_nonzero(1),test_diff_all_packages_rejects_spec_without_package(1),test_diff_spec_match_returns_zero(1),test_diff_spec_manifest_reference_returns_zero(1),test_diff_spec_mismatch_returns_nonzero(1),test_diff_missing_spec_returns_nonzero(1)
    _runner()
    _write_version_workspace(base;version)
    _write_monorepo_version_workspace(base)
  redeploy/tests/test_version_manifest.py:
    e: TestVersionManifest,TestCalculateBump,TestVerifySources,TestPlainAdapter,TestVersionBumpTransaction,TestLegacyFunctions,TestJsonAdapter,TestTomlAdapter,TestYamlAdapter,TestRegexAdapter,TestC2004StyleManifest
    TestVersionManifest: test_minimal_manifest(0),test_with_source(1),test_git_config_defaults(0),test_format_version(0),test_format_version_custom(0),test_load_from_file(1),test_load_flat_format(1),test_load_missing_file(1),test_save_and_reload(1),test_get_source_paths(1),test_source_config_accepts_toml_with_key(1),test_source_config_accepts_regex_with_pattern(1)
    TestCalculateBump: _manifest(2),test_patch_bump(1),test_minor_bump(1),test_major_bump(1),test_prerelease_bump_fresh(1),test_prerelease_bump_increment(1),test_explicit_version(1),test_invalid_bump_type(1),test_non_semver_raises(1),test_file_updated_after_bump(1)
    TestVerifySources: test_all_match(1),test_mismatch(1),test_missing_optional_file(1)
    TestPlainAdapter: test_read_write(1),test_read_optional_missing(1)
    TestVersionBumpTransaction: test_prepare_commit(1),test_rollback_cleans_temp_files(1)
    TestLegacyFunctions: test_read_local_version_from_root(1),test_read_local_version_from_app_subdir(1),test_read_local_version_missing(1),test_check_version_match(0),test_check_version_mismatch(0),test_check_version_no_local(0),test_check_version_no_remote(0),test_check_version_http_unreachable(0)
    TestJsonAdapter: test_read_simple_key(1),test_read_nested_key(1),test_write_updates_version(1),test_write_preserves_other_fields(1),test_read_missing_key_raises(1),test_write_pattern(1)
    TestTomlAdapter: test_read_pyproject(1),test_write_pyproject(1),test_write_preserves_other_content(1),test_read_missing_key_raises(1),test_stage_without_commit(1)
    TestYamlAdapter: test_read_simple_key(1),test_write_simple_key(1),test_read_with_value_pattern(1),test_write_with_write_pattern(1),test_read_missing_key_raises(1),test_read_optional_missing(1)
    TestRegexAdapter: test_read_python_version(1),test_read_const_version(1),test_write_replaces_version(1),test_read_no_match_raises(1),test_write_no_match_raises(1),test_stage_does_not_modify_original(1)
    TestC2004StyleManifest: test_multi_source_manifest(1),test_bump_multiple_sources(1),test_load_from_c2004_style_yaml(1)  # Integration tests mirroring c2004/.redeploy/version.yaml str
  redeploy/tests/test_version_sources.py:
    e: src,TestGetAdapter,TestPlainAdapter,TestJsonAdapter,TestTomlAdapter,TestYamlAdapter,TestRegexAdapter,TestVersionDiff,TestBumpPackageMonorepo
    TestGetAdapter: test_known_formats(0),test_unknown_format_raises(0),test_register_custom_adapter(0)
    TestPlainAdapter: test_read_version(1),test_read_strips_whitespace(1),test_read_missing_raises(1),test_read_missing_optional_returns_empty(1),test_stage_creates_temp_with_newline(1),test_write_updates_file(1),test_stage_is_in_same_directory(1)
    TestJsonAdapter: _write_pkg(2),test_read_top_level_key(1),test_read_nested_key(1),test_read_missing_key_raises(1),test_read_non_string_raises(1),test_read_with_value_pattern(1),test_stage_updates_version(1),test_stage_preserves_trailing_newline(1),test_stage_with_write_pattern(1),test_detect_indent_2(1),test_detect_indent_4(1),test_detect_indent_default(0)
    TestTomlAdapter: _write_toml(2),test_read_project_version(1),test_read_missing_key_raises(1),test_read_without_key_raises(1),test_stage_updates_version(1),test_stage_preserves_other_fields(1),test_stage_raises_when_key_not_found(1)
    TestYamlAdapter: _write_yaml(2),test_read_top_level(1),test_read_nested(1),test_read_missing_key_raises(1),test_stage_updates_version(1),test_stage_preserves_other_keys(1),test_read_non_string_raises(1)
    TestRegexAdapter: _write(3),test_read_version_from_source(1),test_read_no_match_raises(1),test_read_without_pattern_raises(1),test_stage_replaces_capture_group(1),test_stage_simple_version_line(1),test_stage_no_match_raises(1),test_stage_no_capture_group_raises(1)
    TestVersionDiff: _manifest(1),test_diff_manifest_vs_spec_match(0),test_diff_manifest_vs_spec_mismatch(0),test_diff_manifest_vs_spec_at_manifest_ref(0),test_diff_manifest_vs_live_match(0),test_diff_manifest_vs_live_mismatch(0),test_diff_manifest_vs_live_none(0),test_format_diff_report_all_ok(0),test_format_diff_report_with_mismatch(0),test_format_diff_report_with_error(0)
    TestBumpPackageMonorepo: _make_manifest(1),test_is_monorepo_true(1),test_list_packages(1),test_get_package_existing(1),test_get_package_missing_returns_none(1),test_get_all_package_versions(1),test_bump_package_patch(1),test_bump_package_minor(1),test_bump_package_unknown_raises(1),test_bump_package_result_keys(1),test_bump_all_packages(1),test_bump_all_packages_not_monorepo_raises(1),test_bump_package_independent_of_other(1)
    src(path;fmt;key;pattern;optional;value_pattern;write_pattern)
  redeploy/tests/test_workflow.py:
    e: _state,_reachable_host,_unreachable_host,TestWorkflowResult,TestHostDetectionResult,TestCollectHosts,TestDetectionWorkflowRun
    TestWorkflowResult: test_reachable_filter(0),test_by_env(0),test_summary_contains_host(0),test_summary_unreachable(0),test_generated_redeploy_yaml_contains_host(0),test_generated_redeploy_yaml_deduplicates_envs(0),test_generated_redeploy_yaml_empty_when_no_reachable(0),test_generated_migration_yaml_no_reachable(0),test_generated_migration_yaml_contains_strategy(0),test_generated_migration_yaml_for_env(0)
    TestHostDetectionResult: test_strategy_from_template(0),test_strategy_from_state_when_no_template(0),test_strategy_unknown_when_nothing(0),test_environment(0),test_confidence(0),test_env_block_generated(0),test_notes(0)
    TestCollectHosts: _workflow(0),test_explicit_hosts_included(0),test_manifest_envs_added(0),test_local_hosts_excluded_from_manifest(0),test_registry_hosts_added(0),test_deduplication_by_ip(0),test_explicit_takes_priority_over_registry(0),test_empty_when_no_sources(0)
    TestDetectionWorkflowRun: _mock_probe(2),test_run_empty_hosts_returns_empty(0),test_run_unreachable_host(0),test_run_reachable_scores_template(0),test_run_sets_app_on_result(0)
    _state(host;strategy;ports;version)
    _reachable_host(host;strategy;env)
    _unreachable_host(host)
  redeploy/verify.py:
    e: verify_data_integrity,VerifyContext
    VerifyContext: check(5),add_pass(1),add_fail(2),add_warn(1),add_info(1),passed(0),failed(0),warned(0),total(0),ok(0),summary(0)  # Accumulates check results during verification.
    verify_data_integrity(ctx;local_counts;remote_counts)
  redeploy/version/__init__.py:
    e: read_local_version,read_remote_version,check_version,check_version_http
    read_local_version(workspace_root;app)
    read_remote_version(remote;remote_dir;app)
    check_version(local;remote)
    check_version_http(base_url;expected_version;timeout;endpoint)
  redeploy/version/bump.py:
    e: bump_version,verify_sources,bump_version_with_git,bump_package,bump_all_packages,_calculate_bump
    bump_version(manifest;bump_type;new_version)
    verify_sources(manifest)
    bump_version_with_git(manifest;bump_type;repo_path;new_version;manifest_path;commit;tag;push;sign;allow_dirty)
    bump_package(manifest;package_name;bump_type;new_version)
    bump_all_packages(manifest;bump_type)
    _calculate_bump(current;bump_type)
  redeploy/version/changelog.py:
    e: get_commits_since_tag,ChangelogManager
    ChangelogManager: __init__(1),exists(0),read(0),_default_template(0),get_unreleased_section(0),prepare_release(3),_format_release_content(2),_init_categories(0),_categorize_commits(2),_format_commit_entry(1),_add_to_category(3),_build_release_content(1),write(1),preview_release(2)  # Manage CHANGELOG.md in keep-a-changelog format.
    get_commits_since_tag(repo_path;tag)
  redeploy/version/commits.py:
    e: parse_conventional,analyze_commits,format_analysis_report,ConventionalCommit,BumpAnalysis
    ConventionalCommit:  # Parsed conventional commit.
    BumpAnalysis:  # Result of analyzing commits for bump decision.
    parse_conventional(message)
    analyze_commits(since_tag;repo_path;config)
    format_analysis_report(analysis)
  redeploy/version/diff.py:
    e: diff_manifest_vs_spec,diff_manifest_vs_live,format_diff_report,VersionDiff
    VersionDiff:  # Version comparison result.
    diff_manifest_vs_spec(manifest;spec_version)
    diff_manifest_vs_live(manifest;live_version)
    format_diff_report(diffs;manifest_version)
  redeploy/version/git_integration.py:
    e: GitIntegrationError,GitIntegration
    GitIntegrationError:  # Git operation failed.
    GitIntegration: __init__(2),_run(2),require_clean(0),is_clean(0),get_dirty_files(0),stage_files(1),commit(2),tag(3),push(2),tag_exists(1),get_last_tag(0),get_commits_since(1),get_current_branch(0)  # Git operations for version management.
  redeploy/version/git_transaction.py:
    e: GitTransactionResult,GitVersionBumpTransaction
    GitTransactionResult:  # Result of full version bump transaction with git.
    GitVersionBumpTransaction: __init__(5),prepare(0),commit_and_tag(3),push(0),rollback(0)  # Version bump transaction with Git integration.
  redeploy/version/manifest.py:
    e: SourceConfig,GitConfig,ChangelogConfig,CommitRules,CommitsConfig,PackageConfig,Constraint,VersionManifest
    SourceConfig: key_required_for_structured(3),pattern_required_for_regex(3)  # Single source of version truth (one file).
    GitConfig:  # Git integration settings.
    ChangelogConfig:  # Changelog generation settings.
    CommitRules:  # Conventional commits → bump type mapping.
    CommitsConfig:  # Conventional commits analysis settings.
    PackageConfig:  # Single package in monorepo (for policy=independent).
    Constraint:  # Cross-package version constraint.
    VersionManifest: load(2),save(1),format_version(1),get_source_paths(0),get_package(1),list_packages(0),is_monorepo(0),get_all_package_versions(0)  # Root manifest model for .redeploy/version.yaml.
  redeploy/version/sources/__init__.py:
    e: get_adapter,register_adapter,SourceAdapter
    SourceAdapter: read(2),write(3),stage(3)  # Protocol for version source adapters.
    get_adapter(format_name)
    register_adapter(format_name;adapter)
  redeploy/version/sources/base.py:
    e: BaseAdapter
    BaseAdapter: _validate_path(2),_extract_version(2),_create_temp(1),_atomic_write(3),write(3)  # Base class for source adapters with common utilities.
  redeploy/version/sources/json_.py:
    e: JsonAdapter
    JsonAdapter: read(2),stage(3),_detect_indent(1)  # Read/write version from JSON files.
  redeploy/version/sources/plain.py:
    e: PlainAdapter
    PlainAdapter: read(2),stage(3)  # Read/write version from plain text file.
  redeploy/version/sources/regex.py:
    e: RegexAdapter
    RegexAdapter: read(2),stage(3)  # Read/write version using regex pattern with capture group.
  redeploy/version/sources/toml_.py:
    e: TomlAdapter
    TomlAdapter: _get_toml_lib(0),read(2),stage(3)  # Read/write version from TOML files using tomllib/tomli.
  redeploy/version/sources/yaml_.py:
    e: YamlAdapter
    YamlAdapter: _get_yaml_lib(0),read(2),stage(3)  # Read/write version from YAML files.
  redeploy/version/transaction.py:
    e: StagingResult,VersionBumpTransaction
    StagingResult:  # Result of staging one source.
    VersionBumpTransaction: __init__(2),prepare(0),_stage_one(1),commit(0),rollback(0),get_summary(0)  # Atomic transaction for bumping version across multiple sourc
  redeploy/version.py:
  scripts/quality_gate.py:
  tests/contract/__init__.py:
  tests/contract/test_blueprint_op3_parity.py:
    e: mock_device_map,_build_mock_snapshot,test_snapshot_to_device_map_roundtrip
    mock_device_map()
    _build_mock_snapshot()
    test_snapshot_to_device_map_roundtrip(mock_device_map)
  tests/contract/test_detect_op3_parity.py:
    e: mock_infra,_build_mock_snapshot,test_snapshot_to_infra_state_parity
    mock_infra()
    _build_mock_snapshot()
    test_snapshot_to_infra_state_parity(mock_infra)
  tests/contract/test_hardware_op3_parity.py:
    e: mock_hw,test_hardware_yaml_shape
    mock_hw()
    test_hardware_yaml_shape(mock_hw;monkeypatch)
  tests/integration/__init__.py:
  tests/integration/test_op3_bridge.py:
    e: test_op3_importable,test_require_op3_is_noop_when_available,test_make_scanner_defaults_to_hardware_layers,test_make_scanner_instances_are_isolated,test_make_ssh_context_forwards_key,test_end_to_end_mock_scan_physical_display
    test_op3_importable()
    test_require_op3_is_noop_when_available()
    test_make_scanner_defaults_to_hardware_layers()
    test_make_scanner_instances_are_isolated()
    test_make_ssh_context_forwards_key()
    test_end_to_end_mock_scan_physical_display()
  tests/test_blueprint_sources.py:
    e: FakeHw,TestParseMigrationMeta,TestBuildHwRequirements,FakeSvc,FakeInfra,TestExtractServicesFromInfra,TestInferAppUrl
    FakeHw: __init__(0)  # Minimal fake hardware probe result.
    TestParseMigrationMeta: test_reads_version_and_strategy(1),test_infers_podman_quadlet_from_steps(1),test_infers_docker_from_steps(1),test_missing_file_returns_empty(1),test_invalid_yaml_returns_empty(1),test_no_strategy_or_version_returns_empty(1)
    TestBuildHwRequirements: test_none_returns_empty(0),test_dsi_detected(0),test_backlight_and_i2c_features(0),test_rpi_arch(0),test_aarch64_arch(0),test_non_pi_arch(0)
    FakeSvc: __init__(2)
    FakeInfra: __init__(3)
    TestExtractServicesFromInfra: test_empty_infra(0),test_extracts_services(0),test_skips_already_seen(0),test_multiple_groups(0)
    TestInferAppUrl: test_none_infra(0),test_no_host(0),test_port_80(0),test_port_443(0),test_port_8100(0),test_no_matching_ports(0),test_strips_user_from_host(0)
  tests/test_blueprint_sources_compose.py:
    e: compose_file,TestMergeComposeFiles,TestParseComposePorts,TestParseComposeVolumes,TestParseComposeEnv,TestParseComposeHealthcheck
    TestMergeComposeFiles: test_parses_services(1),test_populates_seen(1),test_noop_on_empty_list(0),test_skips_missing_file(1),test_skips_invalid_yaml(1),test_merges_duplicate_service(1)
    TestParseComposePorts: test_int_form(0),test_string_form(0),test_string_with_protocol(0),test_dict_form(0),test_dict_form_defaults(0),test_mixed_list(0)
    TestParseComposeVolumes: test_string_form(0),test_string_form_readonly(0),test_dict_form(0),test_dict_input(0)
    TestParseComposeEnv: test_dict_form(0),test_list_form(0),test_skips_none_values(0)
    TestParseComposeHealthcheck: test_list_test(0),test_string_test(0),test_empty_returns_none(0)
    compose_file(tmp_path)
  tests/test_cli_gh_workflow.py:
    e: _write_workflow,test_gh_workflow_list,test_gh_workflow_analyze_missing_dispatch_hint,test_gh_workflow_run_dry_run,test_gh_workflow_run_rejects_non_dispatchable
    _write_workflow(path;content)
    test_gh_workflow_list(tmp_path)
    test_gh_workflow_analyze_missing_dispatch_hint(tmp_path)
    test_gh_workflow_run_dry_run(tmp_path)
    test_gh_workflow_run_rejects_non_dispatchable(tmp_path)
  tests/test_cli_query.py:
    e: _FakeModel,TestExecuteQuery
    _FakeModel: __init__(1),model_dump(0)  # Minimal stand-in for a Pydantic model.
    TestExecuteQuery: test_basic_dict_result(1),test_json_format(1),test_yaml_format(1),test_no_match_message(1),test_jmespath_expression(1),test_jmespath_error_exits(1),test_custom_echo(0),test_json_with_non_serializable_default(1)
  tests/test_example_argocd_flux_plugin.py:
    e: _load_example_module,test_example_module_exposes_parsers,test_argocd_application_parser,test_flux_kustomization_parser
    _load_example_module()
    test_example_module_exposes_parsers()
    test_argocd_application_parser(tmp_path)
    test_flux_kustomization_parser(tmp_path)
  tests/test_example_gitops_ci_plugin.py:
    e: _load_example_module,test_example_module_exposes_parsers,test_github_actions_gitops_parser,test_gitlab_ci_gitops_parser
    _load_example_module()
    test_example_module_exposes_parsers()
    test_github_actions_gitops_parser(tmp_path)
    test_gitlab_ci_gitops_parser(tmp_path)
  tests/test_example_helm_kustomize_plugin.py:
    e: _load_example_module,test_example_module_exposes_parsers,test_helm_templates_parser_extracts_images,test_kustomize_parser_extracts_resources_and_images
    _load_example_module()
    test_example_module_exposes_parsers()
    test_helm_templates_parser_extracts_images(tmp_path)
    test_kustomize_parser_extracts_resources_and_images(tmp_path)
  tests/test_hardware_config.py:
    e: test_add_new_line_to_all_section,test_no_op_when_line_already_present,test_replace_existing_dsi_overlay,test_replace_is_idempotent_for_same_line,test_add_to_pi5_section,test_add_to_existing_section,test_no_op_for_existing_line_in_section,test_ensure_lines_multiple,test_ensure_lines_no_change_when_all_present,test_ensure_lines_partial_update,test_all_panels_non_empty,test_waveshare_8_inch_registered,test_overlay_line_dsi1,test_overlay_line_dsi0,test_official_rpi_panel_registered,test_hyperpixel_panels_registered,test_raspi_config_i2c_enable,test_raspi_config_spi_disable,test_raspi_config_invalid_interface,test_raspi_config_invalid_state
    test_add_new_line_to_all_section()
    test_no_op_when_line_already_present()
    test_replace_existing_dsi_overlay()
    test_replace_is_idempotent_for_same_line()
    test_add_to_pi5_section()
    test_add_to_existing_section()
    test_no_op_for_existing_line_in_section()
    test_ensure_lines_multiple()
    test_ensure_lines_no_change_when_all_present()
    test_ensure_lines_partial_update()
    test_all_panels_non_empty()
    test_waveshare_8_inch_registered()
    test_overlay_line_dsi1()
    test_overlay_line_dsi0()
    test_official_rpi_panel_registered()
    test_hyperpixel_panels_registered()
    test_raspi_config_i2c_enable()
    test_raspi_config_spi_disable()
    test_raspi_config_invalid_interface()
    test_raspi_config_invalid_state()
  tests/test_hardware_kiosk.py:
    e: test_autostart_entry_render_with_comment,test_autostart_entry_render_no_comment,test_ensure_autostart_entry_appends_to_empty,test_ensure_autostart_entry_no_op_when_correct,test_ensure_autostart_entry_replaces_stale_line,test_ensure_autostart_entry_appends_preserving_existing,test_ensure_autostart_entry_no_double_newline,test_generate_labwc_autostart_has_kanshi_first,test_generate_labwc_autostart_sleep_between,test_generate_labwc_autostart_default_browser_path,test_generate_labwc_autostart_custom_browser_path,test_generate_labwc_autostart_extra_entries,test_output_profile_to_kanshi_config_basic,test_output_profile_transform_included,test_output_profile_mode_included,test_dsi_only_profile_defaults,test_dsi_only_profile_custom_connector,test_dsi_only_profile_with_transform,test_dsi_only_profile_kanshi_output,test_labwc_uses_kanshi,test_labwc_autostart_path_expands,test_labwc_required_packages,test_compositors_registry_contains_labwc,test_labwc_notes_mention_password_store,test_labwc_notes_warn_about_windowed_flag,test_chromium_kiosk_required_flags,test_chromium_kiosk_incompatible_windowed,test_build_launch_cmd_basic,test_build_launch_cmd_raises_on_incompatible_flag,test_chromium_notes_mention_keyring,test_chromium_wayland_platform_flag
    test_autostart_entry_render_with_comment()
    test_autostart_entry_render_no_comment()
    test_ensure_autostart_entry_appends_to_empty()
    test_ensure_autostart_entry_no_op_when_correct()
    test_ensure_autostart_entry_replaces_stale_line()
    test_ensure_autostart_entry_appends_preserving_existing()
    test_ensure_autostart_entry_no_double_newline()
    test_generate_labwc_autostart_has_kanshi_first()
    test_generate_labwc_autostart_sleep_between()
    test_generate_labwc_autostart_default_browser_path()
    test_generate_labwc_autostart_custom_browser_path()
    test_generate_labwc_autostart_extra_entries()
    test_output_profile_to_kanshi_config_basic()
    test_output_profile_transform_included()
    test_output_profile_mode_included()
    test_dsi_only_profile_defaults()
    test_dsi_only_profile_custom_connector()
    test_dsi_only_profile_with_transform()
    test_dsi_only_profile_kanshi_output()
    test_labwc_uses_kanshi()
    test_labwc_autostart_path_expands()
    test_labwc_required_packages()
    test_compositors_registry_contains_labwc()
    test_labwc_notes_mention_password_store()
    test_labwc_notes_warn_about_windowed_flag()
    test_chromium_kiosk_required_flags()
    test_chromium_kiosk_incompatible_windowed()
    test_build_launch_cmd_basic()
    test_build_launch_cmd_raises_on_incompatible_flag()
    test_chromium_notes_mention_keyring()
    test_chromium_wayland_platform_flag()
  tests/test_hardware_rules.py:
    e: _hw,_dsi_output,_backlight,test_no_dsi_overlay_when_dsi_overlays_empty,test_no_dsi_overlay_rule_absent_when_overlay_present,test_auto_detect_conflict_flagged,test_auto_detect_no_conflict_when_zero,test_overlay_but_no_drm_connector_flagged,test_overlay_with_drm_connector_no_connector_error,test_dsi_disconnected_flagged,test_no_backlight_when_dsi_connected,test_backlight_power_off_flagged,test_backlight_brightness_zero_flagged,test_all_ok_emits_info,test_all_ok_no_wayland_warns,test_i2c_chip_missing_flagged,test_i2c_chip_present_no_warn
    _hw()
    _dsi_output(status;edid_bytes)
    _backlight(name;brightness;bl_power)
    test_no_dsi_overlay_when_dsi_overlays_empty()
    test_no_dsi_overlay_rule_absent_when_overlay_present()
    test_auto_detect_conflict_flagged()
    test_auto_detect_no_conflict_when_zero()
    test_overlay_but_no_drm_connector_flagged()
    test_overlay_with_drm_connector_no_connector_error()
    test_dsi_disconnected_flagged()
    test_no_backlight_when_dsi_connected()
    test_backlight_power_off_flagged()
    test_backlight_brightness_zero_flagged()
    test_all_ok_emits_info()
    test_all_ok_no_wayland_warns()
    test_i2c_chip_missing_flagged()
    test_i2c_chip_present_no_warn()
  tests/test_heal_decider.py:
    e: TestDecideAfterFailure,TestFormatDecisionMessage
    TestDecideAfterFailure: test_loop_aborts(0),test_missing_step_aborts(0),test_max_retries_aborts(0),test_patch_retries(0),test_llm_error_retries_then_aborts(0),test_no_patch_skips(0)
    TestFormatDecisionMessage: test_contains_action(0)
  tests/test_heal_loop_detector.py:
    e: TestHealLoopDetector,TestHealAbort
    TestHealLoopDetector: test_empty_hint_ignored(0),test_loop_detected_after_n_identical(0),test_different_hints_reset(0),test_reset_clears_history(0),test_different_step_ids_isolated(0)
    TestHealAbort: test_message(0)
  tests/test_iac.py:
    e: write_compose,TestParsedSpec,TestPortParsing,TestVolumeParsing,TestDockerComposeParserCanParse,TestDockerComposeParserBasic,TestParserRegistry,TestGlobalRegistry,TestSummary
    TestParsedSpec: test_all_images_deduplicated(0),test_all_ports_deduplicated(0),test_summary_shows_counts(0),test_add_warning(0)
    TestPortParsing: test_short_form_published(0),test_short_form_container_only(0),test_short_form_with_ip(0),test_short_form_with_protocol(0),test_long_form_dict(0),test_invalid_returns_none(0)
    TestVolumeParsing: test_bind_mount(0),test_named_volume(0),test_read_only(0),test_long_form(0)
    TestDockerComposeParserCanParse: setup_method(0),test_standard_name(1),test_compose_yaml(1),test_heuristic_services_key(1),test_unrelated_yaml(1)
    TestDockerComposeParserBasic: test_simple_service(1),test_multiple_services(1),test_environment_list_form(1),test_environment_dict_form(1),test_volumes_in_service(1),test_depends_on_list(1),test_depends_on_dict_form(1),test_healthcheck(1),test_named_volumes_top_level(1),test_networks_top_level(1),test_env_file(1),test_build_context(1),test_build_dict_form(1),test_deploy_replicas(1),test_variable_substitution(1),test_variable_default_fallback(1),test_labels_dict(1),test_restart_policy(1),test_empty_file_returns_low_confidence(1),test_invalid_yaml_recorded_as_error(1),test_profile_warning(1),test_override_file_merged(1)
    TestParserRegistry: test_register_and_dispatch(1),test_no_parser_raises(1),test_parse_dir_finds_compose(1),test_parse_dir_skip_errors(1),test_registered_list(0)
    TestGlobalRegistry: test_parser_registry_has_compose(0),test_parse_file_helper(1),test_parse_dir_helper(1)
    TestSummary: test_summary_non_empty(1)
    write_compose(tmp_path;content)
  tests/test_iac_config_hints.py:
    e: test_can_parse_dockerfile,test_parse_dockerfile_images,test_parse_nginx_conf_ports,test_parse_k8s_yaml,test_parse_terraform,test_parse_toml,test_parse_vite_config,test_parse_github_actions,test_parse_gitlab_ci
    test_can_parse_dockerfile(tmp_path)
    test_parse_dockerfile_images(tmp_path)
    test_parse_nginx_conf_ports(tmp_path)
    test_parse_k8s_yaml(tmp_path)
    test_parse_terraform(tmp_path)
    test_parse_toml(tmp_path)
    test_parse_vite_config(tmp_path)
    test_parse_github_actions(tmp_path)
    test_parse_gitlab_ci(tmp_path)
  tests/test_iac_plugin_loading.py:
    e: test_load_local_parsers_from_project_dir,test_load_local_parsers_from_user_dir
    test_load_local_parsers_from_project_dir(tmp_path;monkeypatch)
    test_load_local_parsers_from_user_dir(tmp_path;monkeypatch)
  tests/test_import_plugin_template.py:
    e: test_list_plugin_templates,test_copy_plugin_template,test_copy_plugin_template_dry_run,test_source_required_without_plugin_template
    test_list_plugin_templates()
    test_copy_plugin_template(tmp_path)
    test_copy_plugin_template_dry_run(tmp_path)
    test_source_required_without_plugin_template(tmp_path)
  tests/test_parse.py:
    e: test_parse_docker_ps_full_format,test_parse_docker_ps_partial_format,test_parse_docker_ps_skips_empty_lines,test_parse_docker_ps_skips_no_containers_marker,test_parse_docker_ps_empty,test_parse_container_line_full,test_parse_container_line_no_image,test_parse_container_line_invalid_returns_none,test_parse_system_info_basic,test_parse_system_info_disk,test_parse_system_info_memory,test_parse_system_info_unknown_lines_ignored,test_parse_diagnostics_sections,test_parse_diagnostics_empty,test_parse_diagnostics_docker_section_alias,test_parse_diagnostics_skips_no_markers,test_parse_health_info_full,test_parse_health_info_invalid_health_code,test_parse_health_info_empty
    test_parse_docker_ps_full_format()
    test_parse_docker_ps_partial_format()
    test_parse_docker_ps_skips_empty_lines()
    test_parse_docker_ps_skips_no_containers_marker()
    test_parse_docker_ps_empty()
    test_parse_container_line_full()
    test_parse_container_line_no_image()
    test_parse_container_line_invalid_returns_none()
    test_parse_system_info_basic()
    test_parse_system_info_disk()
    test_parse_system_info_memory()
    test_parse_system_info_unknown_lines_ignored()
    test_parse_diagnostics_sections()
    test_parse_diagnostics_empty()
    test_parse_diagnostics_docker_section_alias()
    test_parse_diagnostics_skips_no_markers()
    test_parse_health_info_full()
    test_parse_health_info_invalid_health_code()
    test_parse_health_info_empty()
  tests/test_prompt_llm.py:
    e: _load_env,build_c2004_schema,call_llm,test_schema_discovers_c2004_specs,test_schema_has_command_catalogue,test_schema_has_version_and_cwd,test_schema_has_iac_metadata,test_prompt_dry_run_plan_polish,test_prompt_deploy_english,test_prompt_diagnose_polish,test_prompt_fix_kiosk_polish,test_prompt_bump_minor,test_prompt_fix_with_hint,test_prompt_list_specs,test_prompt_plugin_template_list,test_prompt_plugin_template_generation,test_prompt_response_has_required_fields,test_prompt_argv_always_starts_with_redeploy,test_prompt_uses_real_spec_paths,test_prompt_cli_schema_only,test_prompt_cli_dry_run_no_confirm,test_parse_llm_response_escapes_control_characters,test_parse_llm_response_handles_markdown_fences,test_parse_llm_response_preserves_newlines,test_parse_llm_response_handles_trailing_commas,test_parse_llm_response_handles_raw_newlines_in_strings,test_parse_llm_response_extracts_json_from_surrounding_text
    _load_env()
    build_c2004_schema()
    call_llm(instruction;schema)
    test_schema_discovers_c2004_specs()
    test_schema_has_command_catalogue()
    test_schema_has_version_and_cwd()
    test_schema_has_iac_metadata()
    test_prompt_dry_run_plan_polish()
    test_prompt_deploy_english()
    test_prompt_diagnose_polish()
    test_prompt_fix_kiosk_polish()
    test_prompt_bump_minor()
    test_prompt_fix_with_hint()
    test_prompt_list_specs()
    test_prompt_plugin_template_list()
    test_prompt_plugin_template_generation()
    test_prompt_response_has_required_fields()
    test_prompt_argv_always_starts_with_redeploy()
    test_prompt_uses_real_spec_paths()
    test_prompt_cli_schema_only(tmp_path)
    test_prompt_cli_dry_run_no_confirm(tmp_path)
    test_parse_llm_response_escapes_control_characters()
    test_parse_llm_response_handles_markdown_fences()
    test_parse_llm_response_preserves_newlines()
    test_parse_llm_response_handles_trailing_commas()
    test_parse_llm_response_handles_raw_newlines_in_strings()
    test_parse_llm_response_extracts_json_from_surrounding_text()
  tests/test_redeploy.py:
    e: test_placeholder,test_import
    test_placeholder()
    test_import()
  tests/test_steps_kiosk.py:
    e: TestKioskStepsExistInLibrary,TestKanshiDsiOnly,TestAutostartKiosk,TestBrowserKioskScript,TestKioskStepsAllUnique
    TestKioskStepsExistInLibrary: test_kanshi_dsi_only_in_library(0),test_autostart_kiosk_in_library(0),test_browser_kiosk_script_in_library(0)
    TestKanshiDsiOnly: test_profile_name(0),test_outputs_on_are_strings(0),test_outputs_off_are_strings(0),test_compositor_set(0),test_risk_low(0),test_step_library_get_returns_copy(0),test_override_outputs_on(0)
    TestAutostartKiosk: test_entries_are_strings(0),test_compositor_set(0),test_risk_low(0)
    TestBrowserKioskScript: test_kiosk_script_path(0),test_browser_profile(0),test_risk_low(0)
    TestKioskStepsAllUnique: test_no_duplicate_ids(0)

Source Map

Top 5 modules by symbol density — signatures for LLM orientation.

redeploy.observe (redeploy/observe.py)

class AuditEntry:  # Single audit log entry — immutable snapshot of one deploymen
    def __init__(data)  # CC=1
    def ts()  # CC=1
    def host()  # CC=1
    def app()  # CC=1
    def from_strategy()  # CC=1
    def to_strategy()  # CC=1
    def ok()  # CC=1
    def elapsed_s()  # CC=1
    def steps_total()  # CC=1
    def steps_ok()  # CC=1
    def steps_failed()  # CC=1
    def pattern()  # CC=1
    def version()  # CC=1
    def dry_run()  # CC=1
    def steps()  # CC=1
    def error()  # CC=1
    def to_dict()  # CC=1
    def __repr__()  # CC=2
class DeployAuditLog:  # Persistent audit log — newline-delimited JSON at ``path``.
    def __init__(path)  # CC=1
    def record(plan, completed_steps)  # CC=11 ⚠
    def _append(entry)  # CC=1
    def load(limit)  # CC=5
    def tail(n)  # CC=1
    def filter(host, app, ok, since)  # CC=12 ⚠
    def clear()  # CC=2
class DeployReport:  # Human-readable post-deploy report from an AuditEntry.
    def __init__(entry)  # CC=1
    def text()  # CC=8
    def yaml()  # CC=1
    def summary_line()  # CC=2

redeploy.fleet (redeploy/fleet.py)

class DeviceArch:
class Stage:
class DeviceExpectation:  # Declarative assertions about required infrastructure on a de
class FleetDevice:  # Generic device descriptor — superset of ``deploy``'s DeviceC
    def ssh_user()  # CC=2
    def ssh_ip()  # CC=2
    def is_local()  # CC=1
    def is_prod()  # CC=2
    def has_tag(tag)  # CC=1
    def has_expectation(exp)  # CC=1
    def verify_expectations(state)  # CC=25 ⚠
class FleetConfig:  # Top-level fleet manifest — list of devices with stage / tag 
    def get_device(device_id)  # CC=3
    def by_tag(tag)  # CC=3
    def by_stage(stage)  # CC=3
    def by_strategy(strategy)  # CC=3
    def prod_devices()  # CC=1
    def from_file(cls, path, workspace_root)  # CC=1
class Fleet:  # Unified first-class fleet — wraps FleetConfig and/or DeviceR
    def __init__(devices)  # CC=1
    def from_file(cls, path)  # CC=1
    def from_registry(cls, path)  # CC=6
    def from_config(cls, config)  # CC=1
    def devices()  # CC=1
    def get(device_id)  # CC=3
    def by_tag(tag)  # CC=3
    def by_stage(stage)  # CC=3
    def by_strategy(strategy)  # CC=3
    def prod()  # CC=1
    def reachable(within_seconds)  # CC=5
    def merge(other)  # CC=3
    def __len__()  # CC=1
    def __iter__()  # CC=1
    def __repr__()  # CC=1

redeploy.ssh (redeploy/ssh.py)

class SshResult:
    def ok()  # CC=1
    def success()  # CC=1
    def out()  # CC=1
class SshClient:  # Execute commands on a remote host via SSH (or locally).
    def __init__(host, port, key, ssh_id)  # CC=1
    def key()  # CC=1
    def key(v)  # CC=1
    def run(cmd, timeout)  # CC=5
    def rsync(local_path, remote_path, exclude, delete, timeout)  # CC=7
    def scp(local_path, remote_path, timeout)  # CC=4
    def put_file(content, remote_path, mode)  # CC=5
    def is_reachable(timeout)  # CC=3
    def is_ssh_ready()  # CC=2
    def ping()  # CC=4
    def _run_local(cmd, timeout)  # CC=3
    def _ssh_opts()  # CC=2
    def _scp_opts()  # CC=2
    def _detect_ssh_key()  # CC=1
    def _detect_key()  # CC=6
class RemoteProbe:  # Thin wrapper kept for redeploy.detect compatibility.
    def __init__(host)  # CC=1
    def is_local()  # CC=1
    def is_local(v)  # CC=1
class RemoteExecutor:  # Thin wrapper kept for deploy.core compatibility.
    def __init__(device)  # CC=1
    def ssh_target()  # CC=1
    def ssh_opts()  # CC=1
    def scp_opts()  # CC=1

redeploy.heal (redeploy/heal.py)

def _ssh(host, command)  # CC=3, fan=2
def collect_diagnostics(host, failed_step)  # CC=2, fan=4
def ask_llm(failed_step, step_output, diag, spec_text, fix_hint)  # CC=8, fan=5
def apply_fix_to_spec(spec_path, failed_step, llm_response)  # CC=6, fan=10
def write_repair_log(spec_path, version, repairs)  # CC=6, fan=9
def parse_failed_step(executor_summary, executor)  # CC=8, fan=7
class HealLoopDetector:  # Detect repeated non-converging heal hints for a given step.
    def __init__(max_identical_hints)  # CC=2
    def observe(step_id, hint)  # CC=5
    def reset(step_id)  # CC=1
class HealRunner:  # Wraps Executor with self-healing loop.
    def __init__(migration, spec_path, host, fix_hint, max_retries, dry_run, console, version)  # CC=2
    def _make_executor(resume)  # CC=4
    def _reload_migration()  # CC=1
    def _run_executor_attempt(executor)  # CC=1
    def _collect_diag_with_hint(failed_step)  # CC=2
    def _extract_diag_hint(diag)  # CC=5
    def _ask_and_apply_fix(failed_step, step_output, diag)  # CC=7
    def _record_repair(failed_step, attempt, summary, diag_hint, fixed)  # CC=1
    def _is_repeating_loop(failed_step, summary, diag_hint)  # CC=1
    def _retry_after_heal()  # CC=1
    def run()  # CC=8

redeploy.mcp_server (redeploy/mcp_server.py)

def _redeploy_bin()  # CC=5, fan=4
def _run()  # CC=4, fan=4
def _validate_exec_ssh_inputs(host, command)  # CC=5, fan=3
def schema(directory)  # CC=1, fan=5
def plan_spec(spec, cwd)  # CC=1, fan=2
def run_spec(spec, force, dry_run, heal, fix_hint, cwd)  # CC=5, fan=3
def fix_spec(spec_or_dir, hint, bump, retries, dry_run, cwd)  # CC=4, fan=4
def bump_version(spec_or_dir, level, cwd)  # CC=3, fan=3
def diagnose(host)  # CC=1, fan=2
def list_specs(directory)  # CC=1, fan=6
def exec_ssh(host, command)  # CC=4, fan=4
def nlp_command(instruction, dry_run, cwd)  # CC=2, fan=2
def get_spec_content(path)  # CC=3, fan=5
def get_workspace()  # CC=1, fan=3
def serve(transport, host, port)  # CC=4, fan=4

Call Graph

438 nodes · 406 edges · 118 modules · CC̄=5.0

Hubs (by degree)

Function CC in out total
list (in redeploy.steps.StepLibrary) 1 51 2 53
snapshot_to_hardware_info (in redeploy.integrations.op3_bridge) 10 ⚠ 2 49 51
gh_workflow_run (in redeploy.cli.commands.gh_workflow) 19 ⚠ 0 49 49
lint (in redeploy.cli.commands.lint) 19 ⚠ 0 44 44
_heal_step (in redeploy.heal.runner.HealRunner) 14 ⚠ 0 40 40
exec_cmd (in redeploy.cli.commands.exec_) 9 0 40 40
_bump_single (in redeploy.cli.commands.version.helpers) 25 ⚠ 4 35 39
version_list (in redeploy.cli.commands.version.commands) 13 ⚠ 0 38 38
# code2llm call graph | /home/tom/github/maskservice/redeploy
# generated in 0.22s
# nodes: 438 | edges: 406 | modules: 118
# CC̄=5.0

HUBS[20]:
  redeploy.steps.StepLibrary.list
    CC=1  in:51  out:2  total:53
  redeploy.integrations.op3_bridge.snapshot_to_hardware_info
    CC=10  in:2  out:49  total:51
  redeploy.cli.commands.gh_workflow.gh_workflow_run
    CC=19  in:0  out:49  total:49
  redeploy.cli.commands.lint.lint
    CC=19  in:0  out:44  total:44
  redeploy.heal.runner.HealRunner._heal_step
    CC=14  in:0  out:40  total:40
  redeploy.cli.commands.exec_.exec_cmd
    CC=9  in:0  out:40  total:40
  redeploy.cli.commands.version.helpers._bump_single
    CC=25  in:4  out:35  total:39
  redeploy.cli.commands.version.commands.version_list
    CC=13  in:0  out:38  total:38
  redeploy.iac.config_hints.ConfigHintsParser._parse_k8s_yaml
    CC=26  in:0  out:38  total:38
  redeploy.cli.commands.plugin.plugin_cmd
    CC=13  in:0  out:38  total:38
  redeploy.cli.commands.prompt_cmd.prompt_cmd
    CC=15  in:0  out:37  total:37
  redeploy.discovery.auto_probe.auto_probe
    CC=7  in:4  out:33  total:37
  redeploy.blueprint.sources.compose._merge_compose
    CC=21  in:1  out:33  total:34
  redeploy.plugins.builtin.hardware_diagnostic._analyze_hardware
    CC=14  in:1  out:32  total:33
  redeploy.cli.commands.target.target
    CC=10  in:1  out:31  total:32
  redeploy.heal.hint_provider.apply_fix_to_spec
    CC=16  in:0  out:30  total:30
  redeploy.detect.detector.Detector.run
    CC=9  in:0  out:30  total:30
  examples.redeploy_iac_parsers.helm_kustomize.HelmTemplatesParser.parse
    CC=17  in:0  out:27  total:27
  redeploy.apply.executor.Executor._execute_step
    CC=4  in:0  out:27  total:27
  redeploy.apply.state_apply.HardwareStateHandler.apply
    CC=18  in:0  out:27  total:27

MODULES:
  examples.redeploy_iac_parsers.gitops_ci  [2 funcs]
    can_parse  CC=11  out:9
    _is_gitops_command  CC=2  out:2
  examples.redeploy_iac_parsers.helm_kustomize  [1 funcs]
    parse  CC=17  out:27
  redeploy.analyze.checkers.binary  [2 funcs]
    check  CC=7  out:8
    extract_binaries  CC=14  out:8
  redeploy.analyze.checkers.command_ref  [1 funcs]
    _check_external_ref  CC=6  out:8
  redeploy.analyze.checkers.compose  [6 funcs]
    check  CC=7  out:7
    _check_build_section  CC=7  out:12
    _check_env_files  CC=6  out:8
    _check_volumes  CC=11  out:12
    _is_ignored  CC=2  out:4
    scan_compose_file  CC=6  out:9
  redeploy.analyze.checkers.docker_build  [6 funcs]
    _check_remote_context  CC=12  out:12
    check  CC=4  out:8
    collect_sync_mappings  CC=5  out:10
    match_local_src  CC=5  out:3
    parse_docker_build  CC=9  out:7
    resolve_local_dockerfile  CC=3  out:6
  redeploy.analyze.checkers.path  [4 funcs]
    check  CC=9  out:13
    _check_field  CC=9  out:15
    is_inside  CC=2  out:3
    resolve_local_path  CC=3  out:6
  redeploy.analyze.ignore  [2 funcs]
    is_ignored  CC=9  out:10
    ensure_redeployignore  CC=2  out:2
  redeploy.analyze.models  [1 funcs]
    add  CC=2  out:2
  redeploy.analyze.preflight_schema  [6 funcs]
    _collect_local_artifacts  CC=6  out:16
    _collect_remote_checks  CC=8  out:14
    _resolve_command_refs  CC=11  out:20
    _resolve_local_path  CC=4  out:7
    generate_preflight_schema  CC=14  out:25
    save_preflight_schema  CC=1  out:3
  redeploy.analyze.spec_analyzer  [2 funcs]
    __init__  CC=3  out:2
    analyze_file  CC=7  out:10
  redeploy.apply.executor  [3 funcs]
    __init__  CC=14  out:8
    _execute_step  CC=4  out:27
    _rollback  CC=1  out:1
  redeploy.apply.handlers  [15 funcs]
    _all_containers_healthy  CC=5  out:2
    _ensure_remote_parent_dir  CC=7  out:6
    _format_step_output  CC=6  out:7
    _parse_container_statuses  CC=6  out:8
    _resolve_command_ref  CC=6  out:10
    run_docker_build  CC=1  out:1
    run_docker_health_wait  CC=10  out:11
    run_ensure_autostart_entry  CC=16  out:21
    run_ensure_config_line  CC=7  out:9
    run_inline_script  CC=6  out:7
  redeploy.apply.rollback  [1 funcs]
    rollback_steps  CC=8  out:8
  redeploy.apply.state  [6 funcs]
    reset  CC=1  out:2
    save  CC=5  out:11
    _now_iso  CC=1  out:2
    _slug  CC=5  out:3
    default_state_path  CC=2  out:2
    state_key  CC=1  out:7
  redeploy.apply.state_apply  [4 funcs]
    apply  CC=18  out:27
    _update_kanshi  CC=9  out:17
    apply_state  CC=2  out:4
    detect_handler  CC=3  out:1
  redeploy.apply.utils.run_container_build  [1 funcs]
    run_container_build  CC=10  out:21
  redeploy.audit  [1 funcs]
    audit_spec  CC=1  out:3
  redeploy.audit.extractor  [1 funcs]
    _from_target  CC=7  out:9
  redeploy.audit.paths  [2 funcs]
    extract_port  CC=5  out:6
    normalize_path  CC=3  out:5
  redeploy.blueprint.extractor  [1 funcs]
    extract_blueprint  CC=22  out:23
  redeploy.blueprint.generators.docker_compose  [2 funcs]
    _build_service  CC=20  out:8
    generate_twin  CC=11  out:3
  redeploy.blueprint.sources.compose  [6 funcs]
    _merge_compose  CC=21  out:33
    _parse_compose_env  CC=7  out:8
    _parse_compose_healthcheck  CC=6  out:6
    _parse_compose_ports  CC=7  out:21
    _parse_compose_volumes  CC=8  out:13
    merge_compose_files  CC=2  out:1
  redeploy.blueprint.sources.hardware  [1 funcs]
    build_hw_requirements  CC=13  out:15
  redeploy.blueprint.sources.infra  [1 funcs]
    infer_app_url  CC=8  out:1
  redeploy.cli  [3 funcs]
    _resolve_device  CC=5  out:12
    _setup_logging  CC=2  out:2
    cli  CC=1  out:5
  redeploy.cli.commands.blueprint  [2 funcs]
    _execute_query_blueprint  CC=1  out:1
    show  CC=4  out:18
  redeploy.cli.commands.bump_fix  [9 funcs]
    _bump_patch  CC=2  out:7
    _bump_version_file  CC=1  out:5
    _detect_version  CC=2  out:3
    _find_spec  CC=15  out:22
    _find_version_file  CC=3  out:2
    _prompt_choose_spec  CC=5  out:9
    _update_migration_header  CC=2  out:7
    _update_quadlet_service_version  CC=6  out:9
    bump_cmd  CC=6  out:23
  redeploy.cli.commands.device_map_actions  [2 funcs]
    execute_query_device_map  CC=1  out:1
    probe_device_map  CC=9  out:15
  redeploy.cli.commands.device_map_renderers  [5 funcs]
    _build_drm_table  CC=9  out:8
    _build_header_panel  CC=4  out:3
    _build_issues_table  CC=3  out:12
    _build_services_table  CC=7  out:9
    render_rich  CC=22  out:22
  redeploy.cli.commands.devices  [1 funcs]
    devices  CC=4  out:14
  redeploy.cli.commands.devices_display  [2 funcs]
    filter_devices  CC=13  out:0
    render_devices_table  CC=7  out:16
  redeploy.cli.commands.diagnose  [1 funcs]
    diagnose  CC=5  out:19
  redeploy.cli.commands.exec_  [3 funcs]
    _extract_all_scripts  CC=3  out:7
    _extract_script_for_ref  CC=2  out:1
    exec_cmd  CC=9  out:40
  redeploy.cli.commands.export  [4 funcs]
    _export_to_css  CC=2  out:2
    _find_export_source  CC=9  out:10
    _load_manifest_from_css  CC=1  out:1
    export_cmd  CC=7  out:23
  redeploy.cli.commands.gh_workflow  [12 funcs]
    _collect_workflow_meta  CC=3  out:10
    _find_repo_root  CC=4  out:3
    _has_workflow_dispatch  CC=4  out:3
    _load_yaml  CC=4  out:5
    _on_section  CC=1  out:2
    _resolve_repo_root  CC=3  out:5
    _resolve_workflow_identifier  CC=10  out:11
    _trigger_list  CC=6  out:6
    _workflows_dir  CC=2  out:2
    gh_workflow_analyze  CC=7  out:20
  redeploy.cli.commands.hardware  [4 funcs]
    _apply_fix  CC=8  out:18
    _apply_transform  CC=4  out:4
    _execute_query  CC=1  out:2
    _probe_hardware  CC=4  out:6
  redeploy.cli.commands.import_  [4 funcs]
    _copy_plugin_template  CC=3  out:12
    _examples_plugin_dir  CC=1  out:2
    _plugin_templates  CC=1  out:0
    _print_plugin_templates  CC=2  out:4
  redeploy.cli.commands.inspect  [2 funcs]
    _find_css_path  CC=4  out:4
    inspect  CC=4  out:22
  redeploy.cli.commands.lint  [1 funcs]
    lint  CC=19  out:44
  redeploy.cli.commands.mcp_cmd  [1 funcs]
    mcp_cmd  CC=1  out:6
  redeploy.cli.commands.plan_apply_report  [10 funcs]
    _parse_rsync_output  CC=13  out:8
    _render_checksum_section  CC=7  out:13
    _run_rsync_checksum  CC=6  out:10
    _skipped_checksum  CC=1  out:1
    build_checksum_verification  CC=14  out:15
    default_report_path  CC=1  out:0
    render_markdown_report  CC=12  out:13
    resolve_audit_entry  CC=10  out:16
    step_command_block  CC=14  out:5
    write_markdown_report  CC=2  out:7
  redeploy.cli.commands.plan_apply_run  [1 funcs]
    run_preflight_phase  CC=8  out:19
  redeploy.cli.commands.plan_apply_shared  [2 funcs]
    apply_manifest_to_spec  CC=8  out:9
    load_spec_for_run  CC=4  out:6
  redeploy.cli.commands.plugin  [1 funcs]
    plugin_cmd  CC=13  out:38
  redeploy.cli.commands.probe_display  [1 funcs]
    collect_probe_hosts  CC=6  out:8
  redeploy.cli.commands.prompt_cmd  [1 funcs]
    prompt_cmd  CC=15  out:37
  redeploy.cli.commands.state  [4 funcs]
    _get_state_path  CC=5  out:5
    _list_checkpoints  CC=7  out:17
    _show_checkpoint  CC=4  out:11
    state_cmd  CC=4  out:16
  redeploy.cli.commands.target  [1 funcs]
    target  CC=10  out:31
  redeploy.cli.commands.version.commands  [2 funcs]
    version_list  CC=13  out:38
    version_verify  CC=7  out:18
  redeploy.cli.commands.version.helpers  [10 funcs]
    _build_package_version_manifest  CC=2  out:5
    _bump_single  CC=25  out:35
    _load_live_version_diff  CC=3  out:4
    _load_spec_version_diff  CC=8  out:13
    _print_source_drift_status  CC=7  out:6
    _print_verify_result  CC=6  out:5
    _resolve_monorepo_targets  CC=8  out:11
    _resolve_package_release_changelog_config  CC=5  out:2
    _resolve_package_release_git_config  CC=5  out:5
    _run_version_diff_for_manifest  CC=7  out:11
  redeploy.cli.commands.version.monorepo  [5 funcs]
    _create_version_set_git  CC=6  out:3
    _create_version_set_taggers  CC=2  out:2
    _finalize_monorepo_version_set  CC=11  out:8
    _print_monorepo_set_dry_run  CC=3  out:5
    _set_monorepo_version  CC=8  out:13
  redeploy.cli.commands.version.release  [5 funcs]
    _create_release_tags  CC=3  out:5
    _format_release_tag  CC=1  out:1
    _resolve_package_release_changelog_config  CC=5  out:2
    _update_monorepo_release_changelogs  CC=5  out:12
    _update_release_changelog  CC=7  out:7
  redeploy.cli.commands.version.scanner  [17 funcs]
    _classify_version_scan_source_confidence  CC=3  out:0
    _default_keep_scanned_source  CC=2  out:0
    _derive_scanned_package_name  CC=4  out:5
    _detect_source_version  CC=2  out:1
    _detect_version_sources_in_dir  CC=13  out:17
    _format_version_scan_source_status  CC=2  out:2
    _is_scannable_version_path  CC=2  out:1
    _iter_version_scan_groups  CC=4  out:1
    _print_version_scan_group  CC=3  out:4
    _print_version_scan_review  CC=6  out:5
  redeploy.cli.commands.workflow  [2 funcs]
    _execute_workflow  CC=6  out:8
    workflow_cmd  CC=10  out:21
  redeploy.cli.core  [5 funcs]
    find_manifest_path  CC=3  out:5
    load_spec_or_exit  CC=2  out:3
    load_spec_with_manifest  CC=5  out:8
    resolve_device  CC=5  out:12
    run_detect_workflow  CC=4  out:8
  redeploy.cli.display  [18 funcs]
    _format_workflow_header  CC=2  out:1
    _get_plugin_hint  CC=5  out:1
    _get_status_color  CC=3  out:0
    _print_alternatives  CC=5  out:2
    _print_host_header  CC=1  out:1
    _print_services_table  CC=9  out:14
    _print_spec_metadata  CC=4  out:6
    _print_template_match  CC=5  out:7
    _print_workflow_step  CC=4  out:4
    generate_workflow_output_css  CC=8  out:9
  redeploy.cli.query  [1 funcs]
    execute_query  CC=5  out:9
  redeploy.config_apply.applier  [3 funcs]
    _normalize_hardware  CC=4  out:2
    apply_config_dict  CC=1  out:2
    apply_config_file  CC=4  out:6
  redeploy.config_apply.handlers.display  [2 funcs]
    _validate_display_inputs  CC=3  out:4
    apply_display_transform  CC=7  out:25
  redeploy.config_apply.loader  [1 funcs]
    load_config_file  CC=3  out:4
  redeploy.detect.detector  [2 funcs]
    probe_hardware  CC=2  out:4
    run  CC=9  out:30
  redeploy.detect.hardware  [2 funcs]
    _wrap_remote_probe  CC=1  out:2
    probe_hardware  CC=4  out:10
  redeploy.detect.hardware_rules  [3 funcs]
    _hw_info_to_dict  CC=2  out:2
    _op3_diag_to_hw_diag  CC=1  out:5
    analyze  CC=3  out:4
  redeploy.detect.probes  [4 funcs]
    detect_conflicts  CC=13  out:12
    probe_iptables_dnat  CC=7  out:5
    probe_ports  CC=6  out:11
    probe_runtime  CC=5  out:16
  redeploy.detect.templates  [4 funcs]
    detect  CC=2  out:3
    _build_templates  CC=1  out:1
    _load_templates_from_yaml  CC=9  out:22
    build_context  CC=2  out:1
  redeploy.detect.workflow  [2 funcs]
    _collect_hosts  CC=18  out:14
    _probe_ssh  CC=3  out:3
  redeploy.discovery.auto_probe  [6 funcs]
    auto_probe  CC=7  out:33
    build_probe_command  CC=1  out:0
    build_ssh_command  CC=1  out:1
    detect_strategy_remote  CC=3  out:5
    parse_probe_input  CC=4  out:1
    run_ssh_probe  CC=3  out:1
  redeploy.discovery.helpers  [2 funcs]
    is_ip  CC=1  out:2
    run_shell  CC=2  out:1
  redeploy.discovery.registry  [3 funcs]
    _new_discovered_device  CC=3  out:2
    _update_existing_device  CC=7  out:1
    update_registry  CC=9  out:9
  redeploy.discovery.scanners  [8 funcs]
    detect_local_subnet  CC=9  out:11
    discover  CC=14  out:22
    merge_hosts  CC=11  out:2
    ping_sweep  CC=6  out:20
    probe_ssh_batch  CC=1  out:6
    scan_arp_cache  CC=10  out:23
    scan_known_hosts  CC=10  out:18
    scan_mdns  CC=6  out:11
  redeploy.discovery.ssh_credentials  [3 funcs]
    collect_ssh_keys  CC=14  out:16
    tcp_reachable  CC=2  out:1
    try_ssh_credentials  CC=14  out:15
  redeploy.discovery_probe  [2 funcs]
    infer_strategy  CC=8  out:5
    parse_probe_output  CC=16  out:20
  redeploy.dsl.loader  [9 funcs]
    _build_from_nodes  CC=1  out:4
    _build_manifest  CC=25  out:23
    _build_templates  CC=14  out:24
    _build_workflows  CC=8  out:16
    _condition_key  CC=4  out:5
    load_css  CC=1  out:4
    load_css_text  CC=2  out:4
    manifest_to_css  CC=14  out:17
    templates_to_css  CC=6  out:13
  redeploy.dsl.parser  [3 funcs]
    __repr__  CC=2  out:4
    parse  CC=6  out:23
    _strip_comments  CC=1  out:3
  redeploy.dsl_python.runner  [1 funcs]
    list_migrations  CC=5  out:13
  redeploy.dsl_python.steps  [2 funcs]
    ssh  CC=4  out:4
    version_check  CC=7  out:10
  redeploy.fleet  [4 funcs]
    __init__  CC=1  out:1
    from_registry  CC=6  out:5
    get  CC=3  out:1
    merge  CC=3  out:3
  redeploy.hardware.config_txt  [2 funcs]
    ensure_line  CC=14  out:20
    ensure_lines  CC=4  out:4
  redeploy.hardware.fixes  [6 funcs]
    _detect_port  CC=6  out:0
    _step  CC=1  out:1
    fix_dsi_not_enabled  CC=6  out:20
    fix_enable_i2c  CC=1  out:1
    fix_enable_spi  CC=1  out:1
    generate_fix_plan  CC=7  out:3
  redeploy.hardware.kiosk.autostart  [1 funcs]
    ensure_autostart_entry  CC=6  out:6
  redeploy.hardware.kiosk.browsers  [1 funcs]
    build_launch_cmd  CC=5  out:3
  redeploy.hardware.panels  [1 funcs]
    infer_from_hardware  CC=1  out:0
  redeploy.hardware.raspi_config  [1 funcs]
    build_raspi_config_command  CC=3  out:2
  redeploy.heal  [12 funcs]
    observe  CC=5  out:4
    _ask_and_apply_fix  CC=7  out:15
    _collect_diag_with_hint  CC=2  out:2
    _record_repair  CC=1  out:2
    _reload_migration  CC=1  out:4
    run  CC=8  out:19
    _ssh  CC=3  out:2
    apply_fix_to_spec  CC=6  out:15
    ask_llm  CC=8  out:8
    collect_diagnostics  CC=2  out:4
  redeploy.heal.hint_provider  [6 funcs]
    _extract_step_block  CC=2  out:4
    _parse_step_block  CC=6  out:4
    _ssh  CC=3  out:2
    apply_fix_to_spec  CC=16  out:30
    ask_llm  CC=12  out:22
    collect_diagnostics  CC=2  out:4
  redeploy.heal.loop_detector  [1 funcs]
    observe  CC=5  out:4
  redeploy.heal.runner  [3 funcs]
    _heal_step  CC=14  out:40
    _reload_migration  CC=1  out:4
    run  CC=10  out:24
  redeploy.iac.config_hints  [1 funcs]
    _parse_k8s_yaml  CC=26  out:38
  redeploy.iac.docker_compose  [11 funcs]
    _load_merged  CC=6  out:9
    _parse_service_depends_on  CC=4  out:6
    _parse_service_env  CC=2  out:4
    _parse_service_networks  CC=4  out:6
    _parse_service_ports  CC=5  out:6
    _parse_service_volumes  CC=4  out:3
    _resolve_image_and_build  CC=7  out:8
    _env_dict  CC=7  out:6
    _parse_port  CC=10  out:21
    _parse_volume  CC=5  out:14
  redeploy.iac.parsers.compose  [2 funcs]
    _parse_depends_on  CC=5  out:6
    _parse_service_networks  CC=2  out:2
  redeploy.integrations.op3_bridge  [3 funcs]
    snapshot_to_device_map  CC=7  out:10
    snapshot_to_hardware_info  CC=10  out:49
    snapshot_to_infra_state  CC=3  out:2
  redeploy.markpact.compiler  [6 funcs]
    _deep_merge  CC=5  out:4
    _extract_steps  CC=9  out:20
    _load_block_payload  CC=8  out:7
    _normalize_config_payload  CC=11  out:18
    compile_markpact_document  CC=2  out:4
    compile_markpact_document_to_data  CC=6  out:8
  redeploy.markpact.parser  [10 funcs]
    _check_heading  CC=5  out:5
    _handle_fence_line  CC=7  out:7
    _normalize_section_id  CC=1  out:3
    _parse_markpact_fence_info  CC=14  out:10
    extract_script_by_ref  CC=12  out:11
    extract_script_from_markdown  CC=10  out:10
    parse_markpact_file  CC=1  out:3
    parse_markpact_file_with_refs  CC=6  out:6
    parse_markpact_text  CC=7  out:8
    resolve_script_ref  CC=6  out:5
  redeploy.mcp_server  [14 funcs]
    _redeploy_bin  CC=5  out:4
    _run  CC=4  out:4
    _validate_exec_ssh_inputs  CC=5  out:3
    bump_version  CC=3  out:4
    diagnose  CC=1  out:2
    exec_ssh  CC=4  out:4
    fix_spec  CC=4  out:5
    get_workspace  CC=1  out:3
    list_specs  CC=1  out:6
    nlp_command  CC=2  out:2
  redeploy.models.manifest  [2 funcs]
    find_and_load  CC=6  out:9
    find_css  CC=4  out:4
  redeploy.models.spec  [3 funcs]
    from_file  CC=2  out:5
    to_target_config  CC=2  out:2
    _migrate_legacy_post_deploy  CC=5  out:20
  redeploy.observe  [1 funcs]
    record  CC=11  out:20
  redeploy.parse  [7 funcs]
    _apply_git_line  CC=3  out:3
    _apply_health_line  CC=2  out:1
    _apply_network_line  CC=3  out:2
    _apply_system_line  CC=8  out:10
    _parse_section_line  CC=7  out:6
    parse_container_line  CC=3  out:3
    parse_diagnostics  CC=5  out:4
  redeploy.patterns  [6 funcs]
    expand  CC=2  out:14
    expand  CC=5  out:13
    expand  CC=1  out:8
    _step  CC=1  out:1
    get_pattern  CC=1  out:1
    list_patterns  CC=1  out:2
  redeploy.plan.planner  [1 funcs]
    _plan_pattern  CC=10  out:17
  redeploy.plugins  [5 funcs]
    _ensure_builtins  CC=2  out:1
    names  CC=1  out:2
    _load_builtin_plugins  CC=6  out:7
    load_user_plugins  CC=3  out:4
    register_plugin  CC=1  out:1
  redeploy.plugins.builtin.browser_reload  [1 funcs]
    browser_reload  CC=16  out:26
  redeploy.plugins.builtin.hardware_diagnostic  [11 funcs]
    _analyze_hardware  CC=14  out:32
    _check_gpio  CC=2  out:2
    _detect_platform  CC=10  out:6
    _get_audio_devices  CC=3  out:5
    _get_cpu_info  CC=5  out:10
    _get_memory_mb  CC=3  out:5
    _get_network_interfaces  CC=5  out:6
    _get_storage_gb  CC=6  out:11
    _get_usb_devices  CC=4  out:5
    _run_command  CC=2  out:3
  redeploy.plugins.builtin.notify  [6 funcs]
    _fmt  CC=1  out:3
    _http_post  CC=5  out:10
    _notify_slack  CC=3  out:7
    _notify_webhook  CC=6  out:16
    _resolve_env  CC=1  out:1
    notify  CC=4  out:5
  redeploy.plugins.builtin.process_control  [2 funcs]
    _find_pid_on_port  CC=11  out:14
    process_control  CC=9  out:19
  redeploy.plugins.builtin.systemd_reload  [1 funcs]
    systemd_reload  CC=12  out:23
  redeploy.schema  [5 funcs]
    _discover_specs  CC=14  out:26
    _git_branch  CC=3  out:2
    _iac_info  CC=2  out:0
    _read_version  CC=3  out:4
    build_schema  CC=2  out:7
  redeploy.spec_loader  [1 funcs]
    load_migration_spec  CC=4  out:8
  redeploy.steps  [2 funcs]
    all  CC=2  out:2
    list  CC=1  out:2
  redeploy.version  [1 funcs]
    read_remote_version  CC=4  out:3
  redeploy.version.bump  [6 funcs]
    _calculate_bump  CC=8  out:10
    bump_all_packages  CC=3  out:5
    bump_package  CC=9  out:13
    bump_version  CC=6  out:9
    bump_version_with_git  CC=13  out:14
    verify_sources  CC=4  out:7
  redeploy.version.changelog  [2 funcs]
    _categorize_commits  CC=3  out:3
    get_commits_since_tag  CC=5  out:3
  redeploy.version.commits  [3 funcs]
    analyze_commits  CC=18  out:25
    format_analysis_report  CC=2  out:3
    parse_conventional  CC=4  out:6
  redeploy.version.diff  [2 funcs]
    diff_manifest_vs_live  CC=2  out:2
    diff_manifest_vs_spec  CC=4  out:7
  redeploy.version.manifest  [1 funcs]
    list_packages  CC=2  out:2
  redeploy.version.sources  [1 funcs]
    get_adapter  CC=2  out:1
  redeploy.version.transaction  [1 funcs]
    _stage_one  CC=6  out:7

EDGES:
  redeploy.schema.build_schema → redeploy.schema._read_version
  redeploy.schema.build_schema → redeploy.schema._git_branch
  redeploy.schema.build_schema → redeploy.schema._discover_specs
  redeploy.schema.build_schema → redeploy.schema._iac_info
  redeploy.observe.DeployAuditLog.record → redeploy.steps.StepLibrary.list
  redeploy.heal.collect_diagnostics → redeploy.heal._ssh
  redeploy.heal.HealLoopDetector.observe → redeploy.steps.StepLibrary.all
  redeploy.heal.HealRunner._reload_migration → redeploy.spec_loader.load_migration_spec
  redeploy.heal.HealRunner._collect_diag_with_hint → redeploy.heal.collect_diagnostics
  redeploy.heal.HealRunner._ask_and_apply_fix → redeploy.heal.ask_llm
  redeploy.heal.HealRunner._ask_and_apply_fix → redeploy.heal.apply_fix_to_spec
  redeploy.heal.HealRunner._record_repair → redeploy.heal.write_repair_log
  redeploy.heal.HealRunner.run → redeploy.heal.write_repair_log
  redeploy.heal.HealRunner.run → redeploy.heal.parse_failed_step
  redeploy.parse.parse_diagnostics → redeploy.parse._parse_section_line
  redeploy.parse._parse_section_line → redeploy.parse._apply_system_line
  redeploy.parse._parse_section_line → redeploy.parse.parse_container_line
  redeploy.parse._parse_section_line → redeploy.parse._apply_git_line
  redeploy.parse._parse_section_line → redeploy.parse._apply_health_line
  redeploy.parse._parse_section_line → redeploy.parse._apply_network_line
  redeploy.fleet.Fleet.__init__ → redeploy.steps.StepLibrary.list
  redeploy.fleet.Fleet.from_registry → redeploy.steps.StepLibrary.list
  redeploy.fleet.Fleet.merge → redeploy.steps.StepLibrary.list
  redeploy.spec_loader.load_migration_spec → redeploy.markpact.compiler.compile_markpact_document
  redeploy.spec_loader.load_migration_spec → redeploy.markpact.parser.parse_markpact_file
  redeploy.patterns.BlueGreenPattern.expand → redeploy.patterns._step
  redeploy.patterns.CanaryPattern.expand → redeploy.patterns._step
  redeploy.patterns.RollbackOnFailurePattern.expand → redeploy.patterns._step
  redeploy.patterns.list_patterns → redeploy.steps.StepLibrary.list
  redeploy.mcp_server._run → redeploy.mcp_server._redeploy_bin
  redeploy.mcp_server.schema → redeploy.schema.build_schema
  redeploy.mcp_server.plan_spec → redeploy.mcp_server._run
  redeploy.mcp_server.run_spec → redeploy.mcp_server._run
  redeploy.mcp_server.fix_spec → redeploy.mcp_server._run
  redeploy.mcp_server.bump_version → redeploy.mcp_server._run
  redeploy.mcp_server.diagnose → redeploy.mcp_server._run
  redeploy.mcp_server.list_specs → redeploy.schema.build_schema
  redeploy.mcp_server.exec_ssh → redeploy.mcp_server._validate_exec_ssh_inputs
  redeploy.mcp_server.nlp_command → redeploy.mcp_server._run
  redeploy.mcp_server.get_workspace → redeploy.schema.build_schema
  redeploy.detect.detector.Detector.run → redeploy.detect.probes.probe_runtime
  redeploy.detect.detector.Detector.run → redeploy.detect.probes.probe_ports
  redeploy.detect.detector.Detector.run → redeploy.detect.probes.probe_iptables_dnat
  redeploy.detect.hardware.probe_hardware → redeploy.detect.hardware._wrap_remote_probe
  redeploy.detect.hardware.probe_hardware → redeploy.integrations.op3_bridge.snapshot_to_hardware_info
  redeploy.detect.hardware.probe_hardware → redeploy.steps.StepLibrary.list
  redeploy.detect.hardware_rules.analyze → redeploy.detect.hardware_rules._hw_info_to_dict
  redeploy.detect.hardware_rules.analyze → redeploy.detect.hardware_rules._op3_diag_to_hw_diag
  redeploy.detect.templates._build_templates → redeploy.detect.templates._load_templates_from_yaml
  redeploy.detect.templates.TemplateEngine.detect → redeploy.detect.templates.build_context

Test Contracts

Scenarios as contract signatures — what the system guarantees.

Cli (1)

CLI Command Tests

Integration (1)

Auto-generated from Python Tests

Intent

Infrastructure migration toolkit: detect → plan → apply