Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,29 @@ This is the **primary** instruction file for AI coding agents. `AGENTS.md` and `

## What this repository is

The single source of truth for generic, domain-agnostic Protobuf contracts shared across Feather gRPC services. The schema in `proto/feather/core/v1/core.proto` is compiled by `buf generate` into committed output under `gen/`, published as:
The single source of truth for generic, domain-agnostic Protobuf contracts shared across Feather gRPC services. The schema in `proto/feather/contracts/core/v1/core.proto` is compiled by `buf generate` into committed output under `gen/`, published as:

- **.NET**: `Feather.Contracts` NuGet package (`Contracts.csproj` compiles `gen/csharp`).
- **PHP**: `feather/contracts` composer package (autoloads `gen/php`).
- **Protobuf module**: `buf.build/feathertools/core` on the Buf Schema Registry.
- **Protobuf module**: `buf.build/feathertools/contracts` on the Buf Schema Registry.

It is consumed as a .NET dependency in `Feather.Grpc`, as a PHP dependency in the PHP contracts library, and by depending on the BSR module in other `.proto` files.

## Golden rules

- **`proto/core.proto` is the source of truth.** All message types are defined there. Never hand-edit generated output.
- **`proto/feather/contracts/core/v1/core.proto` is the source of truth.** All message types are defined there. Never hand-edit generated output.
- **Keep contracts generic and domain-agnostic.** This library holds only reusable primitives. Do not add domain-specific types.
- **NO abbreviations** in names. Use full, readable words (`Instance` not `Inst`, `Message` not `Msg`). Exception: an adopted standard's proper name is written fully uppercase.
- Change **only what is asked**. No unsolicited refactors, extra files, or "improvements".
- Do not add `.gitignore` entries or new tooling unless explicitly requested.

## Editing the schema

After changing `proto/feather/core/v1/core.proto`:
After changing `proto/feather/contracts/core/v1/core.proto`:

1. Lint: `buf lint` (config in `buf.yaml`, STANDARD rule set).
2. .NET classes regenerate automatically at build time via `Grpc.Tools` — run `./build.sh`.
3. Regenerate committed classes: `buf generate` (remote plugins in `buf.gen.yaml`, managed mode) emits C# to `gen/csharp` and PHP to `gen/php`. Commit the updated `gen/` output. `buf build` only compiles the schema; use `buf generate` to emit code.
2. Regenerate committed classes: `buf generate` (remote plugins in `buf.gen.yaml`, managed mode) emits C# to `gen/csharp` and PHP to `gen/php`. Commit the updated `gen/` output. `buf build` only compiles the schema; use `buf generate` to emit code.
3. Build the .NET package with `./build.sh`; `Contracts.csproj` compiles the committed `gen/csharp` (no `Grpc.Tools` codegen).

**Before opening a PR**, always run `buf generate` and commit the regenerated `gen/` files so they stay in sync with the schema in git.

Expand All @@ -36,7 +36,7 @@ After changing `proto/feather/core/v1/core.proto`:
- Messages / enums: `UpperCamelCase`
- Fields: `lower_snake_case`
- Enum values: `UPPER_SNAKE_CASE`
- Package is `feather.core.v1`; do NOT set `csharp_namespace` / `php_namespace` — Buf managed mode derives them (`Feather.Core.V1`, `Feather\Core\V1`).
- Package is `feather.contracts.core.v1`; do NOT set `csharp_namespace` / `php_namespace` — Buf managed mode derives them (`Feather.Contracts.Core.V1`, `Feather\Contracts\Core\V1`).

## Build & tooling

Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ The authoritative agent instructions for this repository live in
[`.github/copilot-instructions.md`](.github/copilot-instructions.md).

Read that file first and follow it for all work in this repository. It covers the
project purpose, the `proto/core.proto` source-of-truth rule, naming conventions,
project purpose, the `proto/feather/contracts/core/v1/core.proto` source-of-truth rule, naming conventions,
code generation, build tooling, CI, and the release process.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

<!-- There is always Unreleased section on the top. Subsections (Add, Changed, Fix, Removed) should be Add as needed. -->
## Unreleased
### Changed
- Renamed the package to `feather.contracts.core.v1` (module `buf.build/feathertools/contracts`, path `proto/feather/contracts/core/v1/core.proto`).
- Generated namespaces are now .NET `Feather.Contracts.Core.V1` and PHP `Feather\Contracts\Core\V1`.

## 1.1.0 - 2026-07-31
### Changed
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ The authoritative agent instructions for this repository live in
[`.github/copilot-instructions.md`](.github/copilot-instructions.md).

Read that file first and follow it for all work in this repository. It covers the
project purpose, the `proto/core.proto` source-of-truth rule, naming conventions,
project purpose, the `proto/feather/contracts/core/v1/core.proto` source-of-truth rule, naming conventions,
code generation, build tooling, CI, and the release process.
58 changes: 28 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@

> Core Protobuf contracts (generic, reusable message types) shared across Feather gRPC services — packaged for both .NET and PHP.

This repository is the single source of truth for the low-level, domain-agnostic contracts used across Feather. The Protobuf schema in [`proto/feather/core/v1/core.proto`](proto/feather/core/v1/core.proto) is compiled into:
This repository is the single source of truth for the low-level, domain-agnostic contracts used across Feather. The Protobuf schema in [`proto/feather/contracts/core/v1/core.proto`](proto/feather/contracts/core/v1/core.proto) is compiled into:

- a **.NET** library published as the [`Feather.Contracts`](https://www.nuget.org/packages/Feather.Contracts) NuGet package,
- a **PHP** package (`feather/contracts`) with generated message, client and RoadRunner server classes under [`gen/php/`](gen/php/), and
- a **Protobuf module** published to the [Buf Schema Registry](https://buf.build/feathertools/core) (`buf.build/feathertools/core`).
- a **Protobuf module** published to the [Buf Schema Registry](https://buf.build/feathertools/contracts) (`buf.build/feathertools/contracts`).

It is designed to be consumed in three ways:

1. As a **.NET dependency** in the `Feather.Grpc` library, providing the core message types.
2. As a **PHP dependency** in the PHP contracts library, providing the same core types.
3. **Directly in other `.proto` files**, by depending on the BSR module `buf.build/feathertools/core` and referencing the `feather.core.v1` types.
3. **Directly in other `.proto` files**, by depending on the BSR module `buf.build/feathertools/contracts` and referencing the `feather.contracts.core.v1` types.

## Contracts

All messages live in the `feather.core.v1` package ([`proto/feather/core/v1/core.proto`](proto/feather/core/v1/core.proto)):
All messages live in the `feather.contracts.core.v1` package ([`proto/feather/contracts/core/v1/core.proto`](proto/feather/contracts/core/v1/core.proto)):

| Message | Purpose |
| ----------------------- | ------------------------------------------------------------------------------ |
Expand All @@ -32,10 +32,10 @@ All messages live in the `feather.core.v1` package ([`proto/feather/core/v1/core
| `Box` | An `Instance` bound to a `Spot`. |
| `SerializedForChunking` | Wrapper (`bytes content`) for chunking large payloads in streaming gRPC calls. |

