review r1 fix: sole-authoring-path precision; storage transport/adapter disposition recorded in code and inventory doc
ci/woodpecker/pr/ci Pipeline was successful

This commit is contained in:
fred
2026-08-29 16:36:26 -05:00
parent 931542ee19
commit e4cb0f99b1
3 changed files with 29 additions and 11 deletions
+7 -5
View File
@@ -2,11 +2,13 @@ import { describe, it, expect, vi } from 'vitest';
import { createMissionTasksRepo } from './mission-tasks.js';
/**
* SHARED-CONTRACT §5.5 "mission_tasks.status write prohibition": the repo is
* the sole write path, and it must never forward a caller-supplied status to
* the database on create or update. Callers keep working (the field is
* accepted and ignored), so these tests assert on what reaches the Drizzle
* chain, not on rejection.
* SHARED-CONTRACT §5.5 "mission_tasks.status write prohibition": this repo is
* the sole path that authors mission_tasks.status from caller input (storage
* tier migration is row transport and preserves stored values; the generic
* storage adapters have no mission_tasks caller), and it must never forward a
* caller-supplied status to the database on create or update. Callers keep
* working (the field is accepted and ignored), so these tests assert on what
* reaches the Drizzle chain, not on rejection.
*/
function makeInsertDb(returned: unknown[]) {
+11 -5
View File
@@ -4,11 +4,17 @@ export type MissionTask = typeof missionTasks.$inferSelect;
export type NewMissionTask = typeof missionTasks.$inferInsert;
// SHARED-CONTRACT §5.1 phase 1 / §5.4: mission_tasks.status is prohibited as a
// write source through the N-1 window. This repo is the sole write path, so the
// field is stripped here — accepted and ignored rather than rejected, because
// the legacy surface is frozen with existing consumers kept working
// (tool-gateway-mapping.md §3.2). The column keeps its DB default, stays
// declared and readable, and is retired only after no readers remain.
// write source through the N-1 window. This repo is the sole path that authors
// status from caller input, so the field is stripped here — accepted and
// ignored rather than rejected, because the legacy surface is frozen with
// existing consumers kept working (tool-gateway-mapping.md §3.2). Two other
// surfaces touch the column and are deliberately NOT stripped:
// packages/storage/migrate-tier.ts copies whole rows between storage tiers and
// must preserve the stored value verbatim, and the generic table-keyed storage
// adapters register mission_tasks but have no caller that targets it (runtime
// callers use fixed collection constants). Neither authors a new status. The
// column keeps its DB default, stays declared and readable, and is retired
// only after no readers remain.
function stripStatus<T extends { status?: unknown }>(data: T): Omit<T, 'status'> {
const rest = { ...data };
delete rest.status;