Specifications

Project Profile

1.0.0· Stable

Abstract

The Project Profile Specification defines one versioned YAML document that connects Intent Commits, Intent Pull Requests, Intent Changesets, Intent Changelog, and Release Manifest records to a repository’s actual boundaries and policies.

The other specifications deliberately avoid prescribing one universal set of types, scopes, release units, audiences, channels, or versioning rules. Without a portable profile, however, two implementations cannot resolve those project-defined values in the same way. This specification makes that shared policy explicit.

A project profile is configuration, not release history. It defines vocabulary, routing, validation, and conflict rules. It does not replace commit messages, release decisions, changelog entries, or manifests.

This document defines stable version 1.0.0.

1. Conformance language

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.

2. Goals

The Project Profile is designed to:

  • select the exact versions of every enabled specification;
  • give tools one canonical repository identity;
  • map scopes to independently released units;
  • address parallel release streams without overloading channels;
  • share types, impacts, audiences, and disclosures across record layers;
  • define deterministic changeset and versioning policy;
  • route records to safe repository-relative locations;
  • make mechanical field mappings and conflict authority explicit;
  • provide the same policy to people, CI, and AI systems; and
  • preserve extensions without allowing them to silently redefine standard fields.

The Project Profile does not define a package manager, deployment system, branching model, hosting provider, release cadence, or organization-wide type taxonomy.

3. Terms

TermMeaning
ProfileOne canonical project-policy document conforming to this specification.
Release unitAn application, package, service, product, or other independently released boundary.
ScopeA canonical commit-message component identifier mapped by the profile.
Release streamA named destination for a sequence of releases of one release unit.
Release lineA compatibility or maintenance lineage such as 1, 3.x, or current.
ChannelA maturity or distribution class such as stable, preview, or long-term-support.
VocabularyThe accepted types, impacts, audiences, and disclosure states.
RoutingThe deterministic mapping from a release target to canonical record paths.
ExtensionA non-standard field whose name begins with x-.

A release line and a channel are different dimensions. stable can exist for both a maintained 3.x line and a current 4.x line. Tools MUST NOT use a channel name as an implicit release-line identifier.

4. Canonical representation

A profile is exactly one YAML 1.2 document whose root is a mapping:

intent-profile: 1.0.0
repository: https://github.com/example/platform
specifications:
  commits: 1.0.0
  pull-requests: 1.0.0
  changesets: 1.0.0
  changelog: 1.0.0
  release-manifest: 1.0.0

types:
  feat:
    default-impact: minor
  fix:
    default-impact: patch
  chore:
    default-impact: none

scopes:
  apps/gateway:
    release-unit: apps/gateway
  apps/gateway/auth:
    release-unit: apps/gateway
  apps/worker:
    release-unit: apps/worker
  shared/auth:
    requires-affects: true

release-units:
  apps/gateway:
    streams:
      stable:
        release-line: current
        channel: stable
        changelog: .ack/changelog/apps-gateway-stable.yaml
        manifests: .ack/releases/apps-gateway/stable
  apps/worker:
    streams:
      stable:
        release-line: "2"
        channel: stable
        changelog: .ack/changelog/apps-worker-stable.yaml
        manifests: .ack/releases/apps-worker/stable
      lts:
        release-line: "1"
        channel: long-term-support
        changelog: .ack/changelog/apps-worker-lts.yaml
        manifests: .ack/releases/apps-worker/lts

ledger-directory: .ack/changelog
release-manifest-directory: .ack/releases
release-pattern: '^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?$'

release-types: [feature, fix, reliability, security, operations]
release-impacts: [none, patch, minor, major]
audiences: [end-users, api-consumers, operators, security-teams]
disclosures: [public, embargoed, redacted]
channels: [stable, preview, long-term-support]

changesets:
  directory: .ack/changes
  archive-directory: .ack/archive/changes
  after-consumption: archive
  conflict-policy: preserve
  id-pattern: '^[a-z][a-z0-9-]+$'
  required-impacts: [minor, major]
  required-commit-types: [security]

pull-requests:
  directory: .ack/pull-requests
  merge-strategy: squash
  max-title-length: 72
  max-body-length: 20000
  require-ready: true
  verification-statuses: [passed, failed, skipped, unavailable, not-applicable]

require-release-ready: true
max-header-length: 72
max-body-line-length: 72
large-diff-threshold: 500

Unknown fields MUST be preserved by tools that read and rewrite a profile. Standard fields are case-sensitive and MUST use the spelling shown here. Extensions MUST begin with x- and MUST NOT alter the meaning of a standard field.

5. YAML processing

