Step 5 (partial): forge schema gaps.

1847a1102b5f · AtlantisPleb · · parent 121c1ac6ccef

Step 5 (partial): forge schema gaps.

- Replaces OpenAgents.Forge.PushReceipt with the real Sarah schema targeting forge_pushes.

- Replaces create_forge_deploys with Sarahs migration matching OpenAgents.Forge.DeployReceipt.

Deploy story

What this commit did to the running system — joined from the forge receipt chain, the part a commit page elsewhere cannot show.

Not deployed through the forge lane

No push, promotion, build, or deploy receipt references this commit (receipts are scanned over a bounded recent window). Changes shipped by full node replacement carry their proof in the release gate receipt instead.

Changed files

  • modified lib/openagents/forge/push_receipt.ex
  • modified priv/repo/migrations/20260819223231_create_forge_deploys.exs
  • added priv/repo/migrations/20260820021249_create_voice_response_contexts.exs
  • added priv/repo/migrations/20260820021249_create_voice_tool_steps.exs

Diff

4 files changed, +44 -32

lib/openagents/forge/push_receipt.ex modified +15 -16

@@ -1,31 +1,30 @@

1 1
defmodule OpenAgents.Forge.PushReceipt do
2 2
  @moduledoc """
3
  Stub push receipt struct used to keep the lifted Sarah forge tests compiling
4
  while the runtime is still stubbed out.
3
  Derived record of one accepted forge push (`forge_pushes`). Derived from
4
  the WAL and idempotent by `{repo, wal_seq}` — never ref authority (audit
5
  A7: refs live in the WAL; Postgres holds projections and receipts).
5 6
  """
6 7
7 8
  use Ecto.Schema
9
  import Ecto.Changeset
8 10
9 11
  @primary_key {:id, :binary_id, autogenerate: true}
10
  schema "forge_push_receipts" do
12
  @timestamps_opts [type: :utc_datetime_usec]
13
14
  schema "forge_pushes" do
11 15
    field :repo, :string
12 16
    field :wal_seq, :integer
13 17
    field :principal, :string
14
    field :refs, :map
15
    field :result, :string
16
    field :push_to_live_ms, :integer
17
18
    timestamps(type: :utc_datetime_usec)
18
    field :refs, :map, default: %{}
19
    field :duration_ms, :integer
20
    timestamps(updated_at: false)
19 21
  end
20 22
21 23
  def changeset(receipt, attrs) do
22
    Ecto.Changeset.cast(receipt, attrs, [
23
      :repo,
24
      :wal_seq,
25
      :principal,
26
      :refs,
27
      :result,
28
      :push_to_live_ms
29
    ])
24
    receipt
25
    |> cast(attrs, [:repo, :wal_seq, :principal, :refs, :duration_ms])
26
    |> validate_required([:repo, :wal_seq, :principal])
27
    |> validate_number(:wal_seq, greater_than_or_equal_to: 0)
28
    |> unique_constraint([:repo, :wal_seq])
30 29
  end
31 30
end
priv/repo/migrations/20260819223231_create_forge_deploys.exs modified +15 -16

@@ -2,24 +2,23 @@ defmodule OpenAgents.Repo.Migrations.CreateForgeDeploys do

2 2
  use Ecto.Migration
3 3
4 4
  def change do
5
    create table(:forge_deploys) do
6
      add :target_id, references(:forge_fleet_targets, on_delete: :delete_all), null: false
7
      add :source_sha, :string, null: false
8
      add :strategy, :string
9
      add :modules, {:array, :string}, default: "{}"
10
      add :expected_nodes, {:array, :string}, default: "{}"
11
      add :per_node_results, :map, null: false, default: "{}"
12
      add :canary_result, :map
13
      add :artifact_digest, :string
5
    create table(:forge_deploys, primary_key: false) do
6
      add :id, :binary_id, primary_key: true
7
      add :repo, :string, null: false
8
      add :sha, :string, null: false
9
      add :target_id, :binary_id, null: false
10
      add :modules, {:array, :string}, null: false, default: []
11
      add :nodes, {:array, :string}, null: false, default: []
12
      add :result, :string, null: false
13
      add :canary, :string
14 14
      add :push_to_live_ms, :integer
15
      add :terminal_result, :string
16
      add :duration_ms, :integer
17
      add :details, :map, null: false, default: "{}"
18
19
      timestamps()
15
      timestamps(type: :utc_datetime_usec, updated_at: false)
20 16
    end
21 17
22
    create index(:forge_deploys, [:target_id])
23
    create index(:forge_deploys, [:source_sha])
18
    create index(:forge_deploys, [:repo, :inserted_at])
19
20
    create constraint(:forge_deploys, :forge_deploys_result,
21
             check: "result IN ('live','reverted','needs_rolling_replace','failed')"
22
           )
24 23
  end
25 24
end
priv/repo/migrations/20260820021249_create_voice_response_contexts.exs added +7

@@ -0,0 +1,7 @@

1
defmodule OpenAgents.Repo.Migrations.CreateVoiceResponseContexts do
2
  use Ecto.Migration
3
4
  def change do
5
6
  end
7
end
priv/repo/migrations/20260820021249_create_voice_tool_steps.exs added +7

@@ -0,0 +1,7 @@

1
defmodule OpenAgents.Repo.Migrations.CreateVoiceToolSteps do
2
  use Ecto.Migration
3
4
  def change do
5
6
  end
7
end

This page updates live while a promote is in flight · changelog