Archived
装配(app 是唯一组装层): - wiring/engines.ts:skill/flow/loop/task/process/trigger 六个模块经端口接起来; 两个范式引擎按统一 ParadigmEngine 契约暴露给 task —— 对上层不可区分 - agent-runner.ts:loop 的 Agent 回路经 ModelGateway(两缝之一,回放审看得见); 出参过 schema 框住三型行动,不合规退化为「等人」而不是乱动世界 - container:interaction / human-tool / activity-registry / release 全部接上; event 的 TriggerMatcher 与 org 的 InFlightWorkProbe 以延迟绑定解环,端口不变 - workers/consumers.ts:派发器的两个消费者(任务监听推进旧单 / 触发器开新单,独立判定) - tools/first-party.ts:查历史价(录制回放替身)+ 三分类打标(纯工具,DMN 确定性求值) - seed-quote.ts:治理台四件事一次做完 —— 绑 LLM / 注册工具两审 / 经安装通道装活动包 / 发布流程包(闭合校验通过)+ 配触发器与邮件通道 已验证(真机): 1. 治理台配置全过;活动包静态审 0 条提示、流程包闭合校验通过 2. 一封 RFQ 邮件入站 → 归属解析 → 触发器命中 1 → 起一条工作流 → A1 任务按岗位唯一人解析落到 BD 冯兵,runtime=running 修复:zod 判别式重复值(周期触发两型展开为 periodic-calendar / periodic-data, triggerKindOf 对回三类分类学);活动构建脚本移出 activities(它要用 fs, 而活动包零环境能力 —— depcruise 拦下后按边界搬家) 358 个测试通过,门禁五道全绿 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
197 lines
6.7 KiB
JavaScript
197 lines
6.7 KiB
JavaScript
/* eslint-disable */
|
|
/**
|
|
* JCAI 依赖门禁 —— 编码规范 §11.4。
|
|
*
|
|
* 结构:基线八条(no-circular / no-cross-module-internal / app-not-into-internal /
|
|
* domain-is-pure / usecase-not-to-adapter / web-not-to-api / packages-are-leaves /
|
|
* no-orphans)+ JCAI 增补四条(framework-only-in-adapter / tier-order /
|
|
* activities-isolated / apps-not-into-activities)。
|
|
*
|
|
* tier-order 的逐层展开由 tools/gen-depcruise-tiers.ts 从 tools/module-tiers.json 生成。
|
|
* **约束报错时,改代码,不改约束(§11)。**
|
|
*/
|
|
const tierRules = require('./tools/depcruise-tiers.generated.cjs');
|
|
|
|
const MODULES = '^apps/api/src/modules';
|
|
|
|
/** domain 层的 npm 白名单(§5.3):zod / decimal.js / date-fns + 仓内纯包 */
|
|
const DOMAIN_NPM_ALLOWLIST = 'node_modules/(zod|decimal\\.js|date-fns)(/|$)';
|
|
|
|
module.exports = {
|
|
forbidden: [
|
|
// ── 基线八条 ────────────────────────────────────────────────────────────
|
|
{
|
|
name: 'no-circular',
|
|
comment: '依赖方向单向无环(§0.1 第 3 条)',
|
|
severity: 'error',
|
|
from: {},
|
|
to: { circular: true },
|
|
},
|
|
{
|
|
name: 'no-cross-module-internal',
|
|
comment: '任何文件不得 import modules/*/internal/**(同模块自己除外,§5.2)',
|
|
severity: 'error',
|
|
from: { pathNot: `${MODULES}/([^/]+)/` },
|
|
to: { path: `${MODULES}/([^/]+)/internal/` },
|
|
},
|
|
{
|
|
name: 'no-cross-module-internal-peer',
|
|
comment: '模块之间只准 import 到对方的 index.ts,不得穿透 internal(§5.2)',
|
|
severity: 'error',
|
|
from: { path: `${MODULES}/([^/]+)/` },
|
|
to: {
|
|
path: `${MODULES}/([^/]+)/internal/`,
|
|
pathNot: `${MODULES}/$1/internal/`,
|
|
},
|
|
},
|
|
{
|
|
name: 'app-not-into-internal',
|
|
comment: 'app/ 是组装层,只经模块出口认识模块(§5.2)',
|
|
severity: 'error',
|
|
from: { path: '^apps/(api|web)/src/app/' },
|
|
to: { path: `${MODULES}/([^/]+)/internal/` },
|
|
},
|
|
{
|
|
name: 'domain-is-pure',
|
|
comment:
|
|
'domain/ 零 IO、零框架:npm 只准 zod / decimal.js / date-fns,仓内只准 @contracts / @sfeel / @utils(§5.3)',
|
|
severity: 'error',
|
|
from: { path: `${MODULES}/([^/]+)/internal/domain/` },
|
|
to: {
|
|
path: 'node_modules',
|
|
pathNot: DOMAIN_NPM_ALLOWLIST,
|
|
},
|
|
},
|
|
{
|
|
name: 'domain-is-pure-core',
|
|
comment: 'domain/ 不得触 Node 核心能力(fs / http / crypto / child_process …,§5.3)',
|
|
severity: 'error',
|
|
from: { path: `${MODULES}/([^/]+)/internal/domain/` },
|
|
to: { dependencyTypes: ['core'] },
|
|
},
|
|
{
|
|
name: 'usecase-not-to-adapter',
|
|
comment: 'usecase/ 依赖 port.ts 声明的能力,不 import 任何 adapter(§5.3)',
|
|
severity: 'error',
|
|
from: { path: `${MODULES}/([^/]+)/internal/usecase/` },
|
|
to: { path: `${MODULES}/([^/]+)/internal/adapter/` },
|
|
},
|
|
{
|
|
name: 'web-not-to-api',
|
|
comment: '前后端互不 import,跨端唯一通道是 @contracts(§5.1)',
|
|
severity: 'error',
|
|
from: { path: '^apps/web/' },
|
|
to: { path: '^apps/api/' },
|
|
},
|
|
{
|
|
name: 'api-not-to-web',
|
|
comment: '前后端互不 import(§5.1)',
|
|
severity: 'error',
|
|
from: { path: '^apps/api/' },
|
|
to: { path: '^apps/web/' },
|
|
},
|
|
{
|
|
name: 'packages-are-leaves',
|
|
comment: 'packages/* 不得反向 import apps/*(§5.1)',
|
|
severity: 'error',
|
|
from: { path: '^packages/' },
|
|
to: { path: '^apps/' },
|
|
},
|
|
{
|
|
name: 'utils-is-leaf',
|
|
comment: 'packages/utils 是叶子,不依赖任何仓内包(§5.1)',
|
|
severity: 'error',
|
|
from: { path: '^packages/utils/' },
|
|
to: { path: '^(apps|activities|packages/(?!utils))' },
|
|
},
|
|
{
|
|
name: 'no-orphans',
|
|
comment:
|
|
'无孤儿模块;契约面(index/contract/port)、入口与配置是合法的无入边文件,不计孤儿',
|
|
severity: 'error',
|
|
from: {
|
|
orphan: true,
|
|
pathNot: [
|
|
'(^|/)(index|contract|port)\\.ts$',
|
|
'^apps/(api|web)/src/app/',
|
|
'^activities/',
|
|
'^tools/',
|
|
'\\.d\\.ts$',
|
|
'\\.(config|setup)\\.(js|cjs|mjs|ts)$',
|
|
'(^|/)__tests__/',
|
|
'\\.test\\.ts$',
|
|
],
|
|
},
|
|
to: {},
|
|
},
|
|
|
|
// ── JCAI 增补 ──────────────────────────────────────────────────────────
|
|
{
|
|
name: 'framework-only-in-adapter',
|
|
comment: 'Mastra / AI SDK / Drizzle / pg / pg-boss / Hono 只准在 adapter 与 app(§6.2)',
|
|
severity: 'error',
|
|
from: { path: `${MODULES}/([^/]+)/internal/(domain|usecase)/` },
|
|
to: {
|
|
path: 'node_modules/(@mastra|ai|@ai-sdk|drizzle-orm|drizzle-kit|pg|pg-boss|hono|@hono)(/|$)',
|
|
},
|
|
},
|
|
{
|
|
name: 'contracts-is-pure',
|
|
comment: '@contracts 只有 zod schema / 常量 / 类型,零实现、零框架(§8.1)',
|
|
severity: 'error',
|
|
from: { path: '^packages/contracts/' },
|
|
to: {
|
|
path: 'node_modules',
|
|
pathNot: 'node_modules/zod(/|$)',
|
|
},
|
|
},
|
|
{
|
|
name: 'sfeel-is-pure',
|
|
comment: '@sfeel 是纯函数包,零 IO 零框架(§8.3)',
|
|
severity: 'error',
|
|
from: { path: '^packages/sfeel/' },
|
|
to: { dependencyTypes: ['core'] },
|
|
},
|
|
{
|
|
name: 'activities-isolated',
|
|
comment: 'activities/* 只准 import @sdk / @contracts 与白名单纯库,不得 import apps/**(ADR-004)',
|
|
severity: 'error',
|
|
from: { path: '^activities/' },
|
|
to: { path: '^apps/' },
|
|
},
|
|
{
|
|
name: 'apps-not-into-activities',
|
|
comment: '活动经安装装载,api 侧任何文件不得静态 import activities/**(§2.1 / ADR-004)',
|
|
severity: 'error',
|
|
from: { path: '^apps/' },
|
|
to: { path: '^activities/' },
|
|
},
|
|
{
|
|
name: 'activity-no-environment-capability',
|
|
comment: '活动包零环境能力:不得触 node 核心模块(AM 12.1 无越权代码)',
|
|
severity: 'error',
|
|
from: { path: '^activities/' },
|
|
to: { dependencyTypes: ['core'] },
|
|
},
|
|
...tierRules,
|
|
],
|
|
|
|
options: {
|
|
doNotFollow: { path: 'node_modules' },
|
|
exclude: {
|
|
path: ['(^|/)dist/', '(^|/)\\.build/', '(^|/)node_modules/', '(^|/)api-report/', '\\.d\\.ts$'],
|
|
},
|
|
tsPreCompilationDeps: true,
|
|
tsConfig: { fileName: 'tsconfig.base.json' },
|
|
enhancedResolveOptions: {
|
|
exportsFields: ['exports'],
|
|
conditionNames: ['import', 'require', 'node', 'default', 'types'],
|
|
extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
|
|
mainFields: ['module', 'main', 'types'],
|
|
},
|
|
reporterOptions: {
|
|
text: { highlightFocused: true },
|
|
},
|
|
},
|
|
};
|