@longzai-intelligence-issues/ledger 0.0.3 → 0.0.4

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.
@@ -1,7 +1,7 @@
1
1
  $ oxlint && oxfmt --check
2
2
  Found 0 warnings and 0 errors.
3
- Finished in 224ms on 39 files with 186 rules using 10 threads.
3
+ Finished in 417ms on 42 files with 186 rules using 10 threads.
4
4
  Checking formatting...
5
5
 
6
6
  All matched files use the correct format.
7
- Finished in 153ms on 48 files using 10 threads.
7
+ Finished in 229ms on 51 files using 10 threads.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,12 @@
5
5
  格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),
6
6
  本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
7
7
 
8
+ ## [0.0.4] - 2026-09-14
9
+
10
+ ### 变更
11
+
12
+ - migrate-legacy 渲染层字段块连续化(去除规范组/额外组间空行)——修复 0.0.3 分组空行致解析层 bodyStart 误判的幂等循环(docs/issues/0013-npm-003-render-grouping-blank-breaks-idempotency.md)
13
+
8
14
  ## [0.0.3] - 2026-09-14
9
15
 
10
16
  ### 新增
package/dist/index.js CHANGED
@@ -66,7 +66,7 @@ import"./rolldown-runtime-BqT_7tdF.js";import{renderBaselineRegeneratedConfig as
66
66
  `)}}function L(e,t){let n=Qe(e);return m(`sha256`).update(`${n}\nidentity:${t.command}`).digest(`hex`)}function R(e,t,n){return u(e,`.lzi`,`issues`,`vault`,`certificates`,t,`${n}.json`)}function $e(e,n,i){let a=R(e,n,i);if(!t(a))return null;try{let e=JSON.parse(r(a,`utf8`));return et(e)?e:null}catch{return null}}function et(e){if(typeof e!=`object`||!e)return!1;let t=Reflect.get(e,`fingerprint`),n=Reflect.get(e,`exitCode`);return typeof t==`string`&&typeof n==`number`}function tt(e){let t=e.split(/\r?\n/).filter(e=>e!==``);return t.length<=16?t:[...t.slice(0,8),`……(共 ${t.length} 行)`,...t.slice(-8)]}function nt(e){let t=e.fingerprint??L(e.root,e.criterion),n=$e(e.root,e.criterion.channel,t);if(n!==null&&n.exitCode===0)return{green:!0,reused:!0,certificate:n};let r=new Date().toISOString();try{let n=p(`/bin/sh`,[`-c`,e.criterion.command],{cwd:u(e.root,e.criterion.cwd),maxBuffer:16777216}).toString(`utf8`),i={fingerprint:t,channel:e.criterion.channel,command:e.criterion.command,cwd:e.criterion.cwd,exitCode:0,outputSummary:tt(n),executedAt:r};return rt(e.root,i),{green:!0,reused:!1,certificate:i}}catch(n){let i=typeof n==`object`&&n?n:{},a=Reflect.get(i,`status`),o=Reflect.get(i,`stdout`),s=Reflect.get(i,`stderr`),c={fingerprint:t,channel:e.criterion.channel,command:e.criterion.command,cwd:e.criterion.cwd,exitCode:typeof a==`number`?a:127,outputSummary:tt(`${typeof o==`string`?o:``}\n${typeof s==`string`?s:``}`.trim()),executedAt:r};return rt(e.root,c),{green:!1,reused:!1,certificate:c}}}function rt(e,t){let r=R(e,t.channel,t.fingerprint);n(l(r),{recursive:!0});let i=`${r}.tmp`;c(i,`${JSON.stringify(t,null,2)}\n`),a(i,r)}function it(e){let i=u(e,`.lzi`,`issues`,`vault`,`run.lock`);if(n(l(i),{recursive:!0}),t(i))throw Error(`已有并行真跑持锁(${i})——完成后自动释放;如为残留死锁请人工确认后删除`);return c(i,`${process.pid}\n`),{unlock:()=>{try{r(i,`utf8`).trim()===String(process.pid)&&o(i,{force:!0})}catch{return}}}}function at(e,t,n){if(n.length===0)return[];let r=F(u(e,t));return n.filter(e=>{let t=r.find(t=>t.id===e);return t===void 0||t.status!==`green`&&t.status!==`legacy-green`})}function ot(e){let t=[];for(let n of e.files)t.push(st(e.root,e.config,n,e.summaryOverride,e.dryRun===!0));return{cases:t,succeeded:t.filter(e=>e.ok).length,gateBlocked:!1,gateMessage:``}}function st(e,t,n,i,a){let o=u(e,n),s=``;try{s=r(o,`utf8`)}catch{return{file:n,ok:!1,message:`读档失败(文件不存在或不可读)`,idempotent:!1}}let l=P(n.split(`/`).pop()??``,s,0);if(l===null)return{file:n,ok:!1,message:`文件名不符合注册表口径`,idempotent:!1};if(l.status===`frozen`)return{file:n,ok:!1,message:`冻结案拒收(不翻绿、不回填证据——须先经 unfreeze 裁定)`,idempotent:!1};let d=_e(l.statusLine,t.close.pendingWords);if(d!==null)return{file:n,ok:!1,message:`状态行含挂起词「${d}」——诚实黄灯维持,不得收口`,idempotent:!1};if(t.close.blockingMustBeGreen){let t=at(e,n.split(`/`).slice(0,-1).join(`/`),l.blockedByRefs.map(e=>e.number));if(t.length>0)return{file:n,ok:!1,message:`「阻塞」引用未全 🟢:${t.join(`、`)}——阻塞收口门禁拒收`,idempotent:!1}}let f=ge(s);if(f.anchors.length===0)return{file:n,ok:!1,message:`处置段围栏外零绿证据锚点——不核验即翻绿红线维持(补证据或走 --rerun 真跑)`,idempotent:!1};let p=i??l.criteria?.summary??`末次通过证据收口(${l.id}):${f.anchors.length} 条绿证据锚点`,m=Xe(f.anchors.map(e=>e.line),`末次通过即收口`),h;try{h=I({raw:s,summary:p,evidenceBlock:m})}catch(e){return{file:n,ok:!1,message:e instanceof Error?e.message:String(e),idempotent:!1}}return!a&&!h.idempotent&&c(o,h.content),{file:n,ok:!0,message:h.idempotent?`已 🟢 且概要一致——幂等零变更`:`翻绿完成(${f.anchors.length} 条锚点,零执行)`,idempotent:h.idempotent}}function ct(e,t,n,r){if(!n&&e.close.fullPattern!==void 0){let n=t.filter(t=>new RegExp(e.close.fullPattern??``).test(t.command));if(n.length>0)return{blocked:!0,kind:`full`,message:`禁用级门禁:判据须 scope 定向,禁止全量(命中 ${n.length} 条:${n.map(e=>e.label).join(`、`)})——确需全量须 --allow-full-criterion 且留痕`}}if(!r&&e.close.heavyPattern!==void 0){let n=t.filter(t=>new RegExp(e.close.heavyPattern??``).test(t.command));if(n.length>0)return{blocked:!0,kind:`heavy`,message:`确认级门禁:判据含重度命令(命中 ${n.length} 条:${n.map(e=>e.label).join(`、`)})——预览未执行,确认执行须 --confirm-heavy(仅人类明令环节)`}}return{blocked:!1,kind:`none`,message:``}}function lt(e){let t=[];for(let n of e.files){let i=``;try{i=r(u(e.root,n),`utf8`)}catch{continue}let a=P(n.split(`/`).pop()??``,i,0);if(a===null||a.status===`frozen`)continue;let o=[];e.criteriaFromIssue===!0&&a.criteria!==null&&o.push(...a.criteria.criteria);for(let t of e.explicitCriteria??[]){let e=t.split(`|`);e.length===4&&o.push({label:e[0]?.trim()??``,channel:e[1]?.trim()??``,cwd:e[2]?.trim()??``,command:e[3]?.trim()??``})}o.length!==0&&t.push({file:n,raw:i,criteria:o})}let n=t.flatMap(e=>e.criteria),i=ct(e.config,n,e.allowFullCriterion===!0,e.confirmHeavy===!0);if(i.blocked)return{cases:t.map(e=>({file:e.file,ok:!1,message:`门禁拦截(${i.kind}),零执行`,idempotent:!1})),succeeded:0,gateBlocked:!0,gateMessage:i.message};if(e.dryRun===!0)return{cases:t.map(e=>({file:e.file,ok:!0,message:`干跑预览(${e.criteria.length} 条判据,未执行)`,idempotent:!1})),succeeded:t.length,gateBlocked:!1,gateMessage:``};let a=it(e.root),o=[];try{for(let n of t){let t=n.criteria.map(t=>{let n=L(e.root,t);return{criterion:t,fingerprint:n,run:nt({root:e.root,criterion:t,fingerprint:n})}}),r=t.filter(e=>!e.run.green);if(r.length>0){o.push({file:n.file,ok:!1,message:`判据未全绿(${r.map(e=>`${e.criterion.label} 退出码 ${e.run.certificate.exitCode}`).join(`、`)})——跳过翻绿`,idempotent:!1});continue}let i=P(n.file.split(`/`).pop()??``,n.raw,0),a=e.summaryOverride??i?.criteria?.summary??`批量证书化收口(${i?.id??``}):${t.length} 条判据全绿`,s=t.map(e=>`${e.criterion.label}:证书指纹 ${e.run.certificate.fingerprint}(${e.run.reused?`复用`:`真实执行`},退出码 ${e.run.certificate.exitCode})`),l=I({raw:n.raw,summary:a,evidenceBlock:Ze(a,s,`issues:verify-close`)});l.idempotent||c(u(e.root,n.file),l.content),o.push({file:n.file,ok:!0,message:`证书化收口完成(${t.length} 条判据全绿${l.idempotent?`,幂等零变更`:``})`,idempotent:l.idempotent})}}finally{a.unlock()}return{cases:o,succeeded:o.filter(e=>e.ok).length,gateBlocked:!1,gateMessage:``}}const z=`用户裁定`;function ut(e){let t=e.split(/\r?\n/),n=Math.min(t.length,30);for(let e=0;e<n;e+=1)if(v.test(t[e]??``))return{line:t[e]??``,index:e};return null}function dt(e){return e.reason.includes(`用户裁定`)?pt(e.root,e.file,e.reason,`freeze`):{ok:!1,message:`冻结属人类裁定事项:--reason 必须含「${z}」——工具拒绝形式冻结`,idempotent:!1}}function ft(e){return e.note.includes(`用户裁定`)?pt(e.root,e.file,e.note,`unfreeze`):{ok:!1,message:`解冻属人类裁定事项:--note 必须含「${z}」——工具拒绝形式解冻`,idempotent:!1}}function pt(e,t,n,i){let a=``;try{a=r(u(e,t),`utf8`)}catch{return{ok:!1,message:`读档失败(文件不存在或不可读)`,idempotent:!1}}let o=ut(a);if(o===null)return{ok:!1,message:`未定位到状态行——冻结/解冻拒绝写入`,idempotent:!1};if(o.line.includes(`|`))return{ok:!1,message:`状态行为复合元信息行(含 |)——拒绝整行破坏性替换,请先经 normalize-header 迁移`,idempotent:!1};let s=o.line.includes(`已冻结`);if(i===`unfreeze`&&!s)return{ok:!1,message:`非冻结案拒绝解冻(当前状态行:${o.line})`,idempotent:!1};let l=i===`freeze`?`**状态**: ⚪ 已冻结(${n}——不推进、不处置、无验证判据;如需推进须先取得「解冻」的显式裁定)`:`**状态**: 🔴 待处理(${n}——冻结解除,处置方向待重新评估)`;if(o.line===l)return{ok:!0,message:`状态行已为目标形态——幂等零变更`,idempotent:!0};let d=`${RegExp(`^(状态\\*{0,2}\\s*[::])\\s*`).exec(o.line)?.[1]??`**状态**:`} ${l.replace(/^\*\*状态\*\*:\s*/,``)}`,f=a.split(/\r?\n/);return f[o.index]=d,c(u(e,t),f.join(`
67
67
  `)),{ok:!0,message:i===`freeze`?`已冻结(⚪)`:`已解冻恢复 🔴`,idempotent:!1}}const mt=[`真机`,`雪场`,`合作方`,`回执`,`技术支持`,`REAL_DEVICE`,`人工确认`,`环境不具备`],ht=[`在途`,`并行线`,`待并行`,`让锁`,`待落地`,`待补跑`,`待复跑`];function B(e){let t=mt.find(t=>e.rawContent.includes(t));if(t!==void 0)return{category:`B`,reason:`判据依赖环境(命中「${t}」)——诚实保持黄灯,环境具备后再收口`};let n=ht.find(t=>e.rawContent.includes(t));if(n!==void 0)return{category:`C`,reason:`被并行在途线阻断(命中「${n}」)——待在途线落地后复跑收口`};let r=e.criteria?.criteria.length??0;return{category:`A`,reason:r>0?`判据全部机器可跑(${r} 条)——verify-close 补跑收口`:`判据清单为空,需人工核对后补录 criteria 块再收口`}}function gt(e,t,n){return(n===void 0?t.scopes:t.scopes.filter(e=>n.includes(e.registryDir))).flatMap(t=>F(u(e,t.registryDir)).map(e=>({record:e,file:`${t.registryDir}/${e.file}`,registryDir:t.registryDir})))}function _t(e){let t=gt(e.root,e.config,e.dirRels),n={};for(let{record:e}of t)n[e.status]=(n[e.status]??0)+1;let r=t.filter(({record:e})=>e.status===`yellow`||e.status===`legacy-yellow`),i=r.reduce((e,{record:t})=>Math.max(e,t.modifiedAtMs),0),a={};for(let{record:e}of r){let{category:t}=B(e);a[t]=(a[t]??0)+1}return{statusCounts:n,yellowTotal:r.length,oldestYellowAgeDays:i===0?0:Math.max(0,Math.floor((Date.now()-i)/864e5)),categoryCounts:a}}function vt(e){let r=gt(e.root,e.config).filter(({record:e})=>e.status===`yellow`||e.status===`legacy-yellow`).map(({record:e,file:t})=>{let n=B(e);return{id:e.id,file:t,status:e.status,category:n.category,reason:n.reason,criteriaCommands:e.criteria?.criteria.map(e=>e.command)??[]}}),i={generatedAtMs:Date.now(),registryDirs:e.config.scopes.map(e=>e.registryDir),items:r},o=e.outDir??u(e.root,`.lzi`,`issues`,`runs`,`ledger`);n(o,{recursive:!0});let s=u(o,`triage-${i.generatedAtMs}.json`);for(;t(s)||t(`${s}.tmp`);)i.generatedAtMs+=1,s=u(o,`triage-${i.generatedAtMs}.json`);let l=`${s}.tmp`;return c(l,`${JSON.stringify(i,null,2)}\n`),a(l,s),{ledgerPath:s,ledger:i}}const yt=new Map;function bt(e,t){yt.set(e,t)}function xt(e){if(typeof e!=`object`||!e)return null;let t=Reflect.get(e,`items`);if(t===void 0)return[];if(!Array.isArray(t))return null;let n=[];for(let e of t){if(typeof e!=`object`||!e)continue;let t=Reflect.get(e,`issueId`);typeof t==`string`&&t!==``&&n.push(t)}return n}const St=[{name:`status-line-missing`,evaluate:e=>e.status===`unknown`?`头部 30 行内未定位到状态行(状态行是处理情况的第一入口)`:null},{name:`status-line-legacy-format`,evaluate:(e,t)=>t.config.lint.strictLegacy&&(e.status===`legacy-yellow`||e.status===`legacy-green`)?`状态行为旧格式变体(${e.status})——须迁移为规范五态写法`:null},{name:`yellow-no-pending-reason`,evaluate:e=>(e.status===`yellow`||e.status===`legacy-yellow`)&&e.pendingReason===null?`黄灯(处理中)状态行须括注 ≥4 字挂起原因`:null},{name:`green-no-disposition-section`,evaluate:e=>(e.status===`green`||e.status===`legacy-green`)&&!e.hasDispositionSection?`绿灯缺少「处置结果/验证口径」段`:null},{name:`green-disposition-placeholder`,evaluate:e=>(e.status===`green`||e.status===`legacy-green`)&&e.hasDispositionSection&&e.dispositionIsPlaceholder?`处置段仍为占位形态(处置中/待回填)——禁止虚标终态`:null},{name:`green-canonical-no-evidence-block`,evaluate:e=>e.status===`green`&&e.statusLine.includes(`判据证据锚点见处置段`)&&!e.hasEvidenceAnchorBlock?`状态行声称「判据证据锚点见处置段」而证据锚点块缺席(手工翻绿识别——收口须经 verify-close)`:null},{name:`frozen-format`,evaluate:e=>e.status===`frozen`&&!/⚪\s*已冻结/.test(e.statusLine)?`冻结状态行须为「⚪ 已冻结(…)」规范形态`:null},{name:`frozen-no-adjudication-note`,evaluate:e=>e.status===`frozen`&&!e.statusLine.includes(`用户裁定`)?`冻结状态行须含「用户裁定」语(工具拒绝形式冻结)`:null},{name:`issue-slug-non-ascii`,evaluate:e=>g.test(e.slug)?null:`slug 段须为纯 ASCII kebab(小写字母/数字/连字符,禁中文与非 ASCII 字符):${e.file}`},{name:`issue-slug-contains-digit`,evaluate:(e,t)=>{if(!/\d/.test(e.slug)||t.config.scopes.find(e=>e.key===t.scopeKey)?.slugDigitPolicy===`allow`)return null;let n=`${t.registryDir}/${e.file}`;return t.config.slugDigitAllowlist.some(e=>k(e.glob,n))?null:`slug 段含数字(scope 政策 slugDigitPolicy 或白名单 slugDigitAllowlist 登记):${e.file}`}},{name:`duplicate-metadata-key`,evaluate:e=>{let t=[];for(let n of e.rawContent.split(/\r?\n/)){if(n.startsWith(`## `)||t.length>=40)break;t.push(n)}let n=new Map;for(let e of t){let t=/^(?:\*\*|- \*\*|- )(优先级|状态|立案日期|所属域|来源|严重程度)(?:\*\*)?\s*[::]/.exec(e.trim());if(t!==null){let e=t[1]??``;n.set(e,(n.get(e)??0)+1)}}let r=[...n.entries()].filter(([,e])=>e>1).map(([e])=>e);return r.length>0?`头部区元信息键重复:${r.join(`、`)}(方言残留块与规范头部并存——须经 migrate-legacy 收敛)`:null}},{name:`canceled-no-reason`,evaluate:e=>e.status===`canceled`&&e.pendingReason===null?`已取消(⚫)状态行须括注 ≥4 字取消原因`:null},{name:`blocking-ref-unknown`,evaluate:(e,t)=>{let n=e.blockedByRefs.filter(e=>!t.registryBasenames.has(`${e.number}.md`));return n.length>0?`「阻塞」引用的 issue 不存在:${n.map(e=>e.number).join(`、`)}`:null}},{name:`orphan-sidecar`,evaluate:(e,n)=>{let i=u(n.root,`.lzi`,`issues`,`comments`,n.scopeKey,`${e.id}.json`);if(!t(i))return null;try{let e=xt(JSON.parse(r(i,`utf8`)));if(e===null)return`评论边车结构非法(items 非数组)——孤儿判定降级为违规提示`;let t=e.filter(e=>!n.registryBasenames.has(`${e}.md`));return t.length>0?`评论边车存在孤儿引用(issue 不存在):${t.join(`、`)}`:null}catch{return`评论边车 JSON 解析失败(孤儿判定降级为违规提示)`}}}];function Ct(e){let t=[...St];for(let n of e.config.lint.rulePacks){let e=yt.get(n);e!==void 0&&t.push(...e)}let n=e.dirRels===void 0?e.config.scopes:e.config.scopes.filter(t=>e.dirRels?.includes(t.registryDir)),r=[];for(let i of n){let n=F(u(e.root,i.registryDir)),a=new Set(n.map(e=>e.file)),o={root:e.root,scopeKey:i.key,registryDir:i.registryDir,registryBasenames:a,config:e.config};for(let e of n)for(let n of t){let t=n.evaluate(e,o);t!==null&&r.push({file:`${i.registryDir}/${e.file}`,line:e.statusLineNumber,rule:n.name,message:t})}}let i=new Map(e.config.lint.baseline.map(e=>[`${e.file}::${e.rule}`,e]));if(e.ignoreBaseline===!0)return{violations:r.sort(wt),suppressed:0,baselineCount:i.size};let a=[],o=0,s=new Set;for(let e of r){let t=`${e.file}::${e.rule}`;if(i.has(t)){o+=1,s.add(t);continue}a.push(e)}let c=[...i.entries()].filter(([e])=>!s.has(e)).map(([e,t])=>({file:e.split(`::`)[0]??``,line:0,rule:`baseline-stale`,message:`基线条目已无对应现行违规——棘轮只许缩短,须同步删除该条目(收编指针:${t.issue})`}));return{violations:[...a,...c].sort(wt),suppressed:o,baselineCount:i.size}}function wt(e,t){return e.file===t.file?e.rule.localeCompare(t.rule):e.file.localeCompare(t.file)}function Tt(e,n){let r=[];for(let i of n.scopes){let n=u(e,`.lzi`,`issues`,`comments`,i.key);if(!t(n))continue;let a=new Set(F(u(e,i.registryDir)).map(e=>e.id));for(let e of j(n,[``])){let t=e.split(`/`).pop()?.replace(/\.json$/,``)??``;t!==``&&!a.has(t)&&r.push({file:`.lzi/issues/comments/${i.key}/${t}.json`,line:0,rule:`orphan-sidecar`,message:`评论边车为孤儿(注册表无 ${i.registryDir}/${t}-*.md)——请联动清理`})}}return r}function Et(t){if(t.issuePointer.trim()===``)return{ok:!1,error:`再生须携带非空 --issue <指针>(收编盖章)`};let n=Ct({root:t.root,config:t.config,ignoreBaseline:!0}).violations.filter(e=>e.rule!==`baseline-stale`),r=new Set(t.config.lint.baseline.map(e=>`${e.file}::${e.rule}`)),i=n.filter(e=>!r.has(`${e.file}::${e.rule}`));if(i.length>0){let e=i.slice(0,10).map(e=>`${e.file} [${e.rule}]`).join(`
68
68
  `);return{ok:!1,error:`存在 ${i.length} 项基线外新增违规,拒绝再生(先处置新增违规后再收编存量):\n${e}`}}let a=n.map(e=>({file:e.file,rule:e.rule,issue:t.issuePointer}));return{ok:!0,content:e(t.config,`lint`,a),entryCount:a.length}}function Dt(e,t){return e.map(e=>({file:e.file,rule:e.rule,issue:t}))}const V=new Set([`优先级`,`状态`,`立案日期`,`日期`,`所属域`,`来源`,`严重程度`,`严重度`]),Ot={立案日期:10,优先级:20,严重程度:30,状态:40,处置日期:50,所属域:60};function H(e){let t=[],n=[],r=e.length;for(let i=0;i<e.length;i+=1){let a=e[i]??``,o=/^##\s+([^::]{1,10})\s*$/.exec(a);if(o!==null&&V.has(o[1]?.trim()??``)){let n=i+1;for(;n<e.length&&(e[n]??``).trim()===``;)n+=1;let r=(e[n]??``).trim();if(r!==``&&!/^[#>*|`-]/.test(r)&&!/^[^::]{1,8}[::]/.test(r)&&r.length<=40){t.push({key:o[1]?.trim()??``,value:r});let a=n+1;for(;a<e.length&&(e[a]??``).trim()===``;)a+=1;let s=e[a]??``,c=/^##\s+([^::]{1,10})\s*$/.exec(s);i=c!==null&&V.has(c[1]?.trim()??``)?a-1:n;continue}}if(a.startsWith(`## `)||a===``&&t.length>0&&i>4){r=i;break}if(a===``||a.startsWith(`# `))continue;let s=/^##\s+([^::]{1,8})\s*[::]\s*(.+)$/.exec(a);if(s!==null){t.push({key:s[1]?.trim()??``,value:s[2]?.trim()??``});continue}let c=/^(?:\*\*|- \*\*|- )([^*::]{1,8})(?:\*\*)?\s*[::]\s*(.+)$/.exec(a);if(c!==null){t.push({key:c[1]?.trim()??``,value:c[2]?.trim()??``});continue}let l=/^(?:\*\*|- \*\*|- )([^*::]{1,8})(?:\*\*)?\s*[::]\s*$/.exec(a);if(l!==null){let n=[],r=a.length-a.trimStart().length,o=i+1;for(;o<e.length;){let t=e[o]??``;if(t.trim()===``||t.length-t.trimStart().length<=r)break;n.push(t.trim().replace(/^-\s*/,``)),o+=1}if(n.length>0){t.push({key:l[1]?.trim()??``,value:n.join(`;`)}),i=o-1;continue}}if(a.startsWith(`>`)){let e=a.slice(1).split(/[||]/).map(e=>e.trim()),r=[];for(let n of e){let e=/^([^::]{1,8})\s*[::]\s*(.+)$/.exec(n);e===null?r.push(n):t.push({key:(e[1]??``).replace(/^\*+|\*+$/g,``).trim(),value:e[2]?.trim()??``})}r.length===e.length?n.push(a):n.push(...r);continue}let u=/^\|([^|]*)\|([^|]*)\|$/.exec(a.trim());if(u!==null){let r=(u[1]??``).trim(),o=(u[2]??``).trim(),s=/^:?-{2,}:?$/,c=s.test(r)&&s.test(o),l=/^\|([^|]*)\|([^|]*)\|$/.exec((e[i+1]??``).trim()),d=l!==null&&s.test((l[1]??``).trim())&&s.test((l[2]??``).trim());if(c||d&&r!==``)continue;r===``?n.push(a):t.push({key:r,value:o});continue}n.push(a)}return{fields:t,residuals:n,bodyStartIndex:r}}function kt(e,t){return Ot[e]??1e3+t}function At(e,t){let n=e.split(/\r?\n/),r=H(n);if(!r.fields.some(e=>e.key===`状态`)){if(t?.status===void 0)return{content:e,outcome:`skipped`};r.fields.push({key:`状态`,value:E[t.status]})}let i=new Map;r.fields.forEach((e,t)=>{i.has(e.key)||i.set(e.key,t)});let a=[...[...r.fields].sort((e,t)=>{let n=kt(e.key,i.get(e.key)??0),r=kt(t.key,i.get(t.key)??0);return n===r?0:n-r}).map(e=>`**${e.key}**: ${e.value}`),...r.residuals],o=n.findIndex((e,t)=>t>0&&e.startsWith(`# `)),s=[...n.slice(0,o===-1?1:o),``,...a,``,...n.slice(r.bodyStartIndex)].join(`
69
- `);return s===e?{content:e,outcome:`unchanged`}:{content:s,outcome:`rewritten`}}function jt(e,t){return e.fields.filter(e=>!t.includes(`**${e.key}**: ${e.value}`)).map(e=>e.key)}function Mt(e){let t=``;try{t=r(u(e.root,e.file),`utf8`)}catch{return{file:e.file,outcome:`failed`,message:`读档失败(文件不存在或不可读)`}}let n=At(t,{status:e.status});if(n.outcome===`skipped`)return{file:e.file,outcome:`skipped`,message:`无可识别状态行且未给 --status——灯位属语义判断,不猜灯`};if(n.outcome===`unchanged`)return{file:e.file,outcome:`unchanged`,message:`头部已是规范形态`};let i=jt(H(t.split(/\r?\n/)),n.content);return i.length>0?{file:e.file,outcome:`failed`,message:`零丢失守卫失败:字段 ${i.join(`、`)} 未在产物在场——不落盘`}:(c(u(e.root,e.file),n.content),{file:e.file,outcome:`rewritten`,message:`头部已迁移为规范形态`})}function U(e){return e.trim().replace(/^\*\*/,``).replace(/\*\*$/,``).replace(/\*\*(?=[((])/,``).trim()}function Nt(e){for(let t of[`frozen`,`green`,`deferred`,`canceled`,`inProgress`,`red`])for(let n of ae[t])if(e.startsWith(n))return{tier:t,word:n};return null}function Pt(e,t){let n=e.slice(t.length).trim(),r=/^[((]([^))]*)[))]/.exec(n);return r===null?{paren:``,rest:n}:{paren:(r[1]??``).trim(),rest:n.slice((r[0]??``).length).trim()}}function W(e){let t=Nt(e);if(t===null)return null;let{paren:n,rest:r}=Pt(e,t.word),i=[n,r,`原「${t.word}」`].filter(e=>e!==``);switch(t.tier){case`frozen`:return null;case`green`:return{value:`🟢 已处置(${i.join(`;`)})`,tier:t.tier,word:t.word};case`red`:return{value:`🔴 待处理(${i.join(`;`)})`,tier:t.tier,word:t.word};case`deferred`:return{value:`🔴 待处理(${[n===``?`延期`:n,`原「${t.word}」`].join(`;`)})`,tier:t.tier,word:t.word};case`canceled`:return n===``||n.length<4?null:{value:`⚫ 已取消(${i.join(`;`)})`,tier:t.tier,word:t.word};case`inProgress`:return n.length<4?null:{value:`🟡 处理中(${n})`,tier:t.tier,word:t.word}}}function G(e){return{高:`P1`,中:`P2`,低:`P3`,P1:`P1`,P2:`P2`,P3:`P3`}[U(e)]??null}function Ft(e,t){let n=e.replace(/^#\s+/,``).replace(RegExp(`^${t}\\s*(?:[-—―·..::-]+\\s*)?`),``).trim();return{line:`# ${t} - ${n}`,titleCore:n}}function It(e){let{fields:t,transformations:n}=e,r=t.findIndex(e=>e.key===`立案日期`),i=t.findIndex(e=>e.key===`日期`);if(r===-1&&i!==-1){let e=t[i];e!==void 0&&(t[i]={key:`立案日期`,value:e.value},n.push({kind:`field-alias`,detail:`日期 → 立案日期(${e.value})`}))}if(!t.some(e=>e.key===`立案日期`)){if(e.defaultFilingDate===void 0)return{skipMessage:`缺立案日期且未给回填缺省——交人工`};t.push({key:`立案日期`,value:e.defaultFilingDate}),n.push({kind:`required-backfilled`,detail:`立案日期 ← ${e.defaultFilingDate}`})}let a=t.findIndex(e=>e.key===`优先级`);if(a!==-1){let e=t[a]?.value??``,r=G(e);r!==null&&r!==e&&(t[a]={key:`优先级`,value:r},n.push({kind:`priority-mapped`,detail:`优先级 ${e} → ${r}`}))}else{let r=t.find(e=>e.key===`严重程度`),i=(r===void 0?null:G(r.value))??e.defaultPriority??null;if(i===null)return{skipMessage:`缺优先级且未给回填缺省——交人工`};t.push({key:`优先级`,value:i}),n.push({kind:r===void 0?`priority-backfilled`:`priority-mapped`,detail:`优先级 ← ${i}${r===void 0?`(缺省回填)`:`(严重程度 ${r.value})`}`})}return{skipMessage:null}}const Lt=new Set([`状态`,`优先级`,`立案日期`,`日期`,`来源`,`严重程度`,`严重度`,`所属域`,`处置日期`,`沿革`,`阻塞`]);function Rt(e,t){let n=[],r=0,i=!1,a=!1,o=0,s=[];for(;o<e.length;){let t=e[o]??``;if(t.trim()===``){n.push(t),o+=1;continue}let c=/^(?:\*\*|- \*\*|- )([^*::]{1,20})(?:\*\*)?\s*[::]\s*(.+)$/.exec(t),l=/^(?:\*\*|- \*\*|- )([^*::]{1,20})(?:\*\*)?\s*[::]\s*$/.exec(t);if(c===null&&l===null)break;let u=((c??l)?.[1]??``).trim();if(u===``)break;if(n.push(t),r+=1,Lt.has(u)&&(i=!0),c!==null){s.push({key:u,value:U(c[2]??``)}),o+=1;continue}let d=[],f=t.length-t.trimStart().length;for(o+=1;o<e.length;){let t=e[o]??``;if(t.trim()===``||t.length-t.trimStart().length<=f)break;n.push(t),d.push(t.trim().replace(/^-\s*/,``)),o+=1}d.length===0?s.push({key:u,value:``}):(s.push({key:u,value:d.join(`;`)}),a=!0)}if(r===0||!i&&r<2&&!a)return{consumedLines:0,restLines:e};for(t.push(...s);n.length>0&&(n[n.length-1]??``).trim()===``;)n.pop(),--o;return{consumedLines:r,restLines:e.slice(o)}}function zt(e,t){let n,r=!1,i=e.filter(e=>e.key===`状态`);if(i.length>1){let r=i[0]?.value.includes(`存量清偿定档:原案无状态行`)===!0,a=i.slice(1).find(e=>!e.value.includes(`存量清偿定档:原案无状态行`));if(r&&a!==void 0){let r=W(a.value);if(r!==null){let i=e.find(e=>e.key===`状态`);i!==void 0&&(i.value=r.value),n=r.value,t.push({kind:`duplicate-field-converged`,detail:`状态 键去重:注入定档让位原始语义 → ${r.value}`})}}}let a=e.filter(e=>e.key===`来源`);if(a.length>1){let n=a[0]?.value.includes(`格式清偿迁移回填`)===!0,i=a.slice(1).find(e=>!e.value.includes(`格式清偿迁移回填`));if(n&&i!==void 0){let n=e.find(e=>e.key===`来源`);n!==void 0&&(n.value=i.value),r=!0,t.push({kind:`duplicate-field-converged`,detail:`来源 键去重:回填缺省让位原始语义 → ${i.value.slice(0,60)}`})}}let o=new Map;for(let n=0;n<e.length;n+=1){let r=e[n];if(r===void 0)continue;let i=o.get(r.key);if(i===void 0){o.set(r.key,n);continue}let a=e[i];r.value!==``&&a!==void 0&&!a.value.includes(r.value)&&(a.value=a.value===``?r.value:`${a.value};${r.value}`),t.push({kind:`duplicate-field-converged`,detail:`${r.key} 键去重:重复值并入首现(${r.value.slice(0,40)})`}),e.splice(n,1),--n}return{statusValue:n,sourceReplaced:r}}const K=[{pattern:/^验证(结果)?(?!口径)/,title:`处置结果/验证口径`},{pattern:/^(治理记录|治理落地记录|治理落地|落地治理|治理(落地)|治理动作|治理$)/,title:`处置结果/治理记录`},{pattern:/^(修复(?!方向)|解决方案|变更内容|处理报告|处置(?!方向))/,title:`处置结果/变更记录`}];function Bt(e){let t=[],n=-1,r=``;for(let t of K){let i=e.findIndex(e=>e.startsWith(`## `)&&t.pattern.test(e.slice(3).trim()));if(i!==-1){n=i,r=t.title;break}}let i=e.some(e=>e.startsWith(`## `)&&e.includes(`处置结果`)),a=[...e],o=!1;if(!i&&n!==-1){let e=a[n]??``;a[n]=`## ${r}`,t.push({kind:`disposition-renamed`,detail:`${e} → ## ${r}`}),o=a.slice(n+1,n+1+8).some(e=>x.test(e))}return!i&&(n===-1||r===`处置结果/变更记录`)&&!o&&(a.push(``,`## 处置结果/验证口径`,``,`(原案无独立验证段;处置证据见上文各节——格式清偿迁移回填)`),t.push({kind:`disposition-appended`,detail:`追加 ## 处置结果/验证口径(无独立验证段的事实回填说明)`})),{lines:a,transformations:t,placeholder:o}}const Vt=[`优先级`,`状态`,`立案日期`,`所属域`,`来源`,`沿革`,`阻塞`];function Ht(e){if(e.injected||e.alreadyCanonical||e.originalStatus.length<=80)return null;let t=W(U(e.originalStatus).slice(0,12));if(t===null||t.tier!==`green`&&t.tier!==`red`&&t.tier!==`deferred`)return`manual`;let n=t.tier===`green`?`green`:`red`;return{summary:U(e.originalStatus.replace(/\*\*/g,``)),canonical:`${E[n]}(原「${t.word}」)`,tier:n}}function Ut(e){if(!e.fields.some(e=>e.key===`来源`)){if(e.defaultSource===void 0)return{skipMessage:`缺来源且未给回填缺省——交人工`};e.fields.push({key:`来源`,value:e.defaultSource}),e.transformations.push({kind:`required-backfilled`,detail:`来源 ← 缺省回填`})}return e.fields.some(e=>e.key===`所属域`)||(e.fields.push({key:`所属域`,value:e.scopeTitle}),e.transformations.push({kind:`required-backfilled`,detail:`所属域 ← ${e.scopeTitle}`})),{skipMessage:null}}function Wt(e){let t=e.lines.findIndex(e=>e.startsWith(`# `));if(t===-1)return null;let n=Ft(e.lines[t]??``,e.number);return n.line!==(e.lines[t]??``)&&e.transformations.push({kind:`h1-numbered`,detail:`${e.lines[t]} → ${n.line}`}),{line:n.line}}function Gt(e,t){let n=e.split(/\r?\n/),r=H(n),i=r.fields.findIndex(e=>e.key===`状态`),a=i===-1&&(t.status===`red`||t.status===`green`);if(i===-1&&!a)return{outcome:`skipped`,content:e,message:`无可识别状态行——灯位属语义判断,交人工(--status red|green 显式定档)`,transformations:[],sourceReplaced:!1};let o=a?`${E[t.status??`red`]}(存量清偿定档:原案无状态行,依结案内容人工定档)`:U(r.fields[i??0]?.value??``),s=!a&&D(`状态: ${o}`)!==`unknown`,c=Ht({injected:a,alreadyCanonical:s,originalStatus:o});if(c===`manual`)return{outcome:`skipped`,content:e,message:`状态值超长(${o.length} 字符——段落级文本混入状态行且词表未命中)——交人工拆分`,transformations:[],sourceReplaced:!1};let l=[],u=r.fields.map(e=>({key:e.key,value:U(e.value)}));a&&(u.push({key:`状态`,value:o}),l.push({kind:`status-canonicalized`,detail:`<无状态行> → ${o}(--status 注入,人工定档)`}));let d=It({fields:u,transformations:l,defaultPriority:t.defaultPriority,defaultFilingDate:t.defaultFilingDate});if(d.skipMessage!==null)return{outcome:`skipped`,content:e,message:d.skipMessage,transformations:[],sourceReplaced:!1};let f=t.status===`green`?`green`:`red`,p=a?{value:o,tier:f,word:`<无状态行>`}:s?{value:o,tier:D(`状态: ${o}`)===`green`||D(`状态: ${o}`)===`legacy-green`?`green`:`red`,word:`<已规范>`}:c!==null&&c!==`manual`?{value:c.canonical,tier:c.tier,word:`<超长拆分>`}:W(o);if(p===null)return{outcome:`skipped`,content:e,message:`状态值「${o}」不可机械迁移(冻结/取消无据/黄灯无因/词表未识别)——交人工`,transformations:[],sourceReplaced:!1};c!==null&&c!==`manual`&&!u.some(e=>e.key===`处置摘要`)&&(u.push({key:`处置摘要`,value:c.summary}),l.push({kind:`status-canonicalized`,detail:`状态值超长拆分:${c.summary.slice(0,24)}… → 短规范状态 + 处置摘要字段(${c.summary.length} 字符全文承载)`}));let m=p.tier===`green`,h=n.slice(r.bodyStartIndex),g=Rt(h,u);g.consumedLines>0&&(h=g.restLines,l.push({kind:`header-converged`,detail:`体首残留元信息块吸收 ${g.consumedLines} 行(键去重收敛见产物)`}));let _=zt(u,l),v=m?Bt(h):{lines:h,transformations:[],placeholder:!1};h=v.lines,l.push(...v.transformations);let ee=_.statusValue??(!a&&v.placeholder?`🟡 处理中(历史标记已处置但验证口径为占位,清偿时待核实;原「${p.word}」)`:p.value);!a&&!s&&(v.placeholder?l.push({kind:`status-downgraded-placeholder`,detail:`${o} → 🟡 处理中(处置段占位降级)`}):l.push({kind:`status-canonicalized`,detail:`${o} → ${p.value}`}));let y=u.findIndex(e=>e.key===`状态`);y!==-1&&(u[y]={key:`状态`,value:ee});let b=Ut({fields:u,transformations:l,defaultSource:t.defaultSource,scopeTitle:t.scopeTitle});if(b.skipMessage!==null)return{outcome:`skipped`,content:e,message:b.skipMessage,transformations:[],sourceReplaced:!1};let x=Wt({lines:n,number:t.number,transformations:l});if(x===null)return{outcome:`skipped`,content:e,message:`无一级标题——交人工`,transformations:[],sourceReplaced:!1};let te=[...Vt.flatMap(e=>u.filter(t=>t.key===e)),...u.filter(e=>!Vt.includes(e.key))],S=0;for(;S<h.length&&(h[S]??``).trim()===``;)S+=1;let C=[x.line,``,...te.map(e=>`**${e.key}**: ${e.value}`),...r.residuals.length>0?[``,...r.residuals]:[],``,...h.slice(S)].join(`
69
+ `);return s===e?{content:e,outcome:`unchanged`}:{content:s,outcome:`rewritten`}}function jt(e,t){return e.fields.filter(e=>!t.includes(`**${e.key}**: ${e.value}`)).map(e=>e.key)}function Mt(e){let t=``;try{t=r(u(e.root,e.file),`utf8`)}catch{return{file:e.file,outcome:`failed`,message:`读档失败(文件不存在或不可读)`}}let n=At(t,{status:e.status});if(n.outcome===`skipped`)return{file:e.file,outcome:`skipped`,message:`无可识别状态行且未给 --status——灯位属语义判断,不猜灯`};if(n.outcome===`unchanged`)return{file:e.file,outcome:`unchanged`,message:`头部已是规范形态`};let i=jt(H(t.split(/\r?\n/)),n.content);return i.length>0?{file:e.file,outcome:`failed`,message:`零丢失守卫失败:字段 ${i.join(`、`)} 未在产物在场——不落盘`}:(c(u(e.root,e.file),n.content),{file:e.file,outcome:`rewritten`,message:`头部已迁移为规范形态`})}function U(e){return e.trim().replace(/^\*\*/,``).replace(/\*\*$/,``).replace(/\*\*(?=[((])/,``).trim()}function Nt(e){for(let t of[`frozen`,`green`,`deferred`,`canceled`,`inProgress`,`red`])for(let n of ae[t])if(e.startsWith(n))return{tier:t,word:n};return null}function Pt(e,t){let n=e.slice(t.length).trim(),r=/^[((]([^))]*)[))]/.exec(n);return r===null?{paren:``,rest:n}:{paren:(r[1]??``).trim(),rest:n.slice((r[0]??``).length).trim()}}function W(e){let t=Nt(e);if(t===null)return null;let{paren:n,rest:r}=Pt(e,t.word),i=[n,r,`原「${t.word}」`].filter(e=>e!==``);switch(t.tier){case`frozen`:return null;case`green`:return{value:`🟢 已处置(${i.join(`;`)})`,tier:t.tier,word:t.word};case`red`:return{value:`🔴 待处理(${i.join(`;`)})`,tier:t.tier,word:t.word};case`deferred`:return{value:`🔴 待处理(${[n===``?`延期`:n,`原「${t.word}」`].join(`;`)})`,tier:t.tier,word:t.word};case`canceled`:return n===``||n.length<4?null:{value:`⚫ 已取消(${i.join(`;`)})`,tier:t.tier,word:t.word};case`inProgress`:return n.length<4?null:{value:`🟡 处理中(${n})`,tier:t.tier,word:t.word}}}function G(e){return{高:`P1`,中:`P2`,低:`P3`,P1:`P1`,P2:`P2`,P3:`P3`}[U(e)]??null}function Ft(e,t){let n=e.replace(/^#\s+/,``).replace(RegExp(`^${t}\\s*(?:[-—―·..::-]+\\s*)?`),``).trim();return{line:`# ${t} - ${n}`,titleCore:n}}function It(e){let{fields:t,transformations:n}=e,r=t.findIndex(e=>e.key===`立案日期`),i=t.findIndex(e=>e.key===`日期`);if(r===-1&&i!==-1){let e=t[i];e!==void 0&&(t[i]={key:`立案日期`,value:e.value},n.push({kind:`field-alias`,detail:`日期 → 立案日期(${e.value})`}))}if(!t.some(e=>e.key===`立案日期`)){if(e.defaultFilingDate===void 0)return{skipMessage:`缺立案日期且未给回填缺省——交人工`};t.push({key:`立案日期`,value:e.defaultFilingDate}),n.push({kind:`required-backfilled`,detail:`立案日期 ← ${e.defaultFilingDate}`})}let a=t.findIndex(e=>e.key===`优先级`);if(a!==-1){let e=t[a]?.value??``,r=G(e);r!==null&&r!==e&&(t[a]={key:`优先级`,value:r},n.push({kind:`priority-mapped`,detail:`优先级 ${e} → ${r}`}))}else{let r=t.find(e=>e.key===`严重程度`),i=(r===void 0?null:G(r.value))??e.defaultPriority??null;if(i===null)return{skipMessage:`缺优先级且未给回填缺省——交人工`};t.push({key:`优先级`,value:i}),n.push({kind:r===void 0?`priority-backfilled`:`priority-mapped`,detail:`优先级 ← ${i}${r===void 0?`(缺省回填)`:`(严重程度 ${r.value})`}`})}return{skipMessage:null}}const Lt=new Set([`状态`,`优先级`,`立案日期`,`日期`,`来源`,`严重程度`,`严重度`,`所属域`,`处置日期`,`沿革`,`阻塞`]);function Rt(e,t){let n=[],r=0,i=!1,a=!1,o=0,s=[];for(;o<e.length;){let t=e[o]??``;if(t.trim()===``){n.push(t),o+=1;continue}let c=/^(?:\*\*|- \*\*|- )([^*::]{1,20})(?:\*\*)?\s*[::]\s*(.+)$/.exec(t),l=/^(?:\*\*|- \*\*|- )([^*::]{1,20})(?:\*\*)?\s*[::]\s*$/.exec(t);if(c===null&&l===null)break;let u=((c??l)?.[1]??``).trim();if(u===``)break;if(n.push(t),r+=1,Lt.has(u)&&(i=!0),c!==null){s.push({key:u,value:U(c[2]??``)}),o+=1;continue}let d=[],f=t.length-t.trimStart().length;for(o+=1;o<e.length;){let t=e[o]??``;if(t.trim()===``||t.length-t.trimStart().length<=f)break;n.push(t),d.push(t.trim().replace(/^-\s*/,``)),o+=1}d.length===0?s.push({key:u,value:``}):(s.push({key:u,value:d.join(`;`)}),a=!0)}if(r===0||!i&&r<2&&!a)return{consumedLines:0,restLines:e};for(t.push(...s);n.length>0&&(n[n.length-1]??``).trim()===``;)n.pop(),--o;return{consumedLines:r,restLines:e.slice(o)}}function zt(e,t){let n,r=!1,i=e.filter(e=>e.key===`状态`);if(i.length>1){let r=i[0]?.value.includes(`存量清偿定档:原案无状态行`)===!0,a=i.slice(1).find(e=>!e.value.includes(`存量清偿定档:原案无状态行`));if(r&&a!==void 0){let r=W(a.value);if(r!==null){let i=e.find(e=>e.key===`状态`);i!==void 0&&(i.value=r.value),n=r.value,t.push({kind:`duplicate-field-converged`,detail:`状态 键去重:注入定档让位原始语义 → ${r.value}`})}}}let a=e.filter(e=>e.key===`来源`);if(a.length>1){let n=a[0]?.value.includes(`格式清偿迁移回填`)===!0,i=a.slice(1).find(e=>!e.value.includes(`格式清偿迁移回填`));if(n&&i!==void 0){let n=e.find(e=>e.key===`来源`);n!==void 0&&(n.value=i.value),r=!0,t.push({kind:`duplicate-field-converged`,detail:`来源 键去重:回填缺省让位原始语义 → ${i.value.slice(0,60)}`})}}let o=new Map;for(let n=0;n<e.length;n+=1){let r=e[n];if(r===void 0)continue;let i=o.get(r.key);if(i===void 0){o.set(r.key,n);continue}let a=e[i];r.value!==``&&a!==void 0&&!a.value.includes(r.value)&&(a.value=a.value===``?r.value:`${a.value};${r.value}`),t.push({kind:`duplicate-field-converged`,detail:`${r.key} 键去重:重复值并入首现(${r.value.slice(0,40)})`}),e.splice(n,1),--n}return{statusValue:n,sourceReplaced:r}}const K=[{pattern:/^验证(结果)?(?!口径)/,title:`处置结果/验证口径`},{pattern:/^(治理记录|治理落地记录|治理落地|落地治理|治理(落地)|治理动作|治理$)/,title:`处置结果/治理记录`},{pattern:/^(修复(?!方向)|解决方案|变更内容|处理报告|处置(?!方向))/,title:`处置结果/变更记录`}];function Bt(e){let t=[],n=-1,r=``;for(let t of K){let i=e.findIndex(e=>e.startsWith(`## `)&&t.pattern.test(e.slice(3).trim()));if(i!==-1){n=i,r=t.title;break}}let i=e.some(e=>e.startsWith(`## `)&&e.includes(`处置结果`)),a=[...e],o=!1;if(!i&&n!==-1){let e=a[n]??``;a[n]=`## ${r}`,t.push({kind:`disposition-renamed`,detail:`${e} → ## ${r}`}),o=a.slice(n+1,n+1+8).some(e=>x.test(e))}return!i&&(n===-1||r===`处置结果/变更记录`)&&!o&&(a.push(``,`## 处置结果/验证口径`,``,`(原案无独立验证段;处置证据见上文各节——格式清偿迁移回填)`),t.push({kind:`disposition-appended`,detail:`追加 ## 处置结果/验证口径(无独立验证段的事实回填说明)`})),{lines:a,transformations:t,placeholder:o}}const Vt=[`优先级`,`状态`,`立案日期`,`所属域`,`来源`,`沿革`,`阻塞`];function Ht(e){if(e.injected||e.alreadyCanonical||e.originalStatus.length<=80)return null;let t=W(U(e.originalStatus).slice(0,12));if(t===null||t.tier!==`green`&&t.tier!==`red`&&t.tier!==`deferred`)return`manual`;let n=t.tier===`green`?`green`:`red`;return{summary:U(e.originalStatus.replace(/\*\*/g,``)),canonical:`${E[n]}(原「${t.word}」)`,tier:n}}function Ut(e){if(!e.fields.some(e=>e.key===`来源`)){if(e.defaultSource===void 0)return{skipMessage:`缺来源且未给回填缺省——交人工`};e.fields.push({key:`来源`,value:e.defaultSource}),e.transformations.push({kind:`required-backfilled`,detail:`来源 ← 缺省回填`})}return e.fields.some(e=>e.key===`所属域`)||(e.fields.push({key:`所属域`,value:e.scopeTitle}),e.transformations.push({kind:`required-backfilled`,detail:`所属域 ← ${e.scopeTitle}`})),{skipMessage:null}}function Wt(e){let t=e.lines.findIndex(e=>e.startsWith(`# `));if(t===-1)return null;let n=Ft(e.lines[t]??``,e.number);return n.line!==(e.lines[t]??``)&&e.transformations.push({kind:`h1-numbered`,detail:`${e.lines[t]} → ${n.line}`}),{line:n.line}}function Gt(e,t){let n=e.split(/\r?\n/),r=H(n),i=r.fields.findIndex(e=>e.key===`状态`),a=i===-1&&(t.status===`red`||t.status===`green`);if(i===-1&&!a)return{outcome:`skipped`,content:e,message:`无可识别状态行——灯位属语义判断,交人工(--status red|green 显式定档)`,transformations:[],sourceReplaced:!1};let o=a?`${E[t.status??`red`]}(存量清偿定档:原案无状态行,依结案内容人工定档)`:U(r.fields[i??0]?.value??``),s=!a&&D(`状态: ${o}`)!==`unknown`,c=Ht({injected:a,alreadyCanonical:s,originalStatus:o});if(c===`manual`)return{outcome:`skipped`,content:e,message:`状态值超长(${o.length} 字符——段落级文本混入状态行且词表未命中)——交人工拆分`,transformations:[],sourceReplaced:!1};let l=[],u=r.fields.map(e=>({key:e.key,value:U(e.value)}));a&&(u.push({key:`状态`,value:o}),l.push({kind:`status-canonicalized`,detail:`<无状态行> → ${o}(--status 注入,人工定档)`}));let d=It({fields:u,transformations:l,defaultPriority:t.defaultPriority,defaultFilingDate:t.defaultFilingDate});if(d.skipMessage!==null)return{outcome:`skipped`,content:e,message:d.skipMessage,transformations:[],sourceReplaced:!1};let f=t.status===`green`?`green`:`red`,p=a?{value:o,tier:f,word:`<无状态行>`}:s?{value:o,tier:D(`状态: ${o}`)===`green`||D(`状态: ${o}`)===`legacy-green`?`green`:`red`,word:`<已规范>`}:c===null?W(o):{value:c.canonical,tier:c.tier,word:`<超长拆分>`};if(p===null)return{outcome:`skipped`,content:e,message:`状态值「${o}」不可机械迁移(冻结/取消无据/黄灯无因/词表未识别)——交人工`,transformations:[],sourceReplaced:!1};c!==null&&!u.some(e=>e.key===`处置摘要`)&&(u.push({key:`处置摘要`,value:c.summary}),l.push({kind:`status-canonicalized`,detail:`状态值超长拆分:${c.summary.slice(0,24)}… → 短规范状态 + 处置摘要字段(${c.summary.length} 字符全文承载)`}));let m=p.tier===`green`,h=n.slice(r.bodyStartIndex),g=Rt(h,u);g.consumedLines>0&&(h=g.restLines,l.push({kind:`header-converged`,detail:`体首残留元信息块吸收 ${g.consumedLines} 行(键去重收敛见产物)`}));let _=zt(u,l),v=m?Bt(h):{lines:h,transformations:[],placeholder:!1};h=v.lines,l.push(...v.transformations);let ee=_.statusValue??(!a&&v.placeholder?`🟡 处理中(历史标记已处置但验证口径为占位,清偿时待核实;原「${p.word}」)`:p.value);!a&&!s&&(v.placeholder?l.push({kind:`status-downgraded-placeholder`,detail:`${o} → 🟡 处理中(处置段占位降级)`}):l.push({kind:`status-canonicalized`,detail:`${o} → ${p.value}`}));let y=u.findIndex(e=>e.key===`状态`);y!==-1&&(u[y]={key:`状态`,value:ee});let b=Ut({fields:u,transformations:l,defaultSource:t.defaultSource,scopeTitle:t.scopeTitle});if(b.skipMessage!==null)return{outcome:`skipped`,content:e,message:b.skipMessage,transformations:[],sourceReplaced:!1};let x=Wt({lines:n,number:t.number,transformations:l});if(x===null)return{outcome:`skipped`,content:e,message:`无一级标题——交人工`,transformations:[],sourceReplaced:!1};let te=[...Vt.flatMap(e=>u.filter(t=>t.key===e)),...u.filter(e=>!Vt.includes(e.key))],S=0;for(;S<h.length&&(h[S]??``).trim()===``;)S+=1;let C=[x.line,``,...te.map(e=>`**${e.key}**: ${e.value}`),...r.residuals.length>0?[``,...r.residuals]:[],``,...h.slice(S)].join(`
70
70
  `);return C===e?{outcome:`unchanged`,content:e,message:`已是规范形态`,transformations:[],sourceReplaced:!1}:{outcome:`rewritten`,content:C,message:`存量头部已清偿为规范形态`,transformations:l,sourceReplaced:_.sourceReplaced}}const Kt=/^([0-9]{3,4})-.+\.md$/;function qt(e,t){return e.scopes.filter(e=>t===e.registryDir||t.startsWith(`${e.registryDir}/`)).sort((e,t)=>t.registryDir.length-e.registryDir.length)[0]?.title??null}function Jt(e,t,n){let r=[],i=e.split(/\r?\n/);for(let e=0;e<i.length;e+=1){let a=i[e]??``,o=a.trim();if(o===``||t.includes(o))continue;if(o.startsWith(`# `)){let e=o.replace(/^#\s+/,``).replace(/^[0-9]{3,4}\s*(?:[-—―·..::-]+\s*|\s+)/,``).trim();if(e!==``&&t.includes(e))continue}if(o.startsWith(`## `)&&K.some(e=>e.pattern.test(o.slice(3).trim()))&&t.includes(`处置结果/`))continue;let s=/^\|([^|]*)\|([^|]*)\|$/.exec(o);if(s!==null){let a=(s[1]??``).trim(),c=(s[2]??``).trim(),l=/^:?-{2,}:?$/,u=/^\|([^|]*)\|([^|]*)\|$/.exec((i[e+1]??``).trim()),d=u!==null&&l.test((u[1]??``).trim())&&l.test((u[2]??``).trim());if(l.test(a)&&l.test(c)||d&&a!==``||a===``||n.includes(a)||t.includes(`**${a}**: ${c}`))continue;r.push(o.slice(0,60));continue}if(o.startsWith(`>`)){let e=o.slice(1).split(/[||]/),r=!0;for(let i of e){let e=/^([^::]{1,8})\s*[::]\s*(.+)$/.exec(i.trim());if(e===null)continue;let a=(e[1]??``).replace(/^\*+|\*+$/g,``).trim(),o=U(e[2]??``);!n.includes(a)&&!t.includes(o)&&(r=!1)}if(r)continue}let c=/^(?:\*\*|- \*\*|- )([^*::]{1,20})(?:\*\*)?\s*[::]\s*$/.exec(o);if(c!==null&&t.includes(`**${(c[1]??``).trim()}**:`)||o.startsWith(`- `)&&t.includes(o.slice(2).trim()))continue;let l=/^(?:\*\*|- \*\*|- |## )([^*::]{1,20})(?:\*\*)?\s*[::]\s*(.+)$/.exec(a);if(l!==null){let e=(l[1]??``).trim(),r=U(l[2]??``);if(n.includes(e)||t.includes(r))continue}let u=/^##\s*([^::]{1,10})\s*$/.exec(o);if(u!==null&&V.has(u[1]?.trim()??``))continue;let d=e-1;for(;d>=0&&(i[d]??``).trim()===``;)--d;let f=/^##\s*([^::]{1,10})\s*$/.exec((i[d]??``).trim());if(f!==null&&V.has(f[1]?.trim()??``)){let e=(f[1]??``).trim();if(n.includes(e)||t.includes(U(o)))continue}r.push(o.slice(0,60))}return r}function Yt(e){let t=e.file.split(`/`).pop()??``,n=Kt.exec(t);if(n===null)return{file:e.file,outcome:`skipped`,message:`文件名不属注册表编号形态(NNNN-slug.md)`,content:``,transformations:[]};let i=qt(e.config,e.file);if(i===null)return{file:e.file,outcome:`skipped`,message:`文件不在任何已登记 scope 的 registryDir 内——交人工`,content:``,transformations:[]};let a=``;try{a=r(u(e.root,e.file),`utf8`)}catch{return{file:e.file,outcome:`failed`,message:`读档失败(文件不存在或不可读)`,content:``,transformations:[]}}let o=Gt(a,{number:n[1]??``,scopeTitle:i,defaultPriority:e.defaultPriority,defaultSource:e.defaultSource,defaultFilingDate:e.defaultFilingDate,status:e.status});if(o.outcome!==`rewritten`)return{file:e.file,outcome:o.outcome,message:o.message,content:o.content,transformations:o.transformations};let s=Jt(a,o.content,o.sourceReplaced?[`状态`,`日期`,`优先级`,`来源`]:[`状态`,`日期`,`优先级`]);return s.length>0?{file:e.file,outcome:`failed`,message:`零丢失守卫失败:${s.length} 项原文内容未在产物在场(如 ${s[0]})——不落盘`,content:o.content,transformations:o.transformations}:(e.dryRun!==!0&&c(u(e.root,e.file),o.content),{file:e.file,outcome:`rewritten`,message:e.dryRun===!0?`dry-run 通过(未落盘)`:`存量头部已清偿为规范形态`,content:o.content,transformations:o.transformations})}function q(e,t){if(t.kind===`numericPrefix`)return/^(\d+)(?=[-._ ]|$)/.exec(e)?.[1]??null;if(t.kind===`compositePrefix`)return RegExp(`^(\\d+(?:[-._ ]\\d+){${t.groups-1}})(?=[-._ ]|$)`).exec(e)?.[1]??null;if(t.kind===`numericSuffix`){let t=e.replace(/\.[^.]+$/,``);return/(\d+)$/.exec(t)?.[1]??null}return new RegExp(t.pattern).exec(e)?.groups?.key??null}function J(e){let t=/^\d+/.exec(e);return t===null?null:Number.parseInt(t[0]??``,10)}function Y(e){let t=new Set;for(let n of e.basenames){let r=q(n,e.rule);r!==null&&t.add(r)}if(t.size===0)return{ok:!1,error:`该范围当前无编号文件,无法推断位数——请人工定号后落盘`};let n=``;for(let e of t)(J(e)??0)>(J(n)||0)&&(n=e);if(n===``)return{ok:!1,error:`该范围无数字前缀键,无法取号`};let r=n.length,i=new Set(e.reserved),a=0,o=0,s=(J(n)??0)+1;for(;;){let e=String(s).padStart(r,`0`);if(t.has(e)){a+=1,s+=1;continue}if(i.has(e)){o+=1,s+=1;continue}return{ok:!0,number:e,skippedOccupied:a,skippedReserved:o}}}function Xt(e){let t=/^\d+[-._ ](.+)\.[^.]+$/.exec(e);return t===null?null:t[1]??``}function Zt(e,t){if(e.length!==t.length)return!1;let n=[...e].sort(),r=[...t].sort();return n.every((e,t)=>e===r[t])}function Qt(e){let t=[],n=new Map;for(let t of e.basenames){let r=q(t,e.rule);r!==null&&n.set(r,[...n.get(r)??[],t])}let r=new Map(e.reserved.map(e=>[e.number,e.reason])),i=new Set;for(let[a,o]of n){if(o.length>=2){let n=e.allowlist.findIndex((t,n)=>!i.has(n)&&t.number===a&&Zt(t.files,o.map(t=>e.toRepoRelative(t))));n===-1?t.push({kind:`duplicate`,scopeKey:e.scopeKey,message:`scope「${e.scopeKey}」编号 ${a} 撞号:${o.join(`、`)}——先入库者保号,后到线顺延清偿`}):i.add(n);continue}let n=r.get(a);n!==void 0&&t.push({kind:`reservedOccupied`,scopeKey:e.scopeKey,message:`scope「${e.scopeKey}」保留号 ${a} 被占用(${o.join(`、`)};保留理由:${n}——保留号不回收复用,请让号重编`})}if([...n.keys()].some(e=>e.length>1&&e.startsWith(`0`))){let r=new Set([...n.keys()].map(e=>e.length));r.size>1&&t.push({kind:`widthInconsistent`,scopeKey:e.scopeKey,message:`scope「${e.scopeKey}」零填充位数混用(族内键长 ${[...r].sort((e,t)=>e-t).join(`/`)}):${[...n.keys()].slice(0,6).join(`、`)}`})}if(e.allowlist.forEach((r,a)=>{if(i.has(a))return;let o=r.files.filter(e=>{let t=e.split(`/`).pop()??``;return(n.get(r.number)??[]).includes(t)});t.push({kind:`allowlistStale`,scopeKey:e.scopeKey,message:`scope「${e.scopeKey}」豁免条目(${r.number},${r.status})已无对应现行撞号组——棘轮只许缩短,须同步删除该条目(登记集:${r.files.join(`、`)};磁盘现状:${o.length>0?o.join(`、`):`无`})`})}),e.slugDigitPolicy!==`allow`){let n=new Set;for(let r of e.basenames){let i=Xt(r);if(i===null||i===``||!/\d/.test(i))continue;let a=e.toRepoRelative(r);e.slugDigitAllowlist.some(e=>k(e,a)?(n.add(e),!0):!1)||t.push({kind:`slugContainsDigit`,scopeKey:e.scopeKey,message:`scope「${e.scopeKey}」slug 段含数字:${r}(白名单登记请到配置 slugDigitAllowlist,逐条带理由)`})}if(e.fullMode)for(let r of e.slugDigitAllowlist)n.has(r)||t.push({kind:`slugDigitAllowlistStale`,scopeKey:`global`,message:`slug 白名单条目「${r}」在启用域内已匹配不到任何文件——棘轮只许缩短,须同步删除该条目`})}return t}function $t(e){let t=[],n=new RegExp(e.numberishPattern),r=new Map,i=new Set;for(let t of e.files){let a=t.split(`/`).pop()??``;if(!n.test(a)||e.registryDirs.some(e=>t===e||t.startsWith(`${e}/`))||e.pending.find(e=>k(e.glob,t)?(i.add(e.glob),!0):!1)!==void 0)continue;let o=t.split(`/`).slice(0,-1).join(`/`);r.set(o,[...r.get(o)??[],a])}for(let e of[...r.keys()].sort((e,t)=>e.localeCompare(t)))t.push({kind:`coverageGap`,message:`未登记编号区:目录 ${e===``?`(仓库根)`:e} 有 ${r.get(e)?.length??0} 个编号文件未被任何 scope/pending 覆盖——${(r.get(e)??[]).join(`、`)}(请在 lzi-issues.config.ts 登记 scope 或 pending 并注明理由)`});for(let n of e.pending)i.has(n.glob)||t.push({kind:`pendingStale`,message:`pending 条目「${n.glob}」已匹配不到任何编号文件——棘轮只许缩短,须同步删除该条目(登记理由:${n.reason})`});return t}const X={kind:`numericPrefix`};function Z(e,t){return j(e,[t]).map(e=>e.split(`/`).pop()??``)}function en(e){let t=e.scopeKey!==void 0&&e.dirRel!==void 0,n=e.scopeKey===void 0&&e.dirRel===void 0;if(t||n)return{ok:!1,error:`取号须且仅须指定 --scope <key> 或 --dir <目录> 之一`};if(e.scopeKey!==void 0){let t=e.config.scopes.find(t=>t.key===e.scopeKey);if(t===void 0)return{ok:!1,error:`scope「${e.scopeKey}」未登记(请在 lzi-issues.config.ts 注册)`};let n=Y({basenames:Z(e.root,t.registryDir),rule:X,reserved:t.numbering.reserved.map(e=>e.number)});return n.ok?{ok:!0,number:n.number,target:t.key,skippedOccupied:n.skippedOccupied,skippedReserved:n.skippedReserved}:n}let r=e.config.scopes.filter(t=>t.registryDir===e.dirRel);if(r.length===0)return{ok:!1,error:`目录「${e.dirRel}」未登记为任何 scope 的注册表(请在 lzi-issues.config.ts 注册后再取号)`};let i=[...new Set(r.flatMap(e=>e.numbering.reserved.map(e=>e.number)))],a=Y({basenames:Z(e.root,e.dirRel??``),rule:X,reserved:i});return a.ok?{ok:!0,number:a.number,target:e.dirRel??``,skippedOccupied:a.skippedOccupied,skippedReserved:a.skippedReserved}:a}function tn(e){let t=e.dirRel===void 0?e.config.scopes:e.config.scopes.filter(t=>t.registryDir===e.dirRel),n=[],r=0;for(let i of t){let t=Z(e.root,i.registryDir);r+=t.length;let a=e.dirRel===void 0?e.config.numbering.allowlist.filter(e=>e.scopeKey===i.key).map(e=>({...e,files:[...e.files]})):e.config.numbering.allowlist.filter(t=>t.scopeKey===i.key&&t.files.some(t=>t.startsWith(`${e.dirRel}/`))).map(e=>({...e,files:[...e.files]}));n.push(...Qt({scopeKey:i.key,basenames:t,rule:X,reserved:i.numbering.reserved,allowlist:a,slugDigitPolicy:i.slugDigitPolicy,slugDigitAllowlist:e.config.slugDigitAllowlist.map(e=>e.glob),toRepoRelative:e=>`${i.registryDir}/${e}`,fullMode:e.dirRel===void 0}))}return{findings:n,scopeCount:t.length,scannedFiles:r}}function nn(e){let t=[];for(let n of e.config.numbering.audit.roots)t.push(...M(u(e.root,n),{excludeGlobs:e.config.numbering.globalExclusions.map(e=>e.glob)}).map(e=>n===``?e:`${n}/${e}`));return{findings:$t({files:t,numberishPattern:e.config.numbering.audit.numberishPattern,registryDirs:e.config.scopes.map(e=>e.registryDir),pending:e.config.numbering.audit.pending}),scannedFiles:t.length}}const Q=`<!-- issue-file-format-fixture:start -->`,$=`<!-- issue-file-format-fixture:end -->`,rn=`docs/guides/issue-file-format.md`;function an(){let e=l(f(import.meta.url.replace(`file://`,``)));for(let n=0;n<10;n+=1){let n=u(e,rn);if(t(n))return n;let r=l(e);if(r===e)break;e=r}throw Error(`未定位到格式指南:${rn}(自模块位置向上 10 层内)`)}function on(){return r(an(),`utf8`)}function sn(e){let t=e.indexOf(Q),n=e.indexOf($);if(t===-1)throw Error(`指南活样板起点标记缺席:${Q}`);if(n===-1)throw Error(`指南活样板终点标记缺席:${$}`);if(n<t)throw Error(`指南活样板标记次序颠倒(终点在起点之前)`);return e.slice(t+40,n).replace(/^\n+/,``).replace(/\n+$/,``)}const cn=[`## 一、问题动机`,``,`> <问题原文逐字记录,禁止转述改写>`,``,`客观证据(报错/复现步骤/涉及文件/日志路径):`,`- <证据>`,``].join(`
71
71
  `),ln=[`## 二、现状与证据`,``,`<排查链路与实证;无法确认根因时如实标注「根因待治理时核实」>`,``].join(`
72
72
  `),un=[`## 三、处置方向`,``,`【1】备选方案和分析`,`- <备选>:<分析>`,``,`【2】推荐方案和分析`,`- <推荐>:<分析;能自决的直接执行,裁决类停下等用户裁定>`,``].join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@longzai-intelligence-issues/ledger",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "license": "UNLICENSED",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -27,7 +27,7 @@
27
27
  "clean": "lzi-dev-cli clean"
28
28
  },
29
29
  "dependencies": {
30
- "@longzai-intelligence-issues/config": "0.0.3"
30
+ "@longzai-intelligence-issues/config": "0.0.4"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/bun": "^1.4.2"
@@ -605,7 +605,7 @@ export function migrateLegacyCore(raw: string, options: MigrateCoreOptions): Mig
605
605
  : ('red' as const),
606
606
  word: '<已规范>',
607
607
  }
608
- : longSplit !== null && longSplit !== 'manual'
608
+ : longSplit !== null
609
609
  ? {
610
610
  value: longSplit.canonical,
611
611
  tier: longSplit.tier,
@@ -626,11 +626,7 @@ export function migrateLegacyCore(raw: string, options: MigrateCoreOptions): Mig
626
626
  /**
627
627
  * 超长状态拆分产物:短规范状态承载词表档位,全文说明落处置摘要字段
628
628
  */
629
- if (
630
- longSplit !== null &&
631
- longSplit !== 'manual' &&
632
- !fields.some((field) => field.key === '处置摘要')
633
- ) {
629
+ if (longSplit !== null && !fields.some((field) => field.key === '处置摘要')) {
634
630
  fields.push({ key: '处置摘要', value: longSplit.summary });
635
631
 
636
632
  transformations.push({