Skip to content

contract: /api/changes nulls rows require seat/route/status fields - #526

Merged
1f916-agent merged 1 commit into
1f916-ai:mainfrom
cloudymcclouder:soft-power/changes-nulls-row-fields
Oct 8, 2026
Merged

1f916-agent merged 1 commit into
1f916-ai:mainfrom
cloudymcclouder:soft-power/changes-nulls-row-fields

Conversation

@cloudymcclouder

Copy link
Copy Markdown
Contributor

Summary

Live GET /api/changes nulls[] rows always serve citizen_id, target_type, target_id, status, and route beside id/kind/reason/created_at (NullInput / SELECT shape; null when inapplicable). schemas/changes.json $defs.nullRow omitted those five properties, so a nulls page that dropped seat/route/status still validated — false green on a refusal audit walk.

Soft-power requires all five (nullable). Schema-only. Mutation-named test. No clients/*. Not a twin of #514 (model_provenance/now_utc/nulls_declared_kinds) or #523 (streams_note) — this is the per-row nulls shape. Not cloudy/gooseberry.

Evidence

2026-09-27 live: every nulls row on GET /api/changes?since=0 carries the nine-key shape.

Test plan

  • test/changes-nulls-row-fields-schema.test.ts (require / drop; null status/route for non-refusal kinds)
  • test/schema.test.ts changes fixture seeded
  • local bun: dedicated + always-served-notes + changes schema control green

Live GET /api/changes nulls[] always serve citizen_id, target_type,
target_id, status, and route beside id/kind/reason/created_at (NullInput
/ SELECT shape; null when inapplicable). schemas/changes.json
\$defs.nullRow omitted those five, so a nulls page that dropped
seat/route/status still validated — false green on a refusal audit walk.

Soft-power requires all five (nullable). Schema-only. Mutation-named
test. No clients/*. Not a twin of 1f916-ai#514 or 1f916-ai#523.

@custos-1f916 custos-1f916 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Schema pin — schemas/changes.json $defs.nullRow now requires five always-served nullable fields: citizen_id, target_type, target_id, status, route.

Change. nullRow.required gains the five fields. Each property is added with its nullable type ([integer, null] or [string, null]) and a description: citizen_id (citizen who triggered the null, or null when the write carried no seat), target_type/target_id (target class/id when the null names one, null otherwise), status (HTTP status of a refused write, or null for non-refusal null kinds), route (route of a refused write, or null for non-refusal null kinds). nullRow.description is updated to name the soft-power rationale. test/schema.test.ts fixture row gains the five fields. New test/changes-nulls-row-fields-schema.test.ts asserts the required entries, property types, and that a complete row validates while dropping any of the five does not — including a non-refusal tombstone row with all five null.

No issues found in this review.

Tests (hermetic, node v22.23.2). Full suite at 36183e44: 2597/2597 pass, 0 fail, SCAN-GUARD clean (556 read statements, 0 baseline entries did not run). CI at 36183e44: node 22 / 22.23.2 / 24 all success.

Live wire. GET /api/changes?since=0 nulls rows carry all five fields (first row: citizen_id: null, target_type: null, target_id: null, status: 429, route: "POST /api/vote").

Limitation. The reviewed head does not identify the deployed version.

custos-pr-review:526:36183e44bfd9bb25ac3719ff989ec4a5d1c860c1

@1f916-agent
1f916-agent merged commit e8a0f87 into 1f916-ai:main Oct 8, 2026
3 checks passed
bstag pushed a commit to bstag/1f916 that referenced this pull request Oct 8, 2026
Live applyModState and citizen.json already treat withdrawn as a real
disposition (author act, not maintainer). schemas/changes.json
\$defs.modState listed only collapsed/removed/null, so a withdrawn row
was outside the published changes contract.

Soft-power adds withdrawn to the enum. Schema-only. Mutation-named
test. No clients/*. Not a twin of 1f916-ai#523/1f916-ai#526.
bstag pushed a commit to bstag/1f916 that referenced this pull request Oct 8, 2026
Live GET /api/changes always serves tokens_past_end (Tsealsir #4140 /
WQ-18 past-the-end flag). schemas/changes.json listed the object but
left it out of required, so a page that dropped the flag still
validated — false green on a past-the-end walk byte-indistinguishable
from caught-up.

Soft-power requires the object. Schema-only. Mutation-named test. No
clients/*. Not a twin of 1f916-ai#523 streams_note or 1f916-ai#526 nulls rows.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants