evolution 9 min read

SEADF: Self-Evolving Autonomous Development Framework

The SEADF framework for autonomous platform development: five-phase cycle (discover, plan, execute, validate, integrate), guardrails, and human review thresholds.

Tomas Korcak (korczis) 337 words

The Self-Evolving Autonomous Development Framework (SEADF) is a structured approach to AI-assisted platform development. It defines a five-phase cycle where AI agents discover improvement opportunities, plan changes, execute implementations, validate results, and integrate approved changes. The key innovation is the guardrail system that determines when human review is required versus when changes can proceed autonomously.

The Five-Phase Cycle

SEADF operates as a continuous loop. Each phase has defined inputs, outputs, and quality gates:

PhaseInputOutputGate
DiscoverPlatform metrics, code analysisImprovement opportunitiesPriority threshold
PlanOpportunity specImplementation planComplexity limit
ExecutePlan + codebaseCode changes + testsCompilation pass
ValidateChanges + test resultsQuality assessmentDoctrine compliance
IntegrateValidated changesMerged codeHuman review threshold

Phase 1: Discovery

The discovery phase scans the platform for improvement opportunities using static analysis, telemetry data, and doctrine compliance reports:

defmodule PrismaticSeadf.Phases.Discover do
  @moduledoc """
  SEADF Discovery Phase.

  Scans the platform for improvement opportunities by analyzing
  code quality metrics, telemetry data, doctrine compliance gaps,
  and dependency health. Produces prioritized opportunity specs.
  """

  alias PrismaticQuality.Doctrines
  alias PrismaticTelemetry.Metrics

  @type opportunity :: %{
    id: String.t(),
    type: :quality | :performance | :security | :feature,
    priority: float(),
    description: String.t(),
    affected_modules: [module()],
    estimated_effort: :trivial | :small | :medium | :large,
    doctrine_pillar: atom() | nil
  }

  @spec discover() :: [opportunity()]
  def discover do
    [
      discover_doctrine_gaps(),
      discover_performance_issues(),
      discover_security_gaps(),
      discover_test_coverage_gaps()
    ]
    |> List.flatten()
    |> Enum.sort_by(& &1.priority, :desc)
    |> Enum.take(20)
  end

  defp discover_doctrine_gaps do
    results = Doctrines.validate_all()

    for {pillar, %{status: :fail, violations: violations}} <- results,
        violation <- violations do
      %{
        id: "doctrine-#{pillar}-#{hash(violation)}",
        type: :quality,
        priority: pillar_priority(pillar),
        description: "#{pillar} violation: #{violation.message}",
        affected_modules: [violation.module],
        estimated_effort: violation_effort(violation),
        doctrine_pillar: pillar
      }
    end
  end

  defp discover_performance_issues do
    slow_endpoints = Metrics.endpoints_above_threshold(250)

    Enum.map(slow_endpoints, fn endpoint ->
      %{
        id: "perf-#{hash(endpoint.path)}",
        type: :performance,
        priority: endpoint.avg_ms / 1000.0,
        description: "Slow endpoint: #{endpoint.path} (#{endpoint.avg_ms}ms avg)",
        affected_modules: [endpoint.controller],
        estimated_effort: :medium,
        doctrine_pillar: :PERF
      }
    end)
  end

  defp pillar_priority(:ZERO), do: 0.95
  defp pillar_priority(:SEAL), do: 0.9
  defp pillar_priority(:PERF), do: 0.8
  defp pillar_priority(:TACH), do: 0.7
  defp pillar_priority(_), do: 0.5

  defp hash(term), do: :erlang.phash2(term) |> Integer.to_string(16)
end

Phase 2: Planning

The planning phase takes an opportunity spec and generates an implementation plan. Plans are constrained by complexity limits to keep individual changes reviewable:

