Product as Code Specification
1Version 0.2.1
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in BCP 14 RFC2119 RFC8174 when, and only when, they appear in all capitals, as shown here.
This document is licensed under The Apache License, Version 2.0.
2Introduction
The Product as Code Specification (PAC) defines a standard, version-controlled interface to product development workflows which allows both humans and AI coding assistants to discover and understand product requirements, development tasks, and implementation context. When properly defined, AI coding assistants can understand not only what to build, but exactly how it fits into the development workflow, git branches, and deployment process.
A Product as Code definition bridges product management and development execution, providing AI tools with complete context about business requirements, technical implementation details, and workflow integration points.
3Table of Contents
4Definitions
4.1Product as Code Document
A document (or set of documents) that defines or describes product requirements, development tasks, and business context. A Product as Code definition uses and conforms to the Product as Code Specification.
4.2Hierarchical Structure
Product as Code follows a two-level hierarchy: Epics contain Tickets. Tickets represent atomic units of development work that map to single branches and pull requests. Tasks are lightweight implementation steps embedded within tickets as inline arrays. This structure provides natural scope boundaries while maintaining practical development workflow integration.
5Specification
5.1Versions
The Product as Code Specification is versioned using Semantic Versioning 2.0.0 (semver) and follows the semver specification.
The major
.minor
portion of the semver (for example 0.1
) SHALL designate the PAC feature set. Typically, .patch
versions address errors in this document, not the feature set. Tooling which supports PAC 0.1 SHOULD be compatible with all PAC 0.1.* versions.
A Product as Code document compatible with PAC 0.*.* contains a required apiVersion
field which designates the semantic version of the PAC that it uses.
5.2Format
A Product as Code document that conforms to the Product as Code Specification is itself a structured object, which may be represented in either YAML or JSON format.
All field names in the specification are case sensitive.
The schema exposes two types of fields: Fixed fields, which have a declared name, and Optional fields, which may be included to provide additional context but are not required for basic compliance.
5.2.1YAML Format
YAML version 1.2 is RECOMMENDED for human readability and ease of editing. YAML is particularly well-suited for:
- Manual editing and review
- Version control diffs
- Collaborative editing in text editors
5.2.2JSON Format
JSON format is RECOMMENDED for programmatic generation and processing. JSON is particularly well-suited for:
- Tool integration and API consumption
- Automated generation from existing systems
- Environments where YAML parsing is not available
5.2.3Format Equivalence
Both formats MUST represent identical data structures. Tools SHOULD provide conversion utilities between YAML and JSON representations of Product as Code documents.
5.3Document Structure
A Product as Code document MAY be made up of a single document or be divided into multiple, connected parts at the discretion of the user. In the latter case, references between documents MUST use the unique identifier fields.
It is RECOMMENDED that Product as Code documents be named with descriptive names and appropriate file extensions:
- YAML format:
epic-user-auth.yaml
,ticket-login-form.yml
- JSON format:
epic-user-auth.json
,ticket-login-form.json
5.4Data Types
Primitive data types in PAC are based on YAML 1.2 supported types:
string
- UTF-8 textinteger
- Whole numbersboolean
- true/false valuesarray
- Ordered list of valuesobject
- Key-value pairs
6Schema
In the following description, if a field is not explicitly REQUIRED or described with a MUST or SHALL, it can be considered OPTIONAL.
6.1Epic Object
An Epic represents a large feature set or initiative that provides business value. Epics contain multiple related tickets and serve as the highest level of organization in the Product as Code hierarchy.
6.1.1Fixed Fields
Field Name | Type | Description |
---|---|---|
apiVersion | string |
REQUIRED. This string MUST be the semantic version number of the Product as Code Specification version that the document uses. The apiVersion field SHOULD be used by tooling to interpret the document correctly. |
kind | string |
REQUIRED. MUST be "Epic" for Epic objects. |
metadata | Metadata Object | REQUIRED. Metadata about the Epic including unique identifiers and timestamps. |
spec | Epic Specification Object | REQUIRED. The specification of the Epic including description and optional fields. |
6.1.2Epic Specification Object
Field Name | Type | Description |
---|---|---|
description | string |
REQUIRED. A clear, concise description of what the Epic accomplishes and why it provides business value. |
parent | string |
The unique identifier of the parent Epic this Epic belongs to. MUST NOT be present for top-level Epics. |
status | string |
The current status of the Epic. Common values include planning , in-progress , completed , cancelled . |
priority | string |
The business priority of the Epic. Common values include low , medium , high , critical . |
success_metrics | array of string |
Measurable outcomes that define success for this Epic. |
tickets | array of Ticket Reference Object |
List of tickets that belong to this Epic. |
epics | array of Epic Reference Object |
List of sub-epics that belong to this Epic. |
owner | string |
The person or team responsible for this Epic. |
labels | object |
Key-value pairs for categorization and filtering. |
blocked_by | array of string |
List of epic identifiers that are blocking this Epic from starting or completing. |
related_to | array of string |
List of epic identifiers that are related to this Epic but not blocking. |
depends_on | array of string |
List of epic identifiers that must be completed before this Epic can start. |
6.2Ticket Object
A Ticket represents an atomic unit of development work that maps to a single git branch and pull request. Tickets belong to Epics and contain inline tasks that represent implementation steps within the unit of work.
6.2.1Fixed Fields
Field Name | Type | Description |
---|---|---|
apiVersion | string |
REQUIRED. This string MUST be the semantic version number of the Product as Code Specification version. |
kind | string |
REQUIRED. MUST be "Ticket" for Ticket objects. |
metadata | Metadata Object | REQUIRED. Metadata about the Ticket including unique identifiers and timestamps. |
spec | Ticket Specification Object | REQUIRED. The specification of the Ticket including description and optional fields. |
6.2.2Ticket Specification Object
Field Name | Type | Description |
---|---|---|
description | string |
REQUIRED. A detailed description of what needs to be implemented or accomplished in this unit of work. |
parent | string |
REQUIRED. The unique identifier of the Epic this Ticket belongs to. |
type | string |
The type of work this Ticket represents. Common values include feature , bug , chore , refactor . Teams MAY define custom types as needed. |
status | string |
The current status of the Ticket. Common values include todo , in-progress , review , completed , blocked . |
priority | string |
The priority of the Ticket within its Epic. |
branch_name | string |
The git branch name for this unit of work. Enables AI coding assistants to know exactly where to implement changes. |
assignee | string |
The person responsible for implementing this Ticket. |
reviewer | string |
The person responsible for reviewing this Ticket’s implementation. |
estimate | string |
Time or effort estimate for completing this Ticket. |
started_at | string |
ISO 8601 timestamp of when work on this Ticket began. |
completed_at | string |
ISO 8601 timestamp of when this Ticket was completed. |
acceptance_criteria | array of string |
Specific, testable conditions that must be met for the ticket to be considered complete. |
tasks | array of Task Object |
Inline array of implementation steps within this unit of work. |
pull_request | Pull Request Object | Information about the pull request associated with this Ticket. |
labels | array of string |
Tags for categorization and filtering. |
blocked_by | array of string |
List of ticket identifiers that are blocking this Ticket from starting or completing. |
related_to | array of string |
List of ticket identifiers that are related to this Ticket but not blocking. |
depends_on | array of string |
List of ticket identifiers that must be completed before this Ticket can start. |
6.3Task Object
A Task represents a lightweight implementation step within a Ticket. Tasks are embedded inline within Tickets and represent checkboxes or action items that comprise the unit of work.
6.3.1Task Specification Object
Field Name | Type | Description |
---|---|---|
id | integer |
REQUIRED. A unique identifier for this Task within its parent Ticket. |
description | string |
REQUIRED. A specific, actionable description of the implementation step. |
done | boolean |
REQUIRED. Whether this Task has been completed. |
type | string |
The type of work this Task represents. Common values include feature , bug , chore , refactor , test , documentation . Teams MAY define custom types as needed. |
assignee | string |
The person responsible for this Task. |
estimate | string |
Time estimate for completing this Task. |
actual_time | string |
Actual time spent completing this Task. |
6.4Pull Request Object
Information about the pull request associated with a Ticket’s implementation.
6.4.1Pull Request Specification Object
Field Name | Type | Description |
---|---|---|
url | string |
The URL of the pull request. |
status | string |
The status of the pull request. Common values include draft , open , merged , closed . |
title | string |
The title of the pull request. |
created_at | string |
ISO 8601 timestamp of when the pull request was created. |
reviewers | array of string |
List of people assigned to review the pull request. |
6.5Epic Reference Object
A reference to an Epic with both ID and optional human-readable name.
6.5.1Epic Reference Specification Object
Field Name | Type | Description |
---|---|---|
id | string |
REQUIRED. The unique identifier of the referenced Epic. |
name | string |
A human-readable name for the referenced Epic. |
6.6Ticket Reference Object
A reference to a Ticket with both ID and optional human-readable name.
6.6.1Ticket Reference Specification Object
Field Name | Type | Description |
---|---|---|
id | string |
REQUIRED. The unique identifier of the referenced Ticket. |
name | string |
A human-readable name for the referenced Ticket. |
6.7Metadata Object
The Metadata Object contains identifying information and timestamps for all Product as Code objects.
6.7.1Fixed Fields
Field Name | Type | Description |
---|---|---|
id | string |
A globally unique identifier for this object. MUST be present if sequence and custom_id are not provided. |
sequence | integer |
A sequential integer identifier for this object. MUST be present if id and custom_id are not provided. |
custom_id | string |
A custom string identifier for this object. MUST be present if id and sequence are not provided. |
name | string |
A human-readable name for the object. |
created_at | string |
ISO 8601 timestamp of when the object was created. |
updated_at | string |
ISO 8601 timestamp of when the object was last updated. |
owner | string |
The person or team responsible for this object. |
labels | object |
Key-value pairs for categorization, filtering, and additional metadata. |
Note: Exactly one of id
, sequence
, or custom_id
MUST be provided. Additional identifier fields MAY be provided for convenience but are not required for object identification.
7Examples
7.1Epic Example (YAML)
apiVersion: productascode.org/v0.1.0
kind: Epic
metadata:
id: epic-550e8400-e29b-41d4-a716-446655440000
name: user-authentication
created_at: 2025-01-15T10:30:00Z
updated_at: 2025-01-15T10:30:00Z
owner: product-team
labels:
priority: high
quarter: Q1-2025
spec:
description: "Complete user authentication system with signup, login, and password recovery"
status: in-progress
priority: high
success_metrics:
- "90% signup completion rate"
- "< 2 second login time"
- "Zero critical security vulnerabilities"
tickets:
- id: "login-form-ticket"
name: "Login Form Implementation"
- id: "signup-validation-ticket"
name: "Signup Validation Logic"
epics:
- id: "password-recovery-epic"
name: "Password Recovery System"
owner: product-team
related_to:
- "admin-security-epic"
- "user-profile-epic"
7.2Epic Example (JSON)
{
"apiVersion": "productascode.org/v0.1.0",
"kind": "Epic",
"metadata": {
"id": "epic-550e8400-e29b-41d4-a716-446655440000",
"name": "user-authentication",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z",
"owner": "product-team",
"labels": {
"priority": "high",
"quarter": "Q1-2025"
}
},
"spec": {
"description": "Complete user authentication system with signup, login, and password recovery",
"status": "in-progress",
"priority": "high",
"success_metrics": [
"90% signup completion rate",
"< 2 second login time",
"Zero critical security vulnerabilities"
],
"tickets": [
{
"id": "login-form-ticket",
"name": "Login Form Implementation"
},
{
"id": "signup-validation-ticket",
"name": "Signup Validation Logic"
}
],
"epics": [
{
"id": "password-recovery-epic",
"name": "Password Recovery System"
}
],
"owner": "product-team",
"related_to": [
"admin-security-epic",
"user-profile-epic"
]
}
}
7.3Ticket Example (YAML)
apiVersion: productascode.org/v0.1.0
kind: Ticket
metadata:
id: 22
name: "jwt-token-generation-validation"
created_at: 2025-07-09T00:00:00Z
updated_at: 2025-07-09T13:47:39Z
spec:
description: |
Implement comprehensive JWT token generation and validation utilities
for the TIFY authentication system. This includes token creation,
validation, refresh mechanisms, and proper error handling for
expired or invalid tokens.
type: "feature"
parent: user-auth-epic
status: "completed"
priority: "high"
branch_name: "22-jwt-token-generation-validation"
assignee: "@mantcz"
reviewer: "@mantcz"
started_at: "2025-07-09T14:05:10Z"
completed_at: "2025-07-09T14:47:39Z"
estimate: "8h"
acceptance_criteria:
- "JWT token generation with configurable expiration times"
- "Token validation with proper error handling"
- "Refresh token mechanism for seamless user experience"
- "Token blacklisting for logout functionality"
- "Proper JWT claims validation (exp, iat, sub)"
- "Environment-based JWT configuration"
- "Comprehensive error handling for invalid/expired tokens"
- "Token extraction from Authorization headers"
- "Unit tests for all JWT utilities"
- "Integration with existing authentication flow"
tasks:
- id: 1
description: "Enhance JWT token generation with configurable options"
done: true
type: "feature"
assignee: "@mantcz"
- id: 2
description: "Implement JWT token validation with proper error handling"
done: true
type: "feature"
assignee: "@mantcz"
- id: 3
description: "Create refresh token mechanism"
done: true
type: "feature"
assignee: "@mantcz"
pull_request:
url: "https://github.com/company/repo/pull/22"
status: "merged"
title: "Implement JWT token generation and validation"
created_at: "2025-07-09T14:30:00Z"
reviewers: ["@mantcz"]
labels:
- "authentication"
- "jwt"
- "security"
- "middleware"
depends_on:
- "database-setup-ticket"
related_to:
- "user-registration-ticket"
- "password-reset-ticket"
7.4Ticket Example (JSON)
{
"apiVersion": "productascode.org/v0.1.0",
"kind": "Ticket",
"metadata": {
"id": 22,
"name": "jwt-token-generation-validation",
"created_at": "2025-07-09T00:00:00Z",
"updated_at": "2025-07-09T13:47:39Z"
},
"spec": {
"description": "Implement comprehensive JWT token generation and validation utilities for the TIFY authentication system. This includes token creation, validation, refresh mechanisms, and proper error handling for expired or invalid tokens.",
"type": "feature",
"parent": "user-auth-epic",
"status": "completed",
"priority": "high",
"branch_name": "22-jwt-token-generation-validation",
"assignee": "@mantcz",
"reviewer": "@mantcz",
"started_at": "2025-07-09T14:05:10Z",
"completed_at": "2025-07-09T14:47:39Z",
"estimate": "8h",
"acceptance_criteria": [
"JWT token generation with configurable expiration times",
"Token validation with proper error handling",
"Refresh token mechanism for seamless user experience",
"Token blacklisting for logout functionality",
"Proper JWT claims validation (exp, iat, sub)",
"Environment-based JWT configuration",
"Comprehensive error handling for invalid/expired tokens",
"Token extraction from Authorization headers",
"Unit tests for all JWT utilities",
"Integration with existing authentication flow"
],
"tasks": [
{
"id": 1,
"description": "Enhance JWT token generation with configurable options",
"done": true,
"type": "feature",
"assignee": "@mantcz"
},
{
"id": 2,
"description": "Implement JWT token validation with proper error handling",
"done": true,
"type": "feature",
"assignee": "@mantcz"
},
{
"id": 3,
"description": "Create refresh token mechanism",
"done": true,
"type": "feature",
"assignee": "@mantcz"
}
],
"pull_request": {
"url": "https://github.com/company/repo/pull/22",
"status": "merged",
"title": "Implement JWT token generation and validation",
"created_at": "2025-07-09T14:30:00Z",
"reviewers": ["@mantcz"]
},
"labels": [
"authentication",
"jwt",
"security",
"middleware"
],
"depends_on": [
"database-setup-ticket"
],
"related_to": [
"user-registration-ticket",
"password-reset-ticket"
]
}
}
7.5Task Example
Tasks are embedded inline within Tickets as shown in the Ticket example above. They represent lightweight implementation steps with simple fields:
tasks:
- id: 1
description: "Enhance JWT token generation with configurable options"
done: true
type: "feature"
assignee: "@mantcz"
estimate: "2h"
- id: 2
description: "Update environment variables for JWT configuration"
done: false
type: "chore"
assignee: "@alice"
estimate: "30min"
8Specification Extensions
While the Product as Code Specification tries to accommodate most use cases, additional data can be added to extend the specification at certain points.
The extensions properties are implemented as patterned fields that are always prefixed by "x-"
.
Field Pattern | Type | Description |
---|---|---|
^x- | Any | Allows extensions to the Product as Code Schema. The field name MUST begin with x- , for example, x-internal-id . The value can be null , a primitive, an array or an object. |
The extensions may or may not be supported by the available tooling, but those may be extended as well to add requested support.
9Appendix A: Revision History
Version | Date | Notes |
---|---|---|
0.1.0 | 2025-01-18 | Initial release of the Product as Code Specification |