Skip to content

feat(fto): claim charts with manual per-feature findings (ADR 0011) - #23

Merged
corlin merged 1 commit into
feat/product-features-api-uifrom
feat/fto-claim-chart-store
Oct 4, 2026
Merged

corlin merged 1 commit into
feat/product-features-api-uifrom
feat/fto-claim-chart-store

Conversation

@corlin

@corlin corlin commented Oct 4, 2026

Copy link
Copy Markdown
Owner

Stacked on #22 (which now targets main and includes #21). Merge #22 first.

What

The comparison itself (ADR 0011). One chart = one patent's claims × one confirmed product feature set.

  • A person confirms claim features and records per-feature findings.
  • Claim-level conclusions are derived on read with the exact all-elements algorithm (ADR 0008).
  • As decided, findings are manual only: no automated suggestions.
  • Backend only; the screen is the next PR.

Design points

  • Snapshot at creation: creating a chart freezes the latest fetched claim document as parsed at that moment (claim numbers, dependencies, feature texts and spans, parser ID, claims-text SHA-256, what the text represents, warnings). Recorded findings therefore can't drift onto different features after a re-fetch or a parser change.
  • Guards: the product set must be confirmed and from the same case. Claims not yet fetched return 409; no external calls are made in the request path.
  • Input rules, enforced in both the service and DB CHECK constraints:
    • literally_present / present_by_equivalent must cite product feature codes from the chart's own product set
    • present_by_equivalent / absent need a rationale
    • equivalence is a professional judgment that is supplied, never computed
  • Caveats on every response:
    • US text is as granted (reexamination, IPR and corrections aren't reflected)
    • EP text may be a translation
    • conclusions are not a legal opinion

Storage (tenant data, FORCE RLS)

Table Mutability
fto_charts append-only
fto_chart_claim_features text frozen. Roles may update only the confirmation columns, and a trigger forbids revoking a confirmation
fto_feature_findings append-only: history kept, latest wins

API — /cases/{case}/fto/charts

Create · list · get (with conclusions and the features found absent) · confirm a claim's features · record a finding · finding history.

Audit summaries contain IDs, claim numbers and finding values only: no claim text, product text or rationale.

Tests

2 Postgres integration tests through the real app:

  • the guards
  • undetermined → reads_literally after confirmation → does_not_read once a feature is absent, inherited by the dependent claim
  • input rules, history, caveats (US and EP)
  • wrong case and other tenant both get 404
  • audit privacy (checked with a marker string)
  • DB immutability (snapshot text, confirmation revocation, findings, charts)

Mutation check: treating unconfirmed features as confirmed fails the flow test.

Validation

  • ./scripts/test-postgres.sh: 121 passed (+2)
  • .venv/bin/pytest apps/api/tests/unit/: 423 passed
  • pnpm test:web: 66 passed; pnpm build:web: ok
  • verify-source-lock, verify-scaffold, verify-p0-02, verify-p0-e2e, docker compose config: ok

🤖 Generated with Claude Code

Connects the pieces: one chart = one patent's claims x one confirmed
product feature set. A person confirms claim features and records
per-feature findings; claim-level conclusions are derived on read with
the exact all-elements algorithm (ADR 0008). Findings are manual only, as
decided; there are no automated suggestions.

- Creating a chart snapshots the latest fetched claim document: claim
  numbers, dependencies, feature texts and spans, parser id, claims-text
  SHA-256, what the text represents, and parse warnings. The chart stays
  tied to the text and parse it was built from even after re-fetches or
  parser changes. Requires a confirmed product set from the same case;
  claims not yet fetched return 409 (no external calls in the request
  path).
- Input rules (service and DB CHECKs): present findings must cite
  product feature codes from the chart's product set; equivalent and
  absent findings need a rationale. Equivalence is a supplied judgment,
  never computed.
- Every chart response carries caveats: US text is as granted
  (reexamination, IPR and corrections not reflected), EP text may be a
  translation, conclusions are not a legal opinion.
- Storage (0022, tenant FORCE RLS): fto_charts and fto_feature_findings
  are append-only (finding history kept; latest wins).
  fto_chart_claim_features text is frozen: runtime roles may update only
  the confirmation columns, and a trigger forbids revoking a confirmation.
- API under /cases/{case}/fto/charts: create, list, get (with
  conclusions), confirm a claim's features, record a finding, finding
  history. Audit summaries hold ids, claim numbers and finding values
  only; no claim text, product text or rationale.

Tests: 2 Postgres integration tests through the real app (guards;
undetermined -> reads_literally after confirmation -> does_not_read with
an absent feature, inherited by the dependent claim; input rules;
history; caveats; wrong case; other tenant; audit privacy; DB
immutability). Mutation check: treating unconfirmed features as confirmed
fails the flow test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@corlin
corlin merged commit 96f4b46 into feat/product-features-api-ui Oct 4, 2026
1 check failed
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.

1 participant