Commit Graph
3 Commits
Author SHA1 Message Date
Yogesh OjhaandClaude Fable 5.1 0a69f3201c copy: state the fact, delete the explanation
Repo-wide sweep of every user-facing string: frontend components, routes,
config and stores; API details and route docs; shared definitions and
models; stage config help; report prose; MCP, toolbox, interest and
connector text; notification and worker messages.

Descriptions that explained, reassured, justified or restated their title
are deleted. Confirm dialogs name what is removed and stop. Failed actions
read "<Noun> not <verbed>", successes "<Noun> <verbed>". No reader address,
no product-as-subject, no em-dashes or parentheticals in prose.

Mirrors updated on both sides: EPSS band help, compare refusal reasons,
interest labels. Four tests asserting on old wording follow the new text.
The rules are condensed into CLAUDE.md under Writing.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SK5o8xR96cbSnAfjYSTPSe
2026-09-12 11:35:07 +05:30
Yogesh OjhaandClaude Opus 5 2cb8d73280 style: strip explanatory comments across the codebase
The comment rule in CLAUDE.md is one line maximum, never narration: no
multi-line blocks, no module-header explainers, no sentences that explain or
justify the code to the reader. The tree had drifted a long way from it, and
most of the drift is mine.

Removed:
  232  lines of multi-line comment blocks
  203  single-line comments that argued instead of stating
  154  comments joined by so/because/otherwise/rather-than
  143  narrating comments in the frontend
  112  test docstrings (the test name already says what it asserts)
   25  test module docstrings and 25 decorative section dividers

Collapsed:
  324  multi-line docstrings to one factual line
  271  one-line docstrings that had a justifying clause bolted on

Kept: functional directives, section dividers, short field labels, alembic
revision headers, and the eight FastAPI route docstrings that render in /docs.
Where a fact was load-bearing it is in CLAUDE.md, which is where it belongs.

284 python tests and 34 frontend tests pass, ruff and ruff-format clean across
ten packages, svelte-check 0 errors, prettier and eslint clean, app.main imports.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013dKUV96WkQQETZBMoAG98C
2026-09-11 14:11:23 +05:30
Yogesh OjhaandClaude Opus 5 1dad791d94 fix(api): a value Postgres refuses returned 500 instead of 400
A write fuzz over all 113 unguarded write operations (6,465 requests)
produced 36 unhandled 500s. Every one was the same shape: a value
pydantic accepted that Postgres then refused while binding or writing,
surfacing as an unhandled DBAPIError.

Three kinds appeared — a NUL byte in any text field (project, org, tag
and engine names, MCP token names, interest rule queries, the `q` of
all six search grammars, endpoint verify host and path), a string
longer than its column (project label against varchar(50)), and an
integer past bigint (a body-supplied page number, interest rule
weight).

All three are SQLSTATE class 22, the SQL standard's data exception
class, which by definition means the supplied value cannot be
represented in the target column. That is always a client error, so a
handler now maps class 22 to 400 with a message naming the kind of
problem, and re-raises everything else. Class 23 (integrity) is
deliberately left alone: it can indicate a server fault.

The one class 23 failure was a genuine defect rather than bad input.
InterestService.update wrote an explicit null straight through to a
NOT NULL column, so PATCH {"enabled": null} was a 500. It now stores a
null only where the column accepts one, taking that from the column
itself, which keeps `weight: null` clearing the weight while `enabled:
null` means unchanged — the convention every other update service here
already follows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K6LcH8uUddjJbKrahf34ys
2026-09-07 06:54:02 +05:30