1. Introduction

A typical software project today carries a dozen or more root-level metadata files:

  • One or more language manifests (package.json, pyproject.toml, composer.json, Cargo.toml, Gemfile, go.mod, …).
  • LICENSE, sometimes LICENSES/ with REUSE-style per-file annotations.
  • README.md, CHANGELOG.md, AUTHORS, CONTRIBUTORS, MAINTAINERS.
  • CITATION.cff, FUNDING.yml, .github/FUNDING.yml, codemeta.json.
  • .gitignore, .editorconfig, .gitattributes, .nvmrc, .tool-versions.
  • Vendor config: Jenkinsfile, .gitlab-ci.yml, .circleci/config.yml, renovate.json, dependabot.yml.

These files duplicate identity, licensing, authorship, and dependency information, disagree subtly, and lock the project into whatever tool read each file first.

Which of those files a document can stand behind (non-normative). A reserved field carries data the spec defines; an extension carries data a cooperating tool defines and reads; “not covered” means no field or registered extension carries it today.

File Source in a projectfile
package.json, pyproject.toml, composer.json, … identity, license, people, keywords, links, requirements (metadata only)
LICENSE, LICENSES/ license, copyright, people (copyright role)
AUTHORS, CONTRIBUTORS, MAINTAINERS, CODEOWNERS people, organizations (roles); org.projectfile.codeowners
CITATION.cff, codemeta.json identity, people, organizations, license, links; org.projectfile.citation
FUNDING.yml, funding.json org.projectfile.funding
README.md identity, links; org.projectfile.readme
SECURITY.md, CODE_OF_CONDUCT.md, CONTRIBUTING.md people (roles), links; the matching org.projectfile.* extensions
.gitignore and other ignore files, .gitattributes technologies; org.projectfile.ignores
.browserslistrc requirements.browsers
CI configuration org.projectfile.ci
dependabot.yml org.projectfile.dependency-updates, com.github.dependabot
CHANGELOG.md not covered — release history lives in version control
.editorconfig, .nvmrc, .tool-versions not covered

Dependencies are the one duplication projectfile deliberately leaves alone. A projectfile could mirror only the direct dependencies of one ecosystem — never peers, transitives or a lockfile’s resolution — so it would read as a complete manifest while being a lossy copy of one. The language-native manifest stays the source of truth for dependencies.

projectfile consolidates this information. Reserved fields cover concerns shared across every software project (identity, license, people, keywords, technologies, requirements). Reverse-DNS extension namespaces — com.example.build, com.example.ci — represented as nested mappings, carry vendor- or tool-specific data that cooperating consumers can read without stepping on each other.

The spec is deliberately extensible without a committee. Any author can claim an extension namespace (org.example.my-tool) and ship tooling that reads and writes it. An author needs no real or owned domain: any unique string following the segment rules is a valid namespace. The reverse-DNS form is a convention for avoiding collisions — “control” of a name means nothing more than picking a string others are unlikely to also pick — not an ownership requirement, and nothing verifies it. Consumers that do not recognize an extension namespace MUST preserve its values on round-trip and MUST NOT treat the document as invalid (the peaceful cohabitation rule, Section 3.7).

.onion.i2p