Skip to content

Publish ActorTemplate golden snapshots as tags - #1523

Merged
Luiz Oliveira (laoj2) merged 3 commits into
agent-substrate:mainfrom
kagent-dev:fix/golden-template-tag
Sep 16, 2026
Merged

Luiz Oliveira (laoj2) merged 3 commits into
agent-substrate:mainfrom
kagent-dev:fix/golden-template-tag

Conversation

@EItanya

Copy link
Copy Markdown
Collaborator

Fixes #1507

Golden snapshots currently remain owned by the temporary golden actor, so another resume/suspend cycle or actor deletion can collect a snapshot still referenced by its template. The controller now copies the warmed snapshot into a published tag, deletes the golden actor, and records the tag reference on the template. Interrupted tag creation and cleanup remain retryable; template deletion cleans up both resources.

CreateActor resolves an explicit sourceTag or the template's golden tag into the actor's initial snapshot. Actors created before the golden tag is ready retain their cold-boot behavior. The golden tag uses the template UID as its name in ate-golden. The proto replaces golden_snapshot with golden_tag at field 1, without backward compatibility.

This PR is based directly on main and does not depend on #1521.

Follow-up recommendation: move the create → resume → wait → suspend → tag → delete sequence into a golden-template workflow using the existing workflow conventions. The reconciler now coordinates multiple recoverable steps; it could retain scheduling and retries while delegating that sequence to the workflow. This refactor is outside this PR.

  • Tests pass
  • Appropriate changes to documentation are included in the PR

Validation: full env -u NO_COLOR make verify passed after rebasing onto main. After the final proto field-number change, bindings were regenerated and the control API unit/functional tests plus proto-format and Go-format checks passed.

}
if err == nil {
if tag.GetStatus().GetActorTemplateUid() != tmpl.GetMetadata().GetUid() || resources.ActorRefFromObjectRef(tag.GetSourceActor()) != resources.ActorRefFromObjectRef(goldenActorRef) {
return 0, fmt.Errorf("golden tag belongs to another actor or template")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about failing this with r.fail, so we don't retry forever if the existing golden tag matches another actor?

Copy each warmed golden actor snapshot into a published tag before deleting the temporary actor. Resolve that tag as the default when creating actors, and use it for data-only golden restores. Clean up golden resources with their template and recover interrupted tag builds.

Signed-off-by: Eitan Yarmush <[email protected]>
Record ownership conflicts as terminal template failures so reconciliation does not retry indefinitely. Keep conflicting tags untouched and cover actor and template mismatches, repeated reconciliation, and periodic resync.

Signed-off-by: Eitan Yarmush <[email protected]>
return Validate_ListActorTemplatesRequest(ctx, op, nil, req, nil)
}

func (s *RPCService) DeleteActorTemplate(ctx context.Context, req *ateapipb.DeleteActorTemplateRequest) (*ateapipb.ActorTemplate, error) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add a unit test for DeleteActorTemplate?

}
}

func TestReconcileOne_GoldenTagRecovery(t *testing.T) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we make these tests table-driven? It's a bit hard to read right now the per-case inputs/expectations. For example, we could have a struct like this:

tests := []struct {
		name string
		// tag is the golden tag an earlier pass left behind, if any.
		tag *ateapipb.Tag
		// actorDeleted seeds a pass that died after deleting the golden actor.
		actorDeleted bool
		// createTagErr, deleteActorErr and deleteTagErr fail one step of the
		// first pass. The retry runs with every step working again.
		createTagErr   error
		deleteActorErr error
		deleteTagErr   error
		// wantCreateTags is how many copies the whole scenario must cost.
		wantCreateTags int
	}{

Exercise golden resource cleanup, partial failures, and retries through DeleteActorTemplate. Declare recovery and ownership-conflict inputs in tables and assert the number of tag copy attempts.

Signed-off-by: Eitan Yarmush <[email protected]>
@laoj2
Luiz Oliveira (laoj2) merged commit a58481a into agent-substrate:main Sep 16, 2026
11 checks passed
Julian Gutierrez Oschmann (juli4n) pushed a commit that referenced this pull request Sep 16, 2026
#1522 added a resyncInterval parameter to NewActorTemplateReconciler and
#1523 added this call site. They landed without seeing each other, so
`main` doesn't compile.

SEt the resyncInterval to 7s, to match what we have in other tests

- [x] Tests pass
- [x] Appropriate changes to documentation are included in the PR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make ActorTemplate controller generate a golden tag

2 participants