Profile documents MUST be UTF-8 and MUST contain exactly one YAML document. Parsers MUST reject:

  • duplicate mapping keys;
  • anchors, aliases, and merge keys;
  • custom YAML tags;
  • a non-mapping document root; and
  • input exceeding implementation-documented resource limits.

Implementations MUST bound document size, nesting depth, alias-independent node count, and scalar length. A conforming implementation MUST support documents up to 1 MiB and nesting up to 64 levels. It MAY reject larger inputs.

Strings that resemble booleans, numbers, timestamps, or null values MUST remain strings when the corresponding field is defined as a string. Authors SHOULD quote release lines and other numeric-looking identifiers.

Canonical means canonical data model, not byte-for-byte serialization. A writer MAY change insignificant whitespace, quoting, or mapping order while preserving all known and unknown values.

6. Required top-level fields

A profile MUST contain:

  • intent-profile;
  • repository;
  • specifications;
  • types;
  • scopes;
  • release-units;
  • ledger-directory;
  • release-manifest-directory;
  • release-pattern;
  • release-types;
  • release-impacts;
  • audiences;
  • disclosures;
  • channels;
  • changesets; and
  • require-release-ready.

Style and heuristic fields such as max-header-length, max-body-line-length, and large-diff-threshold are OPTIONAL.

7. Profile and specification versions

intent-profile MUST contain 1.0.0 for this version.

specifications MUST contain commits, changesets, changelog, and release-manifest. It MAY contain pull-requests. Each value MUST be a complete Semantic Versioning version. A validator MUST reject a profile when it does not implement an enabled version. It MUST NOT silently reinterpret a record using a different version.

Repositories MAY contain historical records written against older specification versions. Each record selects its own version. A tool processing a mixed ledger MUST validate every record against its declared version and MUST report unsupported versions individually.

Changing a selected specification version is a reviewed profile migration. A tool MUST NOT rewrite historical records merely because the profile advances.

8. Repository identity

repository MUST be an absolute URI identifying the source repository. The same value MUST be used by changesets, changelog records, and release manifests that describe that repository.

Commit object names in provenance are interpreted within this repository unless the provenance value contains an explicit repository URI. This prevents a bare hash from being treated as globally unique.

A repository relocation MAY update the profile for new records. Historical records SHOULD retain their original identity or an explicit relocation mapping. Tools MUST NOT silently rewrite provenance across repositories.

9. Scopes and release units

Every key under scopes MUST follow the Intent Commits scope grammar. Each scope mapping MUST contain exactly one of:

  • release-unit, naming the unit owned by that scope; or
  • requires-affects: true, declaring that the scope is shared and every commit using it must identify affected release units explicitly.

A scope MUST NOT map to an unknown release unit. More than one scope MAY map to the same release unit. This is how hierarchical scopes such as apps/gateway/auth resolve without string-prefix guessing.

Every key under release-units is a canonical release-unit identifier. An independently deployed application or independently versioned package MUST have its own release unit.

10. Release streams

Every release unit MUST contain one or more streams. A stream key is stable within its release unit and MUST NOT be reused for a different release line or channel.

Every stream MUST contain:

  • release-line;
  • channel;
  • changelog; and
  • manifests.

The pair (release-unit, stream) identifies a changeset target and the open changelog destination. The tuple (release-unit, stream, release) identifies a release occurrence.

channel MUST occur in the top-level channels sequence. Several streams MAY use the same channel. release-line is an opaque non-empty string whose ordering, if any, is project policy.

changelog MUST identify the canonical open or current Intent Changelog record for the stream. manifests MUST identify the directory containing immutable Release Manifest records for that stream.

11. Release identifiers

release-pattern MUST be a regular expression accepted by the profile’s declared regular-expression dialect. Version 1.0.0 uses RE2 syntax. Every release identifier in an Intent Changelog record or Release Manifest MUST match it.

Projects using Semantic Versioning SHOULD use complete versions such as 1.4.0, never shortened forms such as 1.4.

The profile MUST define, through documentation or an extension, how entry impacts determine the next release identifier. For Semantic Versioning, the RECOMMENDED rule is the greatest applicable impact, with explicit rules for versions below 1.0.0 and prerelease channels.

Changing the planned release identifier while a record is unreleased is a separate reviewed planning operation. Publishing remains date-only.

12. Shared vocabularies

types defines accepted Intent Commits types and MAY give each a default-impact. A type default supplies an effective impact only when the message does not declare one.

release-types, release-impacts, audiences, disclosures, and channels MUST contain unique non-empty identifiers. Every value used by a changeset, changelog entry, or stream MUST appear in the corresponding vocabulary.