Generated namespaces (derived by Buf managed mode from the `feather.core.v1` package):
Generated namespaces (derived by Buf managed mode from the `feather.contracts.core.v1` package):

- .NET: `Feather.Core.V1`
- PHP: `Feather\Core\V1` (messages) and `Feather\Core\V1\GPBMetadata` (metadata)
- .NET: `Feather.Contracts.Core.V1`
- PHP: `Feather\Contracts\Core\V1` (messages) and `Feather\Contracts\Core\V1\GPBMetadata` (metadata)

## Install

Expand All @@ -46,7 +46,7 @@ dotnet add package Feather.Contracts
```

```fsharp
open Feather.Core.V1
open Feather.Contracts.Core.V1

let error = Error(Name = "NotFound", Message = "Instance not found")
```
Expand All @@ -73,7 +73,7 @@ composer require feather/contracts:dev-main
```

```php
use Feather\Core\V1\Error;
use Feather\Contracts\Core\V1\Error;

$error = (new Error())->setName('NotFound')->setMessage('Instance not found');
```
Expand All @@ -85,19 +85,19 @@ Add the BSR module as a dependency in your `buf.yaml`:
```yaml
version: v2
deps:
- buf.build/feathertools/core
- buf.build/feathertools/contracts
```

Then import and reference the `feather.core.v1` types:
Then import and reference the `feather.contracts.core.v1` types:

```proto
syntax = "proto3";

import "feather/core/v1/core.proto";
import "feather/contracts/core/v1/core.proto";

message Envelope {
feather.core.v1.CorrelationId correlation_id = 1;
feather.core.v1.Error error = 2;
feather.contracts.core.v1.CorrelationId correlation_id = 1;
feather.contracts.core.v1.Error error = 2;
}
```

Expand All @@ -124,31 +124,29 @@ Common flags: `no-lint`, `no-clean` to skip the respective steps.

## Working with the Protobuf schema

[`proto/feather/core/v1/core.proto`](proto/feather/core/v1/core.proto) is the source of truth. After editing it:
[`proto/feather/contracts/core/v1/core.proto`](proto/feather/contracts/core/v1/core.proto) is the source of truth. After editing it:

1. **Lint** the schema:

```sh
buf lint
```

2. **.NET** classes are generated automatically at build time by `Grpc.Tools` (see [`Contracts.csproj`](Contracts.csproj)) — just run `./build.sh`.

3. **PHP** classes (and the C# reference output) are regenerated with Buf using the remote plugins in [`buf.gen.yaml`](buf.gen.yaml):
2. **.NET** and **PHP** classes are regenerated with Buf using the remote plugins in [`buf.gen.yaml`](buf.gen.yaml):

```sh
buf generate
```

This produces PHP message, client and RoadRunner server classes under [`gen/php/`](gen/php/) (namespace `Feather\Core\V1`) and the C# under [`gen/csharp/`](gen/csharp/); both are committed to the repository. `buf build` only compiles the schema to an in-memory image; use `buf generate` to emit code.
This produces C# under [`gen/csharp/`](gen/csharp/) (namespace `Feather.Contracts.Core.V1`, compiled by [`Contracts.csproj`](Contracts.csproj)) and PHP message, client and RoadRunner server classes under [`gen/php/`](gen/php/) (namespace `Feather\Contracts\Core\V1`); both are committed to the repository. `buf build` only compiles the schema to an in-memory image; use `buf generate` to emit code.

> **Before opening a PR**, run `buf generate` and commit the regenerated `gen/` files so they stay in sync with the schema in git.

4. **Publish** the module to the Buf Schema Registry:
3. **Publish** the module to the Buf Schema Registry:

```sh
buf registry login # first time only
buf push # publishes buf.build/feathertools/core
buf push # publishes buf.build/feathertools/contracts
```

### Proto conventions
Expand All @@ -160,15 +158,15 @@ Common flags: `no-lint`, `no-clean` to skip the respective steps.
## Repository layout

```
proto/feather/core/v1/core.proto # Source-of-truth Protobuf schema
buf.yaml # Buf module (buf.build/feathertools/core), lint & breaking config
buf.gen.yaml # Buf code generation (managed mode, remote plugins)
Contracts.csproj # .NET package (Feather.Contracts), compiles gen/csharp
composer.json # PHP package (feather/contracts), autoloads gen/php
gen/csharp/ # Generated C# classes (committed, compiled by Contracts.csproj)
gen/php/ # Generated PHP classes (committed, autoloaded by composer)
build/ # FAKE build project (F#)
.github/workflows/ # CI: net-tests, php-tests, proto-lint, net-publish, bsr-publish, pr-check
proto/feather/contracts/core/v1/core.proto # Source-of-truth Protobuf schema
buf.yaml # Buf module (buf.build/feathertools/contracts), lint & breaking config
buf.gen.yaml # Buf code generation (managed mode, remote plugins)
Contracts.csproj # .NET package (Feather.Contracts), compiles gen/csharp
composer.json # PHP package (feather/contracts), autoloads gen/php
gen/csharp/ # Generated C# classes (committed, compiled by Contracts.csproj)
gen/php/ # Generated PHP classes (committed, autoloaded by composer)
build/ # FAKE build project (F#)
.github/workflows/ # CI: net-tests, php-tests, proto-lint, net-publish, bsr-publish, pr-check
```

## Releasing
Expand Down
2 changes: 1 addition & 1 deletion buf.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: v2
modules:
- path: proto
name: buf.build/feathertools/core
name: buf.build/feathertools/contracts
lint:
use:
- STANDARD
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
},
"autoload": {
"psr-4": {
"Feather\\Core\\V1\\": "gen/php/Feather/Core/V1/"
"Feather\\Contracts\\Core\\V1\\": "gen/php/Feather/Contracts/Core/V1/"
}
},
"archive": {
Expand Down
Loading