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
50 changes: 28 additions & 22 deletions docs/release/v1.0-acceptance.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
- Target: v1.0 release candidate
- Current project version during hardening: v0.9.0
- Scope: synchronous HTTP/1.1 over plaintext TCP
- Purpose: map frozen v1 requirements to concrete implementation/test/CI evidence
- Automated release gates: **Passed**
- Manual acceptance review: **Passed (2026-09-16)**
- Next step: focused `0.9.0 -> 1.0.0` promotion PR

This document is a release gate, not a replacement for `docs/requirements/functional.md` or `docs/requirements/non-functional.md`. A requirement remains authoritative in those frozen documents. This matrix records how the repository verifies it before the version is promoted to v1.0.0.

A v1.0 version bump/tag must not happen until all required CI checks are green and no release-blocking correctness issue remains.
A v1.0 tag/release must not happen until the focused promotion PR is green and merged.

---

Expand All @@ -34,7 +36,7 @@ A v1.0 version bump/tag must not happen until all required CI checks are green a
| Write timeout | REQ-TIME-003 | `tcp_io_test.cpp` (`WriteTimeoutClosesConnection`) | Covered |
| Structured Result / errors | REQ-ERR-001..003 | `result_test.cpp`, protocol/transport error tests, `docs/api/error-model.md` | Covered |
| Stateful client + convenience helpers | REQ-API-001, REQ-API-002 | `client_test.cpp`, public examples | Covered |
| Native socket encapsulation | REQ-API-003 | public-header isolation target + installed consumer | Release gate |
| Native socket encapsulation | REQ-API-003 | public-header isolation target + installed consumer | Passed |
| No mandatory PImpl | REQ-API-004 | public type definitions / implementation inspection | Covered |
| Thread-safety contract | REQ-API-005 | `README.md`, `docs/getting-started.md`, `docs/api/public-api.md` | Covered |
| `std::string_view` contract | REQ-API-006 | public headers + `docs/api/lifetime.md` | Covered |
Expand All @@ -46,7 +48,7 @@ A v1.0 version bump/tag must not happen until all required CI checks are green a
| Requirement area | Requirement IDs | Primary evidence | Gate status |
| --- | --- | --- | --- |
| C++17 minimum | REQ-COMP-001 | target `cxx_std_17`, normal CI matrix | Covered |
| Newer-standard compatibility | REQ-COMP-002 | v1 release gate C++20 build + installed consumer | Release gate |
| Newer-standard compatibility | REQ-COMP-002 | v1 release gate C++20 build + installed consumer | Passed |
| Zero third-party runtime dependency | REQ-DEP-001 | native socket implementation, install-tree consumer | Covered |
| Dev dependencies do not leak | REQ-DEP-002, REQ-BUILD-003 | package export + `PackageConsumer.InstallAndUse` | Covered |
| Allocation/copy discipline | REQ-PERF-001, REQ-PERF-002 | borrowed request body boundary, parser design, benchmarkable hot paths | Reviewed |
Expand All @@ -56,10 +58,10 @@ A v1.0 version bump/tag must not happen until all required CI checks are green a
| Windows / Linux | REQ-PORT-001, REQ-PORT-002 | Debug/Release CI jobs | Covered |
| macOS compatibility | REQ-PORT-003 | Debug/Release CI jobs | Covered |
| Platform isolation | REQ-PORT-004 | `src/platform`, `src/net`, `src/http` boundaries + public-header gate | Covered |
| Deterministic cleanup | REQ-REL-001 | RAII tests + sanitizer gate + timeout-close tests | Release gate |
| Deterministic cleanup | REQ-REL-001 | RAII tests + sanitizer gate + timeout-close tests | Passed |
| Predictable errors / no downgrade | REQ-REL-002, REQ-REL-003 | result/error tests, HTTPS rejection tests | Covered |
| Bounded waits | REQ-REL-004 | connect/read/write timeout tests | Covered |
| Small public surface | REQ-APIQ-001 | eight installed public headers + public-header isolation gate | Release gate |
| Small public surface | REQ-APIQ-001 | eight installed public headers + public-header isolation gate | Passed |
| Value-oriented types | REQ-APIQ-002 | public type inspection | Reviewed |
| Move support | REQ-APIQ-003 | client move tests / resource ownership tests | Covered |
| Thread-safety docs | REQ-APIQ-004 | README / getting-started / public API docs | Covered |
Expand All @@ -77,7 +79,7 @@ A v1.0 version bump/tag must not happen until all required CI checks are green a

## Automated v1 release gates

### Existing gates
All required automated gates were green on the release-hardening candidate merged through PR #30.

1. `C++ CI Build`
- Windows, Linux, macOS.
Expand All @@ -90,15 +92,12 @@ A v1.0 version bump/tag must not happen until all required CI checks are green a
- Windows, Linux, macOS Release builds.
- all v0.9 benchmark executables build and execute locally.

### Added by release hardening

3. `v1 Release Gate / ASan + UBSan (Clang, C++17)`
- Debug Clang build.
- warnings as errors.
- AddressSanitizer + UndefinedBehaviorSanitizer.
- leak detection enabled on Linux.
- unit and loopback tests run under sanitizers.
- the install-consumer test is excluded from this sanitizer run because an independently configured consumer would otherwise need matching sanitizer link flags.

4. `v1 Release Gate / C++20 Compatibility + Installed Consumer`
- full C++20 project build and tests.
Expand All @@ -116,22 +115,29 @@ A v1.0 version bump/tag must not happen until all required CI checks are green a

## Manual release review

The following checks remain deliberate human review items before the final v1.0.0 bump/tag:
Manual review is complete. The detailed record is [`v1.0-manual-review.md`](v1.0-manual-review.md).

Reviewed areas:

- confirm no unresolved correctness issue can corrupt HTTP framing or connection reuse,
- review performance claims against the committed benchmark suite rather than intuition,
- review public API/lifetime docs against current headers,
- confirm the installed target has no GTest/Google Benchmark dependency,
- confirm no post-v1 feature slipped into the frozen scope,
- review release notes/versioning/tagging metadata.
- HTTP framing and connection-reuse correctness,
- performance-claim discipline against the committed benchmark suite,
- public API and lifetime documentation against current headers,
- exported dependency/package boundary,
- frozen-scope compliance,
- versioning/tagging/release metadata.

No code/API feature blocker remains. The repository manifest version mismatch found during review is corrected by the acceptance-cleanup branch before promotion.

---

## Promotion rule

When all automated release-gate checks are green and the manual review above has no blocker, the next change should be a focused release PR that:
The next focused release PR should:

1. change both CMake and manifest versions from `0.9.0` to `1.0.0`,
2. update roadmap/release status to v1.0 complete,
3. freeze remaining editorial pre-release API-document wording,
4. finalize `v1.0-notes.md`,
5. pass all required CI/release gates again.

1. changes the project version from `0.9.0` to `1.0.0`,
2. updates roadmap/release status to v1.0 complete,
3. adds final release notes/changelog metadata if desired,
4. creates the v1.0 tag/release only after that release PR is merged.
Create tag `v1.0.0` and the GitHub release only after that promotion PR is merged.
110 changes: 110 additions & 0 deletions docs/release/v1.0-manual-review.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# v1.0 Manual Acceptance Review

## Status

- Project: `cpp_request`
- Review date: 2026-09-16
- Candidate version during review: `0.9.0`
- Target release: `1.0.0`
- Result: **Accepted for focused version-promotion PR**

This review closes the deliberate human checks listed in `v1.0-acceptance.md`. It does not create a tag or release and does not expand the frozen v1 scope.

## 1. HTTP framing and connection reuse

Reviewed the release-candidate execution path and the existing framing/reuse evidence.

Key observations:

- a retained socket is adopted only for the same effective host and port,
- retained state is cleared before an adopted connection is used,
- write/read/parser failures leave the active `TcpConnection` to close rather than returning it to reusable state,
- a connection is retained only when the parser marks it reusable, there are no pending bytes, the socket is connected, and the request did not ask for `Connection: close`,
- resource-limit and framing failures do not produce a successful partial response,
- stale keep-alive failure is not hidden by an automatic retry.

The release-gate tests, cross-platform CI, and ASan/UBSan run are green. No release-blocking framing/reuse correctness issue was identified during this review.

## 2. Performance claims

The user-facing documentation makes qualitative claims such as lightweight/native/dependency-free at runtime, but does not publish unsupported throughput or latency numbers.

Performance-sensitive areas have committed benchmark coverage for:

- request serialization,
- response parsing,
- chunked decoding,
- steady-state loopback client execution,
- connection reuse versus reconnect.

The benchmark smoke workflow is green across the supported CI platforms. No quantitative performance claim is promoted beyond the committed benchmark evidence.

## 3. Public API and lifetime contract

The installed public surface contains eight headers:

- `client.hpp`
- `error.hpp`
- `headers.hpp`
- `request.hpp`
- `response.hpp`
- `response_limits.hpp`
- `result.hpp`
- `url.hpp`

The public-header isolation gate compiles each header independently using only the public include directory.

Reviewed the current headers against the API/lifetime documentation:

- `Client` is move-only and stateful,
- request URL/body are borrowed `std::string_view` values,
- headers and appended query parameters own copied text,
- responses own reason/header/body storage,
- `Result<T>` exposes explicit success/failure state and preconditioned accessors,
- `Result<void>` remains intentionally unsupported in v1,
- only `http://` is supported,
- response limits and redirect configuration match the documented v1 behavior.

No semantic mismatch requiring an API change was found. Editorial pre-release wording in API documents can be promoted from “Proposed” to final v1 wording in the focused `1.0.0` promotion PR without changing behavior.

## 4. Dependency and package boundary

The production `cpp_request` target has no third-party runtime library dependency. On Windows it links the native `ws2_32` system library; POSIX platforms use native socket APIs.

GoogleTest and Google Benchmark remain development/test tooling and are not part of the exported `cpp_request::cpp_request` link interface. Installed-consumer gates are green, including the C++20 compatibility consumer.

The repository manifest version was found stale at `0.1.0` while the CMake project version was `0.9.0`. The acceptance-cleanup branch synchronizes the manifest to `0.9.0`; the final promotion PR must advance both version sources together to `1.0.0`.

## 5. Frozen scope check

No post-v1 feature was found in the release path. The following remain outside v1:

- HTTPS/TLS,
- async/coroutines,
- HTTP/2 and HTTP/3,
- WebSocket,
- proxy support,
- cookie jar,
- multipart builder,
- gzip/brotli decompression,
- request/response streaming,
- generalized connection pool,
- automatic retries,
- response cache.

## 6. Release metadata plan

The focused promotion PR should be limited to release metadata/documentation:

1. bump CMake project version `0.9.0 -> 1.0.0`,
2. bump `vcpkg.json` version `0.9.0 -> 1.0.0`,
3. mark the v1 roadmap and acceptance status complete,
4. freeze editorial API-document status wording for v1,
5. finalize `docs/release/v1.0-notes.md`,
6. run all required CI/release gates again.

After that PR is merged, create tag `v1.0.0` and the GitHub release as a separate explicit action.

## Decision

The v1 release candidate passes manual acceptance review. No code/API feature work is required before the focused `1.0.0` promotion PR.
88 changes: 88 additions & 0 deletions docs/release/v1.0-notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# cpp_request v1.0 Release Notes

## Status

Draft release notes for the v1.0 promotion. The repository remains version `0.9.0` until the focused promotion PR is merged.

## Overview

`cpp_request` v1.0 is a lightweight synchronous HTTP/1.1 client for C++17 built directly on native operating-system sockets.

The release intentionally focuses on a small, predictable surface: plaintext HTTP over TCP, explicit structured errors, bounded synchronous I/O, connection reuse, redirects, installable CMake packaging, and zero third-party runtime dependencies.

HTTPS/TLS is intentionally not part of v1.0.

## Highlights

- C++17 baseline with C++20 compatibility coverage
- Windows, Linux, and macOS support
- native Winsock2 / POSIX socket transport
- IPv4 and IPv6 resolution/connection support
- GET, HEAD, POST, PUT, PATCH, and DELETE
- ordered custom headers and query parameters
- borrowed request URL/body with documented lifetime rules
- in-memory owned responses
- `Content-Length`, close-delimited, and chunked response decoding
- HTTP/1.1 keep-alive reuse for eligible same-origin requests
- bounded configurable redirects
- separate connect/read/write timeouts
- configurable response head/body/chunk/trailer limits
- structured `Result<T>` / `Error` failure model
- installable `cpp_request::cpp_request` CMake target
- benchmark suite for serializer/parser/chunk/client/reuse paths
- cross-platform CI plus ASan/UBSan release gate

## HTTP behavior

v1.0 supports synchronous HTTP/1.1 over plaintext TCP only. `https://` and redirect targets requiring unsupported schemes fail explicitly rather than silently downgrading or changing transports.

Automatic redirect following is enabled by default with a finite maximum. Redirect handling covers 301, 302, 303, 307, and 308 with documented method/body rules and cross-origin sensitive-header stripping.

Connection reuse is conservative: an active connection is retained only when response framing is complete and reusable, no unread/pending response bytes remain, and neither side requires closure.

## Reliability and safety

The release hardening gate includes:

- Windows/Linux/macOS Debug and Release CI,
- unit and local-loopback integration tests,
- C++20 compatibility build/test,
- installed-package consumer tests,
- public-header isolation compilation,
- ASan + UBSan test execution with Clang,
- warnings-as-errors hardening builds,
- benchmark smoke execution.

Expected URL, DNS, connection, timeout, protocol, redirect, EOF, and resource-limit failures are represented through structured error codes instead of requiring library-specific exceptions.

## Packaging

Consumers can install the library and use:

```cmake
find_package(cpp_request CONFIG REQUIRED)
target_link_libraries(my_app PRIVATE cpp_request::cpp_request)
```

The exported production target does not expose GoogleTest or Google Benchmark dependencies.

## Intentional v1.0 non-goals

The following are deferred to post-v1 design work:

- HTTPS / TLS
- asynchronous API / coroutines
- HTTP/2 / HTTP/3
- WebSocket
- proxy support
- cookie jar
- multipart builder
- gzip/brotli decompression
- request/response streaming
- generalized connection pool
- automatic retries
- response cache

## Upgrade note

v1.0 is the first stable release line. The public v1 contracts are documented under `docs/api/`, with requirement evidence in `docs/release/v1.0-acceptance.md` and the manual review record in `docs/release/v1.0-manual-review.md`.
Loading
Loading