defmodule PrismaticSeadf.Phases.Plan do
  @moduledoc """
  SEADF Planning Phase.

  Generates implementation plans from opportunity specs.
  Plans are decomposed into steps of 5 minutes or less
  per M5M doctrine. Complex opportunities are split
  into multiple sequential plans.
  """

  @type plan :: %{
    id: String.t(),
    opportunity_id: String.t(),
    steps: [step()],
    estimated_duration: non_neg_integer(),
    complexity: :trivial | :simple | :moderate | :complex,
    requires_human_review: boolean(),
    affected_files: [String.t()]
  }

  @type step :: %{
    order: non_neg_integer(),
    action: :modify | :create | :delete | :test,
    target: String.t(),
    description: String.t(),
    estimated_minutes: non_neg_integer()
  }

  @max_autonomous_complexity :moderate
  @max_step_minutes 5

  @spec plan(Discover.opportunity()) :: {:ok, plan()} | {:error, term()}
  def plan(opportunity) do
    steps = generate_steps(opportunity)
    complexity = assess_complexity(steps)

    plan = %{
      id: "plan-#{generate_id()}",
      opportunity_id: opportunity.id,
      steps: steps,
      estimated_duration: Enum.sum(Enum.map(steps, & &1.estimated_minutes)),
      complexity: complexity,
      requires_human_review: complexity_exceeds_threshold?(complexity),
      affected_files: extract_affected_files(steps)
    }

    if valid_plan?(plan) do
      {:ok, plan}
    else
      {:error, :plan_exceeds_limits}
    end
  end

  defp assess_complexity(steps) do
    file_count = steps |> Enum.map(& &1.target) |> Enum.uniq() |> length()
    total_minutes = Enum.sum(Enum.map(steps, & &1.estimated_minutes))

    cond do
      file_count <= 1 and total_minutes <= 5 -> :trivial
      file_count <= 3 and total_minutes <= 15 -> :simple
      file_count <= 8 and total_minutes <= 30 -> :moderate
      true -> :complex
    end
  end

  defp complexity_exceeds_threshold?(complexity) do
    complexity_rank(complexity) > complexity_rank(@max_autonomous_complexity)
  end

  defp complexity_rank(:trivial), do: 0
  defp complexity_rank(:simple), do: 1
  defp complexity_rank(:moderate), do: 2
  defp complexity_rank(:complex), do: 3

  defp generate_id, do: Base.encode16(:crypto.strong_rand_bytes(4), case: :lower)
end

Phase 3: Execution

The execution phase applies the plan's steps to the codebase. Each step is executed atomically with rollback capability:

defmodule PrismaticSeadf.Phases.Execute do
  @moduledoc """
  SEADF Execution Phase.

  Applies plan steps to the codebase. Each step is executed
  atomically: if a step fails, all previous steps for this
  plan are rolled back. Tracks execution timing for M5M
  compliance monitoring.
  """

  require Logger

  @spec execute(Plan.plan()) :: {:ok, map()} | {:error, term()}
  def execute(plan) do
    Logger.info("SEADF executing plan #{plan.id} (#{length(plan.steps)} steps)")

    result =
      Enum.reduce_while(plan.steps, {:ok, []}, fn step, {:ok, completed} ->
        start_time = System.monotonic_time(:millisecond)

        case execute_step(step) do
          {:ok, result} ->
            duration = System.monotonic_time(:millisecond) - start_time
            Logger.info("Step #{step.order} completed in #{duration}ms")
            {:cont, {:ok, [{step, result, duration} | completed]}}

          {:error, reason} ->
            Logger.warning("Step #{step.order} failed: #{inspect(reason)}, rolling back")
            rollback(completed)
            {:halt, {:error, {step.order, reason}}}
        end
      end)

    case result do
      {:ok, completed} ->
        {:ok, %{
          plan_id: plan.id,
          steps_completed: length(completed),
          total_duration_ms: completed |> Enum.map(&elem(&1, 2)) |> Enum.sum(),
          changes: Enum.map(completed, fn {step, result, _} -> {step.target, result} end)
        }}

      {:error, _} = error ->
        error
    end
  end

  defp execute_step(%{action: :modify, target: path, description: desc}) do
    Logger.debug("Modifying #{path}: #{desc}")
    # Apply the planned modification
    apply_modification(path, desc)
  end

  defp execute_step(%{action: :test, target: path}) do
    Logger.debug("Running tests for #{path}")
    run_tests(path)
  end

  defp rollback(completed_steps) do
    for {step, _result, _duration} <- completed_steps do
      Logger.info("Rolling back step #{step.order}: #{step.target}")
      revert_step(step)
    end
  end
