@feng0531/dsh-code-review 0.33.4 → 0.33.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -1
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/business-groups.mjs +11 -0
- package/src/coverage-plan.mjs +6 -2
- package/src/review.mjs +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
# 变更记录
|
|
2
2
|
|
|
3
|
+
## 0.33.5
|
|
4
|
+
|
|
5
|
+
- 少于4个可审查文件免模型分组:精确增删行数<200本地合组,否则逐文件;未知精度不合组。仅调度导航,不证明语义依赖,不免主审或风险/证据校验。
|
|
6
|
+
- 预览同算法计入本地综合输入及调用预算,综合超限仍明确blocked;331离线测试通过,候选待发布门禁。
|
|
7
|
+
|
|
3
8
|
## 0.33.4
|
|
4
9
|
|
|
5
10
|
- 文件失败保留明确MODEL_INVALID_JSON/MODEL_TIMEOUT错误码;取消为CANCELLED,其余未知错误为REVIEW_EXECUTION_FAILED,不猜测根因、不重试。
|
|
6
|
-
- 报告selection保留total/reviewable/excluded/blocked分母;零选择、全排除或全阻塞返回partial及未执行限制,不冒充完整通过。327
|
|
11
|
+
- 报告selection保留total/reviewable/excluded/blocked分母;零选择、全排除或全阻塞返回partial及未执行限制,不冒充完整通过。327冻结离线测试及标签四矩阵通过,唯一发布37910021333原工件89493字节与npm/Release逐字节及双hash一致。
|
|
7
12
|
|
|
8
13
|
## 0.33.3
|
|
9
14
|
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## 当前状态
|
|
6
6
|
|
|
7
|
-
当前正式版本为 0.33.
|
|
7
|
+
当前正式版本为 0.33.4(固定标签四矩阵及npm/Release原工件字节双hash门禁通过)。JSON围栏兼容与有界窗口上下文已交付;实际项目审查效果仍需原报告和新预览执行验证。
|
|
8
8
|
|
|
9
9
|
Git历史预览新增oldContextPaths:最多20个显式仓库相对文件,与contextPaths/自动上下文共享20槽、256KiB每blob及4MiB快照。仅从baseline普通Git blob捕获,不checkout/fetch/读取工作树;根提交无baseline拒绝,working/SVN明确拒绝。旧侧条目携带oldRevision/oldBlobOid/oldHash,仅进入context-old;oldOnly表示仅批准旧侧,不证明target路径不存在。所选变更复用原changed-old,不重复上下文;excluded/blocked变更、链接/submodule、凭据路径不能重新进入。预览显示身份元数据、不显示正文,确认执行才按宿主正常权限发送。主审/综合/复核按侧提示,计入原输入预算,旧证据不能冒充新侧回归证明。
|
|
10
10
|
|
package/package.json
CHANGED
package/src/business-groups.mjs
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
import {changeMap} from './change-map.mjs';
|
|
2
|
+
// Local partitions carry no semantic dependency claim. Unknown precision never bundles.
|
|
3
|
+
export function localBusinessGroups(files) {
|
|
4
|
+
const selected=files.filter(f=>f.eligibility==='reviewable');
|
|
5
|
+
if(selected.length<2||selected.length>=4||selected.some(f=>typeof f.left?.text!=='string'||typeof f.right?.text!=='string'))return null;
|
|
6
|
+
const changes=selected.map(f=>changeMap(f.left.text,f.right.text));
|
|
7
|
+
const exact=changes.every(c=>c.status==='unchanged'||c.precision==='exact');
|
|
8
|
+
const churn=exact?changes.reduce((sum,c)=>sum+c.edits.reduce((n,e)=>n+e.old.count+e.new.count,0),0):null;
|
|
9
|
+
const bundle=churn!==null&&churn<200;
|
|
10
|
+
return {status:'skipped',strategy:bundle?'local-bundle':'local-per-file',churn,groups:(bundle?[selected]:selected.map(f=>[f])).map((members,i)=>({id:'local'+(i+1),fileIds:members.map(f=>f.id),reason:'small change set; no semantic partition',confidence:'local-navigation'})),links:[]};
|
|
11
|
+
}
|
|
1
12
|
export const BUSINESS_GROUP_INSTRUCTIONS = '按共同业务契约对给定变更文件元数据分组,仅为审查调度假设,路径不证明依赖。返回{groups:[{fileIds:[已有id],reason:非空说明}]}。每组1至4文件,每个文件恰好一次,无关联可单文件,不新增路径或读文件。';
|
|
2
13
|
export function prepareBusinessGroups(files) {
|
|
3
14
|
const selected=files.filter(f=>f.eligibility==='reviewable');
|
package/src/coverage-plan.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {localBusinessGroups} from './business-groups.mjs';
|
|
1
2
|
import { prepareInteractionInput } from './interaction-input.mjs';
|
|
2
3
|
import { initialInputBudget } from './input-budget.mjs';
|
|
3
4
|
import { preparePrimaryInput } from './primary-input.mjs';
|
|
@@ -18,7 +19,10 @@ export function buildCoveragePlan(input, options) {
|
|
|
18
19
|
const prepared = preparePrimaryInput(input, file, options);
|
|
19
20
|
return { ...item, ...prepared.metadata, status: prepared.budget.fits ? 'ready' : 'input-blocked', minimumCalls: prepared.budget.fits ? ((prepared.batches?.length ?? 1) * (options.enableRiskPlanning === true ? 2 : 1) + (prepared.synthesis?.budget.fits ? 1 : 0)) : 0 };
|
|
20
21
|
});
|
|
21
|
-
const
|
|
22
|
-
const
|
|
22
|
+
const local = options.enableBusinessGrouping === true ? localBusinessGroups(input.files) : null;
|
|
23
|
+
const groups = [...(options.grouping?.groups ?? [])];
|
|
24
|
+
for(const group of local?.groups ?? [])if(!groups.some(g=>[...g.fileIds].sort().join(',')===[...group.fileIds].sort().join(',')))groups.push(group);
|
|
25
|
+
const interactions = options.scope && groups.length ? groups.filter(g => g.fileIds.length > 1).map(group => { const prepared = prepareInteractionInput(input, group, payload => initialInputBudget({ instructions: options.instructions, input: payload }, options.scope, options.maxInputBytes)); return { groupId: group.id, fileIds: prepared.fileIds, status: prepared.status, reason: prepared.reason, minimumCalls: prepared.status === 'ready' ? (options.enableRiskPlanning === true ? 2 : 1) : 0 }; }) : [];
|
|
26
|
+
const businessGrouping = options.enableBusinessGrouping === true && input.files.filter(f => f.eligibility === 'reviewable').length > 1 ? local ? {minimumCalls:0,strategy:local.strategy,churn:local.churn,notice:'本地调度无语义依赖证明。'} : { minimumCalls: 1, dynamicInteractionCalls: 'unknown-until-execution', maximumAdditionalInitialCalls: Math.floor(input.files.filter(f => f.eligibility === 'reviewable').length / 2) * (options.enableRiskPlanning === true ? 2 : 1), notice: '模型分组假设仅调度,额外综合动态且不保证预算或覆盖。' } : null;
|
|
23
27
|
return { ...(businessGrouping ? { businessGrouping } : {}), interactions, snapshotId: input.id, maxInputBytes: options.maxInputBytes, items, minimumCalls: (businessGrouping?.minimumCalls ?? 0) + items.reduce((sum,item) => sum + item.minimumCalls, 0) + interactions.reduce((sum,item) => sum + item.minimumCalls, 0), initialRequestsOnly: true };
|
|
24
28
|
}
|
package/src/review.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { correctAnchor } from './anchor-correction.mjs';
|
|
2
2
|
import { validateBusinessRequirement } from './business-requirement.mjs';
|
|
3
3
|
import { riskReadCoverage } from './risk-read-coverage.mjs';
|
|
4
|
-
import { BUSINESS_GROUP_INSTRUCTIONS, prepareBusinessGroups, validateBusinessGroups } from './business-groups.mjs';
|
|
4
|
+
import { BUSINESS_GROUP_INSTRUCTIONS, localBusinessGroups, prepareBusinessGroups, validateBusinessGroups } from './business-groups.mjs';
|
|
5
5
|
import { RISK_PLAN_INSTRUCTIONS, validateRiskPlan } from './risk-plan.mjs';
|
|
6
6
|
import { prepareInteractionInput } from './interaction-input.mjs';
|
|
7
7
|
import { validateInteractionFindings } from './interaction-findings.mjs';
|
|
@@ -141,12 +141,16 @@ export async function reviewSnapshot(snapshot, model, options = {}) {
|
|
|
141
141
|
if (options.enableBusinessGrouping === true && !report.businessGrouping && prepareBusinessGroups(input.files)) {
|
|
142
142
|
report.businessGrouping = { status: 'pending' };
|
|
143
143
|
try {
|
|
144
|
+
const local = localBusinessGroups(input.files);
|
|
145
|
+
let grouped = local;
|
|
146
|
+
if (!local) {
|
|
144
147
|
const groupInput = prepareBusinessGroups(input.files);
|
|
145
148
|
if (Buffer.byteLength(groupInput) + Buffer.byteLength(BUSINESS_GROUP_INSTRUCTIONS) > maxInputBytes) throw new Error('Business grouping input budget exceeded');
|
|
146
149
|
beforeCall();
|
|
147
150
|
const response = await model({ ...enclosingRequest, instructions: BUSINESS_GROUP_INSTRUCTIONS, input: groupInput });
|
|
148
151
|
enclosingRequest.signal.throwIfAborted();
|
|
149
|
-
|
|
152
|
+
grouped = validateBusinessGroups(response, input.files);
|
|
153
|
+
}
|
|
150
154
|
report.businessGrouping = { status: 'completed', ...grouped };
|
|
151
155
|
for (const group of grouped.groups.filter(g => g.fileIds.length > 1)) {
|
|
152
156
|
if (interactionPlans.some(p => [...p.group.fileIds].sort().join(',') === [...group.fileIds].sort().join(','))) continue;
|