Back to blog
The Validation Agent
·
aiengineeringinfrastructure

The Validation Agent

An AI agent that sits between conversation and distribution, enforcing Apple Music style rules and catching metadata drift.

ONCE Engineering


A rejected release costs time and money. Distributors (especially Apple Music) have strict metadata formatting rules, and a single casing mistake or missing contributor credit can bounce an entire submission. We built an AI-powered Validation Agent that catches these issues automatically before anything reaches the distributor.

Where It Sits

The Validation Agent runs between the chat conversation and the distribution adapter on every release. When a user finishes building a release through conversation with the ONCE chat agent, the payload doesn't go straight to distribution. It passes through validation first.

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   User Chat     │────▶│  Validation     │────▶│  Distribution   │
│   Conversation  │     │  Agent (GPT)    │     │  Backend        │
└─────────────────┘     └─────────────────┘     └─────────────────┘
                              │
                              ▼
                    ┌─────────────────┐
                    │  Adjusted       │
                    │  Payload        │
                    └─────────────────┘

The key difference from a traditional validator: it doesn't just flag errors. It makes corrections and explains its reasoning.

Three Sources of Truth

The agent pulls from three inputs simultaneously:

1. Apple Music Style Guide (Live-Fetched)

The agent fetches the Apple Music Style Guide directly from Apple's website at validation time. To stay within context limits, it performs a keyword-driven search against the guide based on the current release metadata (titles, artists, language, explicit flags, genres, and version cues). Only the most relevant excerpts are included in the prompt.

This means the agent stays current with Apple's formatting rules without us manually tracking changes.

2. Conversation History

The full chat conversation between the user and the ONCE agent is included as context. This lets the validator cross-reference the final payload against what the user actually said, catching cases where metadata drifted during the conversation or a contributor was mentioned but not captured.

3. Distribution Backend Requirements

Technical compliance rules from our distribution backend API: required fields, schema constraints, and format specifications that must be met for successful submission.

Priority Order

When rules conflict, the agent follows a strict priority hierarchy:

  1. Apple Music Style Guide: Required formatting rules (rejectable if violated)
  2. Distribution Backend Requirements: Technical compliance for distribution
  3. User Expressed Intent: Honored when it doesn't conflict with store rules
  4. Conversation Context: Inferred intent when safe and compatible
  5. Smart Defaults: Reasonable defaults for missing optional fields

This means if a user titles their track in ALL CAPS but the Apple Music Style Guide requires title case, the agent corrects it and explains why.

Contributor Analysis

One of the trickiest parts of release metadata is contributor credits. The agent analyzes the conversation to ensure all mentioned contributors are correctly captured and assigned:

  • Every writer, producer, arranger, and engineer mentioned in the conversation gets checked against the payload
  • Track-level writer assignments are derived from release-level contributors when missing (the distribution backend requires each track to have a writers array)
  • Writer shares are split evenly among all writers on a track
  • A deterministic fallback runs after the AI analysis to ensure no track is left without writers, catching edge cases the model might miss
// After AI analysis, programmatic fallback ensures completeness
for (const track of tracks) {
  if (!track.writers || track.writers.length === 0) {
    // Derive writers from release.contributors
    track.writers = release.contributors
      .filter(c => ["Writer", "Composer", "Lyricist"].includes(c.role))
      .map(c => ({
        name: c.name,
        share: Math.floor(100 / matchingContributors.length)
      }));
  }
}

Other Corrections

Beyond contributor analysis, the agent handles:

  • Title and artist formatting: Casing, featuring syntax, parenthetical versions per Apple's rules
  • Compound artist splitting: The distribution backend requires a single primary artist, so Artist A & Artist B gets restructured
  • UPC stripping: User-provided UPCs are removed since they must be auto-generated by the distributor
  • Explicit content flags: Verified against actual track content discussed in conversation
  • Classical music formatting: Enhanced rules for classical releases with specific formatting standards for movements, opus numbers, and performer credits

Output

The agent returns an adjusted payload along with a detailed list of every change made:

{
  "success": true,
  "adjustedPayload": { "release": { ... }, "tracks": [ ... ] },
  "adjustments": [
    {
      "field": "release.title",
      "originalValue": "My Song",
      "adjustedValue": "My Song (feat. Artist)",
      "reason": "User mentioned featuring another artist in conversation",
      "source": "conversation"
    }
  ],
  "reasoning": "Analysis summary...",
  "errors": []
}

Every adjustment includes the field changed, original and corrected values, reasoning, and which source triggered the change (Apple guide, distribution backend, conversation, or smart default).

Visibility

Validation results surface in three places:

  • Slack notifications: Each submission notification includes a validation section showing adjustment count, before/after values, and any errors
  • Database records: Full results stored in release_submit_logs for auditing
  • Admin UI: Validation details visible in the release log admin panel

What's Next

We're exploring tighter integration with the chat experience, running validation checks during the conversation rather than only at submission time so issues get caught earlier. We're also looking at learning from past corrections to improve accuracy on common patterns.

The Validation Agent runs automatically on every release submitted through ONCE. It's enabled by default, no user action required.

Try ONCE