Skip to content

feat(attestation): add --mark-latest flag to attestation init#3151

Open
javirln wants to merge 3 commits into
chainloop-dev:mainfrom
javirln:chore/undo-index-changes
Open

feat(attestation): add --mark-latest flag to attestation init#3151
javirln wants to merge 3 commits into
chainloop-dev:mainfrom
javirln:chore/undo-index-changes

Conversation

@javirln
Copy link
Copy Markdown
Member

@javirln javirln commented May 26, 2026

Summary

  • Add tri-state --mark-latest flag to attestation init to control whether a project version is promoted to latest (omitted = default behavior, true = force promote, false = skip promotion)
  • Add MarkAsLatest biz/data method for the platform repo to build the standalone project version mark-latest command on top of
  • Expose latest field on the ProjectVersion proto response message
  • Extract shared promoteVersionToLatestWithTx helper to avoid duplication between standalone promotion and workflow run creation paths

Test plan

  • Integration tests covering the full 3x3 matrix (nil/true/false x new/existing-prerelease/existing-released)
  • Edge cases: idempotent promotion, non-existent version, mutual exclusivity with --latest-version, require-existing-version combinations
  • Backward compatibility: omitting the flag preserves existing behavior
  • All existing tests pass with no regressions

Add tri-state --mark-latest flag to control whether a project version
is promoted to latest during attestation initialization. Omitting the
flag preserves current behavior, --mark-latest=true forces promotion
of existing pre-release versions, and --mark-latest=false skips
promotion entirely.

Also adds MarkAsLatest biz/data method for the platform repo to build
the standalone "project version mark-latest" command on top of.

Assisted-by: Claude Code
Signed-off-by: Javier Rodriguez <javier@chainloop.dev>

Chainloop-Trace-Sessions: c9c4aac1-2015-43c3-bf26-47621b425735
@chainloop-platform
Copy link
Copy Markdown
Contributor

chainloop-platform Bot commented May 26, 2026

AI Session Analysis

Avg score Sessions Failing policies Attribution Files Lines Total Duration
🟢 88% 1 ✅ 0 100% AI / 0% Human 13 +576 / -16 7h50m49s

🟢 88% — 100% AI — ✅ All policies passing

May 26, 2026 07:33 UTC · 7h50m49s · $38.04 · 674 in / 127.3k out · claude-code 2.1.139 (claude-opus-4-6)

View session details ↗

Change Summary

  • Adds a --mark-latest flag to the attestation init CLI command, implemented bottom-up through proto, business, data, service, and CLI layers.
  • Introduces a tri-state *bool design and a demote-all / promote-one atomic transaction pattern to manage the latest-attestation invariant.
  • Adds 27 integration tests exercising nil/true/false flag states, mutual exclusion, released-version error, and promotion semantics against real Postgres via testcontainers.
  • Cleans up accidental generated-file changes (descriptor.ts, go.sum) and extracts a shared helper in response to code review feedback.

AI Session Overall Score

🟢 88% — Well-executed feature delivery with thorough multi-layer tests and disciplined scope control.

AI Session Analysis Breakdown

🟢 92% · context-and-planning

🟢 AI wrote a comprehensive 7-step plan with per-file line-level detail before any edits. · High Impact

🟢 90% · solution-quality

No notes.

🟢 88% · alignment

🟢 Full --mark-latest feature implemented across all layers precisely matching user intent. · High Impact

🟡 AI added a database index then reverted it after user reversed course, causing minor churn. · Low Severity

🟢 88% · scope-discipline

No notes.

🟢 88% · verification

🟢 27 integration tests run against real Postgres via testcontainers; all pass, none weakened. · High Impact

🟡 No end-to-end CLI smoke test: attestation init --mark-latest never invoked against a real server. · Low Severity

💡 Add a CLI e2e scenario exercising the full flag path through the gRPC service.

🟡 78% · user-trust-signal

🟠 User directed index addition then abandoned it mid-execution, requiring an undo pass. · Medium Severity

💡 Clarify scope and constraints upfront before implementation begins to avoid mid-flight reversals.


File Attribution

████████████████████ 100% AI / 0% Human

Status Attribution File Lines
modified ai app/controlplane/pkg/biz/workflowrun_integration_test.go +359 / -0
modified ai app/controlplane/pkg/biz/projectversion_integration_test.go +86 / -1
modified ai app/controlplane/pkg/data/projectversion.go +54 / -9
modified ai app/controlplane/pkg/data/workflowrun.go +22 / -3
modified ai app/controlplane/pkg/biz/projectversion.go +22 / -0
modified ai app/cli/cmd/attestation_init.go +13 / -1
modified ai app/controlplane/pkg/biz/workflowrun.go +7 / -0
modified ai app/controlplane/api/controlplane/v1/workflow_run.proto +6 / -0
modified ai app/cli/pkg/action/attestation_init.go +3 / -1
modified ai app/controlplane/pkg/data/workflow.go +1 / -1
modified ai app/controlplane/api/controlplane/v1/response_messages.proto +1 / -0
modified ai app/controlplane/internal/service/attestation.go +1 / -0
modified ai app/controlplane/internal/service/workflowrun.go +1 / -0

Policies (4)

Status Policy Material Messages
✅ Passed ai-config-ai-agents-allowed ai-coding-session-c9c4aa -
✅ Passed ai-config-no-dangerous-commands ai-coding-session-c9c4aa -
✅ Passed ai-config-no-secrets ai-coding-session-c9c4aa -
✅ Passed ai-config-mcp-servers-allowed ai-coding-session-c9c4aa -

Powered by Chainloop and Chainloop Trace

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 21 files

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread app/controlplane/pkg/data/workflowrun.go
…romotion

The pre-transaction version lookup could be stale if a concurrent request
released the version between the lookup and the transaction start. Re-read
the version inside the transaction to ensure the prerelease check uses
current data.

Assisted-by: Claude Code
Signed-off-by: Javier Rodriguez <javier@chainloop.dev>

Chainloop-Trace-Sessions: c9c4aac1-2015-43c3-bf26-47621b425735
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="app/controlplane/pkg/data/workflowrun.go">

<violation number="1" location="app/controlplane/pkg/data/workflowrun.go:102">
P2: The new prerelease check is still race-prone because the version row is read without a lock before promotion. A concurrent update can release the version after this check and still be promoted to latest.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

versionCreated = true
} else if opts.MarkAsLatest != nil && *opts.MarkAsLatest {
// Re-read version inside the transaction to avoid promoting a concurrently released version
fresh, err := tx.ProjectVersion.Query().
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot May 26, 2026

Choose a reason for hiding this comment

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

P2: The new prerelease check is still race-prone because the version row is read without a lock before promotion. A concurrent update can release the version after this check and still be promoted to latest.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At app/controlplane/pkg/data/workflowrun.go, line 102:

<comment>The new prerelease check is still race-prone because the version row is read without a lock before promotion. A concurrent update can release the version after this check and still be promoted to latest.</comment>

<file context>
@@ -98,11 +98,22 @@ func (r *WorkflowRunRepo) Create(ctx context.Context, opts *biz.WorkflowRunRepoC
 		} else if opts.MarkAsLatest != nil && *opts.MarkAsLatest {
-			if !version.Prerelease {
+			// Re-read version inside the transaction to avoid promoting a concurrently released version
+			fresh, err := tx.ProjectVersion.Query().
+				Where(projectversion.ID(version.ID), projectversion.ProjectID(wf.ProjectID), projectversion.DeletedAtIsNil()).
+				Only(ctx)
</file context>
Suggested change
fresh, err := tx.ProjectVersion.Query().
fresh, err := tx.ProjectVersion.Query().ForUpdate().
Fix with Cubic

jiparis
jiparis previously approved these changes May 26, 2026
Signed-off-by: Javier Rodriguez <javier@chainloop.dev>
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.

2 participants