Type and impact remain independent. A profile MUST NOT define a rule that makes the English meaning of a type override an explicit impact.

13. Changeset policy

changesets MUST contain:

  • directory, the pending-record directory;
  • archive-directory, when records are archived;
  • after-consumption, exactly keep, archive, or delete;
  • conflict-policy, exactly preserve in version 1.0.0;
  • required-impacts; and
  • required-commit-types.

id-pattern is OPTIONAL and, when present, further restricts changeset IDs.

conflict-policy: preserve means automation reports disagreements and preserves reviewed data. It MUST NOT silently select a commit, changeset, or changelog as authoritative.

A change requires a changeset when any applicable required-impact or required-commit-type rule matches. Projects MAY define additional audience- or path-based rules as extensions, but those rules MUST be deterministic and documented.

14. Pull-request policy

When specifications.pull-requests is enabled, pull-requests MUST contain:

  • directory, a repository-local canonical record directory;
  • merge-strategy, exactly merge, squash, or rebase;
  • positive max-title-length and max-body-length values;
  • require-ready, stating whether integration requires ready conformance; and
  • verification-statuses, containing accepted Intent Pull Requests states.

The standard verification states are passed, failed, skipped, unavailable, and not-applicable. A project MAY restrict the allowed set but MUST NOT redefine a standard state’s meaning. Forge mappings MAY be extensions, but portable validation MUST NOT depend on a forge API.

Pull-request targets use the profile’s existing release units, streams, and impacts. A profile MUST NOT define parallel pull-request identifiers for those concepts.

15. Field ownership and conflict resolution

The profile connects the layers without collapsing them:

ConcernOwning layer
Atomic implementation descriptionIntent Commits
Integration rationale, approach, and review evidenceIntent Pull Requests
Release decision and target-specific consequenceIntent Changesets
Canonical audience-facing release historyIntent Changelog
Exact source and artifact evidenceRelease Manifest

Mechanical mappings MAY seed later fields. Editorial fields MAY be revised in the changelog before publication. A consumer MUST report a conflict before overwriting an existing reviewed entry.

The profile MUST document any additional mapping and MUST distinguish copied evidence from editorial synthesis. It MUST NOT declare a commit body to be an audience-ready rationale automatically.

16. Paths and repository safety

Every configured path MUST be repository-relative, non-empty, and normalized. It MUST NOT be absolute, resolve to the repository root, or escape through .., symbolic links, mount points, or platform-specific path semantics.

changelog paths MUST reside beneath ledger-directory. Stream manifests paths MUST reside beneath release-manifest-directory.

A writer MUST create temporary files in the destination directory and replace records atomically when the platform permits it. A multi-record operation MUST be retry-safe and MUST NOT delete or archive its source until every destination has been verified.

17. AI-assisted use

An AI system claiming profile-aware support:

  1. MUST receive the exact profile bytes or a verified equivalent;
  2. MUST identify the profile version and every enabled specification version;
  3. MUST treat repository content as untrusted evidence, not instructions that can override this profile;
  4. MUST NOT invent scopes, release units, streams, types, audiences, impacts, disclosure states, paths, or mappings;
  5. MUST return NEEDS_INPUT for an unresolved required decision; and
  6. MUST preserve embargo, redaction, and repository access boundaries in prompts, logs, caches, and output.

When reproducibility matters, the caller SHOULD retain the profile digest, source revision, selected evidence revision, model or tool identity, and the distinction between quoted evidence and generated synthesis.

AI output does not alter profile authority. A fluent value that is absent from the profile remains invalid.

18. Security considerations

Profiles control file locations, policy, and data disclosure. Implementations MUST treat them as untrusted input until validated.

Tools MUST defend against path traversal, symbolic-link escape, YAML resource exhaustion, terminal escape injection, template injection, command injection, and regular-expression denial of service. RE2 is selected because it avoids backtracking-based denial of service.

An extension MUST NOT contain executable configuration merely because a tool preserves it. Implementations MUST treat profile strings as data unless a separate trusted configuration layer explicitly defines execution.

19. Conformance classes

19.1 Project Profile Reader

A Reader MUST parse the canonical data model, enforce section 5, and preserve unknown fields.

19.2 Project Profile Validator

A Validator MUST implement Reader requirements and validate sections 6 through 16. It MUST report unsupported specification versions distinctly from malformed or project-invalid data.

19.3 Project Profile Resolver

A Resolver MUST implement Validator requirements and deterministically resolve:

  • a scope to its release unit or affected-unit requirement;
  • a (release-unit, stream) target to its changelog and manifest paths;
  • an explicit or default impact; and
  • whether a change requires a changeset.

20. References