end

Phase 4: Validation

The validation phase runs the full quality gate suite against the changes:

defmodule PrismaticSeadf.Phases.Validate do
  @moduledoc """
  SEADF Validation Phase.

  Validates executed changes against platform quality gates,
  doctrine compliance, test suite, and performance benchmarks.
  Produces a validation report with pass/fail status.
  """

  @type validation_result :: %{
    status: :pass | :fail,
    compilation: :ok | {:error, [String.t()]},
    tests: %{passed: integer(), failed: integer(), skipped: integer()},
    doctrine: %{passed: [atom()], failed: [atom()]},
    format: :ok | :needs_formatting
  }

  @spec validate(map()) :: {:ok, validation_result()} | {:error, term()}
  def validate(execution_result) do
    checks = [
      {:compilation, &check_compilation/0},
      {:format, &check_format/0},
      {:tests, &check_tests/1},
      {:doctrine, &check_doctrines/0}
    ]

    results =
      Enum.into(checks, %{}, fn
        {name, fun} when is_function(fun, 0) -> {name, fun.()}
        {name, fun} when is_function(fun, 1) -> {name, fun.(execution_result)}
      end)

    status =
      if results.compilation == :ok and
         results.tests.failed == 0 and
         results.doctrine.failed == [] do
        :pass
      else
        :fail
      end

    {:ok, Map.put(results, :status, status)}
  end

  defp check_compilation do
    case System.cmd("mix", ["compile", "--warnings-as-errors"], stderr_to_stdout: true) do
      {_output, 0} -> :ok
      {output, _} -> {:error, String.split(output, "\n", trim: true)}
    end
  end

  defp check_tests(execution_result) do
    affected = Enum.map(execution_result.changes, &elem(&1, 0))
    {output, code} = System.cmd("mix", ["test" | affected], stderr_to_stdout: true)

    parse_test_output(output, code)
  end
end

Phase 5: Integration and Guardrails

The integration phase determines whether changes can be merged autonomously or require human review. The decision is based on complexity, risk, and the types of files affected:

CriterionAutonomousRequires Review
ComplexityTrivial, SimpleModerate, Complex
Files changed1-3 files4+ files
Doctrine fixesZERO, PERF, DOCSSEAL, architectural
Test changesAdding tests onlyModifying existing tests
Schema changesNever autonomousAlways review
Config changesNever autonomousAlways review
defmodule PrismaticSeadf.Phases.Integrate do
  @moduledoc """
  SEADF Integration Phase with guardrails.

  Determines whether validated changes can be auto-merged
  or require human review. Applies conservative guardrails
  that err on the side of requiring review.
  """

  require Logger

  @always_review_patterns ~w(
    **/migrations/**
    **/config/**
    **/mix.exs
    **/router.ex
    **/*schema*.ex
  )

  @spec integrate(Plan.plan(), Validate.validation_result()) :: :auto_merged | :pending_review
  def integrate(plan, validation) do
    cond do
      validation.status != :pass ->
        Logger.warning("SEADF: Changes failed validation, not integrating")
        :rejected

      plan.requires_human_review ->
        create_review_request(plan)
        :pending_review

      touches_sensitive_files?(plan) ->
        create_review_request(plan)
        :pending_review

      true ->
        commit_changes(plan)
        Logger.info("SEADF: Auto-merged plan #{plan.id}")
        :auto_merged
    end
  end

  defp touches_sensitive_files?(plan) do
    Enum.any?(plan.affected_files, fn file ->
      Enum.any?(@always_review_patterns, &PathGlob.match?(&1, file))
    end)
  end

  defp create_review_request(plan) do
    # Create GitLab MR with SEADF label for human review
    Logger.info("SEADF: Created review request for plan #{plan.id}")
  end
end

SEADF provides a structured framework for AI-assisted development that respects the boundary between autonomous improvement and human oversight. The five-phase cycle ensures that every change is discovered through data, planned with constraints, executed atomically, validated thoroughly, and integrated with appropriate review. The guardrail system makes the autonomous boundary explicit and conservative, building trust through predictable behavior.