feat(ts): add real quality gates — Biome lint + effect-law ratchet + class inventory

- biome.json (2.4.16, linter-only) wired as "lint" in all six packages
- scripts/check-effect-laws.ts: Effect-native law enforcement encoding the
  adapted beep-effect effect-first/schema-first laws (no native JSON/switch/
  sort/fetch/timers, no process.env, no throw new, no Effect.run* outside
  boundaries, no Schema-suffixed constants, no node:fs/path, AST-based
  pure-data interface detection per law 38/39)
- ratcheting baseline allowlist (95 entries / 290 findings) that must shrink
  to documented exemptions only; stale counts fail the gate
- root lint chains turbo lint + law check + native-class inventory
- fix all 163 initial Biome findings: import-type style, templates, two `any`s,
  ten non-null assertions (librarian getService gate, A.matchRight in atoms,
  ensureNode returning nodes, main.tsx mount guard)

Gates: lint, check:tsgo, build, test (force, 11 tasks) all green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
elpresidank 2026-06-11 06:40:01 -05:00
parent cf12defcd8
commit 0746d7ffd5
109 changed files with 951 additions and 611 deletions

View file

@ -1,25 +1,29 @@
import { Clipboard as BrowserClipboard } from "@effect/platform-browser";
import * as BrowserHttpClient from "@effect/platform-browser/BrowserHttpClient";
import * as BrowserKeyValueStore from "@effect/platform-browser/BrowserKeyValueStore";
import type {
GraphRagOptions,
BaseApi,
BeginUploadResponse,
ChunkedUploadDocumentMetadata,
CompleteUploadResponse,
ConnectionState,
DocumentMetadata,
ExplainEvent,
StreamingMetadata,
Term,
Triple,
UploadChunkResponse,
} from "@trustgraph/client";
import {
DispatchPayload,
GatewayWorkbenchHttpApi,
type GraphRagOptions,
makeBaseApi,
TrustGraphRpcs,
type BaseApi,
type BeginUploadResponse,
type ChunkedUploadDocumentMetadata,
type CompleteUploadResponse,
type ConnectionState,
type DocumentMetadata,
type ExplainEvent,
type StreamingMetadata,
type Term,
type Triple,
type UploadChunkResponse,
} from "@trustgraph/client";
import { Cause, Clock, Context, Effect, Layer, Match, Metric, Option, Random, Schema as S, Scope, Stream } from "effect";
import type { Scope, } from "effect";
import { Cause, Clock, Context, Effect, Layer, Match, Metric, Option, Random, Schema as S, Stream } from "effect";
import * as A from "effect/Array";
import * as MutableHashMap from "effect/MutableHashMap";
import * as Predicate from "effect/Predicate";
import { HttpClient, HttpClientRequest } from "effect/unstable/http";
@ -28,7 +32,7 @@ import * as RpcClient from "effect/unstable/rpc/RpcClient";
import * as RpcSerialization from "effect/unstable/rpc/RpcSerialization";
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
import * as Atom from "effect/unstable/reactivity/Atom";
import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry";
import type * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry";
import * as AtomHttpApi from "effect/unstable/reactivity/AtomHttpApi";
import * as AtomRpc from "effect/unstable/reactivity/AtomRpc";
import * as Reactivity from "effect/unstable/reactivity/Reactivity";
@ -1490,14 +1494,15 @@ function updateConversation(get: Atom.FnContext, f: (current: ConversationState)
}
function updateLastMessage(get: Atom.FnContext, updater: (prev: ChatMessage) => ChatMessage): void {
updateConversation(get, (current) => {
if (current.messages.length === 0) return current;
const last = current.messages[current.messages.length - 1]!;
return {
...current,
messages: [...current.messages.slice(0, -1), updater(last)],
};
});
updateConversation(get, (current) =>
A.matchRight(current.messages, {
onEmpty: () => current,
onNonEmpty: (init, last) => ({
...current,
messages: [...init, updater(last)],
}),
}),
);
}
function refreshConfigAtoms(get: Atom.FnContext): void {