Add chat domain lint boundaries

This commit is contained in:
murashit 2026-06-14 19:31:57 +09:00
parent 0becb8f39a
commit 90db7b80c1
2 changed files with 38 additions and 0 deletions

View file

@ -28,6 +28,14 @@ const chatSignalAdapterRestrictions = [
message: "Keep chat signals in panel/shell-state.tsx as a reducer-to-Preact notification adapter.",
},
];
const chatDomainLayerRestrictions = [
{
selector:
"ImportDeclaration[source.value=/^(?:\\.\\.\\/)+(?:app-server|application|host|panel|presentation|ui)(?:\\/|$)|^src\\/features\\/chat\\/(?:app-server|application|host|panel|presentation|ui)(?:\\/|$)/]",
message:
"Keep chat/domain as Panel-owned meaning models and pure derivations; app-server, application, host, panel, presentation, and UI layers may depend on domain, not the reverse.",
},
];
const uiRootImportRestrictions = [
{
selector: "ImportDeclaration[source.value=/shared\\/ui\\/ui-root$/]",
@ -684,6 +692,10 @@ export default defineConfig([
"codex-panel/no-chat-state-direct-mutation": "error",
},
},
{
files: ["src/features/chat/domain/**/*.{ts,tsx}"],
rules: restrictedSyntaxRule([...sourceSyntaxRestrictions, ...chatDomainLayerRestrictions]),
},
{
files: ["src/app-server/**/*.{ts,tsx}", "src/domain/**/*.{ts,tsx}", "src/shared/**/*.{ts,tsx}"],
rules: {

View file

@ -362,6 +362,32 @@ export function timestamp(): number {
expect(messages).toContain("no-restricted-syntax");
});
it("keeps chat domain independent from outer chat layers", async () => {
const messages = await lintSource(
"src/features/chat/domain/message-stream/selectors.ts",
`
import type { ChatStateStore } from "../../application/state/reducer";
export type Store = ChatStateStore;
`,
);
expect(messages).toContain("no-restricted-syntax");
});
it("allows chat domain modules to depend on sibling domain modules", async () => {
const messages = await lintSource(
"src/features/chat/domain/message-stream/selectors.ts",
`
import type { MessageStreamItem } from "./items";
export type Item = MessageStreamItem;
`,
);
expect(messages).not.toContain("no-restricted-syntax");
});
});
async function lintSource(filePath: string, source: string): Promise<string[]> {