Skip to content

Commit 798fa38

Browse files
etrclaude
andcommitted
TASK-009 follow-up: forward-task spec edits (TASK-010, TASK-013)
These edits were prepared in the parent worktree before the TASK-009 worktree branch landed, and the validation-fixer's iter-1 pass missed absorbing them into the housekeeping commit: - TASK-010: clarify the heap-fallback factory contract — must use `::operator new(sizeof(...))` + placement-new (not plain `new`) so that http_response's destructor (which always calls ~body() and then ::operator delete on the heap path) does not double-destroy. - TASK-013: add the `final` action item and `static_assert(is_final_v)` AC that were deferred from TASK-009 because the v1 subclasses still inherit at TASK-009 time. This is the receiving end of the deferral documented in TASK-009.md's AC. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 2af5e36 commit 798fa38

2 files changed

Lines changed: 3 additions & 1 deletion

File tree

specs/tasks/M2-response/TASK-010.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Provide one canonical way to construct each body kind via static factories that
1616
- `static http_response empty();`
1717
- `static http_response deferred(std::function<ssize_t(std::uint64_t, char*, std::size_t)> producer);`
1818
- `static http_response unauthorized(std::string_view scheme, std::string_view realm, std::string body = {});`
19-
- [ ] Each factory placement-news the appropriate `detail::body` subclass into `body_storage_`; falls back to `new` if the subclass doesn't fit (per DR-005 graceful fallback).
19+
- [ ] Each factory placement-news the appropriate `detail::body` subclass into `body_storage_` (and sets `body_inline_ = true`); for the (currently empty) heap-fallback path, the factory MUST use `::operator new(sizeof(concrete_body))` followed by placement-new (NOT plain `new concrete_body(...)`) so that `http_response`'s destructor — which always calls `body_->~body()` and then `::operator delete(body_)` for the heap path — does not double-destroy. This contract is set by TASK-009 (plan OQ-4) for symmetry between inline and heap teardown.
2020
- [ ] `unauthorized()` covers both basic and digest auth (scheme parameter); replaces v1's `basic_auth_fail_response` and `digest_auth_fail_response`.
2121
- [ ] Document lifetime: `pipe(fd, ...)` takes ownership of `fd` and closes it after the response is materialized.
2222

specs/tasks/M2-response/TASK-013.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Delete the public-facing response subclasses and the `get_raw_response`/`decorat
1313
- [ ] Remove the public virtual methods `get_raw_response`, `decorate_response`, `enqueue_response` from `http_response.hpp`.
1414
- [ ] Update `<httpserver.hpp>` umbrella to drop the removed includes.
1515
- [ ] Internal dispatch path (in `webserver.cpp` or `http_response.cpp`) calls `body_->materialize(...)` instead of the removed virtuals.
16+
- [ ] Add `final` to `http_response` (deferred from TASK-009 because the v1 subclasses still inherited at that point — see TASK-009 plan OQ-1). Per PRD §3.5 the class must be sealed.
1617

1718
**Dependencies:**
1819
- Blocked by: TASK-009, TASK-010, TASK-011, TASK-012
@@ -21,6 +22,7 @@ Delete the public-facing response subclasses and the `get_raw_response`/`decorat
2122
**Acceptance Criteria:**
2223
- `grep -E 'class\s+\w+_response\s*:' src/httpserver/*.hpp` returns no public results (PRD §3.5 acceptance).
2324
- `grep -E 'get_raw_response|decorate_response|enqueue_response' src/httpserver/*.hpp` returns no results.
25+
- `static_assert(std::is_final_v<httpserver::http_response>);` (deferred AC from TASK-009 — PRD §3.5 sealed value type).
2426
- Existing tests that constructed `string_response` etc. directly are migrated to factories (or removed if they were testing private details).
2527
- Typecheck passes.
2628
- Tests pass.

0 commit comments

Comments
